ruby-changes:32149
From: ko1 <ko1@a...>
Date: Mon, 16 Dec 2013 13:12:55 +0900 (JST)
Subject: [ruby-changes:32149] ko1:r44228 (trunk): * gc.c: introduce GC.verify_internal_consistency method to verify GC
ko1 2013-12-16 13:12:48 +0900 (Mon, 16 Dec 2013) New Revision: 44228 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=44228 Log: * gc.c: introduce GC.verify_internal_consistency method to verify GC internal data structure. Now this method only checks geneartion (old/young) consistency. Modified files: trunk/ChangeLog trunk/gc.c trunk/test/ruby/test_gc.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 44227) +++ ChangeLog (revision 44228) @@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Mon Dec 16 13:10:54 2013 Koichi Sasada <ko1@a...> + + * gc.c: introduce GC.verify_internal_consistency method to verify GC + internal data structure. + + Now this method only checks geneartion (old/young) consistency. + Mon Dec 16 11:49:26 2013 Aman Gupta <ruby@t...> * gc.c (gc_info_decode): Fix build errors when compiled with Index: gc.c =================================================================== --- gc.c (revision 44227) +++ gc.c (revision 44228) @@ -4135,6 +4135,77 @@ gc_marks_body(rb_objspace_t *objspace, i https://github.com/ruby/ruby/blob/trunk/gc.c#L4135 rgengc_report(1, objspace, "gc_marks_body: end (%s)\n", full_mark ? "full" : "minor"); } +struct verify_internal_consistency_struct { + rb_objspace_t *objspace; + int err_count; + VALUE parent; +}; + +#if USE_RGENGC +static void +verify_internal_consistency_reachable_i(VALUE child, void *ptr) +{ + struct verify_internal_consistency_struct *data = (struct verify_internal_consistency_struct *)ptr; + + assert(RVALUE_OLD_P(data->parent)); + + if (!RVALUE_OLD_P(child)) { + if (!MARKED_IN_BITMAP(GET_HEAP_PAGE(data->parent)->rememberset_bits, data->parent) && + !MARKED_IN_BITMAP(GET_HEAP_PAGE(child)->rememberset_bits, child)) { + fprintf(stderr, "verify_internal_consistency_reachable_i: WB miss %p (%s) -> %p (%s)\n", + (void *)data->parent, obj_type_name(data->parent), + (void *)child, obj_type_name(child)); + data->err_count++; + } + } +} + +static int +verify_internal_consistency_i(void *page_start, void *page_end, size_t stride, void *ptr) +{ + struct verify_internal_consistency_struct *data = (struct verify_internal_consistency_struct *)ptr; + VALUE v; + + for (v = (VALUE)page_start; v != (VALUE)page_end; v += stride) { + if (is_live_object(data->objspace, v)) { + if (RVALUE_OLD_P(v)) { + data->parent = v; + /* reachable objects from an oldgen object should be old or (young with remember) */ + rb_objspace_reachable_objects_from(v, verify_internal_consistency_reachable_i, (void *)data); + } + } + } + + return 0; +} +#endif /* USE_RGENGC */ + +/* + * call-seq: + * GC.verify_internal_consistency -> nil + * + * Verify internal consistency. + * + * This method is implementation specific. + * Now this method checks generatioanl consistency + * if RGenGC is supported. + */ +static VALUE +gc_verify_internal_consistency(VALUE self) +{ + struct verify_internal_consistency_struct data; + data.objspace = &rb_objspace; + data.err_count = 0; + +#if USE_RGENGC + rb_objspace_each_objects(verify_internal_consistency_i, &data); +#endif + if (data.err_count != 0) { + rb_bug("gc_verify_internal_consistency: found internal consistency.\n"); + } + return Qnil; +} + #if RGENGC_CHECK_MODE >= 2 #define MAKE_ROOTSIG(obj) (((VALUE)(obj) << 1) | 0x01) @@ -7459,6 +7530,8 @@ Init_GC(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L7530 rb_include_module(rb_cWeakMap, rb_mEnumerable); } + /* internal methods */ + rb_define_singleton_method(rb_mGC, "verify_internal_consistency", gc_verify_internal_consistency, 0); #if MALLOC_ALLOCATED_SIZE rb_define_singleton_method(rb_mGC, "malloc_allocated_size", gc_malloc_allocated_size, 0); rb_define_singleton_method(rb_mGC, "malloc_allocations", gc_malloc_allocations, 0); Index: test/ruby/test_gc.rb =================================================================== --- test/ruby/test_gc.rb (revision 44227) +++ test/ruby/test_gc.rb (revision 44228) @@ -278,4 +278,8 @@ class TestGc < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_gc.rb#L278 end; end end + + def test_verify_internal_consistency + assert_nil(GC.verify_internal_consistency) + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/