Bug 1180118 - Part 5: Add a RestyleHintData outparam to HasAttributeDependentStyle for use with eRestyle_SomeDescendants. r=bzbarsky
authorCameron McCormack <cam@mcc.id.au>
Wed, 05 Aug 2015 22:42:21 +1000
changeset 287960 2f73362274d6fdda93c5d572726f0e92e53957e4
parent 287959 cf1a39719f3b43bc8f4b59389043295d81fb8e62
child 287961 13729747e3c2f62b5c2debc65d2bc137f05a29b6
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs1180118
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1180118 - Part 5: Add a RestyleHintData outparam to HasAttributeDependentStyle for use with eRestyle_SomeDescendants. r=bzbarsky
layout/base/RestyleManager.cpp
layout/style/AnimationCommon.cpp
layout/style/AnimationCommon.h
layout/style/SVGAttrAnimationRuleProcessor.cpp
layout/style/SVGAttrAnimationRuleProcessor.h
layout/style/nsCSSRuleProcessor.cpp
layout/style/nsCSSRuleProcessor.h
layout/style/nsHTMLCSSStyleSheet.cpp
layout/style/nsHTMLCSSStyleSheet.h
layout/style/nsHTMLStyleSheet.cpp
layout/style/nsHTMLStyleSheet.h
layout/style/nsIStyleRuleProcessor.h
layout/style/nsStyleSet.cpp
layout/style/nsStyleSet.h
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -1165,23 +1165,25 @@ RestyleManager::ContentStateChanged(nsIC
 // Forwarded nsIMutationObserver method, to handle restyling.
 void
 RestyleManager::AttributeWillChange(Element* aElement,
                                     int32_t aNameSpaceID,
                                     nsIAtom* aAttribute,
                                     int32_t aModType,
                                     const nsAttrValue* aNewValue)
 {
+  RestyleHintData rsdata;
   nsRestyleHint rshint =
     mPresContext->StyleSet()->HasAttributeDependentStyle(aElement,
                                                          aAttribute,
                                                          aModType,
                                                          false,
-                                                         aNewValue);
-  PostRestyleEvent(aElement, rshint, NS_STYLE_HINT_NONE);
+                                                         aNewValue,
+                                                         rsdata);
+  PostRestyleEvent(aElement, rshint, NS_STYLE_HINT_NONE, &rsdata);
 }
 
 // Forwarded nsIMutationObserver method, to handle restyling (and
 // passing the notification to the frame).
 void
 RestyleManager::AttributeChanged(Element* aElement,
                                  int32_t aNameSpaceID,
                                  nsIAtom* aAttribute,
@@ -1254,24 +1256,25 @@ RestyleManager::AttributeChanged(Element
     // XXXwaterson should probably check for IB split siblings
     // here, and propagate the AttributeChanged notification to
     // them, as well. Currently, inline frames don't do anything on
     // this notification, so it's not that big a deal.
   }
 
   // See if we can optimize away the style re-resolution -- must be called after
   // the frame's AttributeChanged() in case it does something that affects the style
+  RestyleHintData rsdata;
   nsRestyleHint rshint =
     mPresContext->StyleSet()->HasAttributeDependentStyle(aElement,
                                                          aAttribute,
                                                          aModType,
                                                          true,
-                                                         aOldValue);
-
-  PostRestyleEvent(aElement, rshint, hint);
+                                                         aOldValue,
+                                                         rsdata);
+  PostRestyleEvent(aElement, rshint, hint, &rsdata);
 }
 
 /* static */ uint64_t
 RestyleManager::GetMaxAnimationGenerationForFrame(nsIFrame* aFrame)
 {
   nsIContent* content = aFrame->GetContent();
   if (!content || !content->IsElement()) {
     return 0;
--- a/layout/style/AnimationCommon.cpp
+++ b/layout/style/AnimationCommon.cpp
@@ -205,17 +205,19 @@ CommonAnimationManager::HasStateDependen
 
 bool
 CommonAnimationManager::HasDocumentStateDependentStyle(StateRuleProcessorData* aData)
 {
   return false;
 }
 
 nsRestyleHint
-CommonAnimationManager::HasAttributeDependentStyle(AttributeRuleProcessorData* aData)
+CommonAnimationManager::HasAttributeDependentStyle(
+    AttributeRuleProcessorData* aData,
+    RestyleHintData& aRestyleHintDataResult)
 {
   return nsRestyleHint(0);
 }
 
 /* virtual */ bool
 CommonAnimationManager::MediumFeaturesChanged(nsPresContext* aPresContext)
 {
   return false;
--- a/layout/style/AnimationCommon.h
+++ b/layout/style/AnimationCommon.h
@@ -47,17 +47,18 @@ public:
   // nsISupports
   NS_DECL_ISUPPORTS
 
   // nsIStyleRuleProcessor (parts)
   virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) override;
   virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override;
   virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override;
   virtual nsRestyleHint
-    HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override;
+    HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
+                               RestyleHintData& aRestyleHintDataResult) override;
   virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override;
   virtual void RulesMatching(ElementRuleProcessorData* aData) override;
   virtual void RulesMatching(PseudoElementRuleProcessorData* aData) override;
   virtual void RulesMatching(AnonBoxRuleProcessorData* aData) override;
 #ifdef MOZ_XUL
   virtual void RulesMatching(XULTreeRuleProcessorData* aData) override;
 #endif
   virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf)
