Bug 1522458: Add a resume point after wasm calls inlined in Ion; r=nbp a=lizzard
authorBenjamin Bouvier <bbouvier@mozilla.com>
Mon, 04 Feb 2019 14:18:47 +0200
changeset 515698 f53c459f828ac3254e948afa32b6b2bd58605f1c
parent 515697 50e02e7c1d79c0e0d9ee5756406d449bfdd4e5d0
child 515699 b2a7987967e45c1ee946ee1c7605e8e8020691a6
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp, lizzard
bugs1522458
milestone66.0
Bug 1522458: Add a resume point after wasm calls inlined in Ion; r=nbp a=lizzard Reviewers: nbp Reviewed By: nbp Subscribers: jandem Bug #: 1522458 Differential Revision: https://phabricator.services.mozilla.com/D18247
js/src/jit-test/tests/wasm/regress/ion-inlinedcall-resumepoint.js
js/src/jit/MCallOptimize.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/ion-inlinedcall-resumepoint.js
@@ -0,0 +1,50 @@
+var invalidatedFunction = function() { return false; }
+
+var counter = 0;
+
+function maybeInvalidate(iplusk) {
+    if (iplusk === 0) {
+        // This should happen only once; it will invalidate the call frame of
+        // the ion() function, which should rewind to just after the wasm call
+        // (if it got its own resume point).
+        // Before the patch, the wasm call doesn't get its resume point, so
+        // it's repeated and the importedFunc() is called once too many.
+        counter++;
+        invalidatedFunction = function () { return true; };
+    }
+}
+
+function importedFunc(k) {
+    for (let i = 100; i --> 0 ;) {
+        maybeInvalidate(i + k);
+    }
+}
+
+let { exports } = new WebAssembly.Instance(
+    new WebAssembly.Module(
+        wasmTextToBinary(`
+        (module
+            (func $imp (import "env" "importedFunc") (param i32))
+            (func (export "exp") (param i32)
+                get_local 0
+                call $imp
+            )
+        )
+        `)
+    ), {
+        env: {
+            importedFunc
+        }
+    }
+);
+
+function ion(k) {
+    exports.exp(k);
+    invalidatedFunction();
+}
+
+for (let k = 100; k --> 0 ;) {
+    ion(k);
+}
+
+assertEq(counter, 1);
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -4047,16 +4047,18 @@ IonBuilder::InliningResult IonBuilder::i
 
     current->add(conversion);
     call->initArg(i, conversion);
   }
 
   current->push(call);
   current->add(call);
 
+  MOZ_TRY(resumeAfter(call));
+
   callInfo.setImplicitlyUsedUnchecked();
 
   return InliningStatus_Inlined;
 }
 
 #define ADD_NATIVE(native)                                              \
   const JSJitInfo JitInfo_##native{{nullptr},                           \
                                    {uint16_t(InlinableNative::native)}, \