Implement tri-color mark-and-sweep garbage collector for JS engine
Add a generic GC module (gc.rs) with tri-color marking (white/gray/black),
heap allocation via Vec with free-list reuse, and stop-the-world collection
triggered when live object count exceeds a configurable threshold.
Refactor VM to use GcRef handles for heap objects (plain objects and
functions) instead of owned values. This gives correct JS reference
semantics — object assignment shares identity rather than deep-cloning.
The GC traces through object properties and prototype chains to find all
reachable objects, and correctly collects cycles.
Key changes:
- gc.rs: Generic Gc<T: Traceable> with alloc/get/collect, HeapSlot with
color metadata, mark phase with gray stack, sweep with free-list
- vm.rs: Value::Object(GcRef) and Value::Function(GcRef) replace owned
data; VM allocates through self.gc and triggers collection after
allocations; root collection scans registers and globals
- lib.rs: evaluate() uses to_js_string(&gc) for GC-aware string conversion
8 new GC tests (alloc, collect, transitive reachability, cycle collection,
free-list reuse, threshold, stress) plus 3 integration tests. All 226
existing tests continue to pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
authored by
tangled.org
38791b59
49fa501d