Title: [229307] trunk/Source/WebCore
Revision
229307
Author
[email protected]
Date
2018-03-05 21:59:08 -0800 (Mon, 05 Mar 2018)

Log Message

Add ChildrenAffectedByForwardPositionalRules bit for nth-child pseudo class marking
https://bugs.webkit.org/show_bug.cgi?id=183341
<rdar://problem/38151470>

Reviewed by Zalan Bujtas.

Use it instead of AffectsNextSibling/AffectedByPreviousSibling bits, similar to ChildrenAffectedByBackwardPositionalRules bit.
This is more efficient and requires way less marking.

* css/SelectorChecker.cpp:
(WebCore::countElementsBefore):
(WebCore::countElementsOfTypeBefore):
(WebCore::SelectorChecker::checkOne const):

    Mark with ChildrenAffectedByForwardPositionalRules.

* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChildOf):

     Mark with ChildrenAffectedByForwardPositionalRules.

* dom/Element.cpp:
(WebCore::checkForSiblingStyleChanges):

    Invalidate siblings after added/removed element.

(WebCore::Element::setChildrenAffectedByForwardPositionalRules):
(WebCore::Element::hasFlagsSetDuringStylingOfChildren const):
(WebCore::Element::rareDataChildrenAffectedByForwardPositionalRules const):

    Add the new marking bit.

* dom/Element.h:
(WebCore::Element::childrenAffectedByForwardPositionalRules const):
(WebCore::Element::attributeWithoutSynchronization const):

    Remove assert so we can use this to get the current unresolved lazy value of style attrbute.

* dom/ElementRareData.h:
(WebCore::ElementRareData::childrenAffectedByForwardPositionalRules const):
(WebCore::ElementRareData::setChildrenAffectedByForwardPositionalRules):
(WebCore::ElementRareData::ElementRareData):
(WebCore::ElementRareData::resetStyleRelations):

     Add the new marking bit.

* dom/StyledElement.cpp:
(WebCore::StyledElement::invalidateStyleAttribute):

    In special case where we have attribute selectors for style attribute, synchronize the attribute immediately so we get invalidation right.
    Tested by fast/css/style-attribute-invalidation-propagates-to-counted-siblings.html

* style/StyleRelations.cpp:
(WebCore::Style::commitRelationsToRenderStyle):
(WebCore::Style::commitRelations):

    Commit the new bit.

* style/StyleRelations.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (229306 => 229307)


--- trunk/Source/WebCore/ChangeLog	2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/ChangeLog	2018-03-06 05:59:08 UTC (rev 229307)
@@ -1,3 +1,66 @@
+2018-03-05  Antti Koivisto  <[email protected]>
+
+        Add ChildrenAffectedByForwardPositionalRules bit for nth-child pseudo class marking
+        https://bugs.webkit.org/show_bug.cgi?id=183341
+        <rdar://problem/38151470>
+
+        Reviewed by Zalan Bujtas.
+
+        Use it instead of AffectsNextSibling/AffectedByPreviousSibling bits, similar to ChildrenAffectedByBackwardPositionalRules bit.
+        This is more efficient and requires way less marking.
+
+        * css/SelectorChecker.cpp:
+        (WebCore::countElementsBefore):
+        (WebCore::countElementsOfTypeBefore):
+        (WebCore::SelectorChecker::checkOne const):
+
+            Mark with ChildrenAffectedByForwardPositionalRules.
+
+        * cssjit/SelectorCompiler.cpp:
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChildOf):
+
+             Mark with ChildrenAffectedByForwardPositionalRules.
+
+        * dom/Element.cpp:
+        (WebCore::checkForSiblingStyleChanges):
+
+            Invalidate siblings after added/removed element.
+
+        (WebCore::Element::setChildrenAffectedByForwardPositionalRules):
+        (WebCore::Element::hasFlagsSetDuringStylingOfChildren const):
+        (WebCore::Element::rareDataChildrenAffectedByForwardPositionalRules const):
+
+            Add the new marking bit.
+
+        * dom/Element.h:
+        (WebCore::Element::childrenAffectedByForwardPositionalRules const):
+        (WebCore::Element::attributeWithoutSynchronization const):
+
+            Remove assert so we can use this to get the current unresolved lazy value of style attrbute.
+
+        * dom/ElementRareData.h:
+        (WebCore::ElementRareData::childrenAffectedByForwardPositionalRules const):
+        (WebCore::ElementRareData::setChildrenAffectedByForwardPositionalRules):
+        (WebCore::ElementRareData::ElementRareData):
+        (WebCore::ElementRareData::resetStyleRelations):
+
+             Add the new marking bit.
+
+        * dom/StyledElement.cpp:
+        (WebCore::StyledElement::invalidateStyleAttribute):
+
+            In special case where we have attribute selectors for style attribute, synchronize the attribute immediately so we get invalidation right.
+            Tested by fast/css/style-attribute-invalidation-propagates-to-counted-siblings.html    
+
+        * style/StyleRelations.cpp:
+        (WebCore::Style::commitRelationsToRenderStyle):
+        (WebCore::Style::commitRelations):
+
+            Commit the new bit.
+
+        * style/StyleRelations.h:
+
 2018-03-05  Ryan Haddad  <[email protected]>
 
         Unreviewed build fix, remove unused variables.

Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (229306 => 229307)


