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

ruby-changes:45187

From: tenderlove <ko1@a...>
Date: Wed, 4 Jan 2017 07:42:16 +0900 (JST)
Subject: [ruby-changes:45187] tenderlove:r57260 (trunk): Add `full` option to `ObjectSpace.dump_all`

tenderlove	2017-01-04 07:42:10 +0900 (Wed, 04 Jan 2017)

  New Revision: 57260

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=57260

  Log:
    Add `full` option to `ObjectSpace.dump_all`
    
    The `full` option includes all slots (even `T_NONE`) in the JSON output.
    This is to help with debugging heap fragmentation.
    
    Here is an example usage:
    
    ```ruby
    File.open('heap.json', 'w') do |f|
      ObjectSpace.dump_all(output: f, full: true)
    end
    ```
    
    The `heap.json` file contains all slots, including empty slots.
    
    [Feature #13001] [ruby-core:78468]

  Modified files:
    trunk/ext/objspace/objspace_dump.c
    trunk/test/objspace/test_objspace.rb
Index: ext/objspace/objspace_dump.c
===================================================================
--- ext/objspace/objspace_dump.c	(revision 57259)
+++ ext/objspace/objspace_dump.c	(revision 57260)
@@ -21,6 +21,7 @@ https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L21
 #include "objspace.h"
 
 static VALUE sym_output, sym_stdout, sym_string, sym_file;
+static VALUE sym_full;
 
 struct dump_config {
     VALUE type;
@@ -31,6 +32,7 @@ struct dump_config { https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L32
     VALUE cur_obj;
     VALUE cur_obj_klass;
     size_t cur_obj_references;
+    int full_heap;
 };
 
 PRINTF_ARGS(static void dump_append(struct dump_config *, const char *, ...), 2, 3);
@@ -219,6 +221,10 @@ dump_object(VALUE obj, struct dump_confi https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L221
 	dump_append(dc, ", \"frozen\":true");
 
     switch (BUILTIN_TYPE(obj)) {
+      case T_NONE:
+	  dump_append(dc, "}\n");
+	  return;
+
       case T_NODE:
 	dump_append(dc, ", \"node_type\":\"%s\"", ruby_node_name(nd_type(obj)));
 	break;
@@ -318,10 +324,11 @@ dump_object(VALUE obj, struct dump_confi https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L324
 static int
 heap_i(void *vstart, void *vend, size_t stride, void *data)
 {
+    struct dump_config *dc = (struct dump_config *)data;
     VALUE v = (VALUE)vstart;
     for (; v != (VALUE)vend; v += stride) {
-	if (RBASIC(v)->flags)
-	    dump_object(v, data);
+	if (dc->full_heap || RBASIC(v)->flags)
+	    dump_object(v, dc);
     }
     return 0;
 }
@@ -347,9 +354,15 @@ dump_output(struct dump_config *dc, VALU https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L354
 {
     VALUE tmp;
 
-    if (RTEST(opts))
+    dc->full_heap = 0;
+
+    if (RTEST(opts)) {
 	output = rb_hash_aref(opts, sym_output);
 
+	if (Qtrue == rb_hash_lookup2(opts, sym_full, Qfalse))
+	    dc->full_heap = 1;
+    }
+
     if (output == sym_stdout) {
 	dc->stream = stdout;
 	dc->string = Qnil;
@@ -474,6 +487,7 @@ Init_objspace_dump(VALUE rb_mObjSpace) https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L487
     sym_stdout = ID2SYM(rb_intern("stdout"));
     sym_string = ID2SYM(rb_intern("string"));
     sym_file   = ID2SYM(rb_intern("file"));
+    sym_full   = ID2SYM(rb_intern("full"));
 
     /* force create static IDs */
     rb_obj_gc_flags(rb_mObjSpace, 0, 0);
Index: test/objspace/test_objspace.rb
===================================================================
--- test/objspace/test_objspace.rb	(revision 57259)
+++ test/objspace/test_objspace.rb	(revision 57260)
@@ -275,6 +275,19 @@ class TestObjSpace < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/objspace/test_objspace.rb#L275
     assert_match /"value":"foobar\h+"/, dump
   end
 
+  def test_dump_all_full
+    assert_in_out_err(%w[-robjspace], <<-'end;') do |output, error|
+      def dump_my_heap_please
+        ObjectSpace.dump_all(output: :stdout, full: true)
+      end
+
+      dump_my_heap_please
+    end;
+    heap = output.find_all { |l| JSON.parse(l)['type'] == "NONE" }
+    assert_operator heap.length, :>, 0
+    end
+  end
+
   def test_dump_all
     entry = /"bytesize":11, "value":"TEST STRING", "encoding":"UTF-8", "file":"-", "line":4, "method":"dump_my_heap_please", "generation":/
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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