Observation from auditing #7602, needs a diagnosis
The prescribed recipe for exercising a barrier/rooting change on a compute-only
workload — compile with PERRY_GC_MOVING_LOOP_POLLS=1, run with
PERRY_GC_ZEAL=1 PERRY_GC_PROTECT_FROMSPACE=1 PERRY_GC_DIAG=1 — performed
zero copying minors for me on current main-family binaries (v0.5.1340/41,
perry-dev profile, macOS arm64, default PERRY_RS4GC):
- Workloads:
gc-handoff/bench/push_cls.ts, churn_alloc.ts, retain.ts.
- Polls verified present in the emitted IR (
js_gc_loop_safepoint × 3 in
push_cls), so the compile-time half was live.
- Zero
[gc-fromspace-protect] … retired_set= lines and zero [gc-copy-minor]
lines across all three; outputs matched the unzealed runs.
Per CLAUDE.md, zeal bypasses the pending-flag and the budgeted-due test but not
the entry guards — so either an entry guard (in-alloc, suppressed, FFI zone,
root-lock depth) is persistently true at every back-edge poll on these
workloads, or copying-minor eligibility fails under the statepoint lowering
here, or something else. I did not diagnose further; the #7602 audit had
stronger direct evidence (bit-identical remembered-set counters), so nothing
rests on this.
Why it deserves a look anyway: #7602's own validation cites "110
mode=ProtectPages retired_set=#N sets" — presumably on a workload shape with
event-loop boundaries — and CLAUDE.md's instrument table says to check
retired_set=#N is printed and that zeal_forced_collections() is nonzero.
If the recipe silently arms-but-never-fires on compute-only benches, every
green "ran clean under zeal" claim on such a bench is vacuous — the exact
instrument-liveness failure (#7154 family, CLAUDE.md gate hazard 4) these knobs
exist to prevent. The fix may be as small as a loud
[gc-zeal] forced_collections=0 — this run exercised NOTHING line at exit when
zeal is on and the counter is zero, which converts the vacuous green into a
visible one.
Repro:
PERRY_NO_AUTO_OPTIMIZE=1 PERRY_GC_MOVING_LOOP_POLLS=1 target/…/perry compile gc-handoff/bench/push_cls.ts -o /tmp/p
PERRY_GC_MOVING_LOOP_POLLS=1 PERRY_GC_ZEAL=1 PERRY_GC_PROTECT_FROMSPACE=1 PERRY_GC_DIAG=1 /tmp/p
# expected: retired_set lines; observed: none, and no [gc-copy-minor] lines
Observation from auditing #7602, needs a diagnosis
The prescribed recipe for exercising a barrier/rooting change on a compute-only
workload — compile with
PERRY_GC_MOVING_LOOP_POLLS=1, run withPERRY_GC_ZEAL=1 PERRY_GC_PROTECT_FROMSPACE=1 PERRY_GC_DIAG=1— performedzero copying minors for me on current
main-family binaries (v0.5.1340/41,perry-dev profile, macOS arm64, default
PERRY_RS4GC):gc-handoff/bench/push_cls.ts,churn_alloc.ts,retain.ts.js_gc_loop_safepoint× 3 inpush_cls), so the compile-time half was live.[gc-fromspace-protect] … retired_set=lines and zero[gc-copy-minor]lines across all three; outputs matched the unzealed runs.
Per CLAUDE.md, zeal bypasses the pending-flag and the budgeted-due test but not
the entry guards — so either an entry guard (in-alloc, suppressed, FFI zone,
root-lock depth) is persistently true at every back-edge poll on these
workloads, or copying-minor eligibility fails under the statepoint lowering
here, or something else. I did not diagnose further; the #7602 audit had
stronger direct evidence (bit-identical remembered-set counters), so nothing
rests on this.
Why it deserves a look anyway: #7602's own validation cites "110
mode=ProtectPages retired_set=#Nsets" — presumably on a workload shape withevent-loop boundaries — and CLAUDE.md's instrument table says to check
retired_set=#Nis printed and thatzeal_forced_collections()is nonzero.If the recipe silently arms-but-never-fires on compute-only benches, every
green "ran clean under zeal" claim on such a bench is vacuous — the exact
instrument-liveness failure (#7154 family, CLAUDE.md gate hazard 4) these knobs
exist to prevent. The fix may be as small as a loud
[gc-zeal] forced_collections=0 — this run exercised NOTHINGline at exit whenzeal is on and the counter is zero, which converts the vacuous green into a
visible one.
Repro: