21
21
#include "objspace.h"
22
22
23
23
static VALUE sym_output , sym_stdout , sym_string , sym_file ;
24
+ static VALUE sym_include_pages , sym_include_none ;
24
25
25
26
struct dump_config {
26
27
VALUE type ;
@@ -31,6 +32,9 @@ struct dump_config {
31
32
VALUE cur_obj ;
32
33
VALUE cur_obj_klass ;
33
34
size_t cur_obj_references ;
35
+ int include_pages ;
36
+ int include_none ;
37
+ int pages_seen ;
34
38
};
35
39
36
40
PRINTF_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)
190
194
}
191
195
}
192
196
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
+
193
209
static void
194
210
dump_object (VALUE obj , struct dump_config * dc )
195
211
{
@@ -215,6 +231,8 @@ dump_object(VALUE obj, struct dump_config *dc)
215
231
216
232
if (dc -> cur_obj_klass )
217
233
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 );
218
236
if (rb_obj_frozen_p (obj ))
219
237
dump_append (dc , ", \"frozen\":true" );
220
238
@@ -321,8 +339,11 @@ heap_i(void *vstart, void *vend, size_t stride, void *data)
321
339
VALUE v = (VALUE )vstart ;
322
340
for (; v != (VALUE )vend ; v += stride ) {
323
341
if (RBASIC (v )-> flags )
324
- dump_object (v , data );
342
+ dump_object (v , dc );
343
+ else if (dc -> include_none && T_NONE == BUILTIN_TYPE (v ))
344
+ dump_empty (v , dc );
325
345
}
346
+ dc -> pages_seen ++ ;
326
347
return 0 ;
327
348
}
328
349
@@ -347,9 +368,20 @@ dump_output(struct dump_config *dc, VALUE opts, VALUE output, const char *filena
347
368
{
348
369
VALUE tmp ;
349
370
350
- if (RTEST (opts ))
371
+ dc -> pages_seen = 0 ;
372
+ dc -> include_pages = 0 ;
373
+ dc -> include_none = 0 ;
374
+
375
+ if (RTEST (opts )) {
351
376
output = rb_hash_aref (opts , sym_output );
352
377
378
+ if (Qtrue == rb_hash_lookup2 (opts , sym_include_pages , Qfalse ))
379
+ dc -> include_pages = 1 ;
380
+
381
+ if (Qtrue == rb_hash_lookup2 (opts , sym_include_none , Qfalse ))
382
+ dc -> include_none = 1 ;
383
+ }
384
+
353
385
if (output == sym_stdout ) {
354
386
dc -> stream = stdout ;
355
387
dc -> string = Qnil ;
@@ -474,6 +506,8 @@ Init_objspace_dump(VALUE rb_mObjSpace)
474
506
sym_stdout = ID2SYM (rb_intern ("stdout" ));
475
507
sym_string = ID2SYM (rb_intern ("string" ));
476
508
sym_file = ID2SYM (rb_intern ("file" ));
509
+ sym_include_pages = ID2SYM (rb_intern ("include_pages" ));
510
+ sym_include_none = ID2SYM (rb_intern ("include_none" ));
477
511
478
512
/* force create static IDs */
479
513
rb_obj_gc_flags (rb_mObjSpace , 0 , 0 );
0 commit comments