--- trunk/Source/WebCore/css/SelectorChecker.cpp	2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp	2018-03-06 05:59:08 UTC (rev 229307)
@@ -123,13 +123,10 @@
     return true;
 }
 
-static inline int countElementsBefore(SelectorChecker::CheckingContext& checkingContext, const Element& element)
+static inline int countElementsBefore(const Element& element)
 {
     int count = 0;
     for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
-
-        addStyleRelation(checkingContext, *sibling, Style::Relation::AffectsNextSibling);
-
         unsigned index = sibling->childIndex();
         if (index) {
             count += index;
@@ -140,12 +137,10 @@
     return count;
 }
 
-static inline int countElementsOfTypeBefore(SelectorChecker::CheckingContext& checkingContext, const Element& element, const QualifiedName& type)
+static inline int countElementsOfTypeBefore(const Element& element, const QualifiedName& type)
 {
     int count = 0;
     for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
-        addStyleRelation(checkingContext, *sibling, Style::Relation::AffectsNextSibling);
-
         if (sibling->hasTagName(type))
             ++count;
     }
@@ -837,7 +832,9 @@
         case CSSSelector::PseudoClassNthChild:
             if (!selector.parseNth())
                 break;
-            if (element.parentElement()) {
+            if (auto* parentElement = element.parentElement()) {
+                addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByForwardPositionalRules);
+
                 if (const CSSSelectorList* selectorList = selector.selectorList()) {
                     unsigned selectorListSpecificity;
                     if (!matchSelectorList(checkingContext, context, element, *selectorList, selectorListSpecificity))
@@ -845,19 +842,15 @@
                     specificity = CSSSelector::addSpecificities(specificity, selectorListSpecificity);
                 }
 
-                addStyleRelation(checkingContext, element, Style::Relation::AffectedByPreviousSibling);
-
                 int count = 1;
                 if (const CSSSelectorList* selectorList = selector.selectorList()) {
                     for (Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
-                        addStyleRelation(checkingContext, *sibling, Style::Relation::AffectsNextSibling);
-
                         unsigned ignoredSpecificity;
                         if (matchSelectorList(checkingContext, context, *sibling, *selectorList, ignoredSpecificity))
                             ++count;
                     }
                 } else {
-                    count += countElementsBefore(checkingContext, element);
+                    count += countElementsBefore(element);
                     addStyleRelation(checkingContext, element, Style::Relation::NthChildIndex, count);
                 }
 
@@ -869,10 +862,10 @@
             if (!selector.parseNth())
                 break;
 
-            if (element.parentElement()) {
-                addStyleRelation(checkingContext, element, Style::Relation::AffectedByPreviousSibling);
+            if (auto* parentElement = element.parentElement()) {
+                addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByForwardPositionalRules);
 
-                int count = 1 + countElementsOfTypeBefore(checkingContext, element, element.tagQName());
+                int count = 1 + countElementsOfTypeBefore(element, element.tagQName());
                 if (selector.matchNth(count))
                     return true;
             }

Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (229306 => 229307)


--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp	2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp	2018-03-06 05:59:08 UTC (rev 229307)
@@ -3490,6 +3490,7 @@
     {
         LocalRegister parentElement(m_registerAllocator);
         generateWalkToParentElement(failureCases, parentElement);
+        generateAddStyleRelationIfResolvingStyle(parentElement, Style::Relation::ChildrenAffectedByForwardPositionalRules);
     }
 
     Vector<std::pair<int, int>, 32> validSubsetFilters;
@@ -3502,9 +3503,6 @@
     if (validSubsetFilters.isEmpty())
         return;
 
-    if (!isAdjacentRelation(fragment.relationToRightFragment))
-        generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectedByPreviousSibling);
-
     // Setup the counter at 1.
     LocalRegisterWithPreference elementCounter(m_registerAllocator, JSC::GPRInfo::argumentGPR1);
     m_assembler.move(Assembler::TrustedImm32(1), elementCounter);
@@ -3521,7 +3519,6 @@
 
         Assembler::JumpList noCachedChildIndexCases;
         generateWalkToPreviousAdjacentElement(noMoreSiblingsCases, previousSibling);
-        generateAddStyleRelationIfResolvingStyle(previousSibling, Style::Relation::AffectsNextSibling);
         noCachedChildIndexCases.append(m_assembler.branchTest32(Assembler::Zero, Assembler::Address(previousSibling, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagHasRareData())));
         {
             LocalRegister elementRareData(m_registerAllocator);
@@ -3537,7 +3534,6 @@
 
         Assembler::Label loopStart = m_assembler.label();
         generateWalkToPreviousAdjacentElement(noMoreSiblingsCases, previousSibling);
-        generateAddStyleRelationIfResolvingStyle(previousSibling, Style::Relation::AffectsNextSibling);
         m_assembler.add32(Assembler::TrustedImm32(1), elementCounter);
         m_assembler.jump().linkTo(loopStart, &m_assembler);
         noMoreSiblingsCases.link(&m_assembler);
@@ -3554,6 +3550,7 @@
     {
         LocalRegister parentElement(m_registerAllocator);
         generateWalkToParentElement(failureCases, parentElement);
+        generateAddStyleRelationIfResolvingStyle(parentElement, Style::Relation::ChildrenAffectedByForwardPositionalRules);
     }
 
     // The initial element must match the selector list.
@@ -3569,9 +3566,6 @@
     if (validSubsetFilters.isEmpty())
         return;
 
-    if (!isAdjacentRelation(fragment.relationToRightFragment))
-        generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectedByPreviousSibling);
-
     for (const NthChildOfSelectorInfo* nthChildOfSelectorInfo : validSubsetFilters) {
         // Setup the counter at 1.
         LocalRegisterWithPreference elementCounter(m_registerAllocator, JSC::GPRInfo::argumentGPR1);
@@ -3587,7 +3581,6 @@
             Assembler::Label loopStart = m_assembler.label();
 
             generateWalkToPreviousAdjacentElement(noMoreSiblingsCases, previousSibling);
-            generateAddStyleRelationIfResolvingStyle(previousSibling, Style::Relation::AffectsNextSibling);
 
             Assembler::JumpList localFailureCases;
             generateElementMatchesSelectorList(localFailureCases, previousSibling, nthChildOfSelectorInfo->selectorList);

Modified: trunk/Source/WebCore/dom/Element.cpp (229306 => 229307)


--- trunk/Source/WebCore/dom/Element.cpp	2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/dom/Element.cpp	2018-03-06 05:59:08 UTC (rev 229307)
@@ -2073,9 +2073,13 @@
         }
     }
 
