From db8e759c6654a09aa851384768d580fb632b7274 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Wed, 28 Jun 2017 09:27:30 -0400 Subject: [PATCH] Bug 1353312 - Don't use conditions when caching a struct with no rules. r=dbaron MozReview-Commit-ID: 7yzG5vIKxwh --- layout/style/RuleNodeCacheConditions.h | 5 +++++ layout/style/nsRuleNode.cpp | 17 +++++++++++++++++ layout/style/nsRuleNode.h | 13 +++++++++---- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/layout/style/RuleNodeCacheConditions.h b/layout/style/RuleNodeCacheConditions.h index a7f59365de43..4b1a2349a55a 100644 --- a/layout/style/RuleNodeCacheConditions.h +++ b/layout/style/RuleNodeCacheConditions.h @@ -95,6 +95,11 @@ public: mBits |= eUncacheable; } + void Clear() + { + *this = RuleNodeCacheConditions(); + } + bool Cacheable() const { return !(mBits & eUncacheable); diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 2eea495a67ec..106c55699147 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -2673,6 +2673,23 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID, if (!highestNode) highestNode = rootNode; + if (detail == eRuleNone && isReset) { + // We specified absolutely no rule information for a reset struct, and we + // may or may not have found a parent rule in the tree that specified all + // the rule information. Regardless, we don't need to use any cache + // conditions when we (inevitably) cache this struct in the rule tree. + // + // Normally ruleData.mConditions would already indicate that the struct + // is cacheable without conditions if detail is eRuleNone, but because + // of the UnsetPropertiesWithoutFlags call above, we may have encountered + // some rules with dependencies, which we then cleared out of ruleData. + NS_ASSERTION(ruleData.mConditions.CacheableWithoutDependencies() || + pseudoRestriction, + "we should already be cacheable without dependencies if we " + "didn't have a pseudo restriction"); + ruleData.mConditions.Clear(); + } + MOZ_ASSERT(!(aSID == eStyleStruct_Variables && startStruct), "if we start caching Variables structs in the rule tree, then " "not forcing detail to eRulePartialMixed just below is no " diff --git a/layout/style/nsRuleNode.h b/layout/style/nsRuleNode.h index 1057e568e8d9..b5e9a97913ad 100644 --- a/layout/style/nsRuleNode.h +++ b/layout/style/nsRuleNode.h @@ -193,6 +193,7 @@ public: MOZ_ASSERT(!(mConditionalBits & GetBitForSID(aSID)), "rule node should not have unconditional and conditional style " "data for a given struct"); + mConditionalBits &= ~GetBitForSID(aSID); mEntries[aSID] = aStyleStruct; } @@ -200,13 +201,17 @@ public: nsPresContext* aPresContext, void* aStyleStruct, const mozilla::RuleNodeCacheConditions& aConditions) { - MOZ_ASSERT((mConditionalBits & GetBitForSID(aSID)) || - !mEntries[aSID], - "rule node should not have unconditional and conditional style " - "data for a given struct"); + if (!(mConditionalBits & GetBitForSID(aSID))) { + MOZ_ASSERT(!mEntries[aSID], + "rule node should not have unconditional and conditional " + "style data for a given struct"); + mEntries[aSID] = nullptr; + } + MOZ_ASSERT(aConditions.CacheableWithDependencies(), "don't call SetStyleData with a cache key that has no " "conditions or is uncacheable"); + #ifdef DEBUG for (Entry* e = static_cast(mEntries[aSID]); e; e = e->mNext) { NS_WARNING_ASSERTION(e->mConditions != aConditions,