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
@@ -322,8 +340,11 @@ heap_i(void *vstart, void *vend, size_t stride, void *data)
322
340
VALUE v = (VALUE )vstart ;
323
341
for (; v != (VALUE )vend ; v += stride ) {
324
342
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 );
326
346
}
347
+ dc -> pages_seen ++ ;
327
348
return 0 ;
328
349
}
329
350
@@ -348,9 +369,20 @@ dump_output(struct dump_config *dc, VALUE opts, VALUE output, const char *filena
348
369
{
349
370
VALUE tmp ;
350
371
351
- if (RTEST (opts ))
372
+ dc -> pages_seen = 0 ;
373
+ dc -> include_pages = 0 ;
374
+ dc -> include_none = 0 ;
375
+
376
+ if (RTEST (opts )) {
352
377
output = rb_hash_aref (opts , sym_output );
353
378
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
+
354
386
if (output == sym_stdout ) {
355
387
dc -> stream = stdout ;
356
388
dc -> string = Qnil ;
@@ -475,6 +507,8 @@ Init_objspace_dump(VALUE rb_mObjSpace)
475
507
sym_stdout = ID2SYM (rb_intern ("stdout" ));
476
508
sym_string = ID2SYM (rb_intern ("string" ));
477
509
sym_file = ID2SYM (rb_intern ("file" ));
510
+ sym_include_pages = ID2SYM (rb_intern ("include_pages" ));
511
+ sym_include_none = ID2SYM (rb_intern ("include_none" ));
478
512
479
513
/* force create static IDs */
480
514
rb_obj_gc_flags (rb_mObjSpace , 0 , 0 );
0 commit comments