Commit 35355e5d authored by darin's avatar darin

Reviewed by Dave.

	- fixed 3129129 -- leak of 820 RenderStyle objects each time we run cvs-base

	The RenderStyle objects were the tip of an iceberg.

        I fixed a lot of leaks, but there are still some remaining.

	Note that these changes will make Development builds slower because they disable
	the arena allocator in favor of assertions that check we are using it correctly.
	But the changes make Deployment builds slightly faster.

        * khtml/html/html_baseimpl.cpp: (HTMLFrameSetElementImpl::attach):
	Fix a leak in the !isStyleAvailable() case by ref'ing and deref'ing the style.

        * khtml/html/html_formimpl.cpp:
        (HTMLFormElementImpl::attach): Fix a leak by getting the style from the render
	object instead of calling styleForElement again, which makes a new one.
        (HTMLFormElementImpl::parseAttribute): Ditto.
        (HTMLInputElementImpl::attach): Fix a leak by using the style in the local
	variable rather than calling styleForElement again.

        * khtml/html/html_imageimpl.cpp:
        (HTMLImageElementImpl::parseAttribute): Fix a leak by getting the style from the render
	object instead of calling styleForElement again, which makes a new one.
        (HTMLImageElementImpl::attach): Fix a leak by using the style in the local
	variable rather than calling styleForElement again.

        * khtml/html/html_inlineimpl.cpp: (HTMLBRElementImpl::attach):
	Fix a leak in the display() == NONE case by ref'ing and deref'ing the style.

        * khtml/html/html_objectimpl.cpp: (HTMLObjectElementImpl::attach): Fix a leak by using
	the style in the local variable rather than calling styleForElement again.

        * khtml/rendering/bidi.cpp:
        (BidiIterator::detach): Added debugging code to detect if someone does a delete directly,
	which will not deallocate the object because it won't run the correct arena code.
        (BidiIterator::operator delete): Ditto.
        (appendRunsForObject): Fix a leak by detaching bidi iterators when they are removed from
	the list. The list can't delete them because it doesn't have the arena pointer.
        (deleteMidpoints): Fix a leak by not removing the items from the list until done iterating.
	The old code would fail to delete half the items.

        * khtml/rendering/render_container.cpp:
        (RenderContainer::detach): Detach the continuation here. Before we removed it but did not
	detach it, which led to a leak.
        (RenderContainer::removeChild): Do not remove the continuation here. If we do, then we can't
	detach successfully. No one depends on this removing the continuation.
        (RenderContainer::removeLeftoverAnonymousBoxes): Detach the child, don't just delete it.
	This fixes a leak.

        * khtml/rendering/render_flow.cpp: (RenderFlow::removeChild): Detach the child, don't just
	delete it. This fixes a leak.

        * khtml/rendering/render_object.h: Added arenaDelete.
        * khtml/rendering/render_object.cpp:
        (RenderObject::operator delete): Added debugging code to detect if someone does a delete directly,
	which will not deallocate the object because it won't run the correct arena code.
        (RenderObject::detach): Ditto.
        (RenderObject::arenaDelete): Put the low-level delete here, so that subclasses (RenderWidget)
	can call it.

        * khtml/rendering/render_replaced.h: Add arenaDeref and make deref private so derived classes
	won't use it by accident.
        * khtml/rendering/render_replaced.cpp:
        (RenderWidget::detach): Use the new arenaDeref instead of deref, since we need to pass the
	arena pointer in to delete.
        (RenderWidget::resizeWidget): Ditto. Store the arena before calling back, since we can't get it
	once it's detached from its parent.
        (RenderWidget::eventFilter): Ditto.
        (RenderWidget::arenaDeref): Added. Calls RenderObject's arenaDelete.

	- other changes

        * khtml/rendering/render_arena.cpp:
        (RenderArena::allocate): Added debugging code that stores a signature, arena pointer, and size,
	and uses malloc rather than the arena.
        (RenderArena::free): Check the signature, arena pointer, and size, and use free.

        * khtml/rendering/render_layer.cpp:
        (RenderLayer::operator delete): Added debugging code to detect if someone does a delete directly,
	which will not deallocate the object because it won't run the correct arena code.
        (RenderLayer::detach): Ditto.
        (RenderLayer::RenderLayerElement::operator delete): Ditto.
        (RenderLayer::RenderLayerElement::detach): Ditto.
        (RenderLayer::RenderZTreeNode::operator delete): Ditto.
        (RenderLayer::RenderZTreeNode::detach): Ditto.

        * khtml/rendering/render_text.cpp:
        (TextSlave::detach): Added debugging code to detect if someone does a delete directly,
	which will not deallocate the object because it won't run the correct arena code.
        (TextSlave::operator delete): Ditto.

        * khtml/html/html_elementimpl.cpp: (HTMLElementImpl::createContextualFragment):
	Save one new/delete by using a stack-based HTMLTokenizer and add FIXMEs about
	some possible leaks I spotted here.

        * khtml/rendering/render_list.cpp: (RenderListItem::setStyle): Took out APPLE_CHANGES from around
	a generally useful bug fix.

        * WebCore.pbproj/project.pbxproj: Let Electron be Electron.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@3147 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 3810ad1a
