Found while re-measuring the matrix after #7019. Small, but it silently weakens the one thing this gate exists to assert.
The problem
scripts/gc_repsel_matrix.sh derives its moved= evidence — the liveness predicate for every requires=move arm — by summing two different collectors' counters into one number:
moved=$( { grep -oE 'moved_objects=[0-9]+' ... ; \
grep -oE '\[gc-copy-minor\] ran copied_objects=[0-9]+' ... ; } \
| grep -oE '[0-9]+$' | awk '{s+=$1} END {print s+0}')
A cell can therefore report moved=7 610 512 and be marked live for a move arm while the copying minor never ran once.
It is not hypothetical — it is the current state of the default arm
--arms all --pressure 8 on origin/main @ 4340bffc9, 22 rows, counters separated by hand:
| arm |
Σ copied_objects (scavenge) |
Σ moved_objects (C4b) |
harness's moved |
default |
0 |
7 610 512 |
7 610 512 |
verify_evac |
0 |
7 301 552 |
7 301 552 |
evac_minor |
3 628 777 |
0 |
3 628 777 |
The first two rows read as "movement happened" in the arm-liveness summary. No object was moved by the collector under test. (The reason those arms run no scavenge at all is filed separately — it is the pressure knob colliding with the moving-defer hard cap.)
Suggested direction
Report the two counters as separate columns and let each arm state which one satisfies it. A requires=move arm added for the evacuating scavenge should require copied_objects > 0 specifically; moved_objects > 0 is a fine liveness signal for a full-GC evacuation arm, but it is a different claim.
While there: the collect predicate has the same shape of weakness, already filed as #7017 (a teardown-boundary cycle that frees nothing is indistinguishable from a mid-program one).
Related: #7019, #6942, #6946, #6950, #7017.
Found while re-measuring the matrix after #7019. Small, but it silently weakens the one thing this gate exists to assert.
The problem
scripts/gc_repsel_matrix.shderives itsmoved=evidence — the liveness predicate for everyrequires=movearm — by summing two different collectors' counters into one number:moved_objects=comes from the C4b evacuation policy inside the mark-sweep collector — the pre-existing non-moving-minor path that relocates tenured objects during a full GC.[gc-copy-minor] ran copied_objects=comes from the evacuating young-gen scavenge, which is what gc: default-on evacuating young-gen scavenge (moving minor at precise safepoints) #7019 made default-on and what themovearms are meant to certify.A cell can therefore report
moved=7 610 512and be marked live for amovearm while the copying minor never ran once.It is not hypothetical — it is the current state of the
defaultarm--arms all --pressure 8onorigin/main@4340bffc9, 22 rows, counters separated by hand:copied_objects(scavenge)moved_objects(C4b)moveddefaultverify_evacevac_minorThe first two rows read as "movement happened" in the arm-liveness summary. No object was moved by the collector under test. (The reason those arms run no scavenge at all is filed separately — it is the pressure knob colliding with the moving-defer hard cap.)
Suggested direction
Report the two counters as separate columns and let each arm state which one satisfies it. A
requires=movearm added for the evacuating scavenge should requirecopied_objects > 0specifically;moved_objects > 0is a fine liveness signal for a full-GC evacuation arm, but it is a different claim.While there: the
collectpredicate has the same shape of weakness, already filed as #7017 (a teardown-boundary cycle that frees nothing is indistinguishable from a mid-program one).Related: #7019, #6942, #6946, #6950, #7017.