static void push(void **block) { void *obj = *block; struct segment *seg; size_t index; bitptr_t b; if (!IS_IN_HEAP(obj)) { DBG(("%p at %p outside", obj, block)); if (obj != NULL) sml_trace_ptr(obj); return; } seg = OBJ_TO_SEGMENT(obj); index = OBJ_TO_INDEX(seg, obj); BITPTR_INIT(b, BITMAP0_BASE(seg), index); if (BITPTR_TEST(b)) { DBG(("already marked: %p", obj)); return; } MARKBIT(b, index, seg); DBG(("MARK: %p", obj)); if (OBJ_HAS_NO_POINTER(obj)) { DBG(("EARLYMARK: %p", obj)); return; } STACK_PUSH(obj, seg, index); DBG(("PUSH: %p", obj)); }
static void mark(void **block) { void *obj = *block; struct segment *seg; size_t index; bitptr_t b; ASSERT(STACK_TOP() == NULL); if (!IS_IN_HEAP(obj)) { DBG(("%p at %p outside", obj, block)); if (obj != NULL) sml_trace_ptr(obj); return; } seg = OBJ_TO_SEGMENT(obj); index = OBJ_TO_INDEX(seg, obj); BITPTR_INIT(b, BITMAP0_BASE(seg), index); if (BITPTR_TEST(b)) { DBG(("already marked: %p", obj)); return; } MARKBIT(b, index, seg); DBG(("MARK: %p", obj)); if (OBJ_HAS_NO_POINTER(obj)) { DBG(("EARLYMARK: %p", obj)); return; } for (;;) { sml_obj_enum_ptr(obj, push); obj = STACK_TOP(); if (obj == NULL) { DBG(("MARK END")); break; } STACK_POP(obj); DBG(("POP: %p", obj)); } }
static void forward(void **slot) { void *obj = *slot; size_t obj_size, alloc_size; void *newobj; if (!IS_IN_HEAP_SPACE(sml_heap_from_space, obj)) { DBG(("%p at %p outside", obj, slot)); ASSERT(!IS_IN_HEAP_SPACE(sml_heap_to_space, obj)); if (obj != NULL) sml_trace_ptr(obj); return; } if (OBJ_FORWARDED(obj)) { *slot = OBJ_FORWARD_PTR(obj); GCSTAT_FORWARD_COUNT(); DBG(("%p at %p forward -> %p", obj, slot, *slot)); return; } obj_size = OBJ_TOTAL_SIZE(obj); alloc_size = HEAP_ROUND_SIZE(obj_size); ASSERT(HEAP_REST(sml_heap_to_space) >= alloc_size); newobj = sml_heap_to_space.free; sml_heap_to_space.free += alloc_size; memcpy(&OBJ_HEADER(newobj), &OBJ_HEADER(obj), obj_size); GCSTAT_COPY_COUNT(obj_size); DBG(("%p at %p copy -> %p (%lu/%lu)", obj, slot, newobj, (unsigned long)obj_size, (unsigned long)alloc_size)); OBJ_HEADER(obj) |= GC_FORWARDED_FLAG; OBJ_FORWARD_PTR(obj) = newobj; *slot = newobj; }
static void trace(void **slot) { sml_trace_ptr(*slot); }
static void trace_outside(void *obj) { if (obj != NULL) sml_trace_ptr(obj); }