--- a/layout/style/SVGAttrAnimationRuleProcessor.cpp
+++ b/layout/style/SVGAttrAnimationRuleProcessor.cpp
@@ -57,17 +57,19 @@ SVGAttrAnimationRuleProcessor::HasStateD
 
 /* virtual */ bool
 SVGAttrAnimationRuleProcessor::HasDocumentStateDependentStyle(StateRuleProcessorData* aData)
 {
   return false;
 }
 
 /* virtual */ nsRestyleHint
-SVGAttrAnimationRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData)
+SVGAttrAnimationRuleProcessor::HasAttributeDependentStyle(
+    AttributeRuleProcessorData* aData,
+    RestyleHintData& aRestyleHintDataResult)
 {
   return nsRestyleHint(0);
 }
 
 /* virtual */ bool
 SVGAttrAnimationRuleProcessor::MediumFeaturesChanged(nsPresContext* aPresContext)
 {
   return false;
--- a/layout/style/SVGAttrAnimationRuleProcessor.h
+++ b/layout/style/SVGAttrAnimationRuleProcessor.h
@@ -39,17 +39,18 @@ public:
   virtual void RulesMatching(AnonBoxRuleProcessorData* aData) override;
 #ifdef MOZ_XUL
   virtual void RulesMatching(XULTreeRuleProcessorData* aData) override;
 #endif
   virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) override;
   virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override;
   virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override;
   virtual nsRestyleHint
-    HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override;
+    HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
+                               RestyleHintData& aRestyleHintDataResult) override;
   virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override;
   virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf)
     const MOZ_MUST_OVERRIDE override;
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
     const MOZ_MUST_OVERRIDE override;
 
   size_t DOMSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -2834,17 +2834,19 @@ EnumerateSelectors(nsTArray<nsCSSSelecto
   nsCSSSelector **iter = aSelectors.Elements(),
                 **end = iter + aSelectors.Length();
   for (; iter != end; ++iter) {
     AttributeEnumFunc(*iter, nullptr, aData);
   }
 }
 
 nsRestyleHint
-nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData)
+nsCSSRuleProcessor::HasAttributeDependentStyle(
+    AttributeRuleProcessorData* aData,
+    RestyleHintData& aRestyleHintDataResult)
 {
   //  We could try making use of aData->mModType, but :not rules make it a bit
   //  of a pain to do so...  So just ignore it for now.
 
   AttributeEnumData data(aData);
 
   // Don't do our special handling of certain attributes if the attr
   // hasn't changed yet.
--- a/layout/style/nsCSSRuleProcessor.h
+++ b/layout/style/nsCSSRuleProcessor.h
@@ -139,17 +139,19 @@ public:
 #endif
 
   virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) override;
   virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override;
 
   virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override;
 
   virtual nsRestyleHint
-    HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override;
+    HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
+                               mozilla::RestyleHintData& aRestyleHintDataResult)
+                                 override;
 
   virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override;
 
   /**
    * If this rule processor currently has a substantive media query
    * result cache key, return a copy of it.
    */
   mozilla::UniquePtr<nsMediaQueryResultCacheKey> CloneMQCacheKey();
--- a/layout/style/nsHTMLCSSStyleSheet.cpp
+++ b/layout/style/nsHTMLCSSStyleSheet.cpp
@@ -139,17 +139,19 @@ nsHTMLCSSStyleSheet::HasStateDependentSt
 /* virtual */ bool
 nsHTMLCSSStyleSheet::HasDocumentStateDependentStyle(StateRuleProcessorData* aData)
 {
   return false;
 }
 
 // Test if style is dependent on attribute
 /* virtual */ nsRestyleHint
-nsHTMLCSSStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData)
+nsHTMLCSSStyleSheet::HasAttributeDependentStyle(
+    AttributeRuleProcessorData* aData,
+    RestyleHintData& aRestyleHintDataResult)
 {
   // Perhaps should check that it's XUL, SVG, (or HTML) namespace, but
   // it doesn't really matter.
   if (aData->mAttrHasChanged && aData->mAttribute == nsGkAtoms::style) {
     return eRestyle_StyleAttribute;
   }
 
   return nsRestyleHint(0);
--- a/layout/style/nsHTMLCSSStyleSheet.h
+++ b/layout/style/nsHTMLCSSStyleSheet.h
@@ -38,17 +38,18 @@ public:
   virtual void RulesMatching(AnonBoxRuleProcessorData* aData) override;
 #ifdef MOZ_XUL
   virtual void RulesMatching(XULTreeRuleProcessorData* aData) override;
 #endif
   virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) override;
   virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override;
   virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override;
   virtual nsRestyleHint
-    HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override;
+    HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
+                               mozilla::RestyleHintData& aRestyleHintDataResult) override;
   virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override;
   virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf)
     const MOZ_MUST_OVERRIDE override;
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
     const MOZ_MUST_OVERRIDE override;
 
   // Variants of RulesMatching method above that is specific to this
   // rule processor.
--- a/layout/style/nsHTMLStyleSheet.cpp
+++ b/layout/style/nsHTMLStyleSheet.cpp
@@ -330,17 +330,19 @@ nsHTMLStyleSheet::HasStateDependentStyle
 
 /* virtual */ bool
 nsHTMLStyleSheet::HasDocumentStateDependentStyle(StateRuleProcessorData* aData)
 {
   return false;
 }
 
 /* virtual */ nsRestyleHint
-nsHTMLStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData)
+nsHTMLStyleSheet::HasAttributeDependentStyle(
+    AttributeRuleProcessorData* aData,
+    RestyleHintData& aRestyleHintDataResult)
 {
   // Do nothing on before-change checks
   if (!aData->mAttrHasChanged) {
     return nsRestyleHint(0);
   }
 
   // Note: no need to worry about whether some states changed with this
   // attribute here, because we handle that under HasStateDependentStyle() as
--- a/layout/style/nsHTMLStyleSheet.h
+++ b/layout/style/nsHTMLStyleSheet.h
@@ -40,17 +40,18 @@ public:
   virtual void RulesMatching(AnonBoxRuleProcessorData* aData) override;
 #ifdef MOZ_XUL
   virtual void RulesMatching(XULTreeRuleProcessorData* aData) override;
 #endif
   virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) override;
   virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override;
   virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override;
   virtual nsRestyleHint
-    HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override;
+    HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
+                               mozilla::RestyleHintData& aRestyleHintDataResult) override;
   virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override;
   virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf)
     const MOZ_MUST_OVERRIDE override;
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
     const MOZ_MUST_OVERRIDE override;
   size_t DOMSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
   void Reset();
