Open Bug 1572400 Opened 2 years ago Updated 1 year ago

Change WebAssembly calling convention to have callee clean up stack args

Categories

(Core :: Javascript: WebAssembly, task, P3)

task

Tracking

()

People

(Reporter: wingo, Assigned: wingo)

References

(Blocks 1 open bug)

Details

Attachments

(1 obsolete file)

To implement the wasm tail-calls proposal, we need to make a change to the calling convention that we use for compiled WebAssembly functions.

Specifically, we need to change to require WebAssembly functions to clean up their stack arguments.

Consider, let's say function A calls function B with zero stack arguments. If B then tail-calls C with one stack argument, A can't know that the return will require A to clean up after a stack argument it wasn't expecting. Since we can't enumerate the set of functions that may be tail-callable, all WebAssembly functions should change to clean up after their stack arguments (if any).

This change should land before work starts on tail-call codegen, and can proceed in parallel.

Cranelift will also need to support tail calls. See https://github.com/CraneStation/cranelift/issues/616.

We have another couple pending issues for the calling conventions too. IIRC we want to implement changes to support call-indirect and funcref better, and we also have pending changes for multi-value support (not so much arguments as return values, of course, but ABI still). Callee-saves would be nice on ARM64 esp but should probably not be more of a consideration at this stage than being aware that it must happen at some point in the future.

When we change the ABI we must change it in all three compilers on all four tier-1 architectures at the same time, and ideally not mess things up too much for mips/mips64. Also note Cranelift has risc-v support and quasi-working x86-32 support, which it would be nice not to break too much.

In preparation for tail calls, this change makes it so that the callee
is responsible for cleaning any stack args. The callee will pop the
number of bytes corresponding to its stack args for the native ABI,
rounded up to the WasmStackAlignment. Callers have to align their
stacks to WasmStackAlignment before a call.

Patch in phab appears to be passing tests now. It should be architecture-independent AFAIU. It still needs a cranelift implementation though.

I talked with Luke today and he notes that for multi-value calls, the implication of this approach would be that the callee cleans the stack args (if any), except expecting any stack return values to have space reserved. The caller expects thus to have a return with the stack args popped and the stack returns initialized. Probably space for stack returns is higher on the stack than the args.

Also, another option instead of "callee pops SP to expected position" would be "caller restores SP to FP plus a constant". Given that we seem to be resigned to having a frame pointer, this might be simpler; dunno. I suppose there are more call sites than functions though, so simply from a code size point of view, "callee pops" might be better.

Assignee: nobody → wingo

Given some of the unknowns about how best to implement/optimize the TlsData* saving/restoring (which may have implications to how stack adjustment work), and wanting to minimize ABI changes, I wonder if we should hold off on landing this callee-cleans-the-stack logic.

Priority: -- → P3
Attachment #9084660 - Attachment is obsolete: true
You need to log in before you can comment on or make changes to this bug.