Title: [171059] trunk/Source/WebCore
Revision
171059
Author
[email protected]
Date
2014-07-13 14:51:16 -0700 (Sun, 13 Jul 2014)

Log Message

Remove SelectorCheckerFastPath from the style resolution algorithm
https://bugs.webkit.org/show_bug.cgi?id=134866

Reviewed by Antti Koivisto.

SelectorCheckerFastPath is now pure overhead because it can almost never match
if the CSS JIT was unable to compile.

* css/ElementRuleCollector.cpp:
(WebCore::ElementRuleCollector::ruleMatches):
The "pre-filter" behind fastCheckableSelector had two parts:
1) Filtering the pseudoID.
2) Filtering on the rule hash.

The first part has been generalized (RuleDatacanMatchPseudoElement())
and moved to collectMatchingRulesForList(). 

(WebCore::ElementRuleCollector::collectMatchingRulesForList):
* css/RuleSet.cpp:
(WebCore::selectorCanMatchPseudoElement):
(WebCore::RuleData::RuleData):
(WebCore::RuleSet::addRegionRule):
(WebCore::RuleSet::addRulesFromSheet):
* css/RuleSet.h:
(WebCore::RuleData::canMatchPseudoElement):
(WebCore::RuleData::hasFastCheckableSelector): Deleted.
* css/StyleResolver.cpp:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (171058 => 171059)


--- trunk/Source/WebCore/ChangeLog	2014-07-13 21:46:07 UTC (rev 171058)
+++ trunk/Source/WebCore/ChangeLog	2014-07-13 21:51:16 UTC (rev 171059)
@@ -1,5 +1,35 @@
 2014-07-13  Benjamin Poulain  <[email protected]>
 
+        Remove SelectorCheckerFastPath from the style resolution algorithm
+        https://bugs.webkit.org/show_bug.cgi?id=134866
+
+        Reviewed by Antti Koivisto.
+
+        SelectorCheckerFastPath is now pure overhead because it can almost never match
+        if the CSS JIT was unable to compile.
+
+        * css/ElementRuleCollector.cpp:
+        (WebCore::ElementRuleCollector::ruleMatches):
+        The "pre-filter" behind fastCheckableSelector had two parts:
+        1) Filtering the pseudoID.
+        2) Filtering on the rule hash.
+
+        The first part has been generalized (RuleDatacanMatchPseudoElement())
+        and moved to collectMatchingRulesForList(). 
+
+        (WebCore::ElementRuleCollector::collectMatchingRulesForList):
+        * css/RuleSet.cpp:
+        (WebCore::selectorCanMatchPseudoElement):
+        (WebCore::RuleData::RuleData):
+        (WebCore::RuleSet::addRegionRule):
+        (WebCore::RuleSet::addRulesFromSheet):
+        * css/RuleSet.h:
+        (WebCore::RuleData::canMatchPseudoElement):
+        (WebCore::RuleData::hasFastCheckableSelector): Deleted.
+        * css/StyleResolver.cpp:
+
+2014-07-13  Benjamin Poulain  <[email protected]>
+
         Remove an useless check from SelectorChecker
         https://bugs.webkit.org/show_bug.cgi?id=134868
 

Modified: trunk/Source/WebCore/css/ElementRuleCollector.cpp (171058 => 171059)


--- trunk/Source/WebCore/css/ElementRuleCollector.cpp	2014-07-13 21:46:07 UTC (rev 171058)
+++ trunk/Source/WebCore/css/ElementRuleCollector.cpp	2014-07-13 21:51:16 UTC (rev 171059)
@@ -39,7 +39,6 @@
 #include "InspectorInstrumentation.h"
 #include "RenderRegion.h"
 #include "SVGElement.h"
-#include "SelectorCheckerFastPath.h"
 #include "SelectorCompiler.h"
 #include "StyleProperties.h"
 #include "StyledElement.h"
@@ -273,15 +272,11 @@
 
 inline bool ElementRuleCollector::ruleMatches(const RuleData& ruleData)
 {
-    bool fastCheckableSelector = ruleData.hasFastCheckableSelector();
-    if (fastCheckableSelector) {
-        // We know this selector does not include any pseudo elements.
-        if (m_pseudoStyleRequest.pseudoId != NOPSEUDO)
-            return false;
-        // We know a sufficiently simple single part selector matches simply because we found it from the rule hash.
-        // This is limited to HTML only so we don't need to check the namespace.
-        if (ruleData.hasRightmostSelectorMatchingHTMLBasedOnRuleHash() && m_element.isHTMLElement())
-            return true;
+    // We know a sufficiently simple single part selector matches simply because we found it from the rule hash when filtering the RuleSet.
+    // This is limited to HTML only so we don't need to check the namespace (because of tag name match).
+    if (ruleData.hasRightmostSelectorMatchingHTMLBasedOnRuleHash() && m_element.isHTMLElement()) {
+        ASSERT_WITH_MESSAGE(m_pseudoStyleRequest.pseudoId == NOPSEUDO, "If we match based on the rule hash while collecting for a particular pseudo element ID, we would add incorrect rules for that pseudo element ID. We should never end in ruleMatches() with a pseudo element if the ruleData cannot match any pseudo element.");
+        return true;
     }
 
 #if ENABLE(CSS_SELECTOR_JIT)
@@ -319,16 +314,6 @@
     }
 #endif // ENABLE(CSS_SELECTOR_JIT)
 
-    if (fastCheckableSelector) {
-        if (ruleData.selector()->m_match == CSSSelector::Tag && !SelectorChecker::tagMatches(&m_element, ruleData.selector()->tagQName()))
-            return false;
-        SelectorCheckerFastPath selectorCheckerFastPath(ruleData.selector(), &m_element);
-        if (!selectorCheckerFastPath.matchesRightmostAttributeSelector())
-            return false;
-
-        return selectorCheckerFastPath.matches();
-    }
-
     // Slow path.
     SelectorChecker selectorChecker(m_element.document(), m_mode);
     SelectorChecker::SelectorCheckingContext context(ruleData.selector(), &m_element, SelectorChecker::VisitedMatchEnabled);
@@ -346,6 +331,10 @@
 
     for (unsigned i = 0, size = rules->size(); i < size; ++i) {
         const RuleData& ruleData = rules->data()[i];
+
+        if (!ruleData.canMatchPseudoElement() && m_pseudoStyleRequest.pseudoId != NOPSEUDO)
+            continue;
+
         if (m_canUseFastReject && m_selectorFilter.fastRejectSelector<RuleData::maximumIdentifierCount>(ruleData.descendantSelectorIdentifierHashes()))
             continue;
 

Modified: trunk/Source/WebCore/css/RuleSet.cpp (171058 => 171059)


--- trunk/Source/WebCore/css/RuleSet.cpp	2014-07-13 21:46:07 UTC (rev 171058)
+++ trunk/Source/WebCore/css/RuleSet.cpp	2014-07-13 21:51:16 UTC (rev 171059)
@@ -36,7 +36,6 @@
 #include "MediaQueryEvaluator.h"
 #include "SecurityOrigin.h"
 #include "SelectorChecker.h"
-#include "SelectorCheckerFastPath.h"
 #include "SelectorFilter.h"
 #include "StyleResolver.h"
 #include "StyleRule.h"
@@ -68,6 +67,25 @@
     return selector.m_match == CSSSelector::Id || selector.m_match == CSSSelector::Class;
 }
 
+static bool selectorCanMatchPseudoElement(const CSSSelector& rootSelector)
+{
+    const CSSSelector* selector = &rootSelector;
+    do {
+        if (selector->matchesPseudoElement())
+            return true;
+
+        if (const CSSSelectorList* selectorList = selector->selectorList()) {
+            for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
+                if (selectorCanMatchPseudoElement(*subSelector))
+                    return true;
+            }
+        }
+
+        selector = selector->tagHistory();
+    } while (selector);
+    return false;
+}
+
 static inline bool selectorListContainsAttributeSelector(const CSSSelector* selector)
 {
     const CSSSelectorList* selectorList = selector->selectorList();
@@ -129,13 +147,13 @@
 RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned position, AddRuleFlags addRuleFlags)
     : m_rule(rule)
     , m_selectorIndex(selectorIndex)
+    , m_hasDocumentSecurityOrigin(addRuleFlags & RuleHasDocumentSecurityOrigin)
     , m_position(position)
-    , m_hasFastCheckableSelector((addRuleFlags & RuleCanUseFastCheckSelector) && SelectorCheckerFastPath::canUse(selector()))
     , m_specificity(selector()->specificity())
     , m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash(isSelectorMatchingHTMLBasedOnRuleHash(*selector()))
+    , m_canMatchPseudoElement(selectorCanMatchPseudoElement(*selector()))
     , m_containsUncommonAttributeSelector(WebCore::containsUncommonAttributeSelector(selector()))
     , m_linkMatchType(SelectorChecker::determineLinkMatchType(selector()))
