[前][次][番号順一覧][スレッド一覧]

ruby-changes:71638

From: Kevin <ko1@a...>
Date: Wed, 6 Apr 2022 05:37:18 +0900 (JST)
Subject: [ruby-changes:71638] 8ee4a82e8c (master): RubyVM.stat constant cache metrics (#5766)

https://git.ruby-lang.org/ruby.git/commit/?id=8ee4a82e8c

From 8ee4a82e8cfe6f39abeb60013447bdd2a3a3c61f Mon Sep 17 00:00:00 2001
From: Kevin Newton <kddnewton@g...>
Date: Tue, 5 Apr 2022 16:37:00 -0400
Subject: RubyVM.stat constant cache metrics (#5766)

Before the new constant cache behavior, caches were invalidated by a
single global variable. You could inspect the value of this variable
with RubyVM.stat(:global_constant_state). This was mostly useful to
verify the behavior of the VM or to test constant loading like in Rails.

With the new constant cache behavior, we introduced
RubyVM.stat(:constant_cache) which returned a hash with symbol keys and
integer values that represented the number of live constant caches
associated with the given symbol. Additionally, we removed the old
RubyVM.stat(:global_constant_state).

This was proven to be not very useful, so it doesn't help you diagnose
constant loading issues. So, instead we added the global constant state
back into the RubyVM output. However, that number can be misleading as
now when you invalidate something like `Foo::Bar::Baz` you're actually
invalidating 3 different lists of inline caches.

This commit attempts to get the best of both worlds. We remove
RubyVM.stat(:global_constant_state) like we did originally, as it
doesn't have the same semantic meaning and it could be confusing going
forward. Instead we add RubyVM.stat(:constant_cache_invalidations) and
RubyVM.stat(:constant_cache_misses). These two metrics should provide
enough information to diagnose any constant loading issues, as well as
provide a replacement for the old global constant state.
---
 insns.def       |  1 +
 vm.c            | 43 +++++++++++--------------------------------
 vm_insnhelper.h |  3 ++-
 vm_method.c     |  2 +-
 4 files changed, 15 insertions(+), 34 deletions(-)

diff --git a/insns.def b/insns.def
index cdec216cfe..b5dea9c10c 100644
--- a/insns.def
+++ b/insns.def
@@ -1044,6 +1044,7 @@ opt_getinlinecache https://github.com/ruby/ruby/blob/trunk/insns.def#L1044
         JUMP(dst);
     }
     else {
+        ruby_vm_constant_cache_misses++;
         val = Qnil;
     }
 }
diff --git a/vm.c b/vm.c
index c02d502f37..720d26256e 100644
--- a/vm.c
+++ b/vm.c
@@ -428,7 +428,8 @@ rb_event_flag_t ruby_vm_event_flags; https://github.com/ruby/ruby/blob/trunk/vm.c#L428
 rb_event_flag_t ruby_vm_event_enabled_global_flags;
 unsigned int    ruby_vm_event_local_num;
 
-rb_serial_t ruby_vm_global_constant_state = 1;
+rb_serial_t ruby_vm_constant_cache_invalidations = 0;
+rb_serial_t ruby_vm_constant_cache_misses = 0;
 rb_serial_t ruby_vm_class_serial = 1;
 rb_serial_t ruby_vm_global_cvar_state = 1;
 
@@ -496,16 +497,6 @@ rb_dtrace_setup(rb_execution_context_t *ec, VALUE klass, ID id, https://github.com/ruby/ruby/blob/trunk/vm.c#L497
     return FALSE;
 }
 
