diff --git a/src/libcore/gc.rs b/src/libcore/gc.rs index cdf258aa0aba2..2c68607c6d488 100644 --- a/src/libcore/gc.rs +++ b/src/libcore/gc.rs @@ -54,13 +54,15 @@ extern mod rustrt { fn rust_get_stack_segment() -> *StackSegment; } -// Is fp contained in segment? -unsafe fn is_frame_in_segment(fp: *Word, segment: *StackSegment) -> bool { - let begin: Word = unsafe::reinterpret_cast(&segment); - let end: Word = unsafe::reinterpret_cast(&(*segment).end); - let frame: Word = unsafe::reinterpret_cast(&fp); +unsafe fn bump(ptr: *T, count: uint) -> *U { + return unsafe::reinterpret_cast(&ptr::offset(ptr, count)); +} - return begin <= frame && frame <= end; +unsafe fn align_to_pointer(ptr: *T) -> *T { + let align = sys::min_align_of::<*T>(); + let ptr: uint = unsafe::reinterpret_cast(&ptr); + let ptr = (ptr + (align - 1)) & -align; + return unsafe::reinterpret_cast(&ptr); } type SafePoint = { sp_meta: *Word, fn_meta: *Word }; @@ -69,59 +71,41 @@ type SafePoint = { sp_meta: *Word, fn_meta: *Word }; // any. unsafe fn is_safe_point(pc: *Word) -> Option { let module_meta = rustrt::rust_gc_metadata(); - let num_safe_points_ptr: *u32 = unsafe::reinterpret_cast(&module_meta); - let num_safe_points = *num_safe_points_ptr as Word; - let safe_points: *Word = - ptr::offset(unsafe::reinterpret_cast(&module_meta), 1); + let num_safe_points = *module_meta; + let safe_points: *Word = bump(module_meta, 1); if ptr::is_null(pc) { return None; } // FIXME (#2997): Use binary rather than linear search. - let mut sp = 0 as Word; - while sp < num_safe_points { - let sp_loc = *ptr::offset(safe_points, sp*3) as *Word; + let mut spi = 0; + while spi < num_safe_points { + let sp: **Word = bump(safe_points, spi*3); + let sp_loc = *sp; if sp_loc == pc { - return Some( - {sp_meta: *ptr::offset(safe_points, sp*3 + 1) as *Word, - fn_meta: *ptr::offset(safe_points, sp*3 + 2) as *Word}); + return Some({sp_meta: *bump(sp, 1), fn_meta: *bump(sp, 2)}); } - sp += 1; + spi += 1; } return None; } type Visitor = fn(root: **Word, tydesc: *Word) -> bool; -unsafe fn bump(ptr: *T, count: uint) -> *U { - return unsafe::reinterpret_cast(&ptr::offset(ptr, count)); -} - -unsafe fn align_to_pointer(ptr: *T) -> *T { - let align = sys::min_align_of::<*T>(); - let ptr: uint = unsafe::reinterpret_cast(&ptr); - let ptr = (ptr + (align - 1)) & -align; - return unsafe::reinterpret_cast(&ptr); -} - // Walks the list of roots for the given safe point, and calls visitor // on each root. unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) { let fp_bytes: *u8 = unsafe::reinterpret_cast(&fp); - let sp_meta_u32s: *u32 = unsafe::reinterpret_cast(&sp.sp_meta); + let sp_meta: *u32 = unsafe::reinterpret_cast(&sp.sp_meta); - let num_stack_roots = *sp_meta_u32s as uint; - let num_reg_roots = *ptr::offset(sp_meta_u32s, 1) as uint; + let num_stack_roots = *sp_meta as uint; + let num_reg_roots = *ptr::offset(sp_meta, 1) as uint; - let stack_roots: *u32 = - unsafe::reinterpret_cast(&ptr::offset(sp_meta_u32s, 2)); - let reg_roots: *u8 = - unsafe::reinterpret_cast(&ptr::offset(stack_roots, num_stack_roots)); - let addrspaces: *Word = - unsafe::reinterpret_cast(&ptr::offset(reg_roots, num_reg_roots)); - let tydescs: ***Word = - unsafe::reinterpret_cast(&ptr::offset(addrspaces, num_stack_roots)); + let stack_roots: *u32 = bump(sp_meta, 2); + let reg_roots: *u8 = bump(stack_roots, num_stack_roots); + let addrspaces: *Word = align_to_pointer(bump(reg_roots, num_reg_roots)); + let tydescs: ***Word = bump(addrspaces, num_stack_roots); // Stack roots let mut sri = 0; @@ -152,13 +136,14 @@ unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) { } } -type Memory = uint; - -const task_local_heap: Memory = 1; -const exchange_heap: Memory = 2; -const stack: Memory = 4; +// Is fp contained in segment? +unsafe fn is_frame_in_segment(fp: *Word, segment: *StackSegment) -> bool { + let begin: Word = unsafe::reinterpret_cast(&segment); + let end: Word = unsafe::reinterpret_cast(&(*segment).end); + let frame: Word = unsafe::reinterpret_cast(&fp); -const need_cleanup: Memory = exchange_heap | stack; + return begin <= frame && frame <= end; +} // Find and return the segment containing the given frame pointer. At // stack segment boundaries, returns true for boundary, so that the @@ -191,6 +176,14 @@ unsafe fn find_segment_for_frame(fp: *Word, segment: *StackSegment) return {segment: segment, boundary: false}; } +type Memory = uint; + +const task_local_heap: Memory = 1; +const exchange_heap: Memory = 2; +const stack: Memory = 4; + +const need_cleanup: Memory = exchange_heap | stack; + // Walks stack, searching for roots of the requested type, and passes // each root to the visitor. unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) { diff --git a/src/rt/rust_gc_metadata.cpp b/src/rt/rust_gc_metadata.cpp index bce79f375649b..4566289d2606a 100644 --- a/src/rt/rust_gc_metadata.cpp +++ b/src/rt/rust_gc_metadata.cpp @@ -54,7 +54,7 @@ update_gc_metadata(const void* map) { if (!global_safe_points) return; uintptr_t *next = global_safe_points; - *(uint32_t *)next = safe_points.size(); + *next = safe_points.size(); next++; for (uint32_t i = 0; i < safe_points.size(); i++) { next[0] = safe_points[i].safe_point_loc;