Skip to content

[JSC] Fast JS-to-Wasm call from FTL#8607

Merged
webkit-early-warning-system merged 1 commit intoWebKit:mainfrom
Constellation:eng/JSC-Fast-JS-to-Wasm-call-from-FTL
Jan 24, 2023
Merged

[JSC] Fast JS-to-Wasm call from FTL#8607
webkit-early-warning-system merged 1 commit intoWebKit:mainfrom
Constellation:eng/JSC-Fast-JS-to-Wasm-call-from-FTL

Conversation

@Constellation
Copy link
Copy Markdown
Member

@Constellation Constellation commented Jan 13, 2023

3563dd1

[JSC] Fast JS-to-Wasm call from FTL
https://bugs.webkit.org/show_bug.cgi?id=250545
rdar://104214223

Reviewed by Keith Miller.

This patch supports direct Wasm call from FTL. FTL can know type speculations.
We check this in DFG strength reduction phase, and generate appropriate stack and register assignment for Wasm call.
This is further more efficient than Wasm IC since,

1. Based on type speculation, we can skip many type checks for arguments.
2. Because FTL can control registers and stacks, we can appropriately configure values in the right argument registers
   and stack location in FTL side and directly call Wasm function from FTL. By using patchpoint, B3 can assign right registers / stack
   location for them.
3. This removes Wasm IC trampoline between JS and Wasm function. Wasm function is now directly called from JS.

To make this work, we require 259139@main. That change allows us to remove a hack in unwinding for wasm (wasm function call can modify global state (vm.wasmContext.instance),
and unwinding needed to restore them appropriately. The above patch removed this necessity).
As a result, we can directly call wasm function from FTL without doing a hack in unwinding. And we can also remove save / restore of vm.wasmContext.instance.

We also need to encourage CallWasm in DFG ByteCodeParser. CallWasm needs constant-folded callee currently, but it needs to be materialized well from DFG ByteCodeParser by inserting
appropriate checks from CallVariant.

Note that we are reporting wasm pinned registers' clobbering from FTL patchpoint. This teaches FTL to save and resume these callee-save registers as FTL's callee-save registers.
Thus, OSR exit / exception unwinding just works well: FTL cares these registers and correctly restore them when OSR exit happens. This is also the reason why we cannot apply
this optimization to TailCall right now: wasm function clobbers callee-save registers and tail-call needs an adaptor to restore them correctly when returning to the caller's caller.
In the future, we should align wasm pinned registers with JS JIT default callee-save registers so that we can easily restore then when OSR exit happens from DFG too. This is necessary
if we would like to introduce this direct call from DFG side.

This improves JetStream2/richards-wasm Runtime from 13.021 to 16.129, 23% improvement.

* Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* Source/JavaScriptCore/dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* Source/JavaScriptCore/dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* Source/JavaScriptCore/dfg/DFGMayExit.cpp:
* Source/JavaScriptCore/dfg/DFGNode.cpp:
(JSC::DFG::Node::convertToCallWasm):
* Source/JavaScriptCore/dfg/DFGNode.h:
(JSC::DFG::Node::hasHeapPrediction):
(JSC::DFG::Node::hasCellOperand):
* Source/JavaScriptCore/dfg/DFGNodeType.h:
* Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:
* Source/JavaScriptCore/dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compileCallWasm):
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
* Source/JavaScriptCore/ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):

Canonical link: https://commits.webkit.org/259250@main

60d8b82

Misc iOS, tvOS & watchOS macOS Linux Windows
❌ 🧪 style ✅ 🛠 ios 🛠 mac 🛠 wpe 🛠 🧪 win
✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug 🛠 gtk 🛠 wincairo
✅ 🧪 webkitperl 🧪 ios-wk2 🧪 api-mac 🧪 gtk-wk2
🧪 api-ios 🧪 mac-wk1 🧪 api-gtk
🛠 🧪 jsc ✅ 🛠 tv 🧪 mac-wk2 🛠 jsc-armv7
🛠 🧪 jsc-arm64 🛠 tv-sim 🧪 mac-AS-debug-wk2 🧪 jsc-armv7-tests
✅ 🛠 watch 🧪 mac-wk2-stress 🛠 jsc-mips
🛠 watch-sim 🧪 jsc-mips-tests
✅ 🛠 🧪 unsafe-merge

