diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index 996d7fa1c0..23b32afbd0 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -318,7 +318,8 @@ fn main() { // From iseq.h .allowlist_function("rb_vm_insn_addr2opcode") .allowlist_function("rb_iseqw_to_iseq") - .allowlist_function("rb_iseq_method_name") + .allowlist_function("rb_iseq_label") + .allowlist_function("rb_iseq_line_no") // From builtin.h .allowlist_type("rb_builtin_function.*") diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 67ac1007b6..f99c592e18 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -586,7 +586,7 @@ pub fn gen_entry_prologue(cb: &mut CodeBlock, iseq: IseqPtr, insn_idx: u32) -> O let mut asm = Assembler::new(); if get_option_ref!(dump_disasm).is_some() { - asm.comment(&format!("YJIT entry: {}", iseq_get_location(iseq))); + asm.comment(&format!("YJIT entry point: {}", iseq_get_location(iseq, 0))); } else { asm.comment("YJIT entry"); } @@ -720,7 +720,7 @@ pub fn gen_single_block( #[cfg(feature = "disasm")] if get_option_ref!(dump_disasm).is_some() { let blockid_idx = blockid.idx; - asm.comment(&format!("Block: {} (ISEQ offset: {})", iseq_get_location(blockid.iseq), blockid_idx)); + asm.comment(&format!("Block: {} (ISEQ offset: {})", iseq_get_location(blockid.iseq, blockid_idx), blockid_idx)); } // For each instruction to compile diff --git a/yjit/src/core.rs b/yjit/src/core.rs index abe0797257..c0411a94a2 100644 --- a/yjit/src/core.rs +++ b/yjit/src/core.rs @@ -1536,10 +1536,10 @@ fn gen_block_series_body( // If dump_iseq_disasm is active, see if this iseq's location matches the given substring. // If so, we print the new blocks to the console. if let Some(substr) = get_option_ref!(dump_iseq_disasm).as_ref() { - let iseq_location = iseq_get_location(blockid.iseq); + let blockid_idx = blockid.idx; + let iseq_location = iseq_get_location(blockid.iseq, blockid_idx); if iseq_location.contains(substr) { let last_block = last_blockref.borrow(); - let blockid_idx = blockid.idx; println!("Compiling {} block(s) for {}, ISEQ offsets [{}, {})", batch.len(), iseq_location, blockid_idx, last_block.end_idx); print!("{}", disasm_iseq_insn_range(blockid.iseq, blockid.idx, last_block.end_idx)); } @@ -2191,9 +2191,9 @@ pub fn invalidate_block_version(blockref: &BlockRef) { { // If dump_iseq_disasm is specified, print to console that blocks for matching ISEQ names were invalidated. if let Some(substr) = get_option_ref!(dump_iseq_disasm).as_ref() { - let iseq_location = iseq_get_location(block.blockid.iseq); + let blockid_idx = block.blockid.idx; + let iseq_location = iseq_get_location(block.blockid.iseq, blockid_idx); if iseq_location.contains(substr) { - let blockid_idx = block.blockid.idx; println!("Invalidating block from {}, ISEQ offsets [{}, {})", iseq_location, blockid_idx, block.end_idx); } } diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index 9dff8fe3a0..c28518ea38 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -1163,8 +1163,9 @@ extern "C" { pub fn rb_ensure_iv_list_size(obj: VALUE, len: u32, newsize: u32); pub fn rb_vm_insn_decode(encoded: VALUE) -> ::std::os::raw::c_int; pub fn rb_vm_insn_addr2opcode(addr: *const ::std::os::raw::c_void) -> ::std::os::raw::c_int; + pub fn rb_iseq_line_no(iseq: *const rb_iseq_t, pos: usize) -> ::std::os::raw::c_uint; pub fn rb_iseqw_to_iseq(iseqw: VALUE) -> *const rb_iseq_t; - pub fn rb_iseq_method_name(iseq: *const rb_iseq_t) -> VALUE; + pub fn rb_iseq_label(iseq: *const rb_iseq_t) -> VALUE; pub fn rb_vm_barrier(); pub fn rb_profile_frames( start: ::std::os::raw::c_int, diff --git a/yjit/src/utils.rs b/yjit/src/utils.rs index b156c9d5ed..f66000381e 100644 --- a/yjit/src/utils.rs +++ b/yjit/src/utils.rs @@ -86,21 +86,24 @@ fn ruby_str_to_rust(v: VALUE) -> String { // Location is the file defining the method, colon, method name. // Filenames are sometimes internal strings supplied to eval, // so be careful with them. -pub fn iseq_get_location(iseq: IseqPtr) -> String { +pub fn iseq_get_location(iseq: IseqPtr, pos: u32) -> String { + let iseq_label = unsafe { rb_iseq_label(iseq) }; let iseq_path = unsafe { rb_iseq_path(iseq) }; - let iseq_method = unsafe { rb_iseq_method_name(iseq) }; + let iseq_lineno = unsafe { rb_iseq_line_no(iseq, pos as usize) }; - let mut s = if iseq_path == Qnil { + let mut s = if iseq_label == Qnil { "None".to_string() } else { - ruby_str_to_rust(iseq_path) + ruby_str_to_rust(iseq_label) }; - s.push_str(":"); - if iseq_method == Qnil { + s.push_str("@"); + if iseq_path == Qnil { s.push_str("None"); } else { - s.push_str(& ruby_str_to_rust(iseq_method)); + s.push_str(&ruby_str_to_rust(iseq_path)); } + s.push_str(":"); + s.push_str(&iseq_lineno.to_string()); s }