Stack switching: Infrastructure and runtime support#10388
Merged
alexcrichton merged 44 commits intoJun 4, 2025
Conversation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR is part of a series that adds support for the Wasm stack switching proposal. The explainer document for the proposal is here. There's a tracking issue describing the overall progress and limitations here: #10248
The draft PR #10177 contains the whole (initial) implementation of the proposal.
This PR contains all of the necessary infrastructure and runtime support. In other words, this contains the entire implementation, except for codegen. Tests are added at the end, after codegen has also been added in a follow-up PR.
This was developed together with @dhil.
General implementation notes
In Wasm, continuations are represented by values of type
(ref $ct), where$ctis a new composite type/heap type for continuations.In the implementation, these are represented by values of type
VMContObj. These are fat pointers, consisting of a sequence counter, and a pointer to aVMContRef. The latter type is used for the actual representation of continuations.The sequence counter part of
VMContObjs is used to check that every continuation value can only be used once.The
VMStoreContextis extended to contain a "stack chain": It indicates what stack we are currently executing on. Logically, this is a linked list of stacks, since each continuation has a parent field. The chain stored in theVMStoreContextalways ends with a value representing the initial stack. This is the stack we were on when entering Wasm, which will usually be the main stack.Memory Management
Currently, memory management is very basic: The
StoreOpaqueprovides a new method for allocation a newVMContRef, and keeps track of all continuations created this way. Continuations are never deallocated at the moment, meaning that they live until the store itself is deallocated.The stack memory used by each allocation (represented by type
ContinuationStack) is alwaysmmap-ed, with a guard page at the end. There is currently no support for growing stacks, or segmented stacks.Backtrace generation
The existing backtrace generation mechanism is extended to be fully aware of continuations: When generating backtraces, the entire chain of continuation is traversed, not just the stack frames of the currently active stack/continuation.
Entering/Exiting Wasm
Prior to this PR, there were two separate mechanisms that save and restore some state of the runtime when entering/exiting Wasm:
enter_wasmandexit_wasminfunc.rsCallThreadStatesaves and restores (ondrop) parts of theVMStoreContextThis PR consolidates these two mechanism, because it requires some additional state to be updated and restored on enter/exit:
the type
wasmtime::runtime::func::EntryStoreContextnow stores all of the required runtime state and ensures that it's restored when exiting Wasm.Tables
VMContObjis 2 pointers wide, the maximum size of an entry in a table doubles. As a result, this PR doubles the amount of virtual memory space occupied by the table pool (but the amount of pages actually used stays the same).