Bug 831193 (part 17) - Don't use NS_MEMORY_REPORTER_IMPLEMENT in xpcom/. r=jlebar.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 17 Jan 2013 21:43:21 -0800
changeset 157587 24b954d5230c8f6df5c1a021d0a3bd4629b21ca0
parent 157586 15a219d9119ee956a2216ddc289fe593ba337000
child 157588 e6b4c661c616636e8018fcff3fb1d9f5be913b70
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 17) - Don't use NS_MEMORY_REPORTER_IMPLEMENT in xpcom/. r=jlebar.
xpcom/base/AvailableMemoryTracker.cpp
xpcom/base/MapsMemoryReporter.cpp
xpcom/base/nsMemoryInfoDumper.cpp
xpcom/base/nsMemoryReporterManager.cpp
xpcom/build/XPCOM.h
xpcom/components/nsCategoryManager.cpp
xpcom/components/nsCategoryManager.h
xpcom/components/nsComponentManager.cpp
xpcom/components/nsComponentManager.h
xpcom/reflect/xptinfo/public/XPTInterfaceInfoManager.h
xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
xpcom/reflect/xptinfo/src/xptiprivate.h
--- a/xpcom/base/AvailableMemoryTracker.cpp
+++ b/xpcom/base/AvailableMemoryTracker.cpp
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 ci et: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/AvailableMemoryTracker.h"
 
 #include "prinrval.h"
 #include "prenv.h"
@@ -320,57 +320,24 @@ CreateDIBSectionHook(HDC aDC,
 
   if (doCheck) {
     CheckMemAvailable();
   }
 
   return result;
 }
 
-class NumLowMemoryEventsReporter : public nsIMemoryReporter
-{
-  NS_IMETHOD GetProcess(nsACString &aProcess)
-  {
-    aProcess.Truncate();
-    return NS_OK;
-  }
-
-  NS_IMETHOD GetKind(int *aKind)
-  {
-    *aKind = KIND_OTHER;
-    return NS_OK;
-  }
-
-  NS_IMETHOD GetUnits(int *aUnits)
-  {
-    *aUnits = UNITS_COUNT_CUMULATIVE;
-    return NS_OK;
-  }
-};
-
-class NumLowVirtualMemoryEventsMemoryReporter MOZ_FINAL : public NumLowMemoryEventsReporter
+class LowMemoryEventsVirtualReporter MOZ_FINAL : public MemoryReporterBase
 {
 public:
-  NS_DECL_ISUPPORTS
-
-  NS_IMETHOD GetPath(nsACString &aPath)
-  {
-    aPath.AssignLiteral("low-memory-events/virtual");
-    return NS_OK;
-  }
-
-  NS_IMETHOD GetAmount(int64_t *aAmount)
-  {
-    // This memory reporter shouldn't be installed on 64-bit machines, since we
-    // force-disable virtual-memory tracking there.
-    MOZ_ASSERT(sizeof(void*) == 4);
-
-    *aAmount = sNumLowVirtualMemEvents;
-    return NS_OK;
-  }
+  // The description is "???" because we implement GetDescription().
+  LowMemoryEventsVirtualReporter()
+    : MemoryReporterBase("low-memory-events/virtual",
+                         KIND_OTHER, UNITS_COUNT_CUMULATIVE, "???")
+  {}
 
   NS_IMETHOD GetDescription(nsACString &aDescription)
   {
     aDescription.AssignLiteral(
       "Number of low-virtual-memory events fired since startup. ");
 
     if (sLowVirtualMemoryThreshold == 0) {
       aDescription.AppendLiteral(
@@ -383,36 +350,36 @@ public:
         "We fire such an event if we notice there is less than %d MB of virtual "
         "address space available (controlled by the "
         "'memory.low_virtual_mem_threshold_mb' pref).  We'll likely crash if "
         "we run out of virtual address space, so this event is somewhat dire.",
         sLowVirtualMemoryThreshold));
     }
     return NS_OK;
   }
+
+private:
+  int64_t Amount() MOZ_OVERRIDE
+  {
+    // This memory reporter shouldn't be installed on 64-bit machines, since we
+    // force-disable virtual-memory tracking there.
+    MOZ_ASSERT(sizeof(void*) == 4);
+
+    return sNumLowVirtualMemEvents;
+  }
 };
 
-NS_IMPL_ISUPPORTS1(NumLowVirtualMemoryEventsMemoryReporter, nsIMemoryReporter)
-
-class NumLowCommitSpaceEventsMemoryReporter MOZ_FINAL : public NumLowMemoryEventsReporter
+class LowCommitSpaceEventsReporter MOZ_FINAL : public MemoryReporterBase
 {
 public:
-  NS_DECL_ISUPPORTS
-
-  NS_IMETHOD GetPath(nsACString &aPath)
-  {
-    aPath.AssignLiteral("low-commit-space-events");
-    return NS_OK;
-  }
-
-  NS_IMETHOD GetAmount(int64_t *aAmount)
-  {
-    *aAmount = sNumLowCommitSpaceEvents;
-    return NS_OK;
-  }
+  // The description is "???" because we implement GetDescription().
+  LowCommitSpaceEventsReporter()
+    : MemoryReporterBase("low-commit-space-events",
+                         KIND_OTHER, UNITS_COUNT_CUMULATIVE, "???")
+  {}
 
   NS_IMETHOD GetDescription(nsACString &aDescription)
   {
     aDescription.AssignLiteral(
       "Number of low-commit-space events fired since startup. ");
 
     if (sLowCommitSpaceThreshold == 0) {
       aDescription.Append(
@@ -425,36 +392,29 @@ public:
         "We fire such an event if we notice there is less than %d MB of "
         "available commit space (controlled by the "
         "'memory.low_commit_space_threshold_mb' pref).  Windows will likely "
         "kill us if we run out of commit space, so this event is somewhat dire.",
         sLowCommitSpaceThreshold));
     }
     return NS_OK;
   }
+
+private:
+  int64_t Amount() MOZ_OVERRIDE { return sNumLowCommitSpaceEvents; }
 };
 
-NS_IMPL_ISUPPORTS1(NumLowCommitSpaceEventsMemoryReporter, nsIMemoryReporter)
-
-class NumLowPhysicalMemoryEventsMemoryReporter MOZ_FINAL : public NumLowMemoryEventsReporter
+class LowMemoryEventsPhysicalReporter MOZ_FINAL : public MemoryReporterBase
 {
 public:
-  NS_DECL_ISUPPORTS
-
-  NS_IMETHOD GetPath(nsACString &aPath)
-  {
-    aPath.AssignLiteral("low-memory-events/physical");
-    return NS_OK;
-  }
-
-  NS_IMETHOD GetAmount(int64_t *aAmount)
-  {
-    *aAmount = sNumLowPhysicalMemEvents;
-    return NS_OK;
-  }
+  // The description is "???" because we implement GetDescription().
+  LowMemoryEventsPhysicalReporter()
+    : MemoryReporterBase("low-memory-events/physical",
+                         KIND_OTHER, UNITS_COUNT_CUMULATIVE, "???")
+  {}
 
   NS_IMETHOD GetDescription(nsACString &aDescription)
   {
     aDescription.AssignLiteral(
       "Number of low-physical-memory events fired since startup. ");
 
     if (sLowPhysicalMemoryThreshold == 0) {
       aDescription.Append(
@@ -468,20 +428,21 @@ public:
         "available physical memory (controlled by the "
         "'memory.low_physical_memory_threshold_mb' pref).  The machine will start "
         "to page if it runs out of physical memory; this may cause it to run "
         "slowly, but it shouldn't cause us to crash.",
         sLowPhysicalMemoryThreshold));
     }
     return NS_OK;
   }
+
+private:
+  int64_t Amount() MOZ_OVERRIDE { return sNumLowPhysicalMemEvents; }
 };
 
-NS_IMPL_ISUPPORTS1(NumLowPhysicalMemoryEventsMemoryReporter, nsIMemoryReporter)
-
 #endif // defined(XP_WIN)
 
 /**
  * This runnable is executed in response to a memory-pressure event; we spin
  * the event-loop when receiving the memory-pressure event in the hope that
  * other observers will synchronously free some memory that we'll be able to
  * purge here.
  */
@@ -587,20 +548,20 @@ void Activate()
 
   Preferences::AddUintVarCache(&sLowPhysicalMemoryThreshold,
       "memory.low_physical_memory_threshold_mb", 0);
   Preferences::AddUintVarCache(&sLowCommitSpaceThreshold,
       "memory.low_commit_space_threshold_mb", 128);
   Preferences::AddUintVarCache(&sLowMemoryNotificationIntervalMS,
       "memory.low_memory_notification_interval_ms", 10000);
 
-  NS_RegisterMemoryReporter(new NumLowCommitSpaceEventsMemoryReporter());
-  NS_RegisterMemoryReporter(new NumLowPhysicalMemoryEventsMemoryReporter());
+  NS_RegisterMemoryReporter(new LowCommitSpaceEventsReporter());
+  NS_RegisterMemoryReporter(new LowMemoryEventsPhysicalReporter());
   if (sizeof(void*) == 4) {
-    NS_RegisterMemoryReporter(new NumLowVirtualMemoryEventsMemoryReporter());
+    NS_RegisterMemoryReporter(new LowMemoryEventsVirtualReporter());
   }
   sHooksActive = true;
 #endif
 
   // This object is held alive by the observer service.
   nsRefPtr<nsMemoryPressureWatcher> watcher = new nsMemoryPressureWatcher();
   watcher->Init();
 }
--- a/xpcom/base/MapsMemoryReporter.cpp
+++ b/xpcom/base/MapsMemoryReporter.cpp
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 50; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 ci et: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Util.h"
 
 #include "mozilla/MapsMemoryReporter.h"
 #include "nsIMemoryReporter.h"
@@ -515,61 +515,64 @@ MapsReporter::ParseMapBody(
                      nsIMemoryReporter::UNITS_BYTES,
                      int64_t(size) * 1024, // convert from kB to bytes
                      aDescription, aClosure);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
-static nsresult GetUSS(int64_t *n)
+class ResidentUniqueReporter MOZ_FINAL : public MemoryReporterBase
 {
+public:
+  ResidentUniqueReporter()
+    : MemoryReporterBase("resident-unique", KIND_OTHER, UNITS_BYTES,
+"Memory mapped by the process that is present in physical memory and not "
+"shared with any other processes.  This is also known as the process's unique "
+"set size (USS).  This is the amount of RAM we'd expect to be freed if we "
+"closed this process.")
+  {}
+
+private:
+  NS_IMETHOD GetAmount(int64_t *aAmount)
+  {
     // You might be tempted to calculate USS by subtracting the "shared" value
     // from the "resident" value in /proc/<pid>/statm.  But at least on Linux,
     // statm's "shared" value actually counts pages backed by files, which has
     // little to do with whether the pages are actually shared.  smaps on the
     // other hand appears to give us the correct information.
     //
     // We could calculate this data during the smaps multi-reporter, but the
     // overhead of the smaps reporter is considerable (we don't even run the
     // smaps reporter in normal about:memory operation).  Hopefully this
     // implementation is fast enough not to matter.
 
-    *n = 0;
+    *aAmount = 0;
 
     FILE *f = fopen("/proc/self/smaps", "r");
     NS_ENSURE_STATE(f);
 
     int64_t total = 0;
     char line[256];
-    while(fgets(line, sizeof(line), f)) {
-        long long val = 0;
-        if(sscanf(line, "Private_Dirty: %lld kB", &val) == 1 ||
-           sscanf(line, "Private_Clean: %lld kB", &val) == 1) {
-            total += val * 1024; // convert from kB to bytes
-        }
+    while (fgets(line, sizeof(line), f)) {
+      long long val = 0;
+      if (sscanf(line, "Private_Dirty: %lld kB", &val) == 1 ||
+          sscanf(line, "Private_Clean: %lld kB", &val) == 1) {
+        total += val * 1024; // convert from kB to bytes
+      }
     }
-    *n = total;
+    *aAmount = total;
 
     fclose(f);
     return NS_OK;
-}
-
-NS_FALLIBLE_MEMORY_REPORTER_IMPLEMENT(USS,
-    "resident-unique",
-    KIND_OTHER,
-    UNITS_BYTES,
-    GetUSS,
-    "Memory mapped by the process that is present in physical memory and not "
-    "shared with any other processes.  This is also known as the process's "
-    "unique set size (USS).  This is the amount of RAM we'd expect to be freed "
-    "if we closed this process.")
+  }
+};
 
 void Init()
 {
   nsCOMPtr<nsIMemoryMultiReporter> reporter = new MapsReporter();
   NS_RegisterMemoryMultiReporter(reporter);
 
-  NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(USS));
+  NS_RegisterMemoryReporter(new ResidentUniqueReporter());
 }
 
 } // namespace MapsMemoryReporter
 } // namespace mozilla
