Skip to content

gc: zeal + compiled loop polls performs zero copying minors on compute-only benches — green instrument runs may be vacuous #7604

Description

@proggeramlug

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

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