pub struct Heap { /* private fields */ }Expand description
luna’s incremental mark-sweep GC heap. Owns every Gc<T> allocation
(one per Vm); produces handles via the new_* constructors and traces
reachability through registered roots. Holds the string-intern table and
the auto-GC pacing state.
Implementations§
Source§impl Heap
impl Heap
Sourcepub fn new_table_sized(&mut self, asize: usize) -> Gc<Table>
pub fn new_table_sized(&mut self, asize: usize) -> Gc<Table>
P11-S5c.B — adopt an empty table and pre-allocate asize
NIL slots in the array part. Equivalent to new_table()
followed by set_int(N, Nil) worth of rehashes, except
the array reaches its final size in one allocation rather
than O(log N) doubling rounds.
asize == 0 is identical to new_table(). Larger sizes
are clamped at the array part’s hard ceiling
MAX_ASIZE = 2^27; requests beyond that fall back to the
empty table, which the interpreter would have grown
gracefully via rehash anyway.
Sourcepub fn adopt_proto(&mut self, proto: Proto) -> Gc<Proto>
pub fn adopt_proto(&mut self, proto: Proto) -> Gc<Proto>
Adopt a compiler-built prototype (its hdr must carry ObjTag::Proto).
Sourcepub fn new_closure(
&mut self,
proto: Gc<Proto>,
upvals: Box<[Gc<Upvalue>]>,
) -> Gc<LuaClosure>
pub fn new_closure( &mut self, proto: Gc<Proto>, upvals: Box<[Gc<Upvalue>]>, ) -> Gc<LuaClosure>
P11-S5d.M — back-compat constructor for callers that already
built a Box<[Gc<Upvalue>]>. Internally re-routes through
new_closure_inline so small-upval cases also pick the
inline path (the input Box is freed after the copy).
Sourcepub fn new_closure_inline(
&mut self,
proto: Gc<Proto>,
upvals: &[Gc<Upvalue>],
) -> Gc<LuaClosure>
pub fn new_closure_inline( &mut self, proto: Gc<Proto>, upvals: &[Gc<Upvalue>], ) -> Gc<LuaClosure>
P11-S5d.M — hot-path constructor for the Op::Closure handler.
Takes a slice (typically backed by a stack array) so the caller
doesn’t allocate a Vec/Box just to hand it over. Upvals are
copied into inline_storage for small closures, or into a
freshly-allocated Box<[..]> for the rare overflow case.
Sourcepub fn new_native(
&mut self,
f: NativeFn,
upvals: Box<[Value]>,
) -> Gc<NativeClosure>
pub fn new_native( &mut self, f: NativeFn, upvals: Box<[Value]>, ) -> Gc<NativeClosure>
Allocate a NativeClosure wrapping host function f with the
given captured upvalues.
Sourcepub fn new_async_native(
&mut self,
f: NativeFn,
upvals: Box<[Value]>,
) -> Gc<NativeClosure>
pub fn new_async_native( &mut self, f: NativeFn, upvals: Box<[Value]>, ) -> Gc<NativeClosure>
v1.1 B10 Stage 2 — like Heap::new_native but tags the
closure with is_async = true. The dispatcher’s native-call
path then transmutes f to AsyncNativeFn and routes through
the cooperative-yield path. The caller is responsible for
having transmuted the AsyncNativeFn pointer to NativeFn
shape (both are fn pointers of the same size); see
crate::vm::async_drive for the helper that does this.
Sourcepub fn new_upvalue(&mut self, state: UpvalState) -> Gc<Upvalue>
pub fn new_upvalue(&mut self, state: UpvalState) -> Gc<Upvalue>
Allocate a fresh Upvalue cell in the given state (open / closed).
Sourcepub fn new_coro(&mut self, body: Value, globals: Gc<Table>) -> Gc<Coro>
pub fn new_coro(&mut self, body: Value, globals: Gc<Table>) -> Gc<Coro>
Create a fresh suspended coroutine wrapping body. The new thread
inherits the creator’s globals table; a setfenv(0, env) inside it
will retune that copy without affecting the creator.
Sourcepub fn new_userdata(
&mut self,
payload: UserdataPayload,
writable: bool,
) -> Gc<Userdata>
pub fn new_userdata( &mut self, payload: UserdataPayload, writable: bool, ) -> Gc<Userdata>
Create a userdata (an io file handle — luna’s only userdata) with no
metatable yet; the io library installs the shared FILE* metatable.
Sourcepub fn intern(&mut self, bytes: &[u8]) -> Gc<LuaStr>
pub fn intern(&mut self, bytes: &[u8]) -> Gc<LuaStr>
Create (or find) a string. Short strings (≤ 40 bytes) are interned.
Sourcepub fn live_objects(&self) -> usize
pub fn live_objects(&self) -> usize
Number of GC-managed objects currently linked into the heap (live + not
yet swept). Useful for collectgarbage("count")-style introspection.
Sourcepub fn walk_objects(&self, visit: impl FnMut(ObjTag))
pub fn walk_objects(&self, visit: impl FnMut(ObjTag))
v2.0 Track TL — pure-read walk over the intrusive all
objects list, invoking visit(tag) once per live (or
not-yet-swept) GC-managed object. Used by luna-tools’s
luna-heap-dump to build a per-type histogram; embedders
can reuse it for ad-hoc heap introspection.
§Read-only contract
The callback receives only the ObjTag discriminant and
is invoked under a &self borrow on the heap: no pointer
to the GC payload escapes, no as_mut-style aliasing is
available, and the walk performs zero allocation in the
loop. Safe to call between dispatch ticks (the only allocs
happen in the caller’s bookkeeping).
The walk visits both the live all list and the
sweep_cur detached list so a mid-cycle invocation reports
the same total as Heap::live_objects.
Sourcepub fn gc_due(&self) -> bool
pub fn gc_due(&self) -> bool
Whether allocation has crossed the auto-GC threshold (cheap safe-point check for the interpreter loop).
Sourcepub fn rearm_gc_pause(&mut self, pause: i64)
pub fn rearm_gc_pause(&mut self, pause: i64)
Re-arm with caller-supplied pause (PUC param, % of live bytes). The
next cycle fires once bytes >= live * pause / 100. pause=200 (PUC
default) waits for the heap to double; pause=100 fires immediately
when alloc resumes; pause=300 is 3× — lower pause = more aggressive.
Sourcepub fn rearm_gc(&mut self)
pub fn rearm_gc(&mut self)
Re-arm the auto-GC threshold after a collection (PUC pause-style: next collection once the live set roughly doubles).
Sourcepub fn collect(&mut self, roots: &[Value]) -> usize
pub fn collect(&mut self, roots: &[Value]) -> usize
Mark from roots, sweep everything unreachable. Returns the number of
objects freed.
Sourcepub fn barrier_forward(&mut self, parent: *mut GcHeader, child: Value)
pub fn barrier_forward(&mut self, parent: *mut GcHeader, child: Value)
Forward write barrier: when a BLACK parent acquires a fresh reference
to a WHITE child, gray the child (strings go straight to BLACK as
leaves) and push onto the persistent gray queue so the next propagate
step traces it. Mirrors PUC luaC_barrier_. No-op outside Propagate
(parent is gray or white — the mutator never sees a BLACK object live
outside an incremental cycle).
Sourcepub fn barrier_back(&mut self, parent: *mut GcHeader)
pub fn barrier_back(&mut self, parent: *mut GcHeader)
Backward write barrier for objects with many fields (tables, threads):
demote the parent itself back to gray so propagate re-traces it.
Mirrors PUC luaC_barrierback_. One call covers any number of
subsequent stores until the next propagate finishes — much cheaper for
tables than per-child forward barriers. No-op outside Propagate.