Precise garbage collector

The precise GC exposes two functions, gc and cleanup_stack_for_failure. The gc function is the entry point to the garbage collector itself. The cleanup_stack_for_failure is the entry point for GC-based cleanup.

Precise GC depends on changes to LLVM's GC which add support for automatic rooting and addrspace-based metadata marking. Rather than explicitly rooting pointers with LLVM's gcroot intrinsic, the GC merely creates allocas for pointers, and allows an LLVM pass to automatically infer roots based on the allocas present in a function (and live at a given location). The compiler communicates the type of the pointer to LLVM by setting the addrspace of the pointer type. The compiler then emits a map from addrspace to tydesc, which LLVM then uses to match pointers with their tydesc. The GC reads the metadata table produced by LLVM, and uses it to determine which glue functions to call to free objects on their respective heaps.

GC-based cleanup is a replacement for landing pads which relies on the GC infrastructure to find pointers on the stack to cleanup. Whereas the normal GC needs to walk task-local heap allocations, the cleanup code needs to walk exchange heap allocations and stack-allocations with destructors.

Const exchange_heap

Memory

Const need_cleanup

Memory

Const stack

Memory

Const task_local_heap

Memory

Type Memory

type Memory = uint

Type RootSet

type RootSet = LinearMap<*Word, ()>

Type SafePoint

type SafePoint = {sp_meta: *Word, fn_meta: *Word,}

Type Visitor

type Visitor = &fn(root: **Word, tydesc: *Word) -> bool

Struct StackSegment

struct StackSegment {
    prev: *StackSegment,
    next: *StackSegment,
    end: uintptr_t,
}

Function RootSet

fn RootSet() -> RootSet

Function align_to_pointer

fn align_to_pointer<T>(ptr: *T) -> *T

Function bump

fn bump<T, U>(ptr: *T, count: uint) -> *U

Function cleanup_stack_for_failure

fn cleanup_stack_for_failure()

Function find_segment_for_frame

fn find_segment_for_frame(fp: *Word, segment: *StackSegment) ->
 {segment: *StackSegment, boundary: bool,}

Function gc

fn gc()

Function get_safe_point_count

fn get_safe_point_count() -> uint

Function is_frame_in_segment

fn is_frame_in_segment(fp: *Word, segment: *StackSegment) -> bool

Function is_safe_point

fn is_safe_point(pc: *Word) -> Option<SafePoint>

Function walk_gc_roots

fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor)

Function walk_safe_point

fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor)