Bug 867295 - Do not use JSContext to root in parallel code; r=nmatsakis
authorTerrence Cole <terrence@mozilla.com>
Thu, 02 May 2013 11:56:30 -0700
changeset 141606 a303955db0b5aa7a3405f06fc8fba879e81ed0f5
parent 141605 478105be6e91d2608c1a784ec96e3407589e4205
child 141607 9a10069d27ba729f2332d3c9495e7d5b07d4ca9a
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnmatsakis
bugs867295
milestone23.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 867295 - Do not use JSContext to root in parallel code; r=nmatsakis
js/src/vm/ParallelDo.cpp
--- a/js/src/vm/ParallelDo.cpp
+++ b/js/src/vm/ParallelDo.cpp
@@ -399,18 +399,18 @@ class ParallelIonInvoke
         // Find JIT code pointer.
         IonScript *ion = callee->nonLazyScript()->parallelIonScript();
         IonCode *code = ion->method();
         jitcode_ = code->raw();
         enter_ = cx->compartment->ionCompartment()->enterJIT();
         calleeToken_ = CalleeToParallelToken(callee);
     }
 
-    bool invoke(JSContext *cx) {
-        RootedValue result(cx);
+    bool invoke() {
+        RootedValue result(TlsPerThreadData.get());
         enter_(jitcode_, argc_ + 1, argv_ + 1, NULL, calleeToken_, NULL, 0, result.address());
         return !result.isMagic();
     }
 };
 #endif // JS_ION
 
 class ParallelDo : public ForkJoinOp
 {
@@ -482,27 +482,27 @@ class ParallelDo : public ForkJoinOp
         return SpewEndOp(disqualifyFromParallelExecution());
     }
 
     MethodStatus compileForParallelExecution() {
         // The kernel should be a self-hosted function.
         if (!fun_->isFunction())
             return Method_Skipped;
 
-        RootedFunction callee(cx_, fun_->toFunction());
+        RootedFunction callee(TlsPerThreadData.get(), fun_->toFunction());
 
         if (!callee->isInterpreted() || !callee->isSelfHostedBuiltin())
             return Method_Skipped;
 
         if (callee->isInterpretedLazy() && !callee->initializeLazyScript(cx_))
             return Method_Error;
 
         // If this function has not been run enough to enable parallel
         // execution, perform a warmup.
-        RootedScript script(cx_, callee->nonLazyScript());
+        RootedScript script(TlsPerThreadData.get(), callee->nonLazyScript());
         if (script->getUseCount() < js_IonOptions.usesBeforeCompileParallel) {
             if (!warmupForParallelExecution())
                 return Method_Error;
         }
 
         if (script->hasParallelIonScript() &&
             !script->parallelIonScript()->hasInvalidatedCallTarget())
         {
@@ -532,17 +532,17 @@ class ParallelDo : public ForkJoinOp
 
     ExecutionStatus disqualifyFromParallelExecution() {
         if (!executeSequentially())
             return ExecutionFatal;
         return ExecutionSequential;
     }
 
     bool invalidateBailedOutScripts() {
-        RootedScript script(cx_, fun_->toFunction()->nonLazyScript());
+        RootedScript script(TlsPerThreadData.get(), fun_->toFunction()->nonLazyScript());
 
         // Sometimes the script is collected or invalidated already,
         // for example when a full GC runs at an inconvenient time.
         if (!script->hasParallelIonScript()) {
             JS_ASSERT(hasNoPendingInvalidations());
             return true;
         }
 
@@ -563,17 +563,17 @@ class ParallelDo : public ForkJoinOp
     bool warmupForParallelExecution() {
         AutoEnterWarmup warmup(cx_->runtime);
         return executeSequentially();
     }
 #endif // JS_ION
 
     bool executeSequentially() {
         uint32_t numSlices = ForkJoinSlices(cx_);
-        RootedValue funVal(cx_, ObjectValue(*fun_));
+        RootedValue funVal(TlsPerThreadData.get(), ObjectValue(*fun_));
         FastInvokeGuard fig(cx_, funVal);
         for (uint32_t i = 0; i < numSlices; i++) {
             InvokeArgsGuard &args = fig.args();
             if (!args.pushed() && !cx_->stack.pushInvokeArgs(cx_, 3, &args))
                 return false;
             args.setCallee(funVal);
             args.setThis(UndefinedValue());
             args[0].setInt32(i);
@@ -594,33 +594,33 @@ class ParallelDo : public ForkJoinOp
 
         // Make a new IonContext for the slice, which is needed if we need to
         // re-enter the VM.
         IonContext icx(cx_, NULL);
 
         JS_ASSERT(pendingInvalidations[slice.sliceId] == NULL);
 
         JS_ASSERT(fun_->isFunction());
-        RootedFunction callee(cx_, fun_->toFunction());
+        RootedFunction callee(TlsPerThreadData.get(), fun_->toFunction());
         if (!callee->nonLazyScript()->hasParallelIonScript()) {
             // Sometimes, particularly with GCZeal, the parallel ion
             // script can be collected between starting the parallel
             // op and reaching this point.  In that case, we just fail
             // and fallback.
             Spew(SpewOps, "Down (Script no longer present)");
             return false;
         }
 
         ParallelIonInvoke<3> fii(cx_, callee, 3);
 
         fii.args[0] = Int32Value(slice.sliceId);
         fii.args[1] = Int32Value(slice.numSlices);
         fii.args[2] = BooleanValue(false);
 
-        bool ok = fii.invoke(cx_);
+        bool ok = fii.invoke();
         JS_ASSERT(ok == !slice.abortedScript);
         if (!ok) {
             JSScript *script = slice.abortedScript;
             Spew(SpewBailouts, "Aborted script: %p (hasParallelIonScript? %d)",
                  script, script->hasParallelIonScript());
             JS_ASSERT(script->hasParallelIonScript());
             pendingInvalidations[slice.sliceId] = script;
         }
@@ -649,24 +649,24 @@ class ParallelDo : public ForkJoinOp
 };
 
 bool
 js::parallel::Do(JSContext *cx, CallArgs &args)
 {
     JS_ASSERT(args[0].isObject());
     JS_ASSERT(args[0].toObject().isFunction());
 
-    RootedObject fun(cx, &args[0].toObject());
+    RootedObject fun(TlsPerThreadData.get(), &args[0].toObject());
     ParallelDo op(cx, fun);
     ExecutionStatus status = op.apply();
     if (status == ExecutionFatal)
         return false;
 
     if (args[1].isObject()) {
-        RootedObject feedback(cx, &args[1].toObject());
+        RootedObject feedback(TlsPerThreadData.get(), &args[1].toObject());
         if (feedback && feedback->isFunction()) {
             InvokeArgsGuard feedbackArgs;
             if (!cx->stack.pushInvokeArgs(cx, 1, &feedbackArgs))
                 return false;
             feedbackArgs.setCallee(ObjectValue(*feedback));
             feedbackArgs.setThis(UndefinedValue());
             if (status == ExecutionParallel)
                 feedbackArgs[0].setInt32(op.bailouts);