--- 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);