ruby-changes:29075
From: tarui <ko1@a...>
Date: Fri, 7 Jun 2013 11:28:13 +0900 (JST)
Subject: [ruby-changes:29075] tarui:r41127 (trunk): * gc.c: introduce oldgen bitmap for preparing performance tuning.
tarui 2013-06-07 11:28:03 +0900 (Fri, 07 Jun 2013) New Revision: 41127 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41127 Log: * gc.c: introduce oldgen bitmap for preparing performance tuning. Modified files: trunk/ChangeLog trunk/gc.c Index: ChangeLog =================================================================== --- ChangeLog (revision 41126) +++ ChangeLog (revision 41127) @@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Jun 7 11:25:56 2013 Masaya Tarui <tarui@r...> + + * gc.c: introduce oldgen bitmap for preparing performance tuning. + Fri Jun 7 11:20:57 2013 Masaya Tarui <tarui@r...> * gc.c (MARKED_IN_BITMAP, MARK_IN_BITMAP, CLEAR_IN_BITMAP): bring Index: gc.c =================================================================== --- gc.c (revision 41126) +++ gc.c (revision 41127) @@ -241,6 +241,7 @@ struct heaps_header { https://github.com/ruby/ruby/blob/trunk/gc.c#L241 uintptr_t *mark_bits; #if USE_RGENGC uintptr_t *rememberset_bits; + uintptr_t *oldgen_bits; #endif RVALUE *start; RVALUE *end; @@ -422,6 +423,7 @@ int *ruby_initial_gc_stress_ptr = &rb_ob https://github.com/ruby/ruby/blob/trunk/gc.c#L423 #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) (((uintptr_t)(p) & HEAP_ALIGN_MASK)/sizeof(RVALUE)) #define BITMAP_INDEX(p) (NUM_IN_SLOT(p) / (sizeof(uintptr_t) * CHAR_BIT)) #define BITMAP_OFFSET(p) (NUM_IN_SLOT(p) & ((sizeof(uintptr_t) * CHAR_BIT)-1)) @@ -497,10 +499,12 @@ static size_t rgengc_rememberset_mark(rb https://github.com/ruby/ruby/blob/trunk/gc.c#L499 #define RVALUE_SHADY(x) (!FL_TEST2((x), FL_WB_PROTECTED)) #define RVALUE_PROMOTED(x) FL_TEST2((x), FL_OLDGEN) +#define RVALUE_PROMOTED_FROM_BITMAP(x) MARKED_IN_BITMAP(GET_HEAP_OLDGEN_BITS(x),x) static inline void RVALUE_PROMOTE(VALUE obj) { + MARK_IN_BITMAP(GET_HEAP_OLDGEN_BITS(obj), obj); FL_SET2(obj, FL_OLDGEN); #if RGENGC_PROFILE >= 1 { @@ -512,7 +516,11 @@ RVALUE_PROMOTE(VALUE obj) https://github.com/ruby/ruby/blob/trunk/gc.c#L516 } #endif } -#define RVALUE_DEMOTE(x) FL_UNSET2((x), FL_OLDGEN) +#define RVALUE_DEMOTE(x) do{ \ + FL_UNSET2((x), FL_OLDGEN); \ + CLEAR_IN_BITMAP(GET_HEAP_OLDGEN_BITS(obj), obj); \ + }while(0) + #endif static void @@ -588,6 +596,7 @@ rb_objspace_free(rb_objspace_t *objspace https://github.com/ruby/ruby/blob/trunk/gc.c#L596 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]); } @@ -629,7 +638,7 @@ allocate_sorted_heaps(rb_objspace_t *obj https://github.com/ruby/ruby/blob/trunk/gc.c#L638 rb_memerror(); } - for (i = 0; i < add * (USE_RGENGC ? 2 : 1) /* mark bits and rememberset bits */; i++) { + for (i = 0; i < add * (USE_RGENGC ? 3 : 1) /* mark bits and rememberset bits and oldgen bits */; i++) { bits = (struct heaps_free_bitmap *)malloc(HEAP_BITMAP_LIMIT * sizeof(uintptr_t)); if (bits == 0) { during_gc = 0; @@ -733,6 +742,7 @@ assign_heap_slot(rb_objspace_t *objspace https://github.com/ruby/ruby/blob/trunk/gc.c#L742 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; @@ -1081,6 +1091,7 @@ free_unused_heaps(rb_objspace_t *objspac https://github.com/ruby/ruby/blob/trunk/gc.c#L1091 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]; @@ -1141,6 +1152,11 @@ obj_free(rb_objspace_t *objspace, VALUE https://github.com/ruby/ruby/blob/trunk/gc.c#L1152 FL_UNSET(obj, FL_EXIVAR); } +#if USE_RGENGC + if (MARKED_IN_BITMAP(GET_HEAP_OLDGEN_BITS(obj),obj)) + CLEAR_IN_BITMAP(GET_HEAP_OLDGEN_BITS(obj),obj); +#endif + switch (BUILTIN_TYPE(obj)) { case T_OBJECT: if (!(RANY(obj)->as.basic.flags & ROBJECT_EMBED) && @@ -3049,8 +3065,10 @@ gc_mark_children(rb_objspace_t *objspace https://github.com/ruby/ruby/blob/trunk/gc.c#L3065 /* minor/major common */ if (!RVALUE_SHADY(obj)) { - RVALUE_PROMOTE((VALUE)obj); /* non-shady object can be promoted to OLDGEN object */ - rgengc_report(3, objspace, "gc_mark_children: promote %p (%s).\n", (void *)obj, obj_type_name((VALUE)obj)); + if (!RVALUE_PROMOTED((VALUE)obj)) { + RVALUE_PROMOTE((VALUE)obj); /* non-shady object can be promoted to OLDGEN object */ + rgengc_report(3, objspace, "gc_mark_children: promote %p (%s).\n", (void *)obj, obj_type_name((VALUE)obj)); + } objspace->rgengc.parent_object_is_promoted = TRUE; objspace->rgengc.oldgen_object_count++; } @@ -3426,22 +3444,24 @@ gc_marks_test(rb_objspace_t *objspace, r https://github.com/ruby/ruby/blob/trunk/gc.c#L3444 { #if USE_RGENGC size_t i; - uintptr_t **prev_bitmaps = (uintptr_t **)malloc(sizeof(uintptr_t **) * heaps_used * 2); - uintptr_t *temp_bitmaps = (uintptr_t *)malloc((HEAP_BITMAP_LIMIT * sizeof(uintptr_t)) * heaps_used * 2); + uintptr_t **prev_bitmaps = (uintptr_t **)malloc(sizeof(uintptr_t **) * heaps_used * 3); + uintptr_t *temp_bitmaps = (uintptr_t *)malloc((HEAP_BITMAP_LIMIT * sizeof(uintptr_t)) * heaps_used * 3); rgengc_report(1, objspace, "gc_marks_test: test-full-gc\n"); if (prev_bitmaps == 0 || temp_bitmaps == 0) { rb_bug("gc_marks_test: not enough memory to test.\n"); } - memset(temp_bitmaps, 0, (HEAP_BITMAP_LIMIT * sizeof(uintptr_t)) * heaps_used * 2); + memset(temp_bitmaps, 0, (HEAP_BITMAP_LIMIT * sizeof(uintptr_t)) * heaps_used * 3); /* swap with temporary bitmaps */ for (i=0; i<heaps_used; i++) { - prev_bitmaps[2*i+0] = objspace->heap.sorted[i]->mark_bits; - prev_bitmaps[2*i+1] = objspace->heap.sorted[i]->rememberset_bits; - objspace->heap.sorted[i]->mark_bits = &temp_bitmaps[(2*i+0)*HEAP_BITMAP_LIMIT]; - objspace->heap.sorted[i]->rememberset_bits = &temp_bitmaps[(2*i+1)*HEAP_BITMAP_LIMIT]; + prev_bitmaps[3*i+0] = objspace->heap.sorted[i]->mark_bits; + prev_bitmaps[3*i+1] = objspace->heap.sorted[i]->rememberset_bits; + prev_bitmaps[3*i+2] = objspace->heap.sorted[i]->oldgen_bits; + objspace->heap.sorted[i]->mark_bits = &temp_bitmaps[(3*i+0)*HEAP_BITMAP_LIMIT]; + objspace->heap.sorted[i]->rememberset_bits = &temp_bitmaps[(3*i+1)*HEAP_BITMAP_LIMIT]; + objspace->heap.sorted[i]->oldgen_bits = &temp_bitmaps[(3*i+2)*HEAP_BITMAP_LIMIT]; } /* run major (full) gc with temporary mark/rememberset */ @@ -3452,8 +3472,9 @@ gc_marks_test(rb_objspace_t *objspace, r https://github.com/ruby/ruby/blob/trunk/gc.c#L3472 /* check & restore */ for (i=0; i<heaps_used; i++) { - uintptr_t *minor_mark_bits = prev_bitmaps[2*i+0]; - uintptr_t *minor_rememberset_bits = prev_bitmaps[2*i+1]; + uintptr_t *minor_mark_bits = prev_bitmaps[3*i+0]; + uintptr_t *minor_rememberset_bits = prev_bitmaps[3*i+1]; + uintptr_t *minor_oldgen_bits = prev_bitmaps[3*i+2]; uintptr_t *major_mark_bits = objspace->heap.sorted[i]->mark_bits; /* uintptr_t *major_rememberset_bits = objspace->heap.sorted[i]->rememberset_bits; */ RVALUE *p = objspace->heap.sorted[i]->start; @@ -3473,6 +3494,7 @@ gc_marks_test(rb_objspace_t *objspace, r https://github.com/ruby/ruby/blob/trunk/gc.c#L3494 } objspace->heap.sorted[i]->mark_bits = minor_mark_bits; objspace->heap.sorted[i]->rememberset_bits = minor_rememberset_bits; + objspace->heap.sorted[i]->oldgen_bits = minor_oldgen_bits; } free(prev_bitmaps); free(temp_bitmaps); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/