diff --git a/xpcom/ds/nsFixedSizeAllocator.h b/xpcom/ds/nsFixedSizeAllocator.h index a9424da7da6..248d660ccfe 100644 --- a/xpcom/ds/nsFixedSizeAllocator.h +++ b/xpcom/ds/nsFixedSizeAllocator.h @@ -156,9 +156,13 @@ protected: FindBucket(size_t aSize); public: - nsFixedSizeAllocator() : mBuckets(nsnull) {} + nsFixedSizeAllocator() : mBuckets(nsnull) + { + MOZ_COUNT_CTOR(nsFixedSizeAllocator); + } ~nsFixedSizeAllocator() { + MOZ_COUNT_DTOR(nsFixedSizeAllocator); if (mBuckets) PL_FinishArenaPool(&mPool); } diff --git a/xpcom/ds/nsHashtable.cpp b/xpcom/ds/nsHashtable.cpp index e36e8997560..e18e409f188 100644 --- a/xpcom/ds/nsHashtable.cpp +++ b/xpcom/ds/nsHashtable.cpp @@ -37,6 +37,7 @@ #include "nsReadableUtils.h" #include "nsIObjectInputStream.h" #include "nsIObjectOutputStream.h" +#include "plarena.h" //////////////////////////////////////////////////////////////////////////////// // These functions really should be part of nspr, and have internal knowledge @@ -164,6 +165,10 @@ static void PR_CALLBACK _hashFreeTable(void *pool, void *item) { } static PLHashEntry * PR_CALLBACK _hashAllocEntry(void *pool, const void *key) { + if (pool) { + return (PLHashEntry*)((nsFixedSizeAllocator*)pool)->Alloc(sizeof(PLHashEntry)); + } + return PR_NEW(PLHashEntry); } @@ -172,7 +177,11 @@ static void PR_CALLBACK _hashFreeEntry(void *pool, PLHashEntry *entry, { if (flag == HT_FREE_ENTRY) { delete (nsHashKey *) (entry->key); - PR_DELETE(entry); + if (pool) { + ((nsFixedSizeAllocator*)pool)->Free((void*)entry, sizeof(PLHashEntry)); + } + else + PR_DELETE(entry); } } @@ -220,13 +229,22 @@ nsHashtable::nsHashtable(PRUint32 aInitSize, PRBool threadSafe) : mLock(NULL), mEnumerating(PR_FALSE) { MOZ_COUNT_CTOR(nsHashtable); + + static const size_t kBucketSizes[] = + { sizeof(PLHashEntry) }; + static const PRInt32 kNumBucketSizes = + sizeof(kBucketSizes) / sizeof(size_t); + + mPool.Init("hashFoo", kBucketSizes, kNumBucketSizes, + sizeof(PLHashEntry)*aInitSize); + PRStatus status = PL_HashTableInit(&mHashtable, aInitSize, _hashValue, _hashKeyCompare, _hashValueCompare, &_hashAllocOps, - NULL); + (void*)&mPool); PR_ASSERT(status == PR_SUCCESS); if (threadSafe) { mLock = PR_NewLock(); diff --git a/xpcom/ds/nsHashtable.h b/xpcom/ds/nsHashtable.h index bf176b7b963..398e95ec93b 100644 --- a/xpcom/ds/nsHashtable.h +++ b/xpcom/ds/nsHashtable.h @@ -39,6 +39,8 @@ #include "nsCom.h" #include "nsString.h" +#include "nsFixedSizeAllocator.h" + class nsIObjectInputStream; class nsIObjectOutputStream; @@ -107,6 +109,7 @@ class NS_COM nsHashtable { PRLock* mLock; PLHashTable mHashtable; PRBool mEnumerating; + nsFixedSizeAllocator mPool; public: nsHashtable(PRUint32 aSize = 16, PRBool threadSafe = PR_FALSE); diff --git a/xpcom/ds/nsStaticNameTable.cpp b/xpcom/ds/nsStaticNameTable.cpp index 1d03ac04edb..7e9c3aaacc6 100644 --- a/xpcom/ds/nsStaticNameTable.cpp +++ b/xpcom/ds/nsStaticNameTable.cpp @@ -37,21 +37,16 @@ #include "nscore.h" #include "nsString.h" #include "nsStaticNameTable.h" -#include "nsReadableUtils.h" nsStaticCaseInsensitiveNameTable::nsStaticCaseInsensitiveNameTable() - : mNameArray(nsnull), mNameTable(nsnull), mCount(0), mNullStr("") + : mNameArray(nsnull), mNameTable(nsnull), mCount(0) { MOZ_COUNT_CTOR(nsStaticCaseInsensitiveNameTable); } nsStaticCaseInsensitiveNameTable::~nsStaticCaseInsensitiveNameTable() { - // manually call the destructor on placement-new'ed objects - for (PRInt32 index = 0; index < mCount; index++) { - mNameArray[index].~nsDependentCString(); - } - nsMemory::Free((void*)mNameArray); + delete [] mNameArray; delete mNameTable; MOZ_COUNT_DTOR(nsStaticCaseInsensitiveNameTable); } @@ -65,7 +60,7 @@ nsStaticCaseInsensitiveNameTable::Init(const char* Names[], PRInt32 Count) NS_ASSERTION(Count, "0 count"); mCount = Count; - mNameArray = (nsDependentCString*)nsMemory::Alloc(Count * sizeof(nsDependentCString)); + mNameArray = new nsCString[Count]; // XXX best bucket count heuristic? mNameTable = new nsHashtable(Count<16 ? Count : Count<128 ? Count/4 : 128); if (!mNameArray || !mNameTable) { @@ -75,18 +70,17 @@ nsStaticCaseInsensitiveNameTable::Init(const char* Names[], PRInt32 Count) for (PRInt32 index = 0; index < Count; ++index) { char* raw = (char*) Names[index]; PRUint32 len = nsCRT::strlen(raw); + nsStr* str = NS_STATIC_CAST(nsStr*, &mNameArray[index]); #ifdef DEBUG { // verify invarients of contents nsCAutoString temp1(raw); - nsDependentCString temp2(raw); + nsCAutoString temp2(raw); temp1.ToLowerCase(); NS_ASSERTION(temp1.Equals(temp2), "upper case char in table"); } -#endif - // use placement-new to initialize the string object - nsDependentCString *str = - new (&mNameArray[index]) nsDependentCString(raw); +#endif + nsStr::Initialize(*str, raw, len, len, eOneByte, PR_FALSE); nsCStringKey key(raw, len, nsCStringKey::NEVER_OWN); mNameTable->Put(&key, (void*)(index+1)); // to make 0 != nsnull } @@ -94,7 +88,7 @@ nsStaticCaseInsensitiveNameTable::Init(const char* Names[], PRInt32 Count) } inline PRInt32 -LookupLowercasedKeyword(const nsACString& aLowercasedKeyword, +LookupLowercasedKeyword(const nsCString& aLowercasedKeyword, nsHashtable* aTable) { nsCStringKey key(aLowercasedKeyword); @@ -128,7 +122,7 @@ nsStaticCaseInsensitiveNameTable::Lookup(const nsAString& aName) return LookupLowercasedKeyword(strLower, mNameTable); } -const nsAFlatCString& +const nsCString& nsStaticCaseInsensitiveNameTable::GetStringValue(PRInt32 index) { NS_ASSERTION(mNameArray, "not inited");