-// Iterator function to loop through each entry in the constant cache and add
-// its associated size into the given Hash.
-static enum rb_id_table_iterator_result
-vm_stat_constant_cache_i(ID id, VALUE table, void *constant_cache)
-{
-    st_index_t size = ((st_table *) table)->num_entries;
-    rb_hash_aset((VALUE) constant_cache, ID2SYM(id), LONG2NUM(size));
-    return ID_TABLE_CONTINUE;
-}
-
 /*
  *  call-seq:
  *    RubyVM.stat -> Hash
@@ -517,8 +508,10 @@ vm_stat_constant_cache_i(ID id, VALUE table, void *constant_cache) https://github.com/ruby/ruby/blob/trunk/vm.c#L508
  *  This hash includes information about method/constant caches:
  *
  *    {
- *      :constant_cache=>{:RubyVM=>3},
- *      :class_serial=>9029
+ *      :constant_cache_invalidations=>2,
+ *      :constant_cache_misses=>14,
+ *      :class_serial=>546,
+ *      :global_cvar_state=>27
  *    }
  *
  *  The contents of the hash are implementation specific and may be changed in
@@ -529,7 +522,7 @@ vm_stat_constant_cache_i(ID id, VALUE table, void *constant_cache) https://github.com/ruby/ruby/blob/trunk/vm.c#L522
 static VALUE
 vm_stat(int argc, VALUE *argv, VALUE self)
 {
-    static VALUE sym_global_constant_state, sym_constant_cache, sym_class_serial, sym_global_cvar_state;
+    static VALUE sym_constant_cache_invalidations, sym_constant_cache_misses, sym_class_serial, sym_global_cvar_state;
     VALUE arg = Qnil;
     VALUE hash = Qnil, key = Qnil;
 
@@ -547,8 +540,8 @@ vm_stat(int argc, VALUE *argv, VALUE self) https://github.com/ruby/ruby/blob/trunk/vm.c#L540
     }
 
 #define S(s) sym_##s = ID2SYM(rb_intern_const(#s))
-    S(global_constant_state);
-	S(constant_cache);
+    S(constant_cache_invalidations);
+    S(constant_cache_misses);
 	S(class_serial);
 	S(global_cvar_state);
 #undef S
@@ -559,26 +552,12 @@ vm_stat(int argc, VALUE *argv, VALUE self) https://github.com/ruby/ruby/blob/trunk/vm.c#L552
     else if (hash != Qnil) \
 	rb_hash_aset(hash, sym_##name, SERIALT2NUM(attr));
 
-    SET(global_constant_state, ruby_vm_global_constant_state);
+    SET(constant_cache_invalidations, ruby_vm_constant_cache_invalidations);
+    SET(constant_cache_misses, ruby_vm_constant_cache_misses);
     SET(class_serial, ruby_vm_class_serial);
     SET(global_cvar_state, ruby_vm_global_cvar_state);
 #undef SET
 
-    // Here we're going to set up the constant cache hash that has key-value
-    // pairs of { name => count }, where name is a Symbol that represents the
-    // ID in the cache and count is an Integer representing the number of inline
-    // constant caches associated with that Symbol.
-    if (key == sym_constant_cache || hash != Qnil) {
-        VALUE constant_cache = rb_hash_new();
-        rb_id_table_foreach(GET_VM()->constant_cache, vm_stat_constant_cache_i, (void *) constant_cache);
-
-        if (key == sym_constant_cache) {
-            return constant_cache;
-        } else {
-            rb_hash_aset(hash, sym_constant_cache, constant_cache);
-        }
-    }
-
     if (!NIL_P(key)) { /* matched key should return above */
 	rb_raise(rb_eArgError, "unknown key: %"PRIsVALUE, rb_sym2str(key));
     }
diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index 5506fca4d6..126867025f 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -14,7 +14,8 @@ https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.h#L14
 MJIT_SYMBOL_EXPORT_BEGIN
 
 RUBY_EXTERN VALUE ruby_vm_const_missing_count;
-RUBY_EXTERN rb_serial_t ruby_vm_global_constant_state;
+RUBY_EXTERN rb_serial_t ruby_vm_constant_cache_invalidations;
+RUBY_EXTERN rb_serial_t ruby_vm_constant_cache_misses;
 RUBY_EXTERN rb_serial_t ruby_vm_class_serial;
 RUBY_EXTERN rb_serial_t ruby_vm_global_cvar_state;
 
diff --git a/vm_method.c b/vm_method.c
index 81e88a32c1..36a2c15e4b 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -144,10 +144,10 @@ rb_clear_constant_cache_for_id(ID id) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L144
 
     if (rb_id_table_lookup(vm->constant_cache, id, (VALUE *) &ics)) {
         st_foreach(ics, rb_clear_constant_cache_for_id_i, (st_data_t) NULL);
+        ruby_vm_constant_cache_invalidations += ics->num_entries;
     }
 
     rb_yjit_constant_state_changed();
-    ruby_vm_global_constant_state++;
 }
 
 static void
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]