ruby-changes:43303
From: nobu <ko1@a...>
Date: Sat, 11 Jun 2016 14:04:27 +0900 (JST)
Subject: [ruby-changes:43303] nobu:r55377 (trunk): ObjectSpace.dump_all: valid JSON
nobu 2016-06-11 14:04:22 +0900 (Sat, 11 Jun 2016) New Revision: 55377 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55377 Log: ObjectSpace.dump_all: valid JSON * ext/objspace/objspace_dump.c: generate valid JSON for dump_all. Modified files: trunk/ChangeLog trunk/ext/objspace/objspace_dump.c trunk/test/objspace/test_objspace.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 55376) +++ ChangeLog (revision 55377) @@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sat Jun 11 14:04:19 2016 Nobuyoshi Nakada <nobu@r...> + + * ext/objspace/objspace_dump.c: generate valid JSON for dump_all. + Sat Jun 11 13:52:33 2016 Nobuyoshi Nakada <nobu@r...> * lib/forwardable.rb (_delegator_method): remove __send__ call if Index: test/objspace/test_objspace.rb =================================================================== --- test/objspace/test_objspace.rb (revision 55376) +++ test/objspace/test_objspace.rb (revision 55377) @@ -1,6 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/test/objspace/test_objspace.rb#L1 # frozen_string_literal: false require "test/unit" require "objspace" +begin + require "json" +rescue LoadError +end class TestObjSpace < Test::Unit::TestCase def test_memsize_of @@ -218,6 +222,7 @@ class TestObjSpace < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/objspace/test_objspace.rb#L222 info = ObjectSpace.dump("foo".freeze) assert_match /"wb_protected":true, "old":true/, info assert_match /"fstring":true/, info + JSON.parse(info) if defined?(JSON) end def test_dump_to_default @@ -252,6 +257,7 @@ class TestObjSpace < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/objspace/test_objspace.rb#L257 assert_match /"embedded":true, "bytesize":11, "value":"hello world", "encoding":"UTF-8"/, info assert_match /"file":"#{Regexp.escape __FILE__}", "line":#{line}/, info assert_match /"method":"#{loc.base_label}"/, info + JSON.parse(info) if defined?(JSON) end def test_dump_special_consts @@ -300,6 +306,13 @@ class TestObjSpace < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/objspace/test_objspace.rb#L306 assert_match(entry, File.readlines(output).grep(/TEST STRING/).join("\n")) File.unlink(output) end + + if defined?(JSON) + assert_ruby_status(%w[-rjson -robjspace], "#{<<-"begin;"}\n#{<<-"end;"}") + begin; + JSON.parse(ObjectSpace.dump_all(output: :string)) + end; + end end def test_dump_uninitialized_file Index: ext/objspace/objspace_dump.c =================================================================== --- ext/objspace/objspace_dump.c (revision 55376) +++ ext/objspace/objspace_dump.c (revision 55377) @@ -191,7 +191,7 @@ dump_append_string_content(struct dump_c https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L191 } static void -dump_object(VALUE obj, struct dump_config *dc) +dump_object(VALUE obj, struct dump_config *dc, int part) { size_t memsize; struct allocation_info *ainfo; @@ -211,7 +211,11 @@ dump_object(VALUE obj, struct dump_confi https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L211 if (dc->cur_obj == dc->string) return; - dump_append(dc, "{\"address\":\"%p\", \"type\":\"%s\"", (void *)obj, obj_type(obj)); + if (part) + dump_append(dc, "\"%p\":{", (void *)obj); + else + dump_append(dc, "{\"address\":\"%p\", ", (void *)obj); + dump_append(dc, "\"type\":\"%s\"", obj_type(obj)); if (dc->cur_obj_klass) dump_append(dc, ", \"class\":\"%p\"", (void *)dc->cur_obj_klass); @@ -283,7 +287,8 @@ dump_object(VALUE obj, struct dump_confi https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L287 break; case T_ZOMBIE: - dump_append(dc, "}\n"); + dump_append(dc, "}"); + dc->roots++; return; } @@ -312,16 +317,20 @@ dump_object(VALUE obj, struct dump_confi https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L317 dump_append(dc, "}"); } - dump_append(dc, "}\n"); + dump_append(dc, "}"); + dc->roots++; } 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 (RBASIC(v)->flags && v != dc->string) { + if (dc->roots++) dump_append(dc, ",\n"); + dump_object(v, dc, 1); + } } return 0; } @@ -332,9 +341,11 @@ root_obj_i(const char *category, VALUE o https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L341 struct dump_config *dc = (struct dump_config *)data; if (dc->root_category != NULL && category != dc->root_category) - dump_append(dc, "]}\n"); - if (dc->root_category == NULL || category != dc->root_category) + dump_append(dc, "]},\n"); + if (dc->root_category == NULL || category != dc->root_category) { + dump_append(dc, "\"%p\":", (void *)obj); dump_append(dc, "{\"type\":\"ROOT\", \"root\":\"%s\", \"references\":[\"%p\"", category, (void *)obj); + } else dump_append(dc, ", \"%p\"", (void *)obj); @@ -382,7 +393,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L393 dump_result(struct dump_config *dc, VALUE output) { if (output == sym_string) { - return dc->string; + return rb_str_resurrect(dc->string); } else if (output == sym_file) { rb_io_flush(dc->string); @@ -418,7 +429,8 @@ objspace_dump(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L429 output = dump_output(&dc, opts, sym_string, filename); - dump_object(obj, &dc); + dump_object(obj, &dc, 0); + if (dc.roots) dump_append(&dc, "\n"); return dump_result(&dc, output); } @@ -450,12 +462,14 @@ objspace_dump_all(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace_dump.c#L462 output = dump_output(&dc, opts, sym_file, filename); + dump_append(&dc, "{\n"); /* dump roots */ rb_objspace_reachable_objects_from_root(root_obj_i, &dc); - if (dc.roots) dump_append(&dc, "]}\n"); + if (dc.roots) dump_append(&dc, "]}"); /* dump all objects */ rb_objspace_each_objects(heap_i, &dc); + dump_append(&dc, "\n}"); return dump_result(&dc, output); } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/