Merge inbound to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 15 Nov 2013 21:43:40 -0500
changeset 154915 a475f94bb1b15af9640209c9be8ce5cb91611ac3
parent 154909 bbc57b91c665974036e65589da3b99ada90616b8 (current diff)
parent 154914 a7a6ff24a7b8cbb21e6207220d5f0bf0ddc6c46d (diff)
child 154916 444714c3820a242979b18f8d740d28180dc737f4
child 154978 1e70228c1fba388a05885defb7019bc55b18a627
child 154986 6709808f07d8e9b8f2c11306228d358c9b66edc2
push id25656
push userryanvm@gmail.com
push dateSat, 16 Nov 2013 02:44:05 +0000
treeherdermozilla-central@a475f94bb1b1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone28.0a1
first release with
nightly linux32
a475f94bb1b1 / 28.0a1 / 20131116030211 / files
nightly linux64
a475f94bb1b1 / 28.0a1 / 20131116030211 / files
nightly mac
a475f94bb1b1 / 28.0a1 / 20131116030211 / files
nightly win32
a475f94bb1b1 / 28.0a1 / 20131116030211 / files
nightly win64
a475f94bb1b1 / 28.0a1 / 20131116030211 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c.
--- a/browser/devtools/framework/test/browser.ini
+++ b/browser/devtools/framework/test/browser.ini
@@ -9,16 +9,17 @@ support-files = head.js
 [browser_toolbox_dynamic_registration.js]
 [browser_toolbox_highlight.js]
 [browser_toolbox_hosts.js]
 [browser_toolbox_options.js]
 [browser_toolbox_options_disablejs.html]
 [browser_toolbox_options_disablejs.js]
 [browser_toolbox_options_disablejs_iframe.html]
 [browser_toolbox_raise.js]
+skip-if = os == "win"
 [browser_toolbox_ready.js]
 [browser_toolbox_select_event.js]
 [browser_toolbox_sidebar.js]
 [browser_toolbox_tabsswitch_shortcuts.js]
 [browser_toolbox_tool_ready.js]
 [browser_toolbox_window_shortcuts.js]
 [browser_toolbox_window_title_changes.js]
 [browser_toolbox_zoom.js]
