Last active
December 18, 2015 04:10
-
-
Save tarui/5722819 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ tail -n2 *.log | |
==> 193p194_1.log <== | |
21.601350999999987 | |
31.410000 0.490000 31.900000 ( 31.928621) | |
==> 193p194_2.log <== | |
20.781295 | |
29.910000 0.330000 30.240000 ( 30.335949) | |
==> 193p194_3.log <== | |
20.989313999999993 | |
30.600000 0.490000 31.090000 ( 31.232350) | |
==> head_normal_1.log <== | |
6.557318613000015 | |
18.600000 0.980000 19.580000 ( 19.618884) | |
==> head_normal_2.log <== | |
6.6902496179999975 | |
18.230000 0.880000 19.110000 ( 19.151318) | |
==> head_normal_3.log <== | |
6.592346428 | |
18.470000 0.920000 19.390000 ( 19.420451) | |
==> head_opt_1.log <== | |
6.486426495000009 | |
18.370000 1.050000 19.420000 ( 19.448033) | |
==> head_opt_2.log <== | |
6.33173724900001 | |
17.620000 0.870000 18.490000 ( 18.565018) | |
==> head_opt_3.log <== | |
6.196714822999994 | |
17.100000 0.830000 17.930000 ( 17.977732) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: gc.c | |
=================================================================== | |
--- gc.c (revision 41106) | |
+++ gc.c (working copy) | |
@@ -241,6 +241,7 @@ struct heaps_header { | |
uintptr_t *mark_bits; | |
#if USE_RGENGC | |
uintptr_t *rememberset_bits; | |
+ uintptr_t *oldgen_bits; | |
#endif | |
RVALUE *start; | |
RVALUE *end; | |
@@ -422,11 +423,17 @@ int *ruby_initial_gc_stress_ptr = &rb_objspace.gc_ | |
#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)) | |
-#define MARKED_IN_BITMAP(bits, p) (bits[BITMAP_INDEX(p)] & ((uintptr_t)1 << BITMAP_OFFSET(p))) | |
+#define BITMAP_BIT(p) ((uintptr_t)1 << BITMAP_OFFSET(p)) | |
+/* Marking */ | |
+#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)) | |
+ | |
#ifndef HEAP_ALIGN_LOG | |
/* default tiny heap size: 16KB */ | |
#define HEAP_ALIGN_LOG 14 | |
@@ -483,7 +490,7 @@ static const char *obj_type_name(VALUE obj); | |
#if USE_RGENGC | |
static int rgengc_remembered(rb_objspace_t *objspace, VALUE obj); | |
static void rgengc_remember(rb_objspace_t *objspace, VALUE obj); | |
-static void rgengc_rememberset_clear(rb_objspace_t *objspace); | |
+static void rgengc_mark_and_rememberset_clear(rb_objspace_t *objspace); | |
static size_t rgengc_rememberset_mark(rb_objspace_t *objspace); | |
#define FL_TEST2(x,f) ((RGENGC_CHECK_MODE && SPECIAL_CONST_P(x)) ? (rb_bug("FL_TEST2: SPECIAL_CONST"), 0) : FL_TEST_RAW((x),(f))) | |
@@ -493,11 +500,14 @@ static size_t rgengc_rememberset_mark(rb_objspace_ | |
#define RVALUE_SUNNY(x) FL_TEST2((x), FL_WB_PROTECTED) | |
#define RVALUE_SHADY(x) (!RVALUE_SUNNY(x)) | |
#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 | |
{ | |
rb_objspace_t *objspace = &rb_objspace; | |
@@ -508,7 +518,11 @@ RVALUE_PROMOTE(VALUE obj) | |
} | |
#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 | |
@@ -584,6 +598,7 @@ rb_objspace_free(rb_objspace_t *objspace) | |
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]); | |
} | |
@@ -625,7 +640,7 @@ allocate_sorted_heaps(rb_objspace_t *objspace, siz | |
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; | |
@@ -729,6 +744,7 @@ assign_heap_slot(rb_objspace_t *objspace) | |
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; | |
@@ -1077,6 +1093,7 @@ free_unused_heaps(rb_objspace_t *objspace) | |
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]; | |
@@ -1137,6 +1154,11 @@ obj_free(rb_objspace_t *objspace, VALUE obj) | |
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) && | |
@@ -2102,97 +2124,88 @@ gc_clear_slot_bits(struct heaps_slot *slot) | |
memset(slot->header->mark_bits, 0, HEAP_BITMAP_LIMIT * sizeof(uintptr_t)); | |
} | |
+#if USE_RGENGC | |
+static void | |
+gc_setup_mark_bits(struct heaps_slot *slot) | |
+{ | |
+ memcpy(slot->header->mark_bits, slot->header->oldgen_bits, HEAP_BITMAP_LIMIT * sizeof(uintptr_t)); | |
+} | |
+#endif | |
+ | |
static size_t | |
objspace_live_num(rb_objspace_t *objspace) | |
{ | |
return objspace->total_allocated_object_num - objspace->total_freed_object_num; | |
} | |
-static inline int | |
-living_object_p(rb_objspace_t *objspace, VALUE p, uintptr_t *bits, const int during_minor_gc) | |
-{ | |
-#if USE_RGENGC | |
- int reason = 0; | |
- | |
- if (during_minor_gc) { | |
- if (MARKED_IN_BITMAP(bits, p)) { | |
- reason = 1; | |
- } | |
- else if (RVALUE_PROMOTED(p)) { | |
- reason = 2; | |
- } | |
- } | |
- else { | |
- if (MARKED_IN_BITMAP(bits, p)) { | |
- reason = 1; | |
- } | |
- } | |
- | |
- if (RGENGC_DEBUG && reason > 0) { | |
- rgengc_report(5, objspace, "living_object_p: %p (%s) is living (%s).\n", | |
- (void *)p, obj_type_name(p), reason == 1 ? "marked" : "promoted"); | |
- } | |
- | |
- if (RGENGC_CHECK_MODE && reason == 0 && rgengc_remembered(objspace, p)) { | |
- rb_bug("living_object_p: %p (%s) is remembered, but not marked.\n", (void *)p, obj_type_name(p)); | |
- } | |
- | |
- return reason != 0; | |
-#else /* USE_RGENGC */ | |
- return MARKED_IN_BITMAP(bits, p) != 0; | |
-#endif | |
-} | |
- | |
static inline void | |
slot_sweep_body(rb_objspace_t *objspace, struct heaps_slot *sweep_slot, const int during_minor_gc) | |
{ | |
+ int i; | |
size_t empty_num = 0, freed_num = 0, final_num = 0; | |
- RVALUE *p, *pend; | |
+ RVALUE *p, *pend,*offset; | |
RVALUE *final = deferred_final_list; | |
int deferred; | |
- uintptr_t *bits; | |
+ uintptr_t *bits, bitset; | |
rgengc_report(3, objspace, "slot_sweep_body: start.\n"); | |
p = sweep_slot->header->start; pend = p + sweep_slot->header->limit; | |
+ offset = p - NUM_IN_SLOT(p); | |
bits = GET_HEAP_MARK_BITS(p); | |
- while (p < pend) { | |
- if (!living_object_p(objspace, (VALUE)p, bits, during_minor_gc) && BUILTIN_TYPE(p) != T_ZOMBIE) { | |
- if (p->as.basic.flags) { | |
- rgengc_report(3, objspace, "slot_sweep_body: free %p (%s)\n", p, obj_type_name((VALUE)p)); | |
+ /* create guard : fill 1 out-of-range */ | |
+ bits[BITMAP_INDEX(p)] |= BITMAP_BIT(p)-1; | |
+ bits[BITMAP_INDEX(pend)] |= ~(BITMAP_BIT(pend) - 1); | |
+ | |
+ for(i=0;i<HEAP_BITMAP_LIMIT;i++){ | |
+ bitset = ~bits[i]; | |
+ if(bitset){ | |
+ p = offset + i * (sizeof(uintptr_t) * CHAR_BIT); | |
+ do { | |
+ if ((bitset & 1) && BUILTIN_TYPE(p) != T_ZOMBIE) { | |
+ if (p->as.basic.flags) { | |
+ rgengc_report(3, objspace, "slot_sweep_body: free %p (%s)\n", p, obj_type_name((VALUE)p)); | |
#if USE_RGENGC && RGENGC_CHECK_MODE | |
- if (objspace->rgengc.during_minor_gc && RVALUE_PROMOTED(p)) rb_bug("slot_sweep_body: %p (%s) is promoted.\n", p, obj_type_name((VALUE)p)); | |
- if (rgengc_remembered(objspace, (VALUE)p)) rb_bug("slot_sweep_body: %p (%s) is remembered.\n", p, obj_type_name((VALUE)p)); | |
+ if (objspace->rgengc.during_minor_gc && RVALUE_PROMOTED(p)) rb_bug("slot_sweep_body: %p (%s) is promoted.\n", p, obj_type_name((VALUE)p)); | |
+ if (rgengc_remembered(objspace, (VALUE)p)) rb_bug("slot_sweep_body: %p (%s) is remembered.\n", p, obj_type_name((VALUE)p)); | |
#endif | |
- | |
- if ((deferred = obj_free(objspace, (VALUE)p)) || | |
- (FL_TEST(p, FL_FINALIZE))) { | |
- if (!deferred) { | |
- p->as.free.flags = T_ZOMBIE; | |
- RDATA(p)->dfree = 0; | |
- } | |
- p->as.free.next = deferred_final_list; | |
- deferred_final_list = p; | |
- assert(BUILTIN_TYPE(p) == T_ZOMBIE); | |
- final_num++; | |
- } | |
- else { | |
- (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE)); | |
- p->as.free.flags = 0; | |
- p->as.free.next = sweep_slot->freelist; | |
- sweep_slot->freelist = p; | |
- rgengc_report(3, objspace, "slot_sweep_body: %p (%s) is added to freelist\n", p, obj_type_name((VALUE)p)); | |
- freed_num++; | |
- } | |
- } | |
- else { | |
- empty_num++; | |
- } | |
- } | |
- p++; | |
+ if ((deferred = obj_free(objspace, (VALUE)p)) || | |
+ (FL_TEST(p, FL_FINALIZE))) { | |
+ if (!deferred) { | |
+ p->as.free.flags = T_ZOMBIE; | |
+ | |
+ RDATA(p)->dfree = 0; | |
+ } | |
+ p->as.free.next = deferred_final_list; | |
+ deferred_final_list = p; | |
+ assert(BUILTIN_TYPE(p) == T_ZOMBIE); | |
+ final_num++; | |
+ } | |
+ else { | |
+ (void)VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE)); | |
+ p->as.free.flags = 0; | |
+ p->as.free.next = sweep_slot->freelist; | |
+ sweep_slot->freelist = p; | |
+ rgengc_report(3, objspace, "slot_sweep_body: %p (%s) is added to freelist\n", p, obj_type_name((VALUE)p)); | |
+ freed_num++; | |
+ } | |
+ } | |
+ else { | |
+ empty_num++; | |
+ } | |
+ } | |
+ p++; | |
+ bitset >>= 1; | |
+ } while (bitset); | |
+ } | |
} | |
+#if USE_RGENGC | |
+ gc_setup_mark_bits(sweep_slot); | |
+#else | |
gc_clear_slot_bits(sweep_slot); | |
+#endif | |
+ | |
if (final_num + freed_num + empty_num == sweep_slot->header->limit && | |
objspace->heap.free_num > objspace->heap.do_heap_free) { | |
RVALUE *pp; | |
@@ -2562,12 +2575,7 @@ init_mark_stack(mark_stack_t *stack) | |
} | |
-/* Marking */ | |
-#define MARK_IN_BITMAP(bits, p) (bits[BITMAP_INDEX(p)] = bits[BITMAP_INDEX(p)] | ((uintptr_t)1 << BITMAP_OFFSET(p))) | |
-#define CLEAR_IN_BITMAP(bits, p) (bits[BITMAP_INDEX(p)] = bits[BITMAP_INDEX(p)] & ~((uintptr_t)1 << BITMAP_OFFSET(p))) | |
- | |
- | |
#ifdef __ia64 | |
#define SET_STACK_END (SET_MACHINE_STACK_END(&th->machine_stack_end), th->machine_register_stack_end = rb_ia64_bsp()) | |
#else | |
@@ -2990,15 +2998,6 @@ gc_mark(rb_objspace_t *objspace, VALUE ptr) | |
if (LIKELY(objspace->mark_func_data == 0)) { | |
rgengc_check_shady(objspace, ptr); | |
if (!gc_mark_ptr(objspace, ptr)) return; /* already marked */ | |
-#if USE_RGENGC | |
- if (objspace->rgengc.during_minor_gc) { | |
- /* only minor gc skip marking promoted objects */ | |
- if (RVALUE_PROMOTED(ptr)) { | |
- rgengc_report(3, objspace, "gc_mark: %p (%s) was promoted.\n", ptr, obj_type_name((VALUE)ptr)); | |
- return; /* old gen */ | |
- } | |
- } | |
-#endif /* USE_RGENGC */ | |
push_mark_stack(&objspace->mark_stack, ptr); | |
} | |
else { | |
@@ -3051,8 +3050,10 @@ gc_mark_children(rb_objspace_t *objspace, VALUE pt | |
/* minor/major common */ | |
if (RVALUE_SUNNY(obj)) { | |
- RVALUE_PROMOTE((VALUE)obj); /* Sunny 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(obj)){ | |
+ RVALUE_PROMOTE((VALUE)obj); /* Sunny 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++; | |
} | |
@@ -3370,7 +3371,7 @@ gc_marks_body(rb_objspace_t *objspace, rb_thread_t | |
} | |
else { | |
objspace->profile.major_gc_count++; | |
- rgengc_rememberset_clear(objspace); | |
+ rgengc_mark_and_rememberset_clear(objspace); | |
} | |
#endif | |
@@ -3428,22 +3429,24 @@ gc_marks_test(rb_objspace_t *objspace, rb_thread_t | |
{ | |
#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 */ | |
@@ -3454,8 +3457,9 @@ gc_marks_test(rb_objspace_t *objspace, rb_thread_t | |
/* 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; | |
@@ -3475,6 +3479,7 @@ gc_marks_test(rb_objspace_t *objspace, rb_thread_t | |
} | |
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); | |
@@ -3494,7 +3499,6 @@ gc_marks(rb_objspace_t *objspace, int minor_gc) | |
/* setup marking */ | |
prev_mark_func_data = objspace->mark_func_data; | |
objspace->mark_func_data = 0; | |
- | |
objspace->count++; | |
SET_STACK_END; | |
@@ -3606,10 +3610,10 @@ rgengc_rememberset_mark(rb_objspace_t *objspace) | |
if(bits[j]){ | |
p = offset + j * (sizeof(uintptr_t) * CHAR_BIT); | |
bitset = bits[j]; | |
- while (bitset) { | |
+ do { | |
if (bitset & 1) { | |
- if (gc_mark_ptr(objspace, (VALUE)p)) | |
- push_mark_stack(&objspace->mark_stack, (VALUE) p); | |
+ gc_mark_ptr(objspace, (VALUE)p); | |
+ push_mark_stack(&objspace->mark_stack, (VALUE) p); | |
rgengc_report(2, objspace, "rgengc_rememberset_mark: mark %p (%s)\n", p, obj_type_name((VALUE)p)); | |
if (RVALUE_SUNNY(p)) { | |
@@ -3621,8 +3625,8 @@ rgengc_rememberset_mark(rb_objspace_t *objspace) | |
} | |
} | |
p++; | |
- bitset>>=1; | |
- } | |
+ bitset >>= 1; | |
+ } while (bitset); | |
} | |
} | |
} | |
@@ -3633,13 +3637,13 @@ rgengc_rememberset_mark(rb_objspace_t *objspace) | |
} | |
static void | |
-rgengc_rememberset_clear(rb_objspace_t *objspace) | |
+rgengc_mark_and_rememberset_clear(rb_objspace_t *objspace) | |
{ | |
size_t i; | |
for (i=0; i<heaps_used; i++) { | |
- uintptr_t *bits = objspace->heap.sorted[i]->rememberset_bits; | |
- memset(bits, 0, HEAP_BITMAP_LIMIT * sizeof(uintptr_t)); | |
+ memset(objspace->heap.sorted[i]->mark_bits, 0, HEAP_BITMAP_LIMIT * sizeof(uintptr_t)); | |
+ memset(objspace->heap.sorted[i]->rememberset_bits, 0, HEAP_BITMAP_LIMIT * sizeof(uintptr_t)); | |
} | |
} | |
Index: tool/rdocbench.rb | |
=================================================================== | |
--- tool/rdocbench.rb (revision 41106) | |
+++ tool/rdocbench.rb (working copy) | |
@@ -16,6 +16,7 @@ Dir.mktmpdir('rdocbench-'){|d| | |
r.document args | |
GC::Profiler.report | |
pp GC.stat | |
+ puts "GC Total Time:#{GC::Profiler.total_time}" | |
} | |
} | |
} | |
Index: array.c | |
=================================================================== | |
--- array.c (revision 41106) | |
+++ array.c (working copy) | |
@@ -392,7 +392,7 @@ empty_ary_alloc(VALUE klass) | |
static VALUE | |
ary_new(VALUE klass, long capa) | |
{ | |
- VALUE ary; | |
+ VALUE ary,*ptr; | |
if (capa < 0) { | |
rb_raise(rb_eArgError, "negative array size (or size too big)"); | |
@@ -405,20 +405,16 @@ ary_new(VALUE klass, long capa) | |
RUBY_DTRACE_ARRAY_CREATE(capa, rb_sourcefile(), rb_sourceline()); | |
} | |
- ary = ary_alloc(klass); | |
if (capa > RARRAY_EMBED_LEN_MAX) { | |
+ ptr = ALLOC_N(VALUE, capa); | |
+ ary = ary_alloc(klass); | |
FL_UNSET_EMBED(ary); | |
- ARY_SET_PTR(ary, ALLOC_N(VALUE, capa)); | |
+ ARY_SET_PTR(ary, ptr); | |
ARY_SET_CAPA(ary, capa); | |
ARY_SET_HEAP_LEN(ary, 0); | |
+ } else { | |
+ ary = ary_alloc(klass); | |
- /* NOTE: `ary' can be old because the following suquence is possible. | |
- * (1) ary = ary_alloc(); | |
- * (2) GC (for (3)) -> promote ary | |
- * (3) ALLOC_N(VALUE, capa) | |
- * So that force ary as young object. | |
- */ | |
- RBASIC(ary)->flags &= ~FL_OLDGEN; | |
} | |
return ary; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'benchmark' | |
require 'pp' | |
#require 'google_hash' | |
#GC.disable | |
value = 0.01 | |
#h=GoogleHash.new | |
h = {} | |
n = 3*(10**6) | |
Benchmark.bm{|x| | |
x.report('hash'){ | |
s = Time.now | |
GC::Profiler.enable | |
1.upto(n){|i| | |
h["%020d" % i] = value * i | |
puts "#{i}(#{}) : #{Time.now - s}" if i % 500000 == 0 | |
} | |
GC::Profiler.report | |
pp GC.stat | |
p GC::Profiler.total_time | |
h | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment