Skip to main content

Module heap

Module heap 

Source
Expand description

Phase D mark-and-sweep garbage collector.

This module is the production GC for the Lua runtime, replacing the Rc<T>-backed GcRef<T> placeholder used through Phase B/C. It is a single-threaded precise tracing collector with incremental and generational paths plus forward/backward write barriers.

§Vocabulary

  • Gc: a pointer-sized handle. Copy + Clone. Replaces GcRef<T>.
  • GcBox: the heap allocation; contains a header and the value.
  • GcHeader: per-object metadata (color, age, finalized flag, intrusive next pointer for exactly one heap owner list, and grayagain revisit link).
  • Trace: trait every GC-rooted type implements. The trace method walks all Gc<_> fields and calls Marker::mark on each.
  • Marker: passed to trace; carries the gray queue.
  • Heap: owns the allgc/finobj/tobefnz list heads, byte counters, and GC state machine.

§Safety model

All unsafe is confined to this crate (per harness/unsafe-budgets.toml). The invariants are:

  1. Every Gc<T> points to a valid, allocated, not-yet-swept GcBox<T>.
  2. The intrusive heap lists are consistent: traversing header.next from Heap.head, Heap.finobj, and Heap.tobefnz reaches every live heap-owned GcBox exactly once.
  3. After Heap::full_collect(roots), every Gc<T> reachable from roots is still valid; unreachable boxes are dropped and deallocated.

§Migration shape

Existing code holds GcRef<T> (which after Phase D is a type alias for Gc<T>). Legacy call sites like GcRef::new(value) route through Gc::new_uncollected which allocates a GcBox but does NOT register it in any heap. Phase D-1b agent work converts these to state.heap().allocate(value) so the new box joins the heap owner lists.

Structs§

AllGcCohortStats
Diagnostic counts for the allgc list split by generational cursors.
BootstrapScope
RAII handle for a heap bootstrap window; created by Heap::bootstrap_scope, ends the window on drop. Exists so error paths (? during stdlib install, lua_open failure) cannot leave the heap stuck in bootstrap mode the way a manual end_bootstrap call can.
FinalizerRegistry
FinalizerRegistryStats
Gc
A GC-managed pointer. Copy + Clone (one-machine-word). Replaces GcRef<T>.
GcBox
A heap-allocated, GC-tracked value plus its header.
GcHeader
Per-object GC metadata. Lives at the start of every GcBox.
Heap
HeapGuard
A scoped guard for the currently-active heap. Pushed at entry to state.run() / state.protected_call() / state.load(); popped on drop. Supports nesting (multiple LuaStates on one thread).
HeapRef
Marker
Holds the gray queue during a mark phase. Passed to Trace::trace.
MarkerStats
Diagnostic counters for the latest mark phase.
StepBudget
Work budget for one incremental step.
SweepStats
Diagnostic counters for the latest sweep phase.
WeakRegistry
WeakRegistrySnapshot
WeakRegistryStats

Enums§

Color
A traced color in the tri-color invariant.
GcAge
Object age used by Lua’s generational collector.
GcState
Phases of the incremental collection cycle.
StepOutcome
Outcome of one call to Heap::incremental_step_with_post_mark.
WeakListKind

Traits§

FinalizerEntry
Minimal metadata a finalizable VM object must expose for collector-owned finalizer-list bookkeeping.
Trace
Every GC-rooted type implements Trace to expose its Gc<_> fields.
Udata51Probe
A Lua 5.1 collect-time finalizability probe for a single userdata.
WeakEntry
Minimal operations needed for collector-owned weak-registry bookkeeping.

Functions§

detached_allocations
Total detached (Gc::new_uncollected) allocations made on this thread since it started. Leak canaries assert a zero delta across embedding scenarios. This counter deliberately lives outside the heap’s own bookkeeping: detached boxes never touch bytes/objects, which is exactly the blind spot that hid issue #249 — a mechanism must not be verified with bookkeeping it maintains itself.
strict_guard_mode
True when OMNILUA_GC_STRICT_GUARD=1: the silent no-active-heap fallback arms (GcRef::new → detached allocation, GcRef::downgrade → forever-upgrading weak handle, GcRef::account_buffer → dropped charge) panic with a backtrace instead of degrading, so every guard-coverage gap self-reports under the existing test suites. The dual of LUA_RS_GC_QUARANTINE: quarantine turns freed-too-early into a loud failure, strict-guard turns never-freed into one (issue #249’s class).
with_current_heap
Runs f with a reference to the currently-active heap, or None if no HeapGuard is in scope.