@Constellation Constellation self-assigned this Jan 13, 2023
@Constellation Constellation added the JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues. label Jan 13, 2023
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jan 13, 2023
@Constellation
Copy link
Copy Markdown
Member Author

TODO

  1. Interpreter unwinding should handle wasm -> JS fast transition. We should have special CallSiteIndex which tells wasm entrance.
  2. Wasm instance switching should be emitted in FTL B3 layer.
  3. Ensure OSR exit handling. I think we do not need exception handling since unwinding will unroll this (and wasm function invoked from this is always non host function).
  4. returnsVoid case should use Void and return constant undefined.
  5. More tests

@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label Jan 13, 2023
@Constellation Constellation force-pushed the eng/JSC-Fast-JS-to-Wasm-call-from-FTL branch from 2075dc0 to 20f81f0 Compare January 13, 2023 16:47
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jan 13, 2023
@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label Jan 14, 2023
@Constellation Constellation force-pushed the eng/JSC-Fast-JS-to-Wasm-call-from-FTL branch from 20f81f0 to c2b1a3a Compare January 14, 2023 00:22
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jan 14, 2023
@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label Jan 17, 2023
@Constellation Constellation force-pushed the eng/JSC-Fast-JS-to-Wasm-call-from-FTL branch from c2b1a3a to 0aeb3ac Compare January 17, 2023 21:06
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jan 17, 2023
@Constellation
Copy link
Copy Markdown
Member Author

#8815 This is necessary.

@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label Jan 20, 2023
@Constellation Constellation force-pushed the eng/JSC-Fast-JS-to-Wasm-call-from-FTL branch 2 times, most recently from 9f88961 to 693a0dd Compare January 20, 2023 02:09
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jan 20, 2023
@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label Jan 20, 2023
@Constellation Constellation force-pushed the eng/JSC-Fast-JS-to-Wasm-call-from-FTL branch from 693a0dd to ba37dec Compare January 20, 2023 02:16
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jan 20, 2023
@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label Jan 20, 2023
@Constellation Constellation force-pushed the eng/JSC-Fast-JS-to-Wasm-call-from-FTL branch from ba37dec to f594b97 Compare January 20, 2023 02:27
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jan 22, 2023
@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label Jan 22, 2023
@Constellation Constellation force-pushed the eng/JSC-Fast-JS-to-Wasm-call-from-FTL branch from d06f337 to 42f74eb Compare January 22, 2023 02:15
@Constellation Constellation force-pushed the eng/JSC-Fast-JS-to-Wasm-call-from-FTL branch from 42f74eb to da6ef65 Compare January 22, 2023 02:54
@Constellation Constellation force-pushed the eng/JSC-Fast-JS-to-Wasm-call-from-FTL branch from da6ef65 to 661c2c6 Compare January 22, 2023 05:26
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jan 22, 2023
@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label Jan 22, 2023
@Constellation Constellation force-pushed the eng/JSC-Fast-JS-to-Wasm-call-from-FTL branch from 661c2c6 to 15de248 Compare January 22, 2023 07:08
@Constellation Constellation marked this pull request as ready for review January 22, 2023 07:09
@Constellation Constellation requested a review from a team as a code owner January 22, 2023 07:09
@Constellation Constellation force-pushed the eng/JSC-Fast-JS-to-Wasm-call-from-FTL branch from 15de248 to 67162ac Compare January 22, 2023 09:56
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jan 22, 2023
@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label Jan 22, 2023
Copy link
Copy Markdown
Contributor

