Bug 1367871: Loop over the wasm activations to find the one that's actually interrupted; r=luke
☠☠ backed out by 207e97b313e5 ☠ ☠
authorBenjamin Bouvier <benj@benj.me>
Tue, 30 May 2017 18:32:33 +0200
changeset 409679 8f6a8013e62cf6661bf60fd8a981ac2a8f08dd01
parent 409678 a311d7c6ce201c8b4df80fcf519e25254db991cb
child 409680 c3d4f2814ac382076676fbf894670b5bd9200466
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [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,34 @@ 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;
+
+    for (ActivationIterator iter(cx_); !iter.done(); ++iter) {
+        if (!iter->isWasm())
+            continue;
+
+        WasmActivation* act = iter->asWasm();
+        if (act != this)
+            return false;
+
+        DebugOnly<wasm::Frame*> fp = act->exitFP();
+        MOZ_ASSERT(fp && fp->instance()->code().containsFunctionPC(pc));
+        return true;
+    }
+
+    return false;
 }
 
 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