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
{{ message }}
Repository navigation
gc: PERRY_GC_VERIFY_EVACUATION reports clean on a demonstrable missing rewrite (verifier only self-checks the rewrite pass's own enumeration) #7035
Split out of the #7022 investigation. This is a defect in a verification tool, not in the collector, and it is worth tracking on its own because it is the second of our three GC verification instruments with a known hole.
Symptom
PERRY_GC_VERIFY_EVACUATION=1 is documented to "panic if any mutable live slot still points at a forwarded nursery object after an evacuation/rewrite cycle" (CLAUDE.md). On the #7022 reproducer it never fires — the process SIGSEGVs with the verifier enabled exactly as it does without it:
$ env PERRY_GC_HEAP_LIMIT=8 PERRY_GC_INCREMENTAL=0 PERRY_CONSERVATIVE_STACK_SCAN=off \
PERRY_GC_SCAVENGE_NURSERY_MB=2 PERRY_GC_VERIFY_EVACUATION=1 ./c_pushobj
139 139 139 139 139 # SIGSEGV, not a verifier panic
This is on a case where a missing rewrite is demonstrable: gating off the single set_forwarding_address call in js_array_grow takes the same binary from 139×5 to 0×5 byte-exact (see #7022). So there is a stale reference surviving the rewrite pass, and the verifier that exists to catch exactly that reports clean.
Measured on origin/main @ 775e29193, release, macOS arm64.
Why this matters
The verifier's clean result was, for me, a genuine misdirection: I read "verifier clean" as evidence against a missing rewrite and spent several bisect cycles on other hypotheses (freed arena blocks, malloc-object sweep, out-of-bounds block writes) before the ablation evidence forced me back. A verification tool that silently under-reports is worse than one that is absent, because it is read as a negative result.
The same argument applies to the moved counter in scripts/gc_repsel_matrix.sh (#7025) and to PERRY_GC_TRACE (#7018).
Suspected shape of the hole
verify::verify_slot / try_rewrite_value walk the same mutable root slot surfaces the rewrite pass walks (visit_shadow_stack_root_slots + visit_global_root_slots, plus the registered side-table scanners). Anything that holds a heap address outside those surfaces — a usize-keyed side table, a cached base address, a raw header pointer captured by a runtime helper — is invisible to the rewrite pass and equally invisible to the verifier, because both derive from the same enumeration. The verifier therefore cannot, by construction, detect a holder that the rewrite pass does not already know about.
If that is the mechanism, the verifier is only checking that the rewrite pass agreed with itself.
What would close it
A verification mode that does not depend on the rewrite pass's own enumeration — e.g. after copying_reset_from_spaces_and_flip would have run, walk the whole heap (arena census + malloc registry) and assert that no live object contains a word that decodes to a from-space address, reporting the owning object's obj_type and offset. That is O(heap) and debug-only, but it is independent evidence rather than a self-consistency check.
Related: #7018 (PERRY_GC_TRACE=1 SIGSEGVs under evacuating arms on test_gap_repsel_scalar_replaced_locals — the instrument crashing on the row that most needs it), #7025 (matrix moved counter sums C4b mark-sweep evacuation with the copying minor, so a move arm can read green with zero scavenged objects), #7022 (the collector defect this hole hid).
Fixed by #7041, which added PERRY_GC_FROMSPACE_SCAN — a whole-heap scan independent of the rewrite pass's own enumeration, which is exactly what this issue asked for. gc/fromspace_scan.rs has been maintained since (#7043, #7182, #7196).
Activity
gc: whole-heap from-space scan, independent of the rewrite pass (#7035)
gc: whole-heap from-space scan, independent of the rewrite pass (#7035)…
docs: point the census at its own tracking issue (#7106, not #7035)
test(repsel): promotion census with a ratcheted, falsifiable floor (#…
proggeramlug commentedon Aug 5, 2026
Fixed by #7041, which added
PERRY_GC_FROMSPACE_SCAN— a whole-heap scan independent of the rewrite pass's own enumeration, which is exactly what this issue asked for.gc/fromspace_scan.rshas been maintained since (#7043, #7182, #7196).