--- a/layout/style/nsIStyleRuleProcessor.h
+++ b/layout/style/nsIStyleRuleProcessor.h
@@ -110,18 +110,19 @@ public:
    * implementation to decide how to split the bits up amongst the two
    * return values.  For example, it could return the bits needed by
    * rules that might stop matching the node from the first call and
    * the bits needed by rules that might have started matching the
    * node from the second call.  This test is used for optimization
    * only, and may err on the side of reporting more dependencies than
    * really exist.
    */
-  virtual nsRestyleHint
-    HasAttributeDependentStyle(AttributeRuleProcessorData* aData) = 0;
+  virtual nsRestyleHint HasAttributeDependentStyle(
+      AttributeRuleProcessorData* aData,
+      mozilla::RestyleHintData& aRestyleHintDataResult) = 0;
 
   /**
    * Do any processing that needs to happen as a result of a change in
    * the characteristics of the medium, and return whether this rule
    * processor's rules have changed (e.g., because of media queries).
    */
   virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) = 0;
 
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -2372,42 +2372,51 @@ struct MOZ_STACK_CLASS AttributeData : p
   AttributeData(nsPresContext* aPresContext,
                 Element* aElement, nsIAtom* aAttribute, int32_t aModType,
                 bool aAttrHasChanged, const nsAttrValue* aOtherValue,
                 TreeMatchContext& aTreeMatchContext)
     : AttributeRuleProcessorData(aPresContext, aElement, aAttribute, aModType,
                                  aAttrHasChanged, aOtherValue, aTreeMatchContext),
       mHint(nsRestyleHint(0))
   {}
-  nsRestyleHint   mHint;
+  nsRestyleHint mHint;
+  RestyleHintData mHintData;
 };
 
 static bool
 SheetHasAttributeStyle(nsIStyleRuleProcessor* aProcessor, void *aData)
 {
   AttributeData* data = (AttributeData*)aData;
-  nsRestyleHint hint = aProcessor->HasAttributeDependentStyle(data);
+  nsRestyleHint hint =
+    aProcessor->HasAttributeDependentStyle(data, data->mHintData);
   data->mHint = nsRestyleHint(data->mHint | hint);
   return true; // continue
 }
 
 // Test if style is dependent on content state
 nsRestyleHint
 nsStyleSet::HasAttributeDependentStyle(Element*       aElement,
                                        nsIAtom*       aAttribute,
                                        int32_t        aModType,
                                        bool           aAttrHasChanged,
-                                       const nsAttrValue* aOtherValue)
+                                       const nsAttrValue* aOtherValue,
+                                       mozilla::RestyleHintData&
+                                         aRestyleHintDataResult)
 {
   TreeMatchContext treeContext(false, nsRuleWalker::eLinksVisitedOrUnvisited,
                                aElement->OwnerDoc());
   InitStyleScopes(treeContext, aElement);
   AttributeData data(PresContext(), aElement, aAttribute,
                      aModType, aAttrHasChanged, aOtherValue, treeContext);
   WalkRuleProcessors(SheetHasAttributeStyle, &data, false);
+  if (!(data.mHint & eRestyle_Subtree)) {
+    // No point keeping the list of selectors around if we are going to
+    // restyle the whole subtree unconditionally.
+    aRestyleHintDataResult = Move(data.mHintData);
+  }
   return data.mHint;
 }
 
 bool
 nsStyleSet::MediumFeaturesChanged()
 {
   NS_ASSERTION(mBatching == 0, "rule processors out of date");
 
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -281,17 +281,19 @@ class nsStyleSet final
                                        mozilla::dom::Element* aPseudoElement,
                                        mozilla::EventStates aStateMask);
 
   // Test if style is dependent on the presence of an attribute.
   nsRestyleHint HasAttributeDependentStyle(mozilla::dom::Element* aElement,
                                            nsIAtom*       aAttribute,
                                            int32_t        aModType,
                                            bool           aAttrHasChanged,
-                                           const nsAttrValue* aOtherValue);
+                                           const nsAttrValue* aOtherValue,
+                                           mozilla::RestyleHintData&
+                                             aRestyleHintDataResult);
 
   /*
    * Do any processing that needs to happen as a result of a change in
    * the characteristics of the medium, and return whether style rules
    * may have changed as a result.
    */
   bool MediumFeaturesChanged();