--- a/testing/mochitest/tests/SimpleTest/TestRunner.js
+++ b/testing/mochitest/tests/SimpleTest/TestRunner.js
@@ -388,32 +388,76 @@ TestRunner.runNextTest = function() {
     }
 };
 
 TestRunner.expectChildProcessCrash = function() {
     TestRunner._expectingProcessCrash = true;
 };
 
 /**
+ * Statistics that we want to retrieve and display after every test is
+ * done.  The keys of this table are intended to be identical to the
+ * relevant attributes of nsIMemoryReporterManager.  However, since
+ * nsIMemoryReporterManager doesn't necessarily support all these
+ * statistics in all build configurations, we also use this table to
+ * tell us whether statistics are supported or not.
+ */
+var MEM_STAT_UNKNOWN = 0;
+var MEM_STAT_UNSUPPORTED = 1;
+var MEM_STAT_SUPPORTED = 2;
+TestRunner._hasMemoryStatistics = {}
+TestRunner._hasMemoryStatistics.vsize = MEM_STAT_UNKNOWN;
+TestRunner._hasMemoryStatistics.heapAllocated = MEM_STAT_UNKNOWN;
+TestRunner._hasMemoryStatistics.largestContiguousVMBlock = MEM_STAT_UNKNOWN;
+
+/**
  * This stub is called by SimpleTest when a test is finished.
 **/
 TestRunner.testFinished = function(tests) {
     // Prevent a test from calling finish() multiple times before we
     // have a chance to unload it.
     if (TestRunner._currentTest == TestRunner._lastTestFinished &&
         !TestRunner._loopIsRestarting) {
         TestRunner.error("TEST-UNEXPECTED-FAIL | " +
                          TestRunner.currentTestURL +
                          " | called finish() multiple times");
         TestRunner.updateUI([{ result: false }]);
         return;
     }
     TestRunner._lastTestFinished = TestRunner._currentTest;
     TestRunner._loopIsRestarting = false;
 
+    var mrm;
+    try {
+	mrm = Cc["@mozilla.org/memory-reporter-manager;1"]
+	    .getService(Ci.nsIMemoryReporterManager);
+    } catch (e) {
+	mrm = SpecialPowers.Cc["@mozilla.org/memory-reporter-manager;1"]
+	                   .getService(SpecialPowers.Ci.nsIMemoryReporterManager);
+    }
+    for (stat in TestRunner._hasMemoryStatistics) {
+        var supported = TestRunner._hasMemoryStatistics[stat];
+        var firstAccess = false;
+        if (supported == MEM_STAT_UNKNOWN) {
+            firstAccess = true;
+            try {
+                var value = mrm[stat];
+                supported = MEM_STAT_SUPPORTED;
+            } catch (e) {
+                supported = MEM_STAT_UNSUPPORTED;
+            }
+            TestRunner._hasMemoryStatistics[stat] = supported;
+        }
+        if (supported == MEM_STAT_SUPPORTED) {
+            TestRunner.log("TEST-INFO | MEMORY STAT " + stat + " after test: " + mrm[stat]);
+        } else if (firstAccess) {
+            TestRunner.log("TEST-INFO | MEMORY STAT " + stat + " not supported in this build configuration.");
+        }
+    }
+
     function cleanUpCrashDumpFiles() {
         if (!SpecialPowers.removeExpectedCrashDumpFiles(TestRunner._expectingProcessCrash)) {
             TestRunner.error("TEST-UNEXPECTED-FAIL | " +
                              TestRunner.currentTestURL +
                              " | This test did not leave any crash dumps behind, but we were expecting some!");
             tests.push({ result: false });
         }
         var unexpectedCrashDumpFiles =
--- a/testing/mochitest/tests/SimpleTest/iframe-between-tests.html
+++ b/testing/mochitest/tests/SimpleTest/iframe-between-tests.html
@@ -2,11 +2,21 @@
 <!--
   This page exists so that our accounting for assertions correctly
   counts assertions that happen while leaving a page.  We load this page
   after a test finishes, check the assertion counts, and then go on to
   load the next.
 -->
 <script>
 window.addEventListener("load", function() {
-  (parent.TestRunner || parent.wrappedJSObject.TestRunner).testUnloaded();
+  var runner = (parent.TestRunner || parent.wrappedJSObject.TestRunner);
+  runner.testUnloaded();
+
+  if (SpecialPowers) {
+    if (!runner.garbageCollectCount) {
+      runner.garbageCollectCount = 0;
+    }
+    if (runner.garbageCollectCount++ % 10 == 0) {
+      SpecialPowers.DOMWindowUtils.garbageCollect();
+    }
+  }
 });
 </script>
--- a/xpcom/base/nsIMemoryReporter.idl
+++ b/xpcom/base/nsIMemoryReporter.idl
@@ -180,17 +180,17 @@ interface nsIMemoryReporter : nsISupport
 };
 
 [scriptable, function, uuid(548b3909-c04d-4ca6-8466-b8bee3837457)]
 interface nsIFinishReportingCallback : nsISupports
 {
   void callback(in nsISupports data);
 };
 
-[scriptable, builtinclass, uuid(a1292276-726b-4ef5-a017-5a455d6664dd)]
+[scriptable, builtinclass, uuid(2596fa26-495a-4827-a5f5-e34e7f4dd7b5)]
 interface nsIMemoryReporterManager : nsISupports
 {
   /*
    * Initialize.
    */
   void init();
 
   /*
@@ -295,16 +295,20 @@ interface nsIMemoryReporterManager : nsI
    * |lowMemoryEvents{Virtual,Physical}| (UNITS_COUNT_CUMULATIVE)  The number
    * of low-{virtual,physical}-memory events that have occurred since the
    * process started.
    *
    * |ghostWindows| (UNITS_COUNT)  The number of ghost windows.
    *
    * |pageFaultsHard| (UNITS_COUNT_CUMULATIVE)  The number of hard (a.k.a.
    * major) page faults that have occurred since the process started.
+   *
+   * |largestContiguousVMBlock| (UNITS_BYTES)  The size of the largest
+   * contiguous block of virtual memory.  Only available on Windows; on all
+   * other platforms, reading this value returns 0.
    */
   readonly attribute int64_t explicit;
   readonly attribute int64_t vsize;
   readonly attribute int64_t resident;
   readonly attribute int64_t residentFast;
 
   readonly attribute int64_t heapAllocated;
   readonly attribute int64_t heapOverheadRatio;
@@ -320,16 +324,18 @@ interface nsIMemoryReporterManager : nsI
 
   readonly attribute int64_t lowMemoryEventsVirtual;
   readonly attribute int64_t lowMemoryEventsPhysical;
 
   readonly attribute int64_t ghostWindows;
 
   readonly attribute int64_t pageFaultsHard;
 
+  readonly attribute int64_t largestContiguousVMBlock;
+
   /*
    * This attribute indicates if moz_malloc_usable_size() works.
    */
   [infallible] readonly attribute boolean hasMozMallocUsableSize;
 
   /*
    * Run a series of GC/CC's in an attempt to minimize the application's memory
    * usage.  When we're finished, we invoke the given runnable if it's not
--- a/xpcom/base/nsMemoryReporterManager.cpp
+++ b/xpcom/base/nsMemoryReporterManager.cpp
@@ -332,16 +332,17 @@ static nsresult GetResident(int64_t* aN)
 {
     return GetResident(aN, /* doPurge = */ true);
 }
 
 #elif defined(XP_WIN)
 
 #include <windows.h>
 #include <psapi.h>
