Split out of the post-#7019 matrix re-measurement. New red, attributed to #7019 by A/B on the same source and compiler. Sibling of #7022 (gc_stress), filed separately because the failure is intermittent here and deterministic there, and because it also reaches the default arm.
Symptom
test_gap_repsel_scalar_replaced_locals SIGSEGVs (exit 139) in 10 of 20 arms of scripts/gc_repsel_matrix.sh --arms all --pressure 8: default, evac_minor, force_evac, cons_scan_off, cons_scan_off_force, loop_polls, rep_i32_off, rep_ptr_numarray_off, rep_spec_abi_off, rep_int_valued_off.
It is the file added by #7007/#6968 for escape-analysis-scalarised object/array locals, whose per-field allocas belong to no HIR local — exactly the values a precise-roots collection cannot see unless the shadow-slot pass was taught about them.
It is intermittent, and the rate is config-dependent
Measured with PERRY_GC_HEAP_LIMIT=8 PERRY_GC_INCREMENTAL=0 PERRY_CONSERVATIVE_STACK_SCAN=off, five consecutive runs per binary, on the same host:
| binary (independent compiles of the same source) |
exit codes |
| compile A |
139 139 0 0 139 |
| compile B |
139 139 139 0 139 |
compile B, default arm config (PERRY_GC_HEAP_LIMIT=8 only) |
0 0 0 139 0 |
So do not read a single green run as a fix. On a second host (64 GB RAM, hence a larger derived heap budget) it did not reproduce in 15 runs across three configs at all — the derived budget_scaled thresholds move with device RAM, so the crash rate is machine-dependent.
Attribution — measured
Same source, same compiler, A/B through #7019's kill switch with PERRY_GC_MOVING_LOOP_POLLS=0 at both compile and run time, N=20, evacuating config:
| build |
SIGSEGV |
clean |
| default (#7019 on) |
11/20 |
9 |
PERRY_GC_MOVING_LOOP_POLLS=0 (#7019 off) |
0/20 |
20 |
#7018 reports that PERRY_GC_TRACE=1 SIGSEGVs on this same file under the evacuating arms, i.e. the instrument crashing. That is a different defect: every measurement above ran with no PERRY_GC_TRACE and no PERRY_GC_DIAG and still faults. The instrument is not required to reproduce it. (#7018 remains valid on its own terms and should be fixed separately — while it stands, the liveness instrument is unusable on the one row that most needs it.)
Note for whoever triages the matrix table
Because the rate is well below 100 %, the matrix's per-cell arm assignment for this row is not stable run-to-run: an arm that passes in one full run may fail in the next. Treat "which 10 arms" as indicative and the crash itself as the finding.
Environment: origin/main @ 4340bffc9, release build, macOS arm64, node 26.5.0 pinned.
Related: #7019, #7022, #7018, #6968/#7007 (the fix this file gates), #6981.
Split out of the post-#7019 matrix re-measurement. New red, attributed to #7019 by A/B on the same source and compiler. Sibling of #7022 (
gc_stress), filed separately because the failure is intermittent here and deterministic there, and because it also reaches thedefaultarm.Symptom
test_gap_repsel_scalar_replaced_localsSIGSEGVs (exit 139) in 10 of 20 arms ofscripts/gc_repsel_matrix.sh --arms all --pressure 8:default,evac_minor,force_evac,cons_scan_off,cons_scan_off_force,loop_polls,rep_i32_off,rep_ptr_numarray_off,rep_spec_abi_off,rep_int_valued_off.It is the file added by #7007/#6968 for escape-analysis-scalarised object/array locals, whose per-field allocas belong to no HIR local — exactly the values a precise-roots collection cannot see unless the shadow-slot pass was taught about them.
It is intermittent, and the rate is config-dependent
Measured with
PERRY_GC_HEAP_LIMIT=8 PERRY_GC_INCREMENTAL=0 PERRY_CONSERVATIVE_STACK_SCAN=off, five consecutive runs per binary, on the same host:139 139 0 0 139139 139 139 0 139defaultarm config (PERRY_GC_HEAP_LIMIT=8only)0 0 0 139 0So do not read a single green run as a fix. On a second host (64 GB RAM, hence a larger derived heap budget) it did not reproduce in 15 runs across three configs at all — the derived
budget_scaledthresholds move with device RAM, so the crash rate is machine-dependent.Attribution — measured
Same source, same compiler, A/B through #7019's kill switch with
PERRY_GC_MOVING_LOOP_POLLS=0at both compile and run time, N=20, evacuating config:PERRY_GC_MOVING_LOOP_POLLS=0(#7019 off)It is not #7018
#7018 reports that
PERRY_GC_TRACE=1SIGSEGVs on this same file under the evacuating arms, i.e. the instrument crashing. That is a different defect: every measurement above ran with noPERRY_GC_TRACEand noPERRY_GC_DIAGand still faults. The instrument is not required to reproduce it. (#7018 remains valid on its own terms and should be fixed separately — while it stands, the liveness instrument is unusable on the one row that most needs it.)Note for whoever triages the matrix table
Because the rate is well below 100 %, the matrix's per-cell arm assignment for this row is not stable run-to-run: an arm that passes in one full run may fail in the next. Treat "which 10 arms" as indicative and the crash itself as the finding.
Environment:
origin/main@4340bffc9, release build, macOS arm64, node 26.5.0 pinned.Related: #7019, #7022, #7018, #6968/#7007 (the fix this file gates), #6981.