[Wasm RyuJit] EH, Unwind, and unwindable frames#127043
[Wasm RyuJit] EH, Unwind, and unwindable frames#127043AndyAyersMS merged 8 commits intodotnet:mainfrom
Conversation
Implement the codegen changes necessary for EH and unwind reporting and for making frames unwindable by the runtime: * Add a new phase that assigns Virtual IP ranges to each try, handler, and filter, and a distinct Virtual IP for each call. Call Virtual IPs lie within the range of their enclosing EH region. Region ranges lie within the range of their enclosing region. * Add codegen to the method to ensure the Virtual IP slot is at the bottom of the fixed part of the stack frame, and is updated before each call. * Adjust the localloc codegen so that for variable-sized frames there is a special marker at the bottom of the stack, and a pointer to the bottom of the fixed portion of the stack just above this. * Report unwind data to the host. For Wasm this is just the size of the fixed portion of the frame. * Report EH info to the host. For Wasm these are the Virtual IP ranges for the EH regions as noted above. * Change throw helpers so there is one per EH region (instead of one per EH handler region), so the throw helper calls have a well defined Virtual IP. * Catch funclets now return a value to the runtime, though not the actual resume IP (resume IPs are in a different "IP space" than the virtual IP, and are not meaningful except to codegen). We are currently somewhat generous in handing out Virtual IPs; likely we could compress their range a bit more. Still to do: * Use the Virtual IPs for GC reporting * Host side handling (in particular funclet extraction) * Runtime stack walking and EH processing.
|
FYI @dotnet/wasm-contrib See the revised unwind proposal here: #121651 (comment) |
There was a problem hiding this comment.
Pull request overview
This PR extends the CoreCLR JIT’s Wasm backend to support unwind reporting and EH region mapping using a “Virtual IP” scheme, laying groundwork for runtime stack walking/EH processing on Wasm.
Changes:
- Add a new Wasm JIT phase to assign Virtual IP ranges to EH regions and a distinct Virtual IP at each call site, and inject code to update the Virtual IP prior to calls.
- Track and report per-func (root + funclets) Wasm unwind info (currently: fixed frame size) and report EH clause data to the VM for Wasm.
- Update Wasm frame layout/codegen to place new unwind/EH-related slots at stable positions and adjust localloc handling to keep variable-sized frames unwindable.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/jit/unwindwasm.cpp | Implement Wasm unwind reservation/emission and track per-func frame size. |
| src/coreclr/jit/lclvars.cpp | Ensure Wasm VirtualIP/ResumeIP/FunctionIndex locals are allocated last in the frame layout; add frame diagrams. |
| src/coreclr/jit/jit.h | Include win64unwind.h on TARGET_WASM to get UNWIND_INFO definition. |
| src/coreclr/jit/flowgraph.cpp | Adjust throw helper placement logic for Wasm to allow try-region association. |
| src/coreclr/jit/fgwasm.h | Update Wasm successor enumeration to treat try-beg blocks as region entry points. |
| src/coreclr/jit/fgwasm.cpp | Add fgWasmVirtualIP phase: compute EH Virtual IP ranges, inject Virtual IP stores before calls, mark funcs needing unwindable frames. |
| src/coreclr/jit/compphases.h | Add PHASE_WASM_VIRTUAL_IP. |
| src/coreclr/jit/compmemkind.h | Add WasmEH allocator kind used for EH clause info storage. |
| src/coreclr/jit/compiler.h | Add Wasm-specific locals + per-func fields (frame size, unwindable flag) and store fgWasmEHInfo. |
| src/coreclr/jit/compiler.cpp | Schedule PHASE_WASM_VIRTUAL_IP after lowering and before FinalizeEH/RA. |
| src/coreclr/jit/codegenwasm.cpp | Record unwind stack allocation, create unwindable funclet prolog slots, adjust localloc unwind markers, return a value from catch funclets, and report EH clauses from precomputed data. |
| src/coreclr/jit/codegeninterface.h | Promote EHClauseInfo to a shared type. |
| src/coreclr/jit/codegencommon.cpp | Refactor EH reporting to a shared genReportEHClauses helper callable by Wasm codegen. |
| src/coreclr/jit/codegen.h | Declare genReportEHClauses. |
| src/coreclr/inc/win64unwind.h | Define a Wasm-specific UNWIND_INFO payload (FrameSize). |
| src/coreclr/inc/clrnt.h | Include win64unwind.h for Wasm unwind type definitions. |
kg
left a comment
There was a problem hiding this comment.
LGTM, but a second pair of eyes would be good
Emit just one Virtual IP update per (non-empty) block. Track whether funclets need unwindable frames in codegen. Simplfy the Wasm stack layout charts.
|
We are going to need to iterate a bit on the Virtual IP approach, but this at least gives us a plausible start and unblocks the work we need to do for funclet extraction and implementing unwiunding. Various factors/constraints:
|
|
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara |
|
/ba-g Wasm only JIT change, not testable in CI yet. |
Implement the codegen changes necessary for EH and unwind reporting and for making frames unwindable by the runtime:
We are currently somewhat generous in handing out Virtual IPs; likely we could compress their range a bit more.
Still to do: