Bug 1343078 part 4. Add storage for the singleton non-inheriting anon box style contexts on style set. r?dbaron draft
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 08 Mar 2017 00:18:39 -0500
changeset 495000 4d48dd103b654045957d89ebebe652d22dd27829
parent 494999 b47530d3044990a923652ee84bb815a42985f8b1
child 495001 3dca24ce623021f450d0eb87eb57c4baf0834d6e
push id48199
push userbzbarsky@mozilla.com
push dateWed, 08 Mar 2017 05:19:43 +0000
reviewersdbaron
bugs1343078
milestone55.0a1
Bug 1343078 part 4. Add storage for the singleton non-inheriting anon box style contexts on style set. r?dbaron MozReview-Commit-ID: 9OvEssf3J5o
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSet.h
layout/style/nsStyleSet.cpp
layout/style/nsStyleSet.h
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -24,16 +24,20 @@ using namespace mozilla;
 using namespace mozilla::dom;
 
 ServoStyleSet::ServoStyleSet()
   : mPresContext(nullptr)
   , mBatching(0)
 {
 }
 
+ServoStyleSet::~ServoStyleSet()
+{
+}
+
 void
 ServoStyleSet::Init(nsPresContext* aPresContext)
 {
   mPresContext = aPresContext;
   mRawSet.reset(Servo_StyleSet_Init(aPresContext));
 
   // Now that we have an mRawSet, go ahead and notify about whatever stylesheets
   // we have so far.
@@ -72,16 +76,19 @@ ServoStyleSet::BeginShutdown()
   while (Element* root = iter.GetNextStyleRoot()) {
     ServoRestyleManager::ClearServoDataFromSubtree(root);
   }
 }
 
 void
 ServoStyleSet::Shutdown()
 {
+  // Make sure we drop our cached style contexts before the presshell arena
+  // starts going away.
+  ClearNonInheritingStyleContexts();
   mRawSet = nullptr;
 }
 
 bool
 ServoStyleSet::GetAuthorStyleDisabled() const
 {
   return false;
 }
@@ -652,18 +659,27 @@ ServoStyleSet::FillKeyframesForName(cons
                                              &aTimingFunction,
                                              aComputedValues,
                                              &aKeyframes);
 }
 
 void
 ServoStyleSet::RebuildData()
 {
+  ClearNonInheritingStyleContexts();
   Servo_StyleSet_RebuildData(mRawSet.get());
 }
 
 already_AddRefed<ServoComputedValues>
 ServoStyleSet::ResolveServoStyle(Element* aElement)
 {
   return Servo_ResolveStyle(aElement, mRawSet.get()).Consume();
 }
 
+void
+ServoStyleSet::ClearNonInheritingStyleContexts()
+{
+  for (RefPtr<nsStyleContext>& ptr : mNonInheritingStyleContexts) {
+    ptr = nullptr;
+  }  
+}
+
 bool ServoStyleSet::sInServoTraversal = false;
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -10,16 +10,17 @@
 #include "mozilla/EnumeratedArray.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/ServoBindingTypes.h"
 #include "mozilla/ServoElementSnapshot.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/SheetType.h"
 #include "mozilla/UniquePtr.h"
 #include "nsCSSPseudoElements.h"
+#include "nsCSSAnonBoxes.h"
 #include "nsChangeHint.h"
 #include "nsIAtom.h"
 #include "nsTArray.h"
 
 namespace mozilla {
 namespace dom {
 class Element;
 } // namespace dom
@@ -55,16 +56,17 @@ public:
     // callers, and are likely to take the main-thread codepath if this function
     // returns false. So we assert against other non-main-thread callers here.
     MOZ_ASSERT_IF(aAssertServoTraversalOrMainThread,
                   sInServoTraversal || NS_IsMainThread());
     return sInServoTraversal;
   }
 
   ServoStyleSet();
+  ~ServoStyleSet();
 
   void Init(nsPresContext* aPresContext);
   void BeginShutdown();
   void Shutdown();
 
   bool GetAuthorStyleDisabled() const;
   nsresult SetAuthorStyleDisabled(bool aStyleDisabled);
 
@@ -251,20 +253,31 @@ private:
 
   /**
    * Perform all lazy operations required before traversing
    * a subtree.  Returns whether a post-traversal is required.
    */
   bool PrepareAndTraverseSubtree(RawGeckoElementBorrowed aRoot,
                                  mozilla::TraversalRootBehavior aRootBehavior);
 
+  /**
+   * Clear our cached mNonInheritingStyleContexts.  We do this when we want to
+   * make sure those style contexts won't live too long (e.g. when rebuilding
+   * all style data or when shutting down the style set).
+   */
+  void ClearNonInheritingStyleContexts();
+
   nsPresContext* mPresContext;
   UniquePtr<RawServoStyleSet> mRawSet;
   EnumeratedArray<SheetType, SheetType::Count,
                   nsTArray<RefPtr<ServoStyleSheet>>> mSheets;
   int32_t mBatching;
 
