Downstream: zig-utils/zig-js#62 Related: #4
Problem
Visitor.markConservativeWord lazily rebuilds and sorts a live-cell extent index on the first conservative word of every collection, then binary-searches it for every scanned stack word. That generic fallback is necessary for arbitrary backing allocators, but an embedder with exact slab/chunk ownership already has a persistent address index and can classify an interior address without walking or sorting the live-cell list.
The post-optimization zig-js object_churn profile shows the generic index sort (sort.block) at 98 top-of-stack samples and conservative lookup at 73 samples during repeated nursery collections.
Design
- add an optional binding hook returning a tri-state conservative classification: outside owned storage, owned but not a live payload candidate, or exact allocation base;
- validate header magic and the exact payload extent inside zig-gc before marking;
- allow a binding with compile-time-proven all-owned cell storage to reject outside addresses without building the generic index;
- retain the current lazy sorted-index path unchanged for bindings without the hook or with delegated cells;
- expose the exact cell allocation byte count needed for downstream compile-time size proofs.
Acceptance criteria
- Exact payload and interior pointers in owned slabs mark their live cell.
- Header, padding, unissued, freed, and unrelated addresses reject safely.
- Generic/delegating bindings retain the existing sorted-index fallback.
- A proven all-owned binding never builds the generic address index during conservative scanning.
- Full zig-gc tests pass and downstream profile materially improves.