diff options
| author | Takashi Kokubun <takashi.kokubun@shopify.com> | 2025-09-30 20:50:08 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-30 20:50:08 -0700 |
| commit | 56f777cedf1b9acc2fe74bda3d5dde351ba31951 (patch) | |
| tree | f956ad497379f6fc62b4b427006c4daac2b3838d | |
| parent | 400e150f00ebbd71b14c9c4a885b1eb23be4b4b2 (diff) | |
ZJIT: Add more *_send_count stats (#14689)
| -rw-r--r-- | zjit.rb | 21 | ||||
| -rw-r--r-- | zjit/src/codegen.rs | 5 | ||||
| -rw-r--r-- | zjit/src/stats.rs | 29 |
3 files changed, 51 insertions, 4 deletions
@@ -162,9 +162,16 @@ class << RubyVM::ZJIT print_counters_with_prefix(prefix: 'compile_error_', prompt: 'compile error reasons', buf:, stats:, limit: 20) print_counters_with_prefix(prefix: 'exit_', prompt: 'side exit reasons', buf:, stats:, limit: 20) - # Show the most important stats ratio_in_zjit at the end + # Show no-prefix counters, having the most important stat `ratio_in_zjit` at the end print_counters([ + :send_count, :dynamic_send_count, + :optimized_send_count, + :iseq_optimized_send_count, + :inline_cfunc_optimized_send_count, + :variadic_cfunc_optimized_send_count, + ], buf:, stats:, right_align: true, base: :send_count) + print_counters([ :dynamic_getivar_count, :dynamic_setivar_count, @@ -202,12 +209,18 @@ class << RubyVM::ZJIT # :stopdoc: private - def print_counters(keys, buf:, stats:) - left_pad = keys.map { |key| key.to_s.sub(/_time_ns\z/, '_time').size }.max + 1 + def print_counters(keys, buf:, stats:, right_align: false, base: nil) + key_pad = keys.map { |key| key.to_s.sub(/_time_ns\z/, '_time').size }.max + 1 + key_align = '-' unless right_align + value_pad = keys.filter_map { |key| stats[key] }.map { |value| number_with_delimiter(value).size }.max + keys.each do |key| # Some stats like vm_insn_count and ratio_in_zjit are not supported on the release build next unless stats.key?(key) value = stats[key] + if base && key != base + ratio = " (%4.1f%%)" % (100.0 * value / stats[base]) + end case key when :ratio_in_zjit @@ -219,7 +232,7 @@ class << RubyVM::ZJIT value = number_with_delimiter(value) end - buf << "#{"%-#{left_pad}s" % "#{key}:"} #{value}\n" + buf << "%#{key_align}*s %*s%s\n" % [key_pad, "#{key}:", value_pad, value, ratio] end end diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index b8d527fb8d..23631ae6ba 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -661,6 +661,7 @@ fn gen_patch_point(jit: &mut JITState, asm: &mut Assembler, invariant: &Invarian /// Lowering for [`Insn::CCall`]. This is a low-level raw call that doesn't know /// anything about the callee, so handling for e.g. GC safety is dealt with elsewhere. fn gen_ccall(asm: &mut Assembler, cfun: *const u8, args: Vec<Opnd>) -> lir::Opnd { + gen_incr_counter(asm, Counter::inline_cfunc_optimized_send_count); asm.ccall(cfun, args) } @@ -675,6 +676,8 @@ fn gen_ccall_variadic( cme: *const rb_callable_method_entry_t, state: &FrameState, ) -> lir::Opnd { + gen_incr_counter(asm, Counter::variadic_cfunc_optimized_send_count); + gen_prepare_non_leaf_call(jit, asm, state); let stack_growth = state.stack_size(); @@ -1051,6 +1054,8 @@ fn gen_send_without_block_direct( args: Vec<Opnd>, state: &FrameState, ) -> lir::Opnd { + gen_incr_counter(asm, Counter::iseq_optimized_send_count); + let local_size = unsafe { get_iseq_body_local_table_size(iseq) }.as_usize(); let stack_growth = state.stack_size() + local_size + unsafe { get_iseq_body_stack_max(iseq) }.as_usize(); gen_stack_overflow_check(jit, asm, state, stack_growth); diff --git a/zjit/src/stats.rs b/zjit/src/stats.rs index a9cf1bde7c..5c8333d01d 100644 --- a/zjit/src/stats.rs +++ b/zjit/src/stats.rs @@ -21,6 +21,9 @@ macro_rules! make_counters { dynamic_send { $($dynamic_send_counter_name:ident,)+ } + optimized_send { + $($optimized_send_counter_name:ident,)+ + } $($counter_name:ident,)+ ) => { /// Struct containing the counter values @@ -29,6 +32,7 @@ macro_rules! make_counters { $(pub $default_counter_name: u64,)+ $(pub $exit_counter_name: u64,)+ $(pub $dynamic_send_counter_name: u64,)+ + $(pub $optimized_send_counter_name: u64,)+ $(pub $counter_name: u64,)+ } @@ -39,6 +43,7 @@ macro_rules! make_counters { $($default_counter_name,)+ $($exit_counter_name,)+ $($dynamic_send_counter_name,)+ + $($optimized_send_counter_name,)+ $($counter_name,)+ } @@ -48,6 +53,7 @@ macro_rules! make_counters { $( Counter::$default_counter_name => stringify!($default_counter_name).to_string(), )+ $( Counter::$exit_counter_name => stringify!($exit_counter_name).to_string(), )+ $( Counter::$dynamic_send_counter_name => stringify!($dynamic_send_counter_name).to_string(), )+ + $( Counter::$optimized_send_counter_name => stringify!($optimized_send_counter_name).to_string(), )+ $( Counter::$counter_name => stringify!($counter_name).to_string(), )+ } } @@ -60,6 +66,7 @@ macro_rules! make_counters { $( Counter::$default_counter_name => std::ptr::addr_of_mut!(counters.$default_counter_name), )+ $( Counter::$exit_counter_name => std::ptr::addr_of_mut!(counters.$exit_counter_name), )+ $( Counter::$dynamic_send_counter_name => std::ptr::addr_of_mut!(counters.$dynamic_send_counter_name), )+ + $( Counter::$optimized_send_counter_name => std::ptr::addr_of_mut!(counters.$optimized_send_counter_name), )+ $( Counter::$counter_name => std::ptr::addr_of_mut!(counters.$counter_name), )+ } } @@ -80,6 +87,11 @@ macro_rules! make_counters { $( Counter::$dynamic_send_counter_name, )+ ]; + /// List of other counters that are summed as optimized_send_count. + pub const OPTIMIZED_SEND_COUNTERS: &'static [Counter] = &[ + $( Counter::$optimized_send_counter_name, )+ + ]; + /// List of other counters that are available only for --zjit-stats. pub const OTHER_COUNTERS: &'static [Counter] = &[ $( Counter::$counter_name, )+ @@ -140,6 +152,13 @@ make_counters! { send_fallback_not_optimized_instruction, } + // Optimized send counters that are summed as optimized_send_count + optimized_send { + iseq_optimized_send_count, + inline_cfunc_optimized_send_count, + variadic_cfunc_optimized_send_count, + } + // compile_error_: Compile error reasons compile_error_iseq_stack_too_large, compile_error_exception_handler, @@ -421,6 +440,16 @@ pub extern "C" fn rb_zjit_stats(_ec: EcPtr, _self: VALUE, target_key: VALUE) -> } set_stat_usize!(hash, "dynamic_send_count", dynamic_send_count); + // Set optimized send counters + let mut optimized_send_count = 0; + for &counter in OPTIMIZED_SEND_COUNTERS { + let count = unsafe { *counter_ptr(counter) }; + optimized_send_count += count; + set_stat_usize!(hash, &counter.name(), count); + } + set_stat_usize!(hash, "optimized_send_count", optimized_send_count); + set_stat_usize!(hash, "send_count", dynamic_send_count + optimized_send_count); + // Set send fallback counters for NotOptimizedInstruction let send_fallback_counters = ZJITState::get_send_fallback_counters(); for (op_idx, count) in send_fallback_counters.iter().enumerate().take(VM_INSTRUCTION_SIZE as usize) { |
