Bug 1188721 - Part 1: Add an nsStyleStruct superclass that stores a refcount. r?dbaron draft
authorCameron McCormack <cam@mcc.id.au>
Wed, 23 Mar 2016 17:35:57 +1100
changeset 343751 96d6c4613ef8194dc35333bc34b1e736652af617
parent 343645 3381aa98edf72e02b9d6b4db6efa0865063a2329
child 343752 c479cf7d499edbe188760444b9dc898be3920953
push id13680
push usercmccormack@mozilla.com
push dateWed, 23 Mar 2016 06:36:18 +0000
reviewersdbaron
bugs1188721
milestone48.0a1
Bug 1188721 - Part 1: Add an nsStyleStruct superclass that stores a refcount. r?dbaron MozReview-Commit-ID: Iu5hGOwsFXZ
layout/style/nsStyleStruct.h
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -93,19 +93,50 @@ struct nsStyleVisibility;
 #define NS_RULE_NODE_HAS_ANIMATION_DATA     0x80000000
 
 static_assert(int(mozilla::SheetType::Count) - 1 <=
                 (NS_RULE_NODE_LEVEL_MASK >> NS_RULE_NODE_LEVEL_SHIFT),
               "NS_RULE_NODE_LEVEL_MASK cannot fit SheetType");
 
 static_assert(NS_RULE_NODE_IS_ANIMATION_RULE == (1 << nsStyleStructID_Length),
   "NS_RULE_NODE_IS_ANIMATION_RULE must not overlap the style struct bits.");
+
 // The lifetime of these objects is managed by the presshell's arena.
 
-struct nsStyleFont
+class nsStyleStruct
+{
+public:
+  MozRefCountType AddRef() {
+    if (mRefCnt == UINT32_MAX) {
+      NS_WARNING("refcount overflow, leaking object");
+      return mRefCnt;
+    }
+    return ++mRefCnt;
+  }
+
+  MOZ_MUST_USE MozRefCountType ReleaseWithoutDestroying() {
+    if (mRefCnt == UINT32_MAX) {
+      NS_WARNING("refcount overflow, leaking object");
+      return mRefCnt;
+    }
+    return --mRefCnt;
+  }
+
+protected:
+  nsStyleStruct() : mRefCnt(0) {}
+  nsStyleStruct(const nsStyleStruct& aOther) {}
+  nsStyleStruct& operator=(const nsStyleStruct& aOther) {
+    // Don't copy mRefCnt.
+    return *this;
+  }
+
+  MozRefCountType mRefCnt;
+};
+
+struct nsStyleFont : public nsStyleStruct
 {
   nsStyleFont(const nsFont& aFont, nsPresContext *aPresContext);
   nsStyleFont(const nsStyleFont& aStyleFont);
   explicit nsStyleFont(nsPresContext *aPresContext);
   ~nsStyleFont(void) {
     MOZ_COUNT_DTOR(nsStyleFont);
   }
 
@@ -363,17 +394,17 @@ private:
 
   // This is _currently_ used only in conjunction with eStyleImageType_Image.
   nsAutoPtr<nsStyleSides> mCropRect;
 #ifdef DEBUG
   bool mImageTracked;
 #endif
 };
 
-struct nsStyleColor
+struct nsStyleColor : public nsStyleStruct
 {
   explicit nsStyleColor(nsPresContext* aPresContext);
   nsStyleColor(const nsStyleColor& aOther);
   ~nsStyleColor(void) {
     MOZ_COUNT_DTOR(nsStyleColor);
   }
 
   nsChangeHint CalcDifference(const nsStyleColor& aOther) const;
@@ -665,17 +696,18 @@ struct nsStyleImageLayers {
   #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(var_, layers_) \
     for (uint32_t var_ = (layers_).mImageCount; var_-- != 0; )
   #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, layers_, start_, count_) \
     NS_ASSERTION((int32_t)(start_) >= 0 && (uint32_t)(start_) < (layers_).mImageCount, "Invalid layer start!"); \
     NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1, "Invalid layer range!"); \
     for (uint32_t var_ = (start_) + 1; var_-- != (uint32_t)((start_) + 1 - (count_)); )
 };
 
-struct nsStyleBackground {
+struct nsStyleBackground : public nsStyleStruct
+{
   nsStyleBackground();
   nsStyleBackground(const nsStyleBackground& aOther);
   ~nsStyleBackground();
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleBackground, sz);
   }
