Commit Graph
3 Commits
Author SHA1 Message Date
MarcelineVQ e996796d39 luagc: Lua 5.1 tri-color GC with full forward barrier coverage
Major port of Lua 5.1 incremental GC patterns:

Tri-color system:
- Two-white (WHITE0/WHITE1) with currentwhite flip in atomic phase
- Objects born currentwhite via hooked luaC_link (0x6F7B20)
- String birth mark patched to currentwhite at each flip
- isDead: otherwhite check with FIXED exception for WoW
- makewhite on survivors (preserves KEYWEAK/VALUEWEAK/FIXED)
- Bootstrap: first cycle sets all existing objects to currentwhite

Mark system (5.1 reallymarkobject/propagatemark):
- Strings: stringmark inline (no gray stack)
- Userdata: go black inline, mark metatable
- Tables: gray2black, traverse, black2gray if weak
- Threads: NEVER black, always grayagain (re-traversed in atomic)
- Closures: go black normally

Forward barriers (5.1 luaC_barrierf at every write site):
- OP_SETUPVAL: VM patch at 0x6F8A97 with naked asm trampoline
- lua_setmetatable (0x6F4020): hooked, barrier on new metatable
- lua_setupvalue (0x6F47B0): hooked, barrier grays closure
- lua_setfenv (0x6F40D0): hooked, barrier grays object

Backward barriers (5.1 luaC_barrierback):
- lua_table_set_value (0x6FA840): black2gray + grayagain
- lua_table_set_int_key (0x6FAD80): black2gray + grayagain

Atomic phase (5.1 ordering):
- propagateall, re-traverse weak tables, mark running thread,
  grayagain drain, separateudata, marktmu, cleartable, flip white

Status: enters world successfully with CHUNK_SIZE=5000 (incremental).
Crashes on UI reload (different crash pattern -- NULL+8 deref in mark,
not the old hash chain crash). Progress from "crashes on enter world"
to "crashes on UI reload."
2026-04-09 23:50:37 -07:00
MarcelineVQ 54d1b69f0e luagc: incremental GC fixes (weak tables, isAlive, grayagain, lua_close)
- Weak tables mark strong dimension (condmarkobject pattern)
- isAlive matches WoW binary (raw marked != 0)
- Write barriers use grayagain (barrier-back, prevents livelock)
- removekey sets dead keys to LUA_TNONE
- lua_close hook resets GC state before teardown
- lua_setgcthreshold hook prevents threshold stomping
- Stack nilling in traverseThread
- Sweep order: rootudata -> strings -> rootgc
- Birth mark scoped to string sweep only
2026-04-09 17:25:13 -07:00
MarcelineVQ 1ea1d6655b luagc: from-scratch incremental GC with slab allocator
Replace WoW's stop-the-world Lua 5.0 GC with a fully custom incremental
mark+sweep. The module owns both allocation (slab allocator) and collection.

Key components:
- Slab allocator (luaalloc.zig): copied from weirdperformance, stripped of
  generational age bitmaps. Hooks memory_pool_allocate + lua_gc_step.
- Incremental mark: tri-color with gray stack, write barriers on table writes.
  Correctly handles weak table strong/weak dimensions (condmarkobject).
- From-scratch sweep: cursor-based rootgc, rootudata, chunked string buckets.
  Sweep order matches native (rootudata -> strings -> rootgc).
- Weak table detection: scans metatable for __mode, sets KEYWEAK/VALUEWEAK.
- Weak clearing: removekey semantics (nil value + TNONE dead keys).
- Birth mark scoped to string sweep only (rootgc objects prepend to head).
- Stack nilling: traverseThread nils slots above L->top matching native.
- Hooks lua_setgcthreshold to prevent external threshold stomping.

Native functions retained: lua_gc_free_object (type dispatch), luaCallUserDataGC
(__gc finalizers), luaC_separateudata (dead udata separation).
2026-04-09 16:34:16 -07:00