Bug 831193 (part 18) - Don't use NS_MEMORY_REPORTER_IMPLEMENT for the ICU reporter. r=jlebar.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 22 Aug 2013 22:24:16 -0700
changeset 157588 e6b4c661c616636e8018fcff3fb1d9f5be913b70
parent 157587 24b954d5230c8f6df5c1a021d0a3bd4629b21ca0
child 157589 595cec1f096a3713325595e79a742b9252692ea0
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlebar
bugs831193
milestone26.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 831193 (part 18) - Don't use NS_MEMORY_REPORTER_IMPLEMENT for the ICU reporter. r=jlebar.
xpcom/build/nsXPComInit.cpp
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -329,61 +329,68 @@ NS_GetTraceRefcnt(nsITraceRefcnt** resul
 
 EXPORT_XPCOM_API(nsresult)
 NS_InitXPCOM(nsIServiceManager* *result,
                              nsIFile* binDirectory)
 {
     return NS_InitXPCOM2(result, binDirectory, nullptr);
 }
 
-// |sSizeOfICU| can be accessed by multiple JSRuntimes, so it must be
-// thread-safe.
-static Atomic<size_t> sSizeOfICU;
-
-static int64_t
-GetICUSize()
+class ICUReporter MOZ_FINAL : public MemoryReporterBase
 {
-    return sSizeOfICU;
-}
+public:
+    ICUReporter()
+      : MemoryReporterBase("explicit/icu", KIND_HEAP, UNITS_BYTES,
+"Memory used by ICU, a Unicode and globalization support library.")
+    {
+#ifdef DEBUG
+        // There must be only one instance of this class, due to |sAmount|
+        // being static.
+        static bool hasRun = false;
+        MOZ_ASSERT(!hasRun);
+        hasRun = true;
+#endif
+        sAmount = 0;
+    }
 
-NS_MEMORY_REPORTER_IMPLEMENT(ICU,
-    "explicit/icu",
-    KIND_HEAP,
-    UNITS_BYTES,
-    GetICUSize,
-    "Memory used by ICU, a Unicode and globalization support library."
-)
-
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_ALLOC_FUN(ICUMallocSizeOfOnAlloc)
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_FREE_FUN(ICUMallocSizeOfOnFree)
+    static void* Alloc(const void*, size_t size)
+    {
+        void* p = malloc(size);
+        sAmount += MallocSizeOfOnAlloc(p);
+        return p;
+    }
 
-static void*
-ICUAlloc(const void*, size_t size)
-{
-    void* p = malloc(size);
-    sSizeOfICU += ICUMallocSizeOfOnAlloc(p);
-    return p;
-}
+    static void* Realloc(const void*, void* p, size_t size)
+    {
+        sAmount -= MallocSizeOfOnFree(p);
+        void *pnew = realloc(p, size);
+        if (pnew) {
+            sAmount += MallocSizeOfOnAlloc(pnew);
+        } else {
+            // realloc failed;  undo the decrement from above
+            sAmount += MallocSizeOfOnAlloc(p);
+        }
+        return pnew;
+    }
 
-static void*
-ICURealloc(const void*, void* p, size_t size)
-{
-    size_t delta = 0 - ICUMallocSizeOfOnFree(p);
-    void* pnew = realloc(p, size);
-    delta += pnew ? ICUMallocSizeOfOnAlloc(pnew) : ICUMallocSizeOfOnAlloc(p);
-    sSizeOfICU += delta;
-    return pnew;
-}
+    static void Free(const void*, void* p)
+    {
+        sAmount -= MallocSizeOfOnFree(p);
+        free(p);
+    }
 
-static void
-ICUFree(const void*, void* p)
-{
-    sSizeOfICU -= ICUMallocSizeOfOnFree(p);
-    free(p);
-}
+private:
+    // |sAmount| can be (implicitly) accessed by multiple JSRuntimes, so it
+    // must be thread-safe.
+    static Atomic<size_t> sAmount;
+
+    int64_t Amount() MOZ_OVERRIDE { return sAmount; }
+};
+
+/* static */ Atomic<size_t> ICUReporter::sAmount;
 
 EXPORT_XPCOM_API(nsresult)
 NS_InitXPCOM2(nsIServiceManager* *result,
               nsIFile* binDirectory,
               nsIDirectoryServiceProvider* appFileLocationProvider)
 {
     mozPoisonValueInit();
 
@@ -519,17 +526,18 @@ NS_InitXPCOM2(nsIServiceManager* *result
     nsCycleCollector_startup();
 
     // Register ICU memory functions.  This really shouldn't be necessary: the
     // JS engine should do this on its own inside JS_Init, and memory-reporting
     // code should call a JSAPI function to observe ICU memory usage.  But we
     // can't define the alloc/free functions in the JS engine, because it can't
     // depend on the XPCOM-based memory reporting goop.  So for now, we have
     // this oddness.
-    if (!JS_SetICUMemoryFunctions(ICUAlloc, ICURealloc, ICUFree)) {
+    if (!JS_SetICUMemoryFunctions(ICUReporter::Alloc, ICUReporter::Realloc,
+                                  ICUReporter::Free)) {
         NS_RUNTIMEABORT("JS_SetICUMemoryFunctions failed.");
     }
 
     // Initialize the JS engine.
     if (!JS_Init()) {
         NS_RUNTIMEABORT("JS_Init failed");
     }
 
@@ -567,17 +575,17 @@ NS_InitXPCOM2(nsIServiceManager* *result
 #ifdef XP_WIN
     CreateAnonTempFileRemover();
 #endif
 
     mozilla::MapsMemoryReporter::Init();
 
     // The memory reporter manager is up and running -- register a reporter for
     // ICU's memory usage.
-    NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(ICU));
+    NS_RegisterMemoryReporter(new ICUReporter());
 
     mozilla::Telemetry::Init();
 
     mozilla::HangMonitor::Startup();
 
 #ifdef MOZ_VISUAL_EVENT_TRACER
     mozilla::eventtracer::Init();
 #endif