Bug 677653 - part 2 - add a memory reporter for vorbis-related allocations; r=njn
authorNathan Froyd <froydnj@mozilla.com>
Tue, 25 Feb 2014 11:04:50 -0500
changeset 189977 f84cf36472d3265c221fb75c756364552856a568
parent 189976 54c0440b476fd741f2b075ffe2633f145a8780a0
child 189978 334db4ff0617eb8cdb682d7b807aacd423f565f7
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs677653
milestone30.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 677653 - part 2 - add a memory reporter for vorbis-related allocations; r=njn
xpcom/build/nsXPComInit.cpp
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -124,16 +124,18 @@ extern nsresult nsStringInputStreamConst
 #include "mozilla/AvailableMemoryTracker.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/SystemMemoryReporter.h"
 
 #ifdef MOZ_VISUAL_EVENT_TRACER
 #include "mozilla/VisualEventTracer.h"
 #endif
 
+#include "ogg/ogg.h"
+
 #include "GeckoProfiler.h"
 
 #include "jsapi.h"
 
 using namespace mozilla;
 using base::AtExitManager;
 using mozilla::ipc::BrowserProcessSubThread;
 #ifdef MOZ_VISUAL_EVENT_TRACER
@@ -390,16 +392,88 @@ private:
             "Memory used by ICU, a Unicode and globalization support library.");
     }
 };
 
 NS_IMPL_ISUPPORTS1(ICUReporter, nsIMemoryReporter)
 
 /* static */ Atomic<size_t> ICUReporter::sAmount;
 
+class OggReporter MOZ_FINAL : public nsIMemoryReporter
+{
+public:
+    NS_DECL_ISUPPORTS
+
+    OggReporter()
+    {
+#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;
+    }
+
+    static void* Alloc(size_t size)
+    {
+        void* p = malloc(size);
+        sAmount += MallocSizeOfOnAlloc(p);
+        return p;
+    }
+
+    static void* Realloc(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* Calloc(size_t nmemb, size_t size)
+    {
+        void* p = calloc(nmemb, size);
+        sAmount += MallocSizeOfOnAlloc(p);
+        return p;
+    }
+
+    static void Free(void* p)
+    {
+        sAmount -= MallocSizeOfOnFree(p);
+        free(p);
+    }
+
+private:
+    // |sAmount| can be (implicitly) accessed by multiple threads, so it
+    // must be thread-safe.
+    static Atomic<size_t> sAmount;
+
+    MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf)
+    MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(MallocSizeOfOnAlloc)
+    MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(MallocSizeOfOnFree)
+
+    NS_IMETHODIMP
+    CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData)
+    {
+        return MOZ_COLLECT_REPORT(
+            "explicit/media/libogg", KIND_HEAP, UNITS_BYTES, sAmount,
+            "Memory allocated through libogg for Ogg, Theora, and related media files.");
+    }
+};
+
+NS_IMPL_ISUPPORTS1(OggReporter, nsIMemoryReporter)
+
+/* static */ Atomic<size_t> OggReporter::sAmount;
+
 EXPORT_XPCOM_API(nsresult)
 NS_InitXPCOM2(nsIServiceManager* *result,
               nsIFile* binDirectory,
               nsIDirectoryServiceProvider* appFileLocationProvider)
 {
     mozPoisonValueInit();
 
     char aLocal;
@@ -543,16 +617,22 @@ NS_InitXPCOM2(nsIServiceManager* *result
     // 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.
     mozilla::SetICUMemoryFunctions();
 
+    // Do the same for libogg.
+    ogg_set_mem_functions(OggReporter::Alloc,
+                          OggReporter::Calloc,
+                          OggReporter::Realloc,
+                          OggReporter::Free);
+
     // Initialize the JS engine.
     if (!JS_Init()) {
         NS_RUNTIMEABORT("JS_Init failed");
     }
 
     rv = nsComponentManagerImpl::gComponentManager->Init();
     if (NS_FAILED(rv))
     {
@@ -591,18 +671,19 @@ NS_InitXPCOM2(nsIServiceManager* *result
     // We only want the SystemMemoryReporter running in one process, because it
     // profiles the entire system.  The main process is the obvious place for
     // it.
     if (XRE_GetProcessType() == GeckoProcessType_Default) {
         mozilla::SystemMemoryReporter::Init();
     }
 
     // The memory reporter manager is up and running -- register a reporter for
-    // ICU's memory usage.
+    // ICU's and libogg's memory usage.
     RegisterStrongMemoryReporter(new ICUReporter());
+    RegisterStrongMemoryReporter(new OggReporter());
 
     mozilla::Telemetry::Init();
 
     mozilla::HangMonitor::Startup();
     mozilla::BackgroundHangMonitor::Startup();
 
     const MessageLoop* const loop = MessageLoop::current();
     sMainHangMonitor = new mozilla::BackgroundHangMonitor(