Skip to content

ci: native-roots-aarch64 is red on main — #7330's invoke refusal makes 09_try_catch_roots uncompilable in five of its steps #7335

Description

@proggeramlug

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:

  1. 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.
  2. Safepoint-only contract changes codegen (differential) — globs *.ts
    and runs --statepoint-report=json on each.
  3. Probe matrix, safepoint-only contract in strict mode — globs *.ts.
  4. Probe matrix under both non-default walkers — globs *.ts.

And one more that is not a glob:

  1. 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 #7314 because 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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions