ruby-changes:29463
From: ko1 <ko1@a...>
Date: Fri, 21 Jun 2013 10:27:00 +0900 (JST)
Subject: [ruby-changes:29463] ko1:r41515 (trunk): * gc.c (heaps_header/heaps_slot): embed bitmaps into heaps_slot.
ko1 2013-06-21 10:26:50 +0900 (Fri, 21 Jun 2013) New Revision: 41515 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41515 Log: * gc.c (heaps_header/heaps_slot): embed bitmaps into heaps_slot. no need to maintain allocation/free bitmaps. Modified files: trunk/ChangeLog trunk/gc.c Index: ChangeLog =================================================================== --- ChangeLog (revision 41514) +++ ChangeLog (revision 41515) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Jun 21 10:21:44 2013 Koichi Sasada <ko1@a...> + + * 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@a...> * gc.c (slot_sweep_body): add counters at a time. Index: gc.c =================================================================== --- gc.c (revision 41514) +++ gc.c (revision 41515) @@ -126,7 +126,7 @@ void rb_gcdebug_print_obj_condition(VALU https://github.com/ruby/ruby/blob/trunk/gc.c#L126 * 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 { https://github.com/ruby/ruby/blob/trunk/gc.c#L253 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 { https://github.com/ruby/ruby/blob/trunk/gc.c#L299 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 { https://github.com/ruby/ruby/blob/trunk/gc.c#L403 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 https://github.com/ruby/ruby/blob/trunk/gc.c#L643 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 https://github.com/ruby/ruby/blob/trunk/gc.c#L667 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 *obj https://github.com/ruby/ruby/blob/trunk/gc.c#L684 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 *obj https://github.com/ruby/ruby/blob/trunk/gc.c#L700 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 https://github.com/ruby/ruby/blob/trunk/gc.c#L709 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 https://github.com/ruby/ruby/blob/trunk/gc.c#L729 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 https://github.com/ruby/ruby/blob/trunk/gc.c#L737 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 https://github.com/ruby/ruby/blob/trunk/gc.c#L757 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 https://github.com/ruby/ruby/blob/trunk/gc.c#L777 heaps->freelist = p; p++; } + link_free_heap_slot(objspace, heaps); } @@ -1153,12 +1111,6 @@ free_unused_heaps(rb_objspace_t *objspac https://github.com/ruby/ruby/blob/trunk/gc.c#L1111 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) https://github.com/ruby/ruby/blob/trunk/gc.c#L2136 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 https://github.com/ruby/ruby/blob/trunk/gc.c#L3504 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 *objspa https://github.com/ruby/ruby/blob/trunk/gc.c#L3520 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, r https://github.com/ruby/ruby/blob/trunk/gc.c#L3560 /* 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_obj https://github.com/ruby/ruby/blob/trunk/gc.c#L3759 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); } } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/