Title: [228729] trunk/Source/WebCore
Revision
228729
Author
an...@apple.com
Date
2018-02-19 22:09:13 -0800 (Mon, 19 Feb 2018)

Log 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.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (228728 => 228729)


--- trunk/Source/WebCore/ChangeLog	2018-02-20 05:01:57 UTC (rev 228728)
+++ trunk/Source/WebCore/ChangeLog	2018-02-20 06:09:13 UTC (rev 228729)
@@ -1,3 +1,45 @@
+2018-02-19  Antti Koivisto  <an...@apple.com>
+
+        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.
+
 2018-02-19  Fujii Hironori  <hironori.fu...@sony.com>
 
         null m_lastNodeInserted dereference at ReplaceSelectionCommand::InsertedNodes::lastLeafInserted

Modified: trunk/Source/WebCore/css/SelectorFilter.cpp (228728 => 228729)


--- trunk/Source/WebCore/css/SelectorFilter.cpp	2018-02-20 05:01:57 UTC (rev 228728)
+++ trunk/Source/WebCore/css/SelectorFilter.cpp	2018-02-20 06:09:13 UTC (rev 228729)
@@ -63,8 +63,17 @@
     return !m_parentStack.isEmpty() && m_parentStack.last().element == parentNode;
 }
 
-void SelectorFilter::pushParentStackFrame(Element* parent)
+void SelectorFilter::initializeParentStack(Element& parent)
 {
+    Vector<Element*, 20> ancestors;
+    for (auto* ancestor = &parent; ancestor; ancestor = ancestor->parentElement())
+        ancestors.append(ancestor);
+    for (unsigned i = ancestors.size(); i--;)
+        pushParent(ancestors[i]);
+}
+
+void SelectorFilter::pushParent(Element* parent)
+{
     ASSERT(m_parentStack.isEmpty() || m_parentStack.last().element == parent->parentElement());
     ASSERT(!m_parentStack.isEmpty() || !parent->parentElement());
     m_parentStack.append(ParentStackFrame(parent));
@@ -77,8 +86,17 @@
         m_ancestorIdentifierFilter.add(parentFrame.identifierHashes[i]);
 }
 
-void SelectorFilter::popParentStackFrame()
+void SelectorFilter::pushParentInitializingIfNeeded(Element& parent)
 {
+    if (UNLIKELY(m_parentStack.isEmpty())) {
+        initializeParentStack(parent);
+        return;
+    }
+    pushParent(&parent);
+}
+
+void SelectorFilter::popParent()
+{
     ASSERT(!m_parentStack.isEmpty());
     const ParentStackFrame& parentFrame = m_parentStack.last();
     size_t count = parentFrame.identifierHashes.size();
@@ -91,9 +109,13 @@
     }
 }
 
-void SelectorFilter::pushParent(Element* parent)
+void SelectorFilter::popParentsUntil(Element* parent)
 {
-    pushParentStackFrame(parent);
+    while (!m_parentStack.isEmpty()) {
+        if (parent && m_parentStack.last().element == parent)
+            return;
+        popParent();
+    }
 }
 
 struct CollectedSelectorHashes {

Modified: trunk/Source/WebCore/css/SelectorFilter.h (228728 => 228729)


--- trunk/Source/WebCore/css/SelectorFilter.h	2018-02-20 05:01:57 UTC (rev 228728)
+++ trunk/Source/WebCore/css/SelectorFilter.h	2018-02-20 06:09:13 UTC (rev 228729)
@@ -39,11 +39,10 @@
 
 class SelectorFilter {
 public:
-    void pushParentStackFrame(Element* parent);
-    void popParentStackFrame();
-
     void pushParent(Element* parent);
-    void popParent() { popParentStackFrame(); }
+    void pushParentInitializingIfNeeded(Element& parent);
+    void popParent();
+    void popParentsUntil(Element* parent);
     bool parentStackIsEmpty() const { return m_parentStack.isEmpty(); }
     bool parentStackIsConsistent(const ContainerNode* parentNode) const;
 
@@ -52,6 +51,8 @@
     static Hashes collectHashes(const CSSSelector&);
 
 private:
+    void initializeParentStack(Element& parent);
+
     struct ParentStackFrame {
         ParentStackFrame() : element(0) { }
         ParentStackFrame(Element* element) : element(element) { }

Modified: trunk/Source/WebCore/style/StyleInvalidator.cpp (228728 => 228729)


--- trunk/Source/WebCore/style/StyleInvalidator.cpp	2018-02-20 05:01:57 UTC (rev 228728)
+++ trunk/Source/WebCore/style/StyleInvalidator.cpp	2018-02-20 06:09:13 UTC (rev 228729)
@@ -158,7 +158,7 @@
             if (parent == previousElement) {
                 parentStack.append(parent);
                 if (filter)
-                    filter->pushParent(parent);
+                    filter->pushParentInitializingIfNeeded(*parent);
             } else {
                 while (parentStack.last() != parent) {
                     parentStack.removeLast();
@@ -223,7 +223,8 @@
         break;
     }
     case MatchElement::Ancestor: {
-        invalidateStyleForDescendants(element, nullptr);
+        SelectorFilter filter;
+        invalidateStyleForDescendants(element, &filter);
         break;
     }
     case MatchElement::DirectSibling:
@@ -247,10 +248,14 @@
                 invalidateIfNeeded(siblingChild, nullptr);
         }
         break;
-    case MatchElement::AncestorSibling:
-        for (auto* sibling = element.nextElementSibling(); sibling; sibling = sibling->nextElementSibling())
-            invalidateStyleForDescendants(*sibling, nullptr);
+    case MatchElement::AncestorSibling: {
+        SelectorFilter filter;
+        for (auto* sibling = element.nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) {
+            filter.popParentsUntil(element.parentElement());
+            invalidateStyleForDescendants(*sibling, &filter);
+        }
         break;
+    }
     case MatchElement::Host:
         // FIXME: Handle this here as well.
         break;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to