Bug 1145007 (part 2) - Add a "resident-peak" distinguished amount and memory reporter on Unix. r=erahm.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 19 Mar 2015 15:16:37 -0700
changeset 263552 3ecc822728616ce21eb31e462198fbf5ac8a6a2a
parent 263551 228183a2206317ad38fec6f96cab301c3643b007
child 263553 2eca228bc999547266b09374e616934a73d6ec1a
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerserahm
bugs1145007
milestone39.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 1145007 (part 2) - Add a "resident-peak" distinguished amount and memory reporter on Unix. r=erahm.
toolkit/components/aboutmemory/tests/test_memoryReporters.xul
xpcom/base/nsIMemoryReporter.idl
xpcom/base/nsMemoryReporterManager.cpp
xpcom/base/nsMemoryReporterManager.h
--- a/toolkit/components/aboutmemory/tests/test_memoryReporters.xul
+++ b/toolkit/components/aboutmemory/tests/test_memoryReporters.xul
@@ -152,16 +152,17 @@
     is(ex.result, Cr.NS_ERROR_NOT_AVAILABLE, "mgr.explicit exception");
     haveExplicit = false;
   }
   let amounts = [
     "vsize",
     "vsizeMaxContiguous",
     "resident",
     "residentFast",
+    "residentPeak",
     "residentUnique",
     "heapAllocated",
     "heapOverheadRatio",
     "JSMainRuntimeGCHeap",
     "JSMainRuntimeTemporaryPeak",
     "JSMainRuntimeCompartmentsSystem",
     "JSMainRuntimeCompartmentsUser",
     "imagesContentUsedUncompressed",
--- a/xpcom/base/nsIMemoryReporter.idl
+++ b/xpcom/base/nsIMemoryReporter.idl
@@ -200,17 +200,17 @@ interface nsIMemoryReporter : nsISupport
 };
 
 [scriptable, function, uuid(548b3909-c04d-4ca6-8466-b8bee3837457)]
 interface nsIFinishReportingCallback : nsISupports
 {
   void callback(in nsISupports data);
 };
 
-[scriptable, builtinclass, uuid(51e17609-e98a-47cc-9f95-095ef3c3823e)]
+[scriptable, builtinclass, uuid(5e4eaa5a-4808-4b97-8005-e7cdc4d73693)]
 interface nsIMemoryReporterManager : nsISupports
 {
   /*
    * Initialize.
    */
   void init();
 
   /*
@@ -339,16 +339,18 @@ interface nsIMemoryReporterManager : nsI
    * |resident| (UNITS_BYTES)  The resident size (a.k.a. RSS or physical memory
    * used).
    *
    * |residentFast| (UNITS_BYTES)  This is like |resident|, but on Mac OS
    * |resident| can purge pages, which is slow.  It also affects the result of
    * |residentFast|, and so |resident| and |residentFast| should not be used
    * together.
    *
+   * |residentPeak| (UNITS_BYTES)  The peak resident size.
+   *
    * |residentUnique| (UNITS_BYTES)  The unique set size (a.k.a. USS).
    *
    * |heapAllocated| (UNITS_BYTES)  Memory mapped by the heap allocator.
    *
    * |heapOverheadRatio| (UNITS_PERCENTAGE)  In the heap allocator, this is the
    * ratio of committed, unused bytes to allocated bytes.  Like all
    * UNITS_PERCENTAGE measurements, its amount is multiplied by 100x so it can
    * be represented by an int64_t.
@@ -376,16 +378,17 @@ interface nsIMemoryReporterManager : nsI
    * |pageFaultsHard| (UNITS_COUNT_CUMULATIVE)  The number of hard (a.k.a.
    * major) page faults that have occurred since the process started.
    */
   readonly attribute int64_t explicit;
   readonly attribute int64_t vsize;
   readonly attribute int64_t vsizeMaxContiguous;
   readonly attribute int64_t resident;
   readonly attribute int64_t residentFast;
+  readonly attribute int64_t residentPeak;
   readonly attribute int64_t residentUnique;
 
   readonly attribute int64_t heapAllocated;
   readonly attribute int64_t heapOverheadRatio;
 
   readonly attribute int64_t JSMainRuntimeGCHeap;
   readonly attribute int64_t JSMainRuntimeTemporaryPeak;
   readonly attribute int64_t JSMainRuntimeCompartmentsSystem;
--- a/xpcom/base/nsMemoryReporterManager.cpp
+++ b/xpcom/base/nsMemoryReporterManager.cpp
@@ -136,17 +136,17 @@ ResidentDistinguishedAmount(int64_t* aN)
 }
 
 static nsresult
 ResidentFastDistinguishedAmount(int64_t* aN)
 {
   return ResidentDistinguishedAmount(aN);
 }
 
-#define HAVE_RESIDENT_UNIQUE_REPORTER
+#define HAVE_RESIDENT_UNIQUE_REPORTER 1
 static nsresult
 ResidentUniqueDistinguishedAmount(int64_t* aN)
 {
   return GetProcSelfSmapsPrivate(aN);
 }
 
 class ResidentUniqueReporter MOZ_FINAL : public nsIMemoryReporter
 {
@@ -286,17 +286,17 @@ GetKinfoVmentrySelf(int64_t* aPrss, uint
       *aMaxreg = std::max(*aMaxreg, kve->kve_end - kve->kve_start);
     }
   }
 
   free(vmmap);
   return NS_OK;
 }
 
-#define HAVE_PRIVATE_REPORTER
+#define HAVE_PRIVATE_REPORTER 1
 static nsresult
 PrivateDistinguishedAmount(int64_t* aN)
 {
   int64_t priv;
   nsresult rv = GetKinfoVmentrySelf(&priv, nullptr);
   NS_ENSURE_SUCCESS(rv, rv);
   *aN = priv * getpagesize();
   return NS_OK;
@@ -524,17 +524,17 @@ VsizeMaxContiguousDistinguishedAmount(in
       break;
     }
   }
 
   *aN = biggestRegion;
   return NS_OK;
 }
 
-#define HAVE_PRIVATE_REPORTER
+#define HAVE_PRIVATE_REPORTER 1
 static nsresult
 PrivateDistinguishedAmount(int64_t* aN)
 {
   PROCESS_MEMORY_COUNTERS_EX pmcex;
   pmcex.cb = sizeof(PROCESS_MEMORY_COUNTERS_EX);
 
   if (!GetProcessMemoryInfo(GetCurrentProcess(),
                             (PPROCESS_MEMORY_COUNTERS) &pmcex, sizeof(pmcex))) {
@@ -799,16 +799,63 @@ public:
 NS_IMPL_ISUPPORTS(ResidentReporter, nsIMemoryReporter)
 
 #endif  // HAVE_VSIZE_AND_RESIDENT_REPORTERS
 
 #ifdef XP_UNIX
 
 #include <sys/resource.h>
 
+#define HAVE_RESIDENT_PEAK_REPORTER 1
+
+static nsresult
+ResidentPeakDistinguishedAmount(int64_t* aN)
+{
+  struct rusage usage;
+  if (0 == getrusage(RUSAGE_SELF, &usage)) {
+    // The units for ru_maxrrs:
+    // - Mac: bytes
+    // - Solaris: pages? But some sources it actually always returns 0, so
+    //   check for that
+    // - Linux, {Net/Open/Free}BSD, DragonFly: KiB
+#ifdef XP_MACOSX
+    *aN = usage.ru_maxrss;
+#elif defined(SOLARIS)
+    *aN = usage.ru_maxrss * getpagesize();
+#else
+    *aN = usage.ru_maxrss * 1024;
+#endif
+    if (*aN > 0) {
+      return NS_OK;
+    }
+  }
+  return NS_ERROR_FAILURE;
+}
+
+class ResidentPeakReporter MOZ_FINAL : public nsIMemoryReporter
+{
+  ~ResidentPeakReporter() {}
+
+public:
+  NS_DECL_ISUPPORTS
+
+  NS_METHOD CollectReports(nsIHandleReportCallback* aHandleReport,
+                           nsISupports* aData, bool aAnonymize) MOZ_OVERRIDE
+  {
+    int64_t amount = 0;
+    nsresult rv = ResidentPeakDistinguishedAmount(&amount);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    return MOZ_COLLECT_REPORT(
+      "resident-peak", KIND_OTHER, UNITS_BYTES, amount,
+"The peak 'resident' value for the lifetime of the process.");
+  }
+};
+NS_IMPL_ISUPPORTS(ResidentPeakReporter, nsIMemoryReporter)
+
 #define HAVE_PAGE_FAULT_REPORTERS 1
 
 class PageFaultsSoftReporter MOZ_FINAL : public nsIMemoryReporter
 {
   ~PageFaultsSoftReporter() {}
 
 public:
   NS_DECL_ISUPPORTS
@@ -875,17 +922,17 @@ public:
 "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.");
   }
 };
 NS_IMPL_ISUPPORTS(PageFaultsHardReporter, nsIMemoryReporter)
 
