ruby-changes:34254
From: ko1 <ko1@a...>
Date: Tue, 3 Jun 2014 16:50:30 +0900 (JST)
Subject: [ruby-changes:34254] ko1:r46335 (trunk): * gc.c: add verifying counters code in gc_verify_internal_consistency().
ko1 2014-06-03 16:50:23 +0900 (Tue, 03 Jun 2014) New Revision: 46335 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=46335 Log: * gc.c: add verifying counters code in gc_verify_internal_consistency(). gc_verify_internal_consistency() counts all - live objects - young objects (if age2 promotion) - old objects in all pages and compares with objspace managing counters. * gc.c (gc_after_sweep): do gc_verify_internal_consistency() when RGENGC_CHECK_MODE >= 2. Modified files: trunk/ChangeLog trunk/gc.c Index: ChangeLog =================================================================== --- ChangeLog (revision 46334) +++ ChangeLog (revision 46335) @@ -1,3 +1,15 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Jun 3 16:38:19 2014 Koichi Sasada <ko1@a...> + + * gc.c: add verifying counters code in gc_verify_internal_consistency(). + gc_verify_internal_consistency() counts all + - live objects + - young objects (if age2 promotion) + - old objects + in all pages and compares with objspace managing counters. + + * gc.c (gc_after_sweep): do gc_verify_internal_consistency() + when RGENGC_CHECK_MODE >= 2. + Tue Jun 3 16:33:27 2014 Koichi Sasada <ko1@a...> * gc.c (rb_gc_force_recycle): we only need to know the result (0/1) Index: gc.c =================================================================== --- gc.c (revision 46334) +++ gc.c (revision 46335) @@ -535,6 +535,7 @@ typedef struct rb_objspace { https://github.com/ruby/ruby/blob/trunk/gc.c#L535 size_t remembered_shady_object_limit; size_t old_object_count; size_t old_object_limit; + #if RGENGC_AGE2_PROMOTION size_t young_object_count; #endif @@ -684,6 +685,7 @@ static void gc_mark_maybe(rb_objspace_t https://github.com/ruby/ruby/blob/trunk/gc.c#L685 static void gc_mark_children(rb_objspace_t *objspace, VALUE ptr); static size_t obj_memsize_of(VALUE obj, int use_tdata); +static VALUE gc_verify_internal_consistency(VALUE self); static double getrusage_time(void); static inline void gc_prof_setup_new_record(rb_objspace_t *objspace, int reason); @@ -3053,6 +3055,10 @@ gc_after_sweep(rb_objspace_t *objspace) https://github.com/ruby/ruby/blob/trunk/gc.c#L3055 } #endif +#if RGENGC_CHECK_MODE >= 2 + gc_verify_internal_consistency(Qnil); +#endif + gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_END_SWEEP, 0); } @@ -4226,6 +4232,7 @@ gc_marks_body(rb_objspace_t *objspace, i https://github.com/ruby/ruby/blob/trunk/gc.c#L4232 rgengc_mark_and_rememberset_clear(objspace, heap_eden); } #endif + gc_mark_roots(objspace, full_mark, 0); gc_mark_stacked_objects(objspace); @@ -4487,6 +4494,11 @@ gc_marks_check(rb_objspace_t *objspace, https://github.com/ruby/ruby/blob/trunk/gc.c#L4494 struct verify_internal_consistency_struct { rb_objspace_t *objspace; int err_count; + size_t live_object_count; + size_t old_object_count; +#if RGENGC_AGE2_PROMOTION + size_t young_object_count; +#endif VALUE parent; }; @@ -4516,6 +4528,18 @@ verify_internal_consistency_i(void *page https://github.com/ruby/ruby/blob/trunk/gc.c#L4528 for (v = (VALUE)page_start; v != (VALUE)page_end; v += stride) { if (is_live_object(data->objspace, v)) { + + /* count objects */ + data->live_object_count++; + if (RVALUE_OLD_P(v)) { + data->old_object_count++; + } +#if RGENGC_AGE2_PROMOTION + else if (RVALUE_YOUNG_P(v)) { + data->young_object_count++; + } +#endif + if (RVALUE_OLD_P(v)) { data->parent = v; /* reachable objects from an oldgen object should be old or (young with remember) */ @@ -4544,9 +4568,16 @@ gc_verify_internal_consistency(VALUE sel https://github.com/ruby/ruby/blob/trunk/gc.c#L4568 { #if USE_RGENGC struct verify_internal_consistency_struct data; - data.objspace = &rb_objspace; + rb_objspace_t *objspace = &rb_objspace; + data.objspace = objspace; data.err_count = 0; + data.live_object_count = 0; + data.old_object_count = 0; +#if RGENGC_AGE2_PROMOTION + data.young_object_count = 0; +#endif + { struct each_obj_args eo_args; eo_args.callback = verify_internal_consistency_i; @@ -4560,9 +4591,26 @@ gc_verify_internal_consistency(VALUE sel https://github.com/ruby/ruby/blob/trunk/gc.c#L4591 gc_marks_check(objspace, NULL, NULL); allrefs_dump(objspace); #endif - rb_bug("gc_verify_internal_consistency: found internal consistency."); + rb_bug("gc_verify_internal_consistency: found internal inconsistency."); } #endif + + if (!is_lazy_sweeping(heap_eden) && !finalizing) { + if (objspace_live_slot(objspace) != data.live_object_count) { + fprintf(stderr, "heap_pages_final_slots: %d, objspace->profile.total_freed_object_num: %d\n", + (int)heap_pages_final_slots, (int)objspace->profile.total_freed_object_num); + rb_bug("inconsistent live slot nubmer: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace_live_slot(objspace), data.live_object_count); + } + } + if (objspace->rgengc.old_object_count != data.old_object_count) { + rb_bug("inconsistent old slot nubmer: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace->rgengc.old_object_count, data.old_object_count); + } +#if RGENGC_AGE2_PROMOTION + if (objspace->rgengc.young_object_count != data.young_object_count) { + rb_bug("inconsistent young slot nubmer: expect %"PRIuSIZE", but %"PRIuSIZE".", objspace->rgengc.young_object_count, data.young_object_count); + } +#endif + return Qnil; } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/