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.
exchange_heap
need_cleanup
stack
task_local_heap
Memory
RootSet
SafePoint
Visitor
StackSegment
RootSet
align_to_pointer
bump
cleanup_stack_for_failure
find_segment_for_frame
gc
get_safe_point_count
is_frame_in_segment
is_safe_point
walk_gc_roots
walk_safe_point
gc::rustrt
exchange_heap
Memory
need_cleanup
Memory
stack
Memory
task_local_heap
Memory
Memory
type Memory = uint
RootSet
type RootSet = LinearMap<*Word, ()>
SafePoint
type SafePoint = {sp_meta: *Word, fn_meta: *Word,}
Visitor
type Visitor = &fn(root: **Word, tydesc: *Word) -> bool
StackSegment
struct StackSegment {
prev: *StackSegment,
next: *StackSegment,
end: uintptr_t,
}
RootSet
fn RootSet() -> RootSet
align_to_pointer
fn align_to_pointer<T>(ptr: *T) -> *T
bump
fn bump<T, U>(ptr: *T, count: uint) -> *U
cleanup_stack_for_failure
fn cleanup_stack_for_failure()
find_segment_for_frame
fn find_segment_for_frame(fp: *Word, segment: *StackSegment) ->
{segment: *StackSegment, boundary: bool,}
gc
fn gc()
get_safe_point_count
fn get_safe_point_count() -> uint
is_frame_in_segment
fn is_frame_in_segment(fp: *Word, segment: *StackSegment) -> bool
is_safe_point
fn is_safe_point(pc: *Word) -> Option<SafePoint>
walk_gc_roots
fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor)
walk_safe_point
fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor)