mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-29 18:18:27 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user