The two unstarted follow-ups from #7187, refiled so they stop hiding behind a mostly-finished umbrella.
What already shipped (and is why #7187 closed): Phase A — lazy barrier arming (#7250); Phase B — the dirty-page mark cache (#7298). Both are live.
B3 — slot elision. Skip the write-barrier slot computation where the store provably cannot create an old→young edge. The original analysis identified this as the next lever after the mark cache.
B4 — the generation bit. Carry generation in the object header so classify_heap_generation becomes a header read rather than an arena-range classification.
Why B4 is the interesting one
#7187's own evidence: classify_heap_generation was 19% of batch.ts — 57.4% total GC bookkeeping — with ZERO collections running. That is pure mutator-side cost paid by the write-barrier tower on a program that never collects.
Related and worth reading first: #7511 established that the barrier cost is 98.5% the loop function's keep.push(ptr) and zero from the constructor, and that the "parent array is young" shortcut is unsound. #7602 landed the array-store barrier design that came out of it; its design notes missed the SATB shade clause, so check that before designing anything adjacent.
Before coding
Re-profile. These percentages are days old and this repo has repeatedly found ticket figures stale on re-measure (#7510's went stale three times during its own work; #7698 and #7702 both re-measured lower). Also note PERRY_WRITE_BARRIERS=0 cannot be used to bound barrier cost — it changes the GC regime, so the A/B is not measuring what it appears to.
Bench host per the standing rule: the quiet M1 mini.
The two unstarted follow-ups from #7187, refiled so they stop hiding behind a mostly-finished umbrella.
What already shipped (and is why #7187 closed): Phase A — lazy barrier arming (#7250); Phase B — the dirty-page mark cache (#7298). Both are live.
B3 — slot elision. Skip the write-barrier slot computation where the store provably cannot create an old→young edge. The original analysis identified this as the next lever after the mark cache.
B4 — the generation bit. Carry generation in the object header so
classify_heap_generationbecomes a header read rather than an arena-range classification.Why B4 is the interesting one
#7187's own evidence:
classify_heap_generationwas 19% ofbatch.ts— 57.4% total GC bookkeeping — with ZERO collections running. That is pure mutator-side cost paid by the write-barrier tower on a program that never collects.Related and worth reading first: #7511 established that the barrier cost is 98.5% the loop function's
keep.push(ptr)and zero from the constructor, and that the "parent array is young" shortcut is unsound. #7602 landed the array-store barrier design that came out of it; its design notes missed the SATB shade clause, so check that before designing anything adjacent.Before coding
Re-profile. These percentages are days old and this repo has repeatedly found ticket figures stale on re-measure (#7510's went stale three times during its own work; #7698 and #7702 both re-measured lower). Also note
PERRY_WRITE_BARRIERS=0cannot be used to bound barrier cost — it changes the GC regime, so the A/B is not measuring what it appears to.Bench host per the standing rule: the quiet M1 mini.