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
authorHiroyuki Ikezoe <hiikezoe@mozilla-japan.org>
Thu, 21 Jul 2016 06:12:41 +0900
changeset 345966 f2cfc74a93beafabdd057fc6e1b4582baa9bb078
parent 345965 d2ba56fc82b64d21224de40f089bd1aa45f027df
child 345967 ea6df4951b5694d9f583de132f3926d30c10bb5a
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1282076
milestone50.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 1282076 - Store all non-inherited structs which are stored on the rule node on the style context if we have animation data. r=heycam
layout/style/nsRuleNode.cpp
layout/style/nsRuleNode.h
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -2422,17 +2422,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.
 
@@ -2825,16 +2831,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_));                       \
@@ -10263,17 +10275,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.
@@ -10622,16 +10640,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
@@ -938,16 +938,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_ *>                                \
@@ -1066,11 +1074,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