fix(ext/ffi): match V8 stack-arg layout in turbocall trampoline on Apple silicon#34561
Merged
Conversation
…ple silicon V8's fast API on arm64 always packs stack arguments into 8-byte slots (AAPCS64 layout), but Apple silicon's ABI uses natural alignment (e.g. 4-byte slots for i32/f32). Cranelift's default convention on aarch64-apple-darwin is `AppleAarch64`, so the trampoline wrapper that V8 invokes would read stack args at the wrong offsets and pick up garbage as soon as a fast-call argument spilled past the registers. Force the wrapper's calling convention to `SystemV` (AAPCS64) on aarch64-apple-darwin so the wrapper reads stack args at the same 8-byte-aligned offsets V8 writes them. The target signature used to call the user's C function from inside the wrapper still uses the platform default, so the user function is invoked per its native ABI. V8 still gates fast-API dispatch with `ArgumentCount() > 8` on Apple silicon (`fast-api-calls.cc`), so this change has no observable effect until that upstream guard is relaxed (crbug.com/v8/13171), but it is the Deno-side half of the fix and keeps the trampoline correct for the day V8 lifts the restriction. Closes denoland/orchid#321 Co-Authored-By: Divy Srivastava <[email protected]>
littledivy
pushed a commit
to crowlKats/deno
that referenced
this pull request
Jun 10, 2026
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.
Summary
V8's fast API on arm64 always packs stack arguments into 8-byte slots (AAPCS64 layout), but Apple silicon's ABI uses natural alignment (e.g. 4-byte slots for
i32/f32). Cranelift's default calling convention onaarch64-apple-darwinisAppleAarch64, so the turbocall wrapper that V8 invokes would read stack args at the wrong offsets and pick up garbage as soon as a fast-call argument spilled past the registers.This PR forces the wrapper's calling convention to
SystemV(AAPCS64) onaarch64-apple-darwin, so the wrapper reads stack args at the same 8-byte-aligned offsets V8 writes them. The target signature used to call the user's C function from inside the wrapper still uses the platform default (AppleAarch64), so the user function continues to be invoked per its native ABI.Why no observable change yet
V8 currently short-circuits fast-API dispatch on Apple silicon with
c_signature->ArgumentCount() > 8(v8/src/compiler/fast-api-calls.cc::CanOptimizeFastSignature) as a workaround for the same alignment bug. With the V8 guard in place, the trampoline never gets a stack-arg call on Apple silicon today, so behaviour is unchanged. This change is the Deno-side half of the fix and keeps the trampoline correct for the day V8 relaxes that restriction.Upstream V8 issue: https://crbug.com/v8/13171 (chromium:42203110)
Original Deno issue: #15785
The two skipped fast-call assertions for
log_many_parameters/add_many_u16intests/ffi/testdata/test.jsremain gated ondarwin+arm64, since V8 still refuses to dispatch the fast path there; the comments are updated to note Deno's side is now correct and the skip can be removed once V8 lifts its guard.Closes denoland/divybot#321
Test plan
cargo check -p deno_ffibuilds clean (verified locally onx86_64-linux).cargo testonaarch64-apple-darwincontinues to pass (skipped fast-call cases stay skipped).cfg!(all(target_os = "macos", target_arch = "aarch64")).