summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>2023-02-02 16:54:16 -0500
committerGitHub <noreply@github.com>2023-02-02 16:54:16 -0500
commit73674cac2bbb2616a182305f4719844c59816e21 (patch)
tree2fff89fff390860ba7ea3b5f4919e91499ed06b1
parent92ac5f686b72942c9709a8f3e07f45f6a44ebc6b (diff)
downloadruby-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.rs4
-rw-r--r--yjit/src/codegen.rs16
-rw-r--r--yjit/src/cruby.rs15
-rw-r--r--yjit/src/cruby_bindings.inc.rs2
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;