Bug 969415 (part 2) - Add a pref to enable memory report dumping on JS OOMs. r=luke.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 20 Feb 2014 18:35:43 -0800
changeset 170159 b677573f964bf69fdcc847dbf359cef96678596a
parent 170158 4a83d046db8260973511456ab191d2566ee272c7
child 170168 71e4a149726515b4bd238c65aeaa59e268412313
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersluke
bugs969415
milestone30.0a1
Bug 969415 (part 2) - Add a pref to enable memory report dumping on JS OOMs. r=luke.
b2g/app/b2g.js
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/xpcprivate.h
modules/libpref/src/init/all.js
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -751,16 +751,19 @@ pref("font.size.inflation.disabledInMast
 
 // Enable freeing dirty pages when minimizing memory; this reduces memory
 // consumption when applications are sent to the background.
 pref("memory.free_dirty_pages", true);
 
 // Enable the Linux-specific, system-wide memory reporter.
 pref("memory.system_memory_reporter", true);
 
+// Don't dump memory reports on OOM, by default.
+pref("memory.dump_reports_on_oom", false);
+
 pref("layout.imagevisibility.enabled", true);
 pref("layout.imagevisibility.numscrollportwidths", 1);
 pref("layout.imagevisibility.numscrollportheights", 1);
 
 // Enable native identity (persona/browserid)
 pref("dom.identity.enabled", true);
 
 // Wait up to this much milliseconds when orientation changed
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -11,16 +11,17 @@
 #include "xpcprivate.h"
 #include "xpcpublic.h"
 #include "XPCWrapper.h"
 #include "XPCJSMemoryReporter.h"
 #include "WrapperFactory.h"
 #include "dom_quickstubs.h"
 #include "mozJSComponentLoader.h"
 
+#include "nsIMemoryInfoDumper.h"
 #include "nsIMemoryReporter.h"
 #include "nsIObserverService.h"
 #include "nsIDebug2.h"
 #include "amIAddonManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsPrintfCString.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
@@ -1391,16 +1392,35 @@ XPCJSRuntime::OperationCallback(JSContex
     // machinery with a pref of the user opted out of future slow-script dialogs.
     self->mSlowScriptCheckpoint = TimeStamp::NowLoRes();
     if (response == nsGlobalWindow::AlwaysContinueSlowScript)
         Preferences::SetInt(prefName, 0);
 
     return true;
 }
 
+/* static */ void
+XPCJSRuntime::OutOfMemoryCallback(JSContext *cx)
+{
+    if (!Preferences::GetBool("memory.dump_reports_on_oom")) {
+        return;
+    }
+
+    nsCOMPtr<nsIMemoryInfoDumper> dumper =
+        do_GetService("@mozilla.org/memory-info-dumper;1");
+    if (!dumper) {
+        return;
+    }
+
+    // If this fails, it fails silently.
+    dumper->DumpMemoryInfoToTempDir(NS_LITERAL_STRING("due-to-JS-OOM"),
+                                    /* minimizeMemoryUsage = */ false,
+                                    /* dumpChildProcesses = */ false);
+}
+
 size_t
 XPCJSRuntime::SizeOfIncludingThis(MallocSizeOf mallocSizeOf)
 {
     size_t n = 0;
     n += mallocSizeOf(this);
     n += mWrappedJSMap->SizeOfIncludingThis(mallocSizeOf);
     n += mIID2NativeInterfaceMap->SizeOfIncludingThis(mallocSizeOf);
     n += mClassInfo2NativeSetMap->ShallowSizeOfIncludingThis(mallocSizeOf);
@@ -3096,16 +3116,17 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* 
     if (PseudoStack *stack = mozilla_get_pseudo_stack())
         stack->sampleRuntime(runtime);
 #endif
     JS_SetAccumulateTelemetryCallback(runtime, AccumulateTelemetryCallback);
     js::SetDefaultJSContextCallback(runtime, DefaultJSContextCallback);
     js::SetActivityCallback(runtime, ActivityCallback, this);
     js::SetCTypesActivityCallback(runtime, CTypesActivityCallback);
     JS_SetOperationCallback(runtime, OperationCallback);
+    JS::SetOutOfMemoryCallback(runtime, OutOfMemoryCallback);
 
     // The JS engine needs to keep the source code around in order to implement
     // Function.prototype.toSource(). It'd be nice to not have to do this for
     // chrome code and simply stub out requests for source on it. Life is not so
     // easy, unfortunately. Nobody relies on chrome toSource() working in core
     // browser code, but chrome tests use it. The worst offenders are addons,
     // which like to monkeypatch chrome functions by calling toSource() on them
     // and using regular expressions to modify them. We avoid keeping most browser
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -544,16 +544,17 @@ public:
     void AddContextCallback(xpcContextCallback cb);
     void RemoveContextCallback(xpcContextCallback cb);
 
     static JSContext* DefaultJSContextCallback(JSRuntime *rt);
     static void ActivityCallback(void *arg, bool active);
     static void CTypesActivityCallback(JSContext *cx,
                                        js::CTypesActivityType type);
     static bool OperationCallback(JSContext *cx);
+    static void OutOfMemoryCallback(JSContext *cx);
 
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
 
     AutoMarkingPtr**  GetAutoRootsAdr() {return &mAutoRoots;}
 
     JSObject* GetJunkScope();
     void DeleteJunkScope();
 
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -4126,16 +4126,19 @@ pref("memory.ghost_window_timeout_second
 // Disable freeing dirty pages when minimizing memory.
 pref("memory.free_dirty_pages", false);
 
 // Disable the Linux-specific, system-wide memory reporter.
 #ifdef XP_LINUX
 pref("memory.system_memory_reporter", false);
 #endif
 
+// Don't dump memory reports on OOM, by default.
+pref("memory.dump_reports_on_oom", false);
+
 // Number of stack frames to capture in createObjectURL for about:memory.
 pref("memory.blob_report.stack_frames", 0);
 
 pref("social.enabled", false);
 // comma separated list of domain origins (e.g. https://domain.com) for
 // providers that can install from their own website without user warnings.
 // entries are
 pref("social.whitelist", "https://mozsocial.cliqz.com,https://now.msn.com,https://mixi.jp");