Bug 1384114: Move mRefCnt, Destroy() and HasSingleReference() to GeckoStyleContext. r?bholley
MozReview-Commit-ID: 5XzFYcohl3m
--- 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] &