Downstream: zig-utils/zig-js#97 Builds on the negative result in #28; related: #26, #27, #30, #31, #32.
Evidence
The remaining shared object-churn gap is not fixed by lock policy, a pending-stack gate, per-mutator intrusive chains, atomic publication guards, or batched unpublication. #28 removed the heap-wide publication word but regressed 4/8 lanes by 135%/171%; its collector then consumed per-mutator chains whose traversal order no longer matched the backing slabs. Current samples continue to place allocObjectBatch, sweepPhaseLocked, and reusable-slot lookup in the same serialized path.
zig-js already owns every managed cell in persistent size-class chunks with exact published/free bitmaps. Those chunks can provide a stable, address-local enumeration at a collector quiescence boundary, making the intrusive heap-wide all list unnecessary for opted-in embedders and allowing a later publication shard design without destroying sweep locality.
Design direction
Add a generic opt-in owned-cell enumeration contract and a collector mode that treats it as the authoritative live-cell walk:
- the binding produces a stable snapshot/iterator of published allocation bases only at an explicitly documented heap-quiescent boundary;
- raw slots reserved by a mutator but not yet header-published must never enter the snapshot;
- whitening, ephemeron/weak passes, address-index construction, minor/full sweep, and teardown enumerate each live header exactly once in backing-address order;
- the generic intrusive
alllist remains the fallback for bindings without the opt-in; - allocation/sweep races, header initialization visibility, payload membership, finalization order, and OOM behavior remain sound;
- once collector locality is proven, retry #28-style private publication without a heap-wide per-batch word.
Acceptance criteria
- Generic tests cover mixed sizes, holes/reuse, raw unpublished reservations, minor old/young cells, weak work, teardown, and exact once-only enumeration.
- Parallel tests prove snapshot stability against a publisher stopped before and after header publication; normal and suppression-free TSan gates pass.
- The opted-in collector does not require the intrusive
allprepend on its allocation hot path. - Retry private publication with no heap-wide CAS/lock per batch and exact live/byte/nursery accounting.
- Full zig-gc and focused zig-js semantic/GC gates pass.
- Exact-parent zig-js object-churn A/B does not regress 1/2 lanes and materially improves both 4 and 8 lanes; otherwise revert the downstream activation and retain only independently useful generic infrastructure.