Add nsStyleContext::Alloc for allocations scoped to the lifetime of the style context. (Bug 363249) r=bzbarsky

This commit is contained in:
L. David Baron 2010-07-02 21:18:55 -07:00
parent 7588d7dc90
commit f66de32fe0
2 changed files with 63 additions and 0 deletions

View File

@ -70,6 +70,7 @@ nsStyleContext::nsStyleContext(nsStyleContext* aParent,
mEmptyChild(nsnull),
mPseudoTag(aPseudoTag),
mRuleNode(aRuleNode),
mAllocations(nsnull),
mCachedResetData(nsnull),
mBits(((PRUint32)aPseudoType) << NS_STYLE_CONTEXT_TYPE_SHIFT),
mRefCnt(0)
@ -123,6 +124,8 @@ nsStyleContext::~nsStyleContext()
if (mCachedResetData) {
mCachedResetData->Destroy(mBits, presContext);
}
FreeAllocations(presContext);
}
void nsStyleContext::AddChild(nsStyleContext* aChild)
@ -768,3 +771,31 @@ nsStyleContext::CombineVisitedColors(nscolor *aColors, PRBool aLinkIsVisited)
return NS_RGBA(NS_GET_R(colorColor), NS_GET_G(colorColor),
NS_GET_B(colorColor), NS_GET_A(alphaColor));
}
void*
nsStyleContext::Alloc(size_t aSize)
{
nsIPresShell *shell = PresContext()->PresShell();
aSize += offsetof(AllocationHeader, mStorageStart);
AllocationHeader *alloc =
static_cast<AllocationHeader*>(shell->AllocateMisc(aSize));
alloc->mSize = aSize; // NOTE: inflated by header
alloc->mNext = mAllocations;
mAllocations = alloc;
return static_cast<void*>(&alloc->mStorageStart);
}
void
nsStyleContext::FreeAllocations(nsPresContext *aPresContext)
{
nsIPresShell *shell = aPresContext->PresShell();
for (AllocationHeader *alloc = mAllocations, *next; alloc; alloc = next) {
next = alloc->mNext;
shell->FreeMisc(alloc->mSize, alloc);
}
}

View File

@ -301,6 +301,27 @@ public:
static nscolor CombineVisitedColors(nscolor *aColors,
PRBool aLinkIsVisited);
/**
* Allocate a chunk of memory that is scoped to the lifetime of this
* style context, i.e., memory that will automatically be freed when
* this style context is destroyed. This is intended for allocations
* that are stored on this style context or its style structs. (Use
* on style structs is fine since any style context to which this
* context's style structs are shared will be a descendant of this
* style context and thus keep it alive.)
*
* This currently allocates the memory out of the pres shell arena.
*
* It would be relatively straightforward to write a Free method
* for the underlying implementation, but we don't need it (or the
* overhead of making a doubly-linked list or other structure to
* support it).
*
* WARNING: Memory allocated using this method cannot be stored in the
* rule tree, since rule nodes may outlive the style context.
*/
void* Alloc(size_t aSize);
#ifdef DEBUG
void List(FILE* out, PRInt32 aIndent);
#endif
@ -311,6 +332,8 @@ protected:
void ApplyStyleFixups(nsPresContext* aPresContext);
void FreeAllocations(nsPresContext* aPresContext);
// Helper function that GetStyleData and GetUniqueStyleData use. Only
// returns the structs we cache ourselves; never consults the ruletree.
inline const void* GetCachedStyleData(nsStyleStructID aSID);
@ -368,6 +391,15 @@ protected:
// |mRule| member of |mRuleNode|.
nsRuleNode* const mRuleNode;
// Private to nsStyleContext::Alloc and FreeAllocations.
struct AllocationHeader {
AllocationHeader* mNext;
size_t mSize;
void* mStorageStart; // ensure the storage is at least pointer-aligned
};
AllocationHeader* mAllocations;
// mCachedInheritedData and mCachedResetData point to both structs that
// are owned by this style context and structs that are owned by one of
// this style context's ancestors (which are indirectly owned since this