YJIT: In stats, group by resolved C method name

Previously, in the "Top-N most frequent C calls"
section of --yjit-stats output, we printed the class
name of the receiver, not the method owner. This meant
that calls on subclass instances that land on the same
method showed up as different entires.

Similarly, method called using an alias showed up as
different entries from other aliases.

Group by the resolved method instead.

Test program:

    1.itself; [].itself; true.inspect; true.to_s

Before:

    Top-4 most frequent C calls (80.0% of C calls):
      1 (20.0%): Integer#itself
      1 (20.0%): TrueClass#to_s
      1 (20.0%): TrueClass#inspect
      1 (20.0%): Array#itself

After:

    Top-2 most frequent C calls (80.0% of C calls):
      2 (40.0%): Kernel#itself
      2 (40.0%): TrueClass#to_s
This commit is contained in:
Alan Wu 2024-10-17 16:08:34 -04:00
parent 158b8cb52e
commit cb39283cbf
Notes: git 2024-10-17 21:59:44 +00:00

View File

@ -6871,8 +6871,8 @@ fn gen_send_cfunc(
// We also do this after the C call to minimize the impact of spill_temps() on asm.ccall().
if get_option!(gen_stats) {
// Assemble the method name string
let mid = unsafe { vm_ci_mid(ci) };
let name_str = get_method_name(recv_known_class, mid);
let mid = unsafe { rb_get_def_original_id((*cme).def) };
let name_str = get_method_name(Some(unsafe { (*cme).owner }), mid);
// Get an index for this cfunc name
let cfunc_idx = get_cfunc_idx(&name_str);
@ -9099,7 +9099,10 @@ fn gen_send_general(
/// Get class name from a class pointer.
fn get_class_name(class: Option<VALUE>) -> String {
class.and_then(|class| unsafe {
class.filter(|&class| {
// type checks for rb_class2name()
unsafe { RB_TYPE_P(class, RUBY_T_MODULE) || RB_TYPE_P(class, RUBY_T_CLASS) }
}).and_then(|class| unsafe {
cstr_to_rust_string(rb_class2name(class))
}).unwrap_or_else(|| "Unknown".to_string())
}