Ruby  2.1.10p492(2016-04-01revision54464)
objspace.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  objspace.c - ObjectSpace extender for MRI.
4 
5  $Author: ko1 $
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/ruby.h>
16 #include <ruby/st.h>
17 #include <ruby/io.h>
18 #include <ruby/re.h>
19 #include "node.h"
20 #include "gc.h"
21 #include "internal.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 
36 static VALUE
38 {
39  return SIZET2NUM(rb_obj_memsize_of(obj));
40 }
41 
42 struct total_data {
43  size_t total;
45 };
46 
47 static int
48 total_i(void *vstart, void *vend, size_t stride, void *ptr)
49 {
50  VALUE v;
51  struct total_data *data = (struct total_data *)ptr;
52 
53  for (v = (VALUE)vstart; v != (VALUE)vend; v += stride) {
54  if (RBASIC(v)->flags) {
55  switch (BUILTIN_TYPE(v)) {
56  case T_NONE:
57  case T_ICLASS:
58  case T_NODE:
59  case T_ZOMBIE:
60  continue;
61  case T_CLASS:
62  if (FL_TEST(v, FL_SINGLETON))
63  continue;
64  default:
65  if (data->klass == 0 || rb_obj_is_kind_of(v, data->klass)) {
66  data->total += rb_obj_memsize_of(v);
67  }
68  }
69  }
70  }
71 
72  return 0;
73 }
74 
75 /*
76  * call-seq:
77  * ObjectSpace.memsize_of_all([klass]) -> Integer
78  *
79  * Return consuming memory size of all living objects.
80  *
81  * If +klass+ (should be Class object) is given, return the total memory size
82  * of instances of the given class.
83  *
84  * Note that the returned size is incomplete. You need to deal with this
85  * information as only a *HINT*. Especially, the size of +T_DATA+ may not be
86  * correct.
87  *
88  * Note that this method does *NOT* return total malloc'ed memory size.
89  *
90  * This method can be defined by the following Ruby code:
91  *
92  * def memsize_of_all klass = false
93  * total = 0
94  * ObjectSpace.each_object{|e|
95  * total += ObjectSpace.memsize_of(e) if klass == false || e.kind_of?(klass)
96  * }
97  * total
98  * end
99  *
100  * This method is only expected to work with C Ruby.
101  */
102 
103 static VALUE
105 {
106  struct total_data data = {0, 0};
107 
108  if (argc > 0) {
109  rb_scan_args(argc, argv, "01", &data.klass);
110  }
111 
113  return SIZET2NUM(data.total);
114 }
115 
116 static int
118 {
119  VALUE k = (VALUE)key;
120  VALUE hash = (VALUE)arg;
121  rb_hash_aset(hash, k, INT2FIX(0));
122  return ST_CONTINUE;
123 }
124 
125 static int
126 cos_i(void *vstart, void *vend, size_t stride, void *data)
127 {
128  size_t *counts = (size_t *)data;
129  VALUE v = (VALUE)vstart;
130 
131  for (;v != (VALUE)vend; v += stride) {
132  if (RBASIC(v)->flags) {
133  counts[BUILTIN_TYPE(v)] += rb_obj_memsize_of(v);
134  }
135  }
136  return 0;
137 }
138 
139 static VALUE
141 {
142  VALUE type;
143  switch (i) {
144 #define CASE_TYPE(t) case t: type = ID2SYM(rb_intern(#t)); break;
145  CASE_TYPE(T_NONE);
153  CASE_TYPE(T_HASH);
156  CASE_TYPE(T_FILE);
157  CASE_TYPE(T_DATA);
161  CASE_TYPE(T_NIL);
162  CASE_TYPE(T_TRUE);
167  CASE_TYPE(T_NODE);
170 #undef CASE_TYPE
171  default: rb_bug("type2sym: unknown type (%d)", i);
172  }
173  return type;
174 }
175 
176 /*
177  * call-seq:
178  * ObjectSpace.count_objects_size([result_hash]) -> hash
179  *
180  * Counts objects size (in bytes) for each type.
181  *
182  * Note that this information is incomplete. You need to deal with
183  * this information as only a *HINT*. Especially, total size of
184  * T_DATA may not right size.
185  *
186  * It returns a hash as:
187  * {:TOTAL=>1461154, :T_CLASS=>158280, :T_MODULE=>20672, :T_STRING=>527249, ...}
188  *
189  * If the optional argument, result_hash, is given,
190  * it is overwritten and returned.
191  * This is intended to avoid probe effect.
192  *
193  * The contents of the returned hash is implementation defined.
194  * It may be changed in future.
195  *
196  * This method is only expected to work with C Ruby.
197  */
198 
199 static VALUE
201 {
202  size_t counts[T_MASK+1];
203  size_t total = 0;
204  enum ruby_value_type i;
205  VALUE hash;
206 
207  if (rb_scan_args(argc, argv, "01", &hash) == 1) {
208  if (!RB_TYPE_P(hash, T_HASH))
209  rb_raise(rb_eTypeError, "non-hash given");
210  }
211 
212  for (i = 0; i <= T_MASK; i++) {
213  counts[i] = 0;
214  }
215 
216  rb_objspace_each_objects(cos_i, &counts[0]);
217 
218  if (hash == Qnil) {
219  hash = rb_hash_new();
220  }
221  else if (!RHASH_EMPTY_P(hash)) {
222  st_foreach(RHASH_TBL(hash), set_zero_i, hash);
223  }
224 
225  for (i = 0; i <= T_MASK; i++) {
226  if (counts[i]) {
227  VALUE type = type2sym(i);
228  total += counts[i];
229  rb_hash_aset(hash, type, SIZET2NUM(counts[i]));
230  }
231  }
232  rb_hash_aset(hash, ID2SYM(rb_intern("TOTAL")), SIZET2NUM(total));
233  return hash;
234 }
235 
236 static int
237 cn_i(void *vstart, void *vend, size_t stride, void *n)
238 {
239  size_t *nodes = (size_t *)n;
240  VALUE v = (VALUE)vstart;
241 
242  for (; v != (VALUE)vend; v += stride) {
243  if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_NODE) {
244  size_t s = nd_type((NODE *)v);
245  nodes[s]++;
246  }
247  }
248 
249  return 0;
250 }
251 
252 /*
253  * call-seq:
254  * ObjectSpace.count_nodes([result_hash]) -> hash
255  *
256  * Counts nodes for each node type.
257  *
258  * This method is only for MRI developers interested in performance and memory
259  * usage of Ruby programs.
260  *
261  * It returns a hash as:
262  *
263  * {:NODE_METHOD=>2027, :NODE_FBODY=>1927, :NODE_CFUNC=>1798, ...}
264  *
265  * If the optional argument, result_hash, is given, it is overwritten and
266  * returned. This is intended to avoid probe effect.
267  *
268  * Note:
269  * The contents of the returned hash is implementation defined.
270  * It may be changed in future.
271  *
272  * This method is only expected to work with C Ruby.
273  */
274 
275 static VALUE
277 {
278  size_t nodes[NODE_LAST+1];
279  size_t i;
280  VALUE hash;
281 
282  if (rb_scan_args(argc, argv, "01", &hash) == 1) {
283  if (!RB_TYPE_P(hash, T_HASH))
284  rb_raise(rb_eTypeError, "non-hash given");
285  }
286 
287  for (i = 0; i <= NODE_LAST; i++) {
288  nodes[i] = 0;
289  }
290 
291  rb_objspace_each_objects(cn_i, &nodes[0]);
292 
293  if (hash == Qnil) {
294  hash = rb_hash_new();
295  }
296  else if (!RHASH_EMPTY_P(hash)) {
297  st_foreach(RHASH_TBL(hash), set_zero_i, hash);
298  }
299 
300  for (i=0; i<NODE_LAST; i++) {
301  if (nodes[i] != 0) {
302  VALUE node;
303  switch (i) {
304 #define COUNT_NODE(n) case n: node = ID2SYM(rb_intern(#n)); break;
411 #undef COUNT_NODE
412  default: node = INT2FIX(i);
413  }
414  rb_hash_aset(hash, node, SIZET2NUM(nodes[i]));
415  }
416  }
417  return hash;
418 }
419 
420 static int
421 cto_i(void *vstart, void *vend, size_t stride, void *data)
422 {
423  VALUE hash = (VALUE)data;
424  VALUE v = (VALUE)vstart;
425 
426  for (; v != (VALUE)vend; v += stride) {
427  if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_DATA) {
428  VALUE counter;
429  VALUE key = RBASIC(v)->klass;
430 
431  if (key == 0) {
432  const char *name = rb_objspace_data_type_name(v);
433  if (name == 0) name = "unknown";
434  key = ID2SYM(rb_intern(name));
435  }
436 
437  counter = rb_hash_aref(hash, key);
438  if (NIL_P(counter)) {
439  counter = INT2FIX(1);
440  }
441  else {
442  counter = INT2FIX(FIX2INT(counter) + 1);
443  }
444 
445  rb_hash_aset(hash, key, counter);
446  }
447  }
448 
449  return 0;
450 }
451 
452 /*
453  * call-seq:
454  * ObjectSpace.count_tdata_objects([result_hash]) -> hash
455  *
456  * Counts objects for each +T_DATA+ type.
457  *
458  * This method is only for MRI developers interested in performance and memory
459  * usage of Ruby programs.
460  *
461  * It returns a hash as:
462  *
463  * {RubyVM::InstructionSequence=>504, :parser=>5, :barrier=>6,
464  * :mutex=>6, Proc=>60, RubyVM::Env=>57, Mutex=>1, Encoding=>99,
465  * ThreadGroup=>1, Binding=>1, Thread=>1, RubyVM=>1, :iseq=>1,
466  * Random=>1, ARGF.class=>1, Data=>1, :autoload=>3, Time=>2}
467  * # T_DATA objects existing at startup on r32276.
468  *
469  * If the optional argument, result_hash, is given, it is overwritten and
470  * returned. This is intended to avoid probe effect.
471  *
472  * The contents of the returned hash is implementation specific and may change
473  * in the future.
474  *
475  * In this version, keys are Class object or Symbol object.
476  *
477  * If object is kind of normal (accessible) object, the key is Class object.
478  * If object is not a kind of normal (internal) object, the key is symbol
479  * name, registered by rb_data_type_struct.
480  *
481  * This method is only expected to work with C Ruby.
482  */
483 
484 static VALUE
486 {
487  VALUE hash;
488 
489  if (rb_scan_args(argc, argv, "01", &hash) == 1) {
490  if (!RB_TYPE_P(hash, T_HASH))
491  rb_raise(rb_eTypeError, "non-hash given");
492  }
493 
494  if (hash == Qnil) {
495  hash = rb_hash_new();
496  }
497  else if (!RHASH_EMPTY_P(hash)) {
498  st_foreach(RHASH_TBL(hash), set_zero_i, hash);
499  }
500 
501  rb_objspace_each_objects(cto_i, (void *)hash);
502 
503  return hash;
504 }
505 
506 static void
507 iow_mark(void *ptr)
508 {
509  rb_gc_mark((VALUE)ptr);
510 }
511 
512 static size_t
513 iow_size(const void *ptr)
514 {
515  VALUE obj = (VALUE)ptr;
516  return rb_obj_memsize_of(obj);
517 }
518 
520  "ObjectSpace::InternalObjectWrapper",
521  {iow_mark, 0, iow_size,},
523 };
524 
526 
527 static VALUE
529 {
530  return rb_data_typed_object_alloc(rb_mInternalObjectWrapper, (void *)obj, &iow_data_type);
531 }
532 
533 /* Returns the type of the internal object. */
534 static VALUE
536 {
537  VALUE obj = (VALUE)DATA_PTR(self);
538  return type2sym(BUILTIN_TYPE(obj));
539 }
540 
541 /* See Object#inspect. */
542 static VALUE
544 {
545  VALUE obj = (VALUE)DATA_PTR(self);
547 
548  return rb_sprintf("#<InternalObject:%p %s>", (void *)obj, rb_id2name(SYM2ID(type)));
549 }
550 
551 /* Returns the Object#object_id of the internal object. */
552 static VALUE
554 {
555  VALUE obj = (VALUE)DATA_PTR(self);
556  return rb_obj_id(obj);
557 }
558 
559 struct rof_data {
562 };
563 
564 static void
566 {
567  struct rof_data *data = (struct rof_data *)data_ptr;
568  VALUE key = obj;
569  VALUE val = obj;
570 
573  val = iow_newobj(obj);
574  rb_ary_push(data->internals, val);
575  }
576  st_insert(data->refs, key, val);
577  }
578 }
579 
580 static int
582 {
583  VALUE ary = (VALUE)data;
584  rb_ary_push(ary, (VALUE)value);
585  return ST_CONTINUE;
586 }
587 
588 /*
589  * call-seq:
590  * ObjectSpace.reachable_objects_from(obj) -> array or nil
591  *
592  * [MRI specific feature] Return all reachable objects from `obj'.
593  *
594  * This method returns all reachable objects from `obj'.
595  *
596  * If `obj' has two or more references to the same object `x', then returned
597  * array only includes one `x' object.
598  *
599  * If `obj' is a non-markable (non-heap management) object such as true,
600  * false, nil, symbols and Fixnums (and Flonum) then it simply returns nil.
601  *
602  * If `obj' has references to an internal object, then it returns instances of
603  * ObjectSpace::InternalObjectWrapper class. This object contains a reference
604  * to an internal object and you can check the type of internal object with
605  * `type' method.
606  *
607  * If `obj' is instance of ObjectSpace::InternalObjectWrapper class, then this
608  * method returns all reachable object from an internal object, which is
609  * pointed by `obj'.
610  *
611  * With this method, you can find memory leaks.
612  *
613  * This method is only expected to work except with C Ruby.
614  *
615  * Example:
616  * ObjectSpace.reachable_objects_from(['a', 'b', 'c'])
617  * #=> [Array, 'a', 'b', 'c']
618  *
619  * ObjectSpace.reachable_objects_from(['a', 'a', 'a'])
620  * #=> [Array, 'a', 'a', 'a'] # all 'a' strings have different object id
621  *
622  * ObjectSpace.reachable_objects_from([v = 'a', v, v])
623  * #=> [Array, 'a']
624  *
625  * ObjectSpace.reachable_objects_from(1)
626  * #=> nil # 1 is not markable (heap managed) object
627  *
628  */
629 
630 static VALUE
632 {
634  VALUE ret = rb_ary_new();
635  struct rof_data data;
636 
637  if (rb_typeddata_is_kind_of(obj, &iow_data_type)) {
638  obj = (VALUE)DATA_PTR(obj);
639  }
640 
641  data.refs = st_init_numtable();
642  data.internals = rb_ary_new();
643 
645 
647  return ret;
648  }
649  else {
650  return Qnil;
651  }
652 }
653 
654 struct rofr_data {
656  const char *last_category;
659 };
660 
661 static void
662 reachable_object_from_root_i(const char *category, VALUE obj, void *ptr)
663 {
664  struct rofr_data *data = (struct rofr_data *)ptr;
665  VALUE category_str;
666  VALUE category_objects;
667 
668  if (category == data->last_category) {
669  category_str = data->last_category_str;
670  category_objects = data->last_category_objects;
671  }
672  else {
673  data->last_category = category;
674  category_str = data->last_category_str = rb_str_new2(category);
675  category_objects = data->last_category_objects = rb_hash_new();
676  rb_funcall(category_objects, rb_intern("compare_by_identity"), 0);
677  if (!NIL_P(rb_hash_lookup(data->categories, category_str))) {
678  rb_bug("reachable_object_from_root_i: category should insert at once");
679  }
680  rb_hash_aset(data->categories, category_str, category_objects);
681  }
682 
684  obj != data->categories &&
685  obj != data->last_category_objects) {
687  obj = iow_newobj(obj);
688  }
689  rb_hash_aset(category_objects, obj, obj);
690  }
691 }
692 
693 static int
695 {
696  VALUE ary = rb_ary_new();
697  st_foreach(rb_hash_tbl(category_objects), collect_values, ary);
698  rb_hash_aset(categories, category, ary);
699  return ST_CONTINUE;
700 }
701 
702 /*
703  * call-seq:
704  * ObjectSpace.reachable_objects_from_root -> hash
705  *
706  * [MRI specific feature] Return all reachable objects from root.
707  */
708 static VALUE
710 {
711  struct rofr_data data;
712  VALUE hash = data.categories = rb_hash_new();
713  data.last_category = 0;
714 
715  rb_funcall(hash, rb_intern("compare_by_identity"), 0);
718 
719  return hash;
720 }
721 
722 void Init_object_tracing(VALUE rb_mObjSpace);
723 void Init_objspace_dump(VALUE rb_mObjSpace);
724 
725 /*
726  * Document-module: ObjectSpace
727  *
728  * The objspace library extends the ObjectSpace module and adds several
729  * methods to get internal statistic information about
730  * object/memory management.
731  *
732  * You need to <code>require 'objspace'</code> to use this extension module.
733  *
734  * Generally, you *SHOULD NOT* use this library if you do not know
735  * about the MRI implementation. Mainly, this library is for (memory)
736  * profiler developers and MRI developers who need to know about MRI
737  * memory usage.
738  */
739 
740 void
742 {
743  VALUE rb_mObjSpace;
744 #if 0
745  rb_mObjSpace = rb_define_module("ObjectSpace"); /* let rdoc know */
746 #endif
747  rb_mObjSpace = rb_const_get(rb_cObject, rb_intern("ObjectSpace"));
748 
749  rb_define_module_function(rb_mObjSpace, "memsize_of", memsize_of_m, 1);
750  rb_define_module_function(rb_mObjSpace, "memsize_of_all", memsize_of_all_m, -1);
751 
752  rb_define_module_function(rb_mObjSpace, "count_objects_size", count_objects_size, -1);
753  rb_define_module_function(rb_mObjSpace, "count_nodes", count_nodes, -1);
754  rb_define_module_function(rb_mObjSpace, "count_tdata_objects", count_tdata_objects, -1);
755 
756  rb_define_module_function(rb_mObjSpace, "reachable_objects_from", reachable_objects_from, 1);
757  rb_define_module_function(rb_mObjSpace, "reachable_objects_from_root", reachable_objects_from_root, 0);
758 
759  /*
760  * This class is used as a return value from
761  * ObjectSpace::reachable_objects_from.
762  *
763  * When ObjectSpace::reachable_objects_from returns an object with
764  * references to an internal object, an instance of this class is returned.
765  *
766  * You can use the #type method to check the type of the internal object.
767  */
768  rb_mInternalObjectWrapper = rb_define_class_under(rb_mObjSpace, "InternalObjectWrapper", rb_cObject);
772 
773  Init_object_tracing(rb_mObjSpace);
774  Init_objspace_dump(rb_mObjSpace);
775 }
VALUE data
Definition: tcltklib.c:3360
#define RB_TYPE_P(obj, type)
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: ripper.y:20
#define nd_type(n)
#define NODE_DREGX_ONCE
#define NODE_IF
#define NODE_RESCUE
static VALUE count_objects_size(int argc, VALUE *argv, VALUE os)
Definition: objspace.c:200
#define NODE_RETRY
#define NODE_DEFN
static const rb_data_type_t iow_data_type
Definition: objspace.c:519
#define NODE_FALSE
#define NODE_OR
#define NODE_LAMBDA
void rb_bug(const char *fmt,...)
Definition: error.c:327
#define T_STRUCT
#define rb_hash_lookup
Definition: tcltklib.c:269
memo u1 value
Definition: enum.c:587
static VALUE rb_mInternalObjectWrapper
Definition: objspace.c:525
#define T_MATCH
#define NODE_DSYM
#define FL_TEST(x, f)
#define NODE_DEFS
void Init_objspace(void)
Definition: objspace.c:741
#define NODE_HASH
#define NODE_DOT3
st_table * st_init_numtable(void)
Definition: st.c:272
#define T_ICLASS
const char * last_category
Definition: objspace.c:656
rb_funcall(memo->yielder, id_lshift, 1, rb_assoc_new(memo->prev_value, memo->prev_elts))
#define SIZET2NUM(v)
#define NODE_VCALL
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:1880
#define NODE_NTH_REF
#define NODE_TRUE
VALUE last_category_str
Definition: objspace.c:657
#define T_NODE
#define NODE_ITER
#define NODE_ARGS
#define NODE_MATCH3
int ret
Definition: tcltklib.c:285
#define NODE_UNDEF
#define NODE_ENSURE
VALUE rb_eTypeError
Definition: error.c:548
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:900
#define NODE_PRELUDE
#define RHASH_TBL(h)
NIL_P(eventloop_thread)
Definition: tcltklib.c:4056
#define T_ARRAY
void rb_objspace_reachable_objects_from_root(void(func)(const char *category, VALUE, void *), void *passing_data)
Definition: gc.c:5810
#define NODE_SUPER
#define NODE_EVSTR
static int cto_i(void *vstart, void *vend, size_t stride, void *data)
Definition: objspace.c:421
#define NODE_RESBODY
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:657
#define NODE_DXSTR
#define NODE_CASE
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1857
#define T_HASH
static VALUE memsize_of_all_m(int argc, VALUE *argv, VALUE self)
Definition: objspace.c:104
VALUE rb_obj_id(VALUE)
Definition: gc.c:2376
#define T_FILE
static void reachable_object_from_i(VALUE obj, void *data_ptr)
Definition: objspace.c:565
#define NODE_STR
#define T_NIL
void rb_objspace_each_objects(each_obj_callback *callback, void *data)
Definition: gc.c:1761
#define NODE_REDO
#define NODE_NEXT
int rb_objspace_markable_object_p(VALUE obj)
Definition: gc.c:2281
#define rb_str_new2
#define NODE_XSTR
#define NODE_BLOCK_PASS
size_t rb_obj_memsize_of(VALUE)
Definition: gc.c:2551
ruby_value_type
Definition: ripper.y:442
#define NODE_MATCH2
#define ID2SYM(x)
#define NODE_FOR
#define T_FLOAT
#define T_OBJECT
#define NODE_UNTIL
#define NODE_ARGS_AUX
#define NODE_GASGN
VALUE internals
Definition: objspace.c:561
void rb_hash_foreach(VALUE, int(*)(ANYARGS), VALUE)
Definition: hash.c:273
i
Definition: enum.c:446
VALUE ary
Definition: enum.c:674
#define NODE_POSTEXE
#define NODE_OP_CDECL
Definition: ripper.y:240
VALUE klass
Definition: objspace.c:44
#define T_COMPLEX
#define NODE_CLASS
#define NODE_IFUNC
#define NODE_WHILE
VALUE hash
Definition: tkutil.c:267
static VALUE iow_type(VALUE self)
Definition: objspace.c:535
static size_t iow_size(const void *ptr)
Definition: objspace.c:513
#define NODE_LVAR
#define CASE_TYPE(t)
#define NODE_LASGN
RUBY_SYMBOL_EXPORT_BEGIN const char * rb_objspace_data_type_name(VALUE obj)
Definition: gc.c:1394
#define NODE_OP_ASGN_AND
#define NODE_WHEN
#define Qnil
Definition: enum.c:67
#define val
Definition: tcltklib.c:1935
#define NODE_YIELD
#define NODE_FLIP2
#define NODE_BLOCK
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
Definition: error.c:510
#define NODE_DASGN_CURR
VALUE rb_ary_new(void)
Definition: array.c:499
#define NODE_AND
#define T_RATIONAL
void rb_gc_mark(VALUE)
Definition: gc.c:3607
VALUE categories
Definition: objspace.c:655
static VALUE reachable_objects_from(VALUE self, VALUE obj)
Definition: objspace.c:631
static VALUE VALUE obj
Definition: tcltklib.c:3150
#define FIX2INT(x)
#define INT2FIX(i)
#define T_STRING
void Init_object_tracing(VALUE rb_mObjSpace)
#define NODE_ARGSCAT
#define NODE_COLON2
#define NODE_ZSUPER
#define NODE_BMETHOD
#define NODE_MODULE
static int VALUE key
Definition: tkutil.c:265
st_table * refs
Definition: objspace.c:560
static int total_i(void *vstart, void *vend, size_t stride, void *ptr)
Definition: objspace.c:48
VALUE arg
Definition: enum.c:2427
static VALUE memsize_of_m(VALUE self, VALUE obj)
Definition: objspace.c:37
static VALUE count_nodes(int argc, VALUE *argv, VALUE os)
Definition: objspace.c:276
VALUE * argv
Definition: tcltklib.c:1969
#define NODE_MEMO
static VALUE iow_inspect(VALUE self)
Definition: objspace.c:543
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1661
int st_foreach(st_table *, int(*)(ANYARGS), st_data_t)
Definition: st.c:1034
static VALUE iow_internal_object_id(VALUE self)
Definition: objspace.c:553
#define NODE_NIL
#define NODE_ATTRASGN
static VALUE reachable_objects_from_root(VALUE self)
Definition: objspace.c:709
int rb_objspace_internal_object_p(VALUE obj)
Definition: gc.c:1810
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1250
#define NODE_COLON3
#define NODE_DEFINED
static VALUE count_tdata_objects(int argc, VALUE *argv, VALUE self)
Definition: objspace.c:485
VALUE v
Definition: enum.c:845
#define RUBY_TYPED_FREE_IMMEDIATELY
#define NODE_MASGN
#define T_REGEXP
register char * s
Definition: os2.c:56
#define NODE_CONST
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1719
#define NODE_VALIAS
#define NODE_GVAR
#define NODE_CDECL
#define NODE_LIT
int type
Definition: tcltklib.c:112
#define T_FIXNUM
int argc
Definition: tcltklib.c:1968
rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1))
static int set_zero_i(st_data_t key, st_data_t val, st_data_t arg)
Definition: objspace.c:117
#define NODE_ERRINFO
#define NODE_ARGSPUSH
#define NODE_BACK_REF
#define NODE_MATCH
size_t total
Definition: objspace.c:43
#define NODE_ALIAS
return ptr
Definition: tcltklib.c:789
#define NODE_CVDECL
#define NODE_DASGN
static int collect_values(st_data_t key, st_data_t value, st_data_t data)
Definition: objspace.c:581
#define T_BIGNUM
#define T_TRUE
#define NODE_TO_ARY
#define T_SYMBOL
static int collect_values_of_values(VALUE category, VALUE category_objects, VALUE categories)
Definition: objspace.c:694
#define NODE_FCALL
#define FL_SINGLETON
#define NODE_FLIP3
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:646
static int cos_i(void *vstart, void *vend, size_t stride, void *data)
Definition: objspace.c:126
static void reachable_object_from_root_i(const char *category, VALUE obj, void *ptr)
Definition: objspace.c:662
#define T_CLASS
#define NODE_DVAR
#define NODE_CREF
void rb_objspace_reachable_objects_from(VALUE obj, void(func)(VALUE, void *), void *data)
Definition: gc.c:5782
VALUE name
Definition: enum.c:572
#define NODE_ZARRAY
DATA_PTR(self)
#define NODE_CVAR
#define NODE_BREAK
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1561
#define RBASIC(obj)
#define NODE_LAST
#define NODE_OP_ASGN2
#define NODE_DSTR
static VALUE iow_newobj(VALUE obj)
Definition: objspace.c:528
static VALUE type2sym(enum ruby_value_type i)
Definition: objspace.c:140
#define NODE_ALLOCA
#define NODE_SCLASS
#define NODE_BEGIN
#define NODE_POSTARG
int st_insert(st_table *, st_data_t, st_data_t)
#define NODE_OP_ASGN1
#define NODE_CVASGN
data n
Definition: enum.c:860
#define T_MODULE
static int cn_i(void *vstart, void *vend, size_t stride, void *n)
Definition: objspace.c:237
VALUE rb_hash_new(void)
Definition: hash.c:307
#define T_UNDEF
const char * rb_id2name(ID id)
Definition: ripper.c:17271
#define NODE_CALL
#define BUILTIN_TYPE(x)
#define NODE_OPT_N
VALUE rb_hash_aref(VALUE, VALUE)
Definition: hash.c:706
unsigned long VALUE
Definition: ripper.y:88
#define NODE_IVAR
VALUE rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *)
Definition: gc.c:1376
#define NODE_DOT2
#define NODE_KW_ARG
#define NODE_DREGX
#define NODE_OP_ASGN_OR
#define NODE_IASGN
#define NODE_RETURN
#define RHASH_EMPTY_P(h)
VALUE rb_define_module(const char *name)
Definition: class.c:727
#define NODE_ARRAY
#define NODE_SPLAT
#define rb_intern(str)
#define NULL
Definition: _sdbm.c:102
#define T_DATA
#define NODE_SCOPE
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1479
void Init_objspace_dump(VALUE rb_mObjSpace)
#define NODE_IASGN2
#define NODE_SELF
#define SYM2ID(x)
#define NODE_BLOCK_ARG
VALUE last_category_objects
Definition: objspace.c:658
#define T_NONE
#define T_MASK
Definition: md5.c:131
#define T_FALSE
#define NODE_VALUES
#define COUNT_NODE(n)
static void iow_mark(void *ptr)
Definition: objspace.c:507
struct st_table * rb_hash_tbl(VALUE)
Definition: hash.c:353
#define T_ZOMBIE
#define NODE_OPT_ARG