API reference
On this page 159
Every declaration below is extracted from zig-gc's source, with the doc comments as written there. A declaration listed without prose is public but undocumented in the source.
Root
Heap
const Heap = @import("heap.zig").Heap
CollectionPhaseBoundary
const CollectionPhaseBoundary = @import("heap.zig").CollectionPhaseBoundary
InteriorOwnership
const InteriorOwnership = @import("heap.zig").InteriorOwnership
RelocationRecord
const RelocationRecord = @import("heap.zig").RelocationRecord
RelocationState
const RelocationState = @import("heap.zig").RelocationState
RelocationVisitor
const RelocationVisitor = @import("heap.zig").RelocationVisitor
StableCellId
const StableCellId = @import("heap.zig").StableCellId
Heap
CollectionPhaseBoundary
const CollectionPhaseBoundary = enum
Semantic collection boundaries for opt-in embedder profiling. The generic
heap deliberately owns no clock or counters; bindings that omit the hook pay
no runtime cost. prepare_begin is emitted only after a collection is known
to run, post_sweep_end follows the optional afterSweep hook, and
abort closes an attempt that deliberately skipped weak clearing and sweep.
InteriorOwnership
const InteriorOwnership = union(enum)
Optional binding result for conservative interior-address classification.
allocation is the exact cell allocation base (the header address), while
owned_empty means the address lies in owned storage but cannot name an
issued allocation. outside permits the collector's generic fallback unless
the binding separately proves that every cell uses its owned storage.
StableCellId
const StableCellId = enum(u64)
Process-unique, address-independent identity for one collector cell. IDs are non-zero, never recycled, and remain attached to a cell when compaction relocates its storage. Embedders may use them for diagnostics such as heap snapshots, but must not expose them as mutable language state.
init
fn init(raw: u64) StableCellId
RelocationState
const RelocationState = enum
RelocationRecord
fn RelocationRecord(comptime Kind: type) type
RelocationVisitor
fn RelocationVisitor(comptime Kind: type) type
Infallible old→new resolver handed to binding rewrite hooks after every destination has been reserved. Cells absent from the plan are pinned and retain their address. Dead weak targets have already been cleared before relocation begins, so every non-null weak target follows the same mapping.
resolve
fn resolve(self: *const @This(), old_payload: *anyopaque) *anyopaque
moved
fn moved(self: *const @This(), old_payload: *anyopaque) bool
stableId
fn stableId(self: *const @This(), old_payload: *anyopaque) ?StableCellId
Heap
fn Heap(comptime Binding: type) type
Kind
const Kind = Binding.Kind
CellMetadata
const CellMetadata = struct
RelocationRecordType
const RelocationRecordType = RelocationRecord(Kind)
RelocationVisitorType
const RelocationVisitorType = RelocationVisitor(Kind)
min_nursery_threshold_bytes
const min_nursery_threshold_bytes: usize = 4 * 1024 * 1024
default_nursery_threshold_bytes
const default_nursery_threshold_bytes: usize = 4 * 1024 * 1024
default_tenuring_age
const default_tenuring_age: u8 = 1
Header
const Header = struct
cellAllocationBytes
fn cellAllocationBytes(comptime T: type) usize
Exact backing allocation size for a cell payload type. Embedders that claim all cells use owned storage use this in an exhaustive comptime proof over their cell taxonomy.
Visitor
const Visitor = struct
mark
fn mark(v: *Visitor, cell: ?*anyopaque) void
Mark a strong reference. Null-safe and idempotent (tri-color:
white→grey on first sight, pushed once). The white→grey claim is
atomic under a concurrent mark so the marker and a mutator's
writeBarrier never both push the same cell.
markProperty
fn markProperty(v: *Visitor, name: []const u8, cell: ?*anyopaque) void
Labeled edge variants let bindings retain precise provenance in corruption diagnostics without adding work to successful marks.
markIndex
fn markIndex(v: *Visitor, index: usize, cell: ?*anyopaque) void
markVariable
fn markVariable(v: *Visitor, name: []const u8, cell: ?*anyopaque) void
markInternal
fn markInternal(v: *Visitor, name: []const u8, cell: ?*anyopaque) void
isManaged
fn isManaged(v: *Visitor, cell: ?*anyopaque) bool
Whether cell is one of this heap's managed payloads. Bindings use
this before marking legacy/embedder pointers that may still point
outside the GC heap. Unlike mark, this predicate must tolerate
stale or wild values: root tracers often use it specifically at
mixed ownership boundaries, where a header peek would turn a bad
legacy pointer into a collector crash. So this walks the heap's
live-cell list for an exact payload match instead of reading from
the candidate address. The walk is intentionally paid only by
"maybe managed" compatibility edges; precise edges should call
mark directly.
isMarked
fn isMarked(v: *Visitor, cell: ?*anyopaque) bool
Whether a cell is already black/grey in the current collection. Used by ephemeron tables: if the key is live, the value is a strong edge; if the key stays white, the entry is weak.
markConservativeWord
fn markConservativeWord(v: *Visitor, word: usize) void
Conservatively mark a machine word if it points at the payload
of a managed cell. This is intentionally opt-in: precise
embedders should keep using mark, while runtimes that need to
root native stacks can scan a stack/register spill range without
teaching the collector about their frame layout.
markConservativeWords
fn markConservativeWords(v: *Visitor, start: [*]const usize, words: usize) void
Scan a word-aligned range, inclusive of start and spanning
words machine words. The caller owns choosing safe stack or
register-spill bounds for its platform.
concurrent
fn concurrent(v: *Visitor) bool
Whether this trace is running on the marker thread concurrently with live mutators (M3). Bindings whose cells have internally mutable storage (a growable slot/element vector behind a lock) must, when this is true, read that storage under the same lock the mutator takes — otherwise the marker's read races a mutator's append/realloc. False under stop-the-world (M1) and GIL-held incremental (M2) marking, where the world is quiescent during the read, so the binding can skip the lock on those paths.
deferToFinish
fn deferToFinish(v: *Visitor, cell: *anyopaque) void
Defer this (already-marked) cell's tracing to the world-stopped
finishConcurrentMark. For cells whose mutable storage is too
entangled to read safely mid-mark (e.g. a generator whose exec
is the live VM stack, or an iterator helper whose fields update
around JS callbacks): the binding calls this from trace when
concurrent(), so the cell survives this cycle (it is marked) but
its children are discovered at finish, when the mutator is
quiescent and the storage is stable. A no-op outside a concurrent
mark (the caller should just trace normally then).
markWeak
fn markWeak(v: *Visitor, slot: *?*anyopaque) void
Register a weak slot. After marking completes, if its target stayed white the slot is set to null (the cell is dying).
markWeakAtomic
fn markWeakAtomic(v: *Visitor, slot: *std.atomic.Value(?*anyopaque)) void
Register an externally synchronized weak slot. Clearing uses a CAS so a concurrent embedder clear cannot race a plain store and a future retargeting API cannot lose a newly published target.
init
fn init(backing: std.mem.Allocator, ctx: *Binding) Self
setAuxAllocator
fn setAuxAllocator(self: *Self, aux: std.mem.Allocator) void
Install a thread-safe scratch allocator for concurrent marking (M3).
Must be called right after init, before any allocation, since
mark_stack/barrier_buf must be freed with the same allocator they
were grown with. A no-op conceptually for M1/M2 (leave it as backing).
setParallel
fn setParallel(self: *Self, parallel: bool) void
Enable multi-mutator allocation (the post-GIL model): create's
shared-state bookkeeping runs under alloc_lock. backing must be
thread-safe. Leave off (default) for the single-GIL'd-mutator model so
allocation pays no lock.
setConcurrentMarkerMetadata
fn setConcurrentMarkerMetadata(self: *Self, enabled: bool) void
Serialize allocation metadata against a single dedicated marker
thread. Use this for concurrent marking without enabling the
multi-mutator parallel collector protocol.
setNurseryEnabled
fn setNurseryEnabled(self: *Self, enabled: bool) void
Enable the nursery. New cells start at age zero; a minor
collection reclaims unreachable young cells, advances live survivors,
and tenures cells that reach tenuring_age. Existing cells stay old,
so enabling this after heap initialization is safe. Disabling with a
pending nursery tenures that entire young prefix without collecting:
later old allocations can therefore never split the prefix before a
re-enable.
setMovingNurseryEnabled
fn setMovingNurseryEnabled(self: *Self, enabled: bool) void
Move every live young survivor after weak processing and sweep. Embedders must still open their relocation/root-rewrite token at the stop window; enabling the policy alone never makes an unsafe stack movable.
movingNurseryEnabled
fn movingNurseryEnabled(self: *const Self) bool
setNurseryTenuringAge
fn setNurseryTenuringAge(self: *Self, age: u8) void
Select how many successful minor collections a young cell must survive before promotion. One preserves the original single-cycle nursery policy; larger values retain a measured multi-age nursery.
Accounting
const Accounting = struct
Race-safe accounting snapshot for embedders that expose heap usage
or collection telemetry. live_bytes includes the collector header
and payload allocation for every currently live cell. The
last-full value changes only after a completed full sweep, never
after a nursery-only cycle or an in-progress concurrent mark.
CompactionStatus
const CompactionStatus = enum
CompactionResult
const CompactionResult = struct
accounting
fn accounting(self: *Self) Accounting
cellMetadata
fn cellMetadata(self: *Self, payload: ?*anyopaque) ?CellMetadata
Return immutable diagnostics metadata for a live cell. The embedder must call this at a heap-quiescent boundary, so collection cannot reclaim the returned cell between lookup and the metadata reads. Null and unmanaged/stale payloads return null.
isLive
fn isLive(self: *Self, p: ?*anyopaque) bool
Whether p is a live (marked) cell — O(1). p must be null or a
pointer to a cell allocated by this heap. This is the read a binding
uses for isMarked-based weak clearing: deciding a weak key's /
finalizer target's liveness in the world-stopped finish pass by its
mark bit, instead of pre-registering an interior &slot weak pointer
that a concurrent mutator append could dangle by reallocating the
buffer it points into. Call only with marks still valid (before sweep).
create
fn create(self: *Self, comptime T: type, kind: Kind) !*T
Allocate a GC-managed cell of type T tagged kind. The returned
pointer is uninitialized payload; the caller writes it before the
next safepoint (so a collection never traces a half-built cell).
createBatch
fn createBatch(self: *Self, comptime T: type, kind: Kind, out: []*T) !usize
Allocate several same-kind cells privately, then publish the
successfully allocated prefix under one metadata lock. Returning a
short prefix defers recovery/OOM until the caller has initialized and
consumed those cells, preserving sequential allocation failure
ordering. Every returned payload is uninitialized and must be fully
initialized before the caller's next safepoint, just like create.
maybeCollect
fn maybeCollect(self: *Self) void
Collect if the heap has grown past the threshold. Call at safepoints
(the engine's (steps & 1023) checkpoints) and after large allocs.
writeBarrier
fn writeBarrier(self: *Self, cell: ?*anyopaque) void
Dijkstra insertion write barrier. The embedder calls this whenever it
stores a reference to cell into a heap object during an incremental
mark: it shades cell grey so a reference newly hidden behind an
already-black object is never missed (the black→white invariant). A
no-op when not marking, when cell is null, or when cell is not a
managed payload (the embedder may store non-cell pointers) — so it is
cheap and safe to call broadly. Idempotent (already-grey/black: skip).
writeBarrierFrom
fn writeBarrierFrom(self: *Self, owner: ?*anyopaque, cell: ?*anyopaque) void
Owner-aware insertion barrier. In nursery mode an old owner is
remembered when it receives a young child, so minor collection only
rescans dirty old containers. The incremental/full barrier remains
identical to writeBarrier.
writeBarrierFromManaged
fn writeBarrierFromManaged(self: *Self, owner: *anyopaque, cell: *anyopaque) void
Fast owner-aware barrier for exact live managed payloads allocated by
this heap. Unlike writeBarrierFrom, this deliberately does not
classify arbitrary pointers through the live-payload index. The
caller must provide non-null payload starts from this heap; use the
tolerant barrier whenever either pointer may be external or stale.
writeBarrierWeak
fn writeBarrierWeak(self: *Self, owner: ?*anyopaque) void
Remember an old container whose weak slots changed. This does not mark the weak target; it merely ensures minor GC revisits the container to apply normal weak/ephemeron semantics.
markWorkPublicationFailed
fn markWorkPublicationFailed(self: *const Self) bool
startMarking
fn startMarking(self: *Self) void
Begin an incremental mark: whiten all cells and grey the roots. The
mutator then runs between markSteps with the writeBarrier active.
markStep
fn markStep(self: *Self, budget: usize) bool
Process up to budget grey cells (0 = unbounded). Returns true when
the mark stack is empty (the grey set is drained for now). Because the
barrier keeps shading during mutation, "drained" is not final until
finishMarking re-checks under a stop.
finishMarking
fn finishMarking(self: *Self) void
Finish an incremental mark (stop-the-world tail): re-scan the roots,
drain the grey set, run the ephemeron fixpoint and weak processing,
then sweep. The root re-scan closes the one gap the heap-store
insertion barrier doesn't: a reachable-but-white cell the mutator
moved onto a root (an operand stack, a native frame, the microtask
queue) after startMarking snapshotted them. Heap→heap moves are
covered by the barrier; root moves are covered here. (For a
stop-the-world collect() no mutation happened, so this re-scan only
re-touches already-marked roots — cheap and harmless.)
collect
fn collect(self: *Self) void
A full stop-the-world cycle: mark from roots, clear dead weak edges,
sweep (finalizing) the white cells. Equivalent to
startMarking + drain + finishMarking, kept as the default.
collectAndCompact
fn collectAndCompact(self: *Self) CompactionResult
Run a full collection and then compact every live cell accepted by the binding. Destination reservation is failure-atomic: allocation and the old→new index complete before the first old byte, root, edge, publication bit, or heap index is changed. Rewrite/commit hooks are therefore infallible and execute only with a complete plan.
collectYoung
fn collectYoung(self: *Self) void
collectYoungAndCompact
fn collectYoungAndCompact(self: *Self) CompactionResult
Run the same exact minor trace/weak/sweep contract, then relocate every survivor (including cells promoted by this cycle). Destination reservation completes before roots or graph bytes change.
beginConcurrentMark
fn beginConcurrentMark(self: *Self) void
Begin a concurrent mark. Call with the world stopped (no mutator
running): whitens all cells and greys the roots into mark_stack,
then flips concurrent on so mutators route through barrier_buf.
beginConcurrentMarkParallel
fn beginConcurrentMarkParallel(self: *Self) void
Begin a concurrent mark for the parallel (multi-mutator, GIL-free)
model: peer mutators keep allocating and mutating on other threads
while this runs. Unlike beginConcurrentMark, the world is NOT
stopped, so:
- The whiten pass + state reset run under
alloc_lock, the same leaf lockcreatetakes, so the O(n)all-list walk and the born-grey mark-bit set can't race a peer's prepend.alloc_lockis a leaf (never held across a safepoint or a per-structure lock), so guarding the walk with it cannot deadlock a mutator that is parked or spinning for an object lock. The whiten stores tomarkedare atomic becausealloc_lockdoes NOT serialize the barrier path: a peer still finishing a store from the previous cycle (it readmarkingtrue before the prior finish cleared it) reachesclaimMark, whose CAS atomically touchesmarkedwithoutalloc_lock. That CAS is always a benign no-op here — its target was reachable-and-marked last cycle, so the strong CAS fails andwriteBarrierreturns before mutating any list (a successful CAS would mean a swept-garbage target, which the terminal root handshake already rules out). Atomic-vs-atomic is race-free; the new cycle's happens-before is themarking=true release below. marking+concurrentare published while still holdingalloc_lock, so no cell can be prepended between "whitened" and "barrier armed": acreatethat wins the lock after us already seesmarkingtrue and is born grey.- After arming the barrier,
Binding.traceRootsgreys the embedder's roots. The embedder is responsible for making that trace touch only roots that are safe to read while peers run (its global/realm state, parked-peer stacks, the collector's own stack) and for layering each running peer's own roots in via a safepoint handshake (src/root_handshake.zig) — a running peer's live VM/native stack can't be read by another thread. Peers' concurrent stores shade throughbarrier_bufand their allocations are born grey, so nothing reachable is missed. Requiresparallel.
concurrentMarkRound
fn concurrentMarkRound(self: *Self) bool
One marker-thread round: trace everything currently grey, then fold
in whatever the mutator handed off. Returns true when both the local
stack and the hand-off buffer were empty this round (a quiescent
point — not final until the world is stopped for finishConcurrentMark).
finishConcurrentMark
fn finishConcurrentMark(self: *Self) void
Finish a concurrent mark (call with the world stopped): fold in any
remaining hand-off, re-scan roots, drain, run the ephemeron/weak pass,
and sweep. After this concurrent/marking are off.
bornPendingLen
fn bornPendingLen(self: *Self) usize
Pending mutator-allocated cells not yet folded into the mark (M3
parallel). The driver watches this for stability across two
all-published handshake rounds: a stable count means no peer is
mid-allocation, so every born cell's payload is fully initialized and
safe to fold at finishConcurrentMarkParallel.
deferredPendingLen
fn deferredPendingLen(self: *Self) usize
Cells whose tracing the marker deferred to finish (generators /
iterator helpers whose mutable exec/inner can't be read while the
owning mutator runs). The parallel driver refuses to finish (aborts)
while this is non-empty, because a running peer's deferred cell
can't be traced soundly — only a world-stopped or quiescent finish can.
finishConcurrentMarkParallel
fn finishConcurrentMarkParallel(self: *Self) bool
Finish a concurrent mark in the PARALLEL model — peers keep running,
no stop-the-world. The caller (the engine's mid-script driver) must
have confirmed via the root handshake that every peer published the
current generation, that born_concurrent is stable (no peer
mid-allocation, so every born payload is initialized), and that
deferred_trace is empty. Given that, marking has reached closure
over all live roots, and any store a peer makes from here can only
shade a cell reachable from its already-published (and traced) roots —
i.e. an already-marked cell — so it is sound to drain and sweep
without freezing the world. Claims stay atomic until the final
marking=false; the sweep runs under alloc_lock (sweepPhase).
Returns true if it swept, false if it had to bail (a peer allocated
during the finish, so newly-born cells would be untraced and their
un-barriered creation-time references could be missed); on false the
caller aborts (abortConcurrentMarkParallel), freeing nothing.
shouldCollect
fn shouldCollect(self: *Self) bool
Whether live bytes have crossed the collection threshold, read under
alloc_lock in parallel mode so a mid-script collector's safepoint
check doesn't race a peer's create updating bytes_live.
shouldCollectOld
fn shouldCollectOld(self: *Self) bool
Whether tenured bytes alone have crossed the full-heap threshold.
Generational embedders use this at quiescent boundaries so a large
young batch receives a minor collection before it can force a full
trace. Mid-script collectors that cannot run minor GC should continue
using shouldCollect() over total bytes.
shouldCollectYoung
fn shouldCollectYoung(self: *Self) bool
Whether the nursery has reached its collection threshold, or a remembered-set allocation failure requires the next nursery request to fall back to a full collection.
abortConcurrentMarkParallel
fn abortConcurrentMarkParallel(self: *Self) void
Abort an in-progress parallel concurrent mark after the embedding's terminal handshake could not reach a stable finish. Frees no cells.
deinit
fn deinit(self: *Self) void
Free every remaining cell (finalizing each) and the internal lists.
The embedder calls this at context teardown — equivalent to the old
arena deinit, but finalizers run.
deinitRetainingCellStorage
fn deinitRetainingCellStorage(self: *Self) void
Finalize every remaining cell and release collector side buffers, but
do not return individual cell allocations to backing. Use only when
the embedder owns those allocations through a slab/arena that it will
reclaim wholesale immediately afterward. Cell finalizers still run in
full, so side storage and host resources are released normally.
Kind
const Kind = enum
traceRoots
fn traceRoots(self: *TestRT, v: anytype) void
afterWeakRoots
fn afterWeakRoots(self: *TestRT) void
afterSweep
fn afterSweep(self: *TestRT) void
collectionPhaseBoundary
fn collectionPhaseBoundary(self: *TestRT, boundary: CollectionPhaseBoundary) void
trace
fn trace(cell: *anyopaque, kind: Kind, v: anytype) void
canRelocate
fn canRelocate(_: *TestRT, cell: *anyopaque, kind: Kind) bool
canRelocateYoung
fn canRelocateYoung(_: *TestRT, _: *anyopaque, _: Kind) bool
relocateRoots
fn relocateRoots(self: *TestRT, v: anytype) void
relocateCell
fn relocateCell(_: *TestRT, cell: *anyopaque, kind: Kind, v: anytype) void
verifyRelocationRoots
fn verifyRelocationRoots(self: *TestRT, v: anytype) void
verifyRelocationCell
fn verifyRelocationCell(self: *TestRT, cell: *anyopaque, kind: Kind, v: anytype) void
reserveRelocationCell
fn reserveRelocationCell(self: *TestRT, total: usize) ?*anyopaque
releaseRelocationReservation
fn releaseRelocationReservation(self: *TestRT, allocation: *anyopaque, total: usize) void
commitRelocationCell
fn commitRelocationCell(self: *TestRT, old: *anyopaque, _: *anyopaque, total: usize) void
finalize
fn finalize(self: *TestRT, cell: *anyopaque, kind: Kind) void
Kind
const Kind = enum
allocateCellBatch
fn allocateCellBatch(self: *BatchAllocTestRT, total: usize, out: []*anyopaque) usize
publishCellAllocationBatch
fn publishCellAllocationBatch(self: *BatchAllocTestRT, payloads: []*anyopaque, _: usize, payload_offset: usize) void
allCellsUseOwnedStorage
fn allCellsUseOwnedStorage(_: *BatchAllocTestRT) bool
traceRoots
fn traceRoots(_: *BatchAllocTestRT, _: anytype) void
trace
fn trace(_: *anyopaque, _: Kind, _: anytype) void
finalize
fn finalize(_: *BatchAllocTestRT, _: *anyopaque, _: Kind) void
Kind
const Kind = enum
Iterator
const Iterator = struct
next
fn next(self: *Iterator) ?*anyopaque
ownedCellIterator
fn ownedCellIterator(self: *ShardedBatchTestRT) Iterator
allCellsUseOwnedStorage
fn allCellsUseOwnedStorage(_: *ShardedBatchTestRT) bool
usesOwnedCellStorage
fn usesOwnedCellStorage(_: *ShardedBatchTestRT, _: usize) bool
allocateCellBatch
fn allocateCellBatch(self: *ShardedBatchTestRT, total: usize, out: []*anyopaque) usize
publishCellAllocation
fn publishCellAllocation(self: *ShardedBatchTestRT, allocation: *anyopaque, _: usize) void
publishCellAllocationBatch
fn publishCellAllocationBatch(self: *ShardedBatchTestRT, payloads: []*anyopaque, _: usize, payload_offset: usize) void
unpublishCellAllocation
fn unpublishCellAllocation(self: *ShardedBatchTestRT, allocation: *anyopaque, _: usize) void
ownsCellAllocation
fn ownsCellAllocation(self: *ShardedBatchTestRT, allocation: *anyopaque) bool
freeCellStorageBatch
fn freeCellStorageBatch(_: *ShardedBatchTestRT, total: usize, allocations: []*anyopaque) void
traceRoots
fn traceRoots(_: *ShardedBatchTestRT, _: anytype) void
trace
fn trace(_: *anyopaque, _: Kind, _: anytype) void
finalize
fn finalize(_: *ShardedBatchTestRT, _: *anyopaque, _: Kind) void
Kind
const Kind = enum
traceRoots
fn traceRoots(_: *SweepBatchTestRT, _: anytype) void
trace
fn trace(_: *anyopaque, _: Kind, _: anytype) void
finalize
fn finalize(_: *SweepBatchTestRT, _: *anyopaque, _: Kind) void
freeCellStorageBatch
fn freeCellStorageBatch(self: *SweepBatchTestRT, total: usize, allocations: []*anyopaque) void
Kind
const Kind = enum
traceRoots
fn traceRoots(self: *OwnedCellTestRT, v: anytype) void
trace
fn trace(_: *anyopaque, _: Kind, _: anytype) void
finalize
fn finalize(self: *OwnedCellTestRT, _: *anyopaque, _: Kind) void
publishCellAllocation
fn publishCellAllocation(self: *OwnedCellTestRT, allocation: *anyopaque, _: usize) void
unpublishCellAllocation
fn unpublishCellAllocation(self: *OwnedCellTestRT, allocation: *anyopaque, _: usize) void
usesOwnedCellStorage
fn usesOwnedCellStorage(_: *OwnedCellTestRT, _: usize) bool
ownsCellAllocation
fn ownsCellAllocation(self: *OwnedCellTestRT, allocation: *anyopaque) bool
classifyConservativeInterior
fn classifyConservativeInterior(self: *OwnedCellTestRT, address: usize) InteriorOwnership
allCellsUseOwnedStorage
fn allCellsUseOwnedStorage(_: *OwnedCellTestRT) bool
Kind
const Kind = enum
Iterator
const Iterator = struct
next
fn next(self: *Iterator) ?*anyopaque
ownedCellIterator
fn ownedCellIterator(self: *OwnedIterationTestRT) Iterator
allCellsUseOwnedStorage
fn allCellsUseOwnedStorage(_: *OwnedIterationTestRT) bool
usesOwnedCellStorage
fn usesOwnedCellStorage(_: *OwnedIterationTestRT, _: usize) bool
ownsCellAllocation
fn ownsCellAllocation(self: *OwnedIterationTestRT, allocation: *anyopaque) bool
publishCellAllocation
fn publishCellAllocation(self: *OwnedIterationTestRT, allocation: *anyopaque, _: usize) void
unpublishCellAllocation
fn unpublishCellAllocation(self: *OwnedIterationTestRT, allocation: *anyopaque, _: usize) void
traceRoots
fn traceRoots(self: *OwnedIterationTestRT, v: anytype) void
trace
fn trace(cell: *anyopaque, _: Kind, v: anytype) void
traceOldOnMinor
fn traceOldOnMinor(_: Kind) bool
finalize
fn finalize(self: *OwnedIterationTestRT, cell: *anyopaque, _: Kind) void
Kind
const Kind = enum
hasWeakWork
fn hasWeakWork(self: *EphRT) bool
traceRoots
fn traceRoots(self: *EphRT, v: anytype) void
traceOldOnMinor
fn traceOldOnMinor(kind: Kind) bool
trace
fn trace(cell: *anyopaque, kind: Kind, v: anytype) void
traceEphemeron
fn traceEphemeron(self: *EphRT, cell: *anyopaque, kind: Kind, v: anytype) void
afterWeak
fn afterWeak(self: *EphRT, cell: *anyopaque, kind: Kind) void
finalize
fn finalize(self: *EphRT, cell: *anyopaque, kind: Kind) void