+#include <algorithm>
 
 #define HAVE_VSIZE_AND_RESIDENT_REPORTERS 1
 static nsresult GetVsize(int64_t* aN)
 {
     MEMORYSTATUSEX s;
     s.dwLength = sizeof(s);
 
     if (!GlobalMemoryStatusEx(&s)) {
@@ -365,16 +366,44 @@ static nsresult GetResident(int64_t* aN)
     return NS_OK;
 }
 
 static nsresult GetResidentFast(int64_t* aN)
 {
     return GetResident(aN);
 }
 
+#define HAVE_LARGEST_CONTIGUOUS_BLOCK_REPORTERS 1
+static nsresult LargestContiguousVMBlock(int64_t* aN)
+{
+    SIZE_T biggestRegion = 0;
+    MEMORY_BASIC_INFORMATION vmemInfo = {0};
+    for (size_t currentAddress = 0; ; ) {
+        if (!VirtualQuery((LPCVOID)currentAddress, &vmemInfo, sizeof(vmemInfo))) {
+            // Something went wrong, just return whatever we've got already.
+            break;
+        }
+
+        if (vmemInfo.State == MEM_FREE) {
+            biggestRegion = std::max(biggestRegion, vmemInfo.RegionSize);
+        }
+
+        SIZE_T lastAddress = currentAddress;
+        currentAddress += vmemInfo.RegionSize;
+
+        // If we overflow, we've examined all of the address space.
+        if (currentAddress < lastAddress) {
+            break;
+        }
+    }
+
+    *aN = biggestRegion;
+    return NS_OK;
+}
+
 #define HAVE_PRIVATE_REPORTER
 class PrivateReporter MOZ_FINAL : public MemoryUniReporter
 {
 public:
     PrivateReporter()
       : MemoryUniReporter("private", KIND_OTHER, UNITS_BYTES,
 "Memory that cannot be shared with other processes, including memory that is "
 "committed and marked MEM_PRIVATE, data that is not mapped, and executable "
@@ -1378,16 +1407,27 @@ nsMemoryReporterManager::GetPageFaultsHa
     return PageFaultsHardDistinguishedAmount(aAmount);
 #else
     *aAmount = 0;
     return NS_ERROR_NOT_AVAILABLE;
 #endif
 }
 
 NS_IMETHODIMP
+nsMemoryReporterManager::GetLargestContiguousVMBlock(int64_t* aAmount)
+{
+#ifdef HAVE_LARGEST_CONTIGUOUS_BLOCK_REPORTERS
+    return LargestContiguousVMBlock(aAmount);
+#else
+    *aAmount = 0;
+    return NS_ERROR_NOT_AVAILABLE;
+#endif
+}
+
+NS_IMETHODIMP
 nsMemoryReporterManager::GetHasMozMallocUsableSize(bool* aHas)
 {
     void* p = malloc(16);
     if (!p) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
     size_t usable = moz_malloc_usable_size(p);
     free(p);