Bug 1282076 - Store all non-inherited structs which are stored on the rule node on the style context if we have animation data. r=heycam a=sylvestre
authorHiroyuki Ikezoe <hiikezoe@mozilla-japan.org>
Fri, 22 Jul 2016 15:03:31 +0900
changeset 312200 10c9453407de40dd17d612f802da2fab94c161f4
parent 312199 bc2f5467b33d70d5dc03fdc0d2fcf0d52356f186
child 312201 d91fc76079e07f5e83d66f6891764df8329de2bc
push id213
push userkwierso@gmail.com
push dateMon, 29 Aug 2016 17:22:22 +0000
treeherdermozilla-esr45@fd5052e343df [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam, sylvestre
bugs1282076
milestone45.3.1
Bug 1282076 - Store all non-inherited structs which are stored on the rule node on the style context if we have animation data. r=heycam a=sylvestre
layout/style/nsRuleNode.cpp
layout/style/nsRuleNode.h
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -2373,17 +2373,23 @@ nsRuleNode::WalkRuleTree(const nsStyleSt
     // node in the tree to the node that specified the data that tells nodes on that
     // branch that they never need to examine their rules for this particular struct type
     // ever again.
     PropagateDependentBit(aSID, ruleNode, startStruct);
     // For inherited structs, mark the struct (which will be set on
     // the context by our caller) as not being owned by the context.
     if (!isReset) {
       aContext->AddStyleBit(nsCachedStyleData::GetBitForSID(aSID));
-    }
+    } else if (HasAnimationData()) {
+      // If we have animation data, the struct should be cached on the style
+      // context so that we can peek the struct.
+      // See comment in AnimValuesStyleRule::MapRuleInfoInto.
+      StoreStyleOnContext(aContext, aSID, startStruct);
+    }
+
     return startStruct;
   }
   if ((!startStruct && !isReset &&
        (detail == eRuleNone || detail == eRulePartialInherited)) ||
       detail == eRuleFullInherited) {
     // We specified no non-inherited information and neither did any of
     // our parent rules.
 
@@ -2778,16 +2784,22 @@ nsRuleNode::SetDefaultOnRoot(const nsSty
     }                                                                         \
     NS_ASSERTION(!aHighestNode->mStyleData.mResetData->                       \
                    GetStyleData(eStyleStruct_##type_),                        \
                  "Going to leak style data");                                 \
     aHighestNode->mStyleData.mResetData->                                     \
       SetStyleData(eStyleStruct_##type_, data_);                              \
     /* Propagate the bit down. */                                             \
     PropagateDependentBit(eStyleStruct_##type_, aHighestNode, data_);         \
+    if (HasAnimationData()) {                                                 \
+      /* If we have animation data, the struct should be cached on the */     \
+      /* style context so that we can peek the struct. */                     \
+      /* See comment in AnimValuesStyleRule::MapRuleInfoInto. */              \
+      StoreStyleOnContext(aContext, eStyleStruct_##type_, data_);             \
+    }                                                                         \
   } else if (conditions.Cacheable()) {                                        \
     if (!mStyleData.mResetData) {                                             \
       mStyleData.mResetData = new (mPresContext) nsConditionalResetStyleData; \
     }                                                                         \
     mStyleData.mResetData->                                                   \
       SetStyleData(eStyleStruct_##type_, mPresContext, data_, conditions);    \
     /* Tell the style context that it doesn't own the data */                 \
     aContext->AddStyleBit(NS_STYLE_INHERIT_BIT(type_));                       \
@@ -9711,17 +9723,23 @@ nsRuleNode::GetStyleData(nsStyleStructID
   // see comment on cacheability in AnimValuesStyleRule::MapRuleInfoInto.
   if (!(HasAnimationData() && ParentHasPseudoElementData(aContext))) {
     data = mStyleData.GetStyleData(aSID, aContext, aComputeData);
     if (MOZ_LIKELY(data != nullptr)) {
       // For inherited structs, mark the struct (which will be set on
       // the context by our caller) as not being owned by the context.
       if (!nsCachedStyleData::IsReset(aSID)) {
         aContext->AddStyleBit(nsCachedStyleData::GetBitForSID(aSID));
-      }
+      } else if (HasAnimationData()) {
+        // If we have animation data, the struct should be cached on the style
+        // context so that we can peek the struct.
+        // See comment in AnimValuesStyleRule::MapRuleInfoInto.
+        StoreStyleOnContext(aContext, aSID, const_cast<void*>(data));
+      }
+
       return data; // We have a fully specified struct. Just return it.
     }
   }
 
   if (MOZ_UNLIKELY(!aComputeData))
     return nullptr;
 
   // Nothing is cached.  We'll have to delve further and examine our rules.
@@ -10178,16 +10196,25 @@ nsRuleNode::ComputeColor(const nsCSSValu
 
 /* static */ bool
 nsRuleNode::ParentHasPseudoElementData(nsStyleContext* aContext)
 {
   nsStyleContext* parent = aContext->GetParent();
   return parent && parent->HasPseudoElementData();
 }
 
+/* static */ void
+nsRuleNode::StoreStyleOnContext(nsStyleContext* aContext,
+                                nsStyleStructID aSID,
+                                void* aStruct)
+{
+  aContext->AddStyleBit(nsCachedStyleData::GetBitForSID(aSID));
+  aContext->SetStyle(aSID, aStruct);
+}
+
 #ifdef DEBUG
 bool
 nsRuleNode::ContextHasCachedData(nsStyleContext* aContext,
                                  nsStyleStructID aSID)
 {
   return !!aContext->GetCachedStyleData(aSID);
 }
 #endif
--- a/layout/style/nsRuleNode.h
+++ b/layout/style/nsRuleNode.h
@@ -944,16 +944,24 @@ public:
                                                                               \
     const nsStyle##name_ *data;                                               \
                                                                               \
     /* Never use cached data for animated style inside a pseudo-element; */   \
     /* see comment on cacheability in AnimValuesStyleRule::MapRuleInfoInto */ \
     if (!(HasAnimationData() && ParentHasPseudoElementData(aContext))) {      \
       data = mStyleData.GetStyle##name_(aContext, aComputeData);              \
       if (MOZ_LIKELY(data != nullptr)) {                                      \
+        if (HasAnimationData()) {                                             \
+          /* If we have animation data, the struct should be cached on the */ \
+          /* style context so that we can peek the struct. */                 \
+          /* See comment in AnimValuesStyleRule::MapRuleInfoInto. */          \
+          StoreStyleOnContext(aContext,                                       \
+                              eStyleStruct_##name_,                           \
+                              const_cast<nsStyle##name_*>(data));             \
+        }                                                                     \
         return data;                                                          \
       }                                                                       \
     }                                                                         \
                                                                               \
     if (!aComputeData)                                                        \
       return nullptr;                                                         \
                                                                               \
     data = static_cast<const nsStyle##name_ *>                                \
@@ -1083,11 +1091,16 @@ public:
 
 private:
 #ifdef DEBUG
   // non-inline helper function to allow assertions without incomplete
   // type errors
   bool ContextHasCachedData(nsStyleContext* aContext, nsStyleStructID aSID);
 #endif
 
+  // Store style struct on the style context and tell the style context
+  // that it doesn't own the data
+  static void StoreStyleOnContext(nsStyleContext* aContext,
+                                  nsStyleStructID aSID,
+                                  void* aStruct);
 };
 
 #endif