From 0ee4371256e4eea34c761aa0c18582a334aad6f7 Mon Sep 17 00:00:00 2001 From: Kevin Menard Date: Wed, 2 Oct 2024 17:51:28 -0400 Subject: [PATCH] YJIT: Add JIT compilation of C function substitutions to the compilation log. --- yjit/src/codegen.rs | 6 ++++- yjit/src/compilation_log.rs | 50 +++++++++++++++++++++++++++++-------- yjit/src/core.rs | 2 +- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index d706d72c1facdd..0438a04e64f2f6 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -458,6 +458,7 @@ macro_rules! perf_call { } use crate::codegen::JCCKinds::*; +use crate::compilation_log::CompilationLog; #[allow(non_camel_case_types, unused)] pub enum JCCKinds { @@ -6567,6 +6568,9 @@ fn gen_send_cfunc( perf_call!("gen_send_cfunc: ", known_cfunc_codegen(jit, asm, ci, cme, block, argc, recv_known_class)) }; + let method_id = unsafe { (*cme).called_id }; + CompilationLog::add_cfunc(recv_known_class, method_id); + if cfunc_codegen { assert_eq!(expected_stack_after, asm.ctx.get_stack_size() as i32); gen_counter_incr(jit, asm, Counter::num_send_cfunc_inline); @@ -9075,7 +9079,7 @@ fn get_class_name(class: Option) -> String { } /// Assemble "{class_name}#{method_name}" from a class pointer and a method ID -fn get_method_name(class: Option, mid: u64) -> String { +pub fn get_method_name(class: Option, mid: u64) -> String { let class_name = get_class_name(class); let method_name = if mid != 0 { unsafe { cstr_to_rust_string(rb_id2name(mid)) } diff --git a/yjit/src/compilation_log.rs b/yjit/src/compilation_log.rs index f90d423efe35bd..f0abcd6f93c931 100644 --- a/yjit/src/compilation_log.rs +++ b/yjit/src/compilation_log.rs @@ -2,22 +2,44 @@ use crate::core::BlockId; use crate::cruby::*; use crate::options::*; use crate::yjit::yjit_enabled_p; +use crate::codegen::get_method_name; use std::fmt::{Display, Formatter}; use std::os::raw::c_long; -#[derive(Copy, Clone)] -pub struct CompilationLogEntry { - /// The compiled block. - pub block_id: BlockId, +type Timestamp = f64; +#[derive(Copy, Clone, Debug)] +pub struct CompilationLogEntry { /// The time when the block was compiled. - pub timestamp: f64, + pub timestamp: Timestamp, + + /// The compilation event payload. + pub payload: CompilationLogPayload, +} + +#[derive(Copy, Clone, Debug)] +pub enum CompilationLogPayload { + ISeq(BlockId), + CFunc(Option, ID) +} + +impl Display for CompilationLogPayload { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + CompilationLogPayload::ISeq(block_id) => { + write!(f, "{}", block_id.iseq_name()) + } + CompilationLogPayload::CFunc(class, method_id) => { + write!(f, " {}", get_method_name(*class, *method_id)) + } + } + } } impl Display for CompilationLogEntry { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{:15.6}: {}", self.timestamp, self.block_id.iseq_name()) + write!(f, "{:15.6}: {}", self.timestamp, self.payload) } } @@ -43,7 +65,15 @@ impl CompilationLog { } } - pub fn add_entry(block_id: BlockId) { + pub fn add_iseq(block_id: BlockId) { + Self::add_payload(CompilationLogPayload::ISeq(block_id)) + } + + pub fn add_cfunc(class: Option, method_id: ID) { + Self::add_payload(CompilationLogPayload::CFunc(class, method_id)) + } + + fn add_payload(payload: CompilationLogPayload) { if !Self::has_instance() { return; } @@ -52,8 +82,8 @@ impl CompilationLog { let timestamp = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs_f64(); let entry = CompilationLogEntry { - block_id, - timestamp + timestamp, + payload }; match print_compilation_log { @@ -203,7 +233,7 @@ fn rb_yjit_get_compilation_log_array() -> VALUE { for entry in log.iter() { unsafe { let entry_array = rb_ary_new_capa(2); - rb_ary_push(entry_array, entry.block_id.iseq_name().into()); + rb_ary_push(entry_array, entry.payload.to_string().into()); rb_ary_push(entry_array, rb_float_new(entry.timestamp)); rb_ary_push(array, entry_array); } diff --git a/yjit/src/core.rs b/yjit/src/core.rs index f51da53f2cf35f..14716812f0219e 100644 --- a/yjit/src/core.rs +++ b/yjit/src/core.rs @@ -3234,7 +3234,7 @@ pub fn gen_entry_point(iseq: IseqPtr, ec: EcPtr, jit_exception: bool) -> Option< // Count the number of entry points we compile incr_counter!(compiled_iseq_entry); - CompilationLog::add_entry(blockid); + CompilationLog::add_iseq(blockid); // Compilation successful and block not empty code_ptr.map(|ptr| ptr.raw_ptr(cb))