Title: [249661] trunk
Revision
249661
Author
[email protected]
Date
2019-09-09 13:32:56 -0700 (Mon, 09 Sep 2019)

Log Message

OSR entry into wasm misses some contexts
https://bugs.webkit.org/show_bug.cgi?id=201569

Reviewed by Yusuke Suzuki.

JSTests:

Add a new harness and wast and the generated wasm file for
testing. The idea long term is to make it easy to test by creating
a C file and converting it to a wast then modify that to produce a
test.

* wasm.yaml:
* wasm/wast-tests/harness.js: Added.
(async.runWasmFile):
* wasm/wast-tests/osr-entry-inner-loop-branch-above-no-consts.wasm: Added.
* wasm/wast-tests/osr-entry-inner-loop-branch-above-no-consts.wast: Added.
* wasm/wast-tests/osr-entry-inner-loop-branch-above.wasm: Added.
* wasm/wast-tests/osr-entry-inner-loop-branch-above.wast: Added.
* wasm/wast-tests/osr-entry-inner-loop.wasm: Added.
* wasm/wast-tests/osr-entry-inner-loop.wast: Added.
* wasm/wast-tests/osr-entry-multiple-enclosed-contexts.wasm: Added.
* wasm/wast-tests/osr-entry-multiple-enclosed-contexts.wast: Added.

Source/_javascript_Core:

This patch fixes an issue where we could fail to capture some of
our contexts when OSR entering into wasm code. Before we would
only capture the state of the block immediately surrounding the
entrance loop block header. We actually need to capture all
enclosed stacks.

Additionally, we don't need to use variables for all the captured
values. We can use a Phi and insert an upsilon just below the
captured value.

* interpreter/CallFrame.h:
* jsc.cpp:
(GlobalObject::finishCreation):
(functionCallerIsOMGCompiled):
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::AirIRGenerator):
(JSC::Wasm::AirIRGenerator::emitEntryTierUpCheck):
(JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
(JSC::Wasm::AirIRGenerator::addLoop):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::createStack):
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::addConstant):
(JSC::Wasm::B3IRGenerator::emitEntryTierUpCheck):
(JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck):
(JSC::Wasm::B3IRGenerator::addLoop):
(JSC::Wasm::B3IRGenerator::addEndToUnreachable):
(JSC::Wasm::dumpExpressionStack):
(JSC::Wasm::B3IRGenerator::dump):
(JSC::Wasm::B3IRGenerator::Stack::Stack): Deleted.
(JSC::Wasm::B3IRGenerator::Stack::append): Deleted.
(JSC::Wasm::B3IRGenerator::Stack::takeLast): Deleted.
(JSC::Wasm::B3IRGenerator::Stack::last): Deleted.
(JSC::Wasm::B3IRGenerator::Stack::size const): Deleted.
(JSC::Wasm::B3IRGenerator::Stack::isEmpty const): Deleted.
(JSC::Wasm::B3IRGenerator::Stack::convertToExpressionList): Deleted.
(JSC::Wasm::B3IRGenerator::Stack::at const): Deleted.
(JSC::Wasm::B3IRGenerator::Stack::variableAt const): Deleted.
(JSC::Wasm::B3IRGenerator::Stack::shrink): Deleted.
(JSC::Wasm::B3IRGenerator::Stack::swap): Deleted.
(JSC::Wasm::B3IRGenerator::Stack::dump const): Deleted.
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser::controlStack):

Tools:

Add new test harness mode for tests created from wast files.

* Scripts/run-jsc-stress-tests:

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (249660 => 249661)


--- trunk/JSTests/ChangeLog	2019-09-09 20:32:26 UTC (rev 249660)
+++ trunk/JSTests/ChangeLog	2019-09-09 20:32:56 UTC (rev 249661)
@@ -1,3 +1,27 @@
+2019-09-07  Keith Miller  <[email protected]>
+
+        OSR entry into wasm misses some contexts
+        https://bugs.webkit.org/show_bug.cgi?id=201569
+
+        Reviewed by Yusuke Suzuki.
+
+        Add a new harness and wast and the generated wasm file for
+        testing. The idea long term is to make it easy to test by creating
+        a C file and converting it to a wast then modify that to produce a
+        test.
+
+        * wasm.yaml:
+        * wasm/wast-tests/harness.js: Added.
+        (async.runWasmFile):
+        * wasm/wast-tests/osr-entry-inner-loop-branch-above-no-consts.wasm: Added.
+        * wasm/wast-tests/osr-entry-inner-loop-branch-above-no-consts.wast: Added.
+        * wasm/wast-tests/osr-entry-inner-loop-branch-above.wasm: Added.
+        * wasm/wast-tests/osr-entry-inner-loop-branch-above.wast: Added.
+        * wasm/wast-tests/osr-entry-inner-loop.wasm: Added.
+        * wasm/wast-tests/osr-entry-inner-loop.wast: Added.
+        * wasm/wast-tests/osr-entry-multiple-enclosed-contexts.wasm: Added.
+        * wasm/wast-tests/osr-entry-multiple-enclosed-contexts.wast: Added.
+
 2019-09-09  Yusuke Suzuki  <[email protected]>
 
         [JSC] Promise resolve/reject functions should be created more efficiently

Added: trunk/JSTests/wasm/wast-tests/harness.js (0 => 249661)


--- trunk/JSTests/wasm/wast-tests/harness.js	                        (rev 0)
+++ trunk/JSTests/wasm/wast-tests/harness.js	2019-09-09 20:32:56 UTC (rev 249661)
@@ -0,0 +1,22 @@
+asyncTestStart(1);
+let context = {
+    env: globalThis,
+};
+
+globalThis.__linear_memory = new WebAssembly.Memory({ initial: 1 });
+
+async function runWasmFile(filePath) {
+    let blob = readFile(filePath, "binary");
+    let compiled;
+    try {
+        compiled = await WebAssembly.instantiate(blob, context);
+        compiled.instance.exports.test();
+    } catch (e) {
+        print(e);
+        throw e;
+    }
+    asyncTestPassed();
+}
+
+for (wasmFile of arguments)
+    runWasmFile(wasmFile);

Added: trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop-branch-above-no-consts.wasm (0 => 249661)


--- trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop-branch-above-no-consts.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop-branch-above-no-consts.wasm	2019-09-09 20:32:56 UTC (rev 249661)
@@ -0,0 +1,6 @@
+��asm������
+``��2env__linear_memory����envcallerIsOMGCompiled����test��
+pn �� ��(��!A!A��!@A��!    @��+��A��!@ �� ��(��Al6�� Aj!��E+��j! ��(��! Aj"AG+��  jj j
\ No newline at end of file

Added: trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop-branch-above-no-consts.wast (0 => 249661)


--- trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop-branch-above-no-consts.wast	                        (rev 0)
+++ trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop-branch-above-no-consts.wast	2019-09-09 20:32:56 UTC (rev 249661)
@@ -0,0 +1,65 @@
+(module
+  (type (;0;) (func (param i32) (result i32)))
+  (type (;1;) (func (result i32)))
+  (import "env" "__linear_memory" (memory (;0;) 0))
+  (import "env" "callerIsOMGCompiled" (func (;0;) (type 1)))
+  (func (export "test") (type 0) (param i32) (result i32)
+    (local i32 i32 i32 i32)
+    get_local 0
+    get_local 0
+    i32.load
+    set_local 1
+    i32.const 2
+    set_local 2
+    i32.const 0
+    set_local 3
+    loop  ;; label = @1
+      i32.const 0
+      set_local 4
+      get_local 1
+      get_local 2
+      if i32
+        get_local 2
+      else
+        get_local 2
+      end
+      block  ;; label = @2
+        call 0
+        br_if 0 (;@2;)
+        i32.const 0
+        set_local 4
+        loop  ;; label = @3
+          get_local 0
+          get_local 0
+          i32.load
+          i32.const 3
+          i32.mul
+          i32.store
+          get_local 4
+          i32.const 1
+          i32.add
+          set_local 4
+          call 0
+          i32.eqz
+          br_if 0 (;@3;)
+        end
+      end
+      i32.add
+      set_local 2
+      get_local 0
+      i32.load
+      set_local 1
+      get_local 3
+      i32.const 1
+      i32.add
+      tee_local 3
+      i32.const 20
+      i32.ne
+      br_if 0 (;@1;)
+    end
+    get_local 1
+    get_local 2
+    i32.add
+    i32.add
+    get_local 4
+    i32.add))

Added: trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop-branch-above.wasm (0 => 249661)


--- trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop-branch-above.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop-branch-above.wasm	2019-09-09 20:32:56 UTC (rev 249661)
@@ -0,0 +1,6 @@
+��asm������
+``��2env__linear_memory����envcallerIsOMGCompiled����test��
+\x83\x80 �� ��(��!A!A��!@A C����@@ BA��!    @��+��A��!@ �� ��(��Al6�� Aj!��E+��j! ��(��! Aj"AG+��  jj j
\ No newline at end of file

Added: trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop-branch-above.wast (0 => 249661)


--- trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop-branch-above.wast	                        (rev 0)
+++ trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop-branch-above.wast	2019-09-09 20:32:56 UTC (rev 249661)
@@ -0,0 +1,80 @@
+(module
+  (type (;0;) (func (param i32) (result i32)))
+  (type (;1;) (func (result i32)))
+  (import "env" "__linear_memory" (memory (;0;) 0))
+  (import "env" "callerIsOMGCompiled" (func (;0;) (type 1)))
+  (func (export "test") (type 0) (param i32) (result i32)
+    (local i32 i32 i32 i32)
+    get_local 0
+    get_local 0
+    i32.load
+    set_local 1
+    i32.const 2
+    set_local 2
+    i32.const 0
+    set_local 3
+    loop  ;; label = @1
+      ;; add a bunch of values so there is a bigger stack here than in the if block.
+      i32.const 1
+      get_local 1
+      f32.const 3
+      get_local 3
+      i64.const 4
+
+      ;; real program
+      i32.const 0
+      set_local 4
+      get_local 1
+      get_local 2
+      if i32
+        get_local 2
+      else
+        get_local 2
+      end
+      block  ;; label = @2
+        call 0
+        br_if 0 (;@2;)
+        i32.const 0
+        set_local 4
+        loop  ;; label = @3
+          get_local 0
+          get_local 0
+          i32.load
+          i32.const 3
+          i32.mul
+          i32.store
+          get_local 4
+          i32.const 1
+          i32.add
+          set_local 4
+          call 0
+          i32.eqz
+          br_if 0 (;@3;)
+        end
+      end
+      i32.add
+      set_local 2
+      get_local 0
+      i32.load
+      set_local 1
+      get_local 3
+      i32.const 1
+      i32.add
+      tee_local 3
+      i32.const 20
+      i32.ne
+      br_if 0 (;@1;)
+
+      ;; drop our extra values so we can compile
+      drop
+      drop
+      drop
+      drop
+      drop
+    end
+    get_local 1
+    get_local 2
+    i32.add
+    i32.add
+    get_local 4
+    i32.add))

Added: trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop.wasm (0 => 249661)


--- trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop.wasm	2019-09-09 20:32:56 UTC (rev 249661)
@@ -0,0 +1,6 @@
+��asm������
+``��2env__linear_memory����envcallerIsOMGCompiled����test��
+hf �� ��(��!A!A��!@A��!  @��+��A��!@ �� ��(��Al6�� Aj!��E+��j! ��(��! Aj"AG+��  jj j
\ No newline at end of file

Added: trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop.wast (0 => 249661)


--- trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop.wast	                        (rev 0)
+++ trunk/JSTests/wasm/wast-tests/osr-entry-inner-loop.wast	2019-09-09 20:32:56 UTC (rev 249661)
@@ -0,0 +1,60 @@
+(module
+  (type (;0;) (func (param i32) (result i32)))
+  (type (;1;) (func (result i32)))
+  (import "env" "__linear_memory" (memory (;0;) 0))
+  (import "env" "callerIsOMGCompiled" (func (;0;) (type 1)))
+  (func (export "test") (type 0) (param i32) (result i32)
+    (local i32 i32 i32 i32)
+    get_local 0
+    get_local 0
+    i32.load
+    set_local 1
+    i32.const 2
+    set_local 2
+    i32.const 0
+    set_local 3
+    loop  ;; label = @1
+      i32.const 0
+      set_local 4
+      get_local 1
+      get_local 2
+      block  ;; label = @2
+        call 0
+        br_if 0 (;@2;)
+        i32.const 0
+        set_local 4
+        loop  ;; label = @3
+          get_local 0
+          get_local 0
+          i32.load
+          i32.const 3
+          i32.mul
+          i32.store
+          get_local 4
+          i32.const 1
+          i32.add
+          set_local 4
+          call 0
+          i32.eqz
+          br_if 0 (;@3;)
+        end
+      end
+      i32.add
+      set_local 2
+      get_local 0
+      i32.load
+      set_local 1
+      get_local 3
+      i32.const 1
+      i32.add
+      tee_local 3
+      i32.const 20
+      i32.ne
+      br_if 0 (;@1;)
+    end
+    get_local 1
+    get_local 2
+    i32.add
+    i32.add
+    get_local 4
+    i32.add))

Added: trunk/JSTests/wasm/wast-tests/osr-entry-multiple-enclosed-contexts.wasm (0 => 249661)


--- trunk/JSTests/wasm/wast-tests/osr-entry-multiple-enclosed-contexts.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/wast-tests/osr-entry-multiple-enclosed-contexts.wasm	2019-09-09 20:32:56 UTC (rev 249661)
@@ -0,0 +1,5 @@
+��asm������
+``��2env__linear_memory����envcallerIsOMGCompiled����test��
+RP ��(��Aj��! ��(��!A��!@ +��A��!@ �� Al6�� Aj!��! ��(��! E+�� j j
\ No newline at end of file

Added: trunk/JSTests/wasm/wast-tests/osr-entry-multiple-enclosed-contexts.wast (0 => 249661)


--- trunk/JSTests/wasm/wast-tests/osr-entry-multiple-enclosed-contexts.wast	                        (rev 0)
+++ trunk/JSTests/wasm/wast-tests/osr-entry-multiple-enclosed-contexts.wast	2019-09-09 20:32:56 UTC (rev 249661)
@@ -0,0 +1,47 @@
+(module
+  (type (;0;) (func (param i32) (result i32)))
+  (type (;1;) (func (result i32)))
+  (import "env" "__linear_memory" (memory (;0;) 0))
+  (import "env" "callerIsOMGCompiled" (func (;0;) (type 1)))
+  (func (export "test") (type 0) (param i32) (result i32)
+    (local i32 i32 i32 i32)
+    get_local 0
+    i32.load
+    i32.const 2
+    i32.add
+    call 0
+    set_local 2
+    get_local 0
+    i32.load
+    set_local 3
+    i32.const 0
+    set_local 4
+    block  ;; label = @1
+      get_local 2
+      br_if 0 (;@1;)
+      i32.const 0
+      set_local 4
+      loop  ;; label = @2
+        get_local 0
+        get_local 3
+        i32.const 3
+        i32.mul
+        i32.store
+        get_local 4
+        i32.const 1
+        i32.add
+        set_local 4
+        call 0
+        set_local 2
+        get_local 0
+        i32.load
+        set_local 3
+        get_local 2
+        i32.eqz
+        br_if 0 (;@2;)
+      end
+    end
+    get_local 4
+    i32.add
+    get_local 3
+    i32.add))

Modified: trunk/JSTests/wasm.yaml (249660 => 249661)


--- trunk/JSTests/wasm.yaml	2019-09-09 20:32:26 UTC (rev 249660)
+++ trunk/JSTests/wasm.yaml	2019-09-09 20:32:56 UTC (rev 249661)
@@ -21,8 +21,8 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-- path: wasm/self-test/
-  cmd: runWebAssemblySuite unless parseRunCommands
+- path: wasm/wast-tests/
+  cmd: runWebAssemblyWithHarness
 - path: wasm/js-api/
   cmd: runWebAssemblySuite unless parseRunCommands
 - path: wasm/noJIT/
@@ -43,6 +43,8 @@
   cmd: runWebAssemblySuite unless parseRunCommands
 - path: wasm/modules/
   cmd: runWebAssembly unless parseRunCommands
+- path: wasm/self-test/
+  cmd: runWebAssemblySuite unless parseRunCommands
 
 - path: wasm/spec-tests/address.wast.js
   cmd: runWebAssemblySpecTest :normal
@@ -185,3 +187,4 @@
 
 - path: wasm/modules/run-from-wasm.wasm
   cmd: runWebAssembly
+

Modified: trunk/Source/_javascript_Core/ChangeLog (249660 => 249661)


--- trunk/Source/_javascript_Core/ChangeLog	2019-09-09 20:32:26 UTC (rev 249660)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-09-09 20:32:56 UTC (rev 249661)
@@ -1,3 +1,54 @@
+2019-09-07  Keith Miller  <[email protected]>
+
+        OSR entry into wasm misses some contexts
+        https://bugs.webkit.org/show_bug.cgi?id=201569
+
+        Reviewed by Yusuke Suzuki.
+
+        This patch fixes an issue where we could fail to capture some of
+        our contexts when OSR entering into wasm code. Before we would
+        only capture the state of the block immediately surrounding the
+        entrance loop block header. We actually need to capture all
+        enclosed stacks.
+
+        Additionally, we don't need to use variables for all the captured
+        values. We can use a Phi and insert an upsilon just below the
+        captured value.
+
+        * interpreter/CallFrame.h:
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionCallerIsOMGCompiled):
+        * wasm/WasmAirIRGenerator.cpp:
+        (JSC::Wasm::AirIRGenerator::AirIRGenerator):
+        (JSC::Wasm::AirIRGenerator::emitEntryTierUpCheck):
+        (JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
+        (JSC::Wasm::AirIRGenerator::addLoop):
+        * wasm/WasmB3IRGenerator.cpp:
+        (JSC::Wasm::B3IRGenerator::createStack):
+        (JSC::Wasm::B3IRGenerator::B3IRGenerator):
+        (JSC::Wasm::B3IRGenerator::addConstant):
+        (JSC::Wasm::B3IRGenerator::emitEntryTierUpCheck):
+        (JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck):
+        (JSC::Wasm::B3IRGenerator::addLoop):
+        (JSC::Wasm::B3IRGenerator::addEndToUnreachable):
+        (JSC::Wasm::dumpExpressionStack):
+        (JSC::Wasm::B3IRGenerator::dump):
+        (JSC::Wasm::B3IRGenerator::Stack::Stack): Deleted.
+        (JSC::Wasm::B3IRGenerator::Stack::append): Deleted.
+        (JSC::Wasm::B3IRGenerator::Stack::takeLast): Deleted.
+        (JSC::Wasm::B3IRGenerator::Stack::last): Deleted.
+        (JSC::Wasm::B3IRGenerator::Stack::size const): Deleted.
+        (JSC::Wasm::B3IRGenerator::Stack::isEmpty const): Deleted.
+        (JSC::Wasm::B3IRGenerator::Stack::convertToExpressionList): Deleted.
+        (JSC::Wasm::B3IRGenerator::Stack::at const): Deleted.
+        (JSC::Wasm::B3IRGenerator::Stack::variableAt const): Deleted.
+        (JSC::Wasm::B3IRGenerator::Stack::shrink): Deleted.
+        (JSC::Wasm::B3IRGenerator::Stack::swap): Deleted.
+        (JSC::Wasm::B3IRGenerator::Stack::dump const): Deleted.
+        * wasm/WasmFunctionParser.h:
+        (JSC::Wasm::FunctionParser::controlStack):
+
 2019-09-09  Yusuke Suzuki  <[email protected]>
 
         [JSC] Promise resolve/reject functions should be created more efficiently

Modified: trunk/Source/_javascript_Core/interpreter/CallFrame.h (249660 => 249661)


--- trunk/Source/_javascript_Core/interpreter/CallFrame.h	2019-09-09 20:32:26 UTC (rev 249660)
+++ trunk/Source/_javascript_Core/interpreter/CallFrame.h	2019-09-09 20:32:56 UTC (rev 249661)
@@ -132,7 +132,7 @@
 
         JSGlobalObject* wasmAwareLexicalGlobalObject(VM&);
 
-        bool isAnyWasmCallee();
+        JS_EXPORT_PRIVATE bool isAnyWasmCallee();
 
         // Global object in which the currently executing code was defined.
         // Differs from VM::vmEntryGlobalObject() during function calls across web browser frames.

Modified: trunk/Source/_javascript_Core/jsc.cpp (249660 => 249661)


--- trunk/Source/_javascript_Core/jsc.cpp	2019-09-09 20:32:26 UTC (rev 249660)
+++ trunk/Source/_javascript_Core/jsc.cpp	2019-09-09 20:32:56 UTC (rev 249661)
@@ -27,6 +27,7 @@
 #include "BuiltinNames.h"
 #include "ButterflyInlines.h"
 #include "BytecodeCacheError.h"
+#include "CallFrameInlines.h"
 #include "CatchScope.h"
 #include "CodeBlock.h"
 #include "CodeCache.h"
@@ -320,6 +321,7 @@
 static EncodedJSValue JSC_HOST_CALL functionNoOSRExitFuzzing(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionOptimizeNextInvocation(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionNumberOfDFGCompiles(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionCallerIsOMGCompiled(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionJSCOptions(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionReoptimizationRetryCount(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionTransferArrayBuffer(ExecState*);
@@ -541,6 +543,7 @@
         addFunction(vm, "noFTL", functionNoFTL, 1);
         addFunction(vm, "noOSRExitFuzzing", functionNoOSRExitFuzzing, 1);
         addFunction(vm, "numberOfDFGCompiles", functionNumberOfDFGCompiles, 1);
+        addFunction(vm, "callerIsOMGCompiled", functionCallerIsOMGCompiled, 0);
         addFunction(vm, "jscOptions", functionJSCOptions, 0);
         addFunction(vm, "optimizeNextInvocation", functionOptimizeNextInvocation, 1);
         addFunction(vm, "reoptimizationRetryCount", functionReoptimizationRetryCount, 1);
@@ -1727,6 +1730,31 @@
     return JSValue::encode(numberOfDFGCompiles(exec));
 }
 
+EncodedJSValue JSC_HOST_CALL functionCallerIsOMGCompiled(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (!Options::useBBQTierUpChecks())
+        return JSValue::encode(jsBoolean(true));
+
+    CallerFunctor wasmToJSFrame;
+    StackVisitor::visit(exec, &vm, wasmToJSFrame);
+    if (!wasmToJSFrame.callerFrame()->isAnyWasmCallee())
+        return throwVMError(exec, scope, "caller is not a wasm->js import function");
+
+    // We have a wrapper frame that we generate for imports. If we ever can direct call from wasm we would need to change this.
+    ASSERT(!wasmToJSFrame.callerFrame()->callee().isWasm());
+    CallerFunctor wasmFrame;
+    StackVisitor::visit(wasmToJSFrame.callerFrame(), &vm, wasmFrame);
+    ASSERT(wasmFrame.callerFrame()->callee().isWasm());
+#if ENABLE(WEBASSEMBLY)
+    auto mode = wasmFrame.callerFrame()->callee().asWasmCallee()->compilationMode();
+    return JSValue::encode(jsBoolean(mode == Wasm::CompilationMode::OMGMode || mode == Wasm::CompilationMode::OMGForOSREntryMode));
+#endif
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
 Message::Message(ArrayBufferContents&& contents, int32_t index)
     : m_contents(WTFMove(contents))
     , m_index(index)

Modified: trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp (249660 => 249661)


--- trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp	2019-09-09 20:32:26 UTC (rev 249660)
+++ trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp	2019-09-09 20:32:56 UTC (rev 249661)
@@ -591,8 +591,8 @@
 
     void emitThrowException(CCallHelpers&, ExceptionType);
 
-    void emitEntryTierUpCheck(int32_t incrementCount, B3::Origin);
-    void emitLoopTierUpCheck(int32_t incrementCount, const Stack&, uint32_t, uint32_t, B3::Origin);
+    void emitEntryTierUpCheck();
+    void emitLoopTierUpCheck(uint32_t loopIndex);
 
     void emitWriteBarrierForJSWrapper();
     ExpressionType emitCheckAndPreparePointer(ExpressionType pointer, uint32_t offset, uint32_t sizeOfOp);
@@ -852,7 +852,7 @@
         }
     });
 
-    emitEntryTierUpCheck(TierUpCount::functionEntryIncrement(), B3::Origin());
+    emitEntryTierUpCheck();
 }
 
 void AirIRGenerator::restoreWebAssemblyGlobalState(RestoreCachedStackLimit restoreCachedStackLimit, const MemoryInformation& memory, TypedTmp instance, BasicBlock* block)
@@ -1603,10 +1603,8 @@
     return { };
 }
 
-void AirIRGenerator::emitEntryTierUpCheck(int32_t incrementCount, B3::Origin origin)
+void AirIRGenerator::emitEntryTierUpCheck()
 {
-    UNUSED_PARAM(origin);
-
     if (!m_tierUp)
         return;
 
@@ -1624,7 +1622,7 @@
     patch->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
         AllowMacroScratchRegisterUsage allowScratch(jit);
 
-        CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32(incrementCount), CCallHelpers::Address(params[0].gpr()));
+        CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32(TierUpCount::functionEntryIncrement()), CCallHelpers::Address(params[0].gpr()));
         CCallHelpers::Label tierUpResume = jit.label();
 
         params.addLatePath([=] (CCallHelpers& jit) {
@@ -1650,9 +1648,10 @@
     emitPatchpoint(patch, Tmp(), countdownPtr);
 }
 
-void AirIRGenerator::emitLoopTierUpCheck(int32_t incrementCount, const Stack& expressionStack, uint32_t loopIndex, uint32_t outerLoopIndex, B3::Origin origin)
+void AirIRGenerator::emitLoopTierUpCheck(uint32_t loopIndex)
 {
-    UNUSED_PARAM(origin);
+    uint32_t outerLoopIndex = this->outerLoopIndex();
+    m_outerLoops.append(loopIndex);
 
     if (!m_tierUp)
         return;
@@ -1680,15 +1679,17 @@
     Vector<ConstrainedTmp> patchArgs;
     patchArgs.append(countdownPtr);
 
-    Vector<B3::Type> types;
-    for (auto& local : m_locals) {
+    for (auto& local : m_locals)
         patchArgs.append(ConstrainedTmp(local, B3::ValueRep::ColdAny));
-        types.append(toB3Type(local.type()));
+    for (unsigned controlIndex = 0; controlIndex < m_parser->controlStack().size(); ++controlIndex) {
+        ExpressionList& expressionStack = m_parser->controlStack()[controlIndex].enclosedExpressionStack;
+        for (auto& value : expressionStack)
+            patchArgs.append(ConstrainedTmp(value, B3::ValueRep::ColdAny));
+
+        const auto& results = m_parser->controlStack()[controlIndex].controlData.result;
+        for (auto& value : results)
+            patchArgs.append(ConstrainedTmp(value, B3::ValueRep::ColdAny));
     }
-    for (auto& _expression_ : expressionStack) {
-        patchArgs.append(ConstrainedTmp(_expression_, B3::ValueRep::ColdAny));
-        types.append(toB3Type(_expression_.type()));
-    }
 
     TierUpCount::TriggerReason* forceEntryTrigger = &(m_tierUp->osrEntryTriggers().last());
     static_assert(!static_cast<uint8_t>(TierUpCount::TriggerReason::DontTrigger), "the JIT code assumes non-zero means 'enter'");
@@ -1696,12 +1697,13 @@
     patch->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
         AllowMacroScratchRegisterUsage allowScratch(jit);
         CCallHelpers::Jump forceOSREntry = jit.branchTest8(CCallHelpers::NonZero, CCallHelpers::AbsoluteAddress(forceEntryTrigger));
-        CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32(incrementCount), CCallHelpers::Address(params[0].gpr()));
+        CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32(TierUpCount::loopIncrement()), CCallHelpers::Address(params[0].gpr()));
         MacroAssembler::Label tierUpResume = jit.label();
 
         OSREntryData& osrEntryData = m_tierUp->addOSREntryData(m_functionIndex, loopIndex);
-        for (unsigned index = 0; index < types.size(); ++index)
-            osrEntryData.values().constructAndAppend(params[index + 1], types[index]);
+        // First argument is the countdown location.
+        for (unsigned index = 1; index < params.value()->numChildren(); ++index)
+            osrEntryData.values().constructAndAppend(params[index], params.value()->child(index)->type());
         OSREntryData* osrEntryDataPtr = &osrEntryData;
 
         params.addLatePath([=] (CCallHelpers& jit) {
@@ -1718,7 +1720,7 @@
     emitPatchpoint(patch, Tmp(), WTFMove(patchArgs));
 }
 
-AirIRGenerator::ControlData AirIRGenerator::addLoop(Type signature, const Stack& expressionStack, uint32_t loopIndex)
+AirIRGenerator::ControlData AirIRGenerator::addLoop(Type signature, const Stack&, uint32_t loopIndex)
 {
     BasicBlock* body = m_code.addBlock();
     BasicBlock* continuation = m_code.addBlock();
@@ -1726,10 +1728,8 @@
     append(Jump);
     m_currentBlock->setSuccessors(body);
 
-    uint32_t outerLoopIndex = this->outerLoopIndex();
-    m_outerLoops.append(loopIndex);
     m_currentBlock = body;
-    emitLoopTierUpCheck(TierUpCount::loopIncrement(), expressionStack, loopIndex, outerLoopIndex, origin());
+    emitLoopTierUpCheck(loopIndex);
 
     return ControlData(origin(), signature, tmpForType(signature), BlockType::Loop, continuation, body);
 }

Modified: trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp (249660 => 249661)


--- trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp	2019-09-09 20:32:26 UTC (rev 249660)
+++ trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp	2019-09-09 20:32:56 UTC (rev 249661)
@@ -161,108 +161,9 @@
     typedef Value* ExpressionType;
     typedef Vector<ExpressionType, 1> ExpressionList;
 
-    friend class Stack;
-    class Stack {
-    public:
-        Stack(B3IRGenerator* generator)
-            : m_generator(generator)
-        {
-        }
+    using Stack = ExpressionList;
+    Stack createStack() { return { }; }
 
-        void append(ExpressionType _expression_)
-        {
-            if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode) {
-                Variable* variable = m_generator->m_proc.addVariable(_expression_->type());
-                m_generator->m_currentBlock->appendNew<VariableValue>(m_generator->m_proc, Set, m_generator->origin(), variable, _expression_);
-                m_stack.append(variable);
-                return;
-            }
-            m_data.append(_expression_);
-        }
-
-        ExpressionType takeLast()
-        {
-            if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode)
-                return m_generator->m_currentBlock->appendNew<VariableValue>(m_generator->m_proc, B3::Get, m_generator->origin(), m_stack.takeLast());
-            return m_data.takeLast();
-        }
-
-        ExpressionType last()
-        {
-            if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode)
-                return m_generator->m_currentBlock->appendNew<VariableValue>(m_generator->m_proc, B3::Get, m_generator->origin(), m_stack.last());
-            return m_data.last();
-        }
-
-        unsigned size() const
-        {
-            if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode)
-                return m_stack.size();
-            return m_data.size();
-        }
-        bool isEmpty() const { return size() == 0; }
-
-        ExpressionList convertToExpressionList()
-        {
-            if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode) {
-                ExpressionList results;
-                for (unsigned i = 0; i < m_stack.size(); ++i)
-                    results.append(at(i));
-                return results;
-            }
-            return m_data;
-        }
-
-        ExpressionType at(unsigned i) const
-        {
-            if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode)
-                return m_generator->m_currentBlock->appendNew<VariableValue>(m_generator->m_proc, B3::Get, m_generator->origin(), m_stack.at(i));
-            return m_data.at(i);
-        }
-
-        Variable* variableAt(unsigned i) const
-        {
-            if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode)
-                return m_stack.at(i);
-            return nullptr;
-        }
-
-        void shrink(unsigned i)
-        {
-            if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode) {
-                m_stack.shrink(i);
-                return;
-            }
-            m_data.shrink(i);
-        }
-
-        void swap(Stack& stack)
-        {
-            std::swap(m_generator, stack.m_generator);
-            m_data.swap(stack.m_data);
-            m_stack.swap(stack.m_stack);
-        }
-
-        void dump() const
-        {
-            CommaPrinter comma(", ", "");
-            dataLog(comma, "ExpressionStack:");
-            if (m_generator->m_compilationMode == CompilationMode::OMGForOSREntryMode) {
-                for (const auto& variable : m_stack)
-                    dataLog(comma, *variable);
-                return;
-            }
-            for (const auto& _expression_ : m_data)
-                dataLog(comma, *_expression_);
-        }
-
-    private:
-        B3IRGenerator* m_generator { nullptr };
-        ExpressionList m_data;
-        Vector<Variable*> m_stack;
-    };
-    Stack createStack() { return Stack(this); }
-
     using ControlType = ControlData;
     using ResultList = ControlData::ResultList;
     using ControlEntry = FunctionParser<B3IRGenerator>::ControlEntry;
@@ -351,8 +252,8 @@
 private:
     void emitExceptionCheck(CCallHelpers&, ExceptionType);
 
-    void emitEntryTierUpCheck(int32_t incrementCount, B3::Origin);
-    void emitLoopTierUpCheck(int32_t incrementCount, const Stack&, uint32_t, uint32_t, B3::Origin);
+    void emitEntryTierUpCheck();
+    void emitLoopTierUpCheck(uint32_t loopIndex);
 
     void emitWriteBarrierForJSWrapper();
     ExpressionType emitCheckAndPreparePointer(ExpressionType pointer, uint32_t offset, uint32_t sizeOfOp);
@@ -584,7 +485,7 @@
         });
     }
 
-    emitEntryTierUpCheck(TierUpCount::functionEntryIncrement(), Origin());
+    emitEntryTierUpCheck();
 
     if (m_compilationMode == CompilationMode::OMGForOSREntryMode)
         m_currentBlock = m_proc.addBlock();
@@ -1187,18 +1088,19 @@
 
 B3IRGenerator::ExpressionType B3IRGenerator::addConstant(Type type, uint64_t value)
 {
+
     return constant(toB3Type(type), value);
 }
 
-void B3IRGenerator::emitEntryTierUpCheck(int32_t incrementCount, Origin origin)
+void B3IRGenerator::emitEntryTierUpCheck()
 {
     if (!m_tierUp)
         return;
 
     ASSERT(m_tierUp);
-    Value* countDownLocation = constant(pointerType(), reinterpret_cast<uint64_t>(&m_tierUp->m_counter), origin);
+    Value* countDownLocation = constant(pointerType(), reinterpret_cast<uint64_t>(&m_tierUp->m_counter), Origin());
 
-    PatchpointValue* patch = m_currentBlock->appendNew<PatchpointValue>(m_proc, B3::Void, origin);
+    PatchpointValue* patch = m_currentBlock->appendNew<PatchpointValue>(m_proc, B3::Void, Origin());
     Effects effects = Effects::none();
     // FIXME: we should have a more precise heap range for the tier up count.
     effects.reads = B3::HeapRange::top();
@@ -1209,7 +1111,7 @@
     patch->append(countDownLocation, ValueRep::SomeRegister);
     patch->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
         AllowMacroScratchRegisterUsage allowScratch(jit);
-        CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32(incrementCount), CCallHelpers::Address(params[0].gpr()));
+        CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32(TierUpCount::functionEntryIncrement()), CCallHelpers::Address(params[0].gpr()));
         CCallHelpers::Label tierUpResume = jit.label();
 
         params.addLatePath([=] (CCallHelpers& jit) {
@@ -1233,13 +1135,15 @@
     });
 }
 
-void B3IRGenerator::emitLoopTierUpCheck(int32_t incrementCount, const Stack& expressionStack, uint32_t loopIndex, uint32_t outerLoopIndex, B3::Origin origin)
+void B3IRGenerator::emitLoopTierUpCheck(uint32_t loopIndex)
 {
+    uint32_t outerLoopIndex = this->outerLoopIndex();
+    m_outerLoops.append(loopIndex);
+
     if (!m_tierUp)
         return;
 
-    ASSERT(m_tierUp);
-
+    Origin origin = this->origin();
     ASSERT(m_tierUp->osrEntryTriggers().size() == loopIndex);
     m_tierUp->osrEntryTriggers().append(TierUpCount::TriggerReason::DontTrigger);
     m_tierUp->outerLoops().append(outerLoopIndex);
@@ -1247,16 +1151,14 @@
     Value* countDownLocation = constant(pointerType(), reinterpret_cast<uint64_t>(&m_tierUp->m_counter), origin);
 
     Vector<ExpressionType> stackmap;
-    Vector<B3::Type> types;
     for (auto& local : m_locals) {
         ExpressionType result = m_currentBlock->appendNew<VariableValue>(m_proc, B3::Get, origin, local);
         stackmap.append(result);
-        types.append(result->type());
     }
-    for (unsigned i = 0; i < expressionStack.size(); ++i) {
-        ExpressionType result = expressionStack.at(i);
-        stackmap.append(result);
-        types.append(result->type());
+    for (unsigned controlIndex = 0; controlIndex < m_parser->controlStack().size(); ++controlIndex) {
+        auto& expressionStack = m_parser->controlStack()[controlIndex].enclosedExpressionStack;
+        for (Value* value : expressionStack)
+            stackmap.append(value);
     }
 
     PatchpointValue* patch = m_currentBlock->appendNew<PatchpointValue>(m_proc, B3::Void, origin);
@@ -1281,12 +1183,13 @@
     patch->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
         AllowMacroScratchRegisterUsage allowScratch(jit);
         CCallHelpers::Jump forceOSREntry = jit.branchTest8(CCallHelpers::NonZero, CCallHelpers::AbsoluteAddress(forceEntryTrigger));
-        CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32(incrementCount), CCallHelpers::Address(params[0].gpr()));
+        CCallHelpers::Jump tierUp = jit.branchAdd32(CCallHelpers::PositiveOrZero, CCallHelpers::TrustedImm32(TierUpCount::loopIncrement()), CCallHelpers::Address(params[0].gpr()));
         MacroAssembler::Label tierUpResume = jit.label();
 
         OSREntryData& osrEntryData = m_tierUp->addOSREntryData(m_functionIndex, loopIndex);
-        for (unsigned index = 0; index < types.size(); ++index)
-            osrEntryData.values().constructAndAppend(params[index + 1], types[index]);
+        // First argument is the countdown location.
+        for (unsigned i = 1; i < params.value()->numChildren(); ++i)
+            osrEntryData.values().constructAndAppend(params[i], params.value()->child(i)->type());
         OSREntryData* osrEntryDataPtr = &osrEntryData;
 
         params.addLatePath([=] (CCallHelpers& jit) {
@@ -1301,7 +1204,7 @@
     });
 }
 
-B3IRGenerator::ControlData B3IRGenerator::addLoop(Type signature, const Stack& stack, uint32_t loopIndex)
+B3IRGenerator::ControlData B3IRGenerator::addLoop(Type signature, const Stack&, uint32_t loopIndex)
 {
     BasicBlock* body = m_proc.addBlock();
     BasicBlock* continuation = m_proc.addBlock();
@@ -1308,42 +1211,62 @@
 
     m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), body);
     if (loopIndex == m_loopIndexForOSREntry) {
+        dataLogLnIf(WasmB3IRGeneratorInternal::verbose, "Setting up for OSR entry");
         m_currentBlock = m_rootBlock;
-        m_osrEntryScratchBufferSize = m_locals.size() + stack.size();
         Value* pointer = m_rootBlock->appendNew<ArgumentRegValue>(m_proc, Origin(), GPRInfo::argumentGPR0);
 
-        auto loadFromScratchBuffer = [&] (B3::Type type, unsigned index) {
-            size_t offset = sizeof(uint64_t) * index;
-            switch (type.kind()) {
-            case B3::Int32:
-                return m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int32, origin(), pointer, offset);
-            case B3::Int64:
-                return m_currentBlock->appendNew<MemoryValue>(m_proc, Load, B3::Int64, origin(), pointer, offset);
-            case B3::Float:
-                return m_currentBlock->appendNew<MemoryValue>(m_proc, Load, B3::Float, origin(), pointer, offset);
-            case B3::Double:
-                return m_currentBlock->appendNew<MemoryValue>(m_proc, Load, B3::Double, origin(), pointer, offset);
-            default:
-                RELEASE_ASSERT_NOT_REACHED();
-                break;
-            }
+        unsigned indexInBuffer = 0;
+        auto loadFromScratchBuffer = [&] (B3::Type type) {
+            size_t offset = sizeof(uint64_t) * indexInBuffer++;
+            RELEASE_ASSERT(type.isNumeric());
+            return m_currentBlock->appendNew<MemoryValue>(m_proc, Load, type, origin(), pointer, offset);
         };
 
-        unsigned indexInBuffer = 0;
         for (auto& local : m_locals)
-            m_currentBlock->appendNew<VariableValue>(m_proc, Set, Origin(), local, loadFromScratchBuffer(local->type(), indexInBuffer++));
-        for (unsigned i = 0; i < stack.size(); ++i) {
-            auto* variable = stack.variableAt(i);
-            m_currentBlock->appendNew<VariableValue>(m_proc, Set, Origin(), variable, loadFromScratchBuffer(variable->type(), indexInBuffer++));
+            m_currentBlock->appendNew<VariableValue>(m_proc, Set, Origin(), local, loadFromScratchBuffer(local->type()));
+
+        for (unsigned controlIndex = 0; controlIndex < m_parser->controlStack().size(); ++controlIndex) {
+            const auto& data = ""
+            auto& expressionStack = m_parser->controlStack()[controlIndex].enclosedExpressionStack;
+
+            // For each stack entry enclosed by this loop we need to replace the value with a phi so we can fill it on OSR entry.
+            BasicBlock* sourceBlock = nullptr;
+            unsigned blockIndex = 0;
+            B3::InsertionSet insertionSet(m_proc);
+            for (unsigned i = 0; i < expressionStack.size(); i++) {
+                auto* value = expressionStack[i];
+                if (value->isConstant())
+                    continue;
+
+                if (value->owner != sourceBlock) {
+                    insertionSet.execute(sourceBlock);
+                    ASSERT(insertionSet.isEmpty());
+                    dataLogLnIf(WasmB3IRGeneratorInternal::verbose && sourceBlock, "Executed insertion set into: ", *sourceBlock);
+                    blockIndex = 0;
+                    sourceBlock = value->owner;
+                }
+
+                while (sourceBlock->at(blockIndex++) != value)
+                    ASSERT(blockIndex < sourceBlock->size());
+                ASSERT(sourceBlock->at(blockIndex - 1) == value);
+
+                auto* phi = data.continuation->appendNew<Value>(m_proc, Phi,  value->type(), value->origin());
+                expressionStack[i] = phi;
+                m_currentBlock->appendNew<UpsilonValue>(m_proc, value->origin(), loadFromScratchBuffer(value->type()), phi);
+
+                auto* sourceUpsilon = m_proc.add<UpsilonValue>(value->origin(), value, phi);
+                insertionSet.insertValue(blockIndex, sourceUpsilon);
+            }
+            insertionSet.execute(sourceBlock);
         }
+
+        m_osrEntryScratchBufferSize = indexInBuffer;
         m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), body);
         body->addPredecessor(m_currentBlock);
     }
 
-    uint32_t outerLoopIndex = this->outerLoopIndex();
-    m_outerLoops.append(loopIndex);
     m_currentBlock = body;
-    emitLoopTierUpCheck(TierUpCount::loopIncrement(), stack, loopIndex, outerLoopIndex, origin());
+    emitLoopTierUpCheck(loopIndex);
 
     return ControlData(m_proc, origin(), signature, BlockType::Loop, continuation, body);
 }
@@ -1467,7 +1390,7 @@
 
     // TopLevel does not have any code after this so we need to make sure we emit a return here.
     if (data.type() == BlockType::TopLevel)
-        return addReturn(entry.controlData, entry.enclosedExpressionStack.convertToExpressionList());
+        return addReturn(entry.controlData, entry.enclosedExpressionStack);
 
     return { };
 }
@@ -1739,6 +1662,13 @@
         unify(result[result.size() - 1 - i], resultStack.at(resultStack.size() - 1 - i));
 }
 
+static void dumpExpressionStack(const CommaPrinter& comma, const B3IRGenerator::ExpressionList& expressionStack)
+{
+    dataLog(comma, "ExpressionStack:");
+    for (const auto& _expression_ : expressionStack)
+        dataLog(comma, *_expression_);
+}
+
 void B3IRGenerator::dump(const Vector<ControlEntry>& controlStack, const Stack* expressionStack)
 {
     dataLogLn("Constants:");
@@ -1752,7 +1682,8 @@
     ASSERT(controlStack.size());
     for (size_t i = controlStack.size(); i--;) {
         dataLog("  ", controlStack[i].controlData, ": ");
-        expressionStack->dump();
+        CommaPrinter comma(", ", "");
+        dumpExpressionStack(comma, *expressionStack);
         expressionStack = &controlStack[i].enclosedExpressionStack;
         dataLogLn();
     }

Modified: trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h (249660 => 249661)


--- trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h	2019-09-09 20:32:26 UTC (rev 249660)
+++ trunk/Source/_javascript_Core/wasm/WasmFunctionParser.h	2019-09-09 20:32:56 UTC (rev 249661)
@@ -60,6 +60,8 @@
     OpType currentOpcode() const { return m_currentOpcode; }
     size_t currentOpcodeStartingOffset() const { return m_currentOpcodeStartingOffset; }
 
+    Vector<ControlEntry>& controlStack() { return m_controlStack; }
+
 private:
     static const bool verbose = false;
 

Modified: trunk/Source/_javascript_Core/wasm/WasmOpcodeOrigin.cpp (249660 => 249661)


--- trunk/Source/_javascript_Core/wasm/WasmOpcodeOrigin.cpp	2019-09-09 20:32:26 UTC (rev 249660)
+++ trunk/Source/_javascript_Core/wasm/WasmOpcodeOrigin.cpp	2019-09-09 20:32:56 UTC (rev 249661)
@@ -32,7 +32,7 @@
 
 void OpcodeOrigin::dump(PrintStream& out) const
 {
-    out.print("{opcode: ", makeString(opcode()), ", location: ", location(), "}");
+    out.print("{opcode: ", makeString(opcode()), ", location: ", RawPointer(reinterpret_cast<void*>(location())), "}");
 }
 
 } } // namespace JSC::Wasm

