[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]