ruby-changes:31222
From: ko1 <ko1@a...>
Date: Wed, 16 Oct 2013 15:13:47 +0900 (JST)
Subject: [ruby-changes:31222] ko1:r43301 (trunk): * ext/objspace/objspace.c: add a new method `reachable_objects_from_root'.
ko1 2013-10-16 15:13:41 +0900 (Wed, 16 Oct 2013) New Revision: 43301 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=43301 Log: * ext/objspace/objspace.c: add a new method `reachable_objects_from_root'. ObjectSpace.reachable_objects_from_root returns all objects refered from root (called "root objects"). This feature is for deep object analysis. * test/objspace/test_objspace.rb: add a test. Modified files: trunk/ChangeLog trunk/ext/objspace/objspace.c trunk/test/objspace/test_objspace.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 43300) +++ ChangeLog (revision 43301) @@ -1,3 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Oct 16 15:09:14 2013 Koichi Sasada <ko1@a...> + + * ext/objspace/objspace.c: add a new method `reachable_objects_from_root'. + ObjectSpace.reachable_objects_from_root returns all objects refered + from root (called "root objects"). + This feature is for deep object analysis. + + * test/objspace/test_objspace.rb: add a test. + Wed Oct 16 15:00:21 2013 Eric Hodel <drbrain@s...> * lib/rubygems: Update to RubyGems master b955554. Changes: Index: ext/objspace/objspace.c =================================================================== --- ext/objspace/objspace.c (revision 43300) +++ ext/objspace/objspace.c (revision 43301) @@ -774,6 +774,70 @@ reachable_objects_from(VALUE self, VALUE https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L774 } } +struct rofr_data { + VALUE categories; + const char *last_category; + VALUE last_category_str; + VALUE last_category_objects; +}; + +static void +reachable_object_from_root_i(const char *category, VALUE obj, void *ptr) +{ + struct rofr_data *data = (struct rofr_data *)ptr; + VALUE category_str; + VALUE category_objects; + + if (category == data->last_category) { + category_str = data->last_category_str; + category_objects = data->last_category_objects; + } + else { + data->last_category = category; + category_str = data->last_category_str = rb_str_new2(category); + category_objects = data->last_category_objects = rb_hash_new(); + if (!NIL_P(rb_hash_lookup(data->categories, category_str))) { + rb_bug("reachable_object_from_root_i: category should insert at once"); + } + rb_hash_aset(data->categories, category_str, category_objects); + } + + if (rb_objspace_markable_object_p(obj)) { + if (rb_objspace_internal_object_p(obj)) { + obj = iow_newobj(obj); + } + rb_hash_aset(category_objects, obj, obj); + } +} + +static int +collect_values_of_values(VALUE category, VALUE category_objects, VALUE categories) +{ + VALUE ary = rb_ary_new(); + st_foreach(rb_hash_tbl(category_objects), collect_values, ary); + rb_hash_aset(categories, category, ary); + return ST_CONTINUE; +} + +/* + * call-seq: + * ObjectSpace.reachable_objects_from_root -> hash + * + * [MRI specific feature] Return all reachable objects from root. + */ +static VALUE +reachable_objects_from_root(VALUE self) +{ + struct rofr_data data; + VALUE hash = data.categories = rb_hash_new(); + data.last_category = 0; + + rb_objspace_reachable_objects_from_root(reachable_object_from_root_i, &data); + rb_hash_foreach(hash, collect_values_of_values, hash); + + return hash; +} + void Init_object_tracing(VALUE rb_mObjSpace); void Init_gc_hook(VALUE rb_mObjSpace); @@ -809,6 +873,7 @@ Init_objspace(void) https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L873 rb_define_module_function(rb_mObjSpace, "count_tdata_objects", count_tdata_objects, -1); rb_define_module_function(rb_mObjSpace, "reachable_objects_from", reachable_objects_from, 1); + rb_define_module_function(rb_mObjSpace, "reachable_objects_from_root", reachable_objects_from_root, 0); /* * This class is used as a return value from Index: test/objspace/test_objspace.rb =================================================================== --- test/objspace/test_objspace.rb (revision 43300) +++ test/objspace/test_objspace.rb (revision 43301) @@ -97,6 +97,18 @@ class TestObjSpace < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/objspace/test_objspace.rb#L97 eom end + def test_reachable_objects_from_root + root_objects = ObjectSpace.reachable_objects_from_root + + assert_operator(root_objects.size, :>, 0) + + root_objects.each{|category, objects| + assert_kind_of(String, category) + assert_kind_of(Array, objects) + assert_operator(objects.size, :>, 0) + } + end + def test_reachable_objects_size assert_separately %w[--disable-gem -robjspace], __FILE__, __LINE__, <<-'eom' ObjectSpace.each_object{|o| -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/