2121#include "objspace.h"
2222
2323static VALUE sym_output , sym_stdout , sym_string , sym_file ;
24+ static VALUE sym_include_pages , sym_include_none ;
2425
2526struct dump_config {
2627 VALUE type ;
@@ -31,6 +32,9 @@ struct dump_config {
3132 VALUE cur_obj ;
3233 VALUE cur_obj_klass ;
3334 size_t cur_obj_references ;
35+ int include_pages ;
36+ int include_none ;
37+ int pages_seen ;
3438};
3539
3640PRINTF_ARGS (static void dump_append (struct dump_config * , const char * , ...), 2 , 3 );
@@ -190,6 +194,18 @@ dump_append_string_content(struct dump_config *dc, VALUE obj)
190194 }
191195}
192196
197+ static void
198+ dump_empty (VALUE obj , struct dump_config * dc )
199+ {
200+ dump_append (dc , "{\"address\":\"%p\", " , (void * )obj );
201+ dump_append (dc , "\"type\":\"NONE\"" );
202+
203+ if (dc -> include_pages )
204+ dump_append (dc , ", \"page_number\":%d" , dc -> pages_seen );
205+ dump_append (dc , "}\n" );
206+ return ;
207+ }
208+
193209static void
194210dump_object (VALUE obj , struct dump_config * dc )
195211{
@@ -215,6 +231,8 @@ dump_object(VALUE obj, struct dump_config *dc)
215231
216232 if (dc -> cur_obj_klass )
217233 dump_append (dc , ", \"class\":\"%p\"" , (void * )dc -> cur_obj_klass );
234+ if (dc -> include_pages )
235+ dump_append (dc , ", \"page_number\":%d" , dc -> pages_seen );
218236 if (rb_obj_frozen_p (obj ))
219237 dump_append (dc , ", \"frozen\":true" );
220238
@@ -322,8 +340,11 @@ heap_i(void *vstart, void *vend, size_t stride, void *data)
322340 VALUE v = (VALUE )vstart ;
323341 for (; v != (VALUE )vend ; v += stride ) {
324342 if (RBASIC (v )-> flags )
325- dump_object (v , data );
343+ dump_object (v , dc );
344+ else if (dc -> include_none && T_NONE == BUILTIN_TYPE (v ))
345+ dump_empty (v , dc );
326346 }
347+ dc -> pages_seen ++ ;
327348 return 0 ;
328349}
329350
@@ -348,9 +369,20 @@ dump_output(struct dump_config *dc, VALUE opts, VALUE output, const char *filena
348369{
349370 VALUE tmp ;
350371
351- if (RTEST (opts ))
372+ dc -> pages_seen = 0 ;
373+ dc -> include_pages = 0 ;
374+ dc -> include_none = 0 ;
375+
376+ if (RTEST (opts )) {
352377 output = rb_hash_aref (opts , sym_output );
353378
379+ if (Qtrue == rb_hash_lookup2 (opts , sym_include_pages , Qfalse ))
380+ dc -> include_pages = 1 ;
381+
382+ if (Qtrue == rb_hash_lookup2 (opts , sym_include_none , Qfalse ))
383+ dc -> include_none = 1 ;
384+ }
385+
354386 if (output == sym_stdout ) {
355387 dc -> stream = stdout ;
356388 dc -> string = Qnil ;
@@ -475,6 +507,8 @@ Init_objspace_dump(VALUE rb_mObjSpace)
475507 sym_stdout = ID2SYM (rb_intern ("stdout" ));
476508 sym_string = ID2SYM (rb_intern ("string" ));
477509 sym_file = ID2SYM (rb_intern ("file" ));
510+ sym_include_pages = ID2SYM (rb_intern ("include_pages" ));
511+ sym_include_none = ID2SYM (rb_intern ("include_none" ));
478512
479513 /* force create static IDs */
480514 rb_obj_gc_flags (rb_mObjSpace , 0 , 0 );
0 commit comments