Ruby  2.0.0p598(2014-11-13revision48408)
objspace.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  objspace.c - ObjectSpace extender for MRI.
4 
5  $Author: nagachika $
6  created at: Wed Jun 17 07:39:17 2009
7 
8  NOTE: This extension library is not expected to exist except 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 /* objspace library extends ObjectSpace module and add several
16  * methods to get internal statistic information about
17  * object/memory management.
18  *
19  * Generally, you *SHOULD NOT*use this library if you do not know
20  * about the MRI implementation. Mainly, this library is for (memory)
21  * profiler developers and MRI developers who need to know how MRI
22  * memory usage.
23  *
24  */
25 
26 #include <ruby/ruby.h>
27 #include <ruby/st.h>
28 #include <ruby/io.h>
29 #include <ruby/re.h>
30 #include "node.h"
31 #include "gc.h"
32 #include "regint.h"
33 #include "internal.h"
34 
35 size_t rb_str_memsize(VALUE);
36 size_t rb_ary_memsize(VALUE);
37 size_t rb_io_memsize(const rb_io_t *);
40 
41 static size_t
43 {
44  size_t size = 0;
45 
46  if (SPECIAL_CONST_P(obj)) {
47  return 0;
48  }
49 
50  if (FL_TEST(obj, FL_EXIVAR)) {
51  size += rb_generic_ivar_memsize(obj);
52  }
53 
54  switch (BUILTIN_TYPE(obj)) {
55  case T_OBJECT:
56  if (!(RBASIC(obj)->flags & ROBJECT_EMBED) &&
57  ROBJECT(obj)->as.heap.ivptr) {
58  size += ROBJECT(obj)->as.heap.numiv * sizeof(VALUE);
59  }
60  break;
61  case T_MODULE:
62  case T_CLASS:
63  if (RCLASS_M_TBL(obj)) {
64  size += st_memsize(RCLASS_M_TBL(obj));
65  }
66  if (RCLASS_IV_TBL(obj)) {
67  size += st_memsize(RCLASS_IV_TBL(obj));
68  }
69  if (RCLASS_IV_INDEX_TBL(obj)) {
70  size += st_memsize(RCLASS_IV_INDEX_TBL(obj));
71  }
72  if (RCLASS(obj)->ptr->iv_tbl) {
73  size += st_memsize(RCLASS(obj)->ptr->iv_tbl);
74  }
75  if (RCLASS(obj)->ptr->const_tbl) {
76  size += st_memsize(RCLASS(obj)->ptr->const_tbl);
77  }
78  size += sizeof(rb_classext_t);
79  break;
80  case T_STRING:
81  size += rb_str_memsize(obj);
82  break;
83  case T_ARRAY:
84  size += rb_ary_memsize(obj);
85  break;
86  case T_HASH:
87  if (RHASH(obj)->ntbl) {
88  size += st_memsize(RHASH(obj)->ntbl);
89  }
90  break;
91  case T_REGEXP:
92  if (RREGEXP(obj)->ptr) {
93  size += onig_memsize(RREGEXP(obj)->ptr);
94  }
95  break;
96  case T_DATA:
97  size += rb_objspace_data_type_memsize(obj);
98  break;
99  case T_MATCH:
100  if (RMATCH(obj)->rmatch) {
101  struct rmatch *rm = RMATCH(obj)->rmatch;
102  size += onig_region_memsize(&rm->regs);
103  size += sizeof(struct rmatch_offset) * rm->char_offset_num_allocated;
104  size += sizeof(struct rmatch);
105  }
106  break;
107  case T_FILE:
108  if (RFILE(obj)->fptr) {
109  size += rb_io_memsize(RFILE(obj)->fptr);
110  }
111  break;
112  case T_RATIONAL:
113  case T_COMPLEX:
114  break;
115  case T_ICLASS:
116  /* iClass shares table with the module */
117  break;
118 
119  case T_FLOAT:
120  break;
121 
122  case T_BIGNUM:
123  if (!(RBASIC(obj)->flags & RBIGNUM_EMBED_FLAG) && RBIGNUM_DIGITS(obj)) {
124  size += RBIGNUM_LEN(obj) * sizeof(BDIGIT);
125  }
126  break;
127  case T_NODE:
128  switch (nd_type(obj)) {
129  case NODE_SCOPE:
130  if (RNODE(obj)->u1.tbl) {
131  /* TODO: xfree(RANY(obj)->as.node.u1.tbl); */
132  }
133  break;
134  case NODE_ALLOCA:
135  /* TODO: xfree(RANY(obj)->as.node.u1.node); */
136  ;
137  }
138  break; /* no need to free iv_tbl */
139 
140  case T_STRUCT:
141  if ((RBASIC(obj)->flags & RSTRUCT_EMBED_LEN_MASK) == 0 &&
142  RSTRUCT(obj)->as.heap.ptr) {
143  size += sizeof(VALUE) * RSTRUCT_LEN(obj);
144  }
145  break;
146 
147  case T_ZOMBIE:
148  break;
149 
150  default:
151  rb_bug("objspace/memsize_of(): unknown data type 0x%x(%p)",
152  BUILTIN_TYPE(obj), (void*)obj);
153  }
154 
155  return size;
156 }
157 
158 /*
159  * call-seq:
160  * ObjectSpace.memsize_of(obj) -> Integer
161  *
162  * Return consuming memory size of obj.
163  *
164  * Note that the return size is incomplete. You need to deal with
165  * this information as only a *HINT*. Especially, the size of
166  * T_DATA may not be correct.
167  *
168  * This method is not expected to work except C Ruby.
169  */
170 
171 static VALUE
173 {
174  return SIZET2NUM(memsize_of(obj));
175 }
176 
177 struct total_data {
178  size_t total;
180 };
181 
182 static int
183 total_i(void *vstart, void *vend, size_t stride, void *ptr)
184 {
185  VALUE v;
186  struct total_data *data = (struct total_data *)ptr;
187 
188  for (v = (VALUE)vstart; v != (VALUE)vend; v += stride) {
189  if (RBASIC(v)->flags) {
190  switch (BUILTIN_TYPE(v)) {
191  case T_NONE:
192  case T_ICLASS:
193  case T_NODE:
194  case T_ZOMBIE:
195  continue;
196  case T_CLASS:
197  if (FL_TEST(v, FL_SINGLETON))
198  continue;
199  default:
200  if (data->klass == 0 || rb_obj_is_kind_of(v, data->klass)) {
201  data->total += memsize_of(v);
202  }
203  }
204  }
205  }
206 
207  return 0;
208 }
209 
210 /*
211  * call-seq:
212  * ObjectSpace.memsize_of_all([klass]) -> Integer
213  *
214  * Return consuming memory size of all living objects.
215  * If klass (should be Class object) is given, return the total
216  * memory size of instances of the given class.
217  *
218  * Note that the returned size is incomplete. You need to deal with
219  * this information as only a *HINT*. Especially, the size of
220  * T_DATA may not be correct.
221  *
222  * Note that this method does *NOT* return total malloc'ed memory size.
223  *
224  * This method can be defined by the following Ruby code:
225  *
226  * def memsize_of_all klass = false
227  * total = 0
228  * ObjectSpace.each_object{|e|
229  * total += ObjectSpace.memsize_of(e) if klass == false || e.kind_of?(klass)
230  * }
231  * total
232  * end
233  *
234  * This method is not expected to work except C Ruby.
235  */
236 
237 static VALUE
239 {
240  struct total_data data = {0, 0};
241 
242  if (argc > 0) {
243  rb_scan_args(argc, argv, "01", &data.klass);
244  }
245 
247  return SIZET2NUM(data.total);
248 }
249 
250 static int
252 {
253  VALUE k = (VALUE)key;
254  VALUE hash = (VALUE)arg;
255  rb_hash_aset(hash, k, INT2FIX(0));
256  return ST_CONTINUE;
257 }
258 
259 static int
260 cos_i(void *vstart, void *vend, size_t stride, void *data)
261 {
262  size_t *counts = (size_t *)data;
263  VALUE v = (VALUE)vstart;
264 
265  for (;v != (VALUE)vend; v += stride) {
266  if (RBASIC(v)->flags) {
267  counts[BUILTIN_TYPE(v)] += memsize_of(v);
268  }
269  }
270  return 0;
271 }
272 
273 static VALUE
275 {
276  VALUE type;
277  switch (i) {
278 #define CASE_TYPE(t) case t: type = ID2SYM(rb_intern(#t)); break;
279  CASE_TYPE(T_NONE);
287  CASE_TYPE(T_HASH);
290  CASE_TYPE(T_FILE);
291  CASE_TYPE(T_DATA);
295  CASE_TYPE(T_NIL);
296  CASE_TYPE(T_TRUE);
301  CASE_TYPE(T_NODE);
304 #undef CASE_TYPE
305  default: rb_bug("type2sym: unknown type (%d)", i);
306  }
307  return type;
308 }
309 
310 /*
311  * call-seq:
312  * ObjectSpace.count_objects_size([result_hash]) -> hash
313  *
314  * Counts objects size (in bytes) for each type.
315  *
316  * Note that this information is incomplete. You need to deal with
317  * this information as only a *HINT*. Especially, total size of
318  * T_DATA may not right size.
319  *
320  * It returns a hash as:
321  * {:TOTAL=>1461154, :T_CLASS=>158280, :T_MODULE=>20672, :T_STRING=>527249, ...}
322  *
323  * If the optional argument, result_hash, is given,
324  * it is overwritten and returned.
325  * This is intended to avoid probe effect.
326  *
327  * The contents of the returned hash is implementation defined.
328  * It may be changed in future.
329  *
330  * This method is not expected to work except C Ruby.
331  */
332 
333 static VALUE
335 {
336  size_t counts[T_MASK+1];
337  size_t total = 0;
338  enum ruby_value_type i;
339  VALUE hash;
340 
341  if (rb_scan_args(argc, argv, "01", &hash) == 1) {
342  if (!RB_TYPE_P(hash, T_HASH))
343  rb_raise(rb_eTypeError, "non-hash given");
344  }
345 
346  for (i = 0; i <= T_MASK; i++) {
347  counts[i] = 0;
348  }
349 
350  rb_objspace_each_objects(cos_i, &counts[0]);
351 
352  if (hash == Qnil) {
353  hash = rb_hash_new();
354  }
355  else if (!RHASH_EMPTY_P(hash)) {
356  st_foreach(RHASH_TBL(hash), set_zero_i, hash);
357  }
358 
359  for (i = 0; i <= T_MASK; i++) {
360  if (counts[i]) {
361  VALUE type = type2sym(i);
362  total += counts[i];
363  rb_hash_aset(hash, type, SIZET2NUM(counts[i]));
364  }
365  }
366  rb_hash_aset(hash, ID2SYM(rb_intern("TOTAL")), SIZET2NUM(total));
367  return hash;
368 }
369 
370 static int
371 cn_i(void *vstart, void *vend, size_t stride, void *n)
372 {
373  size_t *nodes = (size_t *)n;
374  VALUE v = (VALUE)vstart;
375 
376  for (; v != (VALUE)vend; v += stride) {
377  if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_NODE) {
378  size_t s = nd_type((NODE *)v);
379  nodes[s]++;
380  }
381  }
382 
383  return 0;
384 }
385 
386 /*
387  * call-seq:
388  * ObjectSpace.count_nodes([result_hash]) -> hash
389  *
390  * Counts nodes for each node type.
391  *
392  * This method is not for ordinary Ruby programmers, but for MRI developers
393  * who have interest in MRI performance and memory usage.
394  *
395  * It returns a hash as:
396  * {:NODE_METHOD=>2027, :NODE_FBODY=>1927, :NODE_CFUNC=>1798, ...}
397  *
398  * If the optional argument, result_hash, is given,
399  * it is overwritten and returned.
400  * This is intended to avoid probe effect.
401  *
402  * The contents of the returned hash is implementation defined.
403  * It may be changed in future.
404  *
405  * This method is not expected to work except C Ruby.
406  */
407 
408 static VALUE
410 {
411  size_t nodes[NODE_LAST+1];
412  size_t i;
413  VALUE hash;
414 
415  if (rb_scan_args(argc, argv, "01", &hash) == 1) {
416  if (!RB_TYPE_P(hash, T_HASH))
417  rb_raise(rb_eTypeError, "non-hash given");
418  }
419 
420  for (i = 0; i <= NODE_LAST; i++) {
421  nodes[i] = 0;
422  }
423 
424  rb_objspace_each_objects(cn_i, &nodes[0]);
425 
426  if (hash == Qnil) {
427  hash = rb_hash_new();
428  }
429  else if (!RHASH_EMPTY_P(hash)) {
430  st_foreach(RHASH_TBL(hash), set_zero_i, hash);
431  }
432 
433  for (i=0; i<NODE_LAST; i++) {
434  if (nodes[i] != 0) {
435  VALUE node;
436  switch (i) {
437 #define COUNT_NODE(n) case n: node = ID2SYM(rb_intern(#n)); break;
544 #undef COUNT_NODE
545  default: node = INT2FIX(i);
546  }
547  rb_hash_aset(hash, node, SIZET2NUM(nodes[i]));
548  }
549  }
550  return hash;
551 }
552 
553 static int
554 cto_i(void *vstart, void *vend, size_t stride, void *data)
555 {
556  VALUE hash = (VALUE)data;
557  VALUE v = (VALUE)vstart;
558 
559  for (; v != (VALUE)vend; v += stride) {
560  if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_DATA) {
561  VALUE counter;
562  VALUE key = RBASIC(v)->klass;
563 
564  if (key == 0) {
565  const char *name = rb_objspace_data_type_name(v);
566  if (name == 0) name = "unknown";
567  key = ID2SYM(rb_intern(name));
568  }
569 
570  counter = rb_hash_aref(hash, key);
571  if (NIL_P(counter)) {
572  counter = INT2FIX(1);
573  }
574  else {
575  counter = INT2FIX(FIX2INT(counter) + 1);
576  }
577 
578  rb_hash_aset(hash, key, counter);
579  }
580  }
581 
582  return 0;
583 }
584 
585 /*
586  * call-seq:
587  * ObjectSpace.count_tdata_objects([result_hash]) -> hash
588  *
589  * Counts objects for each T_DATA type.
590  *
591  * This method is not for ordinary Ruby programmers, but for MRI developers
592  * who interest on MRI performance.
593  *
594  * It returns a hash as:
595  * {RubyVM::InstructionSequence=>504, :parser=>5, :barrier=>6,
596  * :mutex=>6, Proc=>60, RubyVM::Env=>57, Mutex=>1, Encoding=>99,
597  * ThreadGroup=>1, Binding=>1, Thread=>1, RubyVM=>1, :iseq=>1,
598  * Random=>1, ARGF.class=>1, Data=>1, :autoload=>3, Time=>2}
599  * # T_DATA objects existing at startup on r32276.
600  *
601  * If the optional argument, result_hash, is given,
602  * it is overwritten and returned.
603  * This is intended to avoid probe effect.
604  *
605  * The contents of the returned hash is implementation defined.
606  * It may be changed in future.
607  *
608  * In this version, keys are Class object or Symbol object.
609  * If object is kind of normal (accessible) object, the key is Class object.
610  * If object is not a kind of normal (internal) object, the key is symbol
611  * name, registered by rb_data_type_struct.
612  *
613  * This method is not expected to work except C Ruby.
614  *
615  */
616 
617 static VALUE
619 {
620  VALUE hash;
621 
622  if (rb_scan_args(argc, argv, "01", &hash) == 1) {
623  if (!RB_TYPE_P(hash, T_HASH))
624  rb_raise(rb_eTypeError, "non-hash given");
625  }
626 
627  if (hash == Qnil) {
628  hash = rb_hash_new();
629  }
630  else if (!RHASH_EMPTY_P(hash)) {
631  st_foreach(RHASH_TBL(hash), set_zero_i, hash);
632  }
633 
634  rb_objspace_each_objects(cto_i, (void *)hash);
635 
636  return hash;
637 }
638 
639 static void
640 iow_mark(void *ptr)
641 {
642  rb_gc_mark((VALUE)ptr);
643 }
644 
645 static size_t
646 iow_size(const void *ptr)
647 {
648  VALUE obj = (VALUE)ptr;
649  return memsize_of(obj);
650 }
651 
653  "ObjectSpace::InternalObjectWrapper",
654  {iow_mark, 0, iow_size,},
655 };
656 
658 
659 static VALUE
661 {
662  return rb_data_typed_object_alloc(rb_mInternalObjectWrapper, (void *)obj, &iow_data_type);
663 }
664 
665 static VALUE
667 {
668  VALUE obj = (VALUE)DATA_PTR(self);
669  return type2sym(BUILTIN_TYPE(obj));
670 }
671 
672 static VALUE
674 {
675  VALUE obj = (VALUE)DATA_PTR(self);
677 
678  return rb_sprintf("#<InternalObject:%p %s>", (void *)obj, rb_id2name(SYM2ID(type)));
679 }
680 
681 static VALUE
683 {
684  VALUE obj = (VALUE)DATA_PTR(self);
685  return rb_obj_id(obj);
686 }
687 
688 struct rof_data {
691 };
692 
693 static void
695 {
696  struct rof_data *data = (struct rof_data *)data_ptr;
697  VALUE key = obj;
698  VALUE val = obj;
699 
702  val = iow_newobj(obj);
703  rb_ary_push(data->internals, val);
704  }
705  st_insert(data->refs, key, val);
706  }
707 }
708 
709 static int
711 {
712  VALUE ary = (VALUE)data;
713  rb_ary_push(ary, (VALUE)value);
714  return ST_CONTINUE;
715 }
716 
717 /*
718  * call-seq:
719  * ObjectSpace.reachable_objects_from(obj) -> array or nil
720  *
721  * [MRI specific feature] Return all reachable objects from `obj'.
722  *
723  * This method returns all reachable objects from `obj'.
724  * If `obj' has references two or more references to same object `x',
725  * them returned array only include one `x' object.
726  * If `obj' is non-markable (non-heap management) object such as
727  * true, false, nil, symbols and Fixnums (and Flonum) them it simply
728  * returns nil.
729  *
730  * If `obj' has references to internal object, then it returns
731  * instances of `ObjectSpace::InternalObjectWrapper' class.
732  * This object contains a reference to an internal object and
733  * you can check the type of internal object with `type' method.
734  *
735  * If `obj' is instance of `ObjectSpace::InternalObjectWrapper'
736  * class, then this method returns all reachable object from
737  * an internal object, which is pointed by `obj'.
738  *
739  * With this method, you can find memory leaks.
740  *
741  * This method is not expected to work except C Ruby.
742  *
743  * Example:
744  * ObjectSpace.reachable_objects_from(['a', 'b', 'c'])
745  * #=> [Array, 'a', 'b', 'c']
746  *
747  * ObjectSpace.reachable_objects_from(['a', 'a', 'a'])
748  * #=> [Array, 'a', 'a', 'a'] # all 'a' strings have different object id
749  *
750  * ObjectSpace.reachable_objects_from([v = 'a', v, v])
751  * #=> [Array, 'a']
752  *
753  * ObjectSpace.reachable_objects_from(1)
754  * #=> nil # 1 is not markable (heap managed) object
755  *
756  */
757 
758 static VALUE
760 {
762  VALUE ret = rb_ary_new();
763  struct rof_data data;
764 
765  if (rb_typeddata_is_kind_of(obj, &iow_data_type)) {
766  obj = (VALUE)DATA_PTR(obj);
767  }
768 
769  data.refs = st_init_numtable();
770  data.internals = rb_ary_new();
771 
773 
775  return ret;
776  }
777  else {
778  return Qnil;
779  }
780 }
781 
782 /* objspace library extends ObjectSpace module and add several
783  * methods to get internal statistic information about
784  * object/memory management.
785  *
786  * Generally, you *SHOULD NOT*use this library if you do not know
787  * about the MRI implementation. Mainly, this library is for (memory)
788  * profiler developers and MRI developers who need to know how MRI
789  * memory usage.
790  */
791 
792 void
794 {
795  VALUE rb_mObjSpace = rb_const_get(rb_cObject, rb_intern("ObjectSpace"));
796 
797  rb_define_module_function(rb_mObjSpace, "memsize_of", memsize_of_m, 1);
798  rb_define_module_function(rb_mObjSpace, "memsize_of_all", memsize_of_all_m, -1);
799 
800  rb_define_module_function(rb_mObjSpace, "count_objects_size", count_objects_size, -1);
801  rb_define_module_function(rb_mObjSpace, "count_nodes", count_nodes, -1);
802  rb_define_module_function(rb_mObjSpace, "count_tdata_objects", count_tdata_objects, -1);
803 
804  rb_define_module_function(rb_mObjSpace, "reachable_objects_from", reachable_objects_from, 1);
805 
806  rb_mInternalObjectWrapper = rb_define_class_under(rb_mObjSpace, "InternalObjectWrapper", rb_cObject);
810 }
VALUE data
Definition: tcltklib.c:3367
#define RB_TYPE_P(obj, type)
#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:334
#define NODE_RETRY
#define NODE_DEFN
#define ROBJECT_EMBED
ssize_t n
Definition: bigdecimal.c:5676
static const rb_data_type_t iow_data_type
Definition: objspace.c:652
volatile VALUE ary
Definition: tcltklib.c:9712
#define NODE_FALSE
#define NODE_OR
#define NODE_LAMBDA
#define RSTRUCT_LEN(st)
void rb_bug(const char *fmt,...)
Definition: error.c:295
#define T_STRUCT
static VALUE rb_mInternalObjectWrapper
Definition: objspace.c:657
#define T_MATCH
#define NODE_DSYM
#define FL_TEST(x, f)
#define NODE_DEFS
void Init_objspace(void)
Definition: objspace.c:793
#define NODE_HASH
#define NODE_DOT3
#define FL_EXIVAR
st_table * st_init_numtable(void)
Definition: st.c:272
#define T_ICLASS
#define SIZET2NUM(v)
#define NODE_VCALL
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:1876
size_t onig_memsize(const regex_t *reg)
Definition: regcomp.c:5596
#define NODE_NTH_REF
ssize_t i
Definition: bigdecimal.c:5676
#define NODE_TRUE
Definition: io.h:63
#define T_NODE
#define RSTRUCT_EMBED_LEN_MASK
#define NODE_ITER
#define NODE_ARGS
#define NODE_MATCH3
int ret
Definition: tcltklib.c:280
#define NODE_UNDEF
#define RHASH(obj)
#define NODE_ENSURE
VALUE rb_eTypeError
Definition: error.c:516
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
#define ROBJECT(obj)
#define NODE_PRELUDE
#define RHASH_TBL(h)
NIL_P(eventloop_thread)
Definition: tcltklib.c:4067
#define RFILE(obj)
#define T_ARRAY
#define NODE_SUPER
#define NODE_EVSTR
static int cto_i(void *vstart, void *vend, size_t stride, void *data)
Definition: objspace.c:554
#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:549
#define RSTRUCT(obj)
#define NODE_DXSTR
#define NODE_CASE
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1788
#define T_HASH
struct re_registers regs
Definition: re.h:39
static VALUE memsize_of_all_m(int argc, VALUE *argv, VALUE self)
Definition: objspace.c:238
VALUE rb_obj_id(VALUE)
Definition: gc.c:1690
#define T_FILE
size_t st_memsize(const st_table *)
Definition: st.c:342
static void reachable_object_from_i(VALUE obj, void *data_ptr)
Definition: objspace.c:694
#define NODE_STR
#define T_NIL
void rb_objspace_each_objects(each_obj_callback *callback, void *data)
Definition: gc.c:1128
#define NODE_REDO
#define NODE_NEXT
int rb_objspace_markable_object_p(VALUE obj)
Definition: gc.c:2578
#define NODE_XSTR
#define NODE_BLOCK_PASS
ruby_value_type
Definition: ripper.y:450
int char_offset_num_allocated
Definition: re.h:42
#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:690
const char * rb_objspace_data_type_name(VALUE obj)
Definition: gc.c:749
#define NODE_POSTEXE
#define NODE_OP_CDECL
Definition: ripper.y:240
VALUE klass
Definition: objspace.c:179
#define RBIGNUM_LEN(b)
#define T_COMPLEX
unsigned long st_data_t
Definition: ripper.y:35
#define NODE_CLASS
#define NODE_IFUNC
#define NODE_WHILE
VALUE hash
Definition: tkutil.c:267
static VALUE iow_type(VALUE self)
Definition: objspace.c:666
static size_t iow_size(const void *ptr)
Definition: objspace.c:646
#define NODE_LVAR
#define CASE_TYPE(t)
#define NODE_LASGN
#define NODE_OP_ASGN_AND
#define NODE_WHEN
#define Qnil
Definition: tcltklib.c:1895
#define val
Definition: tcltklib.c:1948
#define RCLASS_IV_TBL(c)
#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:478
#define NODE_DASGN_CURR
VALUE rb_ary_new(void)
Definition: array.c:424
#define NODE_AND
int flags
Definition: tcltklib.c:3022
#define T_RATIONAL
void rb_gc_mark(VALUE)
Definition: gc.c:2600
static VALUE reachable_objects_from(VALUE self, VALUE obj)
Definition: objspace.c:759
static VALUE VALUE obj
Definition: tcltklib.c:3157
#define FIX2INT(x)
#define INT2FIX(i)
#define T_STRING
#define NODE_ARGSCAT
#define NODE_COLON2
size_t onig_region_memsize(const OnigRegion *regs)
Definition: regcomp.c:5611
#define NODE_ZSUPER
#define NODE_BMETHOD
#define NODE_MODULE
static size_t memsize_of(VALUE obj)
Definition: objspace.c:42
static int VALUE key
Definition: tkutil.c:265
st_table * refs
Definition: objspace.c:689
static int total_i(void *vstart, void *vend, size_t stride, void *ptr)
Definition: objspace.c:183
#define RBIGNUM_DIGITS(b)
static VALUE memsize_of_m(VALUE self, VALUE obj)
Definition: objspace.c:172
static VALUE count_nodes(int argc, VALUE *argv, VALUE os)
Definition: objspace.c:409
struct rb_classext_struct rb_classext_t
Definition: ripper.y:735
VALUE * argv
Definition: tcltklib.c:1970
#define NODE_MEMO
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
static VALUE iow_inspect(VALUE self)
Definition: objspace.c:673
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1516
int st_foreach(st_table *, int(*)(ANYARGS), st_data_t)
Definition: st.c:1006
static VALUE iow_internal_object_id(VALUE self)
Definition: objspace.c:682
#define NODE_NIL
#define NODE_ATTRASGN
int rb_objspace_internal_object_p(VALUE obj)
Definition: gc.c:1170
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1275
volatile VALUE value
Definition: tcltklib.c:9441
#define NODE_COLON3
#define NODE_DEFINED
size_t rb_io_memsize(const rb_io_t *)
Definition: io.c:4221
static VALUE count_tdata_objects(int argc, VALUE *argv, VALUE self)
Definition: objspace.c:618
#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:1574
#define NODE_VALIAS
#define NODE_GVAR
#define NODE_CDECL
#define NODE_LIT
int type
Definition: tcltklib.c:111
#define T_FIXNUM
int argc
Definition: tcltklib.c:1969
static int set_zero_i(st_data_t key, st_data_t val, st_data_t arg)
Definition: objspace.c:251
#define NODE_ERRINFO
RUBY_FUNC_EXPORTED size_t rb_ary_memsize(VALUE ary)
Definition: array.c:479
#define BDIGIT
Definition: ripper.y:184
#define NODE_ARGSPUSH
#define NODE_BACK_REF
#define NODE_MATCH
size_t total
Definition: objspace.c:178
#define NODE_ALIAS
return ptr
Definition: tcltklib.c:784
#define NODE_CVDECL
Definition: re.h:38
#define NODE_DASGN
static int collect_values(st_data_t key, st_data_t value, st_data_t data)
Definition: objspace.c:710
#define T_BIGNUM
#define T_TRUE
#define NODE_TO_ARY
arg
Definition: ripper.y:1317
#define T_SYMBOL
int size
Definition: encoding.c:52
#define NODE_FCALL
#define FL_SINGLETON
#define NODE_FLIP3
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:593
static int cos_i(void *vstart, void *vend, size_t stride, void *data)
Definition: objspace.c:260
#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:3338
#define NODE_ZARRAY
DATA_PTR(self)
#define NODE_CVAR
#define NODE_BREAK
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1426
#define RBASIC(obj)
#define NODE_LAST
#define NODE_OP_ASGN2
#define NODE_DSTR
static VALUE iow_newobj(VALUE obj)
Definition: objspace.c:660
static VALUE type2sym(enum ruby_value_type i)
Definition: objspace.c:274
#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
#define T_MODULE
#define RCLASS_IV_INDEX_TBL(c)
static int cn_i(void *vstart, void *vend, size_t stride, void *n)
Definition: objspace.c:371
VALUE rb_hash_new(void)
Definition: hash.c:234
#define T_UNDEF
size_t rb_str_memsize(VALUE)
Definition: string.c:838
const char * rb_id2name(ID id)
Definition: ripper.c:17006
#define NODE_CALL
#define BUILTIN_TYPE(x)
#define NODE_OPT_N
#define RMATCH(obj)
Definition: re.h:53
VALUE rb_hash_aref(VALUE, VALUE)
Definition: hash.c:570
unsigned long VALUE
Definition: ripper.y:104
#define NODE_IVAR
#define RREGEXP(obj)
VALUE rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *)
Definition: gc.c:722
#define NODE_DOT2
#define NODE_KW_ARG
#define NODE_DREGX
#define NODE_OP_ASGN_OR
#define NODE_IASGN
#define NODE_RETURN
#define SPECIAL_CONST_P(x)
#define RHASH_EMPTY_P(h)
#define NODE_ARRAY
#define NODE_SPLAT
#define rb_intern(str)
BDIGIT v
Definition: bigdecimal.c:5677
#define RCLASS_M_TBL(c)
#define T_DATA
const char * name
Definition: nkf.c:208
size_t rb_generic_ivar_memsize(VALUE)
Definition: variable.c:1038
#define RNODE(obj)
#define NODE_SCOPE
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1348
#define NODE_IASGN2
#define NODE_SELF
#define RBIGNUM_EMBED_FLAG
#define SYM2ID(x)
#define NODE_BLOCK_ARG
size_t rb_objspace_data_type_memsize(VALUE obj)
Definition: gc.c:738
#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:640
#define RCLASS(obj)
#define T_ZOMBIE
#define NODE_OPT_ARG