+  // Stores pointers to our cached style contexts for non-inheriting anonymous
+  // boxes.
+  RefPtr<nsStyleContext> mNonInheritingStyleContexts[static_cast<nsCSSAnonBoxes::NonInheritingBase>(nsCSSAnonBoxes::NonInheriting::_Count)];
+
   static bool sInServoTraversal;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_ServoStyleSet_h
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -305,16 +305,19 @@ nsStyleSet::BeginReconstruct()
   NS_ASSERTION(!mInReconstruct, "Unmatched begin/end?");
   NS_ASSERTION(mRuleTree, "Reconstructing before first construction?");
   mInReconstruct = true;
 
   // Clear any ArenaRefPtr-managed style contexts, as we don't want them
   // held on to after the rule tree has been reconstructed.
   PresContext()->PresShell()->ClearArenaRefPtrs(eArenaObjectID_nsStyleContext);
 
+  // Clear our cached style contexts for non-inheriting anonymous boxes.
+  ClearNonInheritingStyleContexts();
+
 #ifdef DEBUG
   MOZ_ASSERT(!mOldRootNode);
   mOldRootNode = mRuleTree;
 #endif
 
   // Create a new rule tree root, dropping the reference to our old rule tree.
   // After reconstruction, we will re-enable GC, and allow everything to be
   // collected.
@@ -2267,16 +2270,19 @@ void
 nsStyleSet::BeginShutdown()
 {
   mInShutdown = 1;
 }
 
 void
 nsStyleSet::Shutdown()
 {
+  // Make sure we drop our cached style contexts before the presshell arena
+  // starts going away.
+  ClearNonInheritingStyleContexts();
   mRuleTree = nullptr;
   GCRuleTrees();
   MOZ_ASSERT(mUnusedRuleNodeList.isEmpty());
   MOZ_ASSERT(mUnusedRuleNodeCount == 0);
 }
 
 
 void
@@ -2611,8 +2617,16 @@ nsStyleSet::ClearSelectors()
   if (!mRuleTree) {
     return;
   }
   MOZ_ASSERT(PresContext()->RestyleManager()->IsGecko(),
              "stylo: the style set and restyle manager must have the same "
              "StyleBackendType");
   PresContext()->RestyleManager()->AsGecko()->ClearSelectors();
 }
+
+void
+nsStyleSet::ClearNonInheritingStyleContexts()
+{
+  for (RefPtr<nsStyleContext>& ptr : mNonInheritingStyleContexts) {
+    ptr = nullptr;
+  }
+}
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -21,16 +21,17 @@
 #include "mozilla/SheetType.h"
 
 #include "nsIStyleRuleProcessor.h"
 #include "nsBindingManager.h"
 #include "nsRuleNode.h"
 #include "nsTArray.h"
 #include "nsCOMArray.h"
 #include "nsIStyleRule.h"
+#include "nsCSSAnonBoxes.h"
 
 class gfxFontFeatureValueSet;
 class nsCSSKeyframesRule;
 class nsCSSFontFeatureValuesRule;
 class nsCSSPageRule;
 class nsCSSCounterStyleRule;
 class nsICSSPseudoComparator;
 class nsRuleWalker;
@@ -565,16 +566,21 @@ private:
   ResolvePseudoElementStyleInternal(mozilla::dom::Element* aParentElement,
                                     mozilla::CSSPseudoElementType aType,
                                     nsStyleContext* aParentContext,
                                     mozilla::dom::Element* aPseudoElement,
                                     AnimationFlag aAnimationFlag);
 
   nsPresContext* PresContext() { return mRuleTree->PresContext(); }
 
+  // Clear our cached mNonInheritingStyleContexts.  We do this when we want to
+  // make sure those style contexts won't live too long (e.g. at ruletree
+  // reconstruct or shutdown time).
+  void ClearNonInheritingStyleContexts();
+
   // The sheets in each array in mSheets are stored with the most significant
   // sheet last.
   // The arrays for ePresHintSheet, eStyleAttrSheet, eTransitionSheet,
   // eAnimationSheet and eSVGAttrAnimationSheet are always empty.
   // (FIXME:  We should reduce the storage needed for them.)
   mozilla::EnumeratedArray<mozilla::SheetType, mozilla::SheetType::Count,
                            nsTArray<RefPtr<mozilla::CSSStyleSheet>>> mSheets;
 
@@ -628,16 +634,20 @@ private:
   RefPtr<nsInitialStyleRule> mInitialStyleRule;
 
   // Style rule that sets the internal -x-text-zoom property on
   // <svg:text> elements to disable the effect of text zooming.
   RefPtr<nsDisableTextZoomStyleRule> mDisableTextZoomStyleRule;
 
   // whether font feature values lookup object needs initialization
   RefPtr<gfxFontFeatureValueSet> mFontFeatureValuesLookup;
+
+  // Stores pointers to our cached style contexts for non-inheriting anonymous
+  // boxes.
+  RefPtr<nsStyleContext> mNonInheritingStyleContexts[static_cast<nsCSSAnonBoxes::NonInheritingBase>(nsCSSAnonBoxes::NonInheriting::_Count)];
 };
 
 #ifdef MOZILLA_INTERNAL_API
 inline
 void nsRuleNode::AddRef()
 {
   if (mRefCnt++ == 0) {
     MOZ_ASSERT(mPresContext->StyleSet()->IsGecko(),