ruby-changes:31983
From: tmm1 <ko1@a...>
Date: Sun, 8 Dec 2013 13:06:15 +0900 (JST)
Subject: [ruby-changes:31983] tmm1:r44062 (trunk): vm.c: add RubyVM.stat for accessing cache serials
tmm1 2013-12-08 13:05:59 +0900 (Sun, 08 Dec 2013) New Revision: 44062 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=44062 Log: vm.c: add RubyVM.stat for accessing cache serials * vm.c (ruby_vm_stat): add RubyVM.stat() for access to internal cache counters. this methods behaves like GC.stat, accepting an optional hash or symbol argument. [Bug #9190] [ruby-core:58750] * test/ruby/test_rubyvm.rb: test for new method Added files: trunk/test/ruby/test_rubyvm.rb Modified files: trunk/ChangeLog trunk/vm.c Index: ChangeLog =================================================================== --- ChangeLog (revision 44061) +++ ChangeLog (revision 44062) @@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sun Dec 8 13:01:11 2013 Aman Gupta <ruby@t...> + + * vm.c (ruby_vm_stat): add RubyVM.stat() for access to internal cache + counters. this methods behaves like GC.stat, accepting an optional + hash or symbol argument. [Bug #9190] [ruby-core:58750] + * test/ruby/test_rubyvm.rb: test for new method + Sun Dec 8 11:59:40 2013 Aman Gupta <ruby@t...> * hash.c (rb_hash_replace): add a write barrier to fix GC mark miss on Index: vm.c =================================================================== --- vm.c (revision 44061) +++ vm.c (revision 44062) @@ -113,6 +113,71 @@ rb_vm_inc_const_missing_count(void) https://github.com/ruby/ruby/blob/trunk/vm.c#L113 ruby_vm_const_missing_count +=1; } +/* + * call-seq: + * RubyVM.stat -> Hash + * RubyVM.stat(hsh) -> hsh + * RubyVM.stat(Symbol) -> Numeric + * + * Returns a Hash containing implementation-dependent counters inside the VM. + * + * This hash includes information about method/constant cache serials: + * + * { + * :method_serial=>251, + * :constant_serial=>481, + * :class_serial=>9029 + * } + * + * The contents of the hash are implementation specific and may be changed in + * the future. + * + * This method is only expected to work on C Ruby. + */ + +static VALUE +ruby_vm_stat(int argc, VALUE *argv, VALUE self) +{ + static VALUE sym_method_serial, sym_constant_serial, sym_class_serial; + VALUE arg = Qnil; + VALUE hash = Qnil, key = Qnil; + + if (rb_scan_args(argc, argv, "01", &arg) == 1) { + if (SYMBOL_P(arg)) + key = arg; + else if (RB_TYPE_P(arg, T_HASH)) + hash = arg; + else + rb_raise(rb_eTypeError, "non-hash or symbol given"); + } else if (arg == Qnil) { + hash = rb_hash_new(); + } + + if (sym_method_serial == 0) { +#define S(s) sym_##s = ID2SYM(rb_intern_const(#s)) + S(method_serial); + S(constant_serial); + S(class_serial); +#undef S + } + +#define SET(name, attr) \ + if (key == sym_##name) \ + return SIZET2NUM(attr); \ + else if (hash != Qnil) \ + rb_hash_aset(hash, sym_##name, SIZET2NUM(attr)); + + SET(method_serial, ruby_vm_method_serial); + SET(constant_serial, ruby_vm_constant_serial); + SET(class_serial, ruby_vm_class_serial); +#undef SET + + if (key != Qnil) /* matched key should return above */ + rb_raise(rb_eArgError, "unknown key: %s", RSTRING_PTR(rb_id2str(SYM2ID(key)))); + + return hash; +} + /* control stack frame */ static void @@ -2295,6 +2360,7 @@ Init_VM(void) https://github.com/ruby/ruby/blob/trunk/vm.c#L2360 rb_cRubyVM = rb_define_class("RubyVM", rb_cObject); rb_undef_alloc_func(rb_cRubyVM); rb_undef_method(CLASS_OF(rb_cRubyVM), "new"); + rb_define_singleton_method(rb_cRubyVM, "stat", ruby_vm_stat, -1); /* FrozenCore (hidden) */ fcore = rb_class_new(rb_cBasicObject); Index: test/ruby/test_rubyvm.rb =================================================================== --- test/ruby/test_rubyvm.rb (revision 0) +++ test/ruby/test_rubyvm.rb (revision 44062) @@ -0,0 +1,16 @@ https://github.com/ruby/ruby/blob/trunk/test/ruby/test_rubyvm.rb#L1 +require 'test/unit' + +class TestRubyVM < Test::Unit::TestCase + def test_stat + assert_kind_of Hash, RubyVM.stat + assert_kind_of Fixnum, RubyVM.stat[:method_serial] + + RubyVM.stat(stat = {}) + assert_not_empty stat + assert_equal stat[:method_serial], RubyVM.stat(:method_serial) + end + + def test_stat_unknown + assert_raise(ArgumentError){ RubyVM.stat(:unknown) } + end +end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/