Bug 1384114: Move mRefCnt, Destroy() and HasSingleReference() to GeckoStyleContext. r?bholley draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 25 Jul 2017 15:45:59 +0200
changeset 615141 e353c30c69405d905a89e787f49a1ba31f8775a1
parent 615134 c3f4230e9a234f64ab2df323095a88e60bfe61e1
child 639084 5c2fd8771d5d302e26916e06646cdd83f61792d2
push id70247
push userbmo:emilio+bugs@crisal.io
push dateTue, 25 Jul 2017 13:48:53 +0000
reviewersbholley
bugs1384114
milestone56.0a1
Bug 1384114: Move mRefCnt, Destroy() and HasSingleReference() to GeckoStyleContext. r?bholley MozReview-Commit-ID: 5XzFYcohl3m
layout/style/GeckoStyleContext.cpp
layout/style/GeckoStyleContext.h
layout/style/nsStyleContext.cpp
layout/style/nsStyleContext.h
--- a/layout/style/GeckoStyleContext.cpp
+++ b/layout/style/GeckoStyleContext.cpp
@@ -33,16 +33,17 @@ GeckoStyleContext::Initialize()
 
 GeckoStyleContext::GeckoStyleContext(GeckoStyleContext* aParent,
                                      nsIAtom* aPseudoTag,
                                      CSSPseudoElementType aPseudoType,
                                      already_AddRefed<nsRuleNode> aRuleNode,
                                      bool aSkipParentDisplayBasedStyleFixup)
   : nsStyleContext(aParent, aPseudoTag, aPseudoType)
   , mCachedResetData(nullptr)
