summaryrefslogtreecommitdiff
path: root/ext/objspace/objspace_dump.c
diff options
context:
space:
mode:
authortenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-01-03 22:42:10 +0000
committertenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-01-03 22:42:10 +0000
commited2abc4362e841967a3758baa199f88cf41496b2 (patch)
treed2725607e5991b9c681824ff3872f2c6c0869e57 /ext/objspace/objspace_dump.c
parent6f31dcd72f92c0fe2491a60192f4d7d7891e96a0 (diff)
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
Diffstat (limited to 'ext/objspace/objspace_dump.c')
-rw-r--r--ext/objspace/objspace_dump.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/ext/objspace/objspace_dump.c b/ext/objspace/objspace_dump.c
index 127d33283a..9c2055d6d8 100644
--- a/ext/objspace/objspace_dump.c
+++ b/ext/objspace/objspace_dump.c
@@ -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);