Downstream: zig-utils/zig-js#62 Profile precursor: zig-utils/zig-js#67
Problem
The broad write barrier deliberately accepts wild, stale, arena-owned, and foreign pointers, so it validates each child and owner through the embedder's ownership classifier before reading a header. In zig-js's hot Object-to-Object store path, both pointers are known GC cells and the post-#67 object_churn profile attributes 20 top-of-stack samples to headerForPayload. Repeating slab membership classification at every dense replacement is avoidable.
Scope
- retain the current broad barrier unchanged for maybe-managed inputs;
- give each Heap instance a stable per-heap header cookie without increasing Header size;
- add an explicitly trusted managed-cell barrier whose pointer contract permits direct header recovery and rejects cells owned by a different heap of the same type through that cookie;
- preserve nursery old-to-young owner remembering, conservative child retention when an owner is foreign, incremental/concurrent marking handoff, and parallel locking;
- expose the fast path to zig-js only at Object-to-Object stores whose allocation provenance is managed whenever a barrier is installed;
- keep weak barriers and mixed Environment/Promise/side-record callers on the broad path until independently proven;
- measure clean pinned downstream object_churn A/B with exact checksum equality.
Acceptance criteria
- Broad barriers still reject wild, stale, arena, and foreign inputs safely.
- Managed barriers avoid payload-index/slab ownership classification.
- Cross-heap cells with the same Binding/Header layout are rejected by a per-heap cookie.
- Header size and existing cell size-class selection do not grow.
- Nursery old-to-young edges and incremental/concurrent marking remain correct.
- Focused zig-gc and downstream GC/no-GIL tests pass.
- Clean pinned downstream A/B improves at checksum 1030552128.
- Commits reference this issue and evidence is added to zig-utils/zig-js#62.