-    // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
     // backward case.
+    if (parent.childrenAffectedByForwardPositionalRules()) {
+        for (auto* next = elementAfterChange; next; next = next->nextElementSibling())
+            next->invalidateStyleForSubtree();
+    }
+    // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
     if (parent.childrenAffectedByBackwardPositionalRules()) {
         for (auto* previous = elementBeforeChange; previous; previous = previous->previousElementSibling())
             previous->invalidateStyleForSubtree();
@@ -2809,6 +2813,11 @@
     ensureElementRareData().setChildrenAffectedByDrag(true);
 }
 
+void Element::setChildrenAffectedByForwardPositionalRules()
+{
+    ensureElementRareData().setChildrenAffectedByForwardPositionalRules(true);
+}
+
 void Element::setChildrenAffectedByBackwardPositionalRules()
 {
     ensureElementRareData().setChildrenAffectedByBackwardPositionalRules(true);
@@ -2834,6 +2843,7 @@
         return false;
     return rareDataStyleAffectedByActive()
         || rareDataChildrenAffectedByDrag()
+        || rareDataChildrenAffectedByForwardPositionalRules()
         || rareDataChildrenAffectedByBackwardPositionalRules()
         || rareDataChildrenAffectedByPropertyBasedBackwardPositionalRules();
 }
@@ -2862,6 +2872,12 @@
     return elementRareData()->childrenAffectedByDrag();
 }
 
+bool Element::rareDataChildrenAffectedByForwardPositionalRules() const
+{
+    ASSERT(hasRareData());
+    return elementRareData()->childrenAffectedByForwardPositionalRules();
+}
+
 bool Element::rareDataChildrenAffectedByBackwardPositionalRules() const
 {
     ASSERT(hasRareData());

Modified: trunk/Source/WebCore/dom/Element.h (229306 => 229307)


--- trunk/Source/WebCore/dom/Element.h	2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/dom/Element.h	2018-03-06 05:59:08 UTC (rev 229307)
@@ -331,6 +331,7 @@
     bool childrenAffectedByDrag() const { return hasRareData() && rareDataChildrenAffectedByDrag(); }
     bool childrenAffectedByFirstChildRules() const { return getFlag(ChildrenAffectedByFirstChildRulesFlag); }
     bool childrenAffectedByLastChildRules() const { return getFlag(ChildrenAffectedByLastChildRulesFlag); }
+    bool childrenAffectedByForwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByForwardPositionalRules(); }
     bool childrenAffectedByBackwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByBackwardPositionalRules(); }
     bool childrenAffectedByPropertyBasedBackwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByPropertyBasedBackwardPositionalRules(); }
     bool affectsNextSiblingElementStyle() const { return getFlag(AffectsNextSiblingElementStyle); }
@@ -345,6 +346,7 @@
     void setChildrenAffectedByDrag();
     void setChildrenAffectedByFirstChildRules() { setFlag(ChildrenAffectedByFirstChildRulesFlag); }
     void setChildrenAffectedByLastChildRules() { setFlag(ChildrenAffectedByLastChildRulesFlag); }
+    void setChildrenAffectedByForwardPositionalRules();
     void setChildrenAffectedByBackwardPositionalRules();
     void setChildrenAffectedByPropertyBasedBackwardPositionalRules();
     void setAffectsNextSiblingElementStyle() { setFlag(AffectsNextSiblingElementStyle); }
@@ -648,6 +650,7 @@
     bool rareDataStyleAffectedByActive() const;
     bool rareDataChildrenAffectedByDrag() const;
     bool rareDataChildrenAffectedByLastChildRules() const;
+    bool rareDataChildrenAffectedByForwardPositionalRules() const;
     bool rareDataChildrenAffectedByBackwardPositionalRules() const;
     bool rareDataChildrenAffectedByPropertyBasedBackwardPositionalRules() const;
     unsigned rareDataChildIndex() const;
@@ -706,7 +709,6 @@
 
 inline const AtomicString& Element::attributeWithoutSynchronization(const QualifiedName& name) const
 {
-    ASSERT(fastAttributeLookupAllowed(name));
     if (elementData()) {
         if (const Attribute* attribute = findAttributeByName(name))
             return attribute->value();

Modified: trunk/Source/WebCore/dom/ElementRareData.h (229306 => 229307)


--- trunk/Source/WebCore/dom/ElementRareData.h	2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/dom/ElementRareData.h	2018-03-06 05:59:08 UTC (rev 229307)
@@ -70,6 +70,8 @@
 
     bool childrenAffectedByLastChildRules() const { return m_childrenAffectedByLastChildRules; }
     void setChildrenAffectedByLastChildRules(bool value) { m_childrenAffectedByLastChildRules = value; }
+    bool childrenAffectedByForwardPositionalRules() const { return m_childrenAffectedByForwardPositionalRules; }
+    void setChildrenAffectedByForwardPositionalRules(bool value) { m_childrenAffectedByForwardPositionalRules = value; }
     bool childrenAffectedByBackwardPositionalRules() const { return m_childrenAffectedByBackwardPositionalRules; }
     void setChildrenAffectedByBackwardPositionalRules(bool value) { m_childrenAffectedByBackwardPositionalRules = value; }
     bool childrenAffectedByPropertyBasedBackwardPositionalRules() const { return m_childrenAffectedByPropertyBasedBackwardPositionalRules; }
@@ -128,6 +130,7 @@
     // We optimize for :first-child and :last-child. The other positional child selectors like nth-child or
     // *-child-of-type, we will just give up and re-evaluate whenever children change at all.
     unsigned m_childrenAffectedByLastChildRules : 1;
+    unsigned m_childrenAffectedByForwardPositionalRules : 1;
     unsigned m_childrenAffectedByBackwardPositionalRules : 1;
     unsigned m_childrenAffectedByPropertyBasedBackwardPositionalRules : 1;
 
@@ -168,6 +171,7 @@
     , m_childrenAffectedByHover(false)
     , m_childrenAffectedByDrag(false)
     , m_childrenAffectedByLastChildRules(false)
+    , m_childrenAffectedByForwardPositionalRules(false)
     , m_childrenAffectedByBackwardPositionalRules(false)
     , m_childrenAffectedByPropertyBasedBackwardPositionalRules(false)
     , m_minimumSizeForResizing(defaultMinimumSizeForResizing())
@@ -206,6 +210,7 @@
     setStyleAffectedByActive(false);
     setChildrenAffectedByDrag(false);
     setChildrenAffectedByLastChildRules(false);
+    setChildrenAffectedByForwardPositionalRules(false);
     setChildrenAffectedByBackwardPositionalRules(false);
     setChildrenAffectedByPropertyBasedBackwardPositionalRules(false);
 }

Modified: trunk/Source/WebCore/dom/StyledElement.cpp (229306 => 229307)


--- trunk/Source/WebCore/dom/StyledElement.cpp	2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/dom/StyledElement.cpp	2018-03-06 05:59:08 UTC (rev 229307)
@@ -24,6 +24,7 @@
 #include "config.h"
 #include "StyledElement.h"
 
+#include "AttributeChangeInvalidation.h"
 #include "CSSImageValue.h"
 #include "CSSParser.h"
 #include "CSSStyleSheet.h"
@@ -145,6 +146,19 @@
     InspectorInstrumentation::didInvalidateStyleAttr(document(), *this);
 }
 
