Skip to content

Commit

Permalink
YJIT: add counters for polymorphic send and send with known class (#7288
Browse files Browse the repository at this point in the history
)
  • Loading branch information
maximecb committed Feb 10, 2023
1 parent 7ece23b commit a7e8eab
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 23 deletions.
29 changes: 18 additions & 11 deletions yjit.rb
Expand Up @@ -253,9 +253,12 @@ def _print_stats # :nodoc:
# Number of failed compiler invocations
compilation_failure = stats[:compilation_failure]

if stats[:x86_call_rel32] != 0 || stats[:x86_call_reg] != 0
$stderr.puts "x86_call_rel32: " + format_number(10, stats[:x86_call_rel32])
$stderr.puts "x86_call_reg: " + format_number(10, stats[:x86_call_reg])
$stderr.puts "num_send: " + format_number(10, stats[:num_send])
$stderr.puts "num_send_known_class: " + format_number_pct(10, stats[:num_send_known_class], stats[:num_send])
$stderr.puts "num_send_polymorphic: " + format_number_pct(10, stats[:num_send_polymorphic], stats[:num_send])
if stats[:num_send_x86_rel32] != 0 || stats[:num_send_x86_reg] != 0
$stderr.puts "num_send_x86_rel32: " + format_number(10, stats[:num_send_x86_rel32])
$stderr.puts "num_send_x86_reg: " + format_number(10, stats[:num_send_x86_reg])
end

$stderr.puts "bindings_allocations: " + format_number(10, stats[:binding_allocations])
Expand Down Expand Up @@ -315,10 +318,8 @@ def print_sorted_exit_counts(stats, prefix:, how_many: 20, left_pad: 4) # :nodoc
exits.each do |name, count|
padding = longest_insn_name_len + left_pad
padded_name = "%#{padding}s" % name
padded_count = format_number(10, count)
percent = 100.0 * count / total_exits
formatted_percent = "%.1f" % percent
$stderr.puts("#{padded_name}: #{padded_count} (#{formatted_percent}%)" )
padded_count = format_number_pct(10, count, total_exits)
$stderr.puts("#{padded_name}: #{padded_count}")
end
else
$stderr.puts "total_exits: " + format_number(10, total_exits)
Expand Down Expand Up @@ -350,11 +351,9 @@ def print_counters(counters, prefix:, prompt:) # :nodoc:
total = counters.sum { |(_, counter_value)| counter_value }

counters.reverse_each do |(name, value)|
percentage = value.fdiv(total) * 100
padded_name = name.rjust(longest_name_length, ' ')
padded_count = format_number(10, value)
formatted_pct = "%4.1f%%" % percentage
$stderr.puts(" #{padded_name}: #{padded_count} (#{formatted_pct})")
padded_count = format_number_pct(10, value, total)
$stderr.puts(" #{padded_name}: #{padded_count}")
end
end

Expand All @@ -366,5 +365,13 @@ def format_number(pad, number)
formatted = [with_commas, decimal].compact.join(".")
formatted.rjust(pad, ' ')
end

# Format a number along with a percentage over a total value
def format_number_pct(pad, number, total)
padded_count = format_number(pad, number)
percentage = number.fdiv(total) * 100
formatted_pct = "%4.1f%%" % percentage
"#{padded_count} (#{formatted_pct})"
end
end
end
4 changes: 2 additions & 2 deletions yjit/src/asm/x86_64/mod.rs
Expand Up @@ -700,13 +700,13 @@ pub fn call_ptr(cb: &mut CodeBlock, scratch_opnd: X86Opnd, dst_ptr: *const u8) {

// If the offset fits in 32-bit
if rel64 >= i32::MIN.into() && rel64 <= i32::MAX.into() {
incr_counter!(x86_call_rel32);
incr_counter!(num_send_x86_rel32);
call_rel32(cb, rel64.try_into().unwrap());
return;
}

// Move the pointer into the scratch register and call
incr_counter!(x86_call_reg);
incr_counter!(num_send_x86_reg);
mov(cb, scratch_opnd, const_ptr_opnd(dst_ptr));
call(cb, scratch_opnd);
} else {
Expand Down
23 changes: 15 additions & 8 deletions yjit/src/codegen.rs
Expand Up @@ -5205,7 +5205,6 @@ fn gen_send_iseq(
}
}


if flags & VM_CALL_ARGS_SPLAT != 0 && flags & VM_CALL_ZSUPER != 0 {
// zsuper methods are super calls without any arguments.
// They are also marked as splat, but don't actually have an array
Expand Down Expand Up @@ -5933,10 +5932,16 @@ fn gen_send_general(
}

let recv_idx = argc + if flags & VM_CALL_ARGS_BLOCKARG != 0 { 1 } else { 0 };

let comptime_recv = jit_peek_at_stack(jit, ctx, recv_idx as isize);
let comptime_recv_klass = comptime_recv.class_of();

// Guard that the receiver has the same class as the one from compile time
let side_exit = get_side_exit(jit, ocb, ctx);

// Points to the receiver operand on the stack
let recv = ctx.stack_opnd(recv_idx);
let recv_opnd = StackOpnd(recv_idx.try_into().unwrap());

// Log the name of the method we're calling to
#[cfg(feature = "disasm")]
{
Expand All @@ -5950,12 +5955,14 @@ fn gen_send_general(
}
}

// Guard that the receiver has the same class as the one from compile time
let side_exit = get_side_exit(jit, ocb, ctx);

// Points to the receiver operand on the stack
let recv = ctx.stack_opnd(recv_idx);
let recv_opnd = StackOpnd(recv_idx.try_into().unwrap());
// Gather some statistics about sends
gen_counter_incr!(asm, num_send);
if let Some(_known_klass) = ctx.get_opnd_type(recv_opnd).known_class() {
gen_counter_incr!(asm, num_send_known_class);
}
if ctx.get_chain_depth() > 1 {
gen_counter_incr!(asm, num_send_polymorphic);
}

let megamorphic_exit = counted_exit!(ocb, side_exit, send_klass_megamorphic);
jit_guard_known_klass(
Expand Down
7 changes: 5 additions & 2 deletions yjit/src/stats.rs
Expand Up @@ -318,8 +318,11 @@ make_counters! {

num_gc_obj_refs,

x86_call_rel32,
x86_call_reg,
num_send,
num_send_known_class,
num_send_polymorphic,
num_send_x86_rel32,
num_send_x86_reg,
}

//===========================================================================
Expand Down

0 comments on commit a7e8eab

Please sign in to comment.