[wasm R2R] Align 8-byte stack locals and keep frames 16-aligned#129815
Merged
Conversation
8-byte locals were only 4-byte aligned on wasm, so JS interop reads through the 8-byte HEAP64/HEAPF64 views landed on the wrong word. Align >=8 byte locals to 8 and round the frame to STACK_ALIGN. Fixes dotnet#129802. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates CoreCLR JIT frame layout for WebAssembly targets to ensure (a) stack locals requiring 8-byte alignment are actually 8-byte aligned, and (b) the overall frame size stays aligned to STACK_ALIGN so alignment doesn’t drift across nested calls.
Changes:
- Enable the existing “align >=8-byte locals” padding logic for
TARGET_WASMinlvaAllocLocalAndSetVirtualOffset. - Implement
TARGET_WASMframe-size alignment inlvaAlignFrameby roundingcompLclFrameSizeup toSTACK_ALIGN(and reserving worst-case padding during non-final layout passes).
Member
Author
|
@pavelsavara I can't fully validate this, so give it a try if you can. @adamperlin PTAL |
Member
Contributor
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
pavelsavara
added a commit
to pavelsavara/runtime
that referenced
this pull request
Jun 25, 2026
… frames 16-aligned)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.

Fixes #129802.
Problem
On the WebAssembly CoreCLR + ReadyToRun (crossgen2-wasm) configuration, 64-bit
JS interop values (
long/BigInt,double,DateTime,Int52) were corruptedcrossing the managed↔JS boundary:
corrupted = (original & 0xFFFFFFFF) << 32. The JSside reads/writes these slots through the 8-byte
HEAP64/HEAPF64typed-array views(
addr >>> 3), which require 8-byte alignment; the marshaler buffer was landing at a4-mod-8address, so the view addressed the wrong word.Root cause
wasm is
TARGET_WASM32(4-byte pointers) and does not defineTARGET_64BIT, so:lvaAllocLocalAndSetVirtualOffsetwas gatedon
TARGET_64BITand compiled out, leaving 8-byte stack locals only 4-byte aligned.lvaAlignFramewas a no-op for wasm, so the frame size was only 4-byte aligned. Sincethe shadow stack pointer is threaded through calls (
calleeSP = callerSP - frameSize),a single
4-mod-8-sized frame drifts every deeper frame — and everystackalloc'dmarshaler buffer — out of 8-byte alignment.
Fix
TARGET_WASM.compLclFrameSizeup toSTACK_ALIGNinlvaAlignFramefor wasm so the shadowSP stays aligned across calls.
Validation
JitDumpof a method with the marshaler pattern (address-takenlong+stackalloc Span) confirms every 8-byte local now lands at an 8-aligned frame offsetand the frame size is a multiple of 16 (the
Pad … size=8events only fire from thenewly enabled code block).
JSImportBigInt/doubleecho repro passes on the interpreter (matching theissue's interpreter baseline).
A black-box R2R pass/fail is best covered by the existing
System.Runtime.InteropServices.JavaScript.UnitTestssuite on the coreclr-wasm-R2R lane.Note
This PR was generated with the assistance of GitHub Copilot and reviewed before posting.