--- a/xpcom/base/nsMemoryInfoDumper.cpp
+++ b/xpcom/base/nsMemoryInfoDumper.cpp
@@ -11,16 +11,17 @@
 #include "mozilla/FileUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/unused.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ContentChild.h"
 #include "nsIConsoleService.h"
 #include "nsICycleCollectorListener.h"
+#include "nsIMemoryReporter.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsGZFileWriter.h"
 #include "nsJSEnvironment.h"
 #include "nsPrintfCString.h"
 #include "pratom.h"
 
 #ifdef XP_WIN
 #include <process.h>
--- a/xpcom/base/nsMemoryReporterManager.cpp
+++ b/xpcom/base/nsMemoryReporterManager.cpp
@@ -485,17 +485,17 @@ public:
     HeapAllocatedReporter()
       : MemoryReporterBase("heap-allocated", KIND_OTHER, UNITS_BYTES,
 "Memory mapped by the heap allocator that is currently allocated to the "
 "application.  This may exceed the amount of memory requested by the "
 "application because the allocator regularly rounds up request sizes. (The "
 "exact amount requested is not recorded.)")
     {}
 private:
-    int64_t Amount()
+    int64_t Amount() MOZ_OVERRIDE
     {
         jemalloc_stats_t stats;
         jemalloc_stats(&stats);
         return (int64_t) stats.allocated;
     }
 };
 
 class HeapOverheadWasteReporter MOZ_FINAL : public MemoryReporterBase
--- a/xpcom/build/XPCOM.h
+++ b/xpcom/build/XPCOM.h
@@ -77,17 +77,16 @@
 #include "nsIFactory.h"
 #include "nsIFile.h"
 #include "nsIHashable.h"
 #include "nsIINIParser.h"
 #include "nsIInputStream.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsILineInputStream.h"
 #include "nsIMemory.h"
-#include "nsIMemoryReporter.h"
 #include "nsIMutable.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIOutputStream.h"
 #include "nsIProcess.h"
 #include "nsIProgrammingLanguage.h"
 #include "nsIProperties.h"
 #include "nsIPropertyBag2.h"
