Title: [148754] trunk/Source/WebCore
Revision
148754
Author
[email protected]
Date
2013-04-19 10:25:54 -0700 (Fri, 19 Apr 2013)

Log Message

ContainerNode::removeChildren should first detach the children then remove them
https://bugs.webkit.org/show_bug.cgi?id=113433

Reviewed by Ryosuke Niwa.

Currently, ContainerNode::removeChildren initially removes the nodes from the DOM tree and then
calls detach() on each of them. This is anti-intuitive and can lead to subtle bugs because the
detached renderers are not backed by a valid DOM tree any more. With the patch, the nodes are first
detached and then removed from the DOM.
The patch also lets the tree in a consistent state after each node removal by clearing the previous
sibling pointer of the node following the one removed.
I haven't found any proof the performance will get worse if the detachment happens when the children
are still in the DOM tree.

Tests: No changed visible functionality.

* dom/ContainerNode.cpp:
(WebCore::ContainerNode::removeChildren):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (148753 => 148754)


--- trunk/Source/WebCore/ChangeLog	2013-04-19 17:17:42 UTC (rev 148753)
+++ trunk/Source/WebCore/ChangeLog	2013-04-19 17:25:54 UTC (rev 148754)
@@ -1,3 +1,24 @@
+2013-04-19  Andrei Bucur  <[email protected]>
+
+        ContainerNode::removeChildren should first detach the children then remove them
+        https://bugs.webkit.org/show_bug.cgi?id=113433
+
+        Reviewed by Ryosuke Niwa.
+
+        Currently, ContainerNode::removeChildren initially removes the nodes from the DOM tree and then
+        calls detach() on each of them. This is anti-intuitive and can lead to subtle bugs because the
+        detached renderers are not backed by a valid DOM tree any more. With the patch, the nodes are first
+        detached and then removed from the DOM.
+        The patch also lets the tree in a consistent state after each node removal by clearing the previous
+        sibling pointer of the node following the one removed.
+        I haven't found any proof the performance will get worse if the detachment happens when the children
+        are still in the DOM tree.
+
+        Tests: No changed visible functionality.
+
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::removeChildren):
+
 2013-04-19  Dirk Schulze  <[email protected]>
 
         Refactor transform code in StyleResolver

Modified: trunk/Source/WebCore/dom/ContainerNode.cpp (148753 => 148754)


--- trunk/Source/WebCore/dom/ContainerNode.cpp	2013-04-19 17:17:42 UTC (rev 148753)
+++ trunk/Source/WebCore/dom/ContainerNode.cpp	2013-04-19 17:25:54 UTC (rev 148754)
@@ -616,9 +616,9 @@
             while (RefPtr<Node> n = m_firstChild) {
                 Node* next = n->nextSibling();
 
-                // Remove the node from the tree before calling detach or removedFromDocument (4427024, 4129744).
-                // removeChild() does this after calling detach(). There is no explanation for
-                // this discrepancy between removeChild() and its optimized version removeChildren().
+                if (n->attached())
+                    n->detach();
+
                 n->setPreviousSibling(0);
                 n->setNextSibling(0);
                 n->setParentOrShadowHostNode(0);
@@ -627,20 +627,11 @@
                 m_firstChild = next;
                 if (n == m_lastChild)
                     m_lastChild = 0;
+                else
+                    m_firstChild->setPreviousSibling(0);
+
                 removedChildren.append(n.release());
             }
-
-            // Detach the nodes only after properly removed from the tree because
-            // a. detaching requires a proper DOM tree (for counters and quotes for
-            // example) and during the previous loop the next sibling still points to
-            // the node being removed while the node being removed does not point back
-            // and does not point to the same parent as its next sibling.
-            // b. destroying Renderers of standalone nodes is sometimes faster.
-            for (size_t i = 0; i < removedChildren.size(); ++i) {
-                Node* removedChild = removedChildren[i].get();
-                if (removedChild->attached())
-                    removedChild->detach();
-            }
         }
 
         childrenChanged(false, 0, 0, -static_cast<int>(removedChildren.size()));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to