Changeset 116402 in webkit


Ignore:
Timestamp:
May 8, 2012 1:31:29 AM (12 years ago)
Author:
Antti Koivisto
Message:

Inline Node::traverseNextNode
https://bugs.webkit.org/show_bug.cgi?id=85844

Reviewed by Ryosuke Niwa.

Inline traverseNextNode and traverseNextSibling to reduce entry/exit overhead and allow better code generation
for many hot loops. Also added separate versions of stayWithin and unscoped cases (the function is
so simple that this seemed like the cleanest way to do it, the most reliable too) and used UNLIKELY for the
end-of-traversal conditions.

The traversal function can show up to ~1% in normal page loading profiles.

run-perf-tests seems to think this is a progression in some subtests though bots will tell for certain.

  • WebCore.exp.in:
  • dom/ContainerNode.h:


Following the existing pattern, function bodies go to ContainerNode.h so they can call parentNode().
(which returns ContainerNode, not Node).

(WebCore::Node::traverseNextNode):
(WebCore):
(WebCore::Node::traverseNextSibling):

  • dom/Node.cpp:

(WebCore):

  • dom/Node.h:

(Node):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r116398 r116402  
     12012-05-07  Antti Koivisto  <antti@apple.com>
     2
     3        Inline Node::traverseNextNode
     4        https://bugs.webkit.org/show_bug.cgi?id=85844
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Inline traverseNextNode and traverseNextSibling to reduce entry/exit overhead and allow better code generation
     9        for many hot loops. Also added separate versions of stayWithin and unscoped cases (the function is
     10        so simple that this seemed like the cleanest way to do it, the most reliable too) and used UNLIKELY for the
     11        end-of-traversal conditions.
     12       
     13        The traversal function can show up to ~1% in normal page loading profiles.
     14       
     15        run-perf-tests seems to think this is a progression in some subtests though bots will tell for certain.
     16
     17        * WebCore.exp.in:
     18        * dom/ContainerNode.h:
     19       
     20            Following the existing pattern, function bodies go to ContainerNode.h so they can call parentNode().
     21            (which returns ContainerNode, not Node).
     22
     23        (WebCore::Node::traverseNextNode):
     24        (WebCore):
     25        (WebCore::Node::traverseNextSibling):
     26        * dom/Node.cpp:
     27        (WebCore):
     28        * dom/Node.h:
     29        (Node):
     30
    1312012-05-05  Pavel Feldman  <pfeldman@chromium.org>
    232
  • trunk/Source/WebCore/WebCore.exp.in

    r116371 r116402  
    20972097__ZN7WebCore8Document22setAnimatingFullScreenEb
    20982098__ZNK7WebCore8Document9domWindowEv
    2099 __ZNK7WebCore4Node16traverseNextNodeEPKS0_
    21002099#endif
    21012100
  • trunk/Source/WebCore/bindings/v8/RetainedDOMInfo.cpp

    r110164 r116402  
    3232#include "RetainedDOMInfo.h"
    3333
    34 #include "Node.h"
     34#include "ContainerNode.h"
    3535
    3636namespace WebCore {
  • trunk/Source/WebCore/dom/ContainerNode.h

    r114351 r116402  
    229229}
    230230
     231inline Node* Node::traverseNextNode() const
     232{
     233    if (firstChild())
     234        return firstChild();
     235    if (nextSibling())
     236        return nextSibling();
     237    const Node* node = this;
     238    while (node && !node->nextSibling())
     239        node = node->parentNode();
     240    if (UNLIKELY(!node))
     241        return 0;
     242    return node->nextSibling();
     243}
     244
     245inline Node* Node::traverseNextNode(const Node* stayWithin) const
     246{
     247    if (firstChild())
     248        return firstChild();
     249    if (UNLIKELY(this == stayWithin))
     250        return 0;
     251    if (nextSibling())
     252        return nextSibling();
     253    const Node* node = this;
     254    while (node && !node->nextSibling() && (!stayWithin || node->parentNode() != stayWithin))
     255        node = node->parentNode();
     256    if (UNLIKELY(!node))
     257        return 0;
     258    return node->nextSibling();
     259}
     260
     261inline Node* Node::traverseNextSibling() const
     262{
     263    if (nextSibling())
     264        return nextSibling();
     265    const Node* node = this;
     266    while (node && !node->nextSibling())
     267        node = node->parentNode();
     268    if (UNLIKELY(!node))
     269        return 0;
     270    return node->nextSibling();
     271}
     272
     273inline Node* Node::traverseNextSibling(const Node* stayWithin) const
     274{
     275    if (UNLIKELY(this == stayWithin))
     276        return 0;
     277    if (nextSibling())
     278        return nextSibling();
     279    const Node* node = this;
     280    while (node && !node->nextSibling() && (!stayWithin || node->parentNode() != stayWithin))
     281        node = node->parentNode();
     282    if (UNLIKELY(!node))
     283        return 0;
     284    return node->nextSibling();
     285}
     286
    231287typedef Vector<RefPtr<Node>, 11> NodeVector;
    232288
  • trunk/Source/WebCore/dom/Node.cpp

    r116277 r116402  
    10851085}
    10861086
    1087 Node* Node::traverseNextNode(const Node* stayWithin) const
    1088 {
    1089     if (firstChild())
    1090         return firstChild();
    1091     if (this == stayWithin)
    1092         return 0;
    1093     if (nextSibling())
    1094         return nextSibling();
    1095     const Node *n = this;
    1096     while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin))
    1097         n = n->parentNode();
    1098     if (n)
    1099         return n->nextSibling();
    1100     return 0;
    1101 }
    1102 
    1103 Node* Node::traverseNextSibling(const Node* stayWithin) const
    1104 {
    1105     if (this == stayWithin)
    1106         return 0;
    1107     if (nextSibling())
    1108         return nextSibling();
    1109     const Node *n = this;
    1110     while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin))
    1111         n = n->parentNode();
    1112     if (n)
    1113         return n->nextSibling();
    1114     return 0;
    1115 }
    1116 
    11171087Node* Node::traverseNextNodePostOrder() const
    11181088{
  • trunk/Source/WebCore/dom/Node.h

    r114806 r116402  
    428428    // argument is non-null, the traversal will stop once the specified node is reached.
    429429    // This can be used to restrict traversal to a particular sub-tree.
    430     Node* traverseNextNode(const Node* stayWithin = 0) const;
     430    Node* traverseNextNode() const;
     431    Node* traverseNextNode(const Node* stayWithin) const;
    431432
    432433    // Like traverseNextNode, but skips children and starts with the next sibling.
    433     Node* traverseNextSibling(const Node* stayWithin = 0) const;
     434    Node* traverseNextSibling() const;
     435    Node* traverseNextSibling(const Node* stayWithin) const;
    434436
    435437    // Does a reverse pre-order traversal to find the node that comes before the current one in document order
Note: See TracChangeset for help on using the changeset viewer.