Implement wasm tail calls
Categories
(Core :: JavaScript: WebAssembly, task, P1)
Tracking
()
Tracking | Status | |
---|---|---|
firefox118 | --- | fixed |
People
(Reporter: wingo, Assigned: yury)
References
(Depends on 1 open bug, Blocks 2 open bugs)
Details
Attachments
(5 files, 11 obsolete files)
This patch will add parser and validator support for WebAssembly tail calls. Any attempt to compile a function with a tail call will MOZ_CRASH.
We also add a new #define, ENABLE_WASM_TAIL_CALLS
, a new configure flag --enable-wasm-tail-calls
which is on by default in nightly and off otherwise, and a new run-time flag --wasm-tail-calls
which is off by default.
Reporter | ||
Comment 1•5 years ago
|
||
Updated•5 years ago
|
Updated•3 years ago
|
Comment 2•3 years ago
|
||
Standard ifdeffery, some simple tests, and some placeholder logic that
implements return_call in terms of call+return. It does run, and will
appear to be correct, given unbounded stack space.
Depends on D138879
Comment 3•3 years ago
|
||
Depends on D138898
Updated•3 years ago
|
Comment 4•3 years ago
|
||
Also more test cases.
Depends on D144158
Comment 5•3 years ago
|
||
Depends on D144398
Updated•3 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
Comment 6•3 years ago
|
||
Uncertain here still about whether more rawCaller / wasmCaller sites need to be handled
in the unwind logic.
Depends on D144399
Comment 7•3 years ago
|
||
Some of the code here belongs in the previous patch, because it cleans
up some mechanisms introduced there.
Comment 8•3 years ago
|
||
Friday night / pre-long weekend status: All my tests (included in the queue) pass on x86 and x64, but on arm64 there are assertions for test cases with return_call_indirect, so it looks like the unwind information is not right - not a surprise. Other platforms are not supported but arm, mips64, and loong64 will be like arm64, by and large, and there are very few platform dependencies for now.
The base rev is 0914de230f91.
Updated•3 years ago
|
Updated•3 years ago
|
Comment 9•3 years ago
|
||
Depends on D144946
Updated•3 years ago
|
Comment 10•3 years ago
|
||
Depends on D144399
Comment 11•3 years ago
|
||
Author of syntax and validation tests: Andy Wingo
Depends on D147199
Updated•3 years ago
|
Updated•3 years ago
|
Comment 12•3 years ago
•
|
||
The design document is "WebAssembly ABI 2022" and it outlines a strategy for implementing wasm tail calls without major compiler or ABI changes by executing the initial tail call in a chain of tail calls as a non-tail call (so that our same-instance-biased ABI that requires the caller to perform context restoration after return can continue to be used) and subsequent calls in the chain by collapsing the call frame after call setup and then jumping (thus minimizing compiler changes). Given that most calls take only register arguments this strategy is pretty good. More tweaks are possible for stack arguments; see the design document and comments in the code.
The patch queue on this bug implements the strategy for shared code and for the baseline compiler on all tier-1 platforms. The state of the queue is as follows:
- The base revision for the patches is df9a51c997b9
- While the patches are what they are so as to logically separate various ideas and pieces of functionality, it may sometimes be easier to view some changes through the entire patch stack, ie, apply the stack and hg diff -r <baserev>. This may in particular be true for the baseline compiler changes.
- All test cases pass in the baseline compiler with arbitrary tail-call depths and the baseline code is assumed to be working correctly.
- There are many optimizations possible in the baseline code, and these will make the generated code quite a bit tighter by removing redundancies. They are noted with TODO comments in the patch.
- The greatest uncertainty is around unwinding support. The new FP tag needs to be removed during unwinding, and that logic is a little tricky, especially around rawCaller(). See commit message on the unwinding patch. Further insight might be found in patches on bug 1742053, but this is not an easy thing.
- Ion code still needs to be implemented to correspond to the last baseline patch, and the "Ion sketches" patch is not complete, it really only is a sketch. See the design document for more information about this.
In the code, tail calls are variously called "tail calls" (this is what they are) and "return calls" (this is the wasm nomenclature). It would be meaningful to standardize on one or the other.Fixed this: it's return_call for the opcode name and in the opcode reader, "tail call" everywhere else.
Updated•3 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Comment 13•2 years ago
|
||
Updated•2 years ago
|
Assignee | ||
Comment 14•2 years ago
|
||
Depends on D166353
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Comment 15•2 years ago
|
||
Changes JS->Wasm stubs logic to expect SP being clobbered by Wasm function.
Changes baseline code to use FP to restore SP to pre-call value.
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Comment 16•2 years ago
|
||
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Assignee | ||
Comment 17•2 years ago
•
|
||
Short description of the current approach:
- The wasmCollapseFrame is introduced at masm level: the operation will remove caller/middle frame by moving parameters, instance slots. RA and FP will be used to transfer control to the callee via direct jump.
- The return call caller will prepare parameters on the stack, which will still include its own private frame + its parameters, and then proceed with wasmCollapseFrame. This will also guarantee no data will be written before current SP.
- Every wasm callsite with slow path will be mark with special carefully selected instruction. During collapse frame, when heap registers and realm is changing, this mark is checked.
- In case when the caller of the caller (C0) has a fast path (no heap registers and realm will be recovered), new small frame will be inserted before transferring control to the C0 for the short trampoline that will restore heap registers and realm.
- The stack depth will be changing, so for Ion calls it will be required to restore SP based on its FP.
- Some consideration has to be taken for the entry stubs (from interpreter or JIT) as well, the SP can be changed, so the entry stub shall anticipate that.
Assignee | ||
Comment 18•2 years ago
|
||
Updated•2 years ago
|
Assignee | ||
Comment 19•1 year ago
|
||
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Comment 20•1 year ago
|
||
Comment on attachment 9343294 [details]
Bug 1571998 - Track unwind info for tail calls. r?jseward,mstange
Revision D183269 was moved to bug 1846534. Setting attachment 9343294 [details] to obsolete.
Comment 21•1 year ago
|
||
Updated•1 year ago
|
Comment 22•1 year ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/8193b332f032
https://hg.mozilla.org/mozilla-central/rev/0bc528704114
https://hg.mozilla.org/mozilla-central/rev/4171d4a90a77
https://hg.mozilla.org/mozilla-central/rev/b819214797de
https://hg.mozilla.org/mozilla-central/rev/89a227f6c1ab
Assignee | ||
Updated•1 year ago
|
Comment 23•1 year ago
|
||
You can follow/review the documenting process for the Fx 121 release in these tasks:
Updated•11 months ago
|
Description
•