Ruby 2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)

objspace.c
Go to the documentation of this file.
1 /**********************************************************************
2
3 objspace.c - ObjectSpace extender for MRI.
4
5 $Author$
6 created at: Wed Jun 17 07:39:17 2009
7
8 NOTE: This extension library is only expected to exist with C Ruby.
9
10 All the files in this distribution are covered under the Ruby's
11 license (see the file COPYING).
12
13 **********************************************************************/
14
15 #include <ruby/io.h>
16 #include "internal.h"
17 #include <ruby/st.h>
18 #include <ruby/re.h>
19 #include "node.h"
20 #include "gc.h"
21 #include "symbol.h"
22
23 /*
24 * call-seq:
25 * ObjectSpace.memsize_of(obj) -> Integer
26 *
27 * Return consuming memory size of obj.
28 *
29 * Note that the return size is incomplete. You need to deal with this
30 * information as only a *HINT*. Especially, the size of +T_DATA+ may not be
31 * correct.
32 *
33 * This method is only expected to work with C Ruby.
34 *
35 * From Ruby 2.2, memsize_of(obj) returns a memory size includes
36 * sizeof(RVALUE).
37 */
38
39 static VALUE
40 memsize_of_m(VALUE self, VALUE obj)
41 {
42 return SIZET2NUM(rb_obj_memsize_of(obj));
43 }
44
45 struct total_data {
46 size_t total;
47 VALUE klass;
48 };
49
50 static int
51 total_i(void *vstart, void *vend, size_t stride, void *ptr)
52 {
53 VALUE v;
54 struct total_data *data = (struct total_data *)ptr;
55
56 for (v = (VALUE)vstart; v != (VALUE)vend; v += stride) {
57 if (RBASIC(v)->flags) {
58 switch (BUILTIN_TYPE(v)) {
59 case T_NONE:
60 case T_IMEMO:
61 case T_ICLASS:
62 case T_NODE:
63 case T_ZOMBIE:
64 continue;
65 default:
66 if (data->klass == 0 || rb_obj_is_kind_of(v, data->klass)) {
67 data->total += rb_obj_memsize_of(v);
68 }
69 }
70 }
71 }
72
73 return 0;
74 }
75
76 /*
77 * call-seq:
78 * ObjectSpace.memsize_of_all([klass]) -> Integer
79 *
80 * Return consuming memory size of all living objects.
81 *
82 * If +klass+ (should be Class object) is given, return the total memory size
83 * of instances of the given class.
84 *
85 * Note that the returned size is incomplete. You need to deal with this
86 * information as only a *HINT*. Especially, the size of +T_DATA+ may not be
87 * correct.
88 *
89 * Note that this method does *NOT* return total malloc'ed memory size.
90 *
91 * This method can be defined by the following Ruby code:
92 *
93 * def memsize_of_all klass = false
94 * total = 0
95 * ObjectSpace.each_object{|e|
96 * total += ObjectSpace.memsize_of(e) if klass == false || e.kind_of?(klass)
97 * }
98 * total
99 * end
100 *
101 * This method is only expected to work with C Ruby.
102 */
103
104 static VALUE
105 memsize_of_all_m(int argc, VALUE *argv, VALUE self)
106 {
107 struct total_data data = {0, 0};
108
109 if (argc > 0) {
110 rb_scan_args(argc, argv, "01", &data.klass);
111 }
112
113 rb_objspace_each_objects(total_i, &data);
114 return SIZET2NUM(data.total);
115 }
116
117 static int
118 set_zero_i(st_data_t key, st_data_t val, st_data_t arg)
119 {
120 VALUE k = (VALUE)key;
121 VALUE hash = (VALUE)arg;
122 rb_hash_aset(hash, k, INT2FIX(0));
123 return ST_CONTINUE;
124 }
125
126 static VALUE
127 setup_hash(int argc, VALUE *argv)
128 {
129 VALUE hash;
130
131 if (rb_scan_args(argc, argv, "01", &hash) == 1) {
132 if (!RB_TYPE_P(hash, T_HASH))
133 rb_raise(rb_eTypeError, "non-hash given");
134 }
135
136 if (hash == Qnil) {
137 hash = rb_hash_new();
138 }
139 else if (!RHASH_EMPTY_P(hash)) {
140 st_foreach(RHASH_TBL(hash), set_zero_i, hash);
141 }
142
143 return hash;
144 }
145
146 static int
147 cos_i(void *vstart, void *vend, size_t stride, void *data)
148 {
149 size_t *counts = (size_t *)data;
150 VALUE v = (VALUE)vstart;
151
152 for (;v != (VALUE)vend; v += stride) {
153 if (RBASIC(v)->flags) {
154 counts[BUILTIN_TYPE(v)] += rb_obj_memsize_of(v);
155 }
156 }
157 return 0;
158 }
159
160 static VALUE
161 type2sym(enum ruby_value_type i)
162 {
163 VALUE type;
164 switch (i) {
165 #define CASE_TYPE(t) case t: type = ID2SYM(rb_intern(#t)); break;
166 CASE_TYPE(T_NONE);
167 CASE_TYPE(T_OBJECT);
168 CASE_TYPE(T_CLASS);
169 CASE_TYPE(T_MODULE);
170 CASE_TYPE(T_FLOAT);
171 CASE_TYPE(T_STRING);
172 CASE_TYPE(T_REGEXP);
173 CASE_TYPE(T_ARRAY);
174 CASE_TYPE(T_HASH);
175 CASE_TYPE(T_STRUCT);
176 CASE_TYPE(T_BIGNUM);
177 CASE_TYPE(T_FILE);
178 CASE_TYPE(T_DATA);
179 CASE_TYPE(T_MATCH);
180 CASE_TYPE(T_COMPLEX);
181 CASE_TYPE(T_RATIONAL);
182 CASE_TYPE(T_NIL);
183 CASE_TYPE(T_TRUE);
184 CASE_TYPE(T_FALSE);
185 CASE_TYPE(T_SYMBOL);
186 CASE_TYPE(T_FIXNUM);
187 CASE_TYPE(T_UNDEF);
188 CASE_TYPE(T_IMEMO);
189 CASE_TYPE(T_NODE);
190 CASE_TYPE(T_ICLASS);
191 CASE_TYPE(T_MOVED);
192 CASE_TYPE(T_ZOMBIE);
193 #undef CASE_TYPE
194 default: rb_bug("type2sym: unknown type (%d)", i);
195 }
196 return type;
197 }
198
199 /*
200 * call-seq:
201 * ObjectSpace.count_objects_size([result_hash]) -> hash
202 *
203 * Counts objects size (in bytes) for each type.
204 *
205 * Note that this information is incomplete. You need to deal with
206 * this information as only a *HINT*. Especially, total size of
207 * T_DATA may be wrong.
208 *
209 * It returns a hash as:
210 * {:TOTAL=>1461154, :T_CLASS=>158280, :T_MODULE=>20672, :T_STRING=>527249, ...}
211 *
212 * If the optional argument, result_hash, is given,
213 * it is overwritten and returned.
214 * This is intended to avoid probe effect.
215 *
216 * The contents of the returned hash is implementation defined.
217 * It may be changed in future.
218 *
219 * This method is only expected to work with C Ruby.
220 */
221
222 static VALUE
223 count_objects_size(int argc, VALUE *argv, VALUE os)
224 {
225 size_t counts[T_MASK+1];
226 size_t total = 0;
227 enum ruby_value_type i;
228 VALUE hash = setup_hash(argc, argv);
229
230 for (i = 0; i <= T_MASK; i++) {
231 counts[i] = 0;
232 }
233
234 rb_objspace_each_objects(cos_i, &counts[0]);
235
236 for (i = 0; i <= T_MASK; i++) {
237 if (counts[i]) {
238 VALUE type = type2sym(i);
239 total += counts[i];
240 rb_hash_aset(hash, type, SIZET2NUM(counts[i]));
241 }
242 }
243 rb_hash_aset(hash, ID2SYM(rb_intern("TOTAL")), SIZET2NUM(total));
244 return hash;
245 }
246
247 struct dynamic_symbol_counts {
248 size_t mortal;
249 size_t immortal;
250 };
251
252 static int
253 cs_i(void *vstart, void *vend, size_t stride, void *n)
254 {
255 struct dynamic_symbol_counts *counts = (struct dynamic_symbol_counts *)n;
256 VALUE v = (VALUE)vstart;
257
258 for (; v != (VALUE)vend; v += stride) {
259 if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_SYMBOL) {
260 ID id = RSYMBOL(v)->id;
261 if ((id & ~ID_SCOPE_MASK) == 0) {
262 counts->mortal++;
263 }
264 else {
265 counts->immortal++;
266 }
267 }
268 }
269
270 return 0;
271 }
272
273 size_t rb_sym_immortal_count(void);
274
275 /*
276 * call-seq:
277 * ObjectSpace.count_symbols([result_hash]) -> hash
278 *
279 * Counts symbols for each Symbol type.
280 *
281 * This method is only for MRI developers interested in performance and memory
282 * usage of Ruby programs.
283 *
284 * If the optional argument, result_hash, is given, it is overwritten and
285 * returned. This is intended to avoid probe effect.
286 *
287 * Note:
288 * The contents of the returned hash is implementation defined.
289 * It may be changed in future.
290 *
291 * This method is only expected to work with C Ruby.
292 *
293 * On this version of MRI, they have 3 types of Symbols (and 1 total counts).
294 *
295 * * mortal_dynamic_symbol: GC target symbols (collected by GC)
296 * * immortal_dynamic_symbol: Immortal symbols promoted from dynamic symbols (do not collected by GC)
297 * * immortal_static_symbol: Immortal symbols (do not collected by GC)
298 * * immortal_symbol: total immortal symbols (immortal_dynamic_symbol+immortal_static_symbol)
299 */
300
301 static VALUE
302 count_symbols(int argc, VALUE *argv, VALUE os)
303 {
304 struct dynamic_symbol_counts dynamic_counts = {0, 0};
305 VALUE hash = setup_hash(argc, argv);
306
307 size_t immortal_symbols = rb_sym_immortal_count();
308 rb_objspace_each_objects(cs_i, &dynamic_counts);
309
310 rb_hash_aset(hash, ID2SYM(rb_intern("mortal_dynamic_symbol")), SIZET2NUM(dynamic_counts.mortal));
311 rb_hash_aset(hash, ID2SYM(rb_intern("immortal_dynamic_symbol")), SIZET2NUM(dynamic_counts.immortal));
312 rb_hash_aset(hash, ID2SYM(rb_intern("immortal_static_symbol")), SIZET2NUM(immortal_symbols - dynamic_counts.immortal));
313 rb_hash_aset(hash, ID2SYM(rb_intern("immortal_symbol")), SIZET2NUM(immortal_symbols));
314
315 return hash;
316 }
317
318 static int
319 cn_i(void *vstart, void *vend, size_t stride, void *n)
320 {
321 size_t *nodes = (size_t *)n;
322 VALUE v = (VALUE)vstart;
323
324 for (; v != (VALUE)vend; v += stride) {
325 if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_NODE) {
326 size_t s = nd_type((NODE *)v);
327 nodes[s]++;
328 }
329 }
330
331 return 0;
332 }
333
334 /*
335 * call-seq:
336 * ObjectSpace.count_nodes([result_hash]) -> hash
337 *
338 * Counts nodes for each node type.
339 *
340 * This method is only for MRI developers interested in performance and memory
341 * usage of Ruby programs.
342 *
343 * It returns a hash as:
344 *
345 * {:NODE_METHOD=>2027, :NODE_FBODY=>1927, :NODE_CFUNC=>1798, ...}
346 *
347 * If the optional argument, result_hash, is given, it is overwritten and
348 * returned. This is intended to avoid probe effect.
349 *
350 * Note:
351 * The contents of the returned hash is implementation defined.
352 * It may be changed in future.
353 *
354 * This method is only expected to work with C Ruby.
355 */
356
357 static VALUE
358 count_nodes(int argc, VALUE *argv, VALUE os)
359 {
360 size_t nodes[NODE_LAST+1];
361 enum node_type i;
362 VALUE hash = setup_hash(argc, argv);
363
364 for (i = 0; i <= NODE_LAST; i++) {
365 nodes[i] = 0;
366 }
367
368 rb_objspace_each_objects(cn_i, &nodes[0]);
369
370 for (i=0; i<NODE_LAST; i++) {
371 if (nodes[i] != 0) {
372 VALUE node;
373 switch (i) {
374 #define COUNT_NODE(n) case n: node = ID2SYM(rb_intern(#n)); goto set
375 COUNT_NODE(NODE_SCOPE);
376 COUNT_NODE(NODE_BLOCK);
377 COUNT_NODE(NODE_IF);
378 COUNT_NODE(NODE_UNLESS);
379 COUNT_NODE(NODE_CASE);
380 COUNT_NODE(NODE_CASE2);
381 COUNT_NODE(NODE_CASE3);
382 COUNT_NODE(NODE_WHEN);
383 COUNT_NODE(NODE_IN);
384 COUNT_NODE(NODE_WHILE);
385 COUNT_NODE(NODE_UNTIL);
386 COUNT_NODE(NODE_ITER);
387 COUNT_NODE(NODE_FOR);
388 COUNT_NODE(NODE_FOR_MASGN);
389 COUNT_NODE(NODE_BREAK);
390 COUNT_NODE(NODE_NEXT);
391 COUNT_NODE(NODE_REDO);
392 COUNT_NODE(NODE_RETRY);
393 COUNT_NODE(NODE_BEGIN);
394 COUNT_NODE(NODE_RESCUE);
395 COUNT_NODE(NODE_RESBODY);
396 COUNT_NODE(NODE_ENSURE);
397 COUNT_NODE(NODE_AND);
398 COUNT_NODE(NODE_OR);
399 COUNT_NODE(NODE_MASGN);
400 COUNT_NODE(NODE_LASGN);
401 COUNT_NODE(NODE_DASGN);
402 COUNT_NODE(NODE_DASGN_CURR);
403 COUNT_NODE(NODE_GASGN);
404 COUNT_NODE(NODE_IASGN);
405 COUNT_NODE(NODE_CDECL);
406 COUNT_NODE(NODE_CVASGN);
407 COUNT_NODE(NODE_OP_ASGN1);
408 COUNT_NODE(NODE_OP_ASGN2);
409 COUNT_NODE(NODE_OP_ASGN_AND);
410 COUNT_NODE(NODE_OP_ASGN_OR);
411 COUNT_NODE(NODE_OP_CDECL);
412 COUNT_NODE(NODE_CALL);
413 COUNT_NODE(NODE_OPCALL);
414 COUNT_NODE(NODE_FCALL);
415 COUNT_NODE(NODE_VCALL);
416 COUNT_NODE(NODE_QCALL);
417 COUNT_NODE(NODE_SUPER);
418 COUNT_NODE(NODE_ZSUPER);
419 COUNT_NODE(NODE_LIST);
420 COUNT_NODE(NODE_ZLIST);
421 COUNT_NODE(NODE_VALUES);
422 COUNT_NODE(NODE_HASH);
423 COUNT_NODE(NODE_RETURN);
424 COUNT_NODE(NODE_YIELD);
425 COUNT_NODE(NODE_LVAR);
426 COUNT_NODE(NODE_DVAR);
427 COUNT_NODE(NODE_GVAR);
428 COUNT_NODE(NODE_IVAR);
429 COUNT_NODE(NODE_CONST);
430 COUNT_NODE(NODE_CVAR);
431 COUNT_NODE(NODE_NTH_REF);
432 COUNT_NODE(NODE_BACK_REF);
433 COUNT_NODE(NODE_MATCH);
434 COUNT_NODE(NODE_MATCH2);
435 COUNT_NODE(NODE_MATCH3);
436 COUNT_NODE(NODE_LIT);
437 COUNT_NODE(NODE_STR);
438 COUNT_NODE(NODE_DSTR);
439 COUNT_NODE(NODE_XSTR);
440 COUNT_NODE(NODE_DXSTR);
441 COUNT_NODE(NODE_EVSTR);
442 COUNT_NODE(NODE_DREGX);
443 COUNT_NODE(NODE_ONCE);
444 COUNT_NODE(NODE_ARGS);
445 COUNT_NODE(NODE_ARGS_AUX);
446 COUNT_NODE(NODE_OPT_ARG);
447 COUNT_NODE(NODE_KW_ARG);
448 COUNT_NODE(NODE_POSTARG);
449 COUNT_NODE(NODE_ARGSCAT);
450 COUNT_NODE(NODE_ARGSPUSH);
451 COUNT_NODE(NODE_SPLAT);
452 COUNT_NODE(NODE_BLOCK_PASS);
453 COUNT_NODE(NODE_DEFN);
454 COUNT_NODE(NODE_DEFS);
455 COUNT_NODE(NODE_ALIAS);
456 COUNT_NODE(NODE_VALIAS);
457 COUNT_NODE(NODE_UNDEF);
458 COUNT_NODE(NODE_CLASS);
459 COUNT_NODE(NODE_MODULE);
460 COUNT_NODE(NODE_SCLASS);
461 COUNT_NODE(NODE_COLON2);
462 COUNT_NODE(NODE_COLON3);
463 COUNT_NODE(NODE_DOT2);
464 COUNT_NODE(NODE_DOT3);
465 COUNT_NODE(NODE_FLIP2);
466 COUNT_NODE(NODE_FLIP3);
467 COUNT_NODE(NODE_SELF);
468 COUNT_NODE(NODE_NIL);
469 COUNT_NODE(NODE_TRUE);
470 COUNT_NODE(NODE_FALSE);
471 COUNT_NODE(NODE_ERRINFO);
472 COUNT_NODE(NODE_DEFINED);
473 COUNT_NODE(NODE_POSTEXE);
474 COUNT_NODE(NODE_DSYM);
475 COUNT_NODE(NODE_ATTRASGN);
476 COUNT_NODE(NODE_LAMBDA);
477 COUNT_NODE(NODE_ARYPTN);
478 COUNT_NODE(NODE_HSHPTN);
479 #undef COUNT_NODE
480 case NODE_LAST: break;
481 }
482 UNREACHABLE;
483 set:
484 rb_hash_aset(hash, node, SIZET2NUM(nodes[i]));
485 }
486 }
487 return hash;
488 }
489
490 static int
491 cto_i(void *vstart, void *vend, size_t stride, void *data)
492 {
493 VALUE hash = (VALUE)data;
494 VALUE v = (VALUE)vstart;
495
496 for (; v != (VALUE)vend; v += stride) {
497 if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_DATA) {
498 VALUE counter;
499 VALUE key = RBASIC(v)->klass;
500
501 if (key == 0) {
502 const char *name = rb_objspace_data_type_name(v);
503 if (name == 0) name = "unknown";
504 key = ID2SYM(rb_intern(name));
505 }
506
507 counter = rb_hash_aref(hash, key);
508 if (NIL_P(counter)) {
509 counter = INT2FIX(1);
510 }
511 else {
512 counter = INT2FIX(FIX2INT(counter) + 1);
513 }
514
515 rb_hash_aset(hash, key, counter);
516 }
517 }
518
519 return 0;
520 }
521
522 /*
523 * call-seq:
524 * ObjectSpace.count_tdata_objects([result_hash]) -> hash
525 *
526 * Counts objects for each +T_DATA+ type.
527 *
528 * This method is only for MRI developers interested in performance and memory
529 * usage of Ruby programs.
530 *
531 * It returns a hash as:
532 *
533 * {RubyVM::InstructionSequence=>504, :parser=>5, :barrier=>6,
534 * :mutex=>6, Proc=>60, RubyVM::Env=>57, Mutex=>1, Encoding=>99,
535 * ThreadGroup=>1, Binding=>1, Thread=>1, RubyVM=>1, :iseq=>1,
536 * Random=>1, ARGF.class=>1, Data=>1, :autoload=>3, Time=>2}
537 * # T_DATA objects existing at startup on r32276.
538 *
539 * If the optional argument, result_hash, is given, it is overwritten and
540 * returned. This is intended to avoid probe effect.
541 *
542 * The contents of the returned hash is implementation specific and may change
543 * in the future.
544 *
545 * In this version, keys are Class object or Symbol object.
546 *
547 * If object is kind of normal (accessible) object, the key is Class object.
548 * If object is not a kind of normal (internal) object, the key is symbol
549 * name, registered by rb_data_type_struct.
550 *
551 * This method is only expected to work with C Ruby.
552 */
553
554 static VALUE
555 count_tdata_objects(int argc, VALUE *argv, VALUE self)
556 {
557 VALUE hash = setup_hash(argc, argv);
558 rb_objspace_each_objects(cto_i, (void *)hash);
559 return hash;
560 }
561
562 static ID imemo_type_ids[IMEMO_MASK+1];
563
564 static int
565 count_imemo_objects_i(void *vstart, void *vend, size_t stride, void *data)
566 {
567 VALUE hash = (VALUE)data;
568 VALUE v = (VALUE)vstart;
569
570 for (; v != (VALUE)vend; v += stride) {
571 if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_IMEMO) {
572 VALUE counter;
573 VALUE key = ID2SYM(imemo_type_ids[imemo_type(v)]);
574
575 counter = rb_hash_aref(hash, key);
576
577 if (NIL_P(counter)) {
578 counter = INT2FIX(1);
579 }
580 else {
581 counter = INT2FIX(FIX2INT(counter) + 1);
582 }
583
584 rb_hash_aset(hash, key, counter);
585 }
586 }
587
588 return 0;
589 }
590
591 /*
592 * call-seq:
593 * ObjectSpace.count_imemo_objects([result_hash]) -> hash
594 *
595 * Counts objects for each +T_IMEMO+ type.
596 *
597 * This method is only for MRI developers interested in performance and memory
598 * usage of Ruby programs.
599 *
600 * It returns a hash as:
601 *
602 * {:imemo_ifunc=>8,
603 * :imemo_svar=>7,
604 * :imemo_cref=>509,
605 * :imemo_memo=>1,
606 * :imemo_throw_data=>1}
607 *
608 * If the optional argument, result_hash, is given, it is overwritten and
609 * returned. This is intended to avoid probe effect.
610 *
611 * The contents of the returned hash is implementation specific and may change
612 * in the future.
613 *
614 * In this version, keys are symbol objects.
615 *
616 * This method is only expected to work with C Ruby.
617 */
618
619 static VALUE
620 count_imemo_objects(int argc, VALUE *argv, VALUE self)
621 {
622 VALUE hash = setup_hash(argc, argv);
623
624 if (imemo_type_ids[0] == 0) {
625 imemo_type_ids[0] = rb_intern("imemo_env");
626 imemo_type_ids[1] = rb_intern("imemo_cref");
627 imemo_type_ids[2] = rb_intern("imemo_svar");
628 imemo_type_ids[3] = rb_intern("imemo_throw_data");
629 imemo_type_ids[4] = rb_intern("imemo_ifunc");
630 imemo_type_ids[5] = rb_intern("imemo_memo");
631 imemo_type_ids[6] = rb_intern("imemo_ment");
632 imemo_type_ids[7] = rb_intern("imemo_iseq");
633 imemo_type_ids[8] = rb_intern("imemo_tmpbuf");
634 imemo_type_ids[9] = rb_intern("imemo_ast");
635 imemo_type_ids[10] = rb_intern("imemo_parser_strterm");
636 }
637
638 rb_objspace_each_objects(count_imemo_objects_i, (void *)hash);
639
640 return hash;
641 }
642
643 static void
644 iow_mark(void *ptr)
645 {
646 rb_gc_mark((VALUE)ptr);
647 }
648
649 static size_t
650 iow_size(const void *ptr)
651 {
652 VALUE obj = (VALUE)ptr;
653 return rb_obj_memsize_of(obj);
654 }
655
656 static const rb_data_type_t iow_data_type = {
657 "ObjectSpace::InternalObjectWrapper",
658 {iow_mark, 0, iow_size,},
659 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
660 };
661
662 static VALUE rb_mInternalObjectWrapper;
663
664 static VALUE
665 iow_newobj(VALUE obj)
666 {
667 return TypedData_Wrap_Struct(rb_mInternalObjectWrapper, &iow_data_type, (void *)obj);
668 }
669
670 /* Returns the type of the internal object. */
671 static VALUE
672 iow_type(VALUE self)
673 {
674 VALUE obj = (VALUE)DATA_PTR(self);
675 return type2sym(BUILTIN_TYPE(obj));
676 }
677
678 /* See Object#inspect. */
679 static VALUE
680 iow_inspect(VALUE self)
681 {
682 VALUE obj = (VALUE)DATA_PTR(self);
683 VALUE type = type2sym(BUILTIN_TYPE(obj));
684
685 return rb_sprintf("#<InternalObject:%p %"PRIsVALUE">", (void *)obj, rb_sym2str(type));
686 }
687
688 /* Returns the Object#object_id of the internal object. */
689 static VALUE
690 iow_internal_object_id(VALUE self)
691 {
692 VALUE obj = (VALUE)DATA_PTR(self);
693 return rb_obj_id(obj);
694 }
695
696 struct rof_data {
697 st_table *refs;
698 VALUE internals;
699 };
700
701 static void
702 reachable_object_from_i(VALUE obj, void *data_ptr)
703 {
704 struct rof_data *data = (struct rof_data *)data_ptr;
705 VALUE key = obj;
706 VALUE val = obj;
707
708 if (rb_objspace_markable_object_p(obj)) {
709 if (rb_objspace_internal_object_p(obj)) {
710 val = iow_newobj(obj);
711 rb_ary_push(data->internals, val);
712 }
713 st_insert(data->refs, key, val);
714 }
715 }
716
717 static int
718 collect_values(st_data_t key, st_data_t value, st_data_t data)
719 {
720 VALUE ary = (VALUE)data;
721 rb_ary_push(ary, (VALUE)value);
722 return ST_CONTINUE;
723 }
724
725 /*
726 * call-seq:
727 * ObjectSpace.reachable_objects_from(obj) -> array or nil
728 *
729 * [MRI specific feature] Return all reachable objects from `obj'.
730 *
731 * This method returns all reachable objects from `obj'.
732 *
733 * If `obj' has two or more references to the same object `x', then returned
734 * array only includes one `x' object.
735 *
736 * If `obj' is a non-markable (non-heap management) object such as true,
737 * false, nil, symbols and Fixnums (and Flonum) then it simply returns nil.
738 *
739 * If `obj' has references to an internal object, then it returns instances of
740 * ObjectSpace::InternalObjectWrapper class. This object contains a reference
741 * to an internal object and you can check the type of internal object with
742 * `type' method.
743 *
744 * If `obj' is instance of ObjectSpace::InternalObjectWrapper class, then this
745 * method returns all reachable object from an internal object, which is
746 * pointed by `obj'.
747 *
748 * With this method, you can find memory leaks.
749 *
750 * This method is only expected to work except with C Ruby.
751 *
752 * Example:
753 * ObjectSpace.reachable_objects_from(['a', 'b', 'c'])
754 * #=> [Array, 'a', 'b', 'c']
755 *
756 * ObjectSpace.reachable_objects_from(['a', 'a', 'a'])
757 * #=> [Array, 'a', 'a', 'a'] # all 'a' strings have different object id
758 *
759 * ObjectSpace.reachable_objects_from([v = 'a', v, v])
760 * #=> [Array, 'a']
761 *
762 * ObjectSpace.reachable_objects_from(1)
763 * #=> nil # 1 is not markable (heap managed) object
764 *
765 */
766
767 static VALUE
768 reachable_objects_from(VALUE self, VALUE obj)
769 {
770 if (rb_objspace_markable_object_p(obj)) {
771 VALUE ret = rb_ary_new();
772 struct rof_data data;
773
774 if (rb_typeddata_is_kind_of(obj, &iow_data_type)) {
775 obj = (VALUE)DATA_PTR(obj);
776 }
777
778 data.refs = st_init_numtable();
779 data.internals = rb_ary_new();
780
781 rb_objspace_reachable_objects_from(obj, reachable_object_from_i, &data);
782
783 st_foreach(data.refs, collect_values, (st_data_t)ret);
784 return ret;
785 }
786 else {
787 return Qnil;
788 }
789 }
790
791 struct rofr_data {
792 VALUE categories;
793 const char *last_category;
794 VALUE last_category_str;
795 VALUE last_category_objects;
796 };
797
798 static void
799 reachable_object_from_root_i(const char *category, VALUE obj, void *ptr)
800 {
801 struct rofr_data *data = (struct rofr_data *)ptr;
802 VALUE category_str;
803 VALUE category_objects;
804
805 if (category == data->last_category) {
806 category_str = data->last_category_str;
807 category_objects = data->last_category_objects;
808 }
809 else {
810 data->last_category = category;
811 category_str = data->last_category_str = rb_str_new2(category);
812 category_objects = data->last_category_objects = rb_ident_hash_new();
813 if (!NIL_P(rb_hash_lookup(data->categories, category_str))) {
814 rb_bug("reachable_object_from_root_i: category should insert at once");
815 }
816 rb_hash_aset(data->categories, category_str, category_objects);
817 }
818
819 if (rb_objspace_markable_object_p(obj) &&
820 obj != data->categories &&
821 obj != data->last_category_objects) {
822 if (rb_objspace_internal_object_p(obj)) {
823 obj = iow_newobj(obj);
824 }
825 rb_hash_aset(category_objects, obj, obj);
826 }
827 }
828
829 static int
830 collect_values_of_values(VALUE category, VALUE category_objects, VALUE categories)
831 {
832 VALUE ary = rb_ary_new();
833 rb_hash_foreach(category_objects, collect_values, ary);
834 rb_hash_aset(categories, category, ary);
835 return ST_CONTINUE;
836 }
837
838 /*
839 * call-seq:
840 * ObjectSpace.reachable_objects_from_root -> hash
841 *
842 * [MRI specific feature] Return all reachable objects from root.
843 */
844 static VALUE
845 reachable_objects_from_root(VALUE self)
846 {
847 struct rofr_data data;
848 VALUE hash = data.categories = rb_ident_hash_new();
849 data.last_category = 0;
850
851 rb_objspace_reachable_objects_from_root(reachable_object_from_root_i, &data);
852 rb_hash_foreach(hash, collect_values_of_values, hash);
853
854 return hash;
855 }
856
857 static VALUE
858 wrap_klass_iow(VALUE klass)
859 {
860 if (!RTEST(klass)) {
861 return Qnil;
862 }
863 else if (RB_TYPE_P(klass, T_ICLASS)) {
864 return iow_newobj(klass);
865 }
866 else {
867 return klass;
868 }
869 }
870
871 /*
872 * call-seq:
873 * ObjectSpace.internal_class_of(obj) -> Class or Module
874 *
875 * [MRI specific feature] Return internal class of obj.
876 * obj can be an instance of InternalObjectWrapper.
877 *
878 * Note that you should not use this method in your application.
879 */
880 static VALUE
881 objspace_internal_class_of(VALUE self, VALUE obj)
882 {
883 VALUE klass;
884
885 if (rb_typeddata_is_kind_of(obj, &iow_data_type)) {
886 obj = (VALUE)DATA_PTR(obj);
887 }
888
889 klass = CLASS_OF(obj);
890 return wrap_klass_iow(klass);
891 }
892
893 /*
894 * call-seq:
895 * ObjectSpace.internal_super_of(cls) -> Class or Module
896 *
897 * [MRI specific feature] Return internal super class of cls (Class or Module).
898 * obj can be an instance of InternalObjectWrapper.
899 *
900 * Note that you should not use this method in your application.
901 */
902 static VALUE
903 objspace_internal_super_of(VALUE self, VALUE obj)
904 {
905 VALUE super;
906
907 if (rb_typeddata_is_kind_of(obj, &iow_data_type)) {
908 obj = (VALUE)DATA_PTR(obj);
909 }
910
911 switch (OBJ_BUILTIN_TYPE(obj)) {
912 case T_MODULE:
913 case T_CLASS:
914 case T_ICLASS:
915 super = RCLASS_SUPER(obj);
916 break;
917 default:
918 rb_raise(rb_eArgError, "class or module is expected");
919 }
920
921 return wrap_klass_iow(super);
922 }
923
924 void Init_object_tracing(VALUE rb_mObjSpace);
925 void Init_objspace_dump(VALUE rb_mObjSpace);
926
927 /*
928 * Document-module: ObjectSpace
929 *
930 * The objspace library extends the ObjectSpace module and adds several
931 * methods to get internal statistic information about
932 * object/memory management.
933 *
934 * You need to <code>require 'objspace'</code> to use this extension module.
935 *
936 * Generally, you *SHOULD NOT* use this library if you do not know
937 * about the MRI implementation. Mainly, this library is for (memory)
938 * profiler developers and MRI developers who need to know about MRI
939 * memory usage.
940 */
941
942 void
943 Init_objspace(void)
944 {
945 #undef rb_intern
946 VALUE rb_mObjSpace;
947 #if 0
948 rb_mObjSpace = rb_define_module("ObjectSpace"); /* let rdoc know */
949 #endif
950 rb_mObjSpace = rb_const_get(rb_cObject, rb_intern("ObjectSpace"));
951
952 rb_define_module_function(rb_mObjSpace, "memsize_of", memsize_of_m, 1);
953 rb_define_module_function(rb_mObjSpace, "memsize_of_all", memsize_of_all_m, -1);
954
955 rb_define_module_function(rb_mObjSpace, "count_objects_size", count_objects_size, -1);
956 rb_define_module_function(rb_mObjSpace, "count_symbols", count_symbols, -1);
957 rb_define_module_function(rb_mObjSpace, "count_nodes", count_nodes, -1);
958 rb_define_module_function(rb_mObjSpace, "count_tdata_objects", count_tdata_objects, -1);
959 rb_define_module_function(rb_mObjSpace, "count_imemo_objects", count_imemo_objects, -1);
960
961 rb_define_module_function(rb_mObjSpace, "reachable_objects_from", reachable_objects_from, 1);
962 rb_define_module_function(rb_mObjSpace, "reachable_objects_from_root", reachable_objects_from_root, 0);
963
964 rb_define_module_function(rb_mObjSpace, "internal_class_of", objspace_internal_class_of, 1);
965 rb_define_module_function(rb_mObjSpace, "internal_super_of", objspace_internal_super_of, 1);
966
967 /*
968 * This class is used as a return value from
969 * ObjectSpace::reachable_objects_from.
970 *
971 * When ObjectSpace::reachable_objects_from returns an object with
972 * references to an internal object, an instance of this class is returned.
973 *
974 * You can use the #type method to check the type of the internal object.
975 */
976 rb_mInternalObjectWrapper = rb_define_class_under(rb_mObjSpace, "InternalObjectWrapper", rb_cObject);
977 rb_define_method(rb_mInternalObjectWrapper, "type", iow_type, 0);
978 rb_define_method(rb_mInternalObjectWrapper, "inspect", iow_inspect, 0);
979 rb_define_method(rb_mInternalObjectWrapper, "internal_object_id", iow_internal_object_id, 0);
980
981 Init_object_tracing(rb_mObjSpace);
982 Init_objspace_dump(rb_mObjSpace);
983 }
NODE_NEXT
@ NODE_NEXT
Definition: node.h:47
dynamic_symbol_counts::immortal
size_t immortal
Definition: objspace.c:249
NODE_COLON3
@ NODE_COLON3
Definition: node.h:119
NODE_NIL
@ NODE_NIL
Definition: node.h:125
ID
unsigned long ID
Definition: ruby.h:103
T_FALSE
#define T_FALSE
Definition: ruby.h:537
NODE_ATTRASGN
@ NODE_ATTRASGN
Definition: node.h:132
T_FLOAT
#define T_FLOAT
Definition: ruby.h:527
dynamic_symbol_counts
Definition: objspace.c:247
NODE_DSYM
@ NODE_DSYM
Definition: node.h:131
rb_str_new2
#define rb_str_new2
Definition: intern.h:903
NODE_HSHPTN
@ NODE_HSHPTN
Definition: node.h:135
NODE_RESCUE
@ NODE_RESCUE
Definition: node.h:51
rb_objspace_data_type_name
const char * rb_objspace_data_type_name(VALUE obj)
Definition: gc.c:2430
NODE_OP_ASGN1
@ NODE_OP_ASGN1
Definition: node.h:64
FIX2INT
#define FIX2INT(x)
Definition: ruby.h:717
ruby_value_type
ruby_value_type
Definition: ruby.h:486
rofr_data::last_category_str
VALUE last_category_str
Definition: objspace.c:794
rb_ident_hash_new
VALUE rb_ident_hash_new(void)
Definition: hash.c:4203
rb_hash_new
VALUE rb_hash_new(void)
Definition: hash.c:1501
NODE_TRUE
@ NODE_TRUE
Definition: node.h:126
NODE_MATCH3
@ NODE_MATCH3
Definition: node.h:92
NODE_NTH_REF
@ NODE_NTH_REF
Definition: node.h:88
NODE_ZLIST
@ NODE_ZLIST
Definition: node.h:77
NODE_DREGX
@ NODE_DREGX
Definition: node.h:99
IMEMO_MASK
#define IMEMO_MASK
Definition: internal.h:1145
gc.h
NODE_OR
@ NODE_OR
Definition: node.h:55
NODE_ARYPTN
@ NODE_ARYPTN
Definition: node.h:134
rb_scan_args
#define rb_scan_args(argc, argvp, fmt,...)
Definition: rb_mjit_min_header-2.7.0.h:6372
NODE_OP_ASGN_OR
@ NODE_OP_ASGN_OR
Definition: node.h:67
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
T_MASK
#define T_MASK
Definition: md5.c:131
NODE_HASH
@ NODE_HASH
Definition: node.h:79
OBJ_BUILTIN_TYPE
#define OBJ_BUILTIN_TYPE(obj)
Definition: internal.h:2597
NODE_CONST
@ NODE_CONST
Definition: node.h:86
re.h
NODE_LASGN
@ NODE_LASGN
Definition: node.h:57
rb_hash_aref
VALUE rb_hash_aref(VALUE hash, VALUE key)
Definition: hash.c:1964
st_init_numtable
st_table * st_init_numtable(void)
Definition: st.c:653
NODE_FLIP2
@ NODE_FLIP2
Definition: node.h:122
NODE_ARGSPUSH
@ NODE_ARGSPUSH
Definition: node.h:107
NODE_FOR
@ NODE_FOR
Definition: node.h:44
VALUE
unsigned long VALUE
Definition: ruby.h:102
NODE_CASE
@ NODE_CASE
Definition: node.h:36
rb_eArgError
VALUE rb_eArgError
Definition: error.c:923
rb_intern
#define rb_intern(str)
NODE_OP_ASGN2
@ NODE_OP_ASGN2
Definition: node.h:65
NODE_ARGSCAT
@ NODE_ARGSCAT
Definition: node.h:106
RB_TYPE_P
#define RB_TYPE_P(obj, type)
Definition: ruby.h:560
NODE_DOT2
@ NODE_DOT2
Definition: node.h:120
NODE_EVSTR
@ NODE_EVSTR
Definition: node.h:98
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:772
ID_SCOPE_MASK
#define ID_SCOPE_MASK
Definition: id.h:32
NODE_UNTIL
@ NODE_UNTIL
Definition: node.h:42
RSYMBOL
#define RSYMBOL(obj)
Definition: symbol.h:33
NODE_CVASGN
@ NODE_CVASGN
Definition: node.h:63
NODE_AND
@ NODE_AND
Definition: node.h:54
NODE_LIT
@ NODE_LIT
Definition: node.h:93
rof_data::internals
VALUE internals
Definition: objspace.c:698
NODE_MASGN
@ NODE_MASGN
Definition: node.h:56
T_RATIONAL
#define T_RATIONAL
Definition: ruby.h:541
NODE_DXSTR
@ NODE_DXSTR
Definition: node.h:97
NODE_OPCALL
@ NODE_OPCALL
Definition: node.h:70
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
ptr
struct RIMemo * ptr
Definition: debug.c:74
rb_obj_id
VALUE rb_obj_id(VALUE obj)
Definition: gc.c:3770
T_DATA
#define T_DATA
Definition: ruby.h:538
rb_objspace_reachable_objects_from
void rb_objspace_reachable_objects_from(VALUE obj, void(func)(VALUE, void *), void *data)
Definition: gc.c:9448
rofr_data::last_category
const char * last_category
Definition: objspace.c:793
NODE_OP_ASGN_AND
@ NODE_OP_ASGN_AND
Definition: node.h:66
T_NODE
#define T_NODE
Definition: ruby.h:545
NODE_DASGN
@ NODE_DASGN
Definition: node.h:58
rofr_data::categories
VALUE categories
Definition: objspace.c:792
NODE_BLOCK
@ NODE_BLOCK
Definition: node.h:33
st.h
T_COMPLEX
#define T_COMPLEX
Definition: ruby.h:542
NODE_ERRINFO
@ NODE_ERRINFO
Definition: node.h:128
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:166
NODE_KW_ARG
@ NODE_KW_ARG
Definition: node.h:104
NODE_DSTR
@ NODE_DSTR
Definition: node.h:95
st_insert
int st_insert(st_table *tab, st_data_t key, st_data_t value)
Definition: st.c:1171
ID2SYM
#define ID2SYM(x)
Definition: ruby.h:414
T_SYMBOL
#define T_SYMBOL
Definition: ruby.h:540
T_OBJECT
#define T_OBJECT
Definition: ruby.h:523
NODE_SPLAT
@ NODE_SPLAT
Definition: node.h:108
NODE_ITER
@ NODE_ITER
Definition: node.h:43
NODE_CDECL
@ NODE_CDECL
Definition: node.h:62
NODE_CVAR
@ NODE_CVAR
Definition: node.h:87
v
int VALUE v
Definition: rb_mjit_min_header-2.7.0.h:12332
NODE_IN
@ NODE_IN
Definition: node.h:40
NODE_ZSUPER
@ NODE_ZSUPER
Definition: node.h:75
rb_sym_immortal_count
size_t rb_sym_immortal_count(void)
Definition: symbol.c:848
NODE_LAMBDA
@ NODE_LAMBDA
Definition: node.h:133
NODE_SUPER
@ NODE_SUPER
Definition: node.h:74
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2669
NODE_VCALL
@ NODE_VCALL
Definition: node.h:72
NODE_VALIAS
@ NODE_VALIAS
Definition: node.h:113
T_FILE
#define T_FILE
Definition: ruby.h:534
NODE_DEFS
@ NODE_DEFS
Definition: node.h:111
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.0.h:5742
NODE_UNLESS
@ NODE_UNLESS
Definition: node.h:35
T_ICLASS
#define T_ICLASS
Definition: ruby.h:525
imemo_type
imemo_type
Definition: internal.h:1132
rb_objspace_markable_object_p
int rb_objspace_markable_object_p(VALUE obj)
Definition: gc.c:3598
NODE_DEFN
@ NODE_DEFN
Definition: node.h:110
rb_objspace_internal_object_p
int rb_objspace_internal_object_p(VALUE obj)
Definition: gc.c:3095
DATA_PTR
#define DATA_PTR(dta)
Definition: ruby.h:1175
rof_data::refs
st_table * refs
Definition: objspace.c:697
node.h
T_FIXNUM
#define T_FIXNUM
Definition: ruby.h:535
COUNT_NODE
#define COUNT_NODE(n)
rofr_data
Definition: objspace.c:791
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
NODE_CLASS
@ NODE_CLASS
Definition: node.h:115
RHASH_EMPTY_P
#define RHASH_EMPTY_P(h)
Definition: ruby.h:1131
NODE_IF
@ NODE_IF
Definition: node.h:34
NODE_ENSURE
@ NODE_ENSURE
Definition: node.h:53
NODE_MATCH2
@ NODE_MATCH2
Definition: node.h:91
T_REGEXP
#define T_REGEXP
Definition: ruby.h:529
Init_object_tracing
void Init_object_tracing(VALUE rb_mObjSpace)
Definition: object_tracing.c:482
rb_hash_lookup
VALUE rb_hash_lookup(VALUE hash, VALUE key)
Definition: hash.c:1990
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1195
NODE_CASE3
@ NODE_CASE3
Definition: node.h:38
TypedData_Wrap_Struct
#define TypedData_Wrap_Struct(klass, data_type, sval)
Definition: ruby.h:1231
NODE_DASGN_CURR
@ NODE_DASGN_CURR
Definition: node.h:59
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:922
NODE_COLON2
@ NODE_COLON2
Definition: node.h:118
NODE_DOT3
@ NODE_DOT3
Definition: node.h:121
total_data::klass
VALUE klass
Definition: objspace.c:47
node_type
node_type
Definition: node.h:22
T_CLASS
#define T_CLASS
Definition: ruby.h:524
T_MATCH
#define T_MATCH
Definition: ruby.h:539
NODE_BREAK
@ NODE_BREAK
Definition: node.h:46
NODE_GVAR
@ NODE_GVAR
Definition: node.h:84
NODE_XSTR
@ NODE_XSTR
Definition: node.h:96
symbol.h
dynamic_symbol_counts::mortal
size_t mortal
Definition: objspace.c:248
RCLASS_SUPER
#define RCLASS_SUPER(c)
Definition: classext.h:16
NODE_ARGS
@ NODE_ARGS
Definition: node.h:101
NODE_DVAR
@ NODE_DVAR
Definition: node.h:83
rb_hash_foreach
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
Definition: hash.c:1461
NODE_ALIAS
@ NODE_ALIAS
Definition: node.h:112
T_NONE
#define T_NONE
Definition: ruby.h:521
NODE_OP_CDECL
@ NODE_OP_CDECL
Definition: node.h:68
key
key
Definition: openssl_missing.h:181
T_HASH
#define T_HASH
Definition: ruby.h:531
NODE_POSTARG
@ NODE_POSTARG
Definition: node.h:105
NODE_SELF
@ NODE_SELF
Definition: node.h:124
NODE_LVAR
@ NODE_LVAR
Definition: node.h:82
rb_typeddata_is_kind_of
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
Definition: error.c:872
NODE_STR
@ NODE_STR
Definition: node.h:94
CLASS_OF
#define CLASS_OF(v)
Definition: ruby.h:484
T_MODULE
#define T_MODULE
Definition: ruby.h:526
st_foreach
int st_foreach(st_table *tab, st_foreach_callback_func *func, st_data_t arg)
Definition: st.c:1718
rb_define_module_function
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1771
Init_objspace
void Init_objspace(void)
Definition: objspace.c:943
NODE_IVAR
@ NODE_IVAR
Definition: node.h:85
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
n
const char size_t n
Definition: rb_mjit_min_header-2.7.0.h:5456
T_BIGNUM
#define T_BIGNUM
Definition: ruby.h:533
NODE_BEGIN
@ NODE_BEGIN
Definition: node.h:50
rb_objspace_each_objects
void rb_objspace_each_objects(each_obj_callback *callback, void *data)
Definition: gc.c:3025
NODE_POSTEXE
@ NODE_POSTEXE
Definition: node.h:130
NODE_RESBODY
@ NODE_RESBODY
Definition: node.h:52
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:634
rb_objspace_reachable_objects_from_root
void rb_objspace_reachable_objects_from_root(void(func)(const char *category, VALUE, void *), void *passing_data)
Definition: gc.c:9476
NODE_RETURN
@ NODE_RETURN
Definition: node.h:80
internal.h
NODE_FALSE
@ NODE_FALSE
Definition: node.h:127
T_ARRAY
#define T_ARRAY
Definition: ruby.h:530
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.0.h:5601
argv
char ** argv
Definition: ruby.c:223
NODE_ONCE
@ NODE_ONCE
Definition: node.h:100
ST_CONTINUE
@ ST_CONTINUE
Definition: st.h:99
NODE_IASGN
@ NODE_IASGN
Definition: node.h:61
UNREACHABLE
#define UNREACHABLE
Definition: ruby.h:63
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1197
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.0.h:13254
NODE_ARGS_AUX
@ NODE_ARGS_AUX
Definition: node.h:102
st_data_t
unsigned long st_data_t
Definition: rb_mjit_min_header-2.7.0.h:5363
T_NIL
#define T_NIL
Definition: ruby.h:522
T_MOVED
#define T_MOVED
Definition: ruby.h:547
NODE_WHEN
@ NODE_WHEN
Definition: node.h:39
NODE_BLOCK_PASS
@ NODE_BLOCK_PASS
Definition: node.h:109
NODE_MATCH
@ NODE_MATCH
Definition: node.h:90
RUBY_TYPED_FREE_IMMEDIATELY
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1207
T_ZOMBIE
#define T_ZOMBIE
Definition: ruby.h:546
rb_hash_aset
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:2779
NODE_OPT_ARG
@ NODE_OPT_ARG
Definition: node.h:103
NODE_CALL
@ NODE_CALL
Definition: node.h:69
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
NODE_CASE2
@ NODE_CASE2
Definition: node.h:37
io.h
argc
int argc
Definition: ruby.c:222
T_IMEMO
#define T_IMEMO
Definition: ruby.h:543
rb_obj_memsize_of
size_t rb_obj_memsize_of(VALUE obj)
Definition: gc.c:3934
Init_objspace_dump
void Init_objspace_dump(VALUE rb_mObjSpace)
Definition: objspace_dump.c:499
rb_data_type_struct
Definition: ruby.h:1148
BUILTIN_TYPE
#define BUILTIN_TYPE(x)
Definition: ruby.h:551
RBASIC
#define RBASIC(obj)
Definition: ruby.h:1267
NODE_FCALL
@ NODE_FCALL
Definition: node.h:71
rb_gc_mark
void rb_gc_mark(VALUE ptr)
Definition: gc.c:5212
total_data::total
size_t total
Definition: objspace.c:46
NODE_YIELD
@ NODE_YIELD
Definition: node.h:81
CASE_TYPE
#define CASE_TYPE(t)
NODE_UNDEF
@ NODE_UNDEF
Definition: node.h:114
rof_data
Definition: objspace.c:696
NODE_BACK_REF
@ NODE_BACK_REF
Definition: node.h:89
T_STRING
#define T_STRING
Definition: ruby.h:528
NODE_DEFINED
@ NODE_DEFINED
Definition: node.h:129
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:698
rb_sym2str
VALUE rb_sym2str(VALUE)
Definition: symbol.c:784
SIZET2NUM
#define SIZET2NUM(v)
Definition: ruby.h:295
RHASH_TBL
#define RHASH_TBL(h)
Definition: ruby.h:1127
NODE_LAST
@ NODE_LAST
Definition: node.h:136
NODE_VALUES
@ NODE_VALUES
Definition: node.h:78
NODE_FLIP3
@ NODE_FLIP3
Definition: node.h:123
nd_type
#define nd_type(n)
Definition: node.h:188
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:723
total_data
Definition: objspace.c:45
T_STRUCT
#define T_STRUCT
Definition: ruby.h:532
Qnil
#define Qnil
Definition: ruby.h:469
NODE_REDO
@ NODE_REDO
Definition: node.h:48
rofr_data::last_category_objects
VALUE last_category_objects
Definition: objspace.c:795
NODE_MODULE
@ NODE_MODULE
Definition: node.h:116
st_table
Definition: st.h:79
NODE_QCALL
@ NODE_QCALL
Definition: node.h:73
NODE_SCOPE
@ NODE_SCOPE
Definition: node.h:32
NODE_RETRY
@ NODE_RETRY
Definition: node.h:49
NODE_LIST
@ NODE_LIST
Definition: node.h:76
T_TRUE
#define T_TRUE
Definition: ruby.h:536
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
Definition: object.c:692
RTEST
#define RTEST(v)
Definition: ruby.h:481
NODE_FOR_MASGN
@ NODE_FOR_MASGN
Definition: node.h:45
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
RNode
Definition: node.h:149
T_UNDEF
#define T_UNDEF
Definition: ruby.h:544
NODE_WHILE
@ NODE_WHILE
Definition: node.h:41
NODE_SCLASS
@ NODE_SCLASS
Definition: node.h:117
name
const char * name
Definition: nkf.c:208
NODE_GASGN
@ NODE_GASGN
Definition: node.h:60
rb_const_get
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:2387