@@ -717,17 +749,17 @@ struct nsStyleBackground {
 #define BORDER_COLOR_SPECIAL      0xA0
 #define BORDER_STYLE_MASK         0x1F
 
 #define NS_SPACING_MARGIN   0
 #define NS_SPACING_PADDING  1
 #define NS_SPACING_BORDER   2
 
 
-struct nsStyleMargin
+struct nsStyleMargin : public nsStyleStruct
 {
   nsStyleMargin(void);
   nsStyleMargin(const nsStyleMargin& aMargin);
   ~nsStyleMargin(void) {
     MOZ_COUNT_DTOR(nsStyleMargin);
   }
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
@@ -762,17 +794,17 @@ struct nsStyleMargin
   }
 
 protected:
   bool          mHasCachedMargin;
   nsMargin      mCachedMargin;
 };
 
 
-struct nsStylePadding
+struct nsStylePadding : public nsStyleStruct
 {
   nsStylePadding(void);
   nsStylePadding(const nsStylePadding& aPadding);
   ~nsStylePadding(void) {
     MOZ_COUNT_DTOR(nsStylePadding);
   }
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
@@ -964,17 +996,17 @@ private:
 
 // Returns if the given border style type is visible or not
 static bool IsVisibleBorderStyle(uint8_t aStyle)
 {
   return (aStyle != NS_STYLE_BORDER_STYLE_NONE &&
           aStyle != NS_STYLE_BORDER_STYLE_HIDDEN);
 }
 
-struct nsStyleBorder
+struct nsStyleBorder : public nsStyleStruct
 {
   explicit nsStyleBorder(nsPresContext* aContext);
   nsStyleBorder(const nsStyleBorder& aBorder);
   ~nsStyleBorder();
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleBorder, sz);
@@ -1191,17 +1223,17 @@ protected:
                                   // border.  not used for -moz-border-colors
 private:
   nscoord       mTwipsPerPixel;
 
   nsStyleBorder& operator=(const nsStyleBorder& aOther) = delete;
 };
 
 
-struct nsStyleOutline
+struct nsStyleOutline : public nsStyleStruct
 {
   explicit nsStyleOutline(nsPresContext* aPresContext);
   nsStyleOutline(const nsStyleOutline& aOutline);
   ~nsStyleOutline(void) {
     MOZ_COUNT_DTOR(nsStyleOutline);
   }
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
@@ -1290,17 +1322,17 @@ protected:
 
   bool          mHasCachedOutline;
   uint8_t       mOutlineStyle;    // [reset] See nsStyleConsts.h
 
   nscoord       mTwipsPerPixel;
 };
 
 
-struct nsStyleList
+struct nsStyleList : public nsStyleStruct
 {
   explicit nsStyleList(nsPresContext* aPresContext);
   nsStyleList(const nsStyleList& aStyleList);
   ~nsStyleList(void);
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleList, sz);
@@ -1497,17 +1529,17 @@ struct nsStyleGridTemplate
   }
 
   bool IsRepeatAutoIndex(uint32_t aIndex) const {
     MOZ_ASSERT(aIndex < uint32_t(2*nsStyleGridLine::kMaxLine));
     return int32_t(aIndex) == mRepeatAutoIndex;
   }
 };
 
-struct nsStylePosition
+struct nsStylePosition : public nsStyleStruct
 {
   nsStylePosition(void);
   nsStylePosition(const nsStylePosition& aOther);
   ~nsStylePosition(void);
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStylePosition, sz);
@@ -1747,17 +1779,17 @@ struct nsStyleTextOverflow
     return mLogicalDirections ? nullptr : &mRight;
   }
 
   nsStyleTextOverflowSide mLeft;  // start side when mLogicalDirections is true
   nsStyleTextOverflowSide mRight; // end side when mLogicalDirections is true
   bool mLogicalDirections;  // true when only one value was specified
 };
 
