Reviewed by Anders.
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Jul 2006 09:39:27 +0000 (09:39 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Jul 2006 09:39:27 +0000 (09:39 +0000)
        - fix 26 Node leaks on various fast/dom tests

        * dom/Document.cpp:
        (WebCore::Document::removedLastRef): Delete the tokenizer here, since if we are in mid-parse,
        the parser might hold refs on some of our children that have self-only refs.
        * html/HTMLParser.cpp:
        (WebCore::HTMLStackElem::HTMLStackElem): don't ref the node if it is a document to avoid ref cycles
        (WebCore::HTMLStackElem::~HTMLStackElem): ditto
        (WebCore::HTMLStackElem::node): changed interface a bit to support the above
        (WebCore::HTMLStackElem::setNode): ditto
        (WebCore::HTMLParser::popNestedHeaderTag): use new interface to HTMLStackElem
        (WebCore::HTMLParser::handleResidualStyleCloseTagAcrossBlocks): ditto
        (WebCore::HTMLParser::reopenResidualStyleTags): ditto
        (WebCore::HTMLParser::popBlock): ditto
        (WebCore::HTMLParser::popOneBlock): ditto

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@15182 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/dom/Document.cpp
WebCore/html/HTMLParser.cpp

index 4ab1831c7c9bc1a2b786961cb0813c495138cfe0..70375d27790a47347af4e97f94129c625fa60c27 100644 (file)
@@ -1,4 +1,25 @@
-2006-07-06  Mitz Pettel  <opendarwin.org@mitzpettel.com>\r
+2006-07-06  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Anders.
+
+        - fix 26 Node leaks on various fast/dom tests
+
+        * dom/Document.cpp:
+        (WebCore::Document::removedLastRef): Delete the tokenizer here, since if we are in mid-parse,
+        the parser might hold refs on some of our children that have self-only refs.
+        * html/HTMLParser.cpp:
+        (WebCore::HTMLStackElem::HTMLStackElem): don't ref the node if it is a document to avoid ref cycles
+        (WebCore::HTMLStackElem::~HTMLStackElem): ditto
+        (WebCore::HTMLStackElem::node): changed interface a bit to support the above
+        (WebCore::HTMLStackElem::setNode): ditto
+        (WebCore::HTMLParser::popNestedHeaderTag): use new interface to HTMLStackElem
+        (WebCore::HTMLParser::handleResidualStyleCloseTagAcrossBlocks): ditto
+        (WebCore::HTMLParser::reopenResidualStyleTags): ditto
+        (WebCore::HTMLParser::popBlock): ditto
+        (WebCore::HTMLParser::popOneBlock): ditto
+
+2006-07-06  Mitz Pettel  <opendarwin.org@mitzpettel.com>
+
         Reviewed by Adele.
         
         * rendering/RenderMenuList.h:
index b9480075b3ce20a629214834f3b7a99da453fb13..001cfcdba0d10e583778f7e2448f829392e1d893 100644 (file)
@@ -304,6 +304,9 @@ void Document::removedLastRef()
         removeAllChildren();
 
         m_markers.clear();
+
+        delete m_tokenizer;
+        m_tokenizer = 0;
     } else
         delete this;
 }
index bf4322ec60dd1fe406d219944586664207326f78..6e8f8b45ce70b3f6effb3c7984f55cb98be9ee1e 100644 (file)
@@ -71,15 +71,37 @@ public:
         tagName(_tagName),
         level(_level),
         strayTableContent(false),
-        node(_node),
-        next(_next)
-        { }
+        nodeIsRefd(!_node->isDocumentNode()),
+        next(_next),
+        m_node(_node)
+    { 
+        if (nodeIsRefd)
+            m_node->ref();
+    }
+
+    ~HTMLStackElem()
+    {
+        if (nodeIsRefd)
+            m_node->deref();
+    }
+
+    Node* node() { return m_node; }
+    void setNode(Node* _node)
+    {
+        if (nodeIsRefd)
+            m_node->deref();
+        nodeIsRefd = !_node->isDocumentNode();
+        m_node = _node;
+    }
 
     AtomicString tagName;
     int level;
     bool strayTableContent;
-    RefPtr<Node> node;
+    bool nodeIsRefd;
     HTMLStackElem* next;
+
+private:
+    Node* m_node;
 };
 
 /**
@@ -863,7 +885,7 @@ void HTMLParser::popNestedHeaderTag()
         }
         if (currNode && !isInline(currNode))
             return;
-        currNode = curr->node.get();
+        currNode = curr->node();
     }
 }
 
@@ -974,9 +996,9 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
 
     if (!curr || !maxElem || !isAffectedByResidualStyle(maxElem->tagName)) return;
 
-    Node* residualElem = prev->node.get();
-    Node* blockElem = prevMaxElem ? prevMaxElem->node.get() : current;
-    Node* parentElem = elem->node.get();
+    Node* residualElem = prev->node();
+    Node* blockElem = prevMaxElem ? prevMaxElem->node() : current;
+    Node* parentElem = elem->node();
 
     // Check to see if the reparenting that is going to occur is allowed according to the DOM.
     // FIXME: We should either always allow it or perform an additional fixup instead of
@@ -985,7 +1007,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
     if (!parentElem->childAllowed(blockElem))
         return;
     
-    if (maxElem->node->parentNode() != elem->node) {
+    if (maxElem->node()->parentNode() != elem->node()) {
         // Walk the stack and remove any elements that aren't residual style tags.  These
         // are basically just being closed up.  Example:
         // <font><span>Moo<p>Goo</font></p>.
@@ -996,7 +1018,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
             HTMLStackElem* nextElem = currElem->next;
             if (!isResidualStyleTag(currElem->tagName)) {
                 prevElem->next = nextElem;
-                prevElem->node = currElem->node;
+                prevElem->setNode(currElem->node());
                 delete currElem;
             }
             else
@@ -1014,13 +1036,13 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
         // under the reopened residual tags (e.g., the <i> in the above example.)
         Node* prevNode = 0;
         currElem = maxElem;
-        while (currElem->node != residualElem) {
-            if (isResidualStyleTag(currElem->node->localName())) {
+        while (currElem->node() != residualElem) {
+            if (isResidualStyleTag(currElem->node()->localName())) {
                 // Create a clone of this element.
-                RefPtr<Node> currNode = currElem->node->cloneNode(false);
+                RefPtr<Node> currNode = currElem->node()->cloneNode(false);
 
                 // Change the stack element's node to point to the clone.
-                currElem->node = currNode;
+                currElem->setNode(currNode.get());
                 
                 // Attach the previous node as a child of this new node.
                 if (prevNode)
@@ -1036,7 +1058,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
 
         // Now append the chain of new residual style elements if one exists.
         if (prevNode)
-            elem->node->appendChild(prevNode, ec);
+            elem->node()->appendChild(prevNode, ec);
     }
          
     // Check if the block is still in the tree. If it isn't, then we don't
@@ -1088,7 +1110,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
         currElem = currElem->next;
     }
     prevElem->next = elem->next;
-    prevElem->node = elem->node;
+    prevElem->setNode(elem->node());
     delete elem;
     
     // Step 7: Reopen intermediate inlines, e.g., <b><p><i>Foo</b>Goo</p>.
@@ -1109,7 +1131,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
             // curr->id rather than the node that you should pop to when the element gets pulled off
             // the stack.
             popOneBlock(false);
-            curr->node = currNode;
+            curr->setNode(currNode);
             curr->next = residualStyleStack;
             residualStyleStack = curr;
         }
@@ -1131,7 +1153,7 @@ void HTMLParser::reopenResidualStyleTags(HTMLStackElem* elem, Node* malformedTab
     // Loop for each tag that needs to be reopened.
     while (elem) {
         // Create a shallow clone of the DOM node for this element.
-        RefPtr<Node> newNode = elem->node->cloneNode(false); 
+        RefPtr<Node> newNode = elem->node()->cloneNode(false); 
 
         // Append the new node. In the malformed table case, we need to insert before the table,
         // which will be the last child.
@@ -1236,7 +1258,7 @@ void HTMLParser::popBlock(const AtomicString& _tagName)
                 // the stack.
                 popOneBlock(false);
                 Elem->next = residualStyleStack;
-                Elem->node = currNode;
+                Elem->setNode(currNode);
                 residualStyleStack = Elem;
             }
             else
@@ -1254,11 +1276,11 @@ void HTMLParser::popOneBlock(bool delBlock)
 
     // Form elements restore their state during the parsing process.
     // Also, a few elements (<applet>, <object>) need to know when all child elements (<param>s) are available.
-    if (current && elem->node != current)
+    if (current && elem->node() != current)
         current->closeRenderer();
 
     blockStack = elem->next;
-    setCurrent(elem->node.get());
+    setCurrent(elem->node());
 
     if (elem->strayTableContent)
         inStrayTableContent--;