Bug 1251275. Switch to using an AutoEntryScript in WorkerPrivate::RunExpiredTimeouts. r=khuey
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 26 Feb 2016 15:23:13 -0500
changeset 322208 c10b6b14fce10e51f825d89eaa3cb9cbd6a682f4
parent 322207 0685962294de623d50bcbef680ab730814308f2e
child 322209 d6c6898a18f62838992ddb8d6e8e633ed6240941
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey
bugs1251275
milestone47.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 1251275. Switch to using an AutoEntryScript in WorkerPrivate::RunExpiredTimeouts. r=khuey
dom/workers/WorkerPrivate.cpp
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -5961,46 +5961,58 @@ WorkerPrivate::RunExpiredTimeouts(JSCont
 
     if (info->mCanceled) {
       continue;
     }
 
     LOG(TimeoutsLog(), ("Worker %p executing timeout with original delay %f ms.\n",
                         this, info->mInterval.ToMilliseconds()));
 
-    // Always call JS_ReportPendingException if something fails, and if
-    // JS_ReportPendingException returns false (i.e. uncatchable exception) then
+    // Always check JS_IsExceptionPending if something fails, and if
+    // JS_IsExceptionPending returns false (i.e. uncatchable exception) then
     // break out of the loop.
-
-    if (!info->mTimeoutCallable.isUndefined()) {
-      JS::Rooted<JS::Value> rval(aCx);
-      JS::HandleValueArray args =
-        JS::HandleValueArray::fromMarkedLocation(info->mExtraArgVals.Length(),
-                                                 info->mExtraArgVals.Elements()->address());
-      JS::Rooted<JS::Value> callable(aCx, info->mTimeoutCallable);
-      if (!JS_CallFunctionValue(aCx, global, callable, args, &rval) &&
-          !JS_ReportPendingException(aCx)) {
-        retval = false;
-        break;
+    const char *reason;
+    if (info->mIsInterval) {
+      reason = "setInterval handler";
+    } else {
+      reason = "setTimeout handler";
+    }
+
+    { // scope for the AutoEntryScript, so it comes off the stack before we do
+      // Promise::PerformMicroTaskCheckpoint.
+      AutoEntryScript entryScript(xpc::NativeGlobal(global), reason,
+                                  false, aCx);
+      entryScript.TakeOwnershipOfErrorReporting();
+      if (!info->mTimeoutCallable.isUndefined()) {
+        JS::Rooted<JS::Value> rval(aCx);
+        JS::HandleValueArray args =
+          JS::HandleValueArray::fromMarkedLocation(info->mExtraArgVals.Length(),
+                                                   info->mExtraArgVals.Elements()->address());
+        JS::Rooted<JS::Value> callable(aCx, info->mTimeoutCallable);
+        if (!JS_CallFunctionValue(aCx, global, callable, args, &rval) &&
+            !JS_IsExceptionPending(aCx)) {
+          retval = false;
+          break;
+        }
       }
-    }
-    else {
-      nsString expression = info->mTimeoutString;
-
-      JS::CompileOptions options(aCx);
-      options.setFileAndLine(info->mFilename.get(), info->mLineNumber)
-             .setNoScriptRval(true);
-
-      JS::Rooted<JS::Value> unused(aCx);
-      if ((expression.IsEmpty() ||
-           !JS::Evaluate(aCx, options,
-                         expression.get(), expression.Length(), &unused)) &&
-          !JS_ReportPendingException(aCx)) {
-        retval = false;
-        break;
+      else {
+        nsString expression = info->mTimeoutString;
+
+        JS::CompileOptions options(aCx);
+        options.setFileAndLine(info->mFilename.get(), info->mLineNumber)
+               .setNoScriptRval(true);
+
+        JS::Rooted<JS::Value> unused(aCx);
+        if (!expression.IsEmpty() &&
+            !JS::Evaluate(aCx, options,
+                          expression.get(), expression.Length(), &unused) &&
+            !JS_IsExceptionPending(aCx)) {
+          retval = false;
+          break;
+        }
       }
     }
 
     // Since we might be processing more timeouts, go ahead and flush
     // the promise queue now before we do that.
     Promise::PerformMicroTaskCheckpoint();
 
     NS_ASSERTION(mRunningExpiredTimeouts, "Someone changed this!");