-struct nsStyleTextReset
+struct nsStyleTextReset : public nsStyleStruct
 {
   nsStyleTextReset(void);
   nsStyleTextReset(const nsStyleTextReset& aOther);
   ~nsStyleTextReset(void);
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleTextReset, sz);
@@ -1832,17 +1864,17 @@ struct nsStyleTextReset
   uint8_t mTextDecorationLine;          // [reset] see nsStyleConsts.h
   uint8_t mUnicodeBidi;                 // [reset] see nsStyleConsts.h
 protected:
   uint8_t mTextDecorationStyle;         // [reset] see nsStyleConsts.h
 
   nscolor mTextDecorationColor;         // [reset] the colors to use for a decoration lines, not used at currentColor
 };
 
-struct nsStyleText
+struct nsStyleText : public nsStyleStruct
 {
   explicit nsStyleText(nsPresContext* aPresContext);
   nsStyleText(const nsStyleText& aOther);
   ~nsStyleText(void);
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleText, sz);
@@ -2038,17 +2070,17 @@ protected:
 
   explicit nsStyleImageOrientation(uint8_t aOrientation)
     : mOrientation(aOrientation)
   { }
 
   uint8_t mOrientation;
 };
 
-struct nsStyleVisibility
+struct nsStyleVisibility : public nsStyleStruct
 {
   explicit nsStyleVisibility(nsPresContext* aPresContext);
   nsStyleVisibility(const nsStyleVisibility& aVisibility);
   ~nsStyleVisibility() {
     MOZ_COUNT_DTOR(nsStyleVisibility);
   }
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
@@ -2318,17 +2350,17 @@ private:
   dom::PlaybackDirection mDirection;
   dom::FillMode mFillMode;
   uint8_t mPlayState;
   float mIterationCount; // mozilla::PositiveInfinity<float>() means infinite
 };
 
 } // namespace mozilla
 
-struct nsStyleDisplay
+struct nsStyleDisplay : public nsStyleStruct
 {
   nsStyleDisplay();
   nsStyleDisplay(const nsStyleDisplay& aOther);
   ~nsStyleDisplay() {
     MOZ_COUNT_DTOR(nsStyleDisplay);
   }
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
@@ -2598,17 +2630,17 @@ struct nsStyleDisplay
 
   // Return the 'float' and 'clear' properties, with inline-{start,end} values
   // resolved to {left,right} according to the given writing mode. These are
   // defined in WritingModes.h.
   inline uint8_t PhysicalFloats(mozilla::WritingMode aWM) const;
   inline uint8_t PhysicalBreakType(mozilla::WritingMode aWM) const;
 };
 
-struct nsStyleTable
+struct nsStyleTable : public nsStyleStruct
 {
   nsStyleTable(void);
   nsStyleTable(const nsStyleTable& aOther);
   ~nsStyleTable(void);
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleTable, sz);
@@ -2630,17 +2662,17 @@ struct nsStyleTable
            nsChangeHint_ReflowChangesSizeOrPosition |
            nsChangeHint_ClearAncestorIntrinsics;
   }
 
   uint8_t       mLayoutStrategy;// [reset] see nsStyleConsts.h NS_STYLE_TABLE_LAYOUT_*
   int32_t       mSpan;          // [reset] the number of columns spanned by a colgroup or col
 };
 
-struct nsStyleTableBorder
+struct nsStyleTableBorder : public nsStyleStruct
 {
   nsStyleTableBorder();
   nsStyleTableBorder(const nsStyleTableBorder& aOther);
   ~nsStyleTableBorder(void);
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleTableBorder, sz);
@@ -2729,17 +2761,17 @@ struct nsStyleCounterData
 {
   nsString  mCounter;
   int32_t   mValue;
 };
 
 
 #define DELETE_ARRAY_IF(array)  if (array) { delete[] array; array = nullptr; }
 
-struct nsStyleQuotes
+struct nsStyleQuotes : public nsStyleStruct
 {
   nsStyleQuotes();
   nsStyleQuotes(const nsStyleQuotes& aQuotes);
   ~nsStyleQuotes();
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleQuotes, sz);
@@ -2812,17 +2844,17 @@ struct nsStyleQuotes
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
 protected:
   uint32_t            mQuotesCount;
   nsString*           mQuotes;
 };
 
-struct nsStyleContent
+struct nsStyleContent : public nsStyleStruct
 {
   nsStyleContent(void);
   nsStyleContent(const nsStyleContent& aContent);
   ~nsStyleContent(void);
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleContent, sz);
@@ -2922,17 +2954,17 @@ protected:
   nsStyleCounterData* mIncrements;
   nsStyleCounterData* mResets;
 
   uint32_t            mContentCount;
   uint32_t            mIncrementCount;
   uint32_t            mResetCount;
 };
 
