Skip to content

Commit

Permalink
YJIT: Add JIT compilation of C function substitutions to the compilat…
Browse files Browse the repository at this point in the history
…ion log.
  • Loading branch information
nirvdrum committed Oct 4, 2024
1 parent a36d307 commit 0ee4371
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 12 deletions.
6 changes: 5 additions & 1 deletion yjit/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -9075,7 +9079,7 @@ fn get_class_name(class: Option<VALUE>) -> String {
}

/// Assemble "{class_name}#{method_name}" from a class pointer and a method ID
fn get_method_name(class: Option<VALUE>, mid: u64) -> String {
pub fn get_method_name(class: Option<VALUE>, mid: u64) -> String {
let class_name = get_class_name(class);
let method_name = if mid != 0 {
unsafe { cstr_to_rust_string(rb_id2name(mid)) }
Expand Down
50 changes: 40 additions & 10 deletions yjit/src/compilation_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<VALUE>, 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, "<cfunc> {}", 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)
}
}

Expand All @@ -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<VALUE>, method_id: ID) {
Self::add_payload(CompilationLogPayload::CFunc(class, method_id))
}

fn add_payload(payload: CompilationLogPayload) {
if !Self::has_instance() {
return;
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion yjit/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down

0 comments on commit 0ee4371

Please sign in to comment.