Problem
The current object_churn profile is dominated by young-GC sweep and GcCellBacking.freeFn. Each dead object returns through the generic allocator path, reclassifies the same 1024-byte owned slab bucket, rechecks chunk ownership, and takes a bucket lock in parallel mode.
Parent: #62 Collector dependency: zig-utils/zig-gc#12
Proposed slice
- Implement zig-gc optional batched dead-cell release hooks in the Binding.
- Let GcCellBacking hold its bucket synchronization for the release phase.
- Release each exact owned cell directly into the appropriate free list without allocator-vtable dispatch.
- Keep finalizers ahead of the batch so their side-storage frees cannot recurse into held cell-bucket locks.
- Preserve the generic free path for non-cell allocations and embedders without the hook.
Acceptance criteria
- Focused GcCellBacking tests prove exact per-bucket counts, slot reuse, and delegated frees remain correct.
- Full zig-gc and zig-js suites pass with zero leaks; benchmark harness passes.
- Order-balanced fresh-process object_churn A/B preserves checksum 1030552128 and shows a repeatable improvement.
- Both small conventional commits cross-reference their issues and are pushed as Chris without coauthors.