ruby-changes:2319
From: ko1@a...
Date: 4 Nov 2007 00:09:41 +0900
Subject: [ruby-changes:2319] akr - Ruby:r13810 (trunk): * gc.c (count_objects): ObjectSpace.count_objects implemented.
akr 2007-11-04 00:09:10 +0900 (Sun, 04 Nov 2007) New Revision: 13810 Modified files: trunk/ChangeLog trunk/gc.c Log: * gc.c (count_objects): ObjectSpace.count_objects implemented. http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=13810&r2=13809 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/gc.c?r1=13810&r2=13809 Index: ChangeLog =================================================================== --- ChangeLog (revision 13809) +++ ChangeLog (revision 13810) @@ -1,3 +1,7 @@ +Sun Nov 4 00:06:40 2007 Tanaka Akira <akr@f...> + + * gc.c (count_objects): ObjectSpace.count_objects implemented. + Sat Nov 3 22:49:37 2007 Yukihiro Matsumoto <matz@r...> * hash.c (rb_hash_each_pair): make Hash#each to be alias to Index: gc.c =================================================================== --- gc.c (revision 13809) +++ gc.c (revision 13810) @@ -2150,6 +2150,95 @@ } /* + * call-seq: + * ObjectSpace.count_objects([result_hash]) -> hash + * + * Counts objects for each type. + * + * It returns a hash as: {:FREE=>3012, :T_OBJECT=>6, :T_CLASS=>404, ...} + * + * If the optional argument, result_hash, is given, + * it is overwritten and returned. + * This is intended to avoid probe effect. + * + * The contents of the returned hash is implementation defined. + * It may be changed in future. + * + * This method is not expected to work except C Ruby. + * + */ + +static VALUE +count_objects(int argc, VALUE *argv, VALUE os) +{ + long counts[T_MASK+1]; + long freed = 0; + int i; + VALUE hash; + + if (rb_scan_args(argc, argv, "01", &hash) == 1) { + if (TYPE(hash) != T_HASH) + rb_raise(rb_eTypeError, "non-hash given"); + } + + for (i = 0; i <= T_MASK; i++) { + counts[i] = 0; + } + + for (i = 0; i < heaps_used; i++) { + RVALUE *p, *pend; + + p = heaps[i].slot; pend = p + heaps[i].limit; + for (;p < pend; p++) { + if (p->as.basic.flags) { + counts[BUILTIN_TYPE(p)]++; + } + else { + freed++; + } + } + } + + if (hash == Qnil) + hash = rb_hash_new(); + rb_hash_aset(hash, ID2SYM(rb_intern("FREE")), LONG2NUM(freed)); + for (i = 0; i <= T_MASK; i++) { + VALUE type; + switch (i) { + case T_NONE: type = ID2SYM(rb_intern("T_NONE")); break; + case T_NIL: type = ID2SYM(rb_intern("T_NIL")); break; + case T_OBJECT: type = ID2SYM(rb_intern("T_OBJECT")); break; + case T_CLASS: type = ID2SYM(rb_intern("T_CLASS")); break; + case T_ICLASS: type = ID2SYM(rb_intern("T_ICLASS")); break; + case T_MODULE: type = ID2SYM(rb_intern("T_MODULE")); break; + case T_FLOAT: type = ID2SYM(rb_intern("T_FLOAT")); break; + case T_STRING: type = ID2SYM(rb_intern("T_STRING")); break; + case T_REGEXP: type = ID2SYM(rb_intern("T_REGEXP")); break; + case T_ARRAY: type = ID2SYM(rb_intern("T_ARRAY")); break; + case T_FIXNUM: type = ID2SYM(rb_intern("T_FIXNUM")); break; + case T_HASH: type = ID2SYM(rb_intern("T_HASH")); break; + case T_STRUCT: type = ID2SYM(rb_intern("T_STRUCT")); break; + case T_BIGNUM: type = ID2SYM(rb_intern("T_BIGNUM")); break; + case T_FILE: type = ID2SYM(rb_intern("T_FILE")); break; + case T_TRUE: type = ID2SYM(rb_intern("T_TRUE")); break; + case T_FALSE: type = ID2SYM(rb_intern("T_FALSE")); break; + case T_DATA: type = ID2SYM(rb_intern("T_DATA")); break; + case T_MATCH: type = ID2SYM(rb_intern("T_MATCH")); break; + case T_SYMBOL: type = ID2SYM(rb_intern("T_SYMBOL")); break; + case T_VALUES: type = ID2SYM(rb_intern("T_VALUES")); break; + case T_BLOCK: type = ID2SYM(rb_intern("T_BLOCK")); break; + case T_UNDEF: type = ID2SYM(rb_intern("T_UNDEF")); break; + case T_NODE: type = ID2SYM(rb_intern("T_NODE")); break; + default: type = INT2NUM(i); break; + } + if (counts[i]) + rb_hash_aset(hash, type, LONG2NUM(counts[i])); + } + + return hash; +} + +/* * The <code>GC</code> module provides an interface to Ruby's mark and * sweep garbage collection mechanism. Some of the underlying methods * are also available via the <code>ObjectSpace</code> module. @@ -2194,4 +2283,6 @@ rb_define_method(rb_mKernel, "hash", rb_obj_id, 0); rb_define_method(rb_mKernel, "__id__", rb_obj_id, 0); rb_define_method(rb_mKernel, "object_id", rb_obj_id, 0); + + rb_define_module_function(rb_mObSpace, "count_objects", count_objects, -1); } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml