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 96529 1a38b48816c97943118f90500f9215da60468731
parent 96528 ecfe99b2c9cc0d813a3303649f7bd821596201dd
child 96530 62fc36c0317d7ffd904f166e02198cacdcbe3450
push id1116
push userlsblakk@mozilla.com
push dateMon, 16 Jul 2012 19:38:18 +0000
treeherdermozilla-beta@95f959a8b4dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlebar
bugs744311
milestone15.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 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.