+static bool shouldSynchronizeStyleAttributeImmediatelyForInvalidation(StyledElement& element)
+{
+    // In rare case there is a complex attribute selector targeting style attribute (like "[style] ~ div") we need to synchronize immediately.
+    auto* ruleSets = element.styleResolver().ruleSets().attributeInvalidationRuleSets(styleAttr->localName());
+    if (!ruleSets)
+        return false;
+    for (auto& ruleSet : *ruleSets) {
+        if (ruleSet.matchElement != MatchElement::Subject)
+            return true;
+    }
+    return false;
+}
+
 void StyledElement::invalidateStyleAttribute()
 {
     if (usesStyleBasedEditability(*inlineStyle()))
@@ -152,6 +166,15 @@
 
     elementData()->setStyleAttributeIsDirty(true);
     invalidateStyle();
+
+    if (shouldSynchronizeStyleAttributeImmediatelyForInvalidation(*this)) {
+        if (auto* inlineStyle = this->inlineStyle()) {
+            elementData()->setStyleAttributeIsDirty(false);
+            auto newValue = inlineStyle->asText();
+            Style::AttributeChangeInvalidation styleInvalidation(*this, styleAttr, attributeWithoutSynchronization(styleAttr), newValue);
+            setSynchronizedLazyAttribute(styleAttr, newValue);
+        }
+    }
 }
 
 void StyledElement::inlineStyleChanged()

Modified: trunk/Source/WebCore/style/StyleRelations.cpp (229306 => 229307)


--- trunk/Source/WebCore/style/StyleRelations.cpp	2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/style/StyleRelations.cpp	2018-03-06 05:59:08 UTC (rev 229307)
@@ -76,6 +76,7 @@
         case Relation::AffectedByFocusWithin:
         case Relation::AffectedByPreviousSibling:
         case Relation::AffectsNextSibling:
+        case Relation::ChildrenAffectedByForwardPositionalRules:
         case Relation::ChildrenAffectedByBackwardPositionalRules:
         case Relation::ChildrenAffectedByFirstChildRules:
         case Relation::ChildrenAffectedByPropertyBasedBackwardPositionalRules:
@@ -119,6 +120,9 @@
                 sibling->setAffectsNextSiblingElementStyle();
             break;
         }
+        case Relation::ChildrenAffectedByForwardPositionalRules:
+            element.setChildrenAffectedByForwardPositionalRules();
+            break;
         case Relation::ChildrenAffectedByBackwardPositionalRules:
             element.setChildrenAffectedByBackwardPositionalRules();
             break;

Modified: trunk/Source/WebCore/style/StyleRelations.h (229306 => 229307)


--- trunk/Source/WebCore/style/StyleRelations.h	2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/style/StyleRelations.h	2018-03-06 05:59:08 UTC (rev 229307)
@@ -46,6 +46,7 @@
         AffectedByPreviousSibling,
         // For AffectsNextSibling 'value' tells how many element siblings to mark starting with 'element'.
         AffectsNextSibling,
+        ChildrenAffectedByForwardPositionalRules, 
         ChildrenAffectedByBackwardPositionalRules,
         ChildrenAffectedByFirstChildRules,
         ChildrenAffectedByPropertyBasedBackwardPositionalRules,
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to