Bug 1161377 (part 2.5) - Move all static PLDHashTable instances onto the heap to avoid static constructors. r=froydnj.

This commit is contained in:
Nicholas Nethercote 2015-05-12 17:33:22 -07:00
parent a1d964e932
commit 8a397036c0
10 changed files with 167 additions and 168 deletions

View File

@ -153,7 +153,7 @@ nsSimpleContentList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto
}
// Hashtable for storing nsContentLists
static PLDHashTable gContentListHashTable;
static PLDHashTable* gContentListHashTable;
#define RECENTLY_USED_CONTENT_LIST_CACHE_SIZE 31
static nsContentList*
@ -215,19 +215,17 @@ NS_GetContentList(nsINode* aRootNode,
};
// Initialize the hashtable if needed.
if (!gContentListHashTable.IsInitialized()) {
PL_DHashTableInit(&gContentListHashTable, &hash_table_ops,
sizeof(ContentListHashEntry));
if (!gContentListHashTable) {
gContentListHashTable =
new PLDHashTable(&hash_table_ops, sizeof(ContentListHashEntry));
}
ContentListHashEntry *entry = nullptr;
// First we look in our hashtable. Then we create a content list if needed
if (gContentListHashTable.IsInitialized()) {
entry = static_cast<ContentListHashEntry *>
(PL_DHashTableAdd(&gContentListHashTable, &hashKey, fallible));
if (entry)
list = entry->mContentList;
}
entry = static_cast<ContentListHashEntry *>
(PL_DHashTableAdd(gContentListHashTable, &hashKey, fallible));
if (entry)
list = entry->mContentList;
if (!list) {
// We need to create a ContentList and add it to our new entry, if
@ -272,7 +270,7 @@ nsCacheableFuncStringHTMLCollection::WrapObject(JSContext *cx, JS::Handle<JSObje
}
// Hashtable for storing nsCacheableFuncStringContentList
static PLDHashTable gFuncStringContentListHashTable;
static PLDHashTable* gFuncStringContentListHashTable;
struct FuncStringContentListHashEntry : public PLDHashEntryHdr
{
@ -321,18 +319,18 @@ GetFuncStringContentList(nsINode* aRootNode,
};
// Initialize the hashtable if needed.
if (!gFuncStringContentListHashTable.IsInitialized()) {
PL_DHashTableInit(&gFuncStringContentListHashTable, &hash_table_ops,
sizeof(FuncStringContentListHashEntry));
if (!gFuncStringContentListHashTable) {
gFuncStringContentListHashTable =
new PLDHashTable(&hash_table_ops, sizeof(FuncStringContentListHashEntry));
}
FuncStringContentListHashEntry *entry = nullptr;
// First we look in our hashtable. Then we create a content list if needed
if (gFuncStringContentListHashTable.IsInitialized()) {
if (gFuncStringContentListHashTable) {
nsFuncStringCacheKey hashKey(aRootNode, aFunc, aString);
entry = static_cast<FuncStringContentListHashEntry *>
(PL_DHashTableAdd(&gFuncStringContentListHashTable, &hashKey, fallible));
(PL_DHashTableAdd(gFuncStringContentListHashTable, &hashKey, fallible));
if (entry) {
list = entry->mContentList;
#ifdef DEBUG
@ -970,13 +968,14 @@ nsContentList::RemoveFromHashtable()
sRecentlyUsedContentLists[recentlyUsedCacheIndex] = nullptr;
}
if (!gContentListHashTable.IsInitialized())
if (!gContentListHashTable)
return;
PL_DHashTableRemove(&gContentListHashTable, &key);
PL_DHashTableRemove(gContentListHashTable, &key);
if (gContentListHashTable.EntryCount() == 0) {
PL_DHashTableFinish(&gContentListHashTable);
if (gContentListHashTable->EntryCount() == 0) {
delete gContentListHashTable;
gContentListHashTable = nullptr;
}
}
@ -1008,15 +1007,16 @@ nsCacheableFuncStringContentList::~nsCacheableFuncStringContentList()
void
nsCacheableFuncStringContentList::RemoveFromFuncStringHashtable()
{
if (!gFuncStringContentListHashTable.IsInitialized()) {
if (!gFuncStringContentListHashTable) {
return;
}
nsFuncStringCacheKey key(mRootNode, mFunc, mString);
PL_DHashTableRemove(&gFuncStringContentListHashTable, &key);
PL_DHashTableRemove(gFuncStringContentListHashTable, &key);
if (gFuncStringContentListHashTable.EntryCount() == 0) {
PL_DHashTableFinish(&gFuncStringContentListHashTable);
if (gFuncStringContentListHashTable->EntryCount() == 0) {
delete gFuncStringContentListHashTable;
gFuncStringContentListHashTable = nullptr;
}
}

View File

@ -337,7 +337,7 @@ namespace {
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
static PLDHashTable sEventListenerManagersHash;
static PLDHashTable* sEventListenerManagersHash;
class DOMEventListenerManagersHashReporter final : public nsIMemoryReporter
{
@ -353,9 +353,9 @@ public:
{
// We don't measure the |EventListenerManager| objects pointed to by the
// entries because those references are non-owning.
int64_t amount = sEventListenerManagersHash.IsInitialized()
int64_t amount = sEventListenerManagersHash
? PL_DHashTableSizeOfExcludingThis(
&sEventListenerManagersHash, nullptr, MallocSizeOf)
sEventListenerManagersHash, nullptr, MallocSizeOf)
: 0;
return MOZ_COLLECT_REPORT(
@ -488,7 +488,7 @@ nsContentUtils::Init()
if (!InitializeEventTable())
return NS_ERROR_FAILURE;
if (!sEventListenerManagersHash.IsInitialized()) {
if (!sEventListenerManagersHash) {
static const PLDHashTableOps hash_table_ops =
{
PL_DHashVoidPtrKeyStub,
@ -498,8 +498,8 @@ nsContentUtils::Init()
EventListenerManagerHashInitEntry
};
PL_DHashTableInit(&sEventListenerManagersHash, &hash_table_ops,
sizeof(EventListenerManagerMapEntry));
sEventListenerManagersHash =
new PLDHashTable(&hash_table_ops, sizeof(EventListenerManagerMapEntry));
RegisterStrongMemoryReporter(new DOMEventListenerManagersHashReporter());
}
@ -1810,8 +1810,8 @@ nsContentUtils::Shutdown()
delete sUserDefinedEvents;
sUserDefinedEvents = nullptr;
if (sEventListenerManagersHash.IsInitialized()) {
NS_ASSERTION(sEventListenerManagersHash.EntryCount() == 0,
if (sEventListenerManagersHash) {
NS_ASSERTION(sEventListenerManagersHash->EntryCount() == 0,
"Event listener manager hash not empty at shutdown!");
// See comment above.
@ -1823,8 +1823,9 @@ nsContentUtils::Shutdown()
// it could leave dangling references in DOMClassInfo's preserved
// wrapper table.
if (sEventListenerManagersHash.EntryCount() == 0) {
PL_DHashTableFinish(&sEventListenerManagersHash);
if (sEventListenerManagersHash->EntryCount() == 0) {
delete sEventListenerManagersHash;
sEventListenerManagersHash = nullptr;
}
}
@ -3989,8 +3990,8 @@ ListenerEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aEntry,
void
nsContentUtils::UnmarkGrayJSListenersInCCGenerationDocuments(uint32_t aGeneration)
{
if (sEventListenerManagersHash.IsInitialized()) {
PL_DHashTableEnumerate(&sEventListenerManagersHash, ListenerEnumerator,
if (sEventListenerManagersHash) {
PL_DHashTableEnumerate(sEventListenerManagersHash, ListenerEnumerator,
&aGeneration);
}
}
@ -4000,14 +4001,14 @@ void
nsContentUtils::TraverseListenerManager(nsINode *aNode,
nsCycleCollectionTraversalCallback &cb)
{
if (!sEventListenerManagersHash.IsInitialized()) {
if (!sEventListenerManagersHash) {
// We're already shut down, just return.
return;
}
EventListenerManagerMapEntry *entry =
static_cast<EventListenerManagerMapEntry *>
(PL_DHashTableSearch(&sEventListenerManagersHash, aNode));
(PL_DHashTableSearch(sEventListenerManagersHash, aNode));
if (entry) {
CycleCollectionNoteChild(cb, entry->mListenerManager.get(),
"[via hash] mListenerManager");
@ -4017,7 +4018,7 @@ nsContentUtils::TraverseListenerManager(nsINode *aNode,
EventListenerManager*
nsContentUtils::GetListenerManagerForNode(nsINode *aNode)
{
if (!sEventListenerManagersHash.IsInitialized()) {
if (!sEventListenerManagersHash) {
// We're already shut down, don't bother creating an event listener
// manager.
@ -4026,7 +4027,7 @@ nsContentUtils::GetListenerManagerForNode(nsINode *aNode)
EventListenerManagerMapEntry *entry =
static_cast<EventListenerManagerMapEntry *>
(PL_DHashTableAdd(&sEventListenerManagersHash, aNode, fallible));
(PL_DHashTableAdd(sEventListenerManagersHash, aNode, fallible));
if (!entry) {
return nullptr;
@ -4048,7 +4049,7 @@ nsContentUtils::GetExistingListenerManagerForNode(const nsINode *aNode)
return nullptr;
}
if (!sEventListenerManagersHash.IsInitialized()) {
if (!sEventListenerManagersHash) {
// We're already shut down, don't bother creating an event listener
// manager.
@ -4057,7 +4058,7 @@ nsContentUtils::GetExistingListenerManagerForNode(const nsINode *aNode)
EventListenerManagerMapEntry *entry =
static_cast<EventListenerManagerMapEntry *>
(PL_DHashTableSearch(&sEventListenerManagersHash, aNode));
(PL_DHashTableSearch(sEventListenerManagersHash, aNode));
if (entry) {
return entry->mListenerManager;
}
@ -4069,16 +4070,16 @@ nsContentUtils::GetExistingListenerManagerForNode(const nsINode *aNode)
void
nsContentUtils::RemoveListenerManager(nsINode *aNode)
{
if (sEventListenerManagersHash.IsInitialized()) {
if (sEventListenerManagersHash) {
EventListenerManagerMapEntry *entry =
static_cast<EventListenerManagerMapEntry *>
(PL_DHashTableSearch(&sEventListenerManagersHash, aNode));
(PL_DHashTableSearch(sEventListenerManagersHash, aNode));
if (entry) {
nsRefPtr<EventListenerManager> listenerManager;
listenerManager.swap(entry->mListenerManager);
// Remove the entry and *then* do operations that could cause further
// modification of sEventListenerManagersHash. See bug 334177.
PL_DHashTableRawRemove(&sEventListenerManagersHash, entry);
PL_DHashTableRawRemove(sEventListenerManagersHash, entry);
if (listenerManager) {
listenerManager->Disconnect();
}
@ -7763,4 +7764,4 @@ nsContentUtils::FirePageShowEvent(nsIDocShellTreeItem* aItem,
if (doc->IsShowing() == aFireIfShowing) {
doc->OnPageShow(true, aChromeEventHandler);
}
}
}

View File

@ -83,7 +83,7 @@ static JSObjWrapperTable sJSObjWrappers;
static bool sJSObjWrappersAccessible = false;
// Hash of NPObject wrappers that wrap NPObjects as JSObjects.
static PLDHashTable sNPObjWrappers;
static PLDHashTable* sNPObjWrappers;
// Global wrapper count. This includes JSObject wrappers *and*
// NPObject wrappers. When this count goes to zero, there are no more
@ -401,23 +401,24 @@ DestroyJSObjWrapperTable()
static bool
CreateNPObjWrapperTable()
{
MOZ_ASSERT(!sNPObjWrappers.IsInitialized());
MOZ_ASSERT(!sNPObjWrappers);
if (!RegisterGCCallbacks()) {
return false;
}
PL_DHashTableInit(&sNPObjWrappers, PL_DHashGetStubOps(),
sizeof(NPObjWrapperHashEntry));
sNPObjWrappers =
new PLDHashTable(PL_DHashGetStubOps(), sizeof(NPObjWrapperHashEntry));
return true;
}
static void
DestroyNPObjWrapperTable()
{
MOZ_ASSERT(sNPObjWrappers.EntryCount() == 0);
MOZ_ASSERT(sNPObjWrappers->EntryCount() == 0);
PL_DHashTableFinish(&sNPObjWrappers);
delete sNPObjWrappers;
sNPObjWrappers = nullptr;
}
static void
@ -436,7 +437,7 @@ OnWrapperDestroyed()
DestroyJSObjWrapperTable();
}
if (sNPObjWrappers.IsInitialized()) {
if (sNPObjWrappers) {
// No more wrappers, and our hash was initialized. Finish the
// hash to prevent leaking it.
DestroyNPObjWrapperTable();
@ -1761,8 +1762,8 @@ NPObjWrapper_Finalize(js::FreeOp *fop, JSObject *obj)
{
NPObject *npobj = (NPObject *)::JS_GetPrivate(obj);
if (npobj) {
if (sNPObjWrappers.IsInitialized()) {
PL_DHashTableRemove(&sNPObjWrappers, npobj);
if (sNPObjWrappers) {
PL_DHashTableRemove(sNPObjWrappers, npobj);
}
}
@ -1777,7 +1778,7 @@ NPObjWrapper_ObjectMoved(JSObject *obj, const JSObject *old)
// The wrapper JSObject has been moved, so we need to update the entry in the
// sNPObjWrappers hash table, if present.
if (!sNPObjWrappers.IsInitialized()) {
if (!sNPObjWrappers) {
return;
}
@ -1790,7 +1791,7 @@ NPObjWrapper_ObjectMoved(JSObject *obj, const JSObject *old)
JS::AutoSuppressGCAnalysis nogc;
NPObjWrapperHashEntry *entry = static_cast<NPObjWrapperHashEntry *>
(PL_DHashTableSearch(&sNPObjWrappers, npobj));
(PL_DHashTableSearch(sNPObjWrappers, npobj));
MOZ_ASSERT(entry && entry->mJSObj);
MOZ_ASSERT(entry->mJSObj == old);
entry->mJSObj = obj;
@ -1836,14 +1837,14 @@ nsNPObjWrapper::OnDestroy(NPObject *npobj)
return;
}
if (!sNPObjWrappers.IsInitialized()) {
if (!sNPObjWrappers) {
// No hash yet (or any more), no used wrappers available.
return;
}
NPObjWrapperHashEntry *entry = static_cast<NPObjWrapperHashEntry *>
(PL_DHashTableSearch(&sNPObjWrappers, npobj));
(PL_DHashTableSearch(sNPObjWrappers, npobj));
if (entry && entry->mJSObj) {
// Found a live NPObject wrapper, null out its JSObjects' private
@ -1852,7 +1853,7 @@ nsNPObjWrapper::OnDestroy(NPObject *npobj)
::JS_SetPrivate(entry->mJSObj, nullptr);
// Remove the npobj from the hash now that it went away.
PL_DHashTableRawRemove(&sNPObjWrappers, entry);
PL_DHashTableRawRemove(sNPObjWrappers, entry);
// The finalize hook will call OnWrapperDestroyed().
}
@ -1886,7 +1887,7 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, NPObject *npobj)
return nullptr;
}
if (!sNPObjWrappers.IsInitialized()) {
if (!sNPObjWrappers) {
// No hash yet (or any more), initialize it.
if (!CreateNPObjWrapperTable()) {
return nullptr;
@ -1894,7 +1895,7 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, NPObject *npobj)
}
NPObjWrapperHashEntry *entry = static_cast<NPObjWrapperHashEntry *>
(PL_DHashTableAdd(&sNPObjWrappers, npobj, fallible));
(PL_DHashTableAdd(sNPObjWrappers, npobj, fallible));
if (!entry) {
// Out of memory
@ -1916,24 +1917,24 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, NPObject *npobj)
entry->mNPObj = npobj;
entry->mNpp = npp;
uint32_t generation = sNPObjWrappers.Generation();
uint32_t generation = sNPObjWrappers->Generation();
// No existing JSObject, create one.
JS::Rooted<JSObject*> obj(cx, ::JS_NewObject(cx, js::Jsvalify(&sNPObjectJSWrapperClass)));
if (generation != sNPObjWrappers.Generation()) {
if (generation != sNPObjWrappers->Generation()) {
// Reload entry if the JS_NewObject call caused a GC and reallocated
// the table (see bug 445229). This is guaranteed to succeed.
NS_ASSERTION(PL_DHashTableSearch(&sNPObjWrappers, npobj),
NS_ASSERTION(PL_DHashTableSearch(sNPObjWrappers, npobj),
"Hashtable didn't find what we just added?");
}
if (!obj) {
// OOM? Remove the stale entry from the hash.
PL_DHashTableRawRemove(&sNPObjWrappers, entry);
PL_DHashTableRawRemove(sNPObjWrappers, entry);
return nullptr;
}
@ -2039,9 +2040,9 @@ nsJSNPRuntime::OnPluginDestroy(NPP npp)
// Use the safe JSContext here as we're not always able to find the
// JSContext associated with the NPP any more.
AutoSafeJSContext cx;
if (sNPObjWrappers.IsInitialized()) {
if (sNPObjWrappers) {
NppAndCx nppcx = { npp, cx };
PL_DHashTableEnumerate(&sNPObjWrappers,
PL_DHashTableEnumerate(sNPObjWrappers,
NPObjWrapperPluginDestroyedCallback, &nppcx);
}
}
@ -2074,7 +2075,7 @@ LookupNPP(NPObject *npobj)
}
NPObjWrapperHashEntry *entry = static_cast<NPObjWrapperHashEntry *>
(PL_DHashTableAdd(&sNPObjWrappers, npobj, fallible));
(PL_DHashTableAdd(sNPObjWrappers, npobj, fallible));
if (!entry) {
return nullptr;

View File

@ -235,10 +235,10 @@ Preferences::SizeOfIncludingThisAndOtherStuff(mozilla::MallocSizeOf aMallocSizeO
NS_ENSURE_TRUE(InitStaticMembers(), 0);
size_t n = aMallocSizeOf(sPreferences);
if (gHashTable.IsInitialized()) {
if (gHashTable) {
// pref keys are allocated in a private arena, which we count elsewhere.
// pref stringvals are allocated out of the same private arena.
n += PL_DHashTableSizeOfExcludingThis(&gHashTable, nullptr, aMallocSizeOf);
n += PL_DHashTableSizeOfExcludingThis(gHashTable, nullptr, aMallocSizeOf);
}
if (gCacheData) {
n += gCacheData->SizeOfIncludingThis(aMallocSizeOf);
@ -738,8 +738,8 @@ Preferences::GetPreference(PrefSetting* aPref)
void
Preferences::GetPreferences(InfallibleTArray<PrefSetting>* aPrefs)
{
aPrefs->SetCapacity(gHashTable.Capacity());
PL_DHashTableEnumerate(&gHashTable, pref_GetPrefs, aPrefs);
aPrefs->SetCapacity(gHashTable->Capacity());
PL_DHashTableEnumerate(gHashTable, pref_GetPrefs, aPrefs);
}
NS_IMETHODIMP
@ -944,7 +944,7 @@ Preferences::WritePrefFile(nsIFile* aFile)
uint32_t writeAmount;
nsresult rv;
if (!gHashTable.IsInitialized())
if (!gHashTable)
return NS_ERROR_NOT_INITIALIZED;
// execute a "safe" save by saving through a tempfile
@ -958,23 +958,24 @@ Preferences::WritePrefFile(nsIFile* aFile)
if (NS_FAILED(rv))
return rv;
nsAutoArrayPtr<char*> valueArray(new char*[gHashTable.EntryCount()]);
memset(valueArray, 0, gHashTable.EntryCount() * sizeof(char*));
nsAutoArrayPtr<char*> valueArray(new char*[gHashTable->EntryCount()]);
memset(valueArray, 0, gHashTable->EntryCount() * sizeof(char*));
pref_saveArgs saveArgs;
saveArgs.prefArray = valueArray;
saveArgs.saveTypes = SAVE_ALL;
// get the lines that we're supposed to be writing to the file
PL_DHashTableEnumerate(&gHashTable, pref_savePref, &saveArgs);
PL_DHashTableEnumerate(gHashTable, pref_savePref, &saveArgs);
/* Sort the preferences to make a readable file on disk */
NS_QuickSort(valueArray, gHashTable.EntryCount(), sizeof(char *), pref_CompareStrings, nullptr);
NS_QuickSort(valueArray, gHashTable->EntryCount(), sizeof(char *),
pref_CompareStrings, nullptr);
// write out the file header
outStream->Write(outHeader, sizeof(outHeader) - 1, &writeAmount);
char** walker = valueArray;
for (uint32_t valueIdx = 0; valueIdx < gHashTable.EntryCount(); valueIdx++, walker++) {
for (uint32_t valueIdx = 0; valueIdx < gHashTable->EntryCount(); valueIdx++, walker++) {
if (*walker) {
outStream->Write(*walker, strlen(*walker), &writeAmount);
outStream->Write(NS_LINEBREAK, NS_LINEBREAK_LEN, &writeAmount);

View File

@ -555,15 +555,15 @@ NS_IMETHODIMP nsPrefBranch::GetChildList(const char *aStartingAt, uint32_t *aCou
*aChildArray = nullptr;
*aCount = 0;
if (!gHashTable.IsInitialized())
if (!gHashTable->IsInitialized())
return NS_ERROR_NOT_INITIALIZED;
// this will contain a list of all the pref name strings
// allocate on the stack for speed
ed.parent = getPrefName(aStartingAt);
ed.pref_list = &prefArray;
PL_DHashTableEnumerate(&gHashTable, pref_enumChild, &ed);
PL_DHashTableEnumerate(gHashTable, pref_enumChild, &ed);
// now that we've built up the list, run the callback on
// all the matching elements

View File

@ -68,7 +68,7 @@ matchPrefEntry(PLDHashTable*, const PLDHashEntryHdr* entry,
return (strcmp(prefEntry->key, otherKey) == 0);
}
PLDHashTable gHashTable;
PLDHashTable* gHashTable;
static PLArenaPool gPrefNameArena;
bool gDirty = false;
@ -149,9 +149,10 @@ static nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, u
nsresult PREF_Init()
{
if (!gHashTable.IsInitialized()) {
PL_DHashTableInit(&gHashTable, &pref_HashTableOps,
sizeof(PrefHashEntry), PREF_HASHTABLE_INITIAL_LENGTH);
if (!gHashTable) {
gHashTable = new PLDHashTable(&pref_HashTableOps,
sizeof(PrefHashEntry),
PREF_HASHTABLE_INITIAL_LENGTH);
PL_INIT_ARENA_POOL(&gPrefNameArena, "PrefNameArena",
PREFNAME_ARENA_SIZE);
@ -182,8 +183,9 @@ void PREF_Cleanup()
/* Frees up all the objects except the callback list. */
void PREF_CleanupPrefs()
{
if (gHashTable.IsInitialized()) {
PL_DHashTableFinish(&gHashTable);
if (gHashTable) {
delete gHashTable;
gHashTable = nullptr;
PL_FinishArenaPool(&gPrefNameArena);
}
}
@ -466,7 +468,7 @@ pref_CompareStrings(const void *v1, const void *v2, void *unused)
bool PREF_HasUserPref(const char *pref_name)
{
if (!gHashTable.IsInitialized())
if (!gHashTable)
return false;
PrefHashEntry *pref = pref_HashTableLookup(pref_name);
@ -480,7 +482,7 @@ bool PREF_HasUserPref(const char *pref_name)
nsresult
PREF_CopyCharPref(const char *pref_name, char ** return_buffer, bool get_default)
{
if (!gHashTable.IsInitialized())
if (!gHashTable)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_ERROR_UNEXPECTED;
@ -504,7 +506,7 @@ PREF_CopyCharPref(const char *pref_name, char ** return_buffer, bool get_default
nsresult PREF_GetIntPref(const char *pref_name,int32_t * return_int, bool get_default)
{
if (!gHashTable.IsInitialized())
if (!gHashTable)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_ERROR_UNEXPECTED;
@ -528,7 +530,7 @@ nsresult PREF_GetIntPref(const char *pref_name,int32_t * return_int, bool get_de
nsresult PREF_GetBoolPref(const char *pref_name, bool * return_value, bool get_default)
{
if (!gHashTable.IsInitialized())
if (!gHashTable)
return NS_ERROR_NOT_INITIALIZED;
nsresult rv = NS_ERROR_UNEXPECTED;
@ -579,7 +581,7 @@ PREF_DeleteBranch(const char *branch_name)
int len = (int)strlen(branch_name);
if (!gHashTable.IsInitialized())
if (!gHashTable)
return NS_ERROR_NOT_INITIALIZED;
/* The following check insures that if the branch name already has a "."
@ -592,7 +594,7 @@ PREF_DeleteBranch(const char *branch_name)
if ((len > 1) && branch_name[len - 1] != '.')
branch_dot += '.';
PL_DHashTableEnumerate(&gHashTable, pref_DeleteItem,
PL_DHashTableEnumerate(gHashTable, pref_DeleteItem,
(void*) branch_dot.get());
gDirty = true;
return NS_OK;
@ -602,7 +604,7 @@ PREF_DeleteBranch(const char *branch_name)
nsresult
PREF_ClearUserPref(const char *pref_name)
{
if (!gHashTable.IsInitialized())
if (!gHashTable)
return NS_ERROR_NOT_INITIALIZED;
PrefHashEntry* pref = pref_HashTableLookup(pref_name);
@ -611,7 +613,7 @@ PREF_ClearUserPref(const char *pref_name)
pref->flags &= ~PREF_USERSET;
if (!(pref->flags & PREF_HAS_DEFAULT)) {
PL_DHashTableRemove(&gHashTable, pref_name);
PL_DHashTableRemove(gHashTable, pref_name);
}
pref_DoCallback(pref_name);
@ -647,11 +649,11 @@ PREF_ClearAllUserPrefs()
MOZ_ASSERT(NS_IsMainThread());
#endif
if (!gHashTable.IsInitialized())
if (!gHashTable)
return NS_ERROR_NOT_INITIALIZED;
std::vector<std::string> prefStrings;
PL_DHashTableEnumerate(&gHashTable, pref_ClearUserPref, static_cast<void*>(&prefStrings));
PL_DHashTableEnumerate(gHashTable, pref_ClearUserPref, static_cast<void*>(&prefStrings));
for (std::string& prefString : prefStrings) {
pref_DoCallback(prefString.c_str());
@ -663,7 +665,7 @@ PREF_ClearAllUserPrefs()
nsresult PREF_LockPref(const char *key, bool lockit)
{
if (!gHashTable.IsInitialized())
if (!gHashTable)
return NS_ERROR_NOT_INITIALIZED;
PrefHashEntry* pref = pref_HashTableLookup(key);
@ -734,7 +736,7 @@ PrefHashEntry* pref_HashTableLookup(const void *key)
MOZ_ASSERT(NS_IsMainThread());
#endif
return static_cast<PrefHashEntry*>(PL_DHashTableSearch(&gHashTable, key));
return static_cast<PrefHashEntry*>(PL_DHashTableSearch(gHashTable, key));
}
nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, uint32_t flags)
@ -743,11 +745,11 @@ nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, uint32_t
MOZ_ASSERT(NS_IsMainThread());
#endif
if (!gHashTable.IsInitialized())
if (!gHashTable)
return NS_ERROR_OUT_OF_MEMORY;
PrefHashEntry* pref = static_cast<PrefHashEntry*>
(PL_DHashTableAdd(&gHashTable, key, fallible));
(PL_DHashTableAdd(gHashTable, key, fallible));
if (!pref)
return NS_ERROR_OUT_OF_MEMORY;
@ -839,8 +841,7 @@ pref_SizeOfPrivateData(MallocSizeOf aMallocSizeOf)
PrefType
PREF_GetPrefType(const char *pref_name)
{
if (gHashTable.IsInitialized())
{
if (gHashTable) {
PrefHashEntry* pref = pref_HashTableLookup(pref_name);
if (pref)
{
@ -861,7 +862,7 @@ bool
PREF_PrefIsLocked(const char *pref_name)
{
bool result = false;
if (gIsAnyPrefLocked && gHashTable.IsInitialized()) {
if (gIsAnyPrefLocked && gHashTable) {
PrefHashEntry* pref = pref_HashTableLookup(pref_name);
if (pref && PREF_IS_LOCKED(pref))
result = true;

View File

@ -10,8 +10,8 @@
#include "mozilla/MemoryReporting.h"
extern PLDHashTable gHashTable;
extern bool gDirty;
extern PLDHashTable* gHashTable;
extern bool gDirty;
namespace mozilla {
namespace dom {

View File

@ -40,7 +40,7 @@ struct HttpHeapAtom {
char value[1];
};
static PLDHashTable sAtomTable;
static PLDHashTable *sAtomTable;
static struct HttpHeapAtom *sHeapAtoms = nullptr;
static Mutex *sLock = nullptr;
@ -94,7 +94,7 @@ static const PLDHashTableOps ops = {
nsresult
nsHttp::CreateAtomTable()
{
MOZ_ASSERT(!sAtomTable.IsInitialized(), "atom table already initialized");
MOZ_ASSERT(!sAtomTable, "atom table already initialized");
if (!sLock) {
sLock = new Mutex("nsHttp.sLock");
@ -103,8 +103,8 @@ nsHttp::CreateAtomTable()
// The initial length for this table is a value greater than the number of
// known atoms (NUM_HTTP_ATOMS) because we expect to encounter a few random
// headers right off the bat.
PL_DHashTableInit(&sAtomTable, &ops, sizeof(PLDHashEntryStub),
NUM_HTTP_ATOMS + 10);
sAtomTable = new PLDHashTable(&ops, sizeof(PLDHashEntryStub),
NUM_HTTP_ATOMS + 10);
// fill the table with our known atoms
const char *const atoms[] = {
@ -116,7 +116,7 @@ nsHttp::CreateAtomTable()
for (int i = 0; atoms[i]; ++i) {
PLDHashEntryStub *stub = reinterpret_cast<PLDHashEntryStub *>
(PL_DHashTableAdd(&sAtomTable, atoms[i], fallible));
(PL_DHashTableAdd(sAtomTable, atoms[i], fallible));
if (!stub)
return NS_ERROR_OUT_OF_MEMORY;
@ -130,9 +130,8 @@ nsHttp::CreateAtomTable()
void
nsHttp::DestroyAtomTable()
{
if (sAtomTable.IsInitialized()) {
PL_DHashTableFinish(&sAtomTable);
}
delete sAtomTable;
sAtomTable = nullptr;
while (sHeapAtoms) {
HttpHeapAtom *next = sHeapAtoms->next;
@ -140,10 +139,8 @@ nsHttp::DestroyAtomTable()
sHeapAtoms = next;
}
if (sLock) {
delete sLock;
sLock = nullptr;
}
delete sLock;
sLock = nullptr;
}
Mutex *
@ -158,13 +155,13 @@ nsHttp::ResolveAtom(const char *str)
{
nsHttpAtom atom = { nullptr };
if (!str || !sAtomTable.IsInitialized())
if (!str || !sAtomTable)
return atom;
MutexAutoLock lock(*sLock);
PLDHashEntryStub *stub = reinterpret_cast<PLDHashEntryStub *>
(PL_DHashTableAdd(&sAtomTable, str, fallible));
(PL_DHashTableAdd(sAtomTable, str, fallible));
if (!stub)
return atom; // out of memory

View File

@ -7,8 +7,6 @@
#include "nsHTMLEntities.h"
#include "nsString.h"
#include "nsCRT.h"
#include "pldhash.h"
@ -67,8 +65,8 @@ static const PLDHashTableOps UnicodeToEntityOps = {
nullptr,
};
static PLDHashTable gEntityToUnicode;
static PLDHashTable gUnicodeToEntity;
static PLDHashTable* gEntityToUnicode;
static PLDHashTable* gUnicodeToEntity;
static nsrefcnt gTableRefCnt = 0;
#define HTML_ENTITY(_name, _value) { #_name, _value },
@ -83,10 +81,12 @@ nsresult
nsHTMLEntities::AddRefTable(void)
{
if (!gTableRefCnt) {
PL_DHashTableInit(&gEntityToUnicode, &EntityToUnicodeOps,
sizeof(EntityNodeEntry), NS_HTML_ENTITY_COUNT);
PL_DHashTableInit(&gUnicodeToEntity, &UnicodeToEntityOps,
sizeof(EntityNodeEntry), NS_HTML_ENTITY_COUNT);
gEntityToUnicode = new PLDHashTable(&EntityToUnicodeOps,
sizeof(EntityNodeEntry),
NS_HTML_ENTITY_COUNT);
gUnicodeToEntity = new PLDHashTable(&UnicodeToEntityOps,
sizeof(EntityNodeEntry),
NS_HTML_ENTITY_COUNT);
for (const EntityNode *node = gEntityArray,
*node_end = ArrayEnd(gEntityArray);
node < node_end; ++node) {
@ -94,7 +94,7 @@ nsHTMLEntities::AddRefTable(void)
// add to Entity->Unicode table
EntityNodeEntry* entry =
static_cast<EntityNodeEntry*>
(PL_DHashTableAdd(&gEntityToUnicode, node->mStr, fallible));
(PL_DHashTableAdd(gEntityToUnicode, node->mStr, fallible));
NS_ASSERTION(entry, "Error adding an entry");
// Prefer earlier entries when we have duplication.
if (!entry->node)
@ -102,7 +102,7 @@ nsHTMLEntities::AddRefTable(void)
// add to Unicode->Entity table
entry = static_cast<EntityNodeEntry*>
(PL_DHashTableAdd(&gUnicodeToEntity,
(PL_DHashTableAdd(gUnicodeToEntity,
NS_INT32_TO_PTR(node->mUnicode),
fallible));
NS_ASSERTION(entry, "Error adding an entry");
@ -111,8 +111,8 @@ nsHTMLEntities::AddRefTable(void)
entry->node = node;
}
#ifdef DEBUG
PL_DHashMarkTableImmutable(&gUnicodeToEntity);
PL_DHashMarkTableImmutable(&gEntityToUnicode);
PL_DHashMarkTableImmutable(gUnicodeToEntity);
PL_DHashMarkTableImmutable(gEntityToUnicode);
#endif
}
++gTableRefCnt;
@ -125,20 +125,17 @@ nsHTMLEntities::ReleaseTable(void)
if (--gTableRefCnt != 0)
return;
if (gEntityToUnicode.IsInitialized()) {
PL_DHashTableFinish(&gEntityToUnicode);
}
if (gUnicodeToEntity.IsInitialized()) {
PL_DHashTableFinish(&gUnicodeToEntity);
}
delete gEntityToUnicode;
delete gUnicodeToEntity;
gEntityToUnicode = nullptr;
gUnicodeToEntity = nullptr;
}
int32_t
nsHTMLEntities::EntityToUnicode(const nsCString& aEntity)
{
NS_ASSERTION(gEntityToUnicode.IsInitialized(),
"no lookup table, needs addref");
if (!gEntityToUnicode.IsInitialized())
NS_ASSERTION(gEntityToUnicode, "no lookup table, needs addref");
if (!gEntityToUnicode)
return -1;
//this little piece of code exists because entities may or may not have the terminating ';'.
@ -152,7 +149,7 @@ nsHTMLEntities::EntityToUnicode(const nsCString& aEntity)
EntityNodeEntry* entry =
static_cast<EntityNodeEntry*>
(PL_DHashTableSearch(&gEntityToUnicode, aEntity.get()));
(PL_DHashTableSearch(gEntityToUnicode, aEntity.get()));
return entry ? entry->node->mUnicode : -1;
}
@ -172,11 +169,10 @@ nsHTMLEntities::EntityToUnicode(const nsAString& aEntity) {
const char*
nsHTMLEntities::UnicodeToEntity(int32_t aUnicode)
{
NS_ASSERTION(gUnicodeToEntity.IsInitialized(),
"no lookup table, needs addref");
NS_ASSERTION(gUnicodeToEntity, "no lookup table, needs addref");
EntityNodeEntry* entry =
static_cast<EntityNodeEntry*>
(PL_DHashTableSearch(&gUnicodeToEntity, NS_INT32_TO_PTR(aUnicode)));
(PL_DHashTableSearch(gUnicodeToEntity, NS_INT32_TO_PTR(aUnicode)));
return entry ? entry->node->mStr : nullptr;
}

View File

@ -41,7 +41,7 @@ using namespace mozilla;
* sure it's only manipulated from the main thread. Probably the latter
* is better, since the former would hurt performance.
*/
static PLDHashTable gAtomTable;
static PLDHashTable* gAtomTable;
class StaticAtomEntry : public PLDHashEntryHdr
{
@ -336,19 +336,21 @@ void
NS_PurgeAtomTable()
{
delete gStaticAtomTable;
gStaticAtomTable = nullptr;
if (gAtomTable.IsInitialized()) {
if (gAtomTable) {
#ifdef DEBUG
const char* dumpAtomLeaks = PR_GetEnv("MOZ_DUMP_ATOM_LEAKS");
if (dumpAtomLeaks && *dumpAtomLeaks) {
uint32_t leaked = 0;
printf("*** %d atoms still exist (including permanent):\n",
gAtomTable.EntryCount());
PL_DHashTableEnumerate(&gAtomTable, DumpAtomLeaks, &leaked);
gAtomTable->EntryCount());
PL_DHashTableEnumerate(gAtomTable, DumpAtomLeaks, &leaked);
printf("*** %u non-permanent atoms leaked\n", leaked);
}
#endif
PL_DHashTableFinish(&gAtomTable);
delete gAtomTable;
gAtomTable = nullptr;
}
}
@ -397,17 +399,16 @@ AtomImpl::AtomImpl(nsStringBuffer* aStringBuffer, uint32_t aLength,
AtomImpl::~AtomImpl()
{
NS_PRECONDITION(gAtomTable.IsInitialized(), "uninitialized atom hashtable");
MOZ_ASSERT(gAtomTable, "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_DHashTableRemove(&gAtomTable, &key);
if (gAtomTable.IsInitialized() && gAtomTable.EntryCount() == 0) {
PL_DHashTableFinish(&gAtomTable);
NS_ASSERTION(gAtomTable.EntryCount() == 0,
"PL_DHashTableFinish changed the entry count");
PL_DHashTableRemove(gAtomTable, &key);
if (gAtomTable->EntryCount() == 0) {
delete gAtomTable;
gAtomTable = nullptr;
}
}
@ -523,8 +524,8 @@ void
NS_SizeOfAtomTablesIncludingThis(MallocSizeOf aMallocSizeOf,
size_t* aMain, size_t* aStatic)
{
*aMain = gAtomTable.IsInitialized()
? PL_DHashTableSizeOfExcludingThis(&gAtomTable,
*aMain = gAtomTable
? PL_DHashTableSizeOfExcludingThis(gAtomTable,
SizeOfAtomTableEntryExcludingThis,
aMallocSizeOf)
: 0;
@ -541,9 +542,9 @@ NS_SizeOfAtomTablesIncludingThis(MallocSizeOf aMallocSizeOf,
static inline void
EnsureTableExists()
{
if (!gAtomTable.IsInitialized()) {
PL_DHashTableInit(&gAtomTable, &AtomTableOps,
sizeof(AtomTableEntry), ATOM_HASHTABLE_INITIAL_LENGTH);
if (!gAtomTable) {
gAtomTable = new PLDHashTable(&AtomTableOps, sizeof(AtomTableEntry),
ATOM_HASHTABLE_INITIAL_LENGTH);
}
}
@ -554,7 +555,7 @@ GetAtomHashEntry(const char* aString, uint32_t aLength, uint32_t* aHashOut)
EnsureTableExists();
AtomTableKey key(aString, aLength, aHashOut);
// This is an infallible add.
return static_cast<AtomTableEntry*>(PL_DHashTableAdd(&gAtomTable, &key));
return static_cast<AtomTableEntry*>(PL_DHashTableAdd(gAtomTable, &key));
}
static inline AtomTableEntry*
@ -564,7 +565,7 @@ GetAtomHashEntry(const char16_t* aString, uint32_t aLength, uint32_t* aHashOut)
EnsureTableExists();
AtomTableKey key(aString, aLength, aHashOut);
// This is an infallible add.
return static_cast<AtomTableEntry*>(PL_DHashTableAdd(&gAtomTable, &key));
return static_cast<AtomTableEntry*>(PL_DHashTableAdd(gAtomTable, &key));
}
class CheckStaticAtomSizes
@ -709,7 +710,8 @@ NS_NewPermanentAtom(const nsAString& aUTF16String)
nsrefcnt
NS_GetNumberOfAtoms(void)
{
return gAtomTable.EntryCount();
MOZ_ASSERT(gAtomTable);
return gAtomTable->EntryCount();
}
nsIAtom*