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
The retain cluster regressed 2.2–4.8× on main between 8260a9e50 and d78efca41. Independently confirmed by a second party on a separate build.
The load-independent evidence is the collection census — main now runs full mark-sweeps on programs that previously ran none:
program
collection_kind:"full"
minor
retain
2
6
retain1
1
3
deeplist
1
3
(measured at cf9999855, PERRY_GC_TRACE=1 PERRY_GC_DIAG=1)
The last clean quiet-mini sweep at 8039fa798 recorded retain0.153 s (1.13× node), retain10.068 s, deeplist0.057 s — and that commit predates both suspects, so the regression is invisible to it. Corroborating timing on a loaded dev box (magnitude only, not a benchmark): retain 0.83 s, retain1 0.24 s, deeplist 0.24 s.
The original reporter measured retain2,840 M → 12,421 M instructions with fulls costing 190 ms + 605 ms.
Suspected cause — not bisected
Two PRs merged in that window, both in the promotion/survival accounting:
Both are plausible on mechanism, and they interact: the survival ratio feeds the in-place-promotion decision, and promotion step size feeds the old-gen trigger.
The mechanism this most likely trips
A third party independently instrumented old_reclaim_pressure_due's absolute arm (old_in_use >= T && baseline < T) and found it races two quantities that both move with promotion, so whether it fires depends on promotion step size, not on the heap: same program, same live set, same total promotion, and changing only the schedule from (18.7, 34.6) to (17.7, 17.8) makes it fire twice and buy 588 ms of futile fulls.
#7592 exempted the proportional arm via GC_MAJOR_PACING_RETAINING and left this one. #7902 changing promotion step size is exactly the input that would newly trip it.
That also makes this an instance of the rule CLAUDE.md already carries, for the fifth time: never pace a collection on a quantity that collection does not move — and its corollary that a constant band cannot pace an O(live) process.
Asks
Bisect 8260a9e50..d78efca41 on the full count (a counter, so a single run per commit suffices — no quiet host needed).
Whatever the fix, gate it on the full count, not on wall time — that is what makes this cheap to detect and is how it was found.
Note on downstream measurements
Any A/B taken against a base after e886b56dd is measuring against a regressed baseline. #7960 (first-cycle in-place promotion) reports −41% to −77% against current main but −14% to −31% against the pre-regression base; the latter is the honest figure and its author flagged this unprompted.
Summary
The
retaincluster regressed 2.2–4.8× onmainbetween8260a9e50andd78efca41. Independently confirmed by a second party on a separate build.The load-independent evidence is the collection census —
mainnow runs full mark-sweeps on programs that previously ran none:collection_kind:"full"minorretainretain1deeplist(measured at
cf9999855,PERRY_GC_TRACE=1 PERRY_GC_DIAG=1)The last clean quiet-mini sweep at
8039fa798recordedretain0.153 s (1.13× node),retain10.068 s,deeplist0.057 s — and that commit predates both suspects, so the regression is invisible to it. Corroborating timing on a loaded dev box (magnitude only, not a benchmark):retain0.83 s,retain10.24 s,deeplist0.24 s.The original reporter measured
retain2,840 M → 12,421 M instructions with fulls costing 190 ms + 605 ms.Suspected cause — not bisected
Two PRs merged in that window, both in the promotion/survival accounting:
e886b56dd— "subtract live from-space bytes, not the block high-water, in a copied minor". Changes what the survival ratio is computed from.1bd5eeb6b— "bound and heap-scale the untraced-promotion budget". Bounds the untraced budget ⟹ more, smaller promotion steps.Both are plausible on mechanism, and they interact: the survival ratio feeds the in-place-promotion decision, and promotion step size feeds the old-gen trigger.
The mechanism this most likely trips
A third party independently instrumented
old_reclaim_pressure_due's absolute arm (old_in_use >= T && baseline < T) and found it races two quantities that both move with promotion, so whether it fires depends on promotion step size, not on the heap: same program, same live set, same total promotion, and changing only the schedule from (18.7, 34.6) to (17.7, 17.8) makes it fire twice and buy 588 ms of futile fulls.#7592 exempted the proportional arm via
GC_MAJOR_PACING_RETAININGand left this one. #7902 changing promotion step size is exactly the input that would newly trip it.That also makes this an instance of the rule CLAUDE.md already carries, for the fifth time: never pace a collection on a quantity that collection does not move — and its corollary that a constant band cannot pace an O(live) process.
Asks
8260a9e50..d78efca41on the full count (a counter, so a single run per commit suffices — no quiet host needed).Note on downstream measurements
Any A/B taken against a base after
e886b56ddis measuring against a regressed baseline. #7960 (first-cycle in-place promotion) reports −41% to −77% against currentmainbut −14% to −31% against the pre-regression base; the latter is the honest figure and its author flagged this unprompted.