Bug 1118024 - Add explicit PL_DHashTable{Add,Lookup,Remove} functions. r=nfroyd
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -893,42 +893,40 @@ public:
*aWeakMapsSize = mWeakMaps.SizeOfExcludingThis(aMallocSizeOf);
}
};
PtrInfo*
CCGraph::FindNode(void* aPtr)
{
PtrToNodeEntry* e =
- static_cast<PtrToNodeEntry*>(PL_DHashTableOperate(&mPtrToNodeMap, aPtr,
- PL_DHASH_LOOKUP));
+ static_cast<PtrToNodeEntry*>(PL_DHashTableLookup(&mPtrToNodeMap, aPtr));
if (!PL_DHASH_ENTRY_IS_BUSY(e)) {
return nullptr;
}
return e->mNode;
}
PtrToNodeEntry*
CCGraph::AddNodeToMap(void* aPtr)
{
JS::AutoSuppressGCAnalysis suppress;
PtrToNodeEntry* e =
- static_cast<PtrToNodeEntry*>(PL_DHashTableOperate(&mPtrToNodeMap, aPtr,
- PL_DHASH_ADD));
+ static_cast<PtrToNodeEntry*>(PL_DHashTableAdd(&mPtrToNodeMap, aPtr));
if (!e) {
// Caller should track OOMs
return nullptr;
}
return e;
}
void
CCGraph::RemoveNodeFromMap(void* aPtr)
{
- PL_DHashTableOperate(&mPtrToNodeMap, aPtr, PL_DHASH_REMOVE);
+ PL_DHashTableRemove(&mPtrToNodeMap, aPtr);
}
static nsISupports*
CanonicalizeXPCOMParticipant(nsISupports* aIn)
{
nsISupports* out;
aIn->QueryInterface(NS_GET_IID(nsCycleCollectionISupports),
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -399,17 +399,17 @@ AtomImpl::AtomImpl(nsStringBuffer* aStri
AtomImpl::~AtomImpl()
{
NS_PRECONDITION(gAtomTable.ops, "uninitialized atom hashtable");
// Permanent atoms are removed from the hashtable at shutdown, and we
// don't want to remove them twice. See comment above in
// |AtomTableClearEntry|.
if (!IsPermanentInDestructor()) {
AtomTableKey key(mString, mLength, mHash);
- PL_DHashTableOperate(&gAtomTable, &key, PL_DHASH_REMOVE);
+ PL_DHashTableRemove(&gAtomTable, &key);
if (gAtomTable.ops && gAtomTable.EntryCount() == 0) {
PL_DHashTableFinish(&gAtomTable);
NS_ASSERTION(gAtomTable.EntryCount() == 0,
"PL_DHashTableFinish changed the entry count");
}
}
nsStringBuffer::FromData(mString)->Release();
@@ -550,31 +550,31 @@ EnsureTableExists()
static inline AtomTableEntry*
GetAtomHashEntry(const char* aString, uint32_t aLength, uint32_t* aHashOut)
{
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
EnsureTableExists();
AtomTableKey key(aString, aLength, aHashOut);
AtomTableEntry* e = static_cast<AtomTableEntry*>(
- PL_DHashTableOperate(&gAtomTable, &key, PL_DHASH_ADD));
+ PL_DHashTableAdd(&gAtomTable, &key));
if (!e) {
NS_ABORT_OOM(gAtomTable.EntryCount() * gAtomTable.EntrySize());
}
return e;
}
static inline AtomTableEntry*
GetAtomHashEntry(const char16_t* aString, uint32_t aLength, uint32_t* aHashOut)
{
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
EnsureTableExists();
AtomTableKey key(aString, aLength, aHashOut);
AtomTableEntry* e = static_cast<AtomTableEntry*>(
- PL_DHashTableOperate(&gAtomTable, &key, PL_DHASH_ADD));
+ PL_DHashTableAdd(&gAtomTable, &key));
if (!e) {
NS_ABORT_OOM(gAtomTable.EntryCount() * gAtomTable.EntrySize());
}
return e;
}
class CheckStaticAtomSizes
{
--- a/xpcom/ds/nsPersistentProperties.cpp
+++ b/xpcom/ds/nsPersistentProperties.cpp
@@ -528,17 +528,17 @@ nsPersistentProperties::Load(nsIInputStr
NS_IMETHODIMP
nsPersistentProperties::SetStringProperty(const nsACString& aKey,
const nsAString& aNewValue,
nsAString& aOldValue)
{
const nsAFlatCString& flatKey = PromiseFlatCString(aKey);
PropertyTableEntry* entry = static_cast<PropertyTableEntry*>(
- PL_DHashTableOperate(&mTable, flatKey.get(), PL_DHASH_ADD));
+ PL_DHashTableAdd(&mTable, flatKey.get()));
if (entry->mKey) {
aOldValue = entry->mValue;
NS_WARNING(nsPrintfCString("the property %s already exists\n",
flatKey.get()).get());
} else {
aOldValue.Truncate();
}
@@ -567,17 +567,17 @@ nsPersistentProperties::Subclass(nsIPers
NS_IMETHODIMP
nsPersistentProperties::GetStringProperty(const nsACString& aKey,
nsAString& aValue)
{
const nsAFlatCString& flatKey = PromiseFlatCString(aKey);
PropertyTableEntry* entry = static_cast<PropertyTableEntry*>(
- PL_DHashTableOperate(&mTable, flatKey.get(), PL_DHASH_LOOKUP));
+ PL_DHashTableLookup(&mTable, flatKey.get()));
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
return NS_ERROR_FAILURE;
}
aValue = entry->mValue;
return NS_OK;
}
@@ -639,17 +639,17 @@ nsPersistentProperties::Undefine(const c
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsPersistentProperties::Has(const char* aProp, bool* aResult)
{
PropertyTableEntry* entry = static_cast<PropertyTableEntry*>(
- PL_DHashTableOperate(&mTable, aProp, PL_DHASH_LOOKUP));
+ PL_DHashTableLookup(&mTable, aProp));
*aResult = (entry && PL_DHASH_ENTRY_IS_BUSY(entry));
return NS_OK;
}
NS_IMETHODIMP
nsPersistentProperties::GetKeys(uint32_t* aCount, char*** aKeys)
{
return NS_ERROR_NOT_IMPLEMENTED;
--- a/xpcom/ds/nsStaticNameTable.cpp
+++ b/xpcom/ds/nsStaticNameTable.cpp
@@ -165,18 +165,17 @@ nsStaticCaseInsensitiveNameTable::Init(c
#endif
// use placement-new to initialize the string object
nsDependentCString* strPtr = &mNameArray[index];
new (strPtr) nsDependentCString(raw);
NameTableKey key(strPtr);
NameTableEntry* entry =
- static_cast<NameTableEntry*>(PL_DHashTableOperate(&mNameTable, &key,
- PL_DHASH_ADD));
+ static_cast<NameTableEntry*>(PL_DHashTableAdd(&mNameTable, &key));
if (!entry) {
continue;
}
NS_ASSERTION(entry->mString == 0, "Entry already exists!");
entry->mString = strPtr; // not owned!
entry->mIndex = index;
@@ -192,18 +191,17 @@ nsStaticCaseInsensitiveNameTable::Lookup
{
NS_ASSERTION(mNameArray, "not inited");
NS_ASSERTION(mNameTable.ops, "not inited");
const nsAFlatCString& str = PromiseFlatCString(aName);
NameTableKey key(&str);
NameTableEntry* entry =
- static_cast<NameTableEntry*>(PL_DHashTableOperate(&mNameTable, &key,
- PL_DHASH_LOOKUP));
+ static_cast<NameTableEntry*>(PL_DHashTableLookup(&mNameTable, &key));
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
return nsStaticCaseInsensitiveNameTable::NOT_FOUND;
}
return entry->mIndex;
}
int32_t
@@ -211,18 +209,17 @@ nsStaticCaseInsensitiveNameTable::Lookup
{
NS_ASSERTION(mNameArray, "not inited");
NS_ASSERTION(mNameTable.ops, "not inited");
const nsAFlatString& str = PromiseFlatString(aName);
NameTableKey key(&str);
NameTableEntry* entry =
- static_cast<NameTableEntry*>(PL_DHashTableOperate(&mNameTable, &key,
- PL_DHASH_LOOKUP));
+ static_cast<NameTableEntry*>(PL_DHashTableLookup(&mNameTable, &key));
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
return nsStaticCaseInsensitiveNameTable::NOT_FOUND;
}
return entry->mIndex;
}
const nsAFlatCString&
--- a/xpcom/glue/nsTHashtable.h
+++ b/xpcom/glue/nsTHashtable.h
@@ -123,18 +123,18 @@ public:
* @return pointer to the entry class, if the key exists; nullptr if the
* key doesn't exist
*/
EntryType* GetEntry(KeyType aKey) const
{
NS_ASSERTION(mTable.ops, "nsTHashtable was not initialized properly.");
EntryType* entry = reinterpret_cast<EntryType*>(
- PL_DHashTableOperate(const_cast<PLDHashTable*>(&mTable),
- EntryType::KeyToPointer(aKey), PL_DHASH_LOOKUP));
+ PL_DHashTableLookup(const_cast<PLDHashTable*>(&mTable),
+ EntryType::KeyToPointer(aKey)));
return PL_DHASH_ENTRY_IS_BUSY(entry) ? entry : nullptr;
}
/**
* Return true if an entry for the given key exists, false otherwise.
* @param aKey the key to retrieve
* @return true if the key exists, false if the key doesn't exist
*/
@@ -153,31 +153,30 @@ public:
NS_ABORT_OOM(mTable.EntrySize() * mTable.EntryCount());
}
return e;
}
EntryType* PutEntry(KeyType aKey, const fallible_t&) NS_WARN_UNUSED_RESULT {
NS_ASSERTION(mTable.ops, "nsTHashtable was not initialized properly.");
- return static_cast<EntryType*>(PL_DHashTableOperate(
- &mTable, EntryType::KeyToPointer(aKey), PL_DHASH_ADD));
+ return static_cast<EntryType*>(PL_DHashTableAdd(
+ &mTable, EntryType::KeyToPointer(aKey)));
}
/**
* Remove the entry associated with a key.
* @param aKey of the entry to remove
*/
void RemoveEntry(KeyType aKey)
{
NS_ASSERTION(mTable.ops, "nsTHashtable was not initialized properly.");
- PL_DHashTableOperate(&mTable,
- EntryType::KeyToPointer(aKey),
- PL_DHASH_REMOVE);
+ PL_DHashTableRemove(&mTable,
+ EntryType::KeyToPointer(aKey));
}
/**
* Remove the entry associated with a key, but don't resize the hashtable.
* This is a low-level method, and is not recommended unless you know what
* you're doing and you need the extra performance. This method can be used
* during enumeration, while RemoveEntry() cannot.
* @param aEntry the entry-pointer to remove (obtained from GetEntry or
--- a/xpcom/glue/pldhash.cpp
+++ b/xpcom/glue/pldhash.cpp
@@ -662,16 +662,34 @@ PLDHashTable::Operate(const void* aKey,
}
PLDHashEntryHdr* PL_DHASH_FASTCALL
PL_DHashTableOperate(PLDHashTable* aTable, const void* aKey, PLDHashOperator aOp)
{
return aTable->Operate(aKey, aOp);
}
+PLDHashEntryHdr* PL_DHASH_FASTCALL
+PL_DHashTableLookup(PLDHashTable* aTable, const void* aKey)
+{
+ return aTable->Operate(aKey, PL_DHASH_LOOKUP);
+}
+
+PLDHashEntryHdr* PL_DHASH_FASTCALL
+PL_DHashTableAdd(PLDHashTable* aTable, const void* aKey)
+{
+ return aTable->Operate(aKey, PL_DHASH_ADD);
+}
+
+void PL_DHASH_FASTCALL
+PL_DHashTableRemove(PLDHashTable* aTable, const void* aKey)
+{
+ aTable->Operate(aKey, PL_DHASH_REMOVE);
+}
+
MOZ_ALWAYS_INLINE void
PLDHashTable::RawRemove(PLDHashEntryHdr* aEntry)
{
MOZ_ASSERT(mRecursionLevel != IMMUTABLE_RECURSION_LEVEL);
NS_ASSERTION(ENTRY_IS_LIVE(aEntry), "ENTRY_IS_LIVE(aEntry)");
/* Load keyHash first in case clearEntry() goofs it. */
--- a/xpcom/glue/pldhash.h
+++ b/xpcom/glue/pldhash.h
@@ -522,16 +522,28 @@ void PL_DHashTableFinish(PLDHashTable* a
* If key's entry is found, it is cleared (via table->ops->clearEntry) and
* the entry is marked so that PL_DHASH_ENTRY_IS_FREE(entry). This operation
* returns null unconditionally; you should ignore its return value.
*/
PLDHashEntryHdr* PL_DHASH_FASTCALL
PL_DHashTableOperate(PLDHashTable* aTable, const void* aKey,
PLDHashOperator aOp);
+/* Look up a key in table. */
+PLDHashEntryHdr* PL_DHASH_FASTCALL
+PL_DHashTableLookup(PLDHashTable* aTable, const void* aKey);
+
+/* Add an entry identified by key to table. */
+PLDHashEntryHdr* PL_DHASH_FASTCALL
+PL_DHashTableAdd(PLDHashTable* aTable, const void* aKey);
+
+/* Remove an entry identified by key from table. */
+void PL_DHASH_FASTCALL
+PL_DHashTableRemove(PLDHashTable* aTable, const void* aKey);
+
/*
* Remove an entry already accessed via LOOKUP or ADD.
*
* NB: this is a "raw" or low-level routine, intended to be used only where
* the inefficiency of a full PL_DHashTableOperate (which rehashes in order
* to find the entry given its key) is not tolerable. This function does not
* shrink the table if it is underloaded. It does not update mStats #ifdef
* PL_DHASHMETER, either.
--- a/xpcom/tests/TestPLDHash.cpp
+++ b/xpcom/tests/TestPLDHash.cpp
@@ -94,17 +94,17 @@ static bool test_pldhash_grow_to_max_cap
bool ok = PL_DHashTableInit(&t, &ops, nullptr, sizeof(PLDHashEntryStub),
mozilla::fallible_t(), 128);
if (!ok)
return false;
// Keep inserting elements until failure occurs because the table is full.
size_t numInserted = 0;
while (true) {
- if (!PL_DHashTableOperate(&t, (const void*)numInserted, PL_DHASH_ADD)) {
+ if (!PL_DHashTableAdd(&t, (const void*)numInserted)) {
break;
}
numInserted++;
}
// We stop when the element count is 96.875% of PL_DHASH_MAX_SIZE (see
// MaxLoadOnGrowthFailure()).
return numInserted == PL_DHASH_MAX_CAPACITY - (PL_DHASH_MAX_CAPACITY >> 5);