diff --git a/internal/vm.h b/internal/vm.h index c30e26a8b4..f8461ba6d6 100644 --- a/internal/vm.h +++ b/internal/vm.h @@ -81,7 +81,7 @@ struct vm_ifunc *rb_current_ifunc(void); #if USE_YJIT /* vm_exec.c */ -extern uint64_t rb_vm_insns_count; +extern RB_THREAD_LOCAL_SPECIFIER uint64_t rb_vm_insns_count; #endif extern bool rb_free_at_exit; diff --git a/rjit.c b/rjit.c index 72660394b3..4a01a12d77 100644 --- a/rjit.c +++ b/rjit.c @@ -170,7 +170,7 @@ struct rb_rjit_runtime_counters rb_rjit_counters = { 0 }; extern VALUE rb_gc_enable(void); extern VALUE rb_gc_disable(void); -extern uint64_t rb_vm_insns_count; +extern RB_THREAD_LOCAL_SPECIFIER uint64_t rb_vm_insns_count; // Disable GC, TracePoint, JIT, stats, and $! #define WITH_RJIT_ISOLATED_USING_PC(using_pc, stmt) do { \ diff --git a/rjit_c.c b/rjit_c.c index e421763480..fd09ac87c6 100644 --- a/rjit_c.c +++ b/rjit_c.c @@ -541,7 +541,7 @@ extern VALUE rb_vm_set_ivar_id(VALUE obj, ID id, VALUE val); extern VALUE rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary); extern void* rb_rjit_entry_stub_hit(VALUE branch_stub); extern void* rb_rjit_branch_stub_hit(VALUE branch_stub, int sp_offset, int target0_p); -extern uint64_t rb_vm_insns_count; +extern RB_THREAD_LOCAL_SPECIFIER uint64_t rb_vm_insns_count; #include "rjit_c.rbinc" diff --git a/vm_exec.c b/vm_exec.c index 44d92e2225..2f5e572da9 100644 --- a/vm_exec.c +++ b/vm_exec.c @@ -13,7 +13,7 @@ #if USE_YJIT || USE_RJIT // The number of instructions executed on vm_exec_core. --yjit-stats uses this. -uint64_t rb_vm_insns_count = 0; +RB_THREAD_LOCAL_SPECIFIER uint64_t rb_vm_insns_count = 0; #endif #if VM_COLLECT_USAGE_DETAILS diff --git a/yjit.c b/yjit.c index 6a1d0308b2..39774252b3 100644 --- a/yjit.c +++ b/yjit.c @@ -16,6 +16,7 @@ #include "internal/fixnum.h" #include "internal/numeric.h" #include "internal/gc.h" +#include "internal/vm.h" #include "vm_core.h" #include "vm_callinfo.h" #include "builtin.h" @@ -96,6 +97,11 @@ rb_yjit_mark_executable(void *mem_block, uint32_t mem_size) } } +uint64_t +rb_yjit_vm_insns_count(void) { + return rb_vm_insns_count; +} + // Free the specified memory block. bool rb_yjit_mark_unused(void *mem_block, uint32_t mem_size) diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index e8f88cef64..b6f4c4b7c4 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -317,6 +317,7 @@ fn main() { .allowlist_function("rb_yjit_get_page_size") .allowlist_function("rb_yjit_iseq_builtin_attrs") .allowlist_function("rb_yjit_iseq_inspect") + .allowlist_function("rb_yjit_vm_insns_count") .allowlist_function("rb_yjit_builtin_function") .allowlist_function("rb_set_cfp_(pc|sp)") .allowlist_function("rb_yjit_multi_ractor_p") @@ -380,9 +381,6 @@ fn main() { .allowlist_function("rb_ivar_get") .allowlist_function("rb_mod_name") - // From internal/vm.h - .allowlist_var("rb_vm_insns_count") - // From include/ruby/internal/intern/vm.h .allowlist_function("rb_get_alloc_func") diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index d9bcd2634c..7ad24a274c 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -1061,7 +1061,6 @@ extern "C" { elts: *const VALUE, ) -> VALUE; pub fn rb_vm_top_self() -> VALUE; - pub static mut rb_vm_insns_count: u64; pub fn rb_method_entry_at(obj: VALUE, id: ID) -> *const rb_method_entry_t; pub fn rb_callable_method_entry(klass: VALUE, id: ID) -> *const rb_callable_method_entry_t; pub fn rb_callable_method_entry_or_negative( @@ -1141,6 +1140,7 @@ extern "C" { pub fn rb_jit_cont_each_iseq(callback: rb_iseq_callback, data: *mut ::std::os::raw::c_void); pub fn rb_yjit_mark_writable(mem_block: *mut ::std::os::raw::c_void, mem_size: u32) -> bool; pub fn rb_yjit_mark_executable(mem_block: *mut ::std::os::raw::c_void, mem_size: u32); + pub fn rb_yjit_vm_insns_count() -> u64; pub fn rb_yjit_mark_unused(mem_block: *mut ::std::os::raw::c_void, mem_size: u32) -> bool; pub fn rb_yjit_array_len(a: VALUE) -> ::std::os::raw::c_long; pub fn rb_yjit_icache_invalidate( diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs index 3a3965577b..aa0b3d528c 100644 --- a/yjit/src/stats.rs +++ b/yjit/src/stats.rs @@ -792,7 +792,7 @@ fn rb_yjit_gen_stats_dict(key: VALUE) -> VALUE { set_stat_usize!(hash, "context_cache_bytes", crate::core::CTX_ENCODE_CACHE_BYTES + crate::core::CTX_DECODE_CACHE_BYTES); // VM instructions count - set_stat_usize!(hash, "vm_insns_count", rb_vm_insns_count as usize); + set_stat_usize!(hash, "vm_insns_count", rb_yjit_vm_insns_count() as usize); set_stat_usize!(hash, "live_iseq_count", rb_yjit_live_iseq_count as usize); set_stat_usize!(hash, "iseq_alloc_count", rb_yjit_iseq_alloc_count as usize); @@ -862,7 +862,7 @@ fn rb_yjit_gen_stats_dict(key: VALUE) -> VALUE { set_stat_double!(hash, "avg_len_in_yjit", avg_len_in_yjit); // Proportion of instructions that retire in YJIT - let total_insns_count = retired_in_yjit + rb_vm_insns_count; + let total_insns_count = retired_in_yjit + rb_yjit_vm_insns_count(); set_stat_usize!(hash, "total_insns_count", total_insns_count as usize); let ratio_in_yjit: f64 = 100.0 * retired_in_yjit as f64 / total_insns_count as f64;