pub struct GcHandle<'a> { /* private fields */ }Expand description
A short-lived handle returned by state.gc() for GC operations.
Implementations§
Source§impl<'a> GcHandle<'a>
impl<'a> GcHandle<'a>
Sourcepub fn check_step(&self)
pub fn check_step(&self)
Drives implicit collection when the heap’s byte threshold is
exceeded. Without this hook, loops that allocate without an
explicit collectgarbage() call (e.g. closure.lua’s
while x[1] do local a = A..A end GC-driven loop) never settle.
pub fn full_collect(&self)
Sourcepub fn generational_step(&self) -> bool
pub fn generational_step(&self) -> bool
Run one generational collection step.
Sourcepub fn generational_step_minor_only(&self) -> bool
pub fn generational_step_minor_only(&self) -> bool
Run a generational step forced to the regular minor path.
Used for collectgarbage("step", 0): upstream genstep treats
GCdebt <= 0 as an explicit zero-size step and performs a minor
collection, unless a previous bad major has already armed lastatomic.
Sourcepub fn step(&self)
pub fn step(&self)
No-op stub for luaC_step(L); unused. See GcHandle::check_step
for the real incremental-collection entry point.
Sourcepub fn incremental_step(&self, work_units: isize) -> bool
pub fn incremental_step(&self, work_units: isize) -> bool
Run one budgeted incremental step of the GC.
work_units is the number of GC work units the step is allowed to
perform (one gray trace, one sweep visit, or one phase transition).
Returns true if the step completed a cycle and the collector is
now in the Pause state; false otherwise.
Mirrors collect_via_heap for the post-mark weak-table /
finalizer-promotion logic, but only the atomic-phase transition will
invoke the snapshot-walking hook — propagate and sweep steps reuse
the snapshot but never execute it. The snapshot is rebuilt on every
call; the cost is O(weak_tables_registry) per step.
Sourcepub fn run_until_gc_state_for_test(&self, target: GcState) -> bool
pub fn run_until_gc_state_for_test(&self, target: GcState) -> bool
TestC/debug helper: run the incremental collector until a specific heap
state is entered, preserving the same weak-table/finalizer post-mark
hooks as Self::incremental_step. This is intentionally not used for
normal pacing; it exists so official tests can inspect mid-cycle colors.
Sourcepub fn prune_weak_tables_mark_only(&self)
pub fn prune_weak_tables_mark_only(&self)
Run only the weak-table atomic cleanup used by legacy generational callers that need mark/prune behavior without sweeping.
Explicit generational steps now use Self::generational_step, which
performs a young sweep. This helper remains for call sites that only
need the weak-table atomic pass.
Sourcepub fn change_mode(&self, mode: GcKind)
pub fn change_mode(&self, mode: GcKind)
Set the GC kind (incremental/generational).
Sourcepub fn fix_object<T: Trace + 'static>(&self, _o: &GcRef<T>)
pub fn fix_object<T: Trace + 'static>(&self, _o: &GcRef<T>)
No-op stub for luaC_fix(L, o) (pin an object so GC won’t collect
it). Called from tagmethods.rs for interned tag-method name
strings, which stay alive via the traced GlobalState::tmname root
instead.
Sourcepub fn free_all_objects(&self)
pub fn free_all_objects(&self)
Free all collectable objects deterministically (called during state
teardown by close_state), mirroring C-Lua lua_close’s guarantee
that finalizers and frees complete before the call returns.
Object destruction historically rode on GlobalState’s eventual Rc
drop, so close_state could return with every heap object still live
(issue #260). This now drains the heap through
Heap::drop_all — every destructor runs
before this returns — and clears the GlobalState-side GC bookkeeping
(weak-table registry, finalizer registry, external roots) whose entries
would otherwise name freed boxes. drop_all clears the allocation-token
map, so a pre-existing GcWeak stops upgrading immediately, and leaves
the heap closed, so a HeapGuard that outlived close panics instead
of resurrecting a torn-down heap.
This does not run finalizers: close_state calls
api::run_close_finalizers before invoking this on the complete-state
branch (mirroring C’s luaC_freeallobjects = separatetobefnz +
callallpendingfinalizers + free); this only frees.
A HeapGuard for this state’s own heap is
pushed around the drain: a destructor that allocates via GcRef::new
resolves the top of the TLS guard stack, so without the push its box
would land in whatever heap the caller happened to have active — a
different VM’s heap under a foreign guard, or a panic with no guard at
all. With it, teardown-time allocations always land in (and are drained
from) the heap being closed, regardless of ambient guard state.
The registry clears below also break the GlobalState ↔ coroutine
reference cycle: each ThreadRegistryEntry holds an
Rc<RefCell<LuaState>> whose LuaState.global is a strong
Rc<RefCell<GlobalState>> back-edge, so a live suspended coroutine at
close would otherwise keep the GlobalState — and its Rc<Heap> —
alive forever after the outer state drops. The sibling cross-thread
maps hold only Copy GcRef handles (no cycle), but those handles
dangle once drop_all frees the boxes, so they are cleared with it.
Sourcepub fn barrier_back(&self, p: &dyn Any, v: &LuaValue)
pub fn barrier_back(&self, p: &dyn Any, v: &LuaValue)
Backward write barrier.
Sourcepub fn table_barrier_back(&self, p: &GcRef<LuaTable>, v: &LuaValue)
pub fn table_barrier_back(&self, p: &GcRef<LuaTable>, v: &LuaValue)
Typed table backward barrier for table mutation hot paths.
Sourcepub fn obj_barrier(&self, p: &dyn Any, o: &dyn Any)
pub fn obj_barrier(&self, p: &dyn Any, o: &dyn Any)
Object write barrier.
Sourcepub fn obj_barrier_back(&self, p: &dyn Any, o: &dyn Any)
pub fn obj_barrier_back(&self, p: &dyn Any, o: &dyn Any)
Backward object write barrier.