Changeset 148754 in webkit


Ignore:
Timestamp:
Apr 19, 2013 10:25:54 AM (11 years ago)
Author:
abucur@adobe.com
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):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r148753 r148754  
     12013-04-19  Andrei Bucur  <abucur@adobe.com>
     2
     3        ContainerNode::removeChildren should first detach the children then remove them
     4        https://bugs.webkit.org/show_bug.cgi?id=113433
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Currently, ContainerNode::removeChildren initially removes the nodes from the DOM tree and then
     9        calls detach() on each of them. This is anti-intuitive and can lead to subtle bugs because the
     10        detached renderers are not backed by a valid DOM tree any more. With the patch, the nodes are first
     11        detached and then removed from the DOM.
     12        The patch also lets the tree in a consistent state after each node removal by clearing the previous
     13        sibling pointer of the node following the one removed.
     14        I haven't found any proof the performance will get worse if the detachment happens when the children
     15        are still in the DOM tree.
     16
     17        Tests: No changed visible functionality.
     18
     19        * dom/ContainerNode.cpp:
     20        (WebCore::ContainerNode::removeChildren):
     21
    1222013-04-19  Dirk Schulze  <krit@webkit.org>
    223
  • trunk/Source/WebCore/dom/ContainerNode.cpp

    r148545 r148754  
    617617                Node* next = n->nextSibling();
    618618
    619                 // Remove the node from the tree before calling detach or removedFromDocument (4427024, 4129744).
    620                 // removeChild() does this after calling detach(). There is no explanation for
    621                 // this discrepancy between removeChild() and its optimized version removeChildren().
     619                if (n->attached())
     620                    n->detach();
     621
    622622                n->setPreviousSibling(0);
    623623                n->setNextSibling(0);
     
    628628                if (n == m_lastChild)
    629629                    m_lastChild = 0;
     630                else
     631                    m_firstChild->setPreviousSibling(0);
     632
    630633                removedChildren.append(n.release());
    631             }
    632 
    633             // Detach the nodes only after properly removed from the tree because
    634             // a. detaching requires a proper DOM tree (for counters and quotes for
    635             // example) and during the previous loop the next sibling still points to
    636             // the node being removed while the node being removed does not point back
    637             // and does not point to the same parent as its next sibling.
    638             // b. destroying Renderers of standalone nodes is sometimes faster.
    639             for (size_t i = 0; i < removedChildren.size(); ++i) {
    640                 Node* removedChild = removedChildren[i].get();
    641                 if (removedChild->attached())
    642                     removedChild->detach();
    643634            }
    644635        }
Note: See TracChangeset for help on using the changeset viewer.