Ruby  2.4.2p198(2017-09-14revision59899)
objspace.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  objspace.c - ObjectSpace extender for MRI.
4 
5  $Author: yui-knk $
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 "internal.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 "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
41 {
42  return SIZET2NUM(rb_obj_memsize_of(obj));
43 }
44 
45 struct total_data {
46  size_t total;
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
106 {
107  struct total_data data = {0, 0};
108 
109  if (argc > 0) {
110  rb_scan_args(argc, argv, "01", &data.klass);
111  }
112 
114  return SIZET2NUM(data.total);
115 }
116 
117 static int
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
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
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);
174  CASE_TYPE(T_HASH);
177  CASE_TYPE(T_FILE);
178  CASE_TYPE(T_DATA);
182  CASE_TYPE(T_NIL);
183  CASE_TYPE(T_TRUE);
189  CASE_TYPE(T_NODE);
192 #undef CASE_TYPE
193  default: rb_bug("type2sym: unknown type (%d)", i);
194  }
195  return type;
196 }
197 
198 /*
199  * call-seq:
200  * ObjectSpace.count_objects_size([result_hash]) -> hash
201  *
202  * Counts objects size (in bytes) for each type.
203  *
204  * Note that this information is incomplete. You need to deal with
205  * this information as only a *HINT*. Especially, total size of
206  * T_DATA may not right size.
207  *
208  * It returns a hash as:
209  * {:TOTAL=>1461154, :T_CLASS=>158280, :T_MODULE=>20672, :T_STRING=>527249, ...}
210  *
211  * If the optional argument, result_hash, is given,
212  * it is overwritten and returned.
213  * This is intended to avoid probe effect.
214  *
215  * The contents of the returned hash is implementation defined.
216  * It may be changed in future.
217  *
218  * This method is only expected to work with C Ruby.
219  */
220 
221 static VALUE
223 {
224  size_t counts[T_MASK+1];
225  size_t total = 0;
226  enum ruby_value_type i;
227  VALUE hash = setup_hash(argc, argv);
228 
229  for (i = 0; i <= T_MASK; i++) {
230  counts[i] = 0;
231  }
232 
233  rb_objspace_each_objects(cos_i, &counts[0]);
234 
235  if (hash == Qnil) {
236  hash = rb_hash_new();
237  }
238  else if (!RHASH_EMPTY_P(hash)) {
239  st_foreach(RHASH_TBL(hash), set_zero_i, hash);
240  }
241 
242  for (i = 0; i <= T_MASK; i++) {
243  if (counts[i]) {
244  VALUE type = type2sym(i);
245  total += counts[i];
246  rb_hash_aset(hash, type, SIZET2NUM(counts[i]));
247  }
248  }
249  rb_hash_aset(hash, ID2SYM(rb_intern("TOTAL")), SIZET2NUM(total));
250  return hash;
251 }
252 
254  size_t mortal;
255  size_t immortal;
256 };
257 
258 static int
259 cs_i(void *vstart, void *vend, size_t stride, void *n)
260 {
261  struct dynamic_symbol_counts *counts = (struct dynamic_symbol_counts *)n;
262  VALUE v = (VALUE)vstart;
263 
264  for (; v != (VALUE)vend; v += stride) {
265  if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_SYMBOL) {
266  ID id = RSYMBOL(v)->id;
267  if ((id & ~ID_SCOPE_MASK) == 0) {
268  counts->mortal++;
269  }
270  else {
271  counts->immortal++;
272  }
273  }
274  }
275 
276  return 0;
277 }
278 
279 size_t rb_sym_immortal_count(void);
280 
281 /*
282  * call-seq:
283  * ObjectSpace.count_symbols([result_hash]) -> hash
284  *
285  * Counts symbols for each Symbol type.
286  *
287  * This method is only for MRI developers interested in performance and memory
288  * usage of Ruby programs.
289  *
290  * If the optional argument, result_hash, is given, it is overwritten and
291  * returned. This is intended to avoid probe effect.
292  *
293  * Note:
294  * The contents of the returned hash is implementation defined.
295  * It may be changed in future.
296  *
297  * This method is only expected to work with C Ruby.
298  *
299  * On this version of MRI, they have 3 types of Symbols (and 1 total counts).
300  *
301  * * mortal_dynamic_symbol: GC target symbols (collected by GC)
302  * * immortal_dynamic_symbol: Immortal symbols promoted from dynamic symbols (do not collected by GC)
303  * * immortal_static_symbol: Immortal symbols (do not collected by GC)
304  * * immortal_symbol: total immortal symbols (immortal_dynamic_symbol+immortal_static_symbol)
305  */
306 
307 static VALUE
309 {
310  struct dynamic_symbol_counts dynamic_counts = {0, 0};
311  VALUE hash = setup_hash(argc, argv);
312 
313  size_t immortal_symbols = rb_sym_immortal_count();
314  rb_objspace_each_objects(cs_i, &dynamic_counts);
315 
316  if (hash == Qnil) {
317  hash = rb_hash_new();
318  }
319  else if (!RHASH_EMPTY_P(hash)) {
320  st_foreach(RHASH_TBL(hash), set_zero_i, hash);
321  }
322 
323  rb_hash_aset(hash, ID2SYM(rb_intern("mortal_dynamic_symbol")), SIZET2NUM(dynamic_counts.mortal));
324  rb_hash_aset(hash, ID2SYM(rb_intern("immortal_dynamic_symbol")), SIZET2NUM(dynamic_counts.immortal));
325  rb_hash_aset(hash, ID2SYM(rb_intern("immortal_static_symbol")), SIZET2NUM(immortal_symbols - dynamic_counts.immortal));
326  rb_hash_aset(hash, ID2SYM(rb_intern("immortal_symbol")), SIZET2NUM(immortal_symbols));
327 
328  return hash;
329 }
330 
331 static int
332 cn_i(void *vstart, void *vend, size_t stride, void *n)
333 {
334  size_t *nodes = (size_t *)n;
335  VALUE v = (VALUE)vstart;
336 
337  for (; v != (VALUE)vend; v += stride) {
338  if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_NODE) {
339  size_t s = nd_type((NODE *)v);
340  nodes[s]++;
341  }
342  }
343 
344  return 0;
345 }
346 
347 /*
348  * call-seq:
349  * ObjectSpace.count_nodes([result_hash]) -> hash
350  *
351  * Counts nodes for each node type.
352  *
353  * This method is only for MRI developers interested in performance and memory
354  * usage of Ruby programs.
355  *
356  * It returns a hash as:
357  *
358  * {:NODE_METHOD=>2027, :NODE_FBODY=>1927, :NODE_CFUNC=>1798, ...}
359  *
360  * If the optional argument, result_hash, is given, it is overwritten and
361  * returned. This is intended to avoid probe effect.
362  *
363  * Note:
364  * The contents of the returned hash is implementation defined.
365  * It may be changed in future.
366  *
367  * This method is only expected to work with C Ruby.
368  */
369 
370 static VALUE
372 {
373  size_t nodes[NODE_LAST+1];
374  size_t i;
375  VALUE hash = setup_hash(argc, argv);
376 
377  for (i = 0; i <= NODE_LAST; i++) {
378  nodes[i] = 0;
379  }
380 
381  rb_objspace_each_objects(cn_i, &nodes[0]);
382 
383  if (hash == Qnil) {
384  hash = rb_hash_new();
385  }
386  else if (!RHASH_EMPTY_P(hash)) {
387  st_foreach(RHASH_TBL(hash), set_zero_i, hash);
388  }
389 
390  for (i=0; i<NODE_LAST; i++) {
391  if (nodes[i] != 0) {
392  VALUE node;
393  switch (i) {
394 #define COUNT_NODE(n) case n: node = ID2SYM(rb_intern(#n)); break;
498 #undef COUNT_NODE
499  default: node = INT2FIX(i);
500  }
501  rb_hash_aset(hash, node, SIZET2NUM(nodes[i]));
502  }
503  }
504  return hash;
505 }
506 
507 static int
508 cto_i(void *vstart, void *vend, size_t stride, void *data)
509 {
510  VALUE hash = (VALUE)data;
511  VALUE v = (VALUE)vstart;
512 
513  for (; v != (VALUE)vend; v += stride) {
514  if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_DATA) {
515  VALUE counter;
516  VALUE key = RBASIC(v)->klass;
517 
518  if (key == 0) {
519  const char *name = rb_objspace_data_type_name(v);
520  if (name == 0) name = "unknown";
521  key = ID2SYM(rb_intern(name));
522  }
523 
524  counter = rb_hash_aref(hash, key);
525  if (NIL_P(counter)) {
526  counter = INT2FIX(1);
527  }
528  else {
529  counter = INT2FIX(FIX2INT(counter) + 1);
530  }
531 
532  rb_hash_aset(hash, key, counter);
533  }
534  }
535 
536  return 0;
537 }
538 
539 /*
540  * call-seq:
541  * ObjectSpace.count_tdata_objects([result_hash]) -> hash
542  *
543  * Counts objects for each +T_DATA+ type.
544  *
545  * This method is only for MRI developers interested in performance and memory
546  * usage of Ruby programs.
547  *
548  * It returns a hash as:
549  *
550  * {RubyVM::InstructionSequence=>504, :parser=>5, :barrier=>6,
551  * :mutex=>6, Proc=>60, RubyVM::Env=>57, Mutex=>1, Encoding=>99,
552  * ThreadGroup=>1, Binding=>1, Thread=>1, RubyVM=>1, :iseq=>1,
553  * Random=>1, ARGF.class=>1, Data=>1, :autoload=>3, Time=>2}
554  * # T_DATA objects existing at startup on r32276.
555  *
556  * If the optional argument, result_hash, is given, it is overwritten and
557  * returned. This is intended to avoid probe effect.
558  *
559  * The contents of the returned hash is implementation specific and may change
560  * in the future.
561  *
562  * In this version, keys are Class object or Symbol object.
563  *
564  * If object is kind of normal (accessible) object, the key is Class object.
565  * If object is not a kind of normal (internal) object, the key is symbol
566  * name, registered by rb_data_type_struct.
567  *
568  * This method is only expected to work with C Ruby.
569  */
570 
571 static VALUE
573 {
574  VALUE hash = setup_hash(argc, argv);
575  rb_objspace_each_objects(cto_i, (void *)hash);
576  return hash;
577 }
578 
580 
581 static int
582 count_imemo_objects_i(void *vstart, void *vend, size_t stride, void *data)
583 {
584  VALUE hash = (VALUE)data;
585  VALUE v = (VALUE)vstart;
586 
587  for (; v != (VALUE)vend; v += stride) {
588  if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_IMEMO) {
589  VALUE counter;
591 
592  counter = rb_hash_aref(hash, key);
593 
594  if (NIL_P(counter)) {
595  counter = INT2FIX(1);
596  }
597  else {
598  counter = INT2FIX(FIX2INT(counter) + 1);
599  }
600 
601  rb_hash_aset(hash, key, counter);
602  }
603  }
604 
605  return 0;
606 }
607 
608 /*
609  * call-seq:
610  * ObjectSpace.count_imemo_objects([result_hash]) -> hash
611  *
612  * Counts objects for each +T_IMEMO+ type.
613  *
614  * This method is only for MRI developers interested in performance and memory
615  * usage of Ruby programs.
616  *
617  * It returns a hash as:
618  *
619  * {:imemo_ifunc=>8,
620  * :imemo_svar=>7,
621  * :imemo_cref=>509,
622  * :imemo_memo=>1,
623  * :imemo_throw_data=>1}
624  *
625  * If the optional argument, result_hash, is given, it is overwritten and
626  * returned. This is intended to avoid probe effect.
627  *
628  * The contents of the returned hash is implementation specific and may change
629  * in the future.
630  *
631  * In this version, keys are symbol objects.
632  *
633  * This method is only expected to work with C Ruby.
634  */
635 
636 static VALUE
638 {
639  VALUE hash = setup_hash(argc, argv);
640 
641  if (imemo_type_ids[0] == 0) {
642  imemo_type_ids[0] = rb_intern("imemo_none");
643  imemo_type_ids[1] = rb_intern("imemo_cref");
644  imemo_type_ids[2] = rb_intern("imemo_svar");
645  imemo_type_ids[3] = rb_intern("imemo_throw_data");
646  imemo_type_ids[4] = rb_intern("imemo_ifunc");
647  imemo_type_ids[5] = rb_intern("imemo_memo");
648  imemo_type_ids[6] = rb_intern("imemo_ment");
649  imemo_type_ids[7] = rb_intern("imemo_iseq");
650  }
651 
653 
654  return hash;
655 }
656 
657 static void
658 iow_mark(void *ptr)
659 {
660  rb_gc_mark((VALUE)ptr);
661 }
662 
663 static size_t
664 iow_size(const void *ptr)
665 {
666  VALUE obj = (VALUE)ptr;
667  return rb_obj_memsize_of(obj);
668 }
669 
671  "ObjectSpace::InternalObjectWrapper",
672  {iow_mark, 0, iow_size,},
674 };
675 
677 
678 static VALUE
680 {
681  return TypedData_Wrap_Struct(rb_mInternalObjectWrapper, &iow_data_type, (void *)obj);
682 }
683 
684 /* Returns the type of the internal object. */
685 static VALUE
687 {
688  VALUE obj = (VALUE)DATA_PTR(self);
689  return type2sym(BUILTIN_TYPE(obj));
690 }
691 
692 /* See Object#inspect. */
693 static VALUE
695 {
696  VALUE obj = (VALUE)DATA_PTR(self);
697  VALUE type = type2sym(BUILTIN_TYPE(obj));
698 
699  return rb_sprintf("#<InternalObject:%p %"PRIsVALUE">", (void *)obj, rb_sym2str(type));
700 }
701 
702 /* Returns the Object#object_id of the internal object. */
703 static VALUE
705 {
706  VALUE obj = (VALUE)DATA_PTR(self);
707  return rb_obj_id(obj);
708 }
709 
710 struct rof_data {
713 };
714 
715 static void
716 reachable_object_from_i(VALUE obj, void *data_ptr)
717 {
718  struct rof_data *data = (struct rof_data *)data_ptr;
719  VALUE key = obj;
720  VALUE val = obj;
721 
724  val = iow_newobj(obj);
725  rb_ary_push(data->internals, val);
726  }
727  st_insert(data->refs, key, val);
728  }
729 }
730 
731 static int
733 {
734  VALUE ary = (VALUE)data;
735  rb_ary_push(ary, (VALUE)value);
736  return ST_CONTINUE;
737 }
738 
739 /*
740  * call-seq:
741  * ObjectSpace.reachable_objects_from(obj) -> array or nil
742  *
743  * [MRI specific feature] Return all reachable objects from `obj'.
744  *
745  * This method returns all reachable objects from `obj'.
746  *
747  * If `obj' has two or more references to the same object `x', then returned
748  * array only includes one `x' object.
749  *
750  * If `obj' is a non-markable (non-heap management) object such as true,
751  * false, nil, symbols and Fixnums (and Flonum) then it simply returns nil.
752  *
753  * If `obj' has references to an internal object, then it returns instances of
754  * ObjectSpace::InternalObjectWrapper class. This object contains a reference
755  * to an internal object and you can check the type of internal object with
756  * `type' method.
757  *
758  * If `obj' is instance of ObjectSpace::InternalObjectWrapper class, then this
759  * method returns all reachable object from an internal object, which is
760  * pointed by `obj'.
761  *
762  * With this method, you can find memory leaks.
763  *
764  * This method is only expected to work except with C Ruby.
765  *
766  * Example:
767  * ObjectSpace.reachable_objects_from(['a', 'b', 'c'])
768  * #=> [Array, 'a', 'b', 'c']
769  *
770  * ObjectSpace.reachable_objects_from(['a', 'a', 'a'])
771  * #=> [Array, 'a', 'a', 'a'] # all 'a' strings have different object id
772  *
773  * ObjectSpace.reachable_objects_from([v = 'a', v, v])
774  * #=> [Array, 'a']
775  *
776  * ObjectSpace.reachable_objects_from(1)
777  * #=> nil # 1 is not markable (heap managed) object
778  *
779  */
780 
781 static VALUE
783 {
785  VALUE ret = rb_ary_new();
786  struct rof_data data;
787 
788  if (rb_typeddata_is_kind_of(obj, &iow_data_type)) {
789  obj = (VALUE)DATA_PTR(obj);
790  }
791 
792  data.refs = st_init_numtable();
793  data.internals = rb_ary_new();
794 
796 
798  return ret;
799  }
800  else {
801  return Qnil;
802  }
803 }
804 
805 struct rofr_data {
807  const char *last_category;
810 };
811 
812 static void
813 reachable_object_from_root_i(const char *category, VALUE obj, void *ptr)
814 {
815  struct rofr_data *data = (struct rofr_data *)ptr;
816  VALUE category_str;
817  VALUE category_objects;
818 
819  if (category == data->last_category) {
820  category_str = data->last_category_str;
821  category_objects = data->last_category_objects;
822  }
823  else {
824  data->last_category = category;
825  category_str = data->last_category_str = rb_str_new2(category);
826  category_objects = data->last_category_objects = rb_ident_hash_new();
827  if (!NIL_P(rb_hash_lookup(data->categories, category_str))) {
828  rb_bug("reachable_object_from_root_i: category should insert at once");
829  }
830  rb_hash_aset(data->categories, category_str, category_objects);
831  }
832 
834  obj != data->categories &&
835  obj != data->last_category_objects) {
837  obj = iow_newobj(obj);
838  }
839  rb_hash_aset(category_objects, obj, obj);
840  }
841 }
842 
843 static int
845 {
846  VALUE ary = rb_ary_new();
847  st_foreach(rb_hash_tbl(category_objects), collect_values, ary);
848  rb_hash_aset(categories, category, ary);
849  return ST_CONTINUE;
850 }
851 
852 /*
853  * call-seq:
854  * ObjectSpace.reachable_objects_from_root -> hash
855  *
856  * [MRI specific feature] Return all reachable objects from root.
857  */
858 static VALUE
860 {
861  struct rofr_data data;
863  data.last_category = 0;
864 
867 
868  return hash;
869 }
870 
871 static VALUE
873 {
874  if (!RTEST(klass)) {
875  return Qnil;
876  }
877  else if (RB_TYPE_P(klass, T_ICLASS)) {
878  return iow_newobj(klass);
879  }
880  else {
881  return klass;
882  }
883 }
884 
885 /*
886  * call-seq:
887  * ObjectSpace.internal_class_of(obj) -> Class or Module
888  *
889  * [MRI specific feature] Return internal class of obj.
890  * obj can be an instance of InternalObjectWrapper.
891  *
892  * Note that you should not use this method in your application.
893  */
894 static VALUE
896 {
897  VALUE klass;
898 
899  if (rb_typeddata_is_kind_of(obj, &iow_data_type)) {
900  obj = (VALUE)DATA_PTR(obj);
901  }
902 
903  klass = CLASS_OF(obj);
904  return wrap_klass_iow(klass);
905 }
906 
907 /*
908  * call-seq:
909  * ObjectSpace.internal_super_of(cls) -> Class or Module
910  *
911  * [MRI specific feature] Return internal super class of cls (Class or Module).
912  * obj can be an instance of InternalObjectWrapper.
913  *
914  * Note that you should not use this method in your application.
915  */
916 static VALUE
918 {
919  VALUE super;
920 
921  if (rb_typeddata_is_kind_of(obj, &iow_data_type)) {
922  obj = (VALUE)DATA_PTR(obj);
923  }
924 
925  switch (OBJ_BUILTIN_TYPE(obj)) {
926  case T_MODULE:
927  case T_CLASS:
928  case T_ICLASS:
929  super = RCLASS_SUPER(obj);
930  break;
931  default:
932  rb_raise(rb_eArgError, "class or module is expected");
933  }
934 
935  return wrap_klass_iow(super);
936 }
937 
938 void Init_object_tracing(VALUE rb_mObjSpace);
939 void Init_objspace_dump(VALUE rb_mObjSpace);
940 
941 /*
942  * Document-module: ObjectSpace
943  *
944  * The objspace library extends the ObjectSpace module and adds several
945  * methods to get internal statistic information about
946  * object/memory management.
947  *
948  * You need to <code>require 'objspace'</code> to use this extension module.
949  *
950  * Generally, you *SHOULD NOT* use this library if you do not know
951  * about the MRI implementation. Mainly, this library is for (memory)
952  * profiler developers and MRI developers who need to know about MRI
953  * memory usage.
954  */
955 
956 void
958 {
959  VALUE rb_mObjSpace;
960 #if 0
961  rb_mObjSpace = rb_define_module("ObjectSpace"); /* let rdoc know */
962 #endif
963  rb_mObjSpace = rb_const_get(rb_cObject, rb_intern("ObjectSpace"));
964 
965  rb_define_module_function(rb_mObjSpace, "memsize_of", memsize_of_m, 1);
966  rb_define_module_function(rb_mObjSpace, "memsize_of_all", memsize_of_all_m, -1);
967 
968  rb_define_module_function(rb_mObjSpace, "count_objects_size", count_objects_size, -1);
969  rb_define_module_function(rb_mObjSpace, "count_symbols", count_symbols, -1);
970  rb_define_module_function(rb_mObjSpace, "count_nodes", count_nodes, -1);
971  rb_define_module_function(rb_mObjSpace, "count_tdata_objects", count_tdata_objects, -1);
972  rb_define_module_function(rb_mObjSpace, "count_imemo_objects", count_imemo_objects, -1);
973 
974  rb_define_module_function(rb_mObjSpace, "reachable_objects_from", reachable_objects_from, 1);
975  rb_define_module_function(rb_mObjSpace, "reachable_objects_from_root", reachable_objects_from_root, 0);
976 
977  rb_define_module_function(rb_mObjSpace, "internal_class_of", objspace_internal_class_of, 1);
978  rb_define_module_function(rb_mObjSpace, "internal_super_of", objspace_internal_super_of, 1);
979 
980  /*
981  * This class is used as a return value from
982  * ObjectSpace::reachable_objects_from.
983  *
984  * When ObjectSpace::reachable_objects_from returns an object with
985  * references to an internal object, an instance of this class is returned.
986  *
987  * You can use the #type method to check the type of the internal object.
988  */
989  rb_mInternalObjectWrapper = rb_define_class_under(rb_mObjSpace, "InternalObjectWrapper", rb_cObject);
993 
994  Init_object_tracing(rb_mObjSpace);
995  Init_objspace_dump(rb_mObjSpace);
996 }
#define T_SYMBOL
Definition: ruby.h:508
#define T_OBJECT
Definition: ruby.h:491
Definition: node.h:93
Definition: node.h:29
static VALUE count_objects_size(int argc, VALUE *argv, VALUE os)
Definition: objspace.c:222
static const rb_data_type_t iow_data_type
Definition: objspace.c:670
void rb_bug(const char *fmt,...)
Definition: error.c:482
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1145
static VALUE rb_mInternalObjectWrapper
Definition: objspace.c:676
VALUE rb_obj_id(VALUE obj)
Definition: gc.c:3100
#define T_FIXNUM
Definition: ruby.h:503
Definition: st.h:79
#define T_MATCH
Definition: ruby.h:507
Definition: node.h:47
static unsigned int hash(str, len) register const char *str
void Init_objspace(void)
Definition: objspace.c:957
#define CLASS_OF(v)
Definition: ruby.h:453
#define T_MODULE
Definition: ruby.h:494
static VALUE count_symbols(int argc, VALUE *argv, VALUE os)
Definition: objspace.c:308
const char * last_category
Definition: objspace.c:807
#define st_foreach
Definition: regint.h:186
VALUE last_category_str
Definition: objspace.c:808
#define TypedData_Wrap_Struct(klass, data_type, sval)
Definition: ruby.h:1169
Definition: st.h:99
VALUE rb_eTypeError
Definition: error.c:762
#define T_RATIONAL
Definition: ruby.h:509
Definition: node.h:39
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:905
#define NODE_LAST
Definition: node.h:232
void rb_objspace_reachable_objects_from_root(void(func)(const char *category, VALUE, void *), void *passing_data)
Definition: gc.c:7549
struct st_table * rb_hash_tbl(VALUE hash)
Definition: hash.c:483
static int cto_i(void *vstart, void *vend, size_t stride, void *data)
Definition: objspace.c:508
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:693
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2207
static VALUE memsize_of_all_m(int argc, VALUE *argv, VALUE self)
Definition: objspace.c:105
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:690
#define T_HASH
Definition: ruby.h:499
static void reachable_object_from_i(VALUE obj, void *data_ptr)
Definition: objspace.c:716
#define DATA_PTR(dta)
Definition: ruby.h:1113
void rb_objspace_each_objects(each_obj_callback *callback, void *data)
Definition: gc.c:2431
static VALUE setup_hash(int argc, VALUE *argv)
Definition: objspace.c:127
void rb_gc_mark(VALUE ptr)
Definition: gc.c:4394
VALUE rb_hash_lookup(VALUE hash, VALUE key)
Definition: hash.c:867
int rb_objspace_markable_object_p(VALUE obj)
Definition: gc.c:3007
#define T_ARRAY
Definition: ruby.h:498
#define T_UNDEF
Definition: ruby.h:512
#define nd_type(n)
Definition: node.h:274
VALUE internals
Definition: objspace.c:712
#define RHASH_TBL(h)
Definition: ruby.h:1063
Definition: node.h:27
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: st.h:22
Definition: node.h:235
VALUE klass
Definition: objspace.c:47
void rb_hash_foreach(VALUE hash, int(*func)(ANYARGS), VALUE farg)
Definition: hash.c:402
size_t rb_obj_memsize_of(VALUE obj)
Definition: gc.c:3266
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
static VALUE iow_type(VALUE self)
Definition: objspace.c:686
static size_t iow_size(const void *ptr)
Definition: objspace.c:664
#define ID_SCOPE_MASK
Definition: id.h:32
#define CASE_TYPE(t)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:1576
#define val
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1872
#define T_NIL
Definition: ruby.h:490
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
Definition: error.c:720
VALUE rb_ary_new(void)
Definition: array.c:493
#define T_TRUE
Definition: ruby.h:504
static int cs_i(void *vstart, void *vend, size_t stride, void *n)
Definition: objspace.c:259
#define RSYMBOL(obj)
Definition: symbol.h:33
#define NIL_P(v)
Definition: ruby.h:451
VALUE categories
Definition: objspace.c:806
static VALUE reachable_objects_from(VALUE self, VALUE obj)
Definition: objspace.c:782
#define OBJ_BUILTIN_TYPE(obj)
Definition: internal.h:1766
#define T_FLOAT
Definition: ruby.h:495
int argc
Definition: ruby.c:183
Definition: node.h:59
#define T_BIGNUM
Definition: ruby.h:501
#define T_NODE
Definition: ruby.h:513
#define rb_str_new2
Definition: intern.h:857
#define T_COMPLEX
Definition: ruby.h:510
st_table * refs
Definition: objspace.c:711
static int total_i(void *vstart, void *vend, size_t stride, void *ptr)
Definition: objspace.c:51
static VALUE memsize_of_m(VALUE self, VALUE obj)
Definition: objspace.c:40
static VALUE count_nodes(int argc, VALUE *argv, VALUE os)
Definition: objspace.c:371
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:2335
static VALUE iow_inspect(VALUE self)
Definition: objspace.c:694
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1731
static VALUE iow_internal_object_id(VALUE self)
Definition: objspace.c:704
#define T_DATA
Definition: ruby.h:506
static VALUE reachable_objects_from_root(VALUE self)
Definition: objspace.c:859
int rb_objspace_internal_object_p(VALUE obj)
Definition: gc.c:2494
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1440
static VALUE count_tdata_objects(int argc, VALUE *argv, VALUE self)
Definition: objspace.c:572
VALUE rb_hash_new(void)
Definition: hash.c:441
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1919
#define T_IMEMO
Definition: ruby.h:511
#define PRIsVALUE
Definition: ruby.h:135
unsigned long ID
Definition: ruby.h:86
#define T_STRUCT
Definition: ruby.h:500
#define Qnil
Definition: ruby.h:438
#define BUILTIN_TYPE(x)
Definition: ruby.h:518
unsigned long VALUE
Definition: ruby.h:85
#define RBASIC(obj)
Definition: ruby.h:1204
const char * rb_objspace_data_type_name(VALUE obj)
Definition: gc.c:2042
static VALUE objspace_internal_super_of(VALUE self, VALUE obj)
Definition: objspace.c:917
#define FIX2INT(x)
Definition: ruby.h:686
static int set_zero_i(st_data_t key, st_data_t val, st_data_t arg)
Definition: objspace.c:118
void Init_object_tracing(VALUE rb_mObjSpace)
size_t total
Definition: objspace.c:46
ruby_value_type
Definition: ruby.h:455
static int collect_values(st_data_t key, st_data_t value, st_data_t data)
Definition: objspace.c:732
static ID imemo_type_ids[imemo_mask+1]
Definition: objspace.c:579
static int collect_values_of_values(VALUE category, VALUE category_objects, VALUE categories)
Definition: objspace.c:844
VALUE rb_ident_hash_new(void)
Definition: hash.c:2808
#define INT2FIX(i)
Definition: ruby.h:232
#define RCLASS_SUPER(c)
Definition: classext.h:16
static int cos_i(void *vstart, void *vend, size_t stride, void *data)
Definition: objspace.c:147
static void reachable_object_from_root_i(const char *category, VALUE obj, void *ptr)
Definition: objspace.c:813
Definition: node.h:45
static VALUE objspace_internal_class_of(VALUE self, VALUE obj)
Definition: objspace.c:895
void rb_objspace_reachable_objects_from(VALUE obj, void(func)(VALUE, void *), void *data)
Definition: gc.c:7521
#define st_init_numtable
Definition: regint.h:178
static VALUE wrap_klass_iow(VALUE klass)
Definition: objspace.c:872
Definition: node.h:207
VALUE rb_hash_aref(VALUE hash, VALUE key)
Definition: hash.c:845
#define RTEST(v)
Definition: ruby.h:450
Definition: node.h:141
#define T_STRING
Definition: ruby.h:496
#define T_FALSE
Definition: ruby.h:505
#define T_FILE
Definition: ruby.h:502
static VALUE iow_newobj(VALUE obj)
Definition: objspace.c:679
static VALUE type2sym(enum ruby_value_type i)
Definition: objspace.c:161
#define st_insert
Definition: regint.h:184
#define T_CLASS
Definition: ruby.h:492
const char * name
Definition: nkf.c:208
#define ID2SYM(x)
Definition: ruby.h:383
Definition: node.h:61
static int cn_i(void *vstart, void *vend, size_t stride, void *n)
Definition: objspace.c:332
imemo_type
Definition: internal.h:737
static VALUE count_imemo_objects(int argc, VALUE *argv, VALUE self)
Definition: objspace.c:637
Definition: node.h:31
Definition: node.h:41
#define RHASH_EMPTY_P(h)
Definition: ruby.h:1067
VALUE rb_define_module(const char *name)
Definition: class.c:768
#define rb_intern(str)
#define T_ZOMBIE
Definition: ruby.h:514
#define T_NONE
Definition: ruby.h:489
size_t rb_sym_immortal_count(void)
Definition: symbol.c:822
#define T_ICLASS
Definition: ruby.h:493
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
void Init_objspace_dump(VALUE rb_mObjSpace)
#define SIZET2NUM(v)
Definition: ruby.h:264
VALUE rb_eArgError
Definition: error.c:763
VALUE last_category_objects
Definition: objspace.c:809
#define T_REGEXP
Definition: ruby.h:497
Definition: node.h:139
#define T_MASK
Definition: md5.c:131
static int count_imemo_objects_i(void *vstart, void *vend, size_t stride, void *data)
Definition: objspace.c:582
#define COUNT_NODE(n)
static void iow_mark(void *ptr)
Definition: objspace.c:658
char ** argv
Definition: ruby.c:184
#define rb_sym2str(sym)
Definition: console.c:107