Modified: trunk/Tools/ChangeLog (249660 => 249661)


--- trunk/Tools/ChangeLog	2019-09-09 20:32:26 UTC (rev 249660)
+++ trunk/Tools/ChangeLog	2019-09-09 20:32:56 UTC (rev 249661)
@@ -1,3 +1,14 @@
+2019-09-07  Keith Miller  <[email protected]>
+
+        OSR entry into wasm misses some contexts
+        https://bugs.webkit.org/show_bug.cgi?id=201569
+
+        Reviewed by Yusuke Suzuki.
+
+        Add new test harness mode for tests created from wast files.
+
+        * Scripts/run-jsc-stress-tests:
+
 2019-09-09  Daniel Bates  <[email protected]>
 
         Remove all selection view animations before dumping results

Modified: trunk/Tools/Scripts/run-jsc-stress-tests (249660 => 249661)


--- trunk/Tools/Scripts/run-jsc-stress-tests	2019-09-09 20:32:26 UTC (rev 249660)
+++ trunk/Tools/Scripts/run-jsc-stress-tests	2019-09-09 20:32:56 UTC (rev 249661)
@@ -1114,6 +1114,36 @@
     end
 end
 
+def runHarnessTest(kind, *options)
+    wasmFiles = allWasmFiles($collection)
+    wasmFiles.each {
+        | file |
+        basename = file.basename.to_s
+        addRunCommand("(" + basename + ")-" + kind, [pathToVM.to_s] + $testSpecificRequiredOptions + options + [$benchmark.to_s, "--", basename], silentOutputHandler, simpleErrorHandler)
+    }
+end
+
+def runWebAssemblyWithHarness(*optionalTestSpecificOptions)
+    raise unless $benchmark.to_s =~ /harness\.m?js/
+    return if !$jitTests
+    return if !$isFTLPlatform
+
+    wasmFiles = allWasmFiles($collection)
+    prepareExtraRelativeFiles(wasmFiles.map { |f| f.basename }, $collection)
+
+    runHarnessTest("default-wasm", *(FTL_OPTIONS + optionalTestSpecificOptions))
+    if $mode != "quick"
+        runHarnessTest("wasm-no-cjit-yes-tls-context", "--useFastTLSForWasmContext=true", *(FTL_OPTIONS + NO_CJIT_OPTIONS + optionalTestSpecificOptions))
+        runHarnessTest("wasm-eager", *(FTL_OPTIONS + EAGER_OPTIONS + optionalTestSpecificOptions))
+        runHarnessTest("wasm-eager-jettison", "--forceCodeBlockToJettisonDueToOldAge=true", *(FTL_OPTIONS + optionalTestSpecificOptions))
+        runHarnessTest("wasm-no-call-ic", "--useCallICsForWebAssemblyToJSCalls=false", *(FTL_OPTIONS + optionalTestSpecificOptions))
+        runHarnessTest("wasm-no-tls-context", "--useFastTLSForWasmContext=false", *(FTL_OPTIONS + optionalTestSpecificOptions))
+        runHarnessTest("wasm-slow-memory", "--useWebAssemblyFastMemory=false", *(FTL_OPTIONS + optionalTestSpecificOptions))
+        runHarnessTest("wasm-no-air", "--wasmBBQUsesAir=false", *(FTL_OPTIONS + optionalTestSpecificOptions))
+        runHarnessTest("wasm-collect-continuously", "--collectContinuously=true", *(FTL_OPTIONS + optionalTestSpecificOptions)) if shouldCollectContinuously?
+    end
+end
+
 def runWebAssemblyEmscripten(mode)
     case mode
     when :skip
@@ -1483,6 +1513,21 @@
     puts "Skipping #{$collectionName}/#{$benchmark}"
 end
 
+def allWasmFiles(path)
+    if path.file?
+        [path]
+    else
+        result = []
+        Dir.foreach(path) {
+            | filename |
+            next unless filename =~ /\.m?wasm$/
+            next unless (path + filename).file?
+            result << path + filename
+        }
+        result
+    end
+end
+
 def allJSFiles(path)
     if path.file?
         [path]
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to