+  , mRefCnt(0)
   , mChild(nullptr)
   , mEmptyChild(nullptr)
   , mRuleNode(Move(aRuleNode))
 #ifdef DEBUG
   , mComputingStruct(nsStyleStructID_None)
 #endif
 {
   mBits |= NS_STYLE_CONTEXT_IS_GECKO;
@@ -76,16 +77,31 @@ void*
 GeckoStyleContext::operator new(size_t sz, nsPresContext* aPresContext)
 {
   MOZ_ASSERT(sz == sizeof(GeckoStyleContext));
   // Check the recycle list first.
   return aPresContext->PresShell()->
     AllocateByObjectID(eArenaObjectID_GeckoStyleContext, sz);
 }
 
+// Overridden to prevent the global delete from being called, since the memory
+// came out of an nsIArena instead of the global delete operator's heap.
+void
+GeckoStyleContext::Destroy()
+{
+  // Get the pres context.
+  RefPtr<nsPresContext> presContext = PresContext();
+  // Call our destructor.
+  this->~GeckoStyleContext();
+  // Don't let the memory be freed, since it will be recycled
+  // instead. Don't call the global operator delete.
+  presContext->PresShell()->
+    FreeByObjectID(eArenaObjectID_GeckoStyleContext, this);
+}
+
 GeckoStyleContext::~GeckoStyleContext()
 {
   nsPresContext *presContext = PresContext();
 #ifdef DEBUG
   NS_ASSERTION(HasNoChildren(), "destructing context with children");
   if (sExpensiveStyleStructAssertionsEnabled) {
     // Assert that the style structs we are about to destroy are not referenced
     // anywhere else in the style context tree.  These checks are expensive,
--- a/layout/style/GeckoStyleContext.h
+++ b/layout/style/GeckoStyleContext.h
@@ -133,16 +133,23 @@ public:
 
   bool HasNoChildren() const;
 
   nsRuleNode* RuleNode() const {
     MOZ_ASSERT(mRuleNode);
     return mRuleNode;
   }
 
+  bool HasSingleReference() const {
+    NS_ASSERTION(mRefCnt != 0,
+                 "do not call HasSingleReference on a newly created "
+                 "nsStyleContext with no references yet");
+    return mRefCnt == 1;
+  }
+
   void AddRef() {
     if (mRefCnt == UINT32_MAX) {
       NS_WARNING("refcount overflow, leaking object");
       return;
     }
     ++mRefCnt;
     NS_LOG_ADDREF(this, mRefCnt, "nsStyleContext", sizeof(nsStyleContext));
     return;
@@ -215,24 +222,27 @@ public:
   // is set for a struct, that means that the pointer for that struct is
   // owned by an ancestor or by the rule node rather than by this style context.
   // Since style contexts typically have some inherited data but only sometimes
   // have reset data, we always allocate the mCachedInheritedData, but only
   // sometimes allocate the mCachedResetData.
   nsResetStyleData*       mCachedResetData; // Cached reset style data.
   nsInheritedStyleData    mCachedInheritedData; // Cached inherited style data
 
+  uint32_t mRefCnt;
+
 #ifdef DEBUG
   void AssertStructsNotUsedElsewhere(GeckoStyleContext* aDestroyingContext,
                                      int32_t aLevels) const;
 #endif
 
 private:
   // Helper for ClearCachedInheritedStyleDataOnDescendants.
   void DoClearCachedInheritedStyleDataOnDescendants(uint32_t aStructs);
+  void Destroy();
 
   // Children are kept in two circularly-linked lists.  The list anchor
   // is not part of the list (null for empty), and we point to the first
   // child.
   // mEmptyChild for children whose rule node is the root rule node, and
   // mChild for other children.  The order of children is not
   // meaningful.
   GeckoStyleContext* mChild;
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -79,17 +79,16 @@ const uint32_t nsStyleContext::sDependen
 #endif
 
 nsStyleContext::nsStyleContext(nsStyleContext* aParent,
                                nsIAtom* aPseudoTag,
                                CSSPseudoElementType aPseudoType)
   : mParent(aParent)
   , mPseudoTag(aPseudoTag)
   , mBits(((uint64_t)aPseudoType) << NS_STYLE_CONTEXT_TYPE_SHIFT)
-  , mRefCnt(0)
 #ifdef DEBUG
   , mFrameRefCnt(0)
 #endif
 {}
 
 void
 nsStyleContext::AddChild(nsStyleContext* aChild)
 {
@@ -430,17 +429,18 @@ void nsStyleContext::List(FILE* out, int
 {
   nsAutoCString str;
   // Indent
   int32_t ix;
   for (ix = aIndent; --ix >= 0; ) {
     str.AppendLiteral("  ");
   }
   str.Append(nsPrintfCString("%p(%d) parent=%p ",
-                             (void*)this, mRefCnt, (void *)mParent));
+                             (void*)this, IsGecko() ? AsGecko()->mRefCnt : 0,
+                             (void *)mParent));
   if (mPseudoTag) {
     nsAutoString  buffer;
     mPseudoTag->ToString(buffer);
     AppendUTF16toUTF8(buffer, str);
     str.Append(' ');
   }
 
   if (IsServo()) {
@@ -467,35 +467,16 @@ void nsStyleContext::List(FILE* out, int
   if (aListDescendants) {
     if (GeckoStyleContext* gecko = GetAsGecko()) {
       gecko->ListDescendants(out, aIndent);
     }
   }
 }
 #endif
 
-// Overridden to prevent the global delete from being called, since the memory
-// came out of an nsIArena instead of the global delete operator's heap.
-void
-nsStyleContext::Destroy()
-{
-  if (IsGecko()) {
-    // Get the pres context.
-    RefPtr<nsPresContext> presContext = PresContext();
-    // Call our destructor.
-    this->AsGecko()->~GeckoStyleContext();
-    // Don't let the memory be freed, since it will be recycled
-    // instead. Don't call the global operator delete.
-    presContext->PresShell()->
-      FreeByObjectID(eArenaObjectID_GeckoStyleContext, this);
-  } else {
-    delete static_cast<ServoStyleContext*>(this);
-  }
-}
-
 already_AddRefed<GeckoStyleContext>
 NS_NewStyleContext(GeckoStyleContext* aParentContext,
                    nsIAtom* aPseudoTag,
                    CSSPseudoElementType aPseudoType,
                    nsRuleNode* aRuleNode,
                    bool aSkipParentDisplayBasedStyleFixup)
 {
   RefPtr<nsRuleNode> node = aRuleNode;
--- a/layout/style/nsStyleContext.h
+++ b/layout/style/nsStyleContext.h
@@ -57,18 +57,16 @@ public:
   bool IsGecko() const { return !IsServo(); }
   bool IsServo() const { return (mBits & NS_STYLE_CONTEXT_IS_GECKO) == 0; }
 #else
   bool IsGecko() const { return true; }
   bool IsServo() const { return false; }
 #endif
   MOZ_DECL_STYLO_CONVERT_METHODS(mozilla::GeckoStyleContext, mozilla::ServoStyleContext);
 
-  void Destroy();
-
   // These two methods are for use by ArenaRefPtr.
   static mozilla::ArenaObjectID ArenaObjectID()
   {
     return mozilla::eArenaObjectID_GeckoStyleContext;
   }
   nsIPresShell* Arena();
 
   void AddChild(nsStyleContext* aChild);
@@ -86,23 +84,16 @@ public:
     --mFrameRefCnt;
   }
 
   uint32_t FrameRefCnt() const {
     return mFrameRefCnt;
   }
 #endif
 
-  bool HasSingleReference() const {
-    NS_ASSERTION(mRefCnt != 0,
-                 "do not call HasSingleReference on a newly created "
-                 "nsStyleContext with no references yet");
-    return mRefCnt == 1;
-  }
-
   inline nsPresContext* PresContext() const;
 
   inline mozilla::GeckoStyleContext* GetParent() const;
 
   nsStyleContext* GetParentAllowServo() const {
     return mParent;
   }
 
@@ -355,18 +346,16 @@ protected:
   // mBits stores a number of things:
   //  - It records (using the style struct bits) which structs are
   //    inherited from the parent context or owned by the rule node (i.e.,
   //    not owned by the style context).
   //  - It also stores the additional bits listed at the top of
   //    nsStyleStruct.h.
   uint64_t                mBits;
 
-  uint32_t                mRefCnt;
-
 #ifdef DEBUG
   uint32_t                mFrameRefCnt; // number of frames that use this
                                         // as their style context
 
   static bool DependencyAllowed(nsStyleStructID aOuterSID,
                                 nsStyleStructID aInnerSID)
   {
     return !!(sDependencyTable[aOuterSID] &