Bug 1275755 - Use an explicit init routine for the atom table. r=froydnj
authorBobby Holley <bobbyholley@gmail.com>
Wed, 25 May 2016 18:45:17 -0700
changeset 340455 2ec4d49ae88dbaf20b1d8f2e119695ede301957c
parent 340454 5bab999902fc0147cd24d3f5e1d7465f8ccd498e
child 340456 10ce0f01ee4a95e3e2ae337d6e4725368a6376eb
push id1183
push userraliiev@mozilla.com
push dateMon, 05 Sep 2016 20:01:49 +0000
treeherdermozilla-release@3148731bed45 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1275755
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1275755 - Use an explicit init routine for the atom table. r=froydnj
xpcom/build/XPCOMInit.cpp
xpcom/ds/nsAtomTable.cpp
xpcom/ds/nsAtomTable.h
--- a/xpcom/build/XPCOMInit.cpp
+++ b/xpcom/build/XPCOMInit.cpp
@@ -487,16 +487,18 @@ NS_InitXPCOM2(nsIServiceManager** aResul
   }
 
   sInitialized = true;
 
   mozPoisonValueInit();
 
   NS_LogInit();
 
+  NS_InitAtomTable();
+
   mozilla::LogModule::Init();
 
   JS_SetCurrentEmbedderTimeFunction(TimeSinceProcessCreation);
 
   char aLocal;
   profiler_init(&aLocal);
   nsresult rv = NS_OK;
 
@@ -1021,17 +1023,17 @@ ShutdownXPCOM(nsIServiceManager* aServMg
   if (nsComponentManagerImpl::gComponentManager) {
     nsrefcnt cnt;
     NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
     NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown.");
   }
   nsComponentManagerImpl::gComponentManager = nullptr;
   nsCategoryManager::Destroy();
 
-  NS_PurgeAtomTable();
+  NS_ShutdownAtomTable();
 
   NS_IF_RELEASE(gDebug);
 
   delete sIOThread;
   sIOThread = nullptr;
 
   delete sMessageLoop;
   sMessageLoop = nullptr;
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -377,38 +377,16 @@ AtomTableInitEntry(PLDHashEntryHdr* aEnt
 static const PLDHashTableOps AtomTableOps = {
   AtomTableGetHash,
   AtomTableMatchKey,
   PLDHashTable::MoveEntryStub,
   AtomTableClearEntry,
   AtomTableInitEntry
 };
 
-// The atom table very quickly gets 10,000+ entries in it (or even 100,000+).
-// But choosing the best initial length has some subtleties: we add ~2700
-// static atoms to the table at start-up, and then we start adding and removing
-// dynamic atoms. If we make the table too big to start with, when the first
-// dynamic atom gets removed the load factor will be < 25% and so we will
-// shrink it to 4096 entries.
-//
-// By choosing an initial length of 4096, we get an initial capacity of 8192.
-// That's the biggest initial capacity that will let us be > 25% full when the
-// first dynamic atom is removed (when the count is ~2700), thus avoiding any
-// shrinking.
-#define ATOM_HASHTABLE_INITIAL_LENGTH  4096
-
-static inline void
-EnsureTableExists()
-{
-  if (!gAtomTable) {
-    gAtomTable = new PLDHashTable(&AtomTableOps, sizeof(AtomTableEntry),
-                                  ATOM_HASHTABLE_INITIAL_LENGTH);
-  }
-}
-
 //----------------------------------------------------------------------
 
 DynamicAtom::~DynamicAtom()
 {
   MOZ_ASSERT(gAtomTable, "uninitialized atom hashtable");
 
   // DynamicAtoms must be removed from gAtomTable when their refcount reaches
   // zero and they are released.
@@ -459,68 +437,80 @@ public:
 typedef nsTHashtable<StaticAtomEntry> StaticAtomTable;
 static StaticAtomTable* gStaticAtomTable = nullptr;
 
 /**
  * Whether it is still OK to add atoms to gStaticAtomTable.
  */
 static bool gStaticAtomTableSealed = false;
 
-//----------------------------------------------------------------------
+// The atom table very quickly gets 10,000+ entries in it (or even 100,000+).
+// But choosing the best initial length has some subtleties: we add ~2700
+// static atoms to the table at start-up, and then we start adding and removing
+// dynamic atoms. If we make the table too big to start with, when the first
+// dynamic atom gets removed the load factor will be < 25% and so we will
+// shrink it to 4096 entries.
+//
+// By choosing an initial length of 4096, we get an initial capacity of 8192.
+// That's the biggest initial capacity that will let us be > 25% full when the
+// first dynamic atom is removed (when the count is ~2700), thus avoiding any
+// shrinking.
+#define ATOM_HASHTABLE_INITIAL_LENGTH  4096
 
 void
-NS_PurgeAtomTable()
+NS_InitAtomTable()
+{
+  MOZ_ASSERT(!gAtomTable);
+  gAtomTable = new PLDHashTable(&AtomTableOps, sizeof(AtomTableEntry),
+                                ATOM_HASHTABLE_INITIAL_LENGTH);
+}
+
+void
+NS_ShutdownAtomTable()
 {
   delete gStaticAtomTable;
   gStaticAtomTable = nullptr;
 
-  if (gAtomTable) {
-    // XXXbholley: it would be good to assert gAtomTable->EntryCount() == 0
-    // here, but that currently fails. Probably just a few things that need
-    // to be fixed up.
-    delete gAtomTable;
-    gAtomTable = nullptr;
-  }
+  // XXXbholley: it would be good to assert gAtomTable->EntryCount() == 0
+  // here, but that currently fails. Probably just a few things that need
+  // to be fixed up.
+  delete gAtomTable;
+  gAtomTable = nullptr;
 }
 
 void
 NS_SizeOfAtomTablesIncludingThis(MallocSizeOf aMallocSizeOf,
                                  size_t* aMain, size_t* aStatic)
 {
-  *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);
-    }
+  *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 pointed to by gStaticAtomTable are also pointed to by gAtomTable,
   // and they're measured by the loop above. So no need to measure them here.
   *aStatic = gStaticAtomTable
            ? gStaticAtomTable->ShallowSizeOfIncludingThis(aMallocSizeOf)
            : 0;
 }
 
 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);
   // This is an infallible add.
   return static_cast<AtomTableEntry*>(gAtomTable->Add(&key));
 }
 
 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);
   // This is an infallible add.
   return static_cast<AtomTableEntry*>(gAtomTable->Add(&key));
 }
 
 void
 RegisterStaticAtoms(const nsStaticAtom* aAtoms, uint32_t aAtomCount)
 {
--- a/xpcom/ds/nsAtomTable.h
+++ b/xpcom/ds/nsAtomTable.h
@@ -5,14 +5,15 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsAtomTable_h__
 #define nsAtomTable_h__
 
 #include "mozilla/MemoryReporting.h"
 #include <stddef.h>
 
-void NS_PurgeAtomTable();
+void NS_InitAtomTable();
+void NS_ShutdownAtomTable();
 
 void NS_SizeOfAtomTablesIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
                                       size_t* aMain, size_t* aStatic);
 
 #endif // nsAtomTable_h__