-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
winch: Overhaul the internal ABI #7974
winch: Overhaul the internal ABI #7974
Conversation
@@ -60,6 +64,84 @@ pub(super) enum ParamsOrReturns { | |||
Returns, | |||
} | |||
|
|||
/// Macro to get the pinned register holding the [VMContext]. | |||
macro_rules! vmctx { |
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.
This change is fairly large already, so I opted to just introduce this macro and use it in a couple of places that are updated by this change. My plan is to follow up with a general replace after landing this change (but I can do so here too if preferred).
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.
Overall looks great, thanks! Just a few nits below.
winch/codegen/src/frame/mod.rs
Outdated
/// # Panics | ||
/// This method panics if the index is not associated to a valid WebAssembly | ||
/// local. | ||
pub fn get_local_unchecked(&self, index: usize) -> &LocalSlot { |
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.
Rather than unchecked
, which to me implies lack of a bounds check or similar, can we name this in a way that indicates the index-space is shifted relative to above? E.g. perhaps the above get_local
becomes get_wasm_local
and get_local_unchecked
becomes get_raw_local
?
Alternately, avoid exposing get_local_unchecked
at all and have two separate methods get_callee_local()
/ get_caller_local()
?
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.
Thanks for the suggestion -- I ended up with get_frame_local
and get_wasm_local
to be able to distinguish one from another.
winch/codegen/src/trampoline.rs
Outdated
@@ -601,6 +528,9 @@ where | |||
callee_sig | |||
.params_without_retptr() | |||
.iter() | |||
// Skip the first two arguments, which are the callee and caller | |||
// VMContext pointers. | |||
.skip(2) |
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.
here and perhaps elsewhere, can we have a constant (maybe an associated constant of ContextArgs
) indicating how many args we expect? Basically it'd be nice to tie this to other definitions so that we don't miss it if we ever add, e.g., a third context arg.
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.
Good catch -- I introduced MAX_CONTEXT_ARGS
near the ContextArgs
definition, which is used in the trampoline. In the non-trampoline case (normal function calls), the expected number of context arguments is already parametrized through ContextArgs::len
Subscribe to Label Action
This issue or pull request has been labeled: "winch"
Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
d3326d3
to
9319c49
Compare
Oh bad rebase -- sorry about that. Fixing it now. |
This change overhauls Winch's ABI. This means that as part of this change, the default ABI now closely resembles Cranelift's ABI, particularly on the treatment of the VMContext. This change also fixes many wrong assumptions about trampolines, which are tied to how the previous ABI operated. The main motivation behind this change is: * To make it easier to integrate Winch-generated functions with Wasmtime * Fix fuzz bugs related to imports * Solidify the implementation regarding the usage of a pinned register to hold the VMContext value throughout the lifetime of a function. The previous implementation had the following characteristics, and wrong assumptions): * Assumed that nternal functions don't receive a caller or callee VMContexts as parameters. * Worked correctly in the following scenarios: * `Wasm -> Native`: since we can explicitly load the caller and callee `VMContext`, because we're calling a native import. * `(Native, Array) -> Wasm`: because the native signatures define a tuple of `VMContext` as arguments. * It didn't work in the following scenario: * `Wasm->Wasm`: When calling imports from another WebAssembly instance (via direct call or `call_indirect`. The previous implementation wrongly assumes that there should be a trampoline in this case, but there isn't. The code was generated by the same compiler, so the same ABI should be used in both functions, but it doesn't. This change introduces the following changes, which fix the previous assumptions and bugs: * All internal functions declare a two extra pointer-sized parameters, which will hold the callee and caller `VMContext`s * Use a pinned register that will be considered live through the lifetime of the function instead of pinning it at the trampoline level. The pinning explicitlly happens when entering the function body and no other assumptions are made from there on. * Introduce the concept of special `ContextArgs` for function calls. This enum holds metadata about which context arguments are needed depending on the callee. The previous implementation of introducing register values at arbitrary locations in the value stack conflicts with the stack ordering principle which states that older values must *always* precede newer values. So we can't insert a register, because if a spill happens the order of the values will be wrong. Finally, given that this change also enables the `imports.wast` test suite, it also includes a fix to `global.{get, set}` instructions which didn't account entirely for imported globals. Resolved conflicts Update Winch filetests
9319c49
to
cdbc516
Compare
… `get_local_unchecked`
This commit is a follow-up to bytecodealliance#7974. This commit makes use of the `vmctx!` macro across the compiler codebase
This commit is a follow-up to #7974. This commit makes use of the `vmctx!` macro across the compiler codebase
This change overhauls Winch's ABI. This means that as part of this change, the default ABI now closely resembles Cranelift's ABI, particularly on the treatment of the VMContext. This change also fixes many wrong assumptions about trampolines, which are tied to how the previous ABI operated.
The main motivation behind this change is:
The previous implementation had the following characteristics, and wrong assumptions:
Wasm -> Native
: since we can explicitly load the caller and calleeVMContext
, because we're calling a native import.(Native, Array) -> Wasm
: because the native signatures define a tuple ofVMContext
as arguments.Wasm -> Wasm
: When calling imports from another WebAssembly instance (via direct call orcall_indirect
. The previous implementation wrongly assumed that there should be a trampoline in this case, but there isn't. The code was generated by the same compiler, so the same ABI should be used in both functions.This change introduces the following changes, which fix the previous assumptions and bugs:
VMContext
sContextArgs
for function calls. This enum holds metadata about which context arguments are needed depending on the callee. The previous implementation of introducing register values at arbitrary locations in the value stack conflicts with the stack ordering principle which states that older values must always precede newer values. So we can't insert a register, because if a spill happens the order of the values will be wrong.Finally, given that this change also enables the
imports.wast
test suite, it also includes a fix toglobal.{get, set}
instructions which didn't account entirely for imported globals.