zig-gc

Usage

The 10 examples below are taken from zig-gc's README.

const Kind = enum { ... };                          // your cell taxonomy
fn traceRoots(ctx: *B, v: anytype) void;            // mark every root
fn trace(cell: *anyopaque, kind: Kind, v: anytype) void; // mark a cell's edges
fn finalize(ctx: *B, cell: *anyopaque, kind: Kind) void; // a cell is dying
fn usesOwnedCellStorage(ctx: *B, total: usize) bool;
fn ownsCellAllocation(ctx: *B, allocation: *anyopaque) bool;
fn hasWeakWork(ctx: *B) bool;
fn allocateCellBatch(ctx: *B, total: usize, out: []*anyopaque) usize;
fn allCellsUseOwnedStorage(ctx: *B) bool;
fn publishCellAllocationBatch(
    ctx: *B,
    payloads: []*anyopaque,
    total: usize,
    payload_offset: usize,
) void;
fn ownedCellIterator(ctx: *B) Iterator; // Iterator.next() ?*anyopaque
fn collectionPhaseBoundary(ctx: *B, boundary: gc.CollectionPhaseBoundary) void;
fn canRelocate(ctx: *B, cell: *anyopaque, kind: Kind) bool;
fn relocateRoots(ctx: *B, v: anytype) void;
fn relocateCell(ctx: *B, cell: *anyopaque, kind: Kind, v: anytype) void;
fn verifyRelocationRoots(ctx: *B, v: anytype) void;
fn verifyRelocationCell(ctx: *B, cell: *anyopaque, kind: Kind, v: anytype) void;
fn reserveRelocationCell(ctx: *B, total: usize) ?*anyopaque;
fn releaseRelocationReservation(ctx: *B, allocation: *anyopaque, total: usize) void;
fn commitRelocationCell(ctx: *B, old: *anyopaque, new: *anyopaque, total: usize) void;
const gc = @import("gc");

var rt = MyRuntime{};                 // holds your roots + finalizer state
var heap = gc.Heap(MyRuntime).init(allocator, &rt);
defer heap.deinit();                  // frees + finalizes everything left
heap.setNurseryTenuringAge(3);        // retain survivors for three minor cycles
heap.setNurseryEnabled(true);

const obj = try heap.create(MyObject, .object); // uninitialized payload
obj.* = .{ ... };                      // initialize before the next safepoint

var objects: [32]*MyObject = undefined;
const count = try heap.createBatch(MyObject, .object, &objects); // one metadata lock
for (objects[0..count]) |item| item.* = .{ ... }; // initialize before a safepoint

heap.maybeCollect();                   // call at safepoints; collects past a threshold
heap.collect();                        // or force a full stop-the-world cycle
const compacted = heap.collectAndCompact(); // opt-in binding: collect + relocate
const stats = heap.accounting();       // race-safe generation + heap telemetry