Fil-C's Garbage Collector: FUGC (Fil's Unbelievable Garbage Collector) Fil-C employs a sophisticated garbage collector called FUGC, which is: Parallel: Uses multiple threads for marking and sweeping; more cores yield faster collection. Concurrent: Collector threads run alongside program (mutator) threads with minimal synchronization, mostly avoiding blocking. On-the-fly: Uses soft handshakes or ragged safepoints to coordinate thread scanning asynchronously without global stop-the-world pauses. Grey-stack based: Iteratively rescans thread stacks until no new objects appear, avoiding the need for a load barrier; only a simple store barrier is used. Dijkstra barrier: Implements a store barrier where storing a pointer during marking marks the referenced object immediately. Accurate (precise): Exactly finds all root pointers thanks to the llvm::FilPizlonator compiler pass and runtime APIs that track pointers. Non-moving: Objects do not move, simplifying concurrency and synchronization; freed pointers are redirected to a special free singleton object. Core Concepts Advancing wavefront collector: Once an object is marked during a GC cycle, it remains marked; mutators cannot generate new GC work. Incremental update: Some objects may become freed during collection. Safepoints used to: Emit pollchecks by the compiler; quick checks occur frequently to ensure bounded progress. Use soft handshakes to run callbacks asynchronously on all threads. Support enter/exit states allowing threads to block in syscalls without polling. These enable practical threading support, safe pointer usage, and signal handling without typical GC pause problems. FUGC Collector Loop Wait for GC to trigger. Enable store barrier, soft handshake with no-op callback. Enable black allocation (new objects allocated as marked), soft handshake resets thread caches. Mark global roots. Soft handshake with stack scan callback; if no work remains, proceed to step 7. Trace mark stack until empty, then repeat step 5. Disable store barrier, prepare for sweep, soft handshake to reset caches. Sweep objects; objects allocated in unswept pages are black, else white. Restart cycle. Technical Notes Based on and inspired by the Doligez-Leroy-Gonthier (DLG) collector but enhanced with a grey-stack Dijkstra approach. Sweeping is powered by a bitvector SIMD algorithm for blazing speed (typically <5% time spent sweeping). Heavily relies on the Verse heap configuration within libpas. Bonus Features Freeing Objects: Explicit calls to free mark objects as unusable; accessing freed memory traps the program. Capability pointers to freed objects are repointed to a free singleton, preventing false liveness. Helps avoid GC-induced leaks common in naive GC migrations from manual memory management. Finalizers: Supported via zgcfinq API. Allows custom finalizer queues and controlled thread processing similar to Java finalizers. Weak References: Supported via the zweak API, similar to Java weak references but without reference queues. Weak Maps: Implemented with zweakmap API. Mimics JavaScript’s WeakMap, allowing element iteration and counting. Summary of Guarantees About free Accessing a freed object always traps, even after memory reclamation, thanks to lower pointer repointing. Double-frees also cause immediate traps. Not freeing an object results in automatic reclamation by GC. --- FUGC thus balances concurrency, accuracy, and performance, while providing strong safety guarantees and modern GC features integrated into Fil-C's runtime and compiler.