Пример #1
0
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;
}
Пример #2
0
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);
    }
}
Пример #3
0
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));
	}
}
Пример #4
0
/* 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;
}
Пример #5
0
/* 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;
	}
}
Пример #6
0
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;
}
Пример #7
0
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 */
}
Пример #8
0
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 */

}