The native stack-map scanner on exp/stackmap-viability is Mach-O-only: loaded_stack_map_section() returns None off macOS (crates/perry-runtime/src/gc/roots/stack_maps.rs), so the statepoint backend cannot execute on Linux at all. This blocks two things established during the 2026-07-31/08-01 campaign (see docs/statepoint-gc-experiment.md on the branch):
- CI coverage — every gate for the native-root modes runs only on developer Macs; CI is Linux x86-64 and can exercise none of it.
- Small-hardware numbers — Apple silicon has no unprivileged instruction counter, so all quiet-host figures are wall-clock. The Pi 5
perf stat discipline the repsel campaign uses (0.02% noise floor) needs the scanner to run on ELF. The shadow stack's cost profile is workload- and microarchitecture-dependent (measured 0.1% on numeric loops vs +26.7% instructions on activation-heavy code), so the M1 tie does not automatically transfer to narrow cores.
Design notes from the branch:
- Section discovery: ELF gives it away cheaper than Mach-O — reference
__start___llvm_stackmaps / __stop___llvm_stackmaps linker-provided symbols instead of walking load commands. The v3 parser and the concatenated-sub-map walk are platform-independent already.
- Frame chain: generated functions already carry
"frame-pointer"="non-leaf" in native-root modes. The Rust runtime side needs -Cforce-frame-pointers=yes on Linux (default on aarch64-apple only). x86-64 additionally changes the chain layout ([rbp] pair, DWARF regs 6/7 vs 29/31) and the SP = FP + 16 − stack_size reconstruction used for SP-relative statepoint spills must be re-derived for the x86-64 frame layout — do not port the constant.
- Walker:
match_records and the verify mode (PERRY_STACKMAP_WALKER=verify, both walkers must visit identical slot sets) port as-is and are the acceptance gate: 8 gc-ratchet probes × forced evacuation × verify-walker, byte-matched to the pinned Node oracle, on Linux aarch64 (Pi) and x86-64 (CI).
Non-goal: changing any default. The scanner stays research-mode; this issue is about making the existing gates executable on the platforms Perry actually ships to.
The native stack-map scanner on
exp/stackmap-viabilityis Mach-O-only:loaded_stack_map_section()returnsNoneoff macOS (crates/perry-runtime/src/gc/roots/stack_maps.rs), so the statepoint backend cannot execute on Linux at all. This blocks two things established during the 2026-07-31/08-01 campaign (seedocs/statepoint-gc-experiment.mdon the branch):perf statdiscipline the repsel campaign uses (0.02% noise floor) needs the scanner to run on ELF. The shadow stack's cost profile is workload- and microarchitecture-dependent (measured 0.1% on numeric loops vs +26.7% instructions on activation-heavy code), so the M1 tie does not automatically transfer to narrow cores.Design notes from the branch:
__start___llvm_stackmaps/__stop___llvm_stackmapslinker-provided symbols instead of walking load commands. The v3 parser and the concatenated-sub-map walk are platform-independent already."frame-pointer"="non-leaf"in native-root modes. The Rust runtime side needs-Cforce-frame-pointers=yeson Linux (default on aarch64-apple only). x86-64 additionally changes the chain layout ([rbp] pair, DWARF regs 6/7 vs 29/31) and theSP = FP + 16 − stack_sizereconstruction used for SP-relative statepoint spills must be re-derived for the x86-64 frame layout — do not port the constant.match_recordsand the verify mode (PERRY_STACKMAP_WALKER=verify, both walkers must visit identical slot sets) port as-is and are the acceptance gate: 8 gc-ratchet probes × forced evacuation × verify-walker, byte-matched to the pinned Node oracle, on Linux aarch64 (Pi) and x86-64 (CI).Non-goal: changing any default. The scanner stays research-mode; this issue is about making the existing gates executable on the platforms Perry actually ships to.