Bug 661746 - Part 3: Use const selectors during selector matching. r=bzbarsky
authorDavid Zbarsky <dzbarsky@gmail.com>
Mon, 14 Nov 2011 16:30:16 +1300
changeset 80219 61534874aed701ddc982605d4864229e6d19896c
parent 80218 1cb3705557d9d5cae86418bc2bb3402be7d5a62b
child 80220 2f403e4c42c88edc2bd831db44107f927b8475be
push id323
push userrcampbell@mozilla.com
push dateTue, 15 Nov 2011 21:58:36 +0000
treeherderfx-team@3ea216303184 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs661746
milestone11.0a1
Bug 661746 - Part 3: Use const selectors during selector matching. r=bzbarsky
layout/style/nsCSSRuleProcessor.cpp
layout/style/nsCSSRuleProcessor.h
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -623,17 +623,17 @@ void RuleHash::AppendRule(const RuleSele
 #define RULE_HASH_STAT_INCREMENT_LIST_COUNT(list_, var_) \
   (var_) += (list_).Length()
 #else
 #define RULE_HASH_STAT_INCREMENT_LIST_COUNT(list_, var_) \
   PR_BEGIN_MACRO PR_END_MACRO
 #endif
 
 static inline
-void ContentEnumFunc(css::StyleRule* aRule, nsCSSSelector* aSelector,
+void ContentEnumFunc(css::StyleRule* aRule, const nsCSSSelector* aSelector,
                      RuleProcessorData* data, NodeMatchContext& nodeContext);
 
 void RuleHash::EnumerateAllRules(const Element* aElement, RuleProcessorData* aData,
                                  NodeMatchContext& aNodeContext)
 {
   PRInt32 nameSpace = aElement->GetNameSpaceID();
   nsIAtom* tag = aElement->Tag();
   nsIAtom* id = aElement->GetID();
@@ -1459,17 +1459,17 @@ edgeChildMatches(const Element* aElement
          (!checkLast ||
           aTreeMatchContext.mNthIndexCache.
             GetNthIndex(aElement, false, true, true) == 1);
 }
 
 static inline bool
 nthChildGenericMatches(const Element* aElement,
                        TreeMatchContext& aTreeMatchContext,
-                       nsPseudoClassList* pseudoClass,
+                       const nsPseudoClassList* pseudoClass,
                        bool isOfType, bool isFromEnd)
 {
   const nsIContent *parent = aElement->GetParent();
   if (!parent) {
     return false;
   }
 
   if (aTreeMatchContext.mForStyling) {
@@ -1562,17 +1562,17 @@ PR_STATIC_ASSERT(NS_ARRAY_LENGTH(sPseudo
                    nsCSSPseudoClasses::ePseudoClass_NotPseudoClass + 1);
 
 // |aDependence| has two functions:
 //  * when non-null, it indicates that we're processing a negation,
 //    which is done only when SelectorMatches calls itself recursively
 //  * what it points to should be set to true whenever a test is skipped
 //    because of aStateMask
 static bool SelectorMatches(const Element* aElement,
-                              nsCSSSelector* aSelector,
+                              const nsCSSSelector* aSelector,
                               NodeMatchContext& aNodeMatchContext,
                               TreeMatchContext& aTreeMatchContext,
                               bool* const aDependence = nsnull)
 
 {
   NS_PRECONDITION(!aSelector->IsPseudoElement(),
                   "Pseudo-element snuck into SelectorMatches?");
   NS_ABORT_IF_FALSE(aTreeMatchContext.mForStyling ||
@@ -1591,17 +1591,17 @@ static bool SelectorMatches(const Elemen
     nsIAtom* selectorTag =
       (aTreeMatchContext.mIsHTMLDocument && aElement->IsHTML()) ?
         aSelector->mLowercaseTag : aSelector->mCasedTag;
     if (selectorTag != aElement->Tag()) {
       return false;
     }
   }
 
-  nsAtomList* IDList = aSelector->mIDList;
+  const nsAtomList* IDList = aSelector->mIDList;
   if (IDList) {
     nsIAtom* id = aElement->GetID();
     if (id) {
       // case sensitivity: bug 93371
       const bool isCaseSensitive =
         aTreeMatchContext.mCompatMode != eCompatibility_NavQuirks;
 
       if (isCaseSensitive) {
@@ -1625,17 +1625,17 @@ static bool SelectorMatches(const Elemen
         } while (IDList);
       }
     } else {
       // Element has no id but we have an id selector
       return false;
     }
   }
 
-  nsAtomList* classList = aSelector->mClassList;
+  const nsAtomList* classList = aSelector->mClassList;
   if (classList) {
     // test for class match
     const nsAttrValue *elementClasses = aElement->GetClasses();
     if (!elementClasses) {
       // Element has no classes but we have a class selector
       return false;
     }
 
@@ -1660,17 +1660,17 @@ static bool SelectorMatches(const Elemen
   // we'd probably avoid setting those bits in more cases where setting
   // them is unnecessary.
   NS_ASSERTION(aNodeMatchContext.mStateMask.IsEmpty() ||
                !aTreeMatchContext.mForStyling,
                "mForStyling must be false if we're just testing for "
                "state-dependence");
 
   // test for pseudo class match
-  for (nsPseudoClassList* pseudoClass = aSelector->mPseudoClassList;
+  for (const nsPseudoClassList* pseudoClass = aSelector->mPseudoClassList;
        pseudoClass; pseudoClass = pseudoClass->mNext) {
     nsEventStates statesToCheck = sPseudoClassStates[pseudoClass->mType];
     if (statesToCheck.IsEmpty()) {
       // keep the cases here in the same order as the list in
       // nsCSSPseudoClassList.h
       switch (pseudoClass->mType) {
       case nsCSSPseudoClasses::ePseudoClass_empty:
         if (!checkGenericEmptyMatches(aElement, aTreeMatchContext, true)) {
@@ -1777,19 +1777,19 @@ static bool SelectorMatches(const Elemen
         if (aElement->GetParent() ||
             aElement != aElement->OwnerDoc()->GetRootElement()) {
           return false;
         }
         break;
 
       case nsCSSPseudoClasses::ePseudoClass_any:
         {
-          nsCSSSelectorList *l;
+          const nsCSSSelectorList *l;
           for (l = pseudoClass->u.mSelectors; l; l = l->mNext) {
-            nsCSSSelector *s = l->mSelectors;
+            const nsCSSSelector *s = l->mSelectors;
             NS_ABORT_IF_FALSE(!s->mNext && !s->IsPseudoElement(),
                               "parser failed");
             if (SelectorMatches(aElement, s, aNodeMatchContext,
                                 aTreeMatchContext)) {
               break;
             }
           }
           if (!l) {
@@ -2049,17 +2049,17 @@ static bool SelectorMatches(const Elemen
   if (aSelector->mAttrList) {
     // test for attribute match
     PRUint32 attrCount = aElement->GetAttrCount();
     if (attrCount == 0) {
       // if no attributes on the content, no match
       return false;
     } else {
       result = true;
-      nsAttrSelector* attr = aSelector->mAttrList;
+      const nsAttrSelector* attr = aSelector->mAttrList;
       nsIAtom* matchAttribute;
 
       do {
         bool isHTML =
           (aTreeMatchContext.mIsHTMLDocument && aElement->IsHTML());
         matchAttribute = isHTML ? attr->mLowercaseAttr : attr->mCasedAttr;
         if (attr->mNameSpace == kNameSpaceID_Unknown) {
           // Attr selector with a wildcard namespace.  We have to examine all
@@ -2121,17 +2121,17 @@ static bool SelectorMatches(const Elemen
         
         attr = attr->mNext;
       } while (attr && result);
     }
   }
 
   // apply SelectorMatches to the negated selectors in the chain
   if (!isNegated) {
-    for (nsCSSSelector *negation = aSelector->mNegations;
+    for (const nsCSSSelector *negation = aSelector->mNegations;
          result && negation; negation = negation->mNegations) {
       bool dependence = false;
       result = !SelectorMatches(aElement, negation, aNodeMatchContext,
                                 aTreeMatchContext, &dependence);
       // If the selector does match due to the dependence on aStateMask,
       // then we want to keep result true so that the final result of
       // SelectorMatches is true.  Doing so tells StateEnumFunc that
       // there is a dependence on the state.
@@ -2146,21 +2146,21 @@ static bool SelectorMatches(const Elemen
 // Right now, there are four operators:
 //   ' ', the descendant combinator, is greedy
 //   '~', the indirect adjacent sibling combinator, is greedy
 //   '+' and '>', the direct adjacent sibling and child combinators, are not
 #define NS_IS_GREEDY_OPERATOR(ch) \
   ((ch) == PRUnichar(' ') || (ch) == PRUnichar('~'))
 
 static bool SelectorMatchesTree(const Element* aPrevElement,
-                                  nsCSSSelector* aSelector,
+                                  const nsCSSSelector* aSelector,
                                   TreeMatchContext& aTreeMatchContext,
                                   bool aLookForRelevantLink)
 {
-  nsCSSSelector* selector = aSelector;
+  const nsCSSSelector* selector = aSelector;
   const Element* prevElement = aPrevElement;
   while (selector) { // check compound selectors
     NS_ASSERTION(!selector->mNext ||
                  selector->mNext->mOperator != PRUnichar(0),
                  "compound selector without combinator");
 
     // for adjacent sibling combinators, the content to test against the
     // selector is the previous sibling *element*
@@ -2246,25 +2246,25 @@ static bool SelectorMatchesTree(const El
       }
     }
     prevElement = element;
   }
   return true; // all the selectors matched.
 }
 
 static inline
-void ContentEnumFunc(css::StyleRule* aRule, nsCSSSelector* aSelector,
+void ContentEnumFunc(css::StyleRule* aRule, const nsCSSSelector* aSelector,
                      RuleProcessorData* data, NodeMatchContext& nodeContext)
 {
   if (nodeContext.mIsRelevantLink) {
     data->mTreeMatchContext.SetHaveRelevantLink();
   }
   if (SelectorMatches(data->mElement, aSelector, nodeContext,
                       data->mTreeMatchContext)) {
-    nsCSSSelector *next = aSelector->mNext;
+    const nsCSSSelector *next = aSelector->mNext;
     if (!next || SelectorMatchesTree(data->mElement, next,
                                      data->mTreeMatchContext,
                                      !nodeContext.mIsRelevantLink)) {
       aRule->RuleMatched();
       data->mRuleWalker->Forward(aRule);
       // nsStyleSet will deal with the !important rule
     }
   }
@@ -3105,25 +3105,25 @@ nsCSSRuleProcessor::RefreshRuleCascade(n
     }
   }
   return;
 }
 
 /* static */ bool
 nsCSSRuleProcessor::SelectorListMatches(const Element* aElement,
                                         TreeMatchContext& aTreeMatchContext,
-                                        nsCSSSelectorList* aSelectorList)
+                                        const nsCSSSelectorList* aSelectorList)
 {
   while (aSelectorList) {
-    nsCSSSelector* sel = aSelectorList->mSelectors;
+    const nsCSSSelector* sel = aSelectorList->mSelectors;
     NS_ASSERTION(sel, "Should have *some* selectors");
     NS_ASSERTION(!sel->IsPseudoElement(), "Shouldn't have been called");
     NodeMatchContext nodeContext(nsEventStates(), false);
     if (SelectorMatches(aElement, sel, nodeContext, aTreeMatchContext)) {
-      nsCSSSelector* next = sel->mNext;
+      const nsCSSSelector* next = sel->mNext;
       if (!next ||
           SelectorMatchesTree(aElement, next, aTreeMatchContext, false)) {
         return true;
       }
     }
 
     aSelectorList = aSelectorList->mNext;
   }
--- a/layout/style/nsCSSRuleProcessor.h
+++ b/layout/style/nsCSSRuleProcessor.h
@@ -90,17 +90,17 @@ public:
    * Returns true if the given aElement matches one of the
    * selectors in aSelectorList.  Note that this method will assume
    * the given aElement is not a relevant link.  aSelectorList must not
    * include any pseudo-element selectors.  aSelectorList is allowed
    * to be null; in this case false will be returned.
    */
   static bool SelectorListMatches(const mozilla::dom::Element* aElement,
                                     TreeMatchContext& aTreeMatchContext,
-                                    nsCSSSelectorList* aSelectorList);
+                                    const nsCSSSelectorList* aSelectorList);
 
   /*
    * Helper to get the content state for a content node.  This may be
    * slightly adjusted from IntrinsicState().
    */
   static nsEventStates GetContentState(const mozilla::dom::Element* aElement);
 
   /*