Skip to content

Commit 56f777c

Browse files
authored
ZJIT: Add more *_send_count stats (ruby#14689)
1 parent 400e150 commit 56f777c

3 files changed

Lines changed: 51 additions & 4 deletions

File tree

zjit.rb

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,16 @@ def stats_string
162162
print_counters_with_prefix(prefix: 'compile_error_', prompt: 'compile error reasons', buf:, stats:, limit: 20)
163163
print_counters_with_prefix(prefix: 'exit_', prompt: 'side exit reasons', buf:, stats:, limit: 20)
164164

165-
# Show the most important stats ratio_in_zjit at the end
165+
# Show no-prefix counters, having the most important stat `ratio_in_zjit` at the end
166166
print_counters([
167+
:send_count,
167168
:dynamic_send_count,
169+
:optimized_send_count,
170+
:iseq_optimized_send_count,
171+
:inline_cfunc_optimized_send_count,
172+
:variadic_cfunc_optimized_send_count,
173+
], buf:, stats:, right_align: true, base: :send_count)
174+
print_counters([
168175
:dynamic_getivar_count,
169176
:dynamic_setivar_count,
170177

@@ -202,12 +209,18 @@ def assert_compiles # :nodoc:
202209
# :stopdoc:
203210
private
204211

205-
def print_counters(keys, buf:, stats:)
206-
left_pad = keys.map { |key| key.to_s.sub(/_time_ns\z/, '_time').size }.max + 1
212+
def print_counters(keys, buf:, stats:, right_align: false, base: nil)
213+
key_pad = keys.map { |key| key.to_s.sub(/_time_ns\z/, '_time').size }.max + 1
214+
key_align = '-' unless right_align
215+
value_pad = keys.filter_map { |key| stats[key] }.map { |value| number_with_delimiter(value).size }.max
216+
207217
keys.each do |key|
208218
# Some stats like vm_insn_count and ratio_in_zjit are not supported on the release build
209219
next unless stats.key?(key)
210220
value = stats[key]
221+
if base && key != base
222+
ratio = " (%4.1f%%)" % (100.0 * value / stats[base])
223+
end
211224

212225
case key
213226
when :ratio_in_zjit
@@ -219,7 +232,7 @@ def print_counters(keys, buf:, stats:)
219232
value = number_with_delimiter(value)
220233
end
221234

222-
buf << "#{"%-#{left_pad}s" % "#{key}:"} #{value}\n"
235+
buf << "%#{key_align}*s %*s%s\n" % [key_pad, "#{key}:", value_pad, value, ratio]
223236
end
224237
end
225238

zjit/src/codegen.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,7 @@ fn gen_patch_point(jit: &mut JITState, asm: &mut Assembler, invariant: &Invarian
661661
/// Lowering for [`Insn::CCall`]. This is a low-level raw call that doesn't know
662662
/// anything about the callee, so handling for e.g. GC safety is dealt with elsewhere.
663663
fn gen_ccall(asm: &mut Assembler, cfun: *const u8, args: Vec<Opnd>) -> lir::Opnd {
664+
gen_incr_counter(asm, Counter::inline_cfunc_optimized_send_count);
664665
asm.ccall(cfun, args)
665666
}
666667

@@ -675,6 +676,8 @@ fn gen_ccall_variadic(
675676
cme: *const rb_callable_method_entry_t,
676677
state: &FrameState,
677678
) -> lir::Opnd {
679+
gen_incr_counter(asm, Counter::variadic_cfunc_optimized_send_count);
680+
678681
gen_prepare_non_leaf_call(jit, asm, state);
679682

680683
let stack_growth = state.stack_size();
@@ -1051,6 +1054,8 @@ fn gen_send_without_block_direct(
10511054
args: Vec<Opnd>,
10521055
state: &FrameState,
10531056
) -> lir::Opnd {
1057+
gen_incr_counter(asm, Counter::iseq_optimized_send_count);
1058+
10541059
let local_size = unsafe { get_iseq_body_local_table_size(iseq) }.as_usize();
10551060
let stack_growth = state.stack_size() + local_size + unsafe { get_iseq_body_stack_max(iseq) }.as_usize();
10561061
gen_stack_overflow_check(jit, asm, state, stack_growth);

zjit/src/stats.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ macro_rules! make_counters {
2121
dynamic_send {
2222
$($dynamic_send_counter_name:ident,)+
2323
}
24+
optimized_send {
25+
$($optimized_send_counter_name:ident,)+
26+
}
2427
$($counter_name:ident,)+
2528
) => {
2629
/// Struct containing the counter values
@@ -29,6 +32,7 @@ macro_rules! make_counters {
2932
$(pub $default_counter_name: u64,)+
3033
$(pub $exit_counter_name: u64,)+
3134
$(pub $dynamic_send_counter_name: u64,)+
35+
$(pub $optimized_send_counter_name: u64,)+
3236
$(pub $counter_name: u64,)+
3337
}
3438

@@ -39,6 +43,7 @@ macro_rules! make_counters {
3943
$($default_counter_name,)+
4044
$($exit_counter_name,)+
4145
$($dynamic_send_counter_name,)+
46+
$($optimized_send_counter_name,)+
4247
$($counter_name,)+
4348
}
4449

@@ -48,6 +53,7 @@ macro_rules! make_counters {
4853
$( Counter::$default_counter_name => stringify!($default_counter_name).to_string(), )+
4954
$( Counter::$exit_counter_name => stringify!($exit_counter_name).to_string(), )+
5055
$( Counter::$dynamic_send_counter_name => stringify!($dynamic_send_counter_name).to_string(), )+
56+
$( Counter::$optimized_send_counter_name => stringify!($optimized_send_counter_name).to_string(), )+
5157
$( Counter::$counter_name => stringify!($counter_name).to_string(), )+
5258
}
5359
}
@@ -60,6 +66,7 @@ macro_rules! make_counters {
6066
$( Counter::$default_counter_name => std::ptr::addr_of_mut!(counters.$default_counter_name), )+
6167
$( Counter::$exit_counter_name => std::ptr::addr_of_mut!(counters.$exit_counter_name), )+
6268
$( Counter::$dynamic_send_counter_name => std::ptr::addr_of_mut!(counters.$dynamic_send_counter_name), )+
69+
$( Counter::$optimized_send_counter_name => std::ptr::addr_of_mut!(counters.$optimized_send_counter_name), )+
6370
$( Counter::$counter_name => std::ptr::addr_of_mut!(counters.$counter_name), )+
6471
}
6572
}
@@ -80,6 +87,11 @@ macro_rules! make_counters {
8087
$( Counter::$dynamic_send_counter_name, )+
8188
];
8289

90+
/// List of other counters that are summed as optimized_send_count.
91+
pub const OPTIMIZED_SEND_COUNTERS: &'static [Counter] = &[
92+
$( Counter::$optimized_send_counter_name, )+
93+
];
94+
8395
/// List of other counters that are available only for --zjit-stats.
8496
pub const OTHER_COUNTERS: &'static [Counter] = &[
8597
$( Counter::$counter_name, )+
@@ -140,6 +152,13 @@ make_counters! {
140152
send_fallback_not_optimized_instruction,
141153
}
142154

155+
// Optimized send counters that are summed as optimized_send_count
156+
optimized_send {
157+
iseq_optimized_send_count,
158+
inline_cfunc_optimized_send_count,
159+
variadic_cfunc_optimized_send_count,
160+
}
161+
143162
// compile_error_: Compile error reasons
144163
compile_error_iseq_stack_too_large,
145164
compile_error_exception_handler,
@@ -421,6 +440,16 @@ pub extern "C" fn rb_zjit_stats(_ec: EcPtr, _self: VALUE, target_key: VALUE) ->
421440
}
422441
set_stat_usize!(hash, "dynamic_send_count", dynamic_send_count);
423442

443+
// Set optimized send counters
444+
let mut optimized_send_count = 0;
445+
for &counter in OPTIMIZED_SEND_COUNTERS {
446+
let count = unsafe { *counter_ptr(counter) };
447+
optimized_send_count += count;
448+
set_stat_usize!(hash, &counter.name(), count);
449+
}
450+
set_stat_usize!(hash, "optimized_send_count", optimized_send_count);
451+
set_stat_usize!(hash, "send_count", dynamic_send_count + optimized_send_count);
452+
424453
// Set send fallback counters for NotOptimizedInstruction
425454
let send_fallback_counters = ZJITState::get_send_fallback_counters();
426455
for (op_idx, count) in send_fallback_counters.iter().enumerate().take(VM_INSTRUCTION_SIZE as usize) {

0 commit comments

Comments
 (0)