-    , m_hasDocumentSecurityOrigin(addRuleFlags & RuleHasDocumentSecurityOrigin)
     , m_propertyWhitelistType(determinePropertyWhitelistType(addRuleFlags, selector()))
 #if ENABLE(CSS_SELECTOR_JIT) && CSS_SELECTOR_JIT_PROFILING
     , m_compiledSelectorUseCount(0)
@@ -291,7 +309,7 @@
     // FIXME: Should this add other types of rules? (i.e. use addChildRules() directly?)
     const Vector<RefPtr<StyleRuleBase>>& childRules = regionRule->childRules();
     AddRuleFlags addRuleFlags = hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState;
-    addRuleFlags = static_cast<AddRuleFlags>(addRuleFlags | RuleCanUseFastCheckSelector | RuleIsInRegionRule);
+    addRuleFlags = static_cast<AddRuleFlags>(addRuleFlags | RuleIsInRegionRule);
     for (unsigned i = 0; i < childRules.size(); ++i) {
         StyleRuleBase* regionStylingRule = childRules[i].get();
         if (regionStylingRule->isStyleRule())
@@ -354,7 +372,7 @@
     }
 
     bool hasDocumentSecurityOrigin = resolver && resolver->document().securityOrigin()->canRequest(sheet->baseURL());
-    AddRuleFlags addRuleFlags = static_cast<AddRuleFlags>((hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : 0) | RuleCanUseFastCheckSelector);
+    AddRuleFlags addRuleFlags = static_cast<AddRuleFlags>((hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : 0));
 
     addChildRules(sheet->childRules(), medium, resolver, hasDocumentSecurityOrigin, addRuleFlags);
 

Modified: trunk/Source/WebCore/css/RuleSet.h (171058 => 171059)


--- trunk/Source/WebCore/css/RuleSet.h	2014-07-13 21:46:07 UTC (rev 171058)
+++ trunk/Source/WebCore/css/RuleSet.h	2014-07-13 21:51:16 UTC (rev 171059)
@@ -36,8 +36,7 @@
 enum AddRuleFlags {
     RuleHasNoSpecialState         = 0,
     RuleHasDocumentSecurityOrigin = 1,
-    RuleCanUseFastCheckSelector   = 1 << 1,
-    RuleIsInRegionRule            = 1 << 2,
+    RuleIsInRegionRule            = 1 << 1,
 };
     
 enum PropertyWhitelistType {
@@ -66,7 +65,7 @@
     const CSSSelector* selector() const { return m_rule->selectorList().selectorAt(m_selectorIndex); }
     unsigned selectorIndex() const { return m_selectorIndex; }
 
-    bool hasFastCheckableSelector() const { return m_hasFastCheckableSelector; }
+    bool canMatchPseudoElement() const { return m_canMatchPseudoElement; }
     bool hasRightmostSelectorMatchingHTMLBasedOnRuleHash() const { return m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash; }
     bool containsUncommonAttributeSelector() const { return m_containsUncommonAttributeSelector; }
     unsigned specificity() const { return m_specificity; }
@@ -98,15 +97,15 @@
 private:
     RefPtr<StyleRule> m_rule;
     unsigned m_selectorIndex : 13;
+    unsigned m_hasDocumentSecurityOrigin : 1;
     // This number was picked fairly arbitrarily. We can probably lower it if we need to.
     // Some simple testing showed <100,000 RuleData's on large sites.
     unsigned m_position : 18;
-    unsigned m_hasFastCheckableSelector : 1;
     unsigned m_specificity : 24;
     unsigned m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash : 1;
+    unsigned m_canMatchPseudoElement : 1;
     unsigned m_containsUncommonAttributeSelector : 1;
     unsigned m_linkMatchType : 2; //  SelectorChecker::LinkMatchMask
-    unsigned m_hasDocumentSecurityOrigin : 1;
     unsigned m_propertyWhitelistType : 2;
     // Use plain array instead of a Vector to minimize memory overhead.
     unsigned m_descendantSelectorIdentifierHashes[maximumIdentifierCount];

Modified: trunk/Source/WebCore/css/StyleResolver.cpp (171058 => 171059)


--- trunk/Source/WebCore/css/StyleResolver.cpp	2014-07-13 21:46:07 UTC (rev 171058)
+++ trunk/Source/WebCore/css/StyleResolver.cpp	2014-07-13 21:51:16 UTC (rev 171059)
@@ -109,7 +109,6 @@
 #include "SVGNames.h"
 #include "SVGURIReference.h"
 #include "SecurityOrigin.h"
-#include "SelectorCheckerFastPath.h"
 #include "Settings.h"
 #include "ShadowData.h"
 #include "ShadowRoot.h"
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to