Bug 278443: Use an Arena to allocate nsNodeInfos. Patch by smaug@welho.com.

r=sicking sr=peterv
This commit is contained in:
cvshook%sicking.cc 2005-01-28 22:58:37 +00:00
parent c66cf17ee4
commit c3c6872cf6
2 changed files with 52 additions and 30 deletions

View File

@ -45,6 +45,18 @@
#include "nsCRT.h"
#include "nsContentUtils.h"
#include "nsReadableUtils.h"
#include NEW_H
#include "nsFixedSizeAllocator.h"
static const size_t kNodeInfoPoolSizes[] = {
sizeof(nsNodeInfo)
};
static const PRInt32 kNodeInfoPoolInitialSize =
(NS_SIZE_IN_HEAP(sizeof(nsNodeInfo))) * 64;
// static
nsFixedSizeAllocator* nsNodeInfo::sNodeInfoPool = nsnull;
// static
nsNodeInfo*
@ -57,34 +69,30 @@ nsNodeInfo::Create()
sCachedNodeInfo = nsnull;
return nodeInfo;
}
if (!sNodeInfoPool) {
sNodeInfoPool = new nsFixedSizeAllocator();
if (!sNodeInfoPool)
return nsnull;
nsresult rv = sNodeInfoPool->Init("NodeInfo Pool", kNodeInfoPoolSizes,
1, kNodeInfoPoolInitialSize);
if (NS_FAILED(rv)) {
delete sNodeInfoPool;
sNodeInfoPool = nsnull;
return nsnull;
}
}
// Create a new one
return new nsNodeInfo();
void* place = sNodeInfoPool->Alloc(sizeof(nsNodeInfo));
return place ? new (place) nsNodeInfo() : nsnull;
}
nsNodeInfo::nsNodeInfo()
{
}
nsNodeInfo::~nsNodeInfo()
{
Clear();
}
void
nsNodeInfo::Clear()
{
if (mOwnerManager) {
mOwnerManager->RemoveNodeInfo(this);
NS_RELEASE(mOwnerManager);
}
NS_IF_RELEASE(mInner.mName);
NS_IF_RELEASE(mInner.mPrefix);
}
nsresult
nsNodeInfo::Init(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
nsNodeInfoManager *aOwnerManager)
@ -269,16 +277,33 @@ void
nsNodeInfo::ClearCache()
{
// Clear our cache.
delete sCachedNodeInfo;
sCachedNodeInfo = nsnull;
if (sNodeInfoPool) {
if (sCachedNodeInfo) {
sNodeInfoPool->Free(sCachedNodeInfo, sizeof(nsNodeInfo));
sCachedNodeInfo = nsnull;
}
delete sNodeInfoPool;
sNodeInfoPool = nsnull;
}
}
void
nsNodeInfo::LastRelease()
{
// Clear object so that we have no references to anything external
if (mOwnerManager) {
mOwnerManager->RemoveNodeInfo(this);
NS_RELEASE(mOwnerManager);
}
NS_IF_RELEASE(mInner.mName);
NS_IF_RELEASE(mInner.mPrefix);
mIDAttributeAtom = nsnull;
if (sCachedNodeInfo) {
// No room in cache
delete this;
sNodeInfoPool->Free(this, sizeof(nsNodeInfo));
return;
}
@ -286,9 +311,6 @@ nsNodeInfo::LastRelease()
// this instance in the cache instead of deleting it.
sCachedNodeInfo = this;
// Clear object so that we have no references to anything external
Clear();
// The refcount balancing and destructor re-entrancy protection
// code in Release() sets mRefCnt to 1 so we have to set it to 0
// here to prevent leaks

View File

@ -44,6 +44,8 @@
#include "nsIAtom.h"
#include "nsCOMPtr.h"
class nsFixedSizeAllocator;
class nsNodeInfo : public nsINodeInfo
{
public:
@ -78,8 +80,6 @@ public:
static nsNodeInfo *Create();
private:
nsNodeInfo();
protected:
virtual ~nsNodeInfo();
public:
/*
@ -98,10 +98,10 @@ public:
static void ClearCache();
private:
void Clear();
static nsNodeInfo *sCachedNodeInfo;
static nsFixedSizeAllocator* sNodeInfoPool;
/**
* This method gets called by Release() when it's time to delete
* this object, instead of always deleting the object we'll put the