@kmiller68 kmiller68 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=me

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we assert there's only one result here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, added.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, added.

@Constellation Constellation force-pushed the eng/JSC-Fast-JS-to-Wasm-call-from-FTL branch from 67162ac to 60d8b82 Compare January 24, 2023 00:12
@Constellation Constellation added the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label Jan 24, 2023
https://bugs.webkit.org/show_bug.cgi?id=250545
rdar://104214223

Reviewed by Keith Miller.

This patch supports direct Wasm call from FTL. FTL can know type speculations.
We check this in DFG strength reduction phase, and generate appropriate stack and register assignment for Wasm call.
This is further more efficient than Wasm IC since,

1. Based on type speculation, we can skip many type checks for arguments.
2. Because FTL can control registers and stacks, we can appropriately configure values in the right argument registers
   and stack location in FTL side and directly call Wasm function from FTL. By using patchpoint, B3 can assign right registers / stack
   location for them.
3. This removes Wasm IC trampoline between JS and Wasm function. Wasm function is now directly called from JS.

To make this work, we require 259139@main. That change allows us to remove a hack in unwinding for wasm (wasm function call can modify global state (vm.wasmContext.instance),
and unwinding needed to restore them appropriately. The above patch removed this necessity).
As a result, we can directly call wasm function from FTL without doing a hack in unwinding. And we can also remove save / restore of vm.wasmContext.instance.

We also need to encourage CallWasm in DFG ByteCodeParser. CallWasm needs constant-folded callee currently, but it needs to be materialized well from DFG ByteCodeParser by inserting
appropriate checks from CallVariant.

Note that we are reporting wasm pinned registers' clobbering from FTL patchpoint. This teaches FTL to save and resume these callee-save registers as FTL's callee-save registers.
Thus, OSR exit / exception unwinding just works well: FTL cares these registers and correctly restore them when OSR exit happens. This is also the reason why we cannot apply
this optimization to TailCall right now: wasm function clobbers callee-save registers and tail-call needs an adaptor to restore them correctly when returning to the caller's caller.
In the future, we should align wasm pinned registers with JS JIT default callee-save registers so that we can easily restore then when OSR exit happens from DFG too. This is necessary
if we would like to introduce this direct call from DFG side.

This improves JetStream2/richards-wasm Runtime from 13.021 to 16.129, 23% improvement.

* Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* Source/JavaScriptCore/dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* Source/JavaScriptCore/dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* Source/JavaScriptCore/dfg/DFGMayExit.cpp:
* Source/JavaScriptCore/dfg/DFGNode.cpp:
(JSC::DFG::Node::convertToCallWasm):
* Source/JavaScriptCore/dfg/DFGNode.h:
(JSC::DFG::Node::hasHeapPrediction):
(JSC::DFG::Node::hasCellOperand):
* Source/JavaScriptCore/dfg/DFGNodeType.h:
* Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:
* Source/JavaScriptCore/dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compileCallWasm):
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
* Source/JavaScriptCore/ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):

Canonical link: https://commits.webkit.org/259250@main
@webkit-early-warning-system webkit-early-warning-system force-pushed the eng/JSC-Fast-JS-to-Wasm-call-from-FTL branch from 60d8b82 to 3563dd1 Compare January 24, 2023 00:17
@webkit-commit-queue
Copy link
Copy Markdown
Collaborator

Committed 259250@main (3563dd1): https://commits.webkit.org/259250@main

Reviewed commits have been landed. Closing PR #8607 and removing active labels.

@webkit-early-warning-system webkit-early-warning-system merged commit 3563dd1 into WebKit:main Jan 24, 2023
@webkit-commit-queue webkit-commit-queue removed the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label Jan 24, 2023
@Constellation Constellation deleted the eng/JSC-Fast-JS-to-Wasm-call-from-FTL branch January 24, 2023 00:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants