diff options
-rw-r--r-- | shape.c | 6 | ||||
-rw-r--r-- | shape.h | 1 | ||||
-rw-r--r-- | yjit/bindgen/src/main.rs | 2 | ||||
-rw-r--r-- | yjit/src/asm/arm64/mod.rs | 2 | ||||
-rw-r--r-- | yjit/src/backend/arm64/mod.rs | 19 | ||||
-rw-r--r-- | yjit/src/backend/ir.rs | 6 | ||||
-rw-r--r-- | yjit/src/codegen.rs | 15 | ||||
-rw-r--r-- | yjit/src/cruby_bindings.inc.rs | 6 |
8 files changed, 35 insertions, 22 deletions
@@ -325,10 +325,10 @@ rb_shape_set_shape(VALUE obj, rb_shape_t* shape) rb_shape_set_shape_id(obj, rb_shape_id(shape)); } -VALUE -rb_shape_flags_mask(void) +uint8_t +rb_shape_id_num_bits(void) { - return SHAPE_FLAG_MASK; + return SHAPE_ID_NUM_BITS; } rb_shape_t * @@ -132,6 +132,7 @@ static inline shape_id_t RCLASS_SHAPE_ID(VALUE obj) { bool rb_shape_root_shape_p(rb_shape_t* shape); rb_shape_t * rb_shape_get_root_shape(void); +uint8_t rb_shape_id_num_bits(void); rb_shape_t* rb_shape_get_shape_by_id_without_assertion(shape_id_t shape_id); rb_shape_t * rb_shape_get_parent(rb_shape_t * shape); diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index 2b94d95608..9afba864d2 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -85,7 +85,7 @@ fn main() { // From shape.h .allowlist_function("rb_shape_get_shape_id") .allowlist_function("rb_shape_get_shape_by_id") - .allowlist_function("rb_shape_flags_mask") + .allowlist_function("rb_shape_id_num_bits") .allowlist_function("rb_shape_get_iv_index") // From ruby/internal/intern/object.h diff --git a/yjit/src/asm/arm64/mod.rs b/yjit/src/asm/arm64/mod.rs index 683711259e..d463613943 100644 --- a/yjit/src/asm/arm64/mod.rs +++ b/yjit/src/asm/arm64/mod.rs @@ -540,8 +540,6 @@ pub fn ldur(cb: &mut CodeBlock, rt: A64Opnd, rn: A64Opnd) { pub fn ldurh(cb: &mut CodeBlock, rt: A64Opnd, rn: A64Opnd) { let bytes: [u8; 4] = match (rt, rn) { (A64Opnd::Reg(rt), A64Opnd::Mem(rn)) => { - assert!(rt.num_bits == 32, "Rt should be a 32 bit register"); - assert!(rn.num_bits == 64, "Rn should be a 64 bit register"); assert!(mem_disp_fits_bits(rn.disp), "Expected displacement to be 9 bits or less"); LoadStore::ldurh(rt.reg_no, rn.base_reg_no, rn.disp as i16).into() diff --git a/yjit/src/backend/arm64/mod.rs b/yjit/src/backend/arm64/mod.rs index c899f6871f..cbda5eec05 100644 --- a/yjit/src/backend/arm64/mod.rs +++ b/yjit/src/backend/arm64/mod.rs @@ -344,7 +344,14 @@ impl Assembler Insn::Cmp { left, right } => { let opnd0 = split_load_operand(asm, left); let opnd0 = split_less_than_32_cmp(asm, opnd0); - let opnd1 = split_shifted_immediate(asm, right); + let split_right = split_shifted_immediate(asm, right); + let opnd1 = match split_right { + Opnd::InsnOut { .. } if opnd0.num_bits() != split_right.num_bits() => { + split_right.with_num_bits(opnd0.num_bits().unwrap()).unwrap() + }, + _ => split_right + }; + asm.cmp(opnd0, opnd1); }, Insn::CRet(opnd) => { @@ -828,6 +835,7 @@ impl Assembler Opnd::Mem(_) => { match opnd.rm_num_bits() { 64 | 32 => ldur(cb, out.into(), opnd.into()), + 16 => ldurh(cb, out.into(), opnd.into()), 8 => ldurb(cb, out.into(), opnd.into()), num_bits => panic!("unexpected num_bits: {}", num_bits) }; @@ -1357,6 +1365,15 @@ mod tests { } #[test] + fn test_32_bit_register_with_some_number() { + let (mut asm, mut cb) = setup_asm(); + + let shape_opnd = Opnd::mem(32, Opnd::Reg(X0_REG), 6); + asm.cmp(shape_opnd, Opnd::UImm(4097)); + asm.compile_with_num_regs(&mut cb, 2); + } + + #[test] fn test_emit_xor() { let (mut asm, mut cb) = setup_asm(); diff --git a/yjit/src/backend/ir.rs b/yjit/src/backend/ir.rs index 0aa087630d..973fe89b6d 100644 --- a/yjit/src/backend/ir.rs +++ b/yjit/src/backend/ir.rs @@ -109,8 +109,8 @@ impl Opnd }) }, - Opnd::InsnOut{idx, num_bits } => { - assert!(num_bits == 64); + Opnd::InsnOut{idx, num_bits: out_num_bits } => { + assert!(num_bits <= out_num_bits); Opnd::Mem(Mem { base: MemBase::InsnOut(idx), disp: disp, @@ -143,7 +143,7 @@ impl Opnd } /// Get the size in bits for this operand if there is one. - fn num_bits(&self) -> Option<u8> { + pub fn num_bits(&self) -> Option<u8> { match *self { Opnd::Reg(Reg { num_bits, .. }) => Some(num_bits), Opnd::Mem(Mem { num_bits, .. }) => Some(num_bits), diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index be4fc423b6..c66a293322 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -2040,16 +2040,13 @@ fn gen_get_ivar( // Compile time self is embedded and the ivar index lands within the object let embed_test_result = unsafe { FL_TEST_RAW(comptime_receiver, VALUE(ROBJECT_EMBED.as_usize())) != VALUE(0) }; - let flags_mask: usize = unsafe { rb_shape_flags_mask() }.as_usize(); - let expected_flags_mask: usize = (RUBY_T_MASK as usize) | !flags_mask | (ROBJECT_EMBED as usize); - let expected_flags = comptime_receiver.builtin_flags() & expected_flags_mask; + let expected_shape = unsafe { rb_shape_get_shape_id(comptime_receiver) }; + let shape_bit_size = unsafe { rb_shape_id_num_bits() }; // either 16 or 32 depending on RUBY_DEBUG + let shape_byte_size = shape_bit_size / 8; + let shape_opnd = Opnd::mem(shape_bit_size, recv, RUBY_OFFSET_RBASIC_FLAGS + (8 - shape_byte_size as i32)); - // Combined guard for all flags: shape, embeddedness, and T_OBJECT - let flags_opnd = Opnd::mem(64, recv, RUBY_OFFSET_RBASIC_FLAGS); - - asm.comment("guard shape, embedded, and T_OBJECT"); - let flags_opnd = asm.and(flags_opnd, Opnd::UImm(expected_flags_mask as u64)); - asm.cmp(flags_opnd, Opnd::UImm(expected_flags as u64)); + asm.comment("guard shape"); + asm.cmp(shape_opnd, Opnd::UImm(expected_shape as u64)); let megamorphic_side_exit = counted_exit!(ocb, side_exit, getivar_megamorphic).into(); jit_chain_guard( JCC_JNE, diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index 17e5a84c3c..78967cd4ce 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -425,6 +425,9 @@ pub struct rb_shape { } pub type rb_shape_t = rb_shape; extern "C" { + pub fn rb_shape_id_num_bits() -> u8; +} +extern "C" { pub fn rb_shape_get_shape_by_id(shape_id: shape_id_t) -> *mut rb_shape_t; } extern "C" { @@ -433,9 +436,6 @@ extern "C" { extern "C" { pub fn rb_shape_get_iv_index(shape: *mut rb_shape_t, id: ID, value: *mut attr_index_t) -> bool; } -extern "C" { - pub fn rb_shape_flags_mask() -> VALUE; -} pub const idDot2: ruby_method_ids = 128; pub const idDot3: ruby_method_ids = 129; pub const idUPlus: ruby_method_ids = 132; |