static size_t heap_filled(struct heap_space *heap, size_t *ret_bytes) { char *p = HEAP_START(*heap); size_t filled = 0, count = 0; while (p < heap->free) { count++; filled += OBJ_TOTAL_SIZE(p); p += HEAP_ROUND_SIZE(OBJ_TOTAL_SIZE(p)); } if (ret_bytes) *ret_bytes = filled; return count; }
static void print_heap_occupancy() { unsigned int i; if (gcstat.verbose < GCSTAT_VERBOSE_HEAP) return; stat_notice("heap:"); for (i = 0; i < THE_NUMBER_OF_FIXED_BLOCK; i++) { unsigned int count = 0; unsigned long filled = 0; struct bitmap_info_space *b_info = &bitmap_info[i]; char *end = (char*)bitmap_info[i].obj_base + (heap_layout[i].block_counts << bitmap_info[i].block_size_log); char *p = b_info->obj_base; bitptr b, b_end = b_info->bitmap; if (b_end.mask == 0) b_end.mask = ~0U; CLEAR_BITPTR(b, b_info->base); while (p < end) { if (b.cur < b_end.cur || (b.cur == b_end.cur && b.mask < b_end.mask) || TEST_BITPTR(b)) count++, filled += OBJ_TOTAL_SIZE(p); SUCC_BITPTR(b); p += b_info->block_size_bytes; } stat_notice(" %lu:", (unsigned long)b_info->block_size_bytes); stat_notice(" - {filled: %lu, count: %u, used: %u}", filled, count, count << bitmap_info[i].block_size_log); } }
static void forward_region(void *start) { char *cur = start; DBG(("%p - %p", start, sml_heap_to_space.free)); while (cur < sml_heap_to_space.free) { forward_children(cur); cur += HEAP_ROUND_SIZE(OBJ_TOTAL_SIZE(cur)); } }
/* for debug or GCSTAT */ static size_t segment_filled(struct segment *seg, size_t filled_index, size_t *ret_bytes) { unsigned int i; bitptr_t b; char *p = BLOCK_BASE(seg); size_t filled = 0, count = 0; const size_t blocksize = BLOCK_SIZE(seg); BITPTR_INIT(b, BITMAP0_BASE(seg), 0); for (i = 0; i < seg->layout->num_blocks; i++) { if (i < filled_index || BITPTR_TEST(b)) { ASSERT(OBJ_TOTAL_SIZE(p) <= blocksize); count++; filled += OBJ_TOTAL_SIZE(p); } BITPTR_INC(b); p += blocksize; } if (ret_bytes) *ret_bytes = filled; return count; }
/* for debug */ void sml_heap_dump() { char *cur; unsigned int size, allocsize; sml_debug("from space : %p - %p\n", HEAP_START(sml_heap_from_space), sml_heap_from_space.limit); cur = HEAP_START(sml_heap_from_space); while (cur < sml_heap_from_space.free) { size = OBJ_TOTAL_SIZE(cur); allocsize = HEAP_ROUND_SIZE(size); sml_debug("%p : type=%08x, size=%u, total=%u, alloc=%u\n", cur, OBJ_TYPE(cur), OBJ_SIZE(cur), size, allocsize); cur += allocsize; } }
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 mark(void **slot) { struct bitmap_info_space *b_info; unsigned int obj_size, alloc_size; unsigned int tmp,tmp_index; unsigned int *tmp_bitmap; void *obj = *slot; #ifdef PRINT_ALLOC_TIME count_call_mark++; #endif /* PRINT_ALLOC_TIME */ #define OUTSIDE(obj) do{trace_outside(obj); return;}while(0) MAPPING_HEAP_MARK(obj,b_info,slot,OUTSIDE); #undef OUTSIDE //marked check and mark tmp = FROM_HEAP_TO_BITMAP(b_info,obj); tmp_index = tmp >> 5; tmp_bitmap = (unsigned int *)b_info->base + tmp_index; tmp = (unsigned int)0x01 << (tmp & 0x0000001f); #ifdef GCSTAT gcstat.last.trace_count++; #endif /* GCSTAT */ if(*tmp_bitmap & tmp) { DBG(("%p at %p already marked", obj, slot)); #ifdef PRINT_ALLOC_TIME count_not_mark++; #endif /* PRINT_ALLOC_TIME */ return; } *tmp_bitmap |= tmp; //mark //tree check unsigned int i; for(i=0; (*tmp_bitmap == 0xffffffff)&&(i < b_info->rank); i++) { tmp = ((unsigned int)0x01 << (tmp_index & 0x0000001f)); tmp_index >>= 5; tmp_bitmap = (unsigned int *)b_info->tree[i] + tmp_index; *tmp_bitmap |= tmp; } DBG(("%p at %p mark (%"PRIuMAX", %"PRIuMAX")", obj, slot, (intmax_t)obj_size, (intmax_t)alloc_size)); #ifdef PRINT_ALLOC_TIME print_info[b_info - bitmap_info].count_mark++; live_tmp += HEAP_ROUND_SIZE(OBJ_TOTAL_SIZE(obj)); #endif /* PRINT_ALLOC_TIME */ /* STACK_PUSH */ (*(marking_stack.top)) = obj; marking_stack.top++; #ifdef GCSTAT gcstat.last.push_count++; #endif /* GCSTAT */ }
SML_PRIMITIVE void sml_write(void *objaddr, void **writeaddr, void *new_value) { *writeaddr = new_value; #ifndef NOT_CLEAR_BITMAP if (IS_IN_HEAP_SPACE(writeaddr)) return; /* remember the writeaddr as a root pointer which is outside * of the heap. */ sml_global_barrier(writeaddr, objaddr); #else /* NOT_CLEAR_BITMAP */ struct bitmap_info_space *b_info; unsigned int obj_size, alloc_size; unsigned int tmp,tmp_index; unsigned int *tmp_bitmap; void *obj = *writeaddr; if (!(IS_IN_HEAP_SPACE(writeaddr))) sml_global_barrier(writeaddr, objaddr); #ifdef PRINT_ALLOC_TIME count_call_mark++; #endif /* PRINT_ALLOC_TIME */ #define OUTSIDE(obj) do{trace_outside(obj); return;}while(0) MAPPING_HEAP_MARK(obj,b_info,NULL,OUTSIDE); #undef OUTSIDE //marked check and mark tmp = FROM_HEAP_TO_BITMAP(b_info,obj); tmp_index = tmp >> 5; tmp_bitmap = (unsigned int *)b_info->base + tmp_index; tmp = (unsigned int)0x01 << (tmp & 0x0000001f); if(*tmp_bitmap & tmp) { DBG(("%p at %p already marked", obj, NULL)); #ifdef PRINT_ALLOC_TIME count_not_mark++; #endif /* PRINT_ALLOC_TIME */ return; } *tmp_bitmap |= tmp; //mark //tree check unsigned int i; for(i=0; (*tmp_bitmap == 0xffffffff)&&(i < b_info->rank); i++) { tmp = ((unsigned int)0x01 << (tmp_index & 0x0000001f)); tmp_index >>= 5; tmp_bitmap = (unsigned int *)b_info->tree[i] + tmp_index; *tmp_bitmap |= tmp; } DBG(("%p at %p mark (%"PRIuMAX", %"PRIuMAX")", obj, NULL, (intmax_t)obj_size, (intmax_t)alloc_size)); #ifdef PRINT_ALLOC_TIME print_info[b_info - bitmap_info].count_mark++; live_tmp += HEAP_ROUND_SIZE(OBJ_TOTAL_SIZE(obj)); #endif /* PRINT_ALLOC_TIME */ /* STACK_PUSH */ (*(marking_stack.top)) = obj; marking_stack.top++; #endif /* NOT_CLEAR_BITMAP */ }