1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44062 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
tmm1 2013-12-08 04:05:59 +00:00
parent 2aa57843f2
commit cc1063092b
3 changed files with 89 additions and 0 deletions

View file

@ -1,3 +1,10 @@
Sun Dec 8 13:01:11 2013 Aman Gupta <ruby@tmm1.net>
* 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@tmm1.net>
* hash.c (rb_hash_replace): add a write barrier to fix GC mark miss on

16
test/ruby/test_rubyvm.rb Normal file
View file

@ -0,0 +1,16 @@
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

66
vm.c
View file

@ -113,6 +113,71 @@ rb_vm_inc_const_missing_count(void)
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)
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);