summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2023-12-06 15:20:05 -0500
committerAlan Wu <XrXr@users.noreply.github.com>2023-12-06 16:42:53 -0500
commit9d9865d9bc2f563c2c600ec53cc71926441b973f (patch)
tree8f6ab26401b01cfe4eac27d55e3380dbe9574f31
parentc5a4409f20e816d3777ebd2c23b894022342a975 (diff)
YJIT: Add some object validity assertions
We've seen quite a few compaction bugs lately, and these assertions should give clearer symptoms. We only call class_of() on objects that the Ruby code can see.
-rw-r--r--yjit/src/codegen.rs2
-rw-r--r--yjit/src/cruby.rs9
2 files changed, 9 insertions, 2 deletions
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index aa06537505..42a52432c3 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -7097,6 +7097,8 @@ fn gen_send_general(
let recv_idx = argc + if flags & VM_CALL_ARGS_BLOCKARG != 0 { 1 } else { 0 };
let comptime_recv = jit.peek_at_stack(&asm.ctx, recv_idx as isize);
let comptime_recv_klass = comptime_recv.class_of();
+ assert_eq!(RUBY_T_CLASS, comptime_recv_klass.builtin_type(),
+ "objects visible to ruby code should have a T_CLASS in their klass field");
// Points to the receiver operand on the stack
let recv = asm.stack_opnd(recv_idx);
diff --git a/yjit/src/cruby.rs b/yjit/src/cruby.rs
index a9e35cdbdd..e4b5392cfe 100644
--- a/yjit/src/cruby.rs
+++ b/yjit/src/cruby.rs
@@ -140,7 +140,6 @@ extern "C" {
// Renames
pub use rb_insn_name as raw_insn_name;
pub use rb_insn_len as raw_insn_len;
-pub use rb_yarv_class_of as CLASS_OF;
pub use rb_get_ec_cfp as get_ec_cfp;
pub use rb_get_cfp_iseq as get_cfp_iseq;
pub use rb_get_cfp_pc as get_cfp_pc;
@@ -406,7 +405,13 @@ impl VALUE {
}
pub fn class_of(self) -> VALUE {
- unsafe { CLASS_OF(self) }
+ if !self.special_const_p() {
+ let builtin_type = self.builtin_type();
+ assert_ne!(builtin_type, RUBY_T_NONE, "YJIT should only see live objects");
+ assert_ne!(builtin_type, RUBY_T_MOVED, "YJIT should only see live objects");
+ }
+
+ unsafe { rb_yarv_class_of(self) }
}
pub fn is_frozen(self) -> bool {