import changes from `dev' branch of rmottola/Arctic-Fox:

- pointer style (8365db72a)
- remove stackDepth check not found anywhere in official gecko (98f65d05e)
- Bug 1134198 - Call Debugger::onPop at the point that caused the frame to pop before any unwinding in the JIT. (r=jandem) (5aea98ae6)
- Bug 1189750 - Remove unused JM-related PCCounts counters. r=bhackett (7410480af)
- Bug 1198245 - IonMonkey: Lock helperthread before finishing ionbuilder, r=jandem (0f28ef66a)
- Bug 1188620 - Use PersistentRooted for asyncActivation roots; r=fitzgen (4f6ae0e92)
- Bug 1190446 - Update Coverage information in Baseline. r=jandem (95935926e)
- Bug 1188129 - Use a universal constructor to create and init PersistentRooted; r=jonco (75db7ea8f)
- Bug 1187767 - Ensure PLDHashTable's generation is always updated when the entry store is modified. r=froydnj. (e49936dad)
- Bug 1189156 (part 1) - Don't use enumeration style for PLDHashTable::SizeOf{In,Ex}cludingThis(). r=froydnj. (3152ab914)
- Bug 1189156 (part 2) - Don't use enumeration style for nsTHashtable::SizeOf{In,Ex}cludingThis(). r=erahm. (de21442b7)
- Bug 1189156 (part 3) - Factor out FontTable better. r=jfkthame. (afdee9bd7)
- Bug 1189156 (part 4) - Don't use enumeration style for nsBaseHashtable::SizeOf{In,Ex}cludingThis(). r=erahm,jfkthame. (32d72520f)
- Bug 1189156 (part 5) - Add FontEntryTable typedef and factor out some related code. r=jfkthame. (9983134a9)
- Bug 1137437 - move security/apps/ cert header generation to moz.build; r=mshal,keeler (2f7abb37d)
- Bug 1180993 - Part 3: Correct use sites of functions which return already_AddRefed. r=ehsan (2a6289b6a)
This commit is contained in:
2021-08-30 09:33:31 +08:00
parent be0dbe88f0
commit d43e6f58e1
73 changed files with 829 additions and 1432 deletions
+3 -3
View File
@@ -475,9 +475,9 @@ CycleCollectedJSRuntime::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = 0;
// nullptr for the second arg; we're not measuring anything hanging off the
// entries in mJSHolders.
n += mJSHolders.SizeOfExcludingThis(nullptr, aMallocSizeOf);
// We're deliberately not measuring anything hanging off the entries in
// mJSHolders.
n += mJSHolders.ShallowSizeOfExcludingThis(aMallocSizeOf);
return n;
}
+6 -14
View File
@@ -318,7 +318,7 @@ CategoryNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf)
{
// We don't measure the strings pointed to by the entries because the
// pointers are non-owning.
return mTable.SizeOfExcludingThis(nullptr, aMallocSizeOf);
return mTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
}
//
@@ -455,17 +455,6 @@ nsCategoryManager::CollectReports(nsIHandleReportCallback* aHandleReport,
"Memory used for the XPCOM category manager.");
}
static size_t
SizeOfCategoryManagerTableEntryExcludingThis(nsDepCharHashKey::KeyType aKey,
const nsAutoPtr<CategoryNode>& aData,
MallocSizeOf aMallocSizeOf,
void* aUserArg)
{
// We don't measure the string pointed to by aKey because it's a non-owning
// pointer.
return aData.get()->SizeOfExcludingThis(aMallocSizeOf);
}
size_t
nsCategoryManager::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
{
@@ -473,8 +462,11 @@ nsCategoryManager::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
n += PL_SizeOfArenaPoolExcludingPool(&mArena, aMallocSizeOf);
n += mTable.SizeOfExcludingThis(SizeOfCategoryManagerTableEntryExcludingThis,
aMallocSizeOf);
n += mTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (auto iter = mTable.ConstIter(); !iter.Done(); iter.Next()) {
// We don't measure the key string because it's a non-owning pointer.
n += iter.Data().get()->SizeOfExcludingThis(aMallocSizeOf);
}
return n;
}
+16 -26
View File
@@ -1810,26 +1810,6 @@ nsComponentManagerImpl::ContractIDToCID(const char* aContractID,
return NS_ERROR_FACTORY_NOT_REGISTERED;
}
static size_t
SizeOfFactoriesEntryExcludingThis(nsIDHashKey::KeyType aKey,
nsFactoryEntry* const& aData,
MallocSizeOf aMallocSizeOf,
void* aUserArg)
{
return aData->SizeOfIncludingThis(aMallocSizeOf);
}
static size_t
SizeOfContractIDsEntryExcludingThis(nsCStringHashKey::KeyType aKey,
nsFactoryEntry* const& aData,
MallocSizeOf aMallocSizeOf,
void* aUserArg)
{
// We don't measure the nsFactoryEntry data because its owned by mFactories
// (which measures them in SizeOfFactoriesEntryExcludingThis).
return aKey.SizeOfExcludingThisMustBeUnshared(aMallocSizeOf);
}
MOZ_DEFINE_MALLOC_SIZE_OF(ComponentManagerMallocSizeOf)
NS_IMETHODIMP
@@ -1844,19 +1824,29 @@ nsComponentManagerImpl::CollectReports(nsIHandleReportCallback* aHandleReport,
size_t
nsComponentManagerImpl::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
const
{
size_t n = aMallocSizeOf(this);
n += mLoaderMap.SizeOfExcludingThis(nullptr, aMallocSizeOf);
n += mFactories.SizeOfExcludingThis(SizeOfFactoriesEntryExcludingThis,
aMallocSizeOf);
n += mContractIDs.SizeOfExcludingThis(SizeOfContractIDsEntryExcludingThis,
aMallocSizeOf);
n += mLoaderMap.ShallowSizeOfExcludingThis(aMallocSizeOf);
n += mFactories.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (auto iter = mFactories.ConstIter(); !iter.Done(); iter.Next()) {
n += iter.Data()->SizeOfIncludingThis(aMallocSizeOf);
}
n += mContractIDs.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (auto iter = mContractIDs.ConstIter(); !iter.Done(); iter.Next()) {
// We don't measure the nsFactoryEntry data because it's owned by
// mFactories (which is measured above).
n += iter.Key().SizeOfExcludingThisMustBeUnshared(aMallocSizeOf);
}
n += sStaticModules->ShallowSizeOfIncludingThis(aMallocSizeOf);
n += sModuleLocations->ShallowSizeOfIncludingThis(aMallocSizeOf);
n += mKnownStaticModules.ShallowSizeOfExcludingThis(aMallocSizeOf);
n += mKnownModules.SizeOfExcludingThis(nullptr, aMallocSizeOf);
n += mKnownModules.ShallowSizeOfExcludingThis(aMallocSizeOf);
n += PL_SizeOfArenaPoolExcludingPool(&mArena, aMallocSizeOf);
+1 -1
View File
@@ -336,7 +336,7 @@ public:
nsTArray<PendingServiceInfo> mPendingServices;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
#ifdef MOZ_B2G_LOADER
// Preload XPT interface info for B2G loader.
+10 -16
View File
@@ -502,29 +502,23 @@ AtomImpl::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf)
//----------------------------------------------------------------------
static size_t
SizeOfAtomTableEntryExcludingThis(PLDHashEntryHdr* aHdr,
MallocSizeOf aMallocSizeOf,
void* aArg)
{
AtomTableEntry* entry = static_cast<AtomTableEntry*>(aHdr);
return entry->mAtom->SizeOfIncludingThis(aMallocSizeOf);
}
void
NS_SizeOfAtomTablesIncludingThis(MallocSizeOf aMallocSizeOf,
size_t* aMain, size_t* aStatic)
{
*aMain = gAtomTable
? PL_DHashTableSizeOfExcludingThis(gAtomTable,
SizeOfAtomTableEntryExcludingThis,
aMallocSizeOf)
: 0;
*aMain = 0;
if (gAtomTable) {
*aMain += gAtomTable->ShallowSizeOfIncludingThis(aMallocSizeOf);
for (auto iter = gAtomTable->Iter(); !iter.Done(); iter.Next()) {
auto entry = static_cast<AtomTableEntry*>(iter.Get());
*aMain += entry->mAtom->SizeOfIncludingThis(aMallocSizeOf);
}
}
// The atoms in the this table are almost certainly stored in static data, so
// we don't need a SizeOfEntry function.
// we don't need to measure entries separately.
*aStatic = gStaticAtomTable
? gStaticAtomTable->SizeOfIncludingThis(nullptr, aMallocSizeOf)
? gStaticAtomTable->ShallowSizeOfIncludingThis(aMallocSizeOf)
: 0;
}
+5 -10
View File
@@ -144,15 +144,6 @@ public:
PR_DestroyLock(mLock);
}
static size_t
SizeOfEntryExcludingThis(const T* aKey, const nsAutoPtr<OrderingEntry>& aEntry,
MallocSizeOf aMallocSizeOf, void* aUserArg)
{
// NB: Key is accounted for in the entry.
size_t n = aEntry->SizeOfIncludingThis(aMallocSizeOf);
return n;
}
size_t
SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
@@ -160,7 +151,11 @@ public:
{
PRAutoLock _(mLock);
n += mOrdering.SizeOfExcludingThis(SizeOfEntryExcludingThis, aMallocSizeOf);
n += mOrdering.ShallowSizeOfExcludingThis(aMallocSizeOf);
for (auto iter = mOrdering.ConstIter(); !iter.Done(); iter.Next()) {
// NB: Key is accounted for in the entry.
n += iter.Data()->SizeOfIncludingThis(aMallocSizeOf);
}
}
return n;
+9 -77
View File
@@ -267,80 +267,28 @@ public:
void Clear() { nsTHashtable<EntryType>::Clear(); }
/**
* client must provide a SizeOfEntryExcludingThisFun function for
* SizeOfExcludingThis.
* @param aKey the key being enumerated
* @param aData Reference to data being enumerated.
* @param aMallocSizeOf the function used to measure heap-allocated blocks
* @param aUserArg passed unchanged from SizeOf{In,Ex}cludingThis
* @return summed size of the things pointed to by the entries
*/
typedef size_t
(*SizeOfEntryExcludingThisFun)(KeyType aKey,
const DataType& aData,
mozilla::MallocSizeOf aMallocSizeOf,
void* aUserArg);
/**
* Measure the size of the table's entry storage and the table itself.
* If |aSizeOfEntryExcludingThis| is non-nullptr, measure the size of things
* pointed to by entries.
* Measure the size of the table's entry storage. The size of things pointed
* to by entries must be measured separately; hence the "Shallow" prefix.
*
* @param aSizeOfEntryExcludingThis
* the <code>SizeOfEntryExcludingThisFun</code> function to call
* @param aMallocSizeOf the function used to meeasure heap-allocated blocks
* @param aUserArg a point to pass to the
* <code>SizeOfEntryExcludingThisFun</code> function
* @return the summed size of the entries, the table, and the table's storage
* @param aMallocSizeOf the function used to measure heap-allocated blocks
* @return the summed size of the table's storage
*/
size_t SizeOfIncludingThis(SizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis,
mozilla::MallocSizeOf aMallocSizeOf,
void* aUserArg = nullptr)
size_t ShallowSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
return aMallocSizeOf(this) +
this->SizeOfExcludingThis(aSizeOfEntryExcludingThis, aMallocSizeOf,
aUserArg);
return this->mTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
}
/**
* Measure the size of the table's entry storage, and if
* |aSizeOfEntryExcludingThis| is non-nullptr, measure the size of things
* pointed to by entries.
*
* @param aSizeOfEntryExcludingThis the
* <code>SizeOfEntryExcludingThisFun</code> function to call
* @param aMallocSizeOf the function used to measure heap-allocated blocks
* @param aUserArg a pointer to pass to the
* <code>SizeOfEntryExcludingThisFun</code> function
* @return the summed size of all the entries
* Like ShallowSizeOfExcludingThis, but includes sizeof(*this).
*/
size_t SizeOfExcludingThis(SizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis,
mozilla::MallocSizeOf aMallocSizeOf,
void* aUserArg = nullptr) const
size_t ShallowSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
if (aSizeOfEntryExcludingThis) {
s_SizeOfArgs args = { aSizeOfEntryExcludingThis, aUserArg };
return PL_DHashTableSizeOfExcludingThis(&this->mTable, s_SizeOfStub,
aMallocSizeOf, &args);
}
return PL_DHashTableSizeOfExcludingThis(&this->mTable, nullptr,
aMallocSizeOf);
return aMallocSizeOf(this) + ShallowSizeOfExcludingThis(aMallocSizeOf);
}
#ifdef DEBUG
using nsTHashtable<EntryType>::MarkImmutable;
#endif
protected:
struct s_SizeOfArgs
{
SizeOfEntryExcludingThisFun func;
void* userArg;
};
static size_t s_SizeOfStub(PLDHashEntryHdr* aEntry,
mozilla::MallocSizeOf aMallocSizeOf,
void* aArg);
};
//
@@ -366,20 +314,4 @@ nsBaseHashtableET<KeyClass, DataType>::~nsBaseHashtableET()
{
}
//
// nsBaseHashtable definitions
//
template<class KeyClass, class DataType, class UserDataType>
size_t
nsBaseHashtable<KeyClass, DataType, UserDataType>::s_SizeOfStub(
PLDHashEntryHdr* aHdr, mozilla::MallocSizeOf aMallocSizeOf, void* aArg)
{
EntryType* ent = static_cast<EntryType*>(aHdr);
s_SizeOfArgs* eargs = static_cast<s_SizeOfArgs*>(aArg);
return (eargs->func)(ent->GetKey(), ent->mData, aMallocSizeOf, eargs->userArg);
}
#endif // nsBaseHashtable_h__
+25 -93
View File
@@ -270,68 +270,47 @@ public:
}
/**
* client must provide a <code>SizeOfEntryExcludingThisFun</code> function for
* SizeOfExcludingThis.
* @param aEntry the entry being enumerated
* @param mallocSizeOf the function used to measure heap-allocated blocks
* @param arg passed unchanged from <code>SizeOf{In,Ex}cludingThis</code>
* @return summed size of the things pointed to by the entries
*/
typedef size_t (*SizeOfEntryExcludingThisFun)(EntryType* aEntry,
mozilla::MallocSizeOf aMallocSizeOf,
void* aArg);
/**
* Measure the size of the table's entry storage, and if
* |aSizeOfEntryExcludingThis| is non-nullptr, measure the size of things
* pointed to by entries.
* Measure the size of the table's entry storage. Does *not* measure anything
* hanging off table entries; hence the "Shallow" prefix. To measure that,
* either use SizeOfExcludingThis() or iterate manually over the entries,
* calling SizeOfExcludingThis() on each one.
*
* @param sizeOfEntryExcludingThis the
* <code>SizeOfEntryExcludingThisFun</code> function to call
* @param mallocSizeOf the function used to measure heap-allocated blocks
* @param userArg a pointer to pass to the
* <code>SizeOfEntryExcludingThisFun</code> function
* @return the summed size of all the entries
* @param aMallocSizeOf the function used to measure heap-allocated blocks
* @return the measured shallow size of the table
*/
size_t SizeOfExcludingThis(SizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis,
mozilla::MallocSizeOf aMallocSizeOf,
void* aUserArg = nullptr) const
size_t ShallowSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
if (aSizeOfEntryExcludingThis) {
s_SizeOfArgs args = { aSizeOfEntryExcludingThis, aUserArg };
return PL_DHashTableSizeOfExcludingThis(&mTable, s_SizeOfStub,
aMallocSizeOf, &args);
}
return PL_DHashTableSizeOfExcludingThis(&mTable, nullptr, aMallocSizeOf);
return mTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
}
/**
* If the EntryType defines SizeOfExcludingThis, there's no need to define a new
* SizeOfEntryExcludingThisFun.
* Like ShallowSizeOfExcludingThis, but includes sizeof(*this).
*/
size_t ShallowSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
return aMallocSizeOf(this) + ShallowSizeOfExcludingThis(aMallocSizeOf);
}
/**
* This is a "deep" measurement of the table. To use it, |EntryType| must
* define SizeOfExcludingThis, and that method will be called on all live
* entries.
*/
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
return SizeOfExcludingThis(BasicSizeOfEntryExcludingThisFun, aMallocSizeOf);
size_t n = ShallowSizeOfExcludingThis(aMallocSizeOf);
for (auto iter = ConstIter(); !iter.Done(); iter.Next()) {
n += (*iter.Get()).SizeOfExcludingThis(aMallocSizeOf);
}
return n;
}
/**
* Like SizeOfExcludingThis, but includes sizeof(*this).
*/
size_t SizeOfIncludingThis(SizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis,
mozilla::MallocSizeOf aMallocSizeOf,
void* aUserArg = nullptr) const
{
return aMallocSizeOf(this) +
SizeOfExcludingThis(aSizeOfEntryExcludingThis, aMallocSizeOf, aUserArg);
}
/**
* If the EntryType defines SizeOfExcludingThis, there's no need to define a new
* SizeOfEntryExcludingThisFun.
*/
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
return SizeOfIncludingThis(BasicSizeOfEntryExcludingThisFun, aMallocSizeOf);
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
/**
@@ -374,22 +353,6 @@ protected:
static void s_InitEntry(PLDHashEntryHdr* aEntry, const void* aKey);
/**
* passed internally during sizeOf counting. Allocated on the stack.
*
* @param userFunc the SizeOfEntryExcludingThisFun passed to
* SizeOf{In,Ex}cludingThis by the client
* @param userArg the userArg passed unaltered
*/
struct s_SizeOfArgs
{
SizeOfEntryExcludingThisFun userFunc;
void* userArg;
};
static size_t s_SizeOfStub(PLDHashEntryHdr* aEntry,
mozilla::MallocSizeOf aMallocSizeOf, void* aArg);
private:
// copy constructor, not implemented
nsTHashtable(nsTHashtable<EntryType>& aToCopy) = delete;
@@ -399,14 +362,6 @@ private:
*/
static const PLDHashTableOps* Ops();
/**
* An implementation of SizeOfEntryExcludingThisFun that calls SizeOfExcludingThis()
* on each entry.
*/
static size_t BasicSizeOfEntryExcludingThisFun(EntryType* aEntry,
mozilla::MallocSizeOf aMallocSizeOf,
void*);
// assignment operator, not implemented
nsTHashtable<EntryType>& operator=(nsTHashtable<EntryType>& aToEqual) = delete;
};
@@ -447,16 +402,6 @@ nsTHashtable<EntryType>::Ops()
return &sOps;
}
// static
template<class EntryType>
size_t
nsTHashtable<EntryType>::BasicSizeOfEntryExcludingThisFun(EntryType* aEntry,
mozilla::MallocSizeOf aMallocSizeOf,
void*)
{
return aEntry->SizeOfExcludingThis(aMallocSizeOf);
}
// static definitions
template<class EntryType>
@@ -506,19 +451,6 @@ nsTHashtable<EntryType>::s_InitEntry(PLDHashEntryHdr* aEntry,
new (aEntry) EntryType(reinterpret_cast<KeyTypePointer>(aKey));
}
template<class EntryType>
size_t
nsTHashtable<EntryType>::s_SizeOfStub(PLDHashEntryHdr* aEntry,
mozilla::MallocSizeOf aMallocSizeOf,
void* aArg)
{
// dereferences the function-pointer to the user's enumeration function
return (*reinterpret_cast<s_SizeOfArgs*>(aArg)->userFunc)(
static_cast<EntryType*>(aEntry),
aMallocSizeOf,
reinterpret_cast<s_SizeOfArgs*>(aArg)->userArg);
}
class nsCycleCollectionTraversalCallback;
template<class EntryType>
+35 -74
View File
@@ -218,8 +218,7 @@ PLDHashTable::PLDHashTable(const PLDHashTableOps* aOps, uint32_t aEntrySize,
, mEntrySize(aEntrySize)
, mEntryCount(0)
, mRemovedCount(0)
, mGeneration(0)
, mEntryStore(nullptr)
, mEntryStore()
#ifdef DEBUG
, mChecker()
#endif
@@ -248,7 +247,6 @@ PLDHashTable::operator=(PLDHashTable&& aOther)
mHashShift = Move(aOther.mHashShift);
mEntryCount = Move(aOther.mEntryCount);
mRemovedCount = Move(aOther.mRemovedCount);
mGeneration = Move(aOther.mGeneration);
mEntryStore = Move(aOther.mEntryStore);
#ifdef DEBUG
mChecker = Move(aOther.mChecker);
@@ -259,7 +257,7 @@ PLDHashTable::operator=(PLDHashTable&& aOther)
#ifdef DEBUG
AutoDestructorOp op(mChecker);
#endif
aOther.mEntryStore = nullptr;
aOther.mEntryStore.Set(nullptr);
}
return *this;
@@ -327,7 +325,8 @@ PLDHashTable::MatchEntryKeyhash(PLDHashEntryHdr* aEntry, PLDHashNumber aKeyHash)
PLDHashEntryHdr*
PLDHashTable::AddressEntry(uint32_t aIndex)
{
return reinterpret_cast<PLDHashEntryHdr*>(mEntryStore + aIndex * mEntrySize);
return reinterpret_cast<PLDHashEntryHdr*>(
mEntryStore.Get() + aIndex * mEntrySize);
}
PLDHashTable::~PLDHashTable()
@@ -336,12 +335,12 @@ PLDHashTable::~PLDHashTable()
AutoDestructorOp op(mChecker);
#endif
if (!mEntryStore) {
if (!mEntryStore.Get()) {
return;
}
// Clear any remaining live entries.
char* entryAddr = mEntryStore;
char* entryAddr = mEntryStore.Get();
char* entryLimit = entryAddr + Capacity() * mEntrySize;
while (entryAddr < entryLimit) {
PLDHashEntryHdr* entry = (PLDHashEntryHdr*)entryAddr;
@@ -351,9 +350,7 @@ PLDHashTable::~PLDHashTable()
entryAddr += mEntrySize;
}
// Free entry storage last.
free(mEntryStore);
mEntryStore = nullptr;
// Entry storage is freed last, by ~EntryStore().
}
void
@@ -382,7 +379,7 @@ template <PLDHashTable::SearchReason Reason>
PLDHashEntryHdr* PL_DHASH_FASTCALL
PLDHashTable::SearchTable(const void* aKey, PLDHashNumber aKeyHash)
{
MOZ_ASSERT(mEntryStore);
MOZ_ASSERT(mEntryStore.Get());
NS_ASSERTION(!(aKeyHash & kCollisionFlag),
"!(aKeyHash & kCollisionFlag)");
@@ -451,7 +448,7 @@ PLDHashTable::SearchTable(const void* aKey, PLDHashNumber aKeyHash)
PLDHashEntryHdr* PL_DHASH_FASTCALL
PLDHashTable::FindFreeEntry(PLDHashNumber aKeyHash)
{
MOZ_ASSERT(mEntryStore);
MOZ_ASSERT(mEntryStore.Get());
NS_ASSERTION(!(aKeyHash & kCollisionFlag),
"!(aKeyHash & kCollisionFlag)");
@@ -490,7 +487,7 @@ PLDHashTable::FindFreeEntry(PLDHashNumber aKeyHash)
bool
PLDHashTable::ChangeTable(int32_t aDeltaLog2)
{
MOZ_ASSERT(mEntryStore);
MOZ_ASSERT(mEntryStore.Get());
// Look, but don't touch, until we succeed in getting new entry store.
int32_t oldLog2 = kHashBits - mHashShift;
@@ -513,14 +510,13 @@ PLDHashTable::ChangeTable(int32_t aDeltaLog2)
// We can't fail from here on, so update table parameters.
mHashShift = kHashBits - newLog2;
mRemovedCount = 0;
mGeneration++;
// Assign the new entry store to table.
memset(newEntryStore, 0, nbytes);
char* oldEntryStore;
char* oldEntryAddr;
oldEntryAddr = oldEntryStore = mEntryStore;
mEntryStore = newEntryStore;
oldEntryAddr = oldEntryStore = mEntryStore.Get();
mEntryStore.Set(newEntryStore);
PLDHashMoveEntry moveEntry = mOps->moveEntry;
// Copy only live entries, leaving removed ones behind.
@@ -544,7 +540,7 @@ PLDHashTable::ChangeTable(int32_t aDeltaLog2)
MOZ_ALWAYS_INLINE PLDHashNumber
PLDHashTable::ComputeKeyHash(const void* aKey)
{
MOZ_ASSERT(mEntryStore);
MOZ_ASSERT(mEntryStore.Get());
PLDHashNumber keyHash = mOps->hashKey(this, aKey);
keyHash *= kGoldenRatio;
@@ -565,10 +561,10 @@ PLDHashTable::Search(const void* aKey)
AutoReadOp op(mChecker);
#endif
PLDHashEntryHdr* entry =
mEntryStore ? SearchTable<ForSearchOrRemove>(aKey, ComputeKeyHash(aKey))
: nullptr;
PLDHashEntryHdr* entry = mEntryStore.Get()
? SearchTable<ForSearchOrRemove>(aKey,
ComputeKeyHash(aKey))
: nullptr;
return entry;
}
@@ -580,16 +576,16 @@ PLDHashTable::Add(const void* aKey, const mozilla::fallible_t&)
#endif
// Allocate the entry storage if it hasn't already been allocated.
if (!mEntryStore) {
if (!mEntryStore.Get()) {
uint32_t nbytes;
// We already checked this in the constructor, so it must still be true.
MOZ_RELEASE_ASSERT(SizeOfEntryStore(CapacityFromHashShift(), mEntrySize,
&nbytes));
mEntryStore = (char*)malloc(nbytes);
if (!mEntryStore) {
mEntryStore.Set((char*)malloc(nbytes));
if (!mEntryStore.Get()) {
return nullptr;
}
memset(mEntryStore, 0, nbytes);
memset(mEntryStore.Get(), 0, nbytes);
}
// If alpha is >= .75, grow or compress the table. If aKey is already in the
@@ -638,7 +634,7 @@ PLDHashTable::Add(const void* aKey)
{
PLDHashEntryHdr* entry = Add(aKey, fallible);
if (!entry) {
if (!mEntryStore) {
if (!mEntryStore.Get()) {
// We OOM'd while allocating the initial entry storage.
uint32_t nbytes;
(void) SizeOfEntryStore(CapacityFromHashShift(), mEntrySize, &nbytes);
@@ -661,9 +657,10 @@ PLDHashTable::Remove(const void* aKey)
AutoWriteOp op(mChecker);
#endif
PLDHashEntryHdr* entry =
mEntryStore ? SearchTable<ForSearchOrRemove>(aKey, ComputeKeyHash(aKey))
: nullptr;
PLDHashEntryHdr* entry = mEntryStore.Get()
? SearchTable<ForSearchOrRemove>(aKey,
ComputeKeyHash(aKey))
: nullptr;
if (entry) {
RawRemove(entry);
ShrinkIfAppropriate();
@@ -689,7 +686,7 @@ PLDHashTable::RawRemove(PLDHashEntryHdr* aEntry)
// active, which doesn't fit well into how Checker's mState variable works.
MOZ_ASSERT(mChecker.IsWritable());
MOZ_ASSERT(mEntryStore);
MOZ_ASSERT(mEntryStore.Get());
MOZ_ASSERT(EntryIsLive(aEntry), "EntryIsLive(aEntry)");
@@ -730,56 +727,20 @@ PLDHashTable::ShrinkIfAppropriate()
}
}
MOZ_ALWAYS_INLINE size_t
PLDHashTable::SizeOfExcludingThis(
PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis,
MallocSizeOf aMallocSizeOf, void* aArg /* = nullptr */) const
size_t
PLDHashTable::ShallowSizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{
#ifdef DEBUG
AutoReadOp op(mChecker);
#endif
if (!mEntryStore) {
return 0;
}
size_t n = aMallocSizeOf(mEntryStore);
if (aSizeOfEntryExcludingThis) {
for (auto iter = ConstIter(); !iter.Done(); iter.Next()) {
n += aSizeOfEntryExcludingThis(iter.Get(), aMallocSizeOf, aArg);
}
}
return n;
}
MOZ_ALWAYS_INLINE size_t
PLDHashTable::SizeOfIncludingThis(
PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis,
MallocSizeOf aMallocSizeOf, void* aArg /* = nullptr */) const
{
return aMallocSizeOf(this) +
SizeOfExcludingThis(aSizeOfEntryExcludingThis, aMallocSizeOf, aArg);
return aMallocSizeOf(mEntryStore.Get());
}
size_t
PL_DHashTableSizeOfExcludingThis(
const PLDHashTable* aTable,
PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis,
MallocSizeOf aMallocSizeOf, void* aArg /* = nullptr */)
PLDHashTable::ShallowSizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
return aTable->SizeOfExcludingThis(aSizeOfEntryExcludingThis,
aMallocSizeOf, aArg);
}
size_t
PL_DHashTableSizeOfIncludingThis(
const PLDHashTable* aTable,
PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis,
MallocSizeOf aMallocSizeOf, void* aArg /* = nullptr */)
{
return aTable->SizeOfIncludingThis(aSizeOfEntryExcludingThis,
aMallocSizeOf, aArg);
return aMallocSizeOf(this) + ShallowSizeOfExcludingThis(aMallocSizeOf);
}
PLDHashTable::Iterator::Iterator(Iterator&& aOther)
@@ -803,9 +764,9 @@ PLDHashTable::Iterator::Iterator(Iterator&& aOther)
PLDHashTable::Iterator::Iterator(PLDHashTable* aTable)
: mTable(aTable)
, mStart(mTable->mEntryStore)
, mLimit(mTable->mEntryStore + mTable->Capacity() * mTable->mEntrySize)
, mCurrent(mTable->mEntryStore)
, mStart(mTable->mEntryStore.Get())
, mLimit(mTable->mEntryStore.Get() + mTable->Capacity() * mTable->mEntrySize)
, mCurrent(mTable->mEntryStore.Get())
, mNexts(0)
, mNextsLimit(mTable->EntryCount())
, mHaveRemoved(false)
+45 -35
View File
@@ -52,9 +52,6 @@ private:
PLDHashNumber mKeyHash;
};
typedef size_t (*PLDHashSizeOfEntryExcludingThisFun)(
PLDHashEntryHdr* aHdr, mozilla::MallocSizeOf aMallocSizeOf, void* aArg);
#ifdef DEBUG
// This class does three kinds of checking:
@@ -212,19 +209,48 @@ private:
// hashing is more space-efficient unless the element size gets large (in which
// case you should keep using double hashing but switch to using pointer
// elements). Also, with double hashing, you can't safely hold an entry pointer
// and use it after an ADD or REMOVE operation, unless you sample
// aTable->mGeneration before adding or removing, and compare the sample after,
// dereferencing the entry pointer only if aTable->mGeneration has not changed.
// and use it after an add or remove operation, unless you sample Generation()
// before adding or removing, and compare the sample after, dereferencing the
// entry pointer only if Generation() has not changed.
class PLDHashTable
{
private:
// This class maintains the invariant that every time the entry store is
// changed, the generation is updated.
class EntryStore
{
private:
char* mEntryStore;
uint32_t mGeneration;
public:
EntryStore() : mEntryStore(nullptr), mGeneration(0) {}
~EntryStore()
{
free(mEntryStore);
mEntryStore = nullptr;
mGeneration++; // a little paranoid, but why not be extra safe?
}
char* Get() { return mEntryStore; }
const char* Get() const { return mEntryStore; }
void Set(char* aEntryStore)
{
mEntryStore = aEntryStore;
mGeneration++;
}
uint32_t Generation() const { return mGeneration; }
};
const PLDHashTableOps* const mOps; // Virtual operations; see below.
int16_t mHashShift; // Multiplicative hash shift.
const uint32_t mEntrySize; // Number of bytes in an entry.
uint32_t mEntryCount; // Number of entries in table.
uint32_t mRemovedCount; // Removed entry sentinels in table.
uint32_t mGeneration; // Entry storage generation number.
char* mEntryStore; // Entry storage; allocated lazily.
EntryStore mEntryStore; // (Lazy) entry storage and generation.
#ifdef DEBUG
mutable Checker mChecker;
@@ -264,9 +290,9 @@ public:
// move assignment operator cannot modify them.
: mOps(aOther.mOps)
, mEntrySize(aOther.mEntrySize)
// Initialize these two fields because they are required for a safe call
// to the destructor, which the move assignment operator does.
, mEntryStore(nullptr)
// Initialize this field because it is required for a safe call to the
// destructor, which the move assignment operator does.
, mEntryStore()
#ifdef DEBUG
, mChecker()
#endif
@@ -286,12 +312,12 @@ public:
// entry storage will not have yet been allocated.
uint32_t Capacity() const
{
return mEntryStore ? CapacityFromHashShift() : 0;
return mEntryStore.Get() ? CapacityFromHashShift() : 0;
}
uint32_t EntrySize() const { return mEntrySize; }
uint32_t EntryCount() const { return mEntryCount; }
uint32_t Generation() const { return mGeneration; }
uint32_t Generation() const { return mEntryStore.Generation(); }
// To search for a |key| in |table|, call:
//
@@ -357,17 +383,13 @@ public:
// a new |aLength| argument.
void ClearAndPrepareForLength(uint32_t aLength);
// Measure the size of the table's entry storage, and if
// |aSizeOfEntryExcludingThis| is non-nullptr, measure the size of things
// pointed to by entries.
size_t SizeOfIncludingThis(
PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis,
mozilla::MallocSizeOf aMallocSizeOf, void* aArg = nullptr) const;
// Measure the size of the table's entry storage. If the entries contain
// pointers to other heap blocks, you have to iterate over the table and
// measure those separately; hence the "Shallow" prefix.
size_t ShallowSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
// Like SizeOfExcludingThis(), but includes sizeof(*this).
size_t SizeOfExcludingThis(
PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis,
mozilla::MallocSizeOf aMallocSizeOf, void* aArg = nullptr) const;
// Like ShallowSizeOfExcludingThis(), but includes sizeof(*this).
size_t ShallowSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
#ifdef DEBUG
// Mark a table as immutable for the remainder of its lifetime. This
@@ -601,18 +623,6 @@ PL_DHashGetStubOps(void);
void
PL_DHashTableRawRemove(PLDHashTable* aTable, PLDHashEntryHdr* aEntry);
size_t
PL_DHashTableSizeOfExcludingThis(
const PLDHashTable* aTable,
PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis,
mozilla::MallocSizeOf aMallocSizeOf, void* aArg = nullptr);
size_t
PL_DHashTableSizeOfIncludingThis(
const PLDHashTable* aTable,
PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis,
mozilla::MallocSizeOf aMallocSizeOf, void* aArg = nullptr);
#ifdef DEBUG
void
PL_DHashMarkTableImmutable(PLDHashTable* aTable);
@@ -36,8 +36,8 @@ XPTInterfaceInfoManager::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
// The entries themselves are allocated out of an arena accounted
// for elsewhere, so don't measure them
n += mWorkingSet.mIIDTable.SizeOfExcludingThis(nullptr, aMallocSizeOf);
n += mWorkingSet.mNameTable.SizeOfExcludingThis(nullptr, aMallocSizeOf);
n += mWorkingSet.mIIDTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
n += mWorkingSet.mNameTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
return n;
}
+1 -4
View File
@@ -137,10 +137,7 @@ TEST(PLDHashTableTest, LazyStorage)
ASSERT_TRUE(false); // shouldn't hit this on an empty table
}
// Using a null |mallocSizeOf| should be fine because it shouldn't be called
// for an empty table.
mozilla::MallocSizeOf mallocSizeOf = nullptr;
ASSERT_EQ(PL_DHashTableSizeOfExcludingThis(&t, nullptr, mallocSizeOf), 0u);
ASSERT_EQ(t.ShallowSizeOfExcludingThis(moz_malloc_size_of), 0u);
}
// A trivial hash function is good enough here. It's also super-fast for