mirror of
https://github.com/ruby/ruby.git
synced 2026-01-27 04:24:23 +00:00
ZJIT: Include GC object dump when seeing dead objects
Strictly more info than just the builtin_type from `assert_ne!`.
Old:
assertion `left != right` failed: ZJIT should only see live objects
left: 0
right: 0
New:
ZJIT saw a dead object. T_type=0, out-of-heap:0x0000000110d4bb40
Also, the new `VALUE::obj_info` is more flexible for print debugging than the
dump_info() it replaces. It now allows you to use it as part of a `format!`
string instead of always printing to stderr for you.
This commit is contained in:
parent
8d43867802
commit
5bda42e4de
Notes:
git
2025-10-15 02:35:22 +00:00
@ -82,7 +82,7 @@ fn main() {
|
||||
.allowlist_type("ruby_rstring_flags")
|
||||
|
||||
// This function prints info about a value and is useful for debugging
|
||||
.allowlist_function("rb_obj_info_dump")
|
||||
.allowlist_function("rb_raw_obj_info")
|
||||
|
||||
.allowlist_function("ruby_init")
|
||||
.allowlist_function("ruby_init_stack")
|
||||
|
||||
@ -90,7 +90,7 @@
|
||||
|
||||
use std::convert::From;
|
||||
use std::ffi::{c_void, CString, CStr};
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::os::raw::{c_char, c_int, c_uint};
|
||||
use std::panic::{catch_unwind, UnwindSafe};
|
||||
|
||||
@ -400,10 +400,27 @@ pub enum ClassRelationship {
|
||||
NoRelation,
|
||||
}
|
||||
|
||||
/// A print adapator for debug info about a [VALUE]. Includes info
|
||||
/// the GC knows about the handle. Example: `println!("{}", value.obj_info());`.
|
||||
pub struct ObjInfoPrinter(VALUE);
|
||||
|
||||
impl Display for ObjInfoPrinter {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
use std::mem::MaybeUninit;
|
||||
const BUFFER_SIZE: usize = 0x100;
|
||||
let mut buffer: MaybeUninit<[c_char; BUFFER_SIZE]> = MaybeUninit::uninit();
|
||||
let info = unsafe {
|
||||
rb_raw_obj_info(buffer.as_mut_ptr().cast(), BUFFER_SIZE, self.0);
|
||||
CStr::from_ptr(buffer.as_ptr().cast()).to_string_lossy()
|
||||
};
|
||||
write!(f, "{info}")
|
||||
}
|
||||
}
|
||||
|
||||
impl VALUE {
|
||||
/// Dump info about the value to the console similarly to rp(VALUE)
|
||||
pub fn dump_info(self) {
|
||||
unsafe { rb_obj_info_dump(self) }
|
||||
/// Get a printer for raw debug info from `rb_obj_info()` about the value.
|
||||
pub fn obj_info(self) -> ObjInfoPrinter {
|
||||
ObjInfoPrinter(self)
|
||||
}
|
||||
|
||||
/// Return whether the value is truthy or falsy in Ruby -- only nil and false are falsy.
|
||||
@ -507,8 +524,11 @@ impl VALUE {
|
||||
pub fn class_of(self) -> VALUE {
|
||||
if !self.special_const_p() {
|
||||
let builtin_type = self.builtin_type();
|
||||
assert_ne!(builtin_type, RUBY_T_NONE, "ZJIT should only see live objects");
|
||||
assert_ne!(builtin_type, RUBY_T_MOVED, "ZJIT should only see live objects");
|
||||
assert!(
|
||||
builtin_type != RUBY_T_NONE && builtin_type != RUBY_T_MOVED,
|
||||
"ZJIT saw a dead object. T_type={builtin_type}, {}",
|
||||
self.obj_info()
|
||||
);
|
||||
}
|
||||
|
||||
unsafe { rb_yarv_class_of(self) }
|
||||
|
||||
6
zjit/src/cruby_bindings.inc.rs
generated
6
zjit/src/cruby_bindings.inc.rs
generated
@ -839,7 +839,6 @@ unsafe extern "C" {
|
||||
pub fn rb_ivar_set(obj: VALUE, name: ID, val: VALUE) -> VALUE;
|
||||
pub fn rb_ivar_defined(obj: VALUE, name: ID) -> VALUE;
|
||||
pub fn rb_attr_get(obj: VALUE, name: ID) -> VALUE;
|
||||
pub fn rb_obj_info_dump(obj: VALUE);
|
||||
pub fn rb_class_allocate_instance(klass: VALUE) -> VALUE;
|
||||
pub fn rb_obj_equal(obj1: VALUE, obj2: VALUE) -> VALUE;
|
||||
pub fn rb_reg_new_ary(ary: VALUE, options: ::std::os::raw::c_int) -> VALUE;
|
||||
@ -872,6 +871,11 @@ unsafe extern "C" {
|
||||
cfp: *const rb_control_frame_t,
|
||||
) -> *const rb_callable_method_entry_t;
|
||||
pub fn rb_obj_info(obj: VALUE) -> *const ::std::os::raw::c_char;
|
||||
pub fn rb_raw_obj_info(
|
||||
buff: *mut ::std::os::raw::c_char,
|
||||
buff_size: usize,
|
||||
obj: VALUE,
|
||||
) -> *const ::std::os::raw::c_char;
|
||||
pub fn rb_ec_stack_check(ec: *mut rb_execution_context_struct) -> ::std::os::raw::c_int;
|
||||
pub fn rb_gc_writebarrier_remember(obj: VALUE);
|
||||
pub fn rb_shape_id_offset() -> i32;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user