--- a/xpcom/components/nsCategoryManager.cpp
+++ b/xpcom/components/nsCategoryManager.cpp
@@ -397,24 +397,30 @@ CategoryEnumerator::enumfunc_createenume
 
 
 //
 // nsCategoryManager implementations
 //
 
 NS_IMPL_QUERY_INTERFACE1(nsCategoryManager, nsICategoryManager)
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(CategoryManagerMallocSizeOf)
-
-NS_MEMORY_REPORTER_IMPLEMENT(CategoryManager,
-    "explicit/xpcom/category-manager",
-    KIND_HEAP,
-    nsIMemoryReporter::UNITS_BYTES,
-    nsCategoryManager::GetCategoryManagerSize,
-    "Memory used for the XPCOM category manager.")
+class XPCOMCategoryManagerReporter MOZ_FINAL : public MemoryReporterBase
+{
+public:
+    XPCOMCategoryManagerReporter()
+      : MemoryReporterBase("explicit/xpcom/category-manager",
+                           KIND_HEAP, UNITS_BYTES,
+                           "Memory used for the XPCOM category manager.")
+    {}
+private:
+    int64_t Amount() MOZ_OVERRIDE
+    {
+        return nsCategoryManager::SizeOfIncludingThis(MallocSizeOf);
+    }
+};
 
 NS_IMETHODIMP_(nsrefcnt)
 nsCategoryManager::AddRef()
 {
   return 2;
 }
 
 NS_IMETHODIMP_(nsrefcnt)
@@ -458,24 +464,23 @@ nsCategoryManager::nsCategoryManager()
                      NS_CATEGORYMANAGER_ARENA_SIZE);
 
   mTable.Init();
 }
 
 void
 nsCategoryManager::InitMemoryReporter()
 {
-  mReporter = new NS_MEMORY_REPORTER_NAME(CategoryManager);
+  mReporter = new XPCOMCategoryManagerReporter();
   NS_RegisterMemoryReporter(mReporter);
 }
 
 nsCategoryManager::~nsCategoryManager()
 {
-  (void)::NS_UnregisterMemoryReporter(mReporter);
-  mReporter = nullptr;
+  NS_UnregisterMemoryReporter(mReporter);
 
   // the hashtable contains entries that must be deleted before the arena is
   // destroyed, or else you will have PRLocks undestroyed and other Really
   // Bad Stuff (TM)
   mTable.Clear();
 
   PL_FinishArenaPool(&mArena);
 }
@@ -485,36 +490,37 @@ nsCategoryManager::get_category(const ch
   CategoryNode* node;
   if (!mTable.Get(aName, &node)) {
     return nullptr;
   }
   return node;
 }
 
 /* static */ int64_t
-nsCategoryManager::GetCategoryManagerSize()
+nsCategoryManager::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf)
 {
-  MOZ_ASSERT(nsCategoryManager::gCategoryManager);
-  return nsCategoryManager::gCategoryManager->SizeOfIncludingThis(
-           CategoryManagerMallocSizeOf);
+  return nsCategoryManager::gCategoryManager
+       ? nsCategoryManager::gCategoryManager->SizeOfIncludingThisHelper(
+          aMallocSizeOf)
+       : 0;
 }
 
 static size_t
 SizeOfCategoryManagerTableEntryExcludingThis(nsDepCharHashKey::KeyType aKey,
                                              const nsAutoPtr<CategoryNode> &aData,
                                              MallocSizeOf aMallocSizeOf,
                                              void* aUserArg)
 {
     // We don't measure the string pointed to by aKey because it's a non-owning
     // pointer.
     return aData.get()->SizeOfExcludingThis(aMallocSizeOf);
 }
 
 size_t
-nsCategoryManager::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf)
+nsCategoryManager::SizeOfIncludingThisHelper(MallocSizeOf aMallocSizeOf)
 {
   size_t n = aMallocSizeOf(this);
 
   n += PL_SizeOfArenaPoolExcludingPool(&mArena, aMallocSizeOf);
 
   n += mTable.SizeOfExcludingThis(SizeOfCategoryManagerTableEntryExcludingThis,
                                   aMallocSizeOf);
 
--- a/xpcom/components/nsCategoryManager.h
+++ b/xpcom/components/nsCategoryManager.h
@@ -117,31 +117,32 @@ public:
                         char** aOldValue = NULL);
 
   static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
   void InitMemoryReporter();
 
   static nsCategoryManager* GetSingleton();
   static void Destroy();
 
-  static int64_t GetCategoryManagerSize();
-  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
+  static int64_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
 
 private:
   static nsCategoryManager* gCategoryManager;
 
   nsCategoryManager();
   ~nsCategoryManager();
 
+  size_t SizeOfIncludingThisHelper(mozilla::MallocSizeOf aMallocSizeOf);
+
   CategoryNode* get_category(const char* aName);
   void NotifyObservers(const char* aTopic,
                        const char* aCategoryName, // must be a static string
                        const char* aEntryName);
 
   PLArenaPool mArena;
   nsClassHashtable<nsDepCharHashKey, CategoryNode> mTable;
   mozilla::Mutex mLock;
   bool mSuppressNotifications;
 
-  nsIMemoryReporter* mReporter;
+  nsCOMPtr<nsIMemoryReporter> mReporter;
 };
 
 #endif
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=8 sts=4 et sw=4 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * This Original Code has been modified by IBM Corporation.
  * Modifications made by IBM described herein are
  * Copyright (c) International Business Machines
  * Corporation, 2000
@@ -274,32 +275,33 @@ CloneAndAppend(nsIFile* aBase, const nsA
     f->AppendNative(append);
     return f.forget();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsComponentManagerImpl
 ////////////////////////////////////////////////////////////////////////////////
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ComponentManagerMallocSizeOf)
-
-static int64_t
-GetComponentManagerSize()
+class XPCOMComponentManagerReporter MOZ_FINAL : public MemoryReporterBase
 {
-  MOZ_ASSERT(nsComponentManagerImpl::gComponentManager);
-  return nsComponentManagerImpl::gComponentManager->SizeOfIncludingThis(
-           ComponentManagerMallocSizeOf);
-}
-
-NS_MEMORY_REPORTER_IMPLEMENT(ComponentManager,
-    "explicit/xpcom/component-manager",
-    KIND_HEAP,
-    nsIMemoryReporter::UNITS_BYTES,
-    GetComponentManagerSize,
-    "Memory used for the XPCOM component manager.")
+public:
+    XPCOMComponentManagerReporter()
+      : MemoryReporterBase("explicit/xpcom/component-manager",
+                           KIND_HEAP, UNITS_BYTES,
+                           "Memory used for the XPCOM component manager.")
+    {}
+private:
+    int64_t Amount() MOZ_OVERRIDE
+    {
+        return nsComponentManagerImpl::gComponentManager
+             ? nsComponentManagerImpl::gComponentManager->SizeOfIncludingThis(
+                 MallocSizeOf)
+             : 0;
+    }
+};
 
 nsresult
 nsComponentManagerImpl::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult)
 {
     if (aOuter)
         return NS_ERROR_NO_AGGREGATION;
 
     if (!gComponentManager)
@@ -407,18 +409,18 @@ nsresult nsComponentManagerImpl::Init()
         cl->type = NS_COMPONENT_LOCATION;
         cl->location.Init(greOmnijar, "chrome.manifest");
     }
 
     RereadChromeManifests(false);
 
     nsCategoryManager::GetSingleton()->SuppressNotifications(false);
 
-    mReporter = new NS_MEMORY_REPORTER_NAME(ComponentManager);
-    (void)::NS_RegisterMemoryReporter(mReporter);
+    mReporter = new XPCOMComponentManagerReporter();
+    NS_RegisterMemoryReporter(mReporter);
 
     // Unfortunately, we can't register the nsCategoryManager memory reporter
     // in its constructor (which is triggered by the GetSingleton() call
     // above) because the memory reporter manager isn't initialized at that
     // point.  So we wait until now.
     nsCategoryManager::GetSingleton()->InitMemoryReporter();
 
     mStatus = NORMAL;
