Bug 1367871: Loop over the wasm activations to find the one that's actually interrupted; r=luke
authorBenjamin Bouvier <benj@benj.me>
Tue, 30 May 2017 18:32:33 +0200
changeset 412478 db0bd0d1b8fdd78de2132c4f005e6005ea7a39ce
parent 412477 27a355cf603699b458a0509bfa5719ae3cbd82f3
child 412479 34b63eb52b4d4ee331ddb3f91f3feb06adfea5c2
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1367871
milestone55.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 1367871: Loop over the wasm activations to find the one that's actually interrupted; r=luke MozReview-Commit-ID: GU7os89GqVO
js/src/jit-test/tests/wasm/timeout/interrupt-several-instances.js
js/src/vm/Stack.cpp
js/src/wasm/WasmFrameIterator.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/timeout/interrupt-several-instances.js
@@ -0,0 +1,23 @@
+// |jit-test| exitstatus: 6;
+
+// Don't include wasm.js in timeout tests: when wasm isn't supported, it will
+// quit(0) which will cause the test to fail.
+if (!wasmIsSupported())
+    quit(6);
+
+load(libdir + "asm.js");
+
+var code = `
+    var out = ffi.out;
+    function f() {
+        out();
+    }
+    return f;
+`;
+
+var ffi = {};
+ffi.out = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func (export "f") (loop $top (br $top))))'))).exports.f;
+
+timeout(1);
+asmLink(asmCompile('glob', 'ffi', USE_ASM + code), this, ffi)();
+assertEq(true, false);
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -21,16 +21,17 @@
 #include "jit/JitFrameIterator-inl.h"
 #include "vm/EnvironmentObject-inl.h"
 #include "vm/Interpreter-inl.h"
 #include "vm/Probes-inl.h"
 
 using namespace js;
 
 using mozilla::ArrayLength;
+using mozilla::DebugOnly;
 using mozilla::Maybe;
 using mozilla::PodCopy;
 
 /*****************************************************************************/
 
 void
 InterpreterFrame::initExecuteFrame(JSContext* cx, HandleScript script,
                                    AbstractFramePtr evalInFramePrev,
@@ -1696,17 +1697,30 @@ WasmActivation::finishInterrupt()
 
     cx_->runtime()->setWasmResumePC(nullptr);
     exitFP_ = nullptr;
 }
 
 bool
 WasmActivation::interrupted() const
 {
-    return !!cx_->runtime()->wasmResumePC();
+    void* pc = cx_->runtime()->wasmResumePC();
+    if (!pc)
+        return false;
+
+    Activation* act = cx_->activation();
+    while (act && !act->isWasm())
+        act = act->prev();
+
+    if (act->asWasm() != this)
+        return false;
+
+    DebugOnly<wasm::Frame*> fp = act->asWasm()->exitFP();
+    MOZ_ASSERT(fp && fp->instance()->code().containsFunctionPC(pc));
+    return true;
 }
 
 void*
 WasmActivation::resumePC() const
 {
     MOZ_ASSERT(interrupted());
     return cx_->runtime()->wasmResumePC();
 }
--- a/js/src/wasm/WasmFrameIterator.cpp
+++ b/js/src/wasm/WasmFrameIterator.cpp
@@ -69,16 +69,17 @@ FrameIterator::FrameIterator(WasmActivat
     // itself and so we do not want to skip it. Instead, we can recover the
     // Code and CodeRange from the WasmActivation, which are set when control
     // flow was interrupted. There is no CallSite (b/c the interrupt was async),
     // but this is fine because CallSite is only used for line number for which
     // we can use the beginning of the function from the CodeRange instead.
 
     code_ = activation_->compartment()->wasm.lookupCode(activation->resumePC());
     MOZ_ASSERT(code_);
+    MOZ_ASSERT(&fp_->tls->instance->code() == code_);
 
     codeRange_ = code_->lookupRange(activation->resumePC());
     MOZ_ASSERT(codeRange_->kind() == CodeRange::Function);
 
     MOZ_ASSERT(!done());
 }
 
 bool