-struct nsStyleUIReset
+struct nsStyleUIReset : public nsStyleStruct
 {
   nsStyleUIReset(void);
   nsStyleUIReset(const nsStyleUIReset& aOther);
   ~nsStyleUIReset(void);
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleUIReset, sz);
@@ -2987,17 +3019,17 @@ struct nsCursorImage
   imgIRequest* GetImage() const {
     return mImage;
   }
 
 private:
   nsCOMPtr<imgIRequest> mImage;
 };
 
-struct nsStyleUserInterface
+struct nsStyleUserInterface : public nsStyleStruct
 {
   nsStyleUserInterface(void);
   nsStyleUserInterface(const nsStyleUserInterface& aOther);
   ~nsStyleUserInterface(void);
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleUserInterface, sz);
@@ -3034,17 +3066,17 @@ struct nsStyleUserInterface
                               //   mCursor.  Zero-length array is represented
                               //   by null pointer.
 
   // Does not free mCursorArray; the caller is responsible for calling
   // |delete [] mCursorArray| first if it is needed.
   void CopyCursorArrayFrom(const nsStyleUserInterface& aSource);
 };
 
-struct nsStyleXUL
+struct nsStyleXUL : public nsStyleStruct
 {
   nsStyleXUL();
   nsStyleXUL(const nsStyleXUL& aSource);
   ~nsStyleXUL();
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleXUL, sz);
@@ -3071,17 +3103,17 @@ struct nsStyleXUL
   uint32_t      mBoxOrdinal;            // [reset] see nsStyleConsts.h
   uint8_t       mBoxAlign;              // [reset] see nsStyleConsts.h
   uint8_t       mBoxDirection;          // [reset] see nsStyleConsts.h
   uint8_t       mBoxOrient;             // [reset] see nsStyleConsts.h
   uint8_t       mBoxPack;               // [reset] see nsStyleConsts.h
   bool          mStretchStack;          // [reset] see nsStyleConsts.h
 };
 
-struct nsStyleColumn
+struct nsStyleColumn : public nsStyleStruct
 {
   explicit nsStyleColumn(nsPresContext* aPresContext);
   nsStyleColumn(const nsStyleColumn& aSource);
   ~nsStyleColumn();
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleColumn, sz);
@@ -3165,17 +3197,17 @@ struct nsStyleSVGPaint
   nsStyleSVGPaint& operator=(const nsStyleSVGPaint& aOther);
   bool operator==(const nsStyleSVGPaint& aOther) const;
 
   bool operator!=(const nsStyleSVGPaint& aOther) const {
     return !(*this == aOther);
   }
 };
 
-struct nsStyleSVG
+struct nsStyleSVG : public nsStyleStruct
 {
   nsStyleSVG();
   nsStyleSVG(const nsStyleSVG& aSource);
   ~nsStyleSVG();
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleSVG, sz);
@@ -3452,17 +3484,17 @@ private:
 };
 
 template<>
 struct nsTArray_CopyChooser<nsStyleFilter>
 {
   typedef nsTArray_CopyWithConstructors<nsStyleFilter> Type;
 };
 
-struct nsStyleSVGReset
+struct nsStyleSVGReset : public nsStyleStruct
 {
   nsStyleSVGReset();
   nsStyleSVGReset(const nsStyleSVGReset& aSource);
   ~nsStyleSVGReset();
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleSVGReset, sz);
@@ -3507,17 +3539,17 @@ struct nsStyleSVGReset
   float            mStopOpacity;      // [reset]
   float            mFloodOpacity;     // [reset]
 
   uint8_t          mDominantBaseline; // [reset] see nsStyleConsts.h
   uint8_t          mVectorEffect;     // [reset] see nsStyleConsts.h
   uint8_t          mMaskType;         // [reset] see nsStyleConsts.h
 };
 
-struct nsStyleVariables
+struct nsStyleVariables : public nsStyleStruct
 {
   nsStyleVariables();
   nsStyleVariables(const nsStyleVariables& aSource);
   ~nsStyleVariables();
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->PresShell()->
       AllocateByObjectID(mozilla::eArenaObjectID_nsStyleVariables, sz);