Changeset 228729 in webkit


Ignore:
Timestamp:
Feb 19, 2018 10:09:13 PM (6 years ago)
Author:
Antti Koivisto
Message:

Use selector filter when invalidating descendants
https://bugs.webkit.org/show_bug.cgi?id=182839
<rdar://problem/37581072>

Reviewed by Zalan Bujtas.

We can make descendant invalidation faster by enabling filtering.

  • css/SelectorFilter.cpp:

(WebCore::SelectorFilter::initializeParentStack):

Traverse and reverse the ancestor chain, and push it.

(WebCore::SelectorFilter::pushParent):
(WebCore::SelectorFilter::pushParentInitializingIfNeeded):

Add a version of pushParent that can initialize the stack.

(WebCore::SelectorFilter::popParent):
(WebCore::SelectorFilter::popParentsUntil):

Pop until a given parent element.

(WebCore::SelectorFilter::pushParentStackFrame): Deleted.
(WebCore::SelectorFilter::popParentStackFrame): Deleted.

These were the same as push/popParent.

  • css/SelectorFilter.h:

(WebCore::SelectorFilter::popParent): Deleted.

  • style/StyleInvalidator.cpp:

(WebCore::Style::Invalidator::invalidateStyleForDescendants):

Use pushParentInitializingIfNeeded.

(WebCore::Style::Invalidator::invalidateStyleWithMatchElement):

Use selector filter when doing descendant tree invalidation.
Make sure to pop it until the parent when reusing.

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r228724 r228729  
     12018-02-19  Antti Koivisto  <antti@apple.com>
     2
     3        Use selector filter when invalidating descendants
     4        https://bugs.webkit.org/show_bug.cgi?id=182839
     5        <rdar://problem/37581072>
     6
     7        Reviewed by Zalan Bujtas.
     8
     9        We can make descendant invalidation faster by enabling filtering.
     10
     11        * css/SelectorFilter.cpp:
     12        (WebCore::SelectorFilter::initializeParentStack):
     13
     14            Traverse and reverse the ancestor chain, and push it.
     15
     16        (WebCore::SelectorFilter::pushParent):
     17        (WebCore::SelectorFilter::pushParentInitializingIfNeeded):
     18
     19            Add a version of pushParent that can initialize the stack.
     20
     21        (WebCore::SelectorFilter::popParent):
     22        (WebCore::SelectorFilter::popParentsUntil):
     23
     24            Pop until a given parent element.
     25
     26        (WebCore::SelectorFilter::pushParentStackFrame): Deleted.
     27        (WebCore::SelectorFilter::popParentStackFrame): Deleted.
     28
     29            These were the same as push/popParent.
     30
     31        * css/SelectorFilter.h:
     32        (WebCore::SelectorFilter::popParent): Deleted.
     33        * style/StyleInvalidator.cpp:
     34        (WebCore::Style::Invalidator::invalidateStyleForDescendants):
     35
     36            Use pushParentInitializingIfNeeded.
     37
     38        (WebCore::Style::Invalidator::invalidateStyleWithMatchElement):
     39
     40            Use selector filter when doing descendant tree invalidation.
     41            Make sure to pop it until the parent when reusing.
     42
    1432018-02-19  Fujii Hironori  <Hironori.Fujii@sony.com>
    244
  • trunk/Source/WebCore/css/SelectorFilter.cpp

    r225596 r228729  
    6464}
    6565
    66 void SelectorFilter::pushParentStackFrame(Element* parent)
     66void SelectorFilter::initializeParentStack(Element& parent)
     67{
     68    Vector<Element*, 20> ancestors;
     69    for (auto* ancestor = &parent; ancestor; ancestor = ancestor->parentElement())
     70        ancestors.append(ancestor);
     71    for (unsigned i = ancestors.size(); i--;)
     72        pushParent(ancestors[i]);
     73}
     74
     75void SelectorFilter::pushParent(Element* parent)
    6776{
    6877    ASSERT(m_parentStack.isEmpty() || m_parentStack.last().element == parent->parentElement());
     
    7887}
    7988
    80 void SelectorFilter::popParentStackFrame()
     89void SelectorFilter::pushParentInitializingIfNeeded(Element& parent)
     90{
     91    if (UNLIKELY(m_parentStack.isEmpty())) {
     92        initializeParentStack(parent);
     93        return;
     94    }
     95    pushParent(&parent);
     96}
     97
     98void SelectorFilter::popParent()
    8199{
    82100    ASSERT(!m_parentStack.isEmpty());
     
    92110}
    93111
    94 void SelectorFilter::pushParent(Element* parent)
    95 {
    96     pushParentStackFrame(parent);
     112void SelectorFilter::popParentsUntil(Element* parent)
     113{
     114    while (!m_parentStack.isEmpty()) {
     115        if (parent && m_parentStack.last().element == parent)
     116            return;
     117        popParent();
     118    }
    97119}
    98120
  • trunk/Source/WebCore/css/SelectorFilter.h

    r225596 r228729  
    4040class SelectorFilter {
    4141public:
    42     void pushParentStackFrame(Element* parent);
    43     void popParentStackFrame();
    44 
    4542    void pushParent(Element* parent);
    46     void popParent() { popParentStackFrame(); }
     43    void pushParentInitializingIfNeeded(Element& parent);
     44    void popParent();
     45    void popParentsUntil(Element* parent);
    4746    bool parentStackIsEmpty() const { return m_parentStack.isEmpty(); }
    4847    bool parentStackIsConsistent(const ContainerNode* parentNode) const;
     
    5352
    5453private:
     54    void initializeParentStack(Element& parent);
     55
    5556    struct ParentStackFrame {
    5657        ParentStackFrame() : element(0) { }
  • trunk/Source/WebCore/style/StyleInvalidator.cpp

    r228497 r228729  
    159159                parentStack.append(parent);
    160160                if (filter)
    161                     filter->pushParent(parent);
     161                    filter->pushParentInitializingIfNeeded(*parent);
    162162            } else {
    163163                while (parentStack.last() != parent) {
     
    224224    }
    225225    case MatchElement::Ancestor: {
    226         invalidateStyleForDescendants(element, nullptr);
     226        SelectorFilter filter;
     227        invalidateStyleForDescendants(element, &filter);
    227228        break;
    228229    }
     
    248249        }
    249250        break;
    250     case MatchElement::AncestorSibling:
    251         for (auto* sibling = element.nextElementSibling(); sibling; sibling = sibling->nextElementSibling())
    252             invalidateStyleForDescendants(*sibling, nullptr);
    253         break;
     251    case MatchElement::AncestorSibling: {
     252        SelectorFilter filter;
     253        for (auto* sibling = element.nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) {
     254            filter.popParentsUntil(element.parentElement());
     255            invalidateStyleForDescendants(*sibling, &filter);
     256        }
     257        break;
     258    }
    254259    case MatchElement::Host:
    255260        // FIXME: Handle this here as well.
Note: See TracChangeset for help on using the changeset viewer.