Bug 987995, part 2 - Add a data parameter to two memory-pressure-related callbacks. r=luke.
authorJason Orendorff <jorendorff@mozilla.com>
Thu, 22 May 2014 08:18:01 -0500
changeset 184534 71e447c210781b4428fc9aefe9b7514f8b28e30e
parent 184533 d0d639c162a603f04e0248db1cd2b6d6d73c20c2
child 184535 fe10de17b0d069fd942be962967084074d9dfa8c
push id6936
push userkwierso@gmail.com
push dateFri, 23 May 2014 00:58:57 +0000
treeherderfx-team@975c221719aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs987995
milestone32.0a1
Bug 987995, part 2 - Add a data parameter to two memory-pressure-related callbacks. r=luke.
dom/base/nsJSEnvironment.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jscntxt.cpp
js/src/shell/js.cpp
js/src/vm/Runtime.cpp
js/src/vm/Runtime.h
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/xpcprivate.h
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2908,17 +2908,17 @@ AsmJSCacheOpenEntryForWrite(JS::Handle<J
 {
   nsIPrincipal* principal =
     nsJSPrincipals::get(JS_GetCompartmentPrincipals(js::GetObjectCompartment(aGlobal)));
   return asmjscache::OpenEntryForWrite(principal, aInstalled, aBegin, aEnd,
                                        aSize, aMemory, aHandle);
 }
 
 static void
-OnLargeAllocationFailure()
+OnLargeAllocationFailure(void* data)
 {
   nsCOMPtr<nsIObserverService> os =
     mozilla::services::GetObserverService();
   if (os) {
     os->NotifyObservers(nullptr, "memory-pressure", MOZ_UTF16("heap-minimize"));
   }
 }
 
@@ -2976,17 +2976,17 @@ nsJSContext::EnsureStatics()
     AsmJSCacheOpenEntryForRead,
     asmjscache::CloseEntryForRead,
     AsmJSCacheOpenEntryForWrite,
     asmjscache::CloseEntryForWrite,
     asmjscache::GetBuildId
   };
   JS::SetAsmJSCacheOps(sRuntime, &asmJSCacheOps);
 
-  JS::SetLargeAllocationFailureCallback(sRuntime, OnLargeAllocationFailure);
+  JS::SetLargeAllocationFailureCallback(sRuntime, OnLargeAllocationFailure, nullptr);
 
   // Set these global xpconnect options...
   Preferences::RegisterCallbackAndCall(ReportAllJSExceptionsPrefChangedCallback,
                                        "dom.report_all_js_exceptions");
 
   Preferences::RegisterCallbackAndCall(SetMemoryHighWaterMarkPrefChangedCallback,
                                        "javascript.options.mem.high_water_mark");
 
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -6571,19 +6571,22 @@ JSAutoByteString::encodeLatin1(Exclusive
     if (!linear)
         return nullptr;
 
     mBytes = LossyTwoByteCharsToNewLatin1CharsZ(cx, linear->range()).c_str();
     return mBytes;
 }
 
 JS_PUBLIC_API(void)
-JS::SetLargeAllocationFailureCallback(JSRuntime *rt, JS::LargeAllocationFailureCallback lafc)
+JS::SetLargeAllocationFailureCallback(JSRuntime *rt, JS::LargeAllocationFailureCallback lafc,
+                                      void *data)
 {
     rt->largeAllocationFailureCallback = lafc;
+    rt->largeAllocationFailureCallbackData = data;
 }
 
 JS_PUBLIC_API(void)
-JS::SetOutOfMemoryCallback(JSRuntime *rt, OutOfMemoryCallback cb)
+JS::SetOutOfMemoryCallback(JSRuntime *rt, OutOfMemoryCallback cb, void *data)
 {
     rt->oomCallback = cb;
-}
-
+    rt->oomCallbackData = data;
+}
+
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -5054,33 +5054,33 @@ class MOZ_STACK_CLASS JS_PUBLIC_API(ForO
  * If a large allocation fails, the JS engine may call the large-allocation-
  * failure callback, if set, to allow the embedding to flush caches, possibly
  * perform shrinking GCs, etc. to make some room so that the allocation will
  * succeed if retried. After the callback returns, the JS engine will try to
  * allocate again and may be succesful.
  */
 
 typedef void
-(* LargeAllocationFailureCallback)();
+(* LargeAllocationFailureCallback)(void *data);
 
 extern JS_PUBLIC_API(void)
-SetLargeAllocationFailureCallback(JSRuntime *rt, LargeAllocationFailureCallback afc);
+SetLargeAllocationFailureCallback(JSRuntime *rt, LargeAllocationFailureCallback afc, void *data);
 
 /*
  * Unlike the error reporter, which is only called if the exception for an OOM
  * bubbles up and is not caught, the OutOfMemoryCallback is called immediately
  * at the OOM site to allow the embedding to capture the current state of heap
  * allocation before anything is freed. If the large-allocation-failure callback
  * is called at all (not all allocation sites call the large-allocation-failure
  * callback on failure), it is called before the out-of-memory callback; the
  * out-of-memory callback is only called if the allocation still fails after the
  * large-allocation-failure callback has returned.
  */
 
 typedef void
-(* OutOfMemoryCallback)(JSContext *cx);
+(* OutOfMemoryCallback)(JSContext *cx, void *data);
 
 extern JS_PUBLIC_API(void)
-SetOutOfMemoryCallback(JSRuntime *rt, OutOfMemoryCallback cb);
+SetOutOfMemoryCallback(JSRuntime *rt, OutOfMemoryCallback cb, void *data);
 
 } /* namespace JS */
 
 #endif /* jsapi_h */
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -371,17 +371,17 @@ js_ReportOutOfMemory(ThreadSafeContext *
         return;
 
     JSContext *cx = cxArg->asJSContext();
     cx->runtime()->hadOutOfMemory = true;
 
     /* Report the oom. */
     if (JS::OutOfMemoryCallback oomCallback = cx->runtime()->oomCallback) {
         AutoSuppressGC suppressGC(cx);
-        oomCallback(cx);
+        oomCallback(cx, cx->runtime()->oomCallbackData);
     }
 
     if (JS_IsRunning(cx)) {
         cx->setPendingException(StringValue(cx->names().outOfMemory));
         return;
     }
 
     /* Get the message for this error, but we don't expand any arguments. */
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -5011,17 +5011,17 @@ my_ErrorReporter(JSContext *cx, const ch
             gExitCode = EXITCODE_OUT_OF_MEMORY;
         } else {
             gExitCode = EXITCODE_RUNTIME_ERROR;
         }
     }
 }
 
 static void
-my_OOMCallback(JSContext *cx)
+my_OOMCallback(JSContext *cx, void *data)
 {
     // If a script is running, the engine is about to throw the string "out of
     // memory", which may or may not be caught. Otherwise the engine will just
     // unwind and return null/false, with no exception set.
     if (!JS_IsRunning(cx))
         gGotError = true;
 }
 
@@ -6258,17 +6258,17 @@ main(int argc, char **argv, char **envp)
     if (!JS_Init())
         return 1;
 
     /* Use the same parameters as the browser in xpcjsruntime.cpp. */
     rt = JS_NewRuntime(32L * 1024L * 1024L, JS_USE_HELPER_THREADS);
     if (!rt)
         return 1;
 
-    JS::SetOutOfMemoryCallback(rt, my_OOMCallback);
+    JS::SetOutOfMemoryCallback(rt, my_OOMCallback, nullptr);
     if (!SetRuntimeOptions(rt, op))
         return 1;
 
     gInterruptFunc.construct(rt, NullValue());
 
     JS_SetGCParameter(rt, JSGC_MAX_BYTES, 0xffffffff);
 #ifdef JSGC_GENERATIONAL
     Maybe<JS::AutoDisableGenerationalGC> noggc;
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -767,17 +767,17 @@ JSRuntime::onOutOfMemory(void *p, size_t
     return nullptr;
 }
 
 void *
 JSRuntime::onOutOfMemoryCanGC(void *p, size_t bytes)
 {
     if (!largeAllocationFailureCallback || bytes < LARGE_ALLOCATION)
         return nullptr;
-    largeAllocationFailureCallback();
+    largeAllocationFailureCallback(largeAllocationFailureCallbackData);
     return onOutOfMemory(p, bytes);
 }
 
 bool
 JSRuntime::activeGCInAtomsZone()
 {
     Zone *zone = atomsCompartment_->zone();
     return zone->needsBarrier() || zone->isGCScheduled() || zone->wasGCStarted();
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -1390,18 +1390,21 @@ struct JSRuntime : public JS::shadow::Ru
 
 #ifdef DEBUG
   public:
     js::AutoEnterPolicy *enteredPolicy;
 #endif
 
     /* See comment for JS::SetLargeAllocationFailureCallback in jsapi.h. */
     JS::LargeAllocationFailureCallback largeAllocationFailureCallback;
+    void *largeAllocationFailureCallbackData;
+
     /* See comment for JS::SetOutOfMemoryCallback in jsapi.h. */
     JS::OutOfMemoryCallback oomCallback;
+    void *oomCallbackData;
 
     /*
      * These variations of malloc/calloc/realloc will call the
      * large-allocation-failure callback on OOM and retry the allocation.
      */
 
     static const unsigned LARGE_ALLOCATION = 25 * 1024 * 1024;
 
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -1432,17 +1432,17 @@ XPCJSRuntime::InterruptCallback(JSContex
     self->mSlowScriptCheckpoint = TimeStamp::NowLoRes();
     if (response == nsGlobalWindow::AlwaysContinueSlowScript)
         Preferences::SetInt(prefName, 0);
 
     return true;
 }
 
 /* static */ void
-XPCJSRuntime::OutOfMemoryCallback(JSContext *cx)
+XPCJSRuntime::OutOfMemoryCallback(JSContext *cx, void *data)
 {
     if (!Preferences::GetBool("memory.dump_reports_on_oom")) {
         return;
     }
 
     nsCOMPtr<nsIMemoryInfoDumper> dumper =
         do_GetService("@mozilla.org/memory-info-dumper;1");
     if (!dumper) {
@@ -3173,17 +3173,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_SetInterruptCallback(runtime, InterruptCallback);
-    JS::SetOutOfMemoryCallback(runtime, OutOfMemoryCallback);
+    JS::SetOutOfMemoryCallback(runtime, OutOfMemoryCallback, nullptr);
 
     // 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
@@ -542,17 +542,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 InterruptCallback(JSContext *cx);
-    static void OutOfMemoryCallback(JSContext *cx);
+    static void OutOfMemoryCallback(JSContext *cx, void *data);
 
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
 
     AutoMarkingPtr**  GetAutoRootsAdr() {return &mAutoRoots;}
 
     JSObject* GetJunkScope();
     JSObject* GetCompilationScope();
     void DeleteSingletonScopes();