1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* gc.c (heaps_header/heaps_slot): embed bitmaps into heaps_slot.

no need to maintain allocation/free bitmaps.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41515 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2013-06-21 01:26:50 +00:00
parent 3cef99564b
commit 7986e98394
2 changed files with 58 additions and 98 deletions

View file

@ -1,3 +1,8 @@
Fri Jun 21 10:21:44 2013 Koichi Sasada <ko1@atdot.net>
* gc.c (heaps_header/heaps_slot): embed bitmaps into heaps_slot.
no need to maintain allocation/free bitmaps.
Fri Jun 21 09:22:16 2013 Koichi Sasada <ko1@atdot.net>
* gc.c (slot_sweep_body): add counters at a time.

151
gc.c
View file

@ -126,7 +126,7 @@ void rb_gcdebug_print_obj_condition(VALUE obj);
* 3: show all references
*/
#ifndef RGENGC_CHECK_MODE
#define RGENGC_CHECK_MODE 0
#define RGENGC_CHECK_MODE 2
#endif
/* RGENGC_PROFILE
@ -253,30 +253,13 @@ enum {
BITS_BITLENGTH = ( BITS_SIZE * CHAR_BIT )
};
struct heaps_slot {
struct heaps_header *header;
RVALUE *freelist;
struct heaps_slot *next;
struct heaps_slot *prev;
struct heaps_slot *free_next;
};
struct heaps_header {
struct heaps_slot *base;
bits_t *mark_bits;
#if USE_RGENGC
bits_t *rememberset_bits;
bits_t *oldgen_bits;
#endif
RVALUE *start;
RVALUE *end;
size_t limit;
};
struct heaps_free_bitmap {
struct heaps_free_bitmap *next;
};
struct gc_list {
VALUE *varptr;
struct gc_list *next;
@ -316,7 +299,6 @@ typedef struct rb_objspace {
struct heaps_header **sorted;
size_t length;
size_t used;
struct heaps_free_bitmap *free_bitmap;
RVALUE *range[2];
struct heaps_header *freed;
size_t free_num;
@ -421,20 +403,34 @@ enum {
HEAP_BITMAP_PLANES = USE_RGENGC ? 3 : 1 /* RGENGC: mark bits, rememberset bits and oldgen bits */
};
#define HEAP_HEADER(p) ((struct heaps_header *)(p))
#define GET_HEAP_HEADER(x) (HEAP_HEADER((bits_t)(x) & ~(HEAP_ALIGN_MASK)))
#define GET_HEAP_SLOT(x) (GET_HEAP_HEADER(x)->base)
#define GET_HEAP_MARK_BITS(x) (GET_HEAP_HEADER(x)->mark_bits)
#define GET_HEAP_REMEMBERSET_BITS(x) (GET_HEAP_HEADER(x)->rememberset_bits)
#define GET_HEAP_OLDGEN_BITS(x) (GET_HEAP_HEADER(x)->oldgen_bits)
#define NUM_IN_SLOT(p) (((bits_t)(p) & HEAP_ALIGN_MASK)/sizeof(RVALUE))
#define BITMAP_INDEX(p) (NUM_IN_SLOT(p) / BITS_BITLENGTH )
#define BITMAP_OFFSET(p) (NUM_IN_SLOT(p) & (BITS_BITLENGTH-1))
#define BITMAP_BIT(p) ((bits_t)1 << BITMAP_OFFSET(p))
struct heaps_slot {
struct heaps_header *header;
RVALUE *freelist;
struct heaps_slot *next;
struct heaps_slot *prev;
struct heaps_slot *free_next;
bits_t mark_bits[HEAP_BITMAP_LIMIT];
#if USE_RGENGC
bits_t rememberset_bits[HEAP_BITMAP_LIMIT];
bits_t oldgen_bits[HEAP_BITMAP_LIMIT];
#endif
};
#define HEAP_HEADER(p) ((struct heaps_header *)(p))
#define GET_HEAP_HEADER(x) (HEAP_HEADER((bits_t)(x) & ~(HEAP_ALIGN_MASK)))
#define GET_HEAP_SLOT(x) (GET_HEAP_HEADER(x)->base)
#define GET_HEAP_MARK_BITS(x) (&GET_HEAP_SLOT(x)->mark_bits[0])
#define GET_HEAP_REMEMBERSET_BITS(x) (&GET_HEAP_SLOT(x)->rememberset_bits[0])
#define GET_HEAP_OLDGEN_BITS(x) (&GET_HEAP_SLOT(x)->oldgen_bits[0])
#define NUM_IN_SLOT(p) (((bits_t)(p) & HEAP_ALIGN_MASK)/sizeof(RVALUE))
#define BITMAP_INDEX(p) (NUM_IN_SLOT(p) / BITS_BITLENGTH )
#define BITMAP_OFFSET(p) (NUM_IN_SLOT(p) & (BITS_BITLENGTH-1))
#define BITMAP_BIT(p) ((bits_t)1 << BITMAP_OFFSET(p))
/* Bitmap Operations */
#define MARKED_IN_BITMAP(bits, p) (bits[BITMAP_INDEX(p)] & BITMAP_BIT(p))
#define MARK_IN_BITMAP(bits, p) (bits[BITMAP_INDEX(p)] = bits[BITMAP_INDEX(p)] | BITMAP_BIT(p))
#define CLEAR_IN_BITMAP(bits, p) (bits[BITMAP_INDEX(p)] = bits[BITMAP_INDEX(p)] & ~BITMAP_BIT(p))
#define MARKED_IN_BITMAP(bits, p) ((bits)[BITMAP_INDEX(p)] & BITMAP_BIT(p))
#define MARK_IN_BITMAP(bits, p) ((bits)[BITMAP_INDEX(p)] = (bits)[BITMAP_INDEX(p)] | BITMAP_BIT(p))
#define CLEAR_IN_BITMAP(bits, p) ((bits)[BITMAP_INDEX(p)] = (bits)[BITMAP_INDEX(p)] & ~BITMAP_BIT(p))
/* Aliases */
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
@ -647,21 +643,9 @@ rb_objspace_free(rb_objspace_t *objspace)
xfree(list);
}
}
if (objspace->heap.free_bitmap) {
struct heaps_free_bitmap *list, *next;
for (list = objspace->heap.free_bitmap; list; list = next) {
next = list->next;
free(list);
}
}
if (objspace->heap.sorted) {
size_t i;
for (i = 0; i < heaps_used; ++i) {
free(objspace->heap.sorted[i]->mark_bits);
#if USE_RGENGC
free(objspace->heap.sorted[i]->rememberset_bits);
free(objspace->heap.sorted[i]->oldgen_bits);
#endif
aligned_free(objspace->heap.sorted[i]);
}
free(objspace->heap.sorted);
@ -683,8 +667,7 @@ static void
allocate_sorted_heaps(rb_objspace_t *objspace, size_t next_heaps_length)
{
struct heaps_header **p;
struct heaps_free_bitmap *bits;
size_t size, add, i;
size_t size, add;
size = next_heaps_length*sizeof(struct heaps_header *);
add = next_heaps_length - heaps_used;
@ -701,17 +684,6 @@ allocate_sorted_heaps(rb_objspace_t *objspace, size_t next_heaps_length)
during_gc = 0;
rb_memerror();
}
for (i = 0; i < add * HEAP_BITMAP_PLANES; i++) {
bits = (struct heaps_free_bitmap *)malloc(HEAP_BITMAP_SIZE);
if (bits == 0) {
during_gc = 0;
rb_memerror();
return;
}
bits->next = objspace->heap.free_bitmap;
objspace->heap.free_bitmap = bits;
}
}
static void
@ -728,23 +700,6 @@ unlink_free_heap_slot(rb_objspace_t *objspace, struct heaps_slot *slot)
slot->free_next = NULL;
}
static bits_t *
alloc_bitmap(rb_objspace_t *objspace)
{
bits_t *bits = (bits_t *)objspace->heap.free_bitmap;
assert(objspace->heap.free_bitmap != NULL);
objspace->heap.free_bitmap = objspace->heap.free_bitmap->next;
memset(bits, 0, HEAP_BITMAP_SIZE);
return bits;
}
static void
free_bitmap(rb_objspace_t *objspace, bits_t *bits)
{
((struct heaps_free_bitmap *)(bits))->next = objspace->heap.free_bitmap;
objspace->heap.free_bitmap = (struct heaps_free_bitmap *)bits;
}
static void
assign_heap_slot(rb_objspace_t *objspace)
{
@ -754,11 +709,14 @@ assign_heap_slot(rb_objspace_t *objspace)
size_t objs;
objs = HEAP_OBJ_LIMIT;
p = (RVALUE*)aligned_malloc(HEAP_ALIGN, HEAP_SIZE);
if (p == 0) {
during_gc = 0;
rb_memerror();
}
/* assign heaps_slot entry */
slot = (struct heaps_slot *)malloc(sizeof(struct heaps_slot));
if (slot == 0) {
aligned_free(p);
@ -771,6 +729,7 @@ assign_heap_slot(rb_objspace_t *objspace)
if (heaps) heaps->prev = slot;
heaps = slot;
/* adjust objs (object number available in this slot) */
membase = p;
p = (RVALUE*)((VALUE)p + sizeof(struct heaps_header));
if ((VALUE)p % sizeof(RVALUE) != 0) {
@ -778,6 +737,7 @@ assign_heap_slot(rb_objspace_t *objspace)
objs = (HEAP_SIZE - (size_t)((VALUE)p - (VALUE)membase))/sizeof(RVALUE);
}
/* setup objspace->heap.sorted */
lo = 0;
hi = heaps_used;
while (lo < hi) {
@ -797,17 +757,14 @@ assign_heap_slot(rb_objspace_t *objspace)
if (hi < heaps_used) {
MEMMOVE(&objspace->heap.sorted[hi+1], &objspace->heap.sorted[hi], struct heaps_header*, heaps_used - hi);
}
/* setup header */
heaps->header = (struct heaps_header *)membase;
objspace->heap.sorted[hi] = heaps->header;
objspace->heap.sorted[hi]->start = p;
objspace->heap.sorted[hi]->end = (p + objs);
objspace->heap.sorted[hi]->base = heaps;
objspace->heap.sorted[hi]->limit = objs;
objspace->heap.sorted[hi]->mark_bits = alloc_bitmap(objspace);
#if USE_RGENGC
objspace->heap.sorted[hi]->rememberset_bits = alloc_bitmap(objspace);
objspace->heap.sorted[hi]->oldgen_bits = alloc_bitmap(objspace);
#endif
pend = p + objs;
if (lomem == 0 || lomem > p) lomem = p;
if (himem < pend) himem = pend;
@ -820,6 +777,7 @@ assign_heap_slot(rb_objspace_t *objspace)
heaps->freelist = p;
p++;
}
link_free_heap_slot(objspace, heaps);
}
@ -1153,12 +1111,6 @@ free_unused_heaps(rb_objspace_t *objspace)
for (i = j = 1; j < heaps_used; i++) {
if (objspace->heap.sorted[i]->limit == 0) {
struct heaps_header* h = objspace->heap.sorted[i];
free_bitmap(objspace, h->mark_bits);
#if USE_RGENGC
free_bitmap(objspace, h->rememberset_bits);
free_bitmap(objspace, h->oldgen_bits);
#endif
if (!last) {
last = objspace->heap.sorted[i];
}
@ -2184,13 +2136,13 @@ lazy_sweep_enable(void)
static void
gc_clear_slot_bits(struct heaps_slot *slot)
{
memset(slot->header->mark_bits, 0, HEAP_BITMAP_SIZE);
memset(&slot->mark_bits[0], 0, HEAP_BITMAP_SIZE);
}
#else
static void
gc_setup_mark_bits(struct heaps_slot *slot)
{
memcpy(slot->header->mark_bits, slot->header->oldgen_bits, HEAP_BITMAP_SIZE);
memcpy(&slot->mark_bits[0], &slot->oldgen_bits[0], HEAP_BITMAP_SIZE);
}
#endif
@ -3552,9 +3504,11 @@ gc_store_bitmaps(rb_objspace_t *objspace)
if (stored_bitmaps == 0) rb_bug("gc_store_bitmaps: not enough memory to test.\n");
for (i=0; i<heaps_used; i++) {
memcpy(&stored_bitmaps[(3*i+0)*HEAP_BITMAP_LIMIT], objspace->heap.sorted[i]->mark_bits, HEAP_BITMAP_SIZE);
memcpy(&stored_bitmaps[(3*i+1)*HEAP_BITMAP_LIMIT], objspace->heap.sorted[i]->rememberset_bits, HEAP_BITMAP_SIZE);
memcpy(&stored_bitmaps[(3*i+2)*HEAP_BITMAP_LIMIT], objspace->heap.sorted[i]->oldgen_bits, HEAP_BITMAP_SIZE);
struct heaps_slot *slot = objspace->heap.sorted[i]->base;
memcpy(&stored_bitmaps[(3*i+0)*HEAP_BITMAP_LIMIT], &slot->mark_bits[0], HEAP_BITMAP_SIZE);
memcpy(&stored_bitmaps[(3*i+1)*HEAP_BITMAP_LIMIT], &slot->rememberset_bits[0], HEAP_BITMAP_SIZE);
memcpy(&stored_bitmaps[(3*i+2)*HEAP_BITMAP_LIMIT], &slot->oldgen_bits[0], HEAP_BITMAP_SIZE);
}
return stored_bitmaps;
@ -3566,15 +3520,15 @@ gc_restore_bitmaps(rb_objspace_t *objspace, bits_t *stored_bitmaps)
size_t i;
for (i=0; i<heaps_used; i++) {
bits_t *oldgen_bits = objspace->heap.sorted[i]->oldgen_bits;
struct heaps_slot *slot = objspace->heap.sorted[i]->base;
bits_t *oldgen_bits = &slot->oldgen_bits[0];
RVALUE *p = objspace->heap.sorted[i]->start;
RVALUE *pend = p + objspace->heap.sorted[i]->limit;
/* restore bitmaps */
memcpy(objspace->heap.sorted[i]->mark_bits, &stored_bitmaps[(3*i+0)*HEAP_BITMAP_LIMIT], HEAP_BITMAP_SIZE);
memcpy(objspace->heap.sorted[i]->rememberset_bits, &stored_bitmaps[(3*i+1)*HEAP_BITMAP_LIMIT], HEAP_BITMAP_SIZE);
memcpy(objspace->heap.sorted[i]->oldgen_bits, &stored_bitmaps[(3*i+2)*HEAP_BITMAP_LIMIT], HEAP_BITMAP_SIZE);
memcpy(&slot->mark_bits[0], &stored_bitmaps[(3*i+0)*HEAP_BITMAP_LIMIT], HEAP_BITMAP_SIZE);
memcpy(&slot->rememberset_bits[0], &stored_bitmaps[(3*i+1)*HEAP_BITMAP_LIMIT], HEAP_BITMAP_SIZE);
memcpy(&slot->oldgen_bits[0], &stored_bitmaps[(3*i+2)*HEAP_BITMAP_LIMIT], HEAP_BITMAP_SIZE);
/* resotre oldgen bits */
while (p < pend) {
@ -3606,7 +3560,7 @@ gc_marks_test(rb_objspace_t *objspace, rb_thread_t *th, bits_t *before_stored_bi
/* check */
for (i=0; i<heaps_used; i++) {
bits_t *minor_mark_bits = &stored_bitmaps[(3*i+0)*HEAP_BITMAP_LIMIT];
bits_t *major_mark_bits = objspace->heap.sorted[i]->mark_bits;
bits_t *major_mark_bits = objspace->heap.sorted[i]->base->mark_bits;
RVALUE *p = objspace->heap.sorted[i]->start;
RVALUE *pend = p + objspace->heap.sorted[i]->limit;
@ -3805,8 +3759,9 @@ rgengc_mark_and_rememberset_clear(rb_objspace_t *objspace)
size_t i;
for (i=0; i<heaps_used; i++) {
memset(objspace->heap.sorted[i]->mark_bits, 0, HEAP_BITMAP_SIZE);
memset(objspace->heap.sorted[i]->rememberset_bits, 0, HEAP_BITMAP_SIZE);
struct heaps_slot *slot = objspace->heap.sorted[i]->base;
memset(&slot->mark_bits[0], 0, HEAP_BITMAP_SIZE);
memset(&slot->rememberset_bits[0], 0, HEAP_BITMAP_SIZE);
}
}