Summary
test-files/test_gap_gc_spread_accessor_rooting.ts — the reproducer #7207 added for #7200 — still SIGSEGVs on current main (1679e22b4) when the collection is forced at the allocation point rather than at a loop safepoint.
#7207 verified that fix on the PERRY_GC_MOVING_LOOP_POLLS=1 route, where it is clean 5/5. It is not clean on the evac_minor arm env.
Reproduction
$ export PERRY_RUNTIME_DIR=<main build>/release PERRY_NO_AUTO_OPTIMIZE=1
$ perry test-files/test_gap_gc_spread_accessor_rooting.ts -o /tmp/spread # no compile-time env
$ PERRY_GC_HEAP_LIMIT=8 PERRY_GC_INCREMENTAL=0 PERRY_CONSERVATIVE_STACK_SCAN=off /tmp/spread
exit=139, no output
Compared against a build of PR #7216 on the same host under identical conditions: byte-identical, exit=139, output md5 d41d8cd9… on both. So this is main's behaviour, not #7216's, and #7216's A/B is what surfaced it.
test_gap_gc_static_block_this_rooting (the #7201 reproducer) reports bad 1 under the same env, also identically on both arms — the same story one notch quieter.
Why the two routes differ
gc_repsel_matrix.sh's own header states it: default and the polls route "relocate at a real safepoint (the JS stack has unwound, roots are precise by construction)", whereas the %E% arms "force it at the register-imprecise allocation point". #7207's fixes — the RuntimeHandleScope rooting inside js_object_assign_one and the codegen accumulator root — were reasoned about and verified against the safepoint route. An allocation-point collection inside the helper is a different window: it can fire between any two of the helper's own allocations, including ones inside object_assign_set_string_key's interning and keys-array growth, where #7207 re-reads its handles only at the top of each key iteration.
Caveat, stated because it changes what to do first
Both observations were made while a second agent's build was loading the box. In #7207's own idle --arms all --pressure 8 run this cell was PASS on evac_minor. So the failure is load-dependent, and the first step is an idle reproduction, not a fix — a load-dependent SIGSEGV that disappears when idle is still a real defect (it is the classic #7154 timing signature), but the mechanism should be pinned before anyone changes rooting code on the strength of it.
If it reproduces idle, the natural next instrument is #7196's PERRY_GC_PROTECT_FROMSPACE quarantine, which is built to fault at the stale dereference rather than one cycle later.
Why it matters
This is a residual of #7200, which #7207 reported as closed. It does not reopen the loop_polls result — that remains clean 5/5 — but it means the #7161 revert readiness statement should count the allocation-point route as unverified for the object-spread path, not merely the sites #7208/#7209/#7210 name.
Refs #7207, #7200, #7154, #7161, #7216, #7196.
Summary
test-files/test_gap_gc_spread_accessor_rooting.ts— the reproducer #7207 added for #7200 — still SIGSEGVs on currentmain(1679e22b4) when the collection is forced at the allocation point rather than at a loop safepoint.#7207 verified that fix on the
PERRY_GC_MOVING_LOOP_POLLS=1route, where it is clean 5/5. It is not clean on theevac_minorarm env.Reproduction
Compared against a build of PR #7216 on the same host under identical conditions: byte-identical,
exit=139, output md5d41d8cd9…on both. So this ismain's behaviour, not #7216's, and #7216's A/B is what surfaced it.test_gap_gc_static_block_this_rooting(the #7201 reproducer) reportsbad 1under the same env, also identically on both arms — the same story one notch quieter.Why the two routes differ
gc_repsel_matrix.sh's own header states it:defaultand the polls route "relocate at a real safepoint (the JS stack has unwound, roots are precise by construction)", whereas the%E%arms "force it at the register-imprecise allocation point". #7207's fixes — theRuntimeHandleScoperooting insidejs_object_assign_oneand the codegen accumulator root — were reasoned about and verified against the safepoint route. An allocation-point collection inside the helper is a different window: it can fire between any two of the helper's own allocations, including ones insideobject_assign_set_string_key's interning and keys-array growth, where #7207 re-reads its handles only at the top of each key iteration.Caveat, stated because it changes what to do first
Both observations were made while a second agent's build was loading the box. In #7207's own idle
--arms all --pressure 8run this cell was PASS onevac_minor. So the failure is load-dependent, and the first step is an idle reproduction, not a fix — a load-dependent SIGSEGV that disappears when idle is still a real defect (it is the classic #7154 timing signature), but the mechanism should be pinned before anyone changes rooting code on the strength of it.If it reproduces idle, the natural next instrument is #7196's
PERRY_GC_PROTECT_FROMSPACEquarantine, which is built to fault at the stale dereference rather than one cycle later.Why it matters
This is a residual of #7200, which #7207 reported as closed. It does not reopen the
loop_pollsresult — that remains clean 5/5 — but it means the #7161 revert readiness statement should count the allocation-point route as unverified for the object-spread path, not merely the sites #7208/#7209/#7210 name.Refs #7207, #7200, #7154, #7161, #7216, #7196.