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
ci: the per-PR repsel matrix arms cannot reproduce the relocating-minor defect class (evac base is push-only) #6993
and that combination appears only in --arms all (evac_minor / cons_scan_off_force). cons_scan_off on its own is pressure + precise roots with incremental mode still on, which does not take the relocating path.
Measurement
Built the five #6982 crashers from aa1c15028 (i.e. unfixed) and ran each PR-gated arm. All green:
The same binaries crash immediately under PERRY_GC_HEAP_LIMIT=8 PERRY_GC_INCREMENTAL=0 PERRY_CONSERVATIVE_STACK_SCAN=off (SIGBUS/SIGSEGV, copied_objects 4 579 / 5 965).
So the entire "raw reference held across a relocating collection" class — #6951, #6972, #6982, #6991, #6992 — is invisible to the per-PR gate. It can only go red after merge, on push.
Why I did not just fix it
Adding evac_minor to PR_ARMS today would fail every PR: 13 of 21 corpus cells are still red on that arm (2 crashes + 11 mismatches after #6982's fix). The gate has to become green-able first.
Datapoint for this issue's thesis, from a GC measurement run (#7056): the relocating-minor defect class reproduces in the shipped default configuration, with no special arm at all.
#7055 is an ordinary event-loop TypeScript program that produces a deterministic wrong checksum under plain perry file.ts -o bin && ./bin. The discriminator is exactly copied_objects > 0:
Note the second row: three minor cycles, right answer, because none of them relocated.
This bears on the "suggested shape" here in two ways.
The gate hole may be wider than evac_minor. This issue frames the missing coverage as the PERRY_GC_INCREMENTAL=0 PERRY_CONSERVATIVE_STACK_SCAN=off combination that only --arms all reaches. But the case above needs neither half — it is the default. PERRY_GC_TRACE=1 on the shipped arm shows root_sources.native_stack_fallback.decision = "skip_disabled" on 62 of 63 cycles, so the shipped moving path is already running with precise roots and no conservative scan. #6981's reasoning that gc_check_trigger's forced force_full_scan() keeps this class out of production does not cover the deferred/moving path.
What a green-able discriminator might key on. Since the discriminator here is copied_objects > 0 rather than any particular arm, a cheaper gate than adding evac_minor to PR_ARMS may be available: run the corpus in the default configuration but fail if a test that relocated disagrees with a copied_objects == 0 run of the same binary. That is a self-checking property (no oracle needed beyond Perry-vs-Perry), it does not require the 13-of-21 red cells to be fixed first, and it would have caught #7055 on the PR that introduced it.
Full measurement context, including the per-cycle trace figures quoted above: #7056.
Activity
proggeramlug commentedon Jul 30, 2026
Datapoint for this issue's thesis, from a GC measurement run (#7056): the relocating-minor defect class reproduces in the shipped default configuration, with no special arm at all.
#7055 is an ordinary event-loop TypeScript program that produces a deterministic wrong checksum under plain
perry file.ts -o bin && ./bin. The discriminator is exactlycopied_objects > 0:PERRY_GC_SCAVENGE_NURSERY_MB=128PERRY_GC_MOVING_LOOP_POLLS=0PERRY_GC_MOVING_LOOP_POLLS=0 PERRY_GC_SCAVENGE=1Note the second row: three minor cycles, right answer, because none of them relocated.
This bears on the "suggested shape" here in two ways.
The gate hole may be wider than
evac_minor. This issue frames the missing coverage as thePERRY_GC_INCREMENTAL=0 PERRY_CONSERVATIVE_STACK_SCAN=offcombination that only--arms allreaches. But the case above needs neither half — it is the default.PERRY_GC_TRACE=1on the shipped arm showsroot_sources.native_stack_fallback.decision = "skip_disabled"on 62 of 63 cycles, so the shipped moving path is already running with precise roots and no conservative scan. #6981's reasoning thatgc_check_trigger's forcedforce_full_scan()keeps this class out of production does not cover the deferred/moving path.What a green-able discriminator might key on. Since the discriminator here is
copied_objects > 0rather than any particular arm, a cheaper gate than addingevac_minortoPR_ARMSmay be available: run the corpus in the default configuration but fail if a test that relocated disagrees with acopied_objects == 0run of the same binary. That is a self-checking property (no oracle needed beyond Perry-vs-Perry), it does not require the 13-of-21 red cells to be fixed first, and it would have caught #7055 on the PR that introduced it.Full measurement context, including the per-cycle trace figures quoted above: #7056.
fix(gc): measure the moving-defer allowance from the deferral point s…