mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57260 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
6f31dcd72f
commit
ed2abc4362
2 changed files with 30 additions and 3 deletions
|
@ -21,6 +21,7 @@
|
|||
#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 {
|
|||
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_config *dc)
|
|||
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_config *dc)
|
|||
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, VALUE opts, VALUE output, const char *filena
|
|||
{
|
||||
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)
|
|||
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);
|
||||
|
|
|
@ -275,6 +275,19 @@ class TestObjSpace < Test::Unit::TestCase
|
|||
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":/
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue