Downstream: zig-utils/zig-js#62
Problem
Heap.create prepends every allocation to the intrusive all-cells list. With the one-cycle nursery enabled, every new cell is young and every surviving young cell is tenured at the next minor or full collection. Therefore the active nursery is naturally a contiguous prefix of the list, but collectYoung currently whitens and sweeps through the entire old generation as well.
The current zig-js object_churn profile makes young-GC sweeping the largest named runtime cost after VM numeric dispatch was removed in zig-utils/zig-js#67.
Scope
- make the young-prefix invariant explicit and testable;
- stop minor whitening at the first old cell;
- start binding-selected old-kind tracing at that boundary rather than rechecking the young prefix;
- stop the minor sweep when it reaches the first old cell while preserving list links across promoted and reclaimed young cells;
- make nursery disable/re-enable safe when young cells are pending, rather than permitting old allocations to split the prefix;
- keep full collection, weak/ephemeron processing, finalization, accounting, parallel locking, and generic binding behavior correct.
Acceptance criteria
- Mixed live/dead young prefixes are promoted/reclaimed with exact list and byte/cell accounting.
- Old cells after the boundary are not visited by the minor whitening or sweep loops.
- Disabling and re-enabling the nursery cannot create a split young region.
- Full collections and repeated minor cycles preserve the invariant.
- Weak, ephemeron, remembered-owner, parallel, and conservative-root tests remain clean.
- Full zig-gc tests pass.
- Clean pinned downstream object_churn A/B records exact checksum equality and no regression.
- Commit references this issue and downstream evidence is added to zig-utils/zig-js#62.