You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
native-roots-aarch64 cannot pass on current main. Four of its steps run 09_try_catch_roots through the explicit statepoint bridge, and since #7330
that module refuses to compile — by design.
Nobody has seen it because GitHub's queue has not started a gc-native-roots
job in hours; every run on main and on open PRs is sitting in queued.
Reproduced locally at e98dfdb25
macOS/aarch64, cargo build --profile perry-dev -p perry -p perry-runtime-static -p perry-stdlib-static with the workflow's own RUSTFLAGS:
01_nursery_churn: ok 05_closure_capture: ok
02_survivor_promotion: ok 06_string_retention: ok
03_cross_gen_writes: ok 07_array_grow_evacuate: ok
04_dead_after_deep_stack: ok 08_map_set_sidetables: ok
09_try_catch_roots: COMPILE FAILED
statepoint forced-evacuation matrix: 8/9
thread 'perry-main' panicked at crates/perry-codegen/src/function/precise_roots.rs:722:17:
perry: native-root lowering cannot yet express a safepoint on an `invoke` —
`<indirect-or-unsupported>` in @perry_fn__09_try_catch_roots_ts__roundTrip has 1
live root(s) across it. … PERRY_RS4GC=1 handles invokes, but needs
PERRY_LLVM_CLANG pointing at a version-matched LLVM 22 …
Same result on aarch64-unknown-linux-gnu, so it is not host-specific.
The steps that break
All are in native-roots-aarch64, all use set -euo pipefail, so each dies at
the perry invocation:
Probe matrix, statepoint mode, forced evacuation — globs *.ts and
asserts pass == total; total is derived from the glob (9) precisely so it
cannot go stale, so it can only be satisfied by 09 compiling.
Safepoint-only contract changes codegen (differential) — globs *.ts
and runs --statepoint-report=json on each.
Probe matrix, safepoint-only contract in strict mode — globs *.ts.
Probe matrix under both non-default walkers — globs *.ts.
And one more that is not a glob:
Root-pressure report fails closed (--statepoint-report) hardcodes probe=benchmarks/gc_ratchet/probes/09_try_catch_roots.ts. That step exists
to assert plain_stack_maps == 0 and statepoint_fallbacks == 0, and it now
cannot run at all.
native-roots-rs4gc-aarch64 is unaffected — RS4GC handles invokes.
Why this is awkward rather than obvious
09_try_catch_roots was added by #7314because nothing in the suite contained
a try at all — 0 of 8 probes. Dropping it from the explicit-bridge matrix
gives that coverage straight back up, and #7330's own changelog is explicit that
"this leaves no working statepoint path for try-carrying code on a default
toolchain".
So the options are not equal:
Assert the refusal (the statepoints-refuse-x86 pattern): the bridge must
refuse 09 with that message, and 09 must still pass under RS4GC. Keeps the
gate red if the refusal ever silently becomes a rootless binary. Cheapest, and
it does not pretend the coverage exists.
Skip 09 in the bridge arm. Same effect on CI, but nothing then notices if
the refusal regresses.
Teach the bridge to form a statepoint from an invoke — the statepoint
becomes an invoke, with gc.result and the relocates in the normal successor. fix(gc): the statepoint bridge must refuse an invoke it cannot root (#7327) #7330 calls this "real work"; it is also the only option that restores the
coverage rather than documenting its absence.
I have deliberately not reshaped the gate, since which of these is right is a
call about how long try-carrying code stays uncovered.
Note on the fifth step
Whatever is chosen, step 5's report probe has to move to a module the bridge can
compile, or its assertions are simply not running — which is CLAUDE.md's fourth
failure mode (the gate runs, its subject never did).
native-roots-aarch64cannot pass on currentmain. Four of its steps run09_try_catch_rootsthrough the explicit statepoint bridge, and since #7330that module refuses to compile — by design.
Nobody has seen it because GitHub's queue has not started a
gc-native-rootsjob in hours; every run on
mainand on open PRs is sitting inqueued.Reproduced locally at
e98dfdb25macOS/aarch64,
cargo build --profile perry-dev -p perry -p perry-runtime-static -p perry-stdlib-staticwith the workflow's ownRUSTFLAGS:Same result on
aarch64-unknown-linux-gnu, so it is not host-specific.The steps that break
All are in
native-roots-aarch64, all useset -euo pipefail, so each dies atthe
perryinvocation:Probe matrix, statepoint mode, forced evacuation— globs*.tsandasserts
pass == total; total is derived from the glob (9) precisely so itcannot go stale, so it can only be satisfied by 09 compiling.
Safepoint-only contract changes codegen (differential)— globs*.tsand runs
--statepoint-report=jsonon each.Probe matrix, safepoint-only contract in strict mode— globs*.ts.Probe matrix under both non-default walkers— globs*.ts.And one more that is not a glob:
Root-pressure report fails closed (--statepoint-report)hardcodesprobe=benchmarks/gc_ratchet/probes/09_try_catch_roots.ts. That step existsto assert
plain_stack_maps == 0andstatepoint_fallbacks == 0, and it nowcannot run at all.
native-roots-rs4gc-aarch64is unaffected — RS4GC handles invokes.Why this is awkward rather than obvious
09_try_catch_rootswas added by #7314 because nothing in the suite containeda
tryat all — 0 of 8 probes. Dropping it from the explicit-bridge matrixgives that coverage straight back up, and #7330's own changelog is explicit that
"this leaves no working statepoint path for try-carrying code on a default
toolchain".
So the options are not equal:
statepoints-refuse-x86pattern): the bridge mustrefuse 09 with that message, and 09 must still pass under RS4GC. Keeps the
gate red if the refusal ever silently becomes a rootless binary. Cheapest, and
it does not pretend the coverage exists.
the refusal regresses.
invoke— the statepointbecomes an invoke, with
gc.resultand the relocates in the normal successor.fix(gc): the statepoint bridge must refuse an invoke it cannot root (#7327) #7330 calls this "real work"; it is also the only option that restores the
coverage rather than documenting its absence.
I have deliberately not reshaped the gate, since which of these is right is a
call about how long try-carrying code stays uncovered.
Note on the fifth step
Whatever is chosen, step 5's report probe has to move to a module the bridge can
compile, or its assertions are simply not running — which is CLAUDE.md's fourth
failure mode (the gate runs, its subject never did).