-#endif  // HAVE_PAGE_FAULT_REPORTERS
+#endif  // XP_UNIX
 
 /**
  ** 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).
  **/
 
 #ifdef HAVE_JEMALLOC_STATS
@@ -1149,16 +1196,20 @@ nsMemoryReporterManager::Init()
   RegisterStrongReporter(new VsizeReporter());
   RegisterStrongReporter(new ResidentReporter());
 #endif
 
 #ifdef HAVE_VSIZE_MAX_CONTIGUOUS_REPORTER
   RegisterStrongReporter(new VsizeMaxContiguousReporter());
 #endif
 
+#ifdef HAVE_RESIDENT_PEAK_REPORTER
+  RegisterStrongReporter(new ResidentPeakReporter());
+#endif
+
 #ifdef HAVE_RESIDENT_UNIQUE_REPORTER
   RegisterStrongReporter(new ResidentUniqueReporter());
 #endif
 
 #ifdef HAVE_PAGE_FAULT_REPORTERS
   RegisterStrongReporter(new PageFaultsSoftReporter());
   RegisterStrongReporter(new PageFaultsHardReporter());
 #endif
@@ -1855,16 +1906,40 @@ nsMemoryReporterManager::ResidentFast()
   NS_ENSURE_SUCCESS(rv, 0);
   return amount;
 #else
   return 0;
 #endif
 }
 
 NS_IMETHODIMP
+nsMemoryReporterManager::GetResidentPeak(int64_t* aAmount)
+{
+#ifdef HAVE_RESIDENT_PEAK_REPORTER
+  return ResidentPeakDistinguishedAmount(aAmount);
+#else
+  *aAmount = 0;
+  return NS_ERROR_NOT_AVAILABLE;
+#endif
+}
+
+/*static*/ int64_t
+nsMemoryReporterManager::ResidentPeak()
+{
+#ifdef HAVE_RESIDENT_PEAK_REPORTER
+  int64_t amount = 0;
+  nsresult rv = ResidentPeakDistinguishedAmount(&amount);
+  NS_ENSURE_SUCCESS(rv, 0);
+  return amount;
+#else
+  return 0;
+#endif
+}
+
+NS_IMETHODIMP
 nsMemoryReporterManager::GetResidentUnique(int64_t* aAmount)
 {
 #ifdef HAVE_RESIDENT_UNIQUE_REPORTER
   return ResidentUniqueDistinguishedAmount(aAmount);
 #else
   *aAmount = 0;
   return NS_ERROR_NOT_AVAILABLE;
 #endif
--- a/xpcom/base/nsMemoryReporterManager.h
+++ b/xpcom/base/nsMemoryReporterManager.h
@@ -146,16 +146,19 @@ public:
     }
   };
   AmountFns mAmountFns;
 
   // Convenience function to get RSS easily from other code.  This is useful
   // when debugging transient memory spikes with printf instrumentation.
   static int64_t ResidentFast();
 
+  // Convenience function to get peak RSS easily from other code.
+  static int64_t ResidentPeak();
+
   // Convenience function to get USS easily from other code.  This is useful
   // when debugging unshared memory pages for forked processes.
   static int64_t ResidentUnique();
 
   // Functions that measure per-tab memory consumption.
   struct SizeOfTabFns
   {
     mozilla::JSSizeOfTabFn    mJS;