@@ -793,17 +795,17 @@ nsresult nsComponentManagerImpl::Shutdow
 {
     PR_ASSERT(NORMAL == mStatus);
 
     mStatus = SHUTDOWN_IN_PROGRESS;
 
     // Shutdown the component manager
     PR_LOG(nsComponentManagerLog, PR_LOG_DEBUG, ("nsComponentManager: Beginning Shutdown."));
 
-    (void)::NS_UnregisterMemoryReporter(mReporter);
+    NS_UnregisterMemoryReporter(mReporter);
     mReporter = nullptr;
 
     // Release all cached factories
     mContractIDs.Clear();
     mFactories.Clear(); // XXX release the objects, don't just clear
     mLoaderMap.Clear();
     mKnownModules.Clear();
     mKnownStaticModules.Clear();
--- a/xpcom/components/nsComponentManager.h
+++ b/xpcom/components/nsComponentManager.h
@@ -33,18 +33,18 @@
 #include "nsInterfaceHashtable.h"
 #include "nsClassHashtable.h"
 #include "nsTArray.h"
 
 #include "mozilla/Omnijar.h"
 #include "mozilla/Attributes.h"
 
 struct nsFactoryEntry;
+class nsIMemoryReporter;
 class nsIServiceManager;
-class nsIMemoryReporter;
 struct PRThread;
 
 #define NS_COMPONENTMANAGER_CID                      \
 { /* 91775d60-d5dc-11d2-92fb-00e09805570f */         \
     0x91775d60,                                      \
     0xd5dc,                                          \
     0x11d2,                                          \
     {0x92, 0xfb, 0x00, 0xe0, 0x98, 0x05, 0x57, 0x0f} \
@@ -312,17 +312,17 @@ public:
 
     nsTArray<PendingServiceInfo> mPendingServices;
 
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
 
 private:
     ~nsComponentManagerImpl();
 
-    nsIMemoryReporter* mReporter;
+    nsCOMPtr<nsIMemoryReporter> mReporter;
 };
 
 
 #define NS_MAX_FILENAME_LEN     1024
 
 #define NS_ERROR_IS_DIR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XPCOM, 24)
 
 struct nsFactoryEntry
--- a/xpcom/reflect/xptinfo/public/XPTInterfaceInfoManager.h
+++ b/xpcom/reflect/xptinfo/public/XPTInterfaceInfoManager.h
@@ -10,16 +10,17 @@
 #include "nsIInterfaceInfoManager.h"
 
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "nsDataHashtable.h"
 
 template<typename T> class nsCOMArray;
+class nsIMemoryReporter;
 class XPTHeader;
 class XPTInterfaceDirectoryEntry;
 class xptiInterfaceEntry;
 class xptiInterfaceInfo;
 class xptiTypelibGuts;
 
 namespace mozilla {
 
@@ -103,13 +104,15 @@ private:
 
     // XXX xptiInterfaceInfo want's to poke at the working set itself
     friend class ::xptiInterfaceInfo;
     friend class ::xptiInterfaceEntry;
     friend class ::xptiTypelibGuts;
 
     xptiWorkingSet               mWorkingSet;
     Mutex                        mResolveLock;
+
+    nsCOMPtr<nsIMemoryReporter>  mReporter;
 };
 
 }
 
 #endif
--- a/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
@@ -1,9 +1,10 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Implementation of xptiInterfaceInfoManager. */
 
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/XPTInterfaceInfoManager.h"
@@ -14,58 +15,58 @@
 #include "nsISupportsArray.h"
 #include "nsArrayEnumerator.h"
 #include "nsDirectoryService.h"
 #include "mozilla/FileUtils.h"
 #include "nsIMemoryReporter.h"
 
 using namespace mozilla;
 
-NS_IMPL_ISUPPORTS1(XPTInterfaceInfoManager, 
+NS_IMPL_ISUPPORTS1(XPTInterfaceInfoManager,
                    nsIInterfaceInfoManager)
 
 static XPTInterfaceInfoManager* gInterfaceInfoManager = nullptr;
 #ifdef DEBUG
 static int gCallCount = 0;
 #endif
 
-
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(XPTMallocSizeOf)
-
 size_t
 XPTInterfaceInfoManager::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf)
 {
     size_t n = aMallocSizeOf(this);
     ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
     // The entries themselves are allocated out of an arena accounted
     // for elsewhere, so don't measure them
-    n += mWorkingSet.mIIDTable.SizeOfExcludingThis(NULL, XPTMallocSizeOf);
-    n += mWorkingSet.mNameTable.SizeOfExcludingThis(NULL, XPTMallocSizeOf);
+    n += mWorkingSet.mIIDTable.SizeOfExcludingThis(NULL, aMallocSizeOf);
+    n += mWorkingSet.mNameTable.SizeOfExcludingThis(NULL, aMallocSizeOf);
     return n;
 }
 
