From cb39283cbfcfeb920fff66d3ef77e4ed7f2f8d93 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Thu, 17 Oct 2024 16:08:34 -0400 Subject: [PATCH] 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 --- yjit/src/codegen.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 82ec10b074..86f39414a9 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -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) -> 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()) }