diff options
author | Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> | 2023-02-02 16:54:16 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-02 16:54:16 -0500 |
commit | 73674cac2bbb2616a182305f4719844c59816e21 (patch) | |
tree | 2fff89fff390860ba7ea3b5f4919e91499ed06b1 | |
parent | 92ac5f686b72942c9709a8f3e07f45f6a44ebc6b (diff) | |
download | ruby-73674cac2bbb2616a182305f4719844c59816e21.tar.gz |
YJIT: log the names of methods we call to in disasm (#7231)
* YJIT: log the names of methods we call to in disasm
* Assert that pointer is not null
* Handle case where UTF8 conversion not possible
-rw-r--r-- | yjit/bindgen/src/main.rs | 4 | ||||
-rw-r--r-- | yjit/src/codegen.rs | 16 | ||||
-rw-r--r-- | yjit/src/cruby.rs | 15 | ||||
-rw-r--r-- | yjit/src/cruby_bindings.inc.rs | 2 |
4 files changed, 33 insertions, 4 deletions
diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index 8d29d42bf7..3086d6b860 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -77,6 +77,9 @@ fn main() { // From encindex.h .allowlist_type("ruby_preserved_encindex") + // From include/ruby/ruby.h + .allowlist_function("rb_class2name") + // This struct is public to Ruby C extensions // From include/ruby/internal/core/rbasic.h .allowlist_type("RBasic") @@ -202,6 +205,7 @@ fn main() { // From include/ruby/internal/symbol.h .allowlist_function("rb_intern") .allowlist_function("rb_id2sym") + .allowlist_function("rb_id2name") .allowlist_function("rb_sym2id") .allowlist_function("rb_str_intern") diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 1f975af849..d652f6b07d 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -5668,9 +5668,6 @@ fn gen_send_iseq( }, ); - //print_str(cb, "calling Ruby func:"); - //print_str(cb, rb_id2name(vm_ci_mid(ci))); - // Directly jump to the entry point of the callee gen_direct_jump( jit, @@ -5831,6 +5828,19 @@ fn gen_send_general( let comptime_recv = jit_peek_at_stack(jit, ctx, recv_idx as isize); let comptime_recv_klass = comptime_recv.class_of(); + // Log the name of the method we're calling to + #[cfg(feature = "disasm")] + { + let class_name = unsafe { cstr_to_rust_string(rb_class2name(comptime_recv_klass)) }; + let method_name = unsafe { cstr_to_rust_string(rb_id2name(mid)) }; + match (class_name, method_name) { + (Some(class_name), Some(method_name)) => { + asm.comment(&format!("call to {}#{}", class_name, method_name)) + } + _ => {} + } + } + // Guard that the receiver has the same class as the one from compile time let side_exit = get_side_exit(jit, ocb, ctx); diff --git a/yjit/src/cruby.rs b/yjit/src/cruby.rs index 4c4cba0d58..570cc24719 100644 --- a/yjit/src/cruby.rs +++ b/yjit/src/cruby.rs @@ -564,10 +564,23 @@ pub fn rust_str_to_ruby(str: &str) -> VALUE { pub fn rust_str_to_sym(str: &str) -> VALUE { let c_str = CString::new(str).unwrap(); let c_ptr: *const c_char = c_str.as_ptr(); - unsafe { rb_id2sym(rb_intern(c_ptr)) } } +/// Produce an owned Rust String from a C char pointer +#[cfg(feature = "disasm")] +pub fn cstr_to_rust_string(c_char_ptr: *const c_char) -> Option<String> { + assert!(c_char_ptr != std::ptr::null()); + + use std::ffi::CStr; + let c_str: &CStr = unsafe { CStr::from_ptr(c_char_ptr) }; + + match c_str.to_str() { + Ok(rust_str) => Some(rust_str.to_string()), + Err(_) => None + } +} + /// A location in Rust code for integrating with debugging facilities defined in C. /// Use the [src_loc!] macro to crate an instance. pub struct SourceLocation { diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index a405d2aca6..a9d8009cb0 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -1101,6 +1101,8 @@ extern "C" { pub fn rb_sym2id(obj: VALUE) -> ID; pub fn rb_id2sym(id: ID) -> VALUE; pub fn rb_intern(name: *const ::std::os::raw::c_char) -> ID; + pub fn rb_id2name(id: ID) -> *const ::std::os::raw::c_char; + pub fn rb_class2name(klass: VALUE) -> *const ::std::os::raw::c_char; pub fn rb_gc_mark(obj: VALUE); pub fn rb_gc_mark_movable(obj: VALUE); pub fn rb_gc_location(obj: VALUE) -> VALUE; |