Bug 1224685 - Add |resident-unique| measurement to Windows. r=njn a=ritu
authorEric Rahm <erahm@mozilla.com>
Fri, 13 Nov 2015 13:44:48 -0800
changeset 303948 4936d1c5c1dfe8e2d3d5d93cbe7383f199bda027
parent 303947 971d0fc7eef6033ec89efc62c71b256dbae87e24
child 303949 0fdfba81ce8c38c3b4d789995ede4b654c1d9f53
push id5392
push userraliiev@mozilla.com
push dateMon, 14 Dec 2015 20:08:23 +0000
treeherdermozilla-beta@16ce8562a975 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn, ritu
bugs1224685
milestone44.0a2
Bug 1224685 - Add |resident-unique| measurement to Windows. r=njn a=ritu
xpcom/base/nsMemoryReporterManager.cpp
--- a/xpcom/base/nsMemoryReporterManager.cpp
+++ b/xpcom/base/nsMemoryReporterManager.cpp
@@ -19,16 +19,17 @@
 #include "nsIGlobalObject.h"
 #include "nsIXPConnect.h"
 #if defined(XP_UNIX) || defined(MOZ_DMD)
 #include "nsMemoryInfoDumper.h"
 #endif
 #include "mozilla/Attributes.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/Scoped.h"
 #include "mozilla/Services.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/dom/PMemoryReportRequestParent.h" // for dom::MemoryReport
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/ipc/FileDescriptorUtils.h"
 
 #ifdef XP_WIN
 #include <process.h>
@@ -147,40 +148,16 @@ ResidentFastDistinguishedAmount(int64_t*
 
 #define HAVE_RESIDENT_UNIQUE_REPORTER 1
 static nsresult
 ResidentUniqueDistinguishedAmount(int64_t* aN)
 {
   return GetProcSelfSmapsPrivate(aN);
 }
 
-class ResidentUniqueReporter final : public nsIMemoryReporter
-{
-  ~ResidentUniqueReporter() {}
-
-public:
-  NS_DECL_ISUPPORTS
-
-  NS_METHOD CollectReports(nsIHandleReportCallback* aHandleReport,
-                           nsISupports* aData, bool aAnonymize) override
-  {
-    int64_t amount = 0;
-    nsresult rv = ResidentUniqueDistinguishedAmount(&amount);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    return MOZ_COLLECT_REPORT(
-      "resident-unique", KIND_OTHER, UNITS_BYTES, amount,
-"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.");
-  }
-};
-NS_IMPL_ISUPPORTS(ResidentUniqueReporter, nsIMemoryReporter)
-
 #define HAVE_SYSTEM_HEAP_REPORTER 1
 nsresult
 SystemHeapSize(int64_t* aSizeOut)
 {
     struct mallinfo info = mallinfo();
 
     // The documentation in the glibc man page makes it sound like |uordblks|
     // would suffice, but that only gets the small allocations that are put in
@@ -577,40 +554,16 @@ ResidentUniqueDistinguishedAmount(int64_
   if (host_page_size(mach_host_self(), &pageSize) != KERN_SUCCESS) {
     pageSize = PAGE_SIZE;
   }
 
   *aN = privatePages * pageSize;
   return NS_OK;
 }
 
-class ResidentUniqueReporter final : public nsIMemoryReporter
-{
-  ~ResidentUniqueReporter() {}
-
-public:
-  NS_DECL_ISUPPORTS
-
-  NS_METHOD CollectReports(nsIHandleReportCallback* aHandleReport,
-                           nsISupports* aData, bool aAnonymize) override
-  {
-    int64_t amount = 0;
-    nsresult rv = ResidentUniqueDistinguishedAmount(&amount);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    return MOZ_COLLECT_REPORT(
-      "resident-unique", KIND_OTHER, UNITS_BYTES, amount,
-"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.");
-  }
-};
-NS_IMPL_ISUPPORTS(ResidentUniqueReporter, nsIMemoryReporter)
-
 #elif defined(XP_WIN)
 
 #include <windows.h>
 #include <psapi.h>
 #include <algorithm>
 
 #define HAVE_VSIZE_AND_RESIDENT_REPORTERS 1
 static nsresult
@@ -642,16 +595,65 @@ ResidentDistinguishedAmount(int64_t* aN)
 }
 
 static nsresult
 ResidentFastDistinguishedAmount(int64_t* aN)
 {
   return ResidentDistinguishedAmount(aN);
 }
 
+#define HAVE_RESIDENT_UNIQUE_REPORTER 1
+
+static nsresult
+ResidentUniqueDistinguishedAmount(int64_t* aN)
+{
+  // Determine how many entries we need.
+  PSAPI_WORKING_SET_INFORMATION tmp;
+  DWORD tmpSize = sizeof(tmp);
+  memset(&tmp, 0, tmpSize);
+
+  HANDLE proc = GetCurrentProcess();
+  QueryWorkingSet(proc, &tmp, tmpSize);
+
+  // Fudge the size in case new entries are added between calls.
+  size_t entries = tmp.NumberOfEntries * 2;
+
+  if (!entries) {
+    return NS_ERROR_FAILURE;
+  }
+
+  DWORD infoArraySize = tmpSize + (entries * sizeof(PSAPI_WORKING_SET_BLOCK));
+  mozilla::ScopedFreePtr<PSAPI_WORKING_SET_INFORMATION> infoArray(
+      static_cast<PSAPI_WORKING_SET_INFORMATION*>(malloc(infoArraySize)));
+
+  if (!infoArray) {
+    return NS_ERROR_FAILURE;
+  }
+
+  if (!QueryWorkingSet(proc, infoArray, infoArraySize)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  entries = static_cast<size_t>(infoArray->NumberOfEntries);
+  size_t privatePages = 0;
+  for (size_t i = 0; i < entries; i++) {
+    // Count shared pages that only one process is using as private.
+    if (!infoArray->WorkingSetInfo[i].Shared ||
+        infoArray->WorkingSetInfo[i].ShareCount <= 1) {
+      privatePages++;
+    }
+  }
+
+  SYSTEM_INFO si;
+  GetSystemInfo(&si);
+
+  *aN = privatePages * si.dwPageSize;
+  return NS_OK;
+}
+
 #define HAVE_VSIZE_MAX_CONTIGUOUS_REPORTER 1
 static nsresult
 VsizeMaxContiguousDistinguishedAmount(int64_t* aN)
 {
   SIZE_T biggestRegion = 0;
   MEMORY_BASIC_INFORMATION vmemInfo = { 0 };
   for (size_t currentAddress = 0; ; ) {
     if (!VirtualQuery((LPCVOID)currentAddress, &vmemInfo, sizeof(vmemInfo))) {
@@ -993,16 +995,43 @@ public:
 "for comparing the memory usage of a single process at different points in "
 "time.");
     }
 };
 NS_IMPL_ISUPPORTS(ResidentReporter, nsIMemoryReporter)
 
 #endif  // HAVE_VSIZE_AND_RESIDENT_REPORTERS
 
+#ifdef HAVE_RESIDENT_UNIQUE_REPORTER
+class ResidentUniqueReporter final : public nsIMemoryReporter
+{
+  ~ResidentUniqueReporter() {}
+
+public:
+  NS_DECL_ISUPPORTS
+
+  NS_METHOD CollectReports(nsIHandleReportCallback* aHandleReport,
+                           nsISupports* aData, bool aAnonymize) override
+  {
+    int64_t amount = 0;
+    nsresult rv = ResidentUniqueDistinguishedAmount(&amount);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    return MOZ_COLLECT_REPORT(
+      "resident-unique", KIND_OTHER, UNITS_BYTES, amount,
+"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.");
+  }
+};
+NS_IMPL_ISUPPORTS(ResidentUniqueReporter, nsIMemoryReporter)
+
+#endif // HAVE_RESIDENT_UNIQUE_REPORTER
+
 #ifdef HAVE_SYSTEM_HEAP_REPORTER
 
 class SystemHeapReporter final : public nsIMemoryReporter
 {
   ~SystemHeapReporter() {}
 
 public:
   NS_DECL_ISUPPORTS