-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exit through Cranelift-generated trampolines for builtins #8152
Exit through Cranelift-generated trampolines for builtins #8152
Conversation
I'll note that I'm opening this up as a draft because Winch doesn't work yet. I'll need to update invocation of those libcalls in addition to updating how trampolines are required. I plan on waiting until #8109 lands to fully implement that though to avoid implementing this new trampoline in Winch. |
Subscribe to Label Action
This issue or pull request has been labeled: "wasmtime:api", "winch"
Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Excited to remove the last vestiges of hand-written asm.
9735d55
to
2dd385c
Compare
2dd385c
to
fa18c36
Compare
3810ab5
to
f08e292
Compare
Ok various prerequisites are now landed on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Winch pieces look great to me, thanks!
Local(FuncIndex), | ||
/// Imported function. | ||
Import(&'a CalleeInfo), | ||
Import(FuncIndex), | ||
/// Function reference. | ||
FuncRef(&'a ABISig), | ||
FuncRef(TypeIndex), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome!
This commit changes how builtin functions in Wasmtime (think `memory.grow`) are implemented. These functions are required to exit through some manner of trampoline to handle runtime requirements for backtracing right now. Currently this is done via inline assembly for each architecture (or external assembly for s390x). This is a bit unfortunate as it's a lot of hand-coding and making sure everything is right, and it's not easy to update as it's multiple platforms to update. The change in this commit is to instead use Cranelift-generated trampolines for this purpose instead. The path for invoking a builtin function now looks like: * Wasm code calls a statically known symbol for each builtin. * The statically known symbol will perform exit trampoline duties (e.g. pc/fp/etc) and then load a function pointer to the host implementation. * The host implementation is invoked and then proceeds as usual. The main new piece for this PR is that all wasm modules and functions are compiled in parallel but an output of this compilation phase is what builtin functions are required. All builtin functions are then unioned together into one set and then anything required is generated just afterwards. That means that only one builtin-trampoline per-module is generated per-builtin. This work is inspired by bytecodealliance#8135 and my own personal desire to have as much about our ABI details flowing through Cranelift as we can. This in theory makes it more flexible to deal with future improvements to our ABI. prtest:full
This commit refactors the Winch compiler to use the new trampolines for all Wasmtime builtins created in the previous commits. This required a fair bit of refactoring to handle plumbing through a new kind of relocation and function call. Winch's `FuncEnv` now contains a `PrimaryMap` from `UserExternalNameRef` to `UserExternalName`. This is because there's now more than one kind of name than just wasm function relocations, so the raw index space of `UserExternalNameRef` is no longer applicable. This required threading `FuncEnv` to more locations along with some refactorings to ensure that lifetimes work out ok. The `CompiledFunction` no longer stores a trait object of how to map name refs to names and now directly has a `Primarymap`. This also means that Winch's return value from its `TargetIsa` is a `CompiledFunction` as opposed to the previous just-a-`MachBuffer` so it can also package up all the relocation information. This ends up having `winch-codegen` depend on `wasmtime-cranelift-shared` as a new dependency.
f08e292
to
ed948fa
Compare
…liance#8152) * Exit through Cranelift-generated trampolines for builtins This commit changes how builtin functions in Wasmtime (think `memory.grow`) are implemented. These functions are required to exit through some manner of trampoline to handle runtime requirements for backtracing right now. Currently this is done via inline assembly for each architecture (or external assembly for s390x). This is a bit unfortunate as it's a lot of hand-coding and making sure everything is right, and it's not easy to update as it's multiple platforms to update. The change in this commit is to instead use Cranelift-generated trampolines for this purpose instead. The path for invoking a builtin function now looks like: * Wasm code calls a statically known symbol for each builtin. * The statically known symbol will perform exit trampoline duties (e.g. pc/fp/etc) and then load a function pointer to the host implementation. * The host implementation is invoked and then proceeds as usual. The main new piece for this PR is that all wasm modules and functions are compiled in parallel but an output of this compilation phase is what builtin functions are required. All builtin functions are then unioned together into one set and then anything required is generated just afterwards. That means that only one builtin-trampoline per-module is generated per-builtin. This work is inspired by bytecodealliance#8135 and my own personal desire to have as much about our ABI details flowing through Cranelift as we can. This in theory makes it more flexible to deal with future improvements to our ABI. prtest:full * Fix some build issues * Update winch test expectations * Update Winch to use new builtin shims. This commit refactors the Winch compiler to use the new trampolines for all Wasmtime builtins created in the previous commits. This required a fair bit of refactoring to handle plumbing through a new kind of relocation and function call. Winch's `FuncEnv` now contains a `PrimaryMap` from `UserExternalNameRef` to `UserExternalName`. This is because there's now more than one kind of name than just wasm function relocations, so the raw index space of `UserExternalNameRef` is no longer applicable. This required threading `FuncEnv` to more locations along with some refactorings to ensure that lifetimes work out ok. The `CompiledFunction` no longer stores a trait object of how to map name refs to names and now directly has a `Primarymap`. This also means that Winch's return value from its `TargetIsa` is a `CompiledFunction` as opposed to the previous just-a-`MachBuffer` so it can also package up all the relocation information. This ends up having `winch-codegen` depend on `wasmtime-cranelift-shared` as a new dependency. * Review feedback
This commit changes how builtin functions in Wasmtime (think
memory.grow
) are implemented. These functions are required to exit through some manner of trampoline to handle runtime requirements for backtracing right now. Currently this is done via inline assembly for each architecture (or external assembly for s390x). This is a bit unfortunate as it's a lot of hand-coding and making sure everything is right, and it's not easy to update as it's multiple platforms to update.The change in this commit is to instead use Cranelift-generated trampolines for this purpose instead. The path for invoking a builtin function now looks like:
The main new piece for this PR is that all wasm modules and functions are compiled in parallel but an output of this compilation phase is what builtin functions are required. All builtin functions are then unioned together into one set and then anything required is generated just afterwards. That means that only one builtin-trampoline per-module is generated per-builtin.
This work is inspired by #8135 and my own personal desire to have as much about our ABI details flowing through Cranelift as we can. This in theory makes it more flexible to deal with future improvements to our ABI.