Bug 1251090 - Shell functions should check whether an off main thread compilation is for a script or a module r=shu
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 26 Feb 2016 11:04:15 +0000
changeset 285696 ca189bd124fa6c2ecbd1fdca56aab60ed09d26bb
parent 285695 1f84dea6508d9d5eed33db6c7af1de6762e91d43
child 285697 f19129c21eb309e5ce4142c7941c7ebd0aa3995b
push id72482
push userjcoppeard@mozilla.com
push dateFri, 26 Feb 2016 11:06:48 +0000
treeherdermozilla-inbound@94593f55cd01 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshu
bugs1251090
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 1251090 - Shell functions should check whether an off main thread compilation is for a script or a module r=shu
js/src/jit-test/tests/modules/bug-1251090.js
js/src/shell/js.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/modules/bug-1251090.js
@@ -0,0 +1,3 @@
+// |jit-test| error: Error
+offThreadCompileScript("");
+finishOffThreadModule();
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -3585,36 +3585,45 @@ SyntaxParse(JSContext* cx, unsigned argc
         MOZ_ASSERT(cx->runtime()->hadOutOfMemory);
         return false;
     }
 
     args.rval().setBoolean(succeeded);
     return true;
 }
 
+enum class ScriptKind
+{
+    Script,
+    Module
+};
+
 class OffThreadState {
-  public:
     enum State {
         IDLE,           /* ready to work; no token, no source */
         COMPILING,      /* working; no token, have source */
         DONE            /* compilation done: have token and source */
     };
 
+  public:
     OffThreadState() : monitor(), state(IDLE), token(), source(nullptr) { }
     bool init() { return monitor.init(); }
 
-    bool startIfIdle(JSContext* cx, ScopedJSFreePtr<char16_t>& newSource) {
+    bool startIfIdle(JSContext* cx, ScriptKind kind,
+                     ScopedJSFreePtr<char16_t>& newSource)
+    {
         AutoLockMonitor alm(monitor);
         if (state != IDLE)
             return false;
 
         MOZ_ASSERT(!token);
 
         source = newSource.forget();
 
+        scriptKind = kind;
         state = COMPILING;
         return true;
     }
 
     void abandon(JSContext* cx) {
         AutoLockMonitor alm(monitor);
         MOZ_ASSERT(state == COMPILING);
         MOZ_ASSERT(!token);
@@ -3633,19 +3642,19 @@ class OffThreadState {
         MOZ_ASSERT(source);
         MOZ_ASSERT(newToken);
 
         token = newToken;
         state = DONE;
         alm.notify();
     }
 
-    void* waitUntilDone(JSContext* cx) {
+    void* waitUntilDone(JSContext* cx, ScriptKind kind) {
         AutoLockMonitor alm(monitor);
-        if (state == IDLE)
+        if (state == IDLE || scriptKind != kind)
             return nullptr;
 
         if (state == COMPILING) {
             while (state != DONE)
                 alm.wait();
         }
 
         MOZ_ASSERT(source);
@@ -3656,16 +3665,17 @@ class OffThreadState {
         void* holdToken = token;
         token = nullptr;
         state = IDLE;
         return holdToken;
     }
 
   private:
     Monitor monitor;
+    ScriptKind scriptKind;
     State state;
     void* token;
     char16_t* source;
 };
 
 static OffThreadState offThreadState;
 
 static void
@@ -3742,17 +3752,17 @@ OffThreadCompileScript(JSContext* cx, un
         chars = copy;
     }
 
     if (!JS::CanCompileOffThread(cx, options, length)) {
         JS_ReportError(cx, "cannot compile code on worker thread");
         return false;
     }
 
-    if (!offThreadState.startIfIdle(cx, ownedChars)) {
+    if (!offThreadState.startIfIdle(cx, ScriptKind::Script, ownedChars)) {
         JS_ReportError(cx, "called offThreadCompileScript without calling runOffThreadScript"
                        " to receive prior off-thread compilation");
         return false;
     }
 
     if (!JS::CompileOffThread(cx, options, chars, length,
                               OffThreadCompileScriptCallback, nullptr))
     {
@@ -3768,17 +3778,17 @@ static bool
 runOffThreadScript(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     JSRuntime* rt = cx->runtime();
     if (OffThreadParsingMustWaitForGC(rt))
         gc::AutoFinishGC finishgc(rt);
 
-    void* token = offThreadState.waitUntilDone(cx);
+    void* token = offThreadState.waitUntilDone(cx, ScriptKind::Script);
     if (!token) {
         JS_ReportError(cx, "called runOffThreadScript when no compilation is pending");
         return false;
     }
 
     RootedScript script(cx, JS::FinishOffThreadScript(cx, rt, token));
     if (!script)
         return false;
@@ -3844,17 +3854,17 @@ OffThreadCompileModule(JSContext* cx, un
         chars = copy;
     }
 
     if (!JS::CanCompileOffThread(cx, options, length)) {
         JS_ReportError(cx, "cannot compile code on worker thread");
         return false;
     }
 
-    if (!offThreadState.startIfIdle(cx, ownedChars)) {
+    if (!offThreadState.startIfIdle(cx, ScriptKind::Module, ownedChars)) {
         JS_ReportError(cx, "called offThreadCompileModule without receiving prior off-thread "
                        "compilation");
         return false;
     }
 
     if (!CompileOffThreadModule(cx, options, chars, length,
                                 OffThreadCompileScriptCallback, nullptr))
     {
@@ -3870,17 +3880,17 @@ static bool
 FinishOffThreadModule(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     JSRuntime* rt = cx->runtime();
     if (OffThreadParsingMustWaitForGC(rt))
         gc::AutoFinishGC finishgc(rt);
 
-    void* token = offThreadState.waitUntilDone(cx);
+    void* token = offThreadState.waitUntilDone(cx, ScriptKind::Module);
     if (!token) {
         JS_ReportError(cx, "called finishOffThreadModule when no compilation is pending");
         return false;
     }
 
     RootedObject module(cx, FinishOffThreadModule(cx, rt, token));
     if (!module)
         return false;