2002-12-20 Darin Adler <darin@apple.com>
Reviewed by Dave.
- fixed 3129129 -- leak of 820 RenderStyle objects each time we run cvs-base
The RenderStyle objects were the tip of an iceberg.
I fixed a lot of leaks, but there are still some remaining.
Note that these changes will make Development builds slower because they disable
the arena allocator in favor of assertions that check we are using it correctly.
But the changes make Deployment builds slightly faster.
* khtml/html/html_baseimpl.cpp: (HTMLFrameSetElementImpl::attach):
Fix a leak in the !isStyleAvailable() case by ref'ing and deref'ing the style.
* khtml/html/html_formimpl.cpp:
(HTMLFormElementImpl::attach): Fix a leak by getting the style from the render
object instead of calling styleForElement again, which makes a new one.
(HTMLFormElementImpl::parseAttribute): Ditto.
(HTMLInputElementImpl::attach): Fix a leak by using the style in the local
variable rather than calling styleForElement again.
* khtml/html/html_imageimpl.cpp:
(HTMLImageElementImpl::parseAttribute): Fix a leak by getting the style from the render
object instead of calling styleForElement again, which makes a new one.
(HTMLImageElementImpl::attach): Fix a leak by using the style in the local
variable rather than calling styleForElement again.
* khtml/html/html_inlineimpl.cpp: (HTMLBRElementImpl::attach):
Fix a leak in the display() == NONE case by ref'ing and deref'ing the style.
* khtml/html/html_objectimpl.cpp: (HTMLObjectElementImpl::attach): Fix a leak by using
the style in the local variable rather than calling styleForElement again.
* khtml/rendering/bidi.cpp:
(BidiIterator::detach): Added debugging code to detect if someone does a delete directly,
which will not deallocate the object because it won't run the correct arena code.
(BidiIterator::operator delete): Ditto.
(appendRunsForObject): Fix a leak by detaching bidi iterators when they are removed from
the list. The list can't delete them because it doesn't have the arena pointer.
(deleteMidpoints): Fix a leak by not removing the items from the list until done iterating.
The old code would fail to delete half the items.
* khtml/rendering/render_container.cpp:
(RenderContainer::detach): Detach the continuation here. Before we removed it but did not
detach it, which led to a leak.
(RenderContainer::removeChild): Do not remove the continuation here. If we do, then we can't
detach successfully. No one depends on this removing the continuation.
(RenderContainer::removeLeftoverAnonymousBoxes): Detach the child, don't just delete it.
This fixes a leak.
* khtml/rendering/render_flow.cpp: (RenderFlow::removeChild): Detach the child, don't just
delete it. This fixes a leak.
* khtml/rendering/render_object.h: Added arenaDelete.
* khtml/rendering/render_object.cpp:
(RenderObject::operator delete): Added debugging code to detect if someone does a delete directly,
which will not deallocate the object because it won't run the correct arena code.
(RenderObject::detach): Ditto.
(RenderObject::arenaDelete): Put the low-level delete here, so that subclasses (RenderWidget)
can call it.
* khtml/rendering/render_replaced.h: Add arenaDeref and make deref private so derived classes
won't use it by accident.
* khtml/rendering/render_replaced.cpp:
(RenderWidget::detach): Use the new arenaDeref instead of deref, since we need to pass the
arena pointer in to delete.
(RenderWidget::resizeWidget): Ditto. Store the arena before calling back, since we can't get it
once it's detached from its parent.
(RenderWidget::eventFilter): Ditto.
(RenderWidget::arenaDeref): Added. Calls RenderObject's arenaDelete.
- other changes
* khtml/rendering/render_arena.cpp:
(RenderArena::allocate): Added debugging code that stores a signature, arena pointer, and size,
and uses malloc rather than the arena.
(RenderArena::free): Check the signature, arena pointer, and size, and use free.
* khtml/rendering/render_layer.cpp:
(RenderLayer::operator delete): Added debugging code to detect if someone does a delete directly,
which will not deallocate the object because it won't run the correct arena code.
(RenderLayer::detach): Ditto.
(RenderLayer::RenderLayerElement::operator delete): Ditto.
(RenderLayer::RenderLayerElement::detach): Ditto.
(RenderLayer::RenderZTreeNode::operator delete): Ditto.
(RenderLayer::RenderZTreeNode::detach): Ditto.
* khtml/rendering/render_text.cpp:
(TextSlave::detach): Added debugging code to detect if someone does a delete directly,
which will not deallocate the object because it won't run the correct arena code.
(TextSlave::operator delete): Ditto.
* khtml/html/html_elementimpl.cpp: (HTMLElementImpl::createContextualFragment):
Save one new/delete by using a stack-based HTMLTokenizer and add FIXMEs about
some possible leaks I spotted here.
* khtml/rendering/render_list.cpp: (RenderListItem::setStyle): Took out APPLE_CHANGES from around
a generally useful bug fix.
* WebCore.pbproj/project.pbxproj: Let Electron be Electron.
=== Alexander-42 ===
2002-12-19 David Hyatt <hyatt@apple.com>
......
2002-12-20 Darin Adler <darin@apple.com>
Reviewed by Dave.
- fixed 3129129 -- leak of 820 RenderStyle objects each time we run cvs-base
The RenderStyle objects were the tip of an iceberg.
I fixed a lot of leaks, but there are still some remaining.
Note that these changes will make Development builds slower because they disable
the arena allocator in favor of assertions that check we are using it correctly.
But the changes make Deployment builds slightly faster.
* khtml/html/html_baseimpl.cpp: (HTMLFrameSetElementImpl::attach):
Fix a leak in the !isStyleAvailable() case by ref'ing and deref'ing the style.
* khtml/html/html_formimpl.cpp:
(HTMLFormElementImpl::attach): Fix a leak by getting the style from the render
object instead of calling styleForElement again, which makes a new one.
(HTMLFormElementImpl::parseAttribute): Ditto.
(HTMLInputElementImpl::attach): Fix a leak by using the style in the local
variable rather than calling styleForElement again.
* khtml/html/html_imageimpl.cpp:
(HTMLImageElementImpl::parseAttribute): Fix a leak by getting the style from the render
object instead of calling styleForElement again, which makes a new one.
(HTMLImageElementImpl::attach): Fix a leak by using the style in the local
variable rather than calling styleForElement again.
* khtml/html/html_inlineimpl.cpp: (HTMLBRElementImpl::attach):
Fix a leak in the display() == NONE case by ref'ing and deref'ing the style.
* khtml/html/html_objectimpl.cpp: (HTMLObjectElementImpl::attach): Fix a leak by using
the style in the local variable rather than calling styleForElement again.
* khtml/rendering/bidi.cpp:
(BidiIterator::detach): Added debugging code to detect if someone does a delete directly,
which will not deallocate the object because it won't run the correct arena code.
(BidiIterator::operator delete): Ditto.
(appendRunsForObject): Fix a leak by detaching bidi iterators when they are removed from
the list. The list can't delete them because it doesn't have the arena pointer.
(deleteMidpoints): Fix a leak by not removing the items from the list until done iterating.
The old code would fail to delete half the items.
* khtml/rendering/render_container.cpp:
(RenderContainer::detach): Detach the continuation here. Before we removed it but did not
detach it, which led to a leak.
(RenderContainer::removeChild): Do not remove the continuation here. If we do, then we can't
detach successfully. No one depends on this removing the continuation.
(RenderContainer::removeLeftoverAnonymousBoxes): Detach the child, don't just delete it.
This fixes a leak.
* khtml/rendering/render_flow.cpp: (RenderFlow::removeChild): Detach the child, don't just
delete it. This fixes a leak.
* khtml/rendering/render_object.h: Added arenaDelete.
* khtml/rendering/render_object.cpp:
(RenderObject::operator delete): Added debugging code to detect if someone does a delete directly,
which will not deallocate the object because it won't run the correct arena code.
(RenderObject::detach): Ditto.
(RenderObject::arenaDelete): Put the low-level delete here, so that subclasses (RenderWidget)
can call it.
* khtml/rendering/render_replaced.h: Add arenaDeref and make deref private so derived classes
won't use it by accident.
* khtml/rendering/render_replaced.cpp:
(RenderWidget::detach): Use the new arenaDeref instead of deref, since we need to pass the
arena pointer in to delete.
(RenderWidget::resizeWidget): Ditto. Store the arena before calling back, since we can't get it
once it's detached from its parent.
(RenderWidget::eventFilter): Ditto.
(RenderWidget::arenaDeref): Added. Calls RenderObject's arenaDelete.
- other changes
* khtml/rendering/render_arena.cpp:
(RenderArena::allocate): Added debugging code that stores a signature, arena pointer, and size,
and uses malloc rather than the arena.
(RenderArena::free): Check the signature, arena pointer, and size, and use free.
* khtml/rendering/render_layer.cpp:
(RenderLayer::operator delete): Added debugging code to detect if someone does a delete directly,
which will not deallocate the object because it won't run the correct arena code.
(RenderLayer::detach): Ditto.
(RenderLayer::RenderLayerElement::operator delete): Ditto.
(RenderLayer::RenderLayerElement::detach): Ditto.
(RenderLayer::RenderZTreeNode::operator delete): Ditto.
(RenderLayer::RenderZTreeNode::detach): Ditto.
* khtml/rendering/render_text.cpp:
(TextSlave::detach): Added debugging code to detect if someone does a delete directly,
which will not deallocate the object because it won't run the correct arena code.
(TextSlave::operator delete): Ditto.
* khtml/html/html_elementimpl.cpp: (HTMLElementImpl::createContextualFragment):
Save one new/delete by using a stack-based HTMLTokenizer and add FIXMEs about
some possible leaks I spotted here.
* khtml/rendering/render_list.cpp: (RenderListItem::setStyle): Took out APPLE_CHANGES from around
a generally useful bug fix.
* WebCore.pbproj/project.pbxproj: Let Electron be Electron.
=== Alexander-42 ===
2002-12-19 David Hyatt <hyatt@apple.com>
......
......@@ -66,6 +66,7 @@
F58C8A07025BD3BC018635CA,
F531DDEC02F0C34D018635CA,
);
hasScannedForEncodings = 1;
isa = PBXProject;
knownRegions = (
English,
......@@ -182,7 +183,6 @@
</dict>
</plist>
";
shouldUseHeadermap = 0;
};
0867D69DFE84028FC02AAC07 = {
buildActionMask = 2147483647;
......
......@@ -504,11 +504,13 @@ void HTMLFrameSetElementImpl::attach()
// ignore display: none but do pay attention if a stylesheet has caused us to delay
// our loading.
RenderStyle* style = getDocument()->styleSelector()->styleForElement(this);
style->ref();
if (style->isStyleAvailable()) {
m_render = new (getDocument()->renderArena()) RenderFrameSet(this);
m_render->setStyle(style);
parentNode()->renderer()->addChild(m_render, nextRenderer());
}
style->deref();
NodeBaseImpl::attach();
}
......
......@@ -316,11 +316,12 @@ DocumentFragmentImpl *HTMLElementImpl::createContextualFragment( const DOMString
return NULL;
DocumentFragmentImpl *fragment = new DocumentFragmentImpl( docPtr() );
HTMLTokenizer *tok = new HTMLTokenizer( docPtr(), fragment );
tok->begin();
tok->write( html.string(), true );
tok->end();
delete tok;
{
HTMLTokenizer tok( docPtr(), fragment );
tok.begin();
tok.write( html.string(), true );
tok.end();
}
// Exceptions are ignored because none ought to happen here.
int ignoredExceptionCode;
......@@ -336,20 +337,24 @@ DocumentFragmentImpl *HTMLElementImpl::createContextualFragment( const DOMString
NodeImpl *child = firstChild;
while (child != NULL) {
NodeImpl *nextChild = child->nextSibling();
fragment->insertBefore (child, node, ignoredExceptionCode);
fragment->insertBefore(child, node, ignoredExceptionCode);
// FIXME: Does node leak here?
child = nextChild;
}
if (firstChild == NULL) {
NodeImpl *nextNode = node->nextSibling();
fragment->removeChild(node, ignoredExceptionCode);
node = nextNode;
// FIXME: Does node leak here?
node = nextNode;
} else {
fragment->removeChild(node, ignoredExceptionCode);
// FIXME: Does node leak here?
node = firstChild;
}
} else if (node->id() == ID_HEAD) {
NodeImpl *nextNode = node->nextSibling();
fragment->removeChild(node, ignoredExceptionCode);
// FIXME: Does node leak here?
node = nextNode;
} else {
node = node->nextSibling();
......
......@@ -92,15 +92,13 @@ NodeImpl::Id HTMLFormElementImpl::id() const
void HTMLFormElementImpl::attach()
{
RenderStyle* style = getDocument()->styleSelector()->styleForElement(this);
HTMLElementImpl::attach();
if (style->display() != NONE && getDocument()->isHTMLDocument()) {
if (m_render && getDocument()->isHTMLDocument()) {
HTMLDocumentImpl *document = static_cast<HTMLDocumentImpl *>(getDocument());
document->addNamedImageOrForm(oldNameAttr);
document->addNamedImageOrForm(oldIdAttr);
}
HTMLElementImpl::attach();
}
void HTMLFormElementImpl::detach()
......@@ -533,11 +531,7 @@ void HTMLFormElementImpl::parseAttribute(AttributeImpl *attr)
case ATTR_NAME:
{
QString newNameAttr = attr->value().string();
if (attached() &&
getDocument()->isHTMLDocument() &&
getDocument()->styleSelector()->styleForElement(this)->display() != NONE) {
if (m_render && getDocument()->isHTMLDocument()) {
HTMLDocumentImpl *document = static_cast<HTMLDocumentImpl *>(getDocument());
document->removeNamedImageOrForm(oldNameAttr);
document->addNamedImageOrForm(newNameAttr);
......@@ -548,11 +542,7 @@ void HTMLFormElementImpl::parseAttribute(AttributeImpl *attr)
case ATTR_ID:
{
QString newIdAttr = attr->value().string();
if (attached() &&
getDocument()->isHTMLDocument() &&
getDocument()->styleSelector()->styleForElement(this)->display() != NONE) {
if (m_render && getDocument()->isHTMLDocument()) {
HTMLDocumentImpl *document = static_cast<HTMLDocumentImpl *>(getDocument());
document->removeNamedImageOrForm(oldIdAttr);
document->addNamedImageOrForm(newIdAttr);
......@@ -1243,26 +1233,26 @@ void HTMLInputElementImpl::attach()
{
case TEXT:
case PASSWORD:
case ISINDEX: m_render = new (arena) RenderLineEdit(this); break;
case CHECKBOX: m_render = new (arena) RenderCheckBox(this); break;
case RADIO: m_render = new (arena) RenderRadioButton(this); break;
case SUBMIT: m_render = new (arena) RenderSubmitButton(this); break;
case ISINDEX: m_render = new (arena) RenderLineEdit(this); break;
case CHECKBOX: m_render = new (arena) RenderCheckBox(this); break;
case RADIO: m_render = new (arena) RenderRadioButton(this); break;
case SUBMIT: m_render = new (arena) RenderSubmitButton(this); break;
case IMAGE: {
DOMString width = getAttribute( ATTR_WIDTH );
if (!width.isEmpty()) {
addCSSLength(CSS_PROP_WIDTH, width);
}
m_render = new (arena) RenderImageButton(this);
m_render->setStyle(getDocument()->styleSelector()->styleForElement(this));
m_render->setStyle(_style);
parentNode()->renderer()->addChild(m_render, nextRenderer());
m_render->updateFromElement();
NodeBaseImpl::attach();
_style->deref();
return;
}
case RESET: m_render = new (arena) RenderResetButton(this); break;
case FILE: m_render = new (arena) RenderFileButton(this); break;
case BUTTON: m_render = new (arena) RenderPushButton(this);
case RESET: m_render = new (arena) RenderResetButton(this); break;
case FILE: m_render = new (arena) RenderFileButton(this); break;
case BUTTON: m_render = new (arena) RenderPushButton(this); break;
case HIDDEN: break;
}
}
......
......@@ -138,27 +138,18 @@ void HTMLImageElementImpl::parseAttribute(AttributeImpl *attr)
case ATTR_NAME:
{
QString newNameAttr = attr->value().string();
if (attached() &&
getDocument()->isHTMLDocument() &&
getDocument()->styleSelector()->styleForElement(this)->display() != NONE) {
if (m_render && getDocument()->isHTMLDocument()) {
HTMLDocumentImpl *document = static_cast<HTMLDocumentImpl *>(getDocument());
document->removeNamedImageOrForm(oldNameAttr);
document->addNamedImageOrForm(newNameAttr);
}
oldNameAttr = newNameAttr;
}
break;
case ATTR_ID:
{
QString newIdAttr = attr->value().string();
if (attached() &&
getDocument()->isHTMLDocument() &&
getDocument()->styleSelector()->styleForElement(this)->display() != NONE) {
if (m_render && getDocument()->isHTMLDocument()) {
HTMLDocumentImpl *document = static_cast<HTMLDocumentImpl *>(getDocument());
document->removeNamedImageOrForm(oldIdAttr);
document->addNamedImageOrForm(newIdAttr);
......@@ -201,9 +192,10 @@ void HTMLImageElementImpl::attach()
RenderStyle* _style = getDocument()->styleSelector()->styleForElement(this);
_style->ref();
if (parentNode()->renderer() && _style->display() != NONE) {
m_render = new (getDocument()->renderArena()) RenderImage(this);
m_render->setStyle(getDocument()->styleSelector()->styleForElement(this));
m_render->setStyle(_style);
parentNode()->renderer()->addChild(m_render, nextRenderer());
m_render->updateFromElement();
}
......@@ -213,6 +205,7 @@ void HTMLImageElementImpl::attach()
document->addNamedImageOrForm(oldIdAttr);
document->addNamedImageOrForm(oldNameAttr);
}
_style->deref();
NodeBaseImpl::attach();
......
......@@ -223,11 +223,13 @@ void HTMLBRElementImpl::attach()
RenderObject *parentRenderer = parentNode()->renderer();
if (parentRenderer) {
RenderStyle *style = getDocument()->styleSelector()->styleForElement(this);
style->ref();
if (style->display() != NONE) {
m_render = new (getDocument()->renderArena()) RenderBR(this);
m_render->setStyle(style);
parentRenderer->addChild(m_render, nextRenderer());
}
style->deref();
}
NodeImpl::attach();
......
......@@ -343,7 +343,7 @@ void HTMLObjectElementImpl::attach()
if(serviceType.startsWith("image/") && parentNode()->renderer() && _style->display() != NONE){
m_render = new (getDocument()->renderArena()) RenderImage(this);
m_render->setStyle(getDocument()->styleSelector()->styleForElement(this));
m_render->setStyle(_style);
parentNode()->renderer()->addChild(m_render, nextRenderer());
m_render->updateFromElement();
loadplugin = false;
......
......@@ -55,13 +55,22 @@ static int numSpaces;
static void embed( QChar::Direction d );
static void appendRun();
#ifndef NDEBUG
static bool inBidiIteratorDetach;
#endif
void BidiIterator::detach(RenderArena* renderArena)
{
#ifndef NDEBUG
inBidiIteratorDetach = true;
#endif
delete this;
#ifndef NDEBUG
inBidiIteratorDetach = false;
#endif
// Now perform the destroy.
size_t* sz = (size_t*)this;
renderArena->free(*sz, (void*)this);
// Recover the size left there for us by operator delete and free the memory.
renderArena->free(*(size_t *)this, this);
}
void* BidiIterator::operator new(size_t sz, RenderArena* renderArena) throw()
......@@ -69,9 +78,12 @@ void* BidiIterator::operator new(size_t sz, RenderArena* renderArena) throw()
return renderArena->allocate(sz);
}
void BidiIterator::operator delete(void* ptr, size_t sz) {
size_t* szPtr = (size_t*)ptr;
*szPtr = sz;
void BidiIterator::operator delete(void* ptr, size_t sz)
{
assert(inBidiIteratorDetach);
// Stash size where detach can find it.
*(size_t*)ptr = sz;
}
// ---------------------------------------------------------------------
......@@ -264,6 +276,7 @@ static void appendRunsForObject(int start, int end, RenderObject* obj)
betweenMidpoints = false;
start = nextMidpoint->pos;
smidpoints->removeFirst(); // Delete the midpoint.
nextMidpoint->detach(obj->renderArena());
if (start < end)
return appendRunsForObject(start, end, obj);
}
......@@ -280,6 +293,7 @@ static void appendRunsForObject(int start, int end, RenderObject* obj)
betweenMidpoints = true;
int nextPos = nextMidpoint->pos+1;
smidpoints->removeFirst();
nextMidpoint->detach(obj->renderArena());
return appendRunsForObject(nextPos, end, obj);
}
else
......@@ -985,8 +999,8 @@ static void deleteMidpoints(RenderArena* arena, QPtrList<BidiIterator>* midpoint
BidiIterator* s = midpoints->at(i);
if (s)
s->detach(arena);
midpoints->remove(i);
}
midpoints->clear();
}
void RenderFlow::layoutInlineChildren(bool relayoutChildren)
......
......@@ -34,6 +34,18 @@
#include "render_arena.h"
#ifndef NDEBUG
const int signature = 0xDBA00AEA;
typedef struct {
RenderArena *arena;
size_t size;
int signature;
} RenderArenaDebugHeader;
#endif
RenderArena::RenderArena(unsigned int arenaSize)
{
// Initialize the arena pool
......@@ -51,6 +63,15 @@ RenderArena::~RenderArena()
void* RenderArena::allocate(size_t size)
{
#ifndef NDEBUG
// Use standard malloc so that memory debugging tools work.
void *block = ::malloc(sizeof(RenderArenaDebugHeader) + size);
RenderArenaDebugHeader *header = (RenderArenaDebugHeader *)block;
header->arena = this;
header->size = size;
header->signature = signature;
return header + 1;
#else
void* result = 0;
// Ensure we have correct alignment for pointers. Important for Tru64
......@@ -74,18 +95,19 @@ void* RenderArena::allocate(size_t size)
}
return result;
#endif
}
void RenderArena::free(size_t size, void* ptr)
{
#if APPLE_CHANGES
#ifndef NDEBUG
// Mark the memory with 0xdd in DEBUG builds so that there will be
// problems if someone tries to access memory that they've freed.
memset(ptr, 0xdd, size);
#endif
#endif
// Use standard free so that memory debugging tools work.
RenderArenaDebugHeader *header = (RenderArenaDebugHeader *)ptr - 1;
assert(header->signature == signature);
assert(header->size == size);
assert(header->arena == this);
::free(header);
#else
// Ensure we have correct alignment for pointers. Important for Tru64
size = ROUNDUP(size, sizeof(void*));
......@@ -96,4 +118,5 @@ void RenderArena::free(size_t size, void* ptr)
m_recyclers[index] = ptr;
*((void**)ptr) = currentTop;
}
#endif
}
......@@ -50,6 +50,9 @@ RenderContainer::~RenderContainer()
void RenderContainer::detach(RenderArena* renderArena)
{
if (continuation())
continuation()->detach(renderArena);
RenderObject* next;
for(RenderObject* n = m_first; n; n = next ) {
n->removeFromSpecialObjects();
......@@ -191,9 +194,6 @@ RenderObject* RenderContainer::removeChildNode(RenderObject* oldChild)
void RenderContainer::removeChild(RenderObject *oldChild)
{
if (oldChild->continuation())
oldChild->continuation()->parent()->removeChild(oldChild->continuation());
removeChildNode(oldChild);
setLayouted(false);
}
......@@ -355,7 +355,7 @@ void RenderContainer::removeLeftoverAnonymousBoxes()
c->m_first = 0;
c->m_next = 0;
}
delete child;
child->detach(renderArena());
}
child = next;
}
......
......@@ -2238,7 +2238,7 @@ void RenderFlow::removeChild(RenderObject *oldChild)
prev->setMinMaxKnown(false);
// Nuke the now-empty block.
removeChild(next);
next->detach(renderArena());
mergedBlocks = true;
}
......
......@@ -52,6 +52,12 @@
using namespace DOM;
using namespace khtml;
#ifndef NDEBUG
static bool inRenderLayerDetach;
static bool inRenderLayerElementDetach;
static bool inRenderZTreeNodeDetach;
#endif
RenderLayer::RenderLayer(RenderObject* object)
: m_object( object ),
m_parent( 0 ),
......@@ -116,19 +122,26 @@ void* RenderLayer::operator new(size_t sz, RenderArena* renderArena) throw()
return renderArena->allocate(sz