Bug 744311 (part 1) - Preliminary whitespace and code order changes. r=jlebar.
authorNicholas Nethercote <nnethercote@mozilla.com>
Mon, 09 Apr 2012 22:52:33 -0700
changeset 94742 1a38b48816c97943118f90500f9215da60468731
parent 94741 ecfe99b2c9cc0d813a3303649f7bd821596201dd
child 94743 62fc36c0317d7ffd904f166e02198cacdcbe3450
push idunknown
push userunknown
push dateunknown
reviewersjlebar
bugs744311
milestone15.0a1
Bug 744311 (part 1) - Preliminary whitespace and code order changes. r=jlebar.
content/media/nsMediaDecoder.cpp
dom/ipc/ContentChild.cpp
extensions/spellcheck/hunspell/src/mozHunspell.cpp
ipc/glue/SharedMemory.cpp
js/xpconnect/src/XPCJSRuntime.cpp
layout/style/nsLayoutStylesheetCache.cpp
netwerk/cache/nsCacheService.h
startupcache/StartupCache.cpp
toolkit/components/aboutmemory/content/aboutMemory.js
toolkit/components/places/History.cpp
xpcom/base/nsCycleCollector.cpp
xpcom/base/nsMemoryReporterManager.cpp
--- a/content/media/nsMediaDecoder.cpp
+++ b/content/media/nsMediaDecoder.cpp
@@ -217,28 +217,28 @@ bool nsMediaDecoder::CanPlayThrough()
          stats.mDownloadPosition > stats.mPlaybackPosition + readAheadMargin;
 }
 
 namespace mozilla {
 
 MediaMemoryReporter* MediaMemoryReporter::sUniqueInstance;
 
 NS_MEMORY_REPORTER_IMPLEMENT(MediaDecodedVideoMemory,
-                             "explicit/media/decoded-video",
-                             KIND_HEAP,
-                             UNITS_BYTES,
-                             MediaMemoryReporter::GetDecodedVideoMemory,
-                             "Memory used by decoded video frames.")
+  "explicit/media/decoded-video",
+  KIND_HEAP,
+  UNITS_BYTES,
+  MediaMemoryReporter::GetDecodedVideoMemory,
+  "Memory used by decoded video frames.")
 
 NS_MEMORY_REPORTER_IMPLEMENT(MediaDecodedAudioMemory,
-                             "explicit/media/decoded-audio",
-                             KIND_HEAP,
-                             UNITS_BYTES,
-                             MediaMemoryReporter::GetDecodedAudioMemory,
-                             "Memory used by decoded audio chunks.")
+  "explicit/media/decoded-audio",
+  KIND_HEAP,
+  UNITS_BYTES,
+  MediaMemoryReporter::GetDecodedAudioMemory,
+  "Memory used by decoded audio chunks.")
 
 MediaMemoryReporter::MediaMemoryReporter()
   : mMediaDecodedVideoMemory(new NS_MEMORY_REPORTER_NAME(MediaDecodedVideoMemory))
   , mMediaDecodedAudioMemory(new NS_MEMORY_REPORTER_NAME(MediaDecodedAudioMemory))
 {
   NS_RegisterMemoryReporter(mMediaDecodedVideoMemory);
   NS_RegisterMemoryReporter(mMediaDecodedAudioMemory);
 }
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -376,24 +376,26 @@ ContentChild::RecvPMemoryReportRequestCo
       nsCOMPtr<nsIMemoryReporter> r;
       e->GetNext(getter_AddRefs(r));
 
       nsCString path;
       PRInt32 kind;
       PRInt32 units;
       PRInt64 amount;
       nsCString desc;
-      r->GetPath(path);
-      r->GetKind(&kind);
-      r->GetUnits(&units);
-      r->GetAmount(&amount);
-      r->GetDescription(desc);
 
-      MemoryReport memreport(process, path, kind, units, amount, desc);
-      reports.AppendElement(memreport);
+      if (NS_SUCCEEDED(r->GetPath(path)) &&
+          NS_SUCCEEDED(r->GetKind(&kind)) &&
+          NS_SUCCEEDED(r->GetUnits(&units)) &&
+          NS_SUCCEEDED(r->GetAmount(&amount)) &&
+          NS_SUCCEEDED(r->GetDescription(desc)))
+      {
+        MemoryReport memreport(process, path, kind, units, amount, desc);
+        reports.AppendElement(memreport);
+      }
     }
 
     // Then do the memory multi-reporters, by calling CollectReports on each
     // one, whereupon the callback will turn each measurement into a
     // MemoryReport.
     mgr->EnumerateMultiReporters(getter_AddRefs(e));
     nsRefPtr<MemoryReportsWrapper> wrappedReports =
         new MemoryReportsWrapper(&reports);
--- a/extensions/spellcheck/hunspell/src/mozHunspell.cpp
+++ b/extensions/spellcheck/hunspell/src/mozHunspell.cpp
@@ -107,22 +107,22 @@ void HunspellReportMemoryAllocation(void
 void HunspellReportMemoryDeallocation(void* ptr) {
   gHunspellAllocatedSize -= HunspellMallocSizeOfForCounterDec(ptr);
 }
 static PRInt64 HunspellGetCurrentAllocatedSize() {
   return gHunspellAllocatedSize;
 }
 
 NS_MEMORY_REPORTER_IMPLEMENT(Hunspell,
-    "explicit/spell-check",
-    KIND_HEAP,
-    UNITS_BYTES,
-    HunspellGetCurrentAllocatedSize,
-    "Memory used by the Hunspell spell checking engine.  This number accounts "
-    "for the memory in use by Hunspell's internal data structures."
+  "explicit/spell-check",
+  KIND_HEAP,
+  UNITS_BYTES,
+  HunspellGetCurrentAllocatedSize,
+  "Memory used by the Hunspell spell checking engine.  This number accounts "
+  "for the memory in use by Hunspell's internal data structures."
 )
 
 nsresult
 mozHunspell::Init()
 {
   if (!mDictionaries.Init())
     return NS_ERROR_OUT_OF_MEMORY;
 
--- a/ipc/glue/SharedMemory.cpp
+++ b/ipc/glue/SharedMemory.cpp
@@ -48,28 +48,29 @@ namespace mozilla {
 namespace ipc {
 
 static PRInt64 gShmemAllocated;
 static PRInt64 gShmemMapped;
 static PRInt64 GetShmemAllocated() { return gShmemAllocated; }
 static PRInt64 GetShmemMapped() { return gShmemMapped; }
 
 NS_MEMORY_REPORTER_IMPLEMENT(ShmemAllocated,
-    "shmem-allocated",
-    KIND_OTHER,
-    UNITS_BYTES,
-    GetShmemAllocated,
-    "Memory shared with other processes that is accessible (but not "
-    "necessarily mapped).")
+  "shmem-allocated",
+  KIND_OTHER,
+  UNITS_BYTES,
+  GetShmemAllocated,
+  "Memory shared with other processes that is accessible (but not "
+  "necessarily mapped).")
+
 NS_MEMORY_REPORTER_IMPLEMENT(ShmemMapped,
-    "shmem-mapped",
-    KIND_OTHER,
-    UNITS_BYTES,
-    GetShmemMapped,
-    "Memory shared with other processes that is mapped into the address space.")
+  "shmem-mapped",
+  KIND_OTHER,
+  UNITS_BYTES,
+  GetShmemMapped,
+  "Memory shared with other processes that is mapped into the address space.")
 
 SharedMemory::SharedMemory()
   : mAllocSize(0)
   , mMappedSize(0)
 {
   // NB: SharedMemory is main-thread-only at the moment, but that may
   // change soon
   static bool registered;
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -1263,29 +1263,27 @@ GetJSUserCompartmentCount()
 
 // Nb: js-system-compartment-count + js-user-compartment-count could be
 // different to the number of compartments reported by
 // JSMemoryMultiReporter if a garbage collection occurred
 // between them being consulted.  We could move these reporters into
 // XPConnectJSCompartmentCount to avoid that problem, but then we couldn't
 // easily report them via telemetry, so we live with the small risk of
 // inconsistencies.
-NS_MEMORY_REPORTER_IMPLEMENT(
-    XPConnectJSSystemCompartmentCount,
+NS_MEMORY_REPORTER_IMPLEMENT(XPConnectJSSystemCompartmentCount,
     "js-compartments-system",
     KIND_OTHER,
     nsIMemoryReporter::UNITS_COUNT,
     GetJSSystemCompartmentCount,
     "The number of JavaScript compartments for system code.  The sum of this "
     "and 'js-compartments-user' might not match the number of compartments "
     "listed under 'js' if a garbage collection occurs at an inopportune time, "
     "but such cases should be rare.")
 
-NS_MEMORY_REPORTER_IMPLEMENT(
-    XPConnectJSUserCompartmentCount,
+NS_MEMORY_REPORTER_IMPLEMENT(XPConnectJSUserCompartmentCount,
     "js-compartments-user",
     KIND_OTHER,
     nsIMemoryReporter::UNITS_COUNT,
     GetJSUserCompartmentCount,
     "The number of JavaScript compartments for user code.  The sum of this "
     "and 'js-compartments-system' might not match the number of compartments "
     "listed under 'js' if a garbage collection occurs at an inopportune time, "
     "but such cases should be rare.")
--- a/layout/style/nsLayoutStylesheetCache.cpp
+++ b/layout/style/nsLayoutStylesheetCache.cpp
@@ -54,21 +54,21 @@ NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(Lay
 static PRInt64
 GetStylesheetCacheSize()
 {
   return nsLayoutStylesheetCache::SizeOfIncludingThis(
            LayoutStyleSheetCacheMallocSizeOf);
 }
 
 NS_MEMORY_REPORTER_IMPLEMENT(Sheets,
-                             "explicit/layout/style-sheet-cache",
-                             KIND_HEAP,
-                             nsIMemoryReporter::UNITS_BYTES,
-                             GetStylesheetCacheSize,
-                             "Memory used for some built-in style sheets.")
+  "explicit/layout/style-sheet-cache",
+  KIND_HEAP,
+  nsIMemoryReporter::UNITS_BYTES,
+  GetStylesheetCacheSize,
+  "Memory used for some built-in style sheets.")
 
 NS_IMPL_ISUPPORTS1(nsLayoutStylesheetCache, nsIObserver)
 
 nsresult
 nsLayoutStylesheetCache::Observe(nsISupports* aSubject,
                             const char* aTopic,
                             const PRUnichar* aData)
 {
--- a/netwerk/cache/nsCacheService.h
+++ b/netwerk/cache/nsCacheService.h
@@ -132,18 +132,17 @@ public:
 
     /**
      * Methods called by any cache classes
      */
 
     static
     nsCacheService * GlobalInstance()   { return gService; }
 
-    static
-    PRInt64 MemoryDeviceSize();
+    static PRInt64   MemoryDeviceSize();
     
     static nsresult  DoomEntry(nsCacheEntry * entry);
 
     static bool      IsStorageEnabledForPolicy_Locked(nsCacheStoragePolicy policy);
 
     // This method may be called to release an object while the cache service
     // lock is being held.  If a non-null target is specified and the target
     // does not correspond to the current thread, then the release will be
--- a/startupcache/StartupCache.cpp
+++ b/startupcache/StartupCache.cpp
@@ -90,40 +90,38 @@ namespace scache {
 static PRInt64
 GetStartupCacheMappingSize()
 {
     mozilla::scache::StartupCache* sc = mozilla::scache::StartupCache::GetSingleton();
     return sc ? sc->SizeOfMapping() : 0;
 }
 
 NS_MEMORY_REPORTER_IMPLEMENT(StartupCacheMapping,
-                             "explicit/startup-cache/mapping",
-                             KIND_NONHEAP,
-                             nsIMemoryReporter::UNITS_BYTES,
-                             GetStartupCacheMappingSize,
-                             "Memory used to hold the mapping of the startup "
-                             "cache from file.  This memory is likely to be "
-                             "swapped out shortly after start-up.")
+    "explicit/startup-cache/mapping",
+    KIND_NONHEAP,
+    nsIMemoryReporter::UNITS_BYTES,
+    GetStartupCacheMappingSize,
+    "Memory used to hold the mapping of the startup cache from file.  This "
+    "memory is likely to be swapped out shortly after start-up.")
 
 NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(StartupCacheDataMallocSizeOf, "startup-cache/data")
 
 static PRInt64
 GetStartupCacheDataSize()
 {
     mozilla::scache::StartupCache* sc = mozilla::scache::StartupCache::GetSingleton();
     return sc ? sc->HeapSizeOfIncludingThis(StartupCacheDataMallocSizeOf) : 0;
 }
 
 NS_MEMORY_REPORTER_IMPLEMENT(StartupCacheData,
-                             "explicit/startup-cache/data",
-                             KIND_HEAP,
-                             nsIMemoryReporter::UNITS_BYTES,
-                             GetStartupCacheDataSize,
-                             "Memory used by the startup cache for things "
-                             "other than the file mapping.")
+    "explicit/startup-cache/data",
+    KIND_HEAP,
+    nsIMemoryReporter::UNITS_BYTES,
+    GetStartupCacheDataSize,
+    "Memory used by the startup cache for things other than the file mapping.")
 
 static const char sStartupCacheName[] = "startupCache." SC_WORDSIZE "." SC_ENDIAN;
 static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
 
 StartupCache*
 StartupCache::GetSingleton() 
 {
   if (!gStartupCache)
--- a/toolkit/components/aboutmemory/content/aboutMemory.js
+++ b/toolkit/components/aboutmemory/content/aboutMemory.js
@@ -215,17 +215,17 @@ function processMemoryReporters(aMgr, aI
   {
     // There are two exception cases that must be distinguished here.
     //
     // - We want to halt proceedings on exceptions thrown within this file
     //   (i.e. assertion failures in handleReport);  such exceptions contain
     //   gAssertionFailureMsgPrefix in their string representation.
     //
     // - We want to continue on when faced with exceptions thrown outside this
-    //   file (i.e. in collectReports).
+    //   file (e.g. within a multi-reporter).
 
     let str = aE.toString();
     if (str.search(gAssertionFailureMsgPrefix) >= 0) {
       throw(aE); 
     } else {
       debug("Bad memory " + aReporterStr + " '" + aUnsafePathOrName +
             "': " + aE);
     }
--- a/toolkit/components/places/History.cpp
+++ b/toolkit/components/places/History.cpp
@@ -1429,28 +1429,27 @@ StoreAndNotifyEmbedVisit(VisitData& aPla
 }
 
 NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(HistoryLinksHashtableMallocSizeOf,
                                      "history-links-hashtable")
 
 PRInt64 GetHistoryObserversSize()
 {
   History* history = History::GetService();
-  if (!history)
-    return 0;
-  return history->SizeOfIncludingThis(HistoryLinksHashtableMallocSizeOf);
+  return history ?
+         history->SizeOfIncludingThis(HistoryLinksHashtableMallocSizeOf) : 0;
 }
 
 NS_MEMORY_REPORTER_IMPLEMENT(HistoryService,
-    "explicit/history-links-hashtable",
-    KIND_HEAP,
-    UNITS_BYTES,
-    GetHistoryObserversSize,
-    "Memory used by the hashtable of observers Places uses to notify objects of "
-    "changes to links' visited state.")
+  "explicit/history-links-hashtable",
+  KIND_HEAP,
+  UNITS_BYTES,
+  GetHistoryObserversSize,
+  "Memory used by the hashtable of observers Places uses to notify objects of "
+  "changes to links' visited state.")
 
 } // anonymous namespace
 
 ////////////////////////////////////////////////////////////////////////////////
 //// History
 
 History* History::gService = NULL;
 
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -3279,33 +3279,33 @@ nsCycleCollector::WasFreed(nsISupports *
 #endif
 
 
 ////////////////////////
 // Memory reporter
 ////////////////////////
 
 static PRInt64
-ReportCycleCollectorMem()
+GetCycleCollectorSize()
 {
     if (!sCollector)
         return 0;
     PRInt64 size = sizeof(nsCycleCollector) + 
         sCollector->mPurpleBuf.BlocksSize() +
         sCollector->mGraph.BlocksSize();
     if (sCollector->mWhiteNodes)
         size += sCollector->mWhiteNodes->Capacity() * sizeof(PtrInfo*);
     return size;
 }
 
 NS_MEMORY_REPORTER_IMPLEMENT(CycleCollector,
                              "explicit/cycle-collector",
                              KIND_HEAP,
                              UNITS_BYTES,
-                             ReportCycleCollectorMem,
+                             GetCycleCollectorSize,
                              "Memory used by the cycle collector.  This "
                              "includes the cycle collector structure, the "
                              "purple buffer, the graph, and the white nodes.  "
                              "The latter two are expected to be empty when the "
                              "cycle collector is idle.")
 
 
 ////////////////////////////////////////////////////////////////////////
--- a/xpcom/base/nsMemoryReporterManager.cpp
+++ b/xpcom/base/nsMemoryReporterManager.cpp
@@ -43,59 +43,44 @@
 #include "nsServiceManagerUtils.h"
 #include "nsMemoryReporterManager.h"
 #include "nsArrayEnumerator.h"
 #include "nsISimpleEnumerator.h"
 #include "mozilla/Telemetry.h"
 
 using namespace mozilla;
 
-static PRInt64 GetExplicit()
-{
-    nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
-    if (mgr == nsnull)
-        return (PRInt64)-1;
-
-    PRInt64 n;
-    nsresult rv = mgr->GetExplicit(&n);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    return n;
-}
-
 #if defined(MOZ_MEMORY)
 #  define HAVE_JEMALLOC_STATS 1
 #  include "jemalloc.h"
 #endif  // MOZ_MEMORY
 
 #if defined(XP_LINUX) || defined(XP_MACOSX) || defined(SOLARIS)
 
 #include <sys/time.h>
 #include <sys/resource.h>
 
 static PRInt64 GetHardPageFaults()
 {
-  struct rusage usage;
-  int err = getrusage(RUSAGE_SELF, &usage);
-  if (err != 0) {
-    return PRInt64(-1);
-  }
-
-  return usage.ru_majflt;
+    struct rusage usage;
+    int err = getrusage(RUSAGE_SELF, &usage);
+    if (err != 0) {
+        return PRInt64(-1);
+    }
+    return usage.ru_majflt;
 }
 
 static PRInt64 GetSoftPageFaults()
 {
-  struct rusage usage;
-  int err = getrusage(RUSAGE_SELF, &usage);
-  if (err != 0) {
-    return PRInt64(-1);
-  }
-
-  return usage.ru_minflt;
+    struct rusage usage;
+    int err = getrusage(RUSAGE_SELF, &usage);
+    if (err != 0) {
+        return PRInt64(-1);
+    }
+    return usage.ru_minflt;
 }
 
 #endif
 
 #if defined(XP_LINUX)
 
 #include <unistd.h>
 static PRInt64 GetProcSelfStatmField(int n)
@@ -229,24 +214,35 @@ static PRInt64 GetResident()
 
 #elif defined(XP_WIN)
 
 #include <windows.h>
 #include <psapi.h>
 
 static PRInt64 GetVsize()
 {
-  MEMORYSTATUSEX s;
-  s.dwLength = sizeof(s);
+    MEMORYSTATUSEX s;
+    s.dwLength = sizeof(s);
+
+    bool success = GlobalMemoryStatusEx(&s);
+    if (!success)
+        return -1;
+
+    return s.ullTotalVirtual - s.ullAvailVirtual;
+}
 
-  bool success = GlobalMemoryStatusEx(&s);
-  if (!success)
-    return -1;
+static PRInt64 GetResident()
+{
+    PROCESS_MEMORY_COUNTERS pmc;
+    pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS);
 
-  return s.ullTotalVirtual - s.ullAvailVirtual;
+    if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)))
+        return (PRInt64) -1;
+
+    return pmc.WorkingSetSize;
 }
 
 static PRInt64 GetPrivate()
 {
     PROCESS_MEMORY_COUNTERS_EX pmcex;
     pmcex.cb = sizeof(PROCESS_MEMORY_COUNTERS_EX);
 
     if (!GetProcessMemoryInfo(GetCurrentProcess(),
@@ -260,27 +256,16 @@ NS_MEMORY_REPORTER_IMPLEMENT(Private,
     "private",
     KIND_OTHER,
     UNITS_BYTES,
     GetPrivate,
     "Memory that cannot be shared with other processes, including memory that "
     "is committed and marked MEM_PRIVATE, data that is not mapped, and "
     "executable pages that have been written to.")
 
-static PRInt64 GetResident()
-{
-  PROCESS_MEMORY_COUNTERS pmc;
-  pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS);
-
-  if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)))
-      return (PRInt64) -1;
-
-  return pmc.WorkingSetSize;
-}
-
 #else
 
 static PRInt64 GetResident()
 {
     return (PRInt64) -1;
 }
 
 #endif
@@ -293,16 +278,28 @@ NS_MEMORY_REPORTER_IMPLEMENT(Vsize,
     GetVsize,
     "Memory mapped by the process, including code and data segments, the "
     "heap, thread stacks, memory explicitly mapped by the process via mmap "
     "and similar operations, and memory shared with other processes. "
     "This is the vsize figure as reported by 'top' and 'ps'.  This figure is of "
     "limited use on Mac, where processes share huge amounts of memory with one "
     "another.  But even on other operating systems, 'resident' is a much better "
     "measure of the memory resources used by the process.")
+
+NS_MEMORY_REPORTER_IMPLEMENT(Resident,
+    "resident",
+    KIND_OTHER,
+    UNITS_BYTES,
+    GetResident,
+    "Memory mapped by the process that is present in physical memory, "
+    "also known as the resident set size (RSS).  This is the best single "
+    "figure to use when considering the memory resources used by the process, "
+    "but it depends both on other processes being run and details of the OS "
+    "kernel and so is best used for comparing the memory usage of a single "
+    "process at different points in time.")
 #endif
 
 #if defined(XP_LINUX) || defined(XP_MACOSX) || defined(SOLARIS)
 NS_MEMORY_REPORTER_IMPLEMENT(PageFaultsSoft,
     "page-faults-soft",
     KIND_OTHER,
     UNITS_COUNT_CUMULATIVE,
     GetSoftPageFaults,
@@ -328,37 +325,16 @@ NS_MEMORY_REPORTER_IMPLEMENT(PageFaultsH
     "fault. When memory is plentiful, you should see very few hard page faults. "
     "But if the process tries to use more memory than your machine has "
     "available, you may see many thousands of hard page faults. Because "
     "accessing the disk is up to a million times slower than accessing RAM, "
     "the program may run very slowly when it is experiencing more than 100 or "
     "so hard page faults a second.")
 #endif
 
-NS_MEMORY_REPORTER_IMPLEMENT(Explicit,
-    "explicit",
-    KIND_OTHER,
-    UNITS_BYTES,
-    GetExplicit,
-    "This is the same measurement as the root of the 'explicit' tree.  "
-    "However, it is measured at a different time and so gives slightly "
-    "different results.")
-
-NS_MEMORY_REPORTER_IMPLEMENT(Resident,
-    "resident",
-    KIND_OTHER,
-    UNITS_BYTES,
-    GetResident,
-    "Memory mapped by the process that is present in physical memory, "
-    "also known as the resident set size (RSS).  This is the best single "
-    "figure to use when considering the memory resources used by the process, "
-    "but it depends both on other processes being run and details of the OS "
-    "kernel and so is best used for comparing the memory usage of a single "
-    "process at different points in time.")
-
 /**
  ** memory reporter implementation for jemalloc and OSX malloc,
  ** to obtain info on total memory in use (that we know about,
  ** at least -- on OSX, there are sometimes other zones in use).
  **/
 
 #if HAVE_JEMALLOC_STATS
 
@@ -514,16 +490,38 @@ NS_MEMORY_REPORTER_IMPLEMENT(HeapAllocat
     KIND_OTHER,
     UNITS_BYTES,
     GetHeapAllocated,
     "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.)")
 
+static PRInt64 GetExplicit()
+{
+    nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
+    if (mgr == nsnull)
+        return (PRInt64)-1;
+
+    PRInt64 n;
+    nsresult rv = mgr->GetExplicit(&n);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    return n;
+}
+
+NS_MEMORY_REPORTER_IMPLEMENT(Explicit,
+    "explicit",
+    KIND_OTHER,
+    UNITS_BYTES,
+    GetExplicit,
+    "This is the same measurement as the root of the 'explicit' tree.  "
+    "However, it is measured at a different time and so gives slightly "
+    "different results.")
+
 NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(AtomTableMallocSizeOf, "atom-table")
 
 static PRInt64 GetAtomTableSize() {
   return NS_SizeOfAtomTableIncludingThis(AtomTableMallocSizeOf);
 }
 
 // Why is this here?  At first glance, you'd think it could be defined and
 // registered with nsMemoryReporterManager entirely within nsAtomTable.cpp.