-// static
-int64_t
-XPTInterfaceInfoManager::GetXPTIWorkingSetSize()
+class XPTIWorkingSetReporter MOZ_FINAL : public MemoryReporterBase
 {
-    size_t n = XPT_SizeOfArena(gXPTIStructArena, XPTMallocSizeOf);
-
-    if (gInterfaceInfoManager) {
-        n += gInterfaceInfoManager->SizeOfIncludingThis(XPTMallocSizeOf);
-    }
+public:
+    XPTIWorkingSetReporter()
+      : MemoryReporterBase("explicit/xpti-working-set", KIND_HEAP, UNITS_BYTES,
+                           "Memory used by the XPCOM typelib system.")
+    {}
+private:
+    int64_t Amount() MOZ_OVERRIDE
+    {
+        size_t n = gInterfaceInfoManager
+                 ? gInterfaceInfoManager->SizeOfIncludingThis(MallocSizeOf)
+                 : 0;
 
-    return n;
-}
+        // Measure gXPTIStructArena here, too.  This is a bit grotty because it
+        // doesn't belong to the xptiInterfaceInfoManager, but there's no
+        // obviously better place to measure it.
+        n += XPT_SizeOfArena(gXPTIStructArena, MallocSizeOf);
 
-NS_MEMORY_REPORTER_IMPLEMENT(XPTInterfaceInfoManager,
-                             "explicit/xpti-working-set",
-                             KIND_HEAP,
-                             UNITS_BYTES,
-                             XPTInterfaceInfoManager::GetXPTIWorkingSetSize,
-                             "Memory used by the XPCOM typelib system.")
+        return n;
+    }
+};
 
 // static
 XPTInterfaceInfoManager*
 XPTInterfaceInfoManager::GetSingleton()
 {
     if (!gInterfaceInfoManager) {
         gInterfaceInfoManager = new XPTInterfaceInfoManager();
         NS_ADDREF(gInterfaceInfoManager);
@@ -78,24 +79,27 @@ XPTInterfaceInfoManager::FreeInterfaceIn
 {
     NS_IF_RELEASE(gInterfaceInfoManager);
 }
 
 XPTInterfaceInfoManager::XPTInterfaceInfoManager()
     :   mWorkingSet(),
         mResolveLock("XPTInterfaceInfoManager.mResolveLock")
 {
-    NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(XPTInterfaceInfoManager));
+    mReporter = new XPTIWorkingSetReporter();
+    NS_RegisterMemoryReporter(mReporter);
 }
 
 XPTInterfaceInfoManager::~XPTInterfaceInfoManager()
 {
     // We only do this on shutdown of the service.
     mWorkingSet.InvalidateInterfaceInfos();
 
+    NS_UnregisterMemoryReporter(mReporter);
+
     gInterfaceInfoManager = nullptr;
 #ifdef DEBUG
     gCallCount = 0;
 #endif
 }
 
 void
 XPTInterfaceInfoManager::RegisterBuffer(char *buf, uint32_t length)
--- a/xpcom/reflect/xptinfo/src/xptiprivate.h
+++ b/xpcom/reflect/xptinfo/src/xptiprivate.h
@@ -67,17 +67,16 @@
 
 #if 1 && defined(DEBUG_jband)
 #define SHOW_INFO_COUNT_STATS
 #endif
 
 /***************************************************************************/
 
 class xptiInterfaceInfo;
-class xptiInterfaceInfoManager;
 class xptiInterfaceEntry;
 class xptiTypelibGuts;
 
 extern XPTArena* gXPTIStructArena;
 
 /***************************************************************************/
 
 /***************************************************************************/