diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 7405ca997b8f56..3551ac8ef2adae 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -208,7 +208,7 @@ jobs: matrix: include: # Using the same setup as ZJIT jobs - - bench_opts: '--warmup=1 --bench=1 --excludes=lobsters,ruby-lsp' + - bench_opts: '--warmup=1 --bench=1' runs-on: ubuntu-24.04 diff --git a/.github/workflows/zjit-macos.yml b/.github/workflows/zjit-macos.yml index 7f0f6ebd4d0e8d..6da45a3a42acf8 100644 --- a/.github/workflows/zjit-macos.yml +++ b/.github/workflows/zjit-macos.yml @@ -158,7 +158,7 @@ jobs: include: # Test --call-threshold=2 with 2 iterations in total - ruby_opts: '--zjit-call-threshold=2' - bench_opts: '--warmup=1 --bench=1 --excludes=lobsters,ruby-lsp' + bench_opts: '--warmup=1 --bench=1' configure: '--enable-zjit=dev_nodebug' # --enable-zjit=dev is too slow runs-on: macos-14 diff --git a/.github/workflows/zjit-ubuntu.yml b/.github/workflows/zjit-ubuntu.yml index ba849d9bdf4e3d..d8b5460ed7f703 100644 --- a/.github/workflows/zjit-ubuntu.yml +++ b/.github/workflows/zjit-ubuntu.yml @@ -215,7 +215,7 @@ jobs: include: # Test --call-threshold=2 with 2 iterations in total - ruby_opts: '--zjit-call-threshold=2' - bench_opts: '--warmup=1 --bench=1 --excludes=lobsters,ruby-lsp' + bench_opts: '--warmup=1 --bench=1' configure: '--enable-zjit=dev_nodebug' # --enable-zjit=dev is too slow runs-on: ubuntu-24.04 diff --git a/ext/ripper/lib/ripper/lexer.rb b/ext/ripper/lib/ripper/lexer.rb index 870c79857bd670..9b849dfeae2487 100644 --- a/ext/ripper/lib/ripper/lexer.rb +++ b/ext/ripper/lib/ripper/lexer.rb @@ -68,7 +68,7 @@ def [](index) when 0, :to_int @to_int when 1, :to_s - @event + @to_s else nil end diff --git a/hash.c b/hash.c index dc47eb6ab77736..28b729516474a7 100644 --- a/hash.c +++ b/hash.c @@ -1558,9 +1558,8 @@ rb_hash_dup(VALUE hash) const VALUE flags = RBASIC(hash)->flags; VALUE ret = hash_dup(hash, rb_obj_class(hash), flags & RHASH_PROC_DEFAULT); - if (rb_obj_gen_fields_p(hash)) { - rb_copy_generic_ivar(ret, hash); - } + rb_copy_generic_ivar(ret, hash); + return ret; } diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index c728df7255c8ba..8d832c2e2569b3 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -449,7 +449,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio Insn::Test { val } => gen_test(asm, opnd!(val)), Insn::GuardType { val, guard_type, state } => gen_guard_type(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state)), Insn::GuardTypeNot { val, guard_type, state } => gen_guard_type_not(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state)), - Insn::GuardBitEquals { val, expected, state } => gen_guard_bit_equals(jit, asm, opnd!(val), *expected, &function.frame_state(*state)), + &Insn::GuardBitEquals { val, expected, reason, state } => gen_guard_bit_equals(jit, asm, opnd!(val), expected, reason, &function.frame_state(state)), &Insn::GuardBlockParamProxy { level, state } => no_output!(gen_guard_block_param_proxy(jit, asm, level, &function.frame_state(state))), Insn::GuardNotFrozen { recv, state } => gen_guard_not_frozen(jit, asm, opnd!(recv), &function.frame_state(*state)), Insn::GuardNotShared { recv, state } => gen_guard_not_shared(jit, asm, opnd!(recv), &function.frame_state(*state)), @@ -498,7 +498,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio Insn::LoadPC => gen_load_pc(asm), Insn::LoadEC => gen_load_ec(), Insn::LoadSelf => gen_load_self(), - &Insn::LoadField { recv, id, offset, return_type: _ } => gen_load_field(asm, opnd!(recv), id, offset), + &Insn::LoadField { recv, id, offset, return_type } => gen_load_field(asm, opnd!(recv), id, offset, return_type), &Insn::StoreField { recv, id, offset, val } => no_output!(gen_store_field(asm, opnd!(recv), id, offset, opnd!(val), function.type_of(val))), &Insn::WriteBarrier { recv, val } => no_output!(gen_write_barrier(asm, opnd!(recv), opnd!(val), function.type_of(val))), &Insn::IsBlockGiven => gen_is_block_given(jit, asm), @@ -1130,10 +1130,10 @@ fn gen_load_self() -> Opnd { Opnd::mem(64, CFP, RUBY_OFFSET_CFP_SELF) } -fn gen_load_field(asm: &mut Assembler, recv: Opnd, id: ID, offset: i32) -> Opnd { +fn gen_load_field(asm: &mut Assembler, recv: Opnd, id: ID, offset: i32, return_type: Type) -> Opnd { asm_comment!(asm, "Load field id={} offset={}", id.contents_lossy(), offset); let recv = asm.load(recv); - asm.load(Opnd::mem(64, recv, offset)) + asm.load(Opnd::mem(return_type.num_bits(), recv, offset)) } fn gen_store_field(asm: &mut Assembler, recv: Opnd, id: ID, offset: i32, val: Opnd, val_type: Type) { @@ -2083,14 +2083,15 @@ fn gen_guard_type_not(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, g } /// Compile an identity check with a side exit -fn gen_guard_bit_equals(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, expected: crate::hir::Const, state: &FrameState) -> lir::Opnd { +fn gen_guard_bit_equals(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, expected: crate::hir::Const, reason: SideExitReason, state: &FrameState) -> lir::Opnd { let expected_opnd: Opnd = match expected { crate::hir::Const::Value(v) => { Opnd::Value(v) } crate::hir::Const::CInt64(v) => { v.into() } + crate::hir::Const::CShape(v) => { Opnd::UImm(v.0 as u64) } _ => panic!("gen_guard_bit_equals: unexpected hir::Const {expected:?}"), }; asm.cmp(val, expected_opnd); - asm.jnz(side_exit(jit, state, GuardBitEquals(expected))); + asm.jnz(side_exit(jit, state, reason)); val } diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 2ea6e94c960b6a..c6a104fbd176b0 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -491,7 +491,7 @@ pub enum SideExitReason { GuardType(Type), GuardTypeNot(Type), GuardShape(ShapeId), - GuardBitEquals(Const), + ExpandArray, GuardNotFrozen, GuardNotShared, GuardLess, @@ -580,7 +580,6 @@ impl std::fmt::Display for SideExitReason { SideExitReason::UnhandledDuparraySend(method_id) => write!(f, "UnhandledDuparraySend({method_id})"), SideExitReason::GuardType(guard_type) => write!(f, "GuardType({guard_type})"), SideExitReason::GuardTypeNot(guard_type) => write!(f, "GuardTypeNot({guard_type})"), - SideExitReason::GuardBitEquals(value) => write!(f, "GuardBitEquals({})", value.print(&PtrPrintMap::identity())), SideExitReason::GuardNotShared => write!(f, "GuardNotShared"), SideExitReason::PatchPoint(invariant) => write!(f, "PatchPoint({invariant})"), _ => write!(f, "{self:?}"), @@ -954,7 +953,7 @@ pub enum Insn { GuardType { val: InsnId, guard_type: Type, state: InsnId }, GuardTypeNot { val: InsnId, guard_type: Type, state: InsnId }, /// Side-exit if val is not the expected Const. - GuardBitEquals { val: InsnId, expected: Const, state: InsnId }, + GuardBitEquals { val: InsnId, expected: Const, reason: SideExitReason, state: InsnId }, /// Side-exit if val doesn't have the expected shape. GuardShape { val: InsnId, shape: ShapeId, state: InsnId }, /// Side-exit if the block param has been modified or the block handler for the frame @@ -1975,7 +1974,7 @@ impl Function { &IfFalse { val, ref target } => IfFalse { val: find!(val), target: find_branch_edge!(target) }, &GuardType { val, guard_type, state } => GuardType { val: find!(val), guard_type, state }, &GuardTypeNot { val, guard_type, state } => GuardTypeNot { val: find!(val), guard_type, state }, - &GuardBitEquals { val, expected, state } => GuardBitEquals { val: find!(val), expected, state }, + &GuardBitEquals { val, expected, reason, state } => GuardBitEquals { val: find!(val), expected, reason, state }, &GuardShape { val, shape, state } => GuardShape { val: find!(val), shape, state }, &GuardBlockParamProxy { level, state } => GuardBlockParamProxy { level, state: find!(state) }, &GuardNotFrozen { recv, state } => GuardNotFrozen { recv: find!(recv), state }, @@ -3069,6 +3068,24 @@ impl Function { self.infer_types(); } + fn load_shape(&mut self, block: BlockId, recv: InsnId) -> InsnId { + self.push_insn(block, Insn::LoadField { + recv, + id: ID!(_shape_id), + offset: unsafe { rb_shape_id_offset() } as i32, + return_type: types::CShape + }) + } + + fn guard_shape(&mut self, block: BlockId, val: InsnId, expected: ShapeId, state: InsnId) -> InsnId { + self.push_insn(block, Insn::GuardBitEquals { + val, + expected: Const::CShape(expected), + reason: SideExitReason::GuardShape(expected), + state + }) + } + fn optimize_getivar(&mut self) { for block in self.rpo() { let old_insns = std::mem::take(&mut self.blocks[block.0].insns); @@ -3094,7 +3111,8 @@ impl Function { self.push_insn_id(block, insn_id); continue; } let self_val = self.push_insn(block, Insn::GuardType { val: self_val, guard_type: types::HeapBasicObject, state }); - let self_val = self.push_insn(block, Insn::GuardShape { val: self_val, shape: recv_type.shape(), state }); + let shape = self.load_shape(block, self_val); + self.guard_shape(block, shape, recv_type.shape(), state); let mut ivar_index: u16 = 0; let replacement = if ! unsafe { rb_shape_get_iv_index(recv_type.shape().0, id, &mut ivar_index) } { // If there is no IVAR index, then the ivar was undefined when we @@ -3148,7 +3166,8 @@ impl Function { self.push_insn_id(block, insn_id); continue; } let self_val = self.push_insn(block, Insn::GuardType { val: self_val, guard_type: types::HeapBasicObject, state }); - let _ = self.push_insn(block, Insn::GuardShape { val: self_val, shape: recv_type.shape(), state }); + let shape = self.load_shape(block, self_val); + self.guard_shape(block, shape, recv_type.shape(), state); let mut ivar_index: u16 = 0; let replacement = if unsafe { rb_shape_get_iv_index(recv_type.shape().0, id, &mut ivar_index) } { self.push_insn(block, Insn::Const { val: Const::Value(pushval) }) @@ -3219,7 +3238,8 @@ impl Function { // Fall through to emitting the ivar write } let self_val = self.push_insn(block, Insn::GuardType { val: self_val, guard_type: types::HeapBasicObject, state }); - let self_val = self.push_insn(block, Insn::GuardShape { val: self_val, shape: recv_type.shape(), state }); + let shape = self.load_shape(block, self_val); + self.guard_shape(block, shape, recv_type.shape(), state); // Current shape contains this ivar let (ivar_storage, offset) = if recv_type.flags().is_embedded() { // See ROBJECT_FIELDS() from include/ruby/internal/core/robject.h @@ -6261,7 +6281,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result { let val = state.stack_pop()?; let array = fun.push_insn(block, Insn::GuardType { val, guard_type: types::ArrayExact, state: exit_id, }); let length = fun.push_insn(block, Insn::ArrayLength { array }); - fun.push_insn(block, Insn::GuardBitEquals { val: length, expected: Const::CInt64(num as i64), state: exit_id }); + fun.push_insn(block, Insn::GuardBitEquals { val: length, expected: Const::CInt64(num as i64), reason: SideExitReason::ExpandArray, state: exit_id }); for i in (0..num).rev() { // TODO(max): Add a short-cut path for long indices into an array where the // index is known to be in-bounds diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs index afa97e48f1e4dc..3ad07596b71f58 100644 --- a/zjit/src/hir/opt_tests.rs +++ b/zjit/src/hir/opt_tests.rs @@ -3677,10 +3677,11 @@ mod hir_opt_tests { Jump bb2(v4) bb2(v6:BasicObject): v15:HeapBasicObject = GuardType v6, HeapBasicObject - v16:HeapBasicObject = GuardShape v15, 0x1000 - v17:StringExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) + v16:CShape = LoadField v15, :_shape_id@0x1000 + v17:CShape[0x1001] = GuardBitEquals v16, CShape(0x1001) + v18:StringExact[VALUE(0x1008)] = Const Value(VALUE(0x1008)) CheckInterrupts - Return v17 + Return v18 "); } @@ -3701,10 +3702,11 @@ mod hir_opt_tests { Jump bb2(v4) bb2(v6:BasicObject): v15:HeapBasicObject = GuardType v6, HeapBasicObject - v16:HeapBasicObject = GuardShape v15, 0x1000 - v17:NilClass = Const Value(nil) + v16:CShape = LoadField v15, :_shape_id@0x1000 + v17:CShape[0x1001] = GuardBitEquals v16, CShape(0x1001) + v18:NilClass = Const Value(nil) CheckInterrupts - Return v17 + Return v18 "); } @@ -3821,9 +3823,10 @@ mod hir_opt_tests { v10:Fixnum[5] = Const Value(5) PatchPoint SingleRactorMode v19:HeapBasicObject = GuardType v6, HeapBasicObject - v20:HeapBasicObject = GuardShape v19, 0x1000 - StoreField v20, :@foo@0x1001, v10 - WriteBarrier v20, v10 + v20:CShape = LoadField v19, :_shape_id@0x1000 + v21:CShape[0x1001] = GuardBitEquals v20, CShape(0x1001) + StoreField v19, :@foo@0x1002, v10 + WriteBarrier v19, v10 CheckInterrupts Return v10 "); @@ -3848,11 +3851,12 @@ mod hir_opt_tests { v10:Fixnum[5] = Const Value(5) PatchPoint SingleRactorMode v19:HeapBasicObject = GuardType v6, HeapBasicObject - v20:HeapBasicObject = GuardShape v19, 0x1000 - StoreField v20, :@foo@0x1001, v10 - WriteBarrier v20, v10 - v23:CShape[0x1002] = Const CShape(0x1002) - StoreField v20, :_shape_id@0x1003, v23 + v20:CShape = LoadField v19, :_shape_id@0x1000 + v21:CShape[0x1001] = GuardBitEquals v20, CShape(0x1001) + StoreField v19, :@foo@0x1002, v10 + WriteBarrier v19, v10 + v24:CShape[0x1003] = Const CShape(0x1003) + StoreField v19, :_shape_id@0x1000, v24 CheckInterrupts Return v10 "); @@ -3880,19 +3884,21 @@ mod hir_opt_tests { v10:Fixnum[1] = Const Value(1) PatchPoint SingleRactorMode v25:HeapBasicObject = GuardType v6, HeapBasicObject - v26:HeapBasicObject = GuardShape v25, 0x1000 - StoreField v26, :@foo@0x1001, v10 - WriteBarrier v26, v10 - v29:CShape[0x1002] = Const CShape(0x1002) - StoreField v26, :_shape_id@0x1003, v29 + v26:CShape = LoadField v25, :_shape_id@0x1000 + v27:CShape[0x1001] = GuardBitEquals v26, CShape(0x1001) + StoreField v25, :@foo@0x1002, v10 + WriteBarrier v25, v10 + v30:CShape[0x1003] = Const CShape(0x1003) + StoreField v25, :_shape_id@0x1000, v30 v16:Fixnum[2] = Const Value(2) PatchPoint SingleRactorMode - v31:HeapBasicObject = GuardType v6, HeapBasicObject - v32:HeapBasicObject = GuardShape v31, 0x1002 + v32:HeapBasicObject = GuardType v6, HeapBasicObject + v33:CShape = LoadField v32, :_shape_id@0x1000 + v34:CShape[0x1003] = GuardBitEquals v33, CShape(0x1003) StoreField v32, :@bar@0x1004, v16 WriteBarrier v32, v16 - v35:CShape[0x1005] = Const CShape(0x1005) - StoreField v32, :_shape_id@0x1003, v35 + v37:CShape[0x1005] = Const CShape(0x1005) + StoreField v32, :_shape_id@0x1000, v37 CheckInterrupts Return v16 "); @@ -5611,10 +5617,11 @@ mod hir_opt_tests { PatchPoint MethodRedefined(C@0x1000, foo@0x1008, cme:0x1010) PatchPoint NoSingletonClass(C@0x1000) v21:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C] - v24:HeapObject[class_exact:C] = GuardShape v21, 0x1038 - v25:BasicObject = LoadField v24, :@foo@0x1039 + v24:CShape = LoadField v21, :_shape_id@0x1038 + v25:CShape[0x1039] = GuardBitEquals v24, CShape(0x1039) + v26:BasicObject = LoadField v21, :@foo@0x103a CheckInterrupts - Return v25 + Return v26 "); } @@ -5650,11 +5657,12 @@ mod hir_opt_tests { PatchPoint MethodRedefined(C@0x1000, foo@0x1008, cme:0x1010) PatchPoint NoSingletonClass(C@0x1000) v21:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C] - v24:HeapObject[class_exact:C] = GuardShape v21, 0x1038 - v25:CPtr = LoadField v24, :_as_heap@0x1039 - v26:BasicObject = LoadField v25, :@foo@0x103a + v24:CShape = LoadField v21, :_shape_id@0x1038 + v25:CShape[0x1039] = GuardBitEquals v24, CShape(0x1039) + v26:CPtr = LoadField v21, :_as_heap@0x103a + v27:BasicObject = LoadField v26, :@foo@0x103b CheckInterrupts - Return v26 + Return v27 "); } @@ -5679,11 +5687,12 @@ mod hir_opt_tests { bb2(v6:BasicObject): PatchPoint SingleRactorMode v16:HeapBasicObject = GuardType v6, HeapBasicObject - v17:HeapBasicObject = GuardShape v16, 0x1000 - v18:CUInt16[0] = Const CUInt16(0) - v19:BasicObject = CCall v17, :rb_ivar_get_at_no_ractor_check@0x1008, v18 + v17:CShape = LoadField v16, :_shape_id@0x1000 + v18:CShape[0x1001] = GuardBitEquals v17, CShape(0x1001) + v19:CUInt16[0] = Const CUInt16(0) + v20:BasicObject = CCall v16, :rb_ivar_get_at_no_ractor_check@0x1008, v19 CheckInterrupts - Return v19 + Return v20 "); } @@ -5708,11 +5717,12 @@ mod hir_opt_tests { bb2(v6:BasicObject): PatchPoint SingleRactorMode v16:HeapBasicObject = GuardType v6, HeapBasicObject - v17:HeapBasicObject = GuardShape v16, 0x1000 - v18:CUInt16[0] = Const CUInt16(0) - v19:BasicObject = CCall v17, :rb_ivar_get_at_no_ractor_check@0x1008, v18 + v17:CShape = LoadField v16, :_shape_id@0x1000 + v18:CShape[0x1001] = GuardBitEquals v17, CShape(0x1001) + v19:CUInt16[0] = Const CUInt16(0) + v20:BasicObject = CCall v16, :rb_ivar_get_at_no_ractor_check@0x1008, v19 CheckInterrupts - Return v19 + Return v20 "); } @@ -5739,11 +5749,12 @@ mod hir_opt_tests { bb2(v6:BasicObject): PatchPoint SingleRactorMode v16:HeapBasicObject = GuardType v6, HeapBasicObject - v17:HeapBasicObject = GuardShape v16, 0x1000 - v18:CUInt16[0] = Const CUInt16(0) - v19:BasicObject = CCall v17, :rb_ivar_get_at_no_ractor_check@0x1008, v18 + v17:CShape = LoadField v16, :_shape_id@0x1000 + v18:CShape[0x1001] = GuardBitEquals v17, CShape(0x1001) + v19:CUInt16[0] = Const CUInt16(0) + v20:BasicObject = CCall v16, :rb_ivar_get_at_no_ractor_check@0x1008, v19 CheckInterrupts - Return v19 + Return v20 "); } @@ -6030,10 +6041,11 @@ mod hir_opt_tests { v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(C@0x1010, foo@0x1018, cme:0x1020) PatchPoint NoSingletonClass(C@0x1010) - v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048 - v26:NilClass = Const Value(nil) + v25:CShape = LoadField v20, :_shape_id@0x1048 + v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049) + v27:NilClass = Const Value(nil) CheckInterrupts - Return v26 + Return v27 "); } @@ -6064,10 +6076,11 @@ mod hir_opt_tests { v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(C@0x1010, foo@0x1018, cme:0x1020) PatchPoint NoSingletonClass(C@0x1010) - v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048 - v26:NilClass = Const Value(nil) + v25:CShape = LoadField v20, :_shape_id@0x1048 + v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049) + v27:NilClass = Const Value(nil) CheckInterrupts - Return v26 + Return v27 "); } @@ -6096,10 +6109,11 @@ mod hir_opt_tests { PatchPoint MethodRedefined(C@0x1000, foo@0x1008, cme:0x1010) PatchPoint NoSingletonClass(C@0x1000) v21:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C] - v24:HeapObject[class_exact:C] = GuardShape v21, 0x1038 - v25:NilClass = Const Value(nil) + v24:CShape = LoadField v21, :_shape_id@0x1038 + v25:CShape[0x1039] = GuardBitEquals v24, CShape(0x1039) + v26:NilClass = Const Value(nil) CheckInterrupts - Return v25 + Return v26 "); } @@ -6128,10 +6142,11 @@ mod hir_opt_tests { PatchPoint MethodRedefined(C@0x1000, foo@0x1008, cme:0x1010) PatchPoint NoSingletonClass(C@0x1000) v21:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C] - v24:HeapObject[class_exact:C] = GuardShape v21, 0x1038 - v25:NilClass = Const Value(nil) + v24:CShape = LoadField v21, :_shape_id@0x1038 + v25:CShape[0x1039] = GuardBitEquals v24, CShape(0x1039) + v26:NilClass = Const Value(nil) CheckInterrupts - Return v25 + Return v26 "); } @@ -6160,11 +6175,12 @@ mod hir_opt_tests { v16:Fixnum[5] = Const Value(5) PatchPoint MethodRedefined(C@0x1000, foo=@0x1008, cme:0x1010) v26:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C] - v29:HeapObject[class_exact:C] = GuardShape v26, 0x1038 - StoreField v29, :@foo@0x1039, v16 - WriteBarrier v29, v16 - v32:CShape[0x103a] = Const CShape(0x103a) - StoreField v29, :_shape_id@0x103b, v32 + v29:CShape = LoadField v26, :_shape_id@0x1038 + v30:CShape[0x1039] = GuardBitEquals v29, CShape(0x1039) + StoreField v26, :@foo@0x103a, v16 + WriteBarrier v26, v16 + v33:CShape[0x103b] = Const CShape(0x103b) + StoreField v26, :_shape_id@0x1038, v33 CheckInterrupts Return v16 "); @@ -6195,11 +6211,12 @@ mod hir_opt_tests { v16:Fixnum[5] = Const Value(5) PatchPoint MethodRedefined(C@0x1000, foo=@0x1008, cme:0x1010) v26:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C] - v29:HeapObject[class_exact:C] = GuardShape v26, 0x1038 - StoreField v29, :@foo@0x1039, v16 - WriteBarrier v29, v16 - v32:CShape[0x103a] = Const CShape(0x103a) - StoreField v29, :_shape_id@0x103b, v32 + v29:CShape = LoadField v26, :_shape_id@0x1038 + v30:CShape[0x1039] = GuardBitEquals v29, CShape(0x1039) + StoreField v26, :@foo@0x103a, v16 + WriteBarrier v26, v16 + v33:CShape[0x103b] = Const CShape(0x103b) + StoreField v26, :_shape_id@0x1038, v33 CheckInterrupts Return v16 "); @@ -9752,21 +9769,22 @@ mod hir_opt_tests { SetLocal :formatted, l0, EP@3, v15 PatchPoint SingleRactorMode v54:HeapBasicObject = GuardType v14, HeapBasicObject - v55:HeapBasicObject = GuardShape v54, 0x1000 - StoreField v55, :@formatted@0x1001, v15 - WriteBarrier v55, v15 - v58:CShape[0x1002] = Const CShape(0x1002) - StoreField v55, :_shape_id@0x1003, v58 + v55:CShape = LoadField v54, :_shape_id@0x1000 + v56:CShape[0x1001] = GuardBitEquals v55, CShape(0x1001) + StoreField v54, :@formatted@0x1002, v15 + WriteBarrier v54, v15 + v59:CShape[0x1003] = Const CShape(0x1003) + StoreField v54, :_shape_id@0x1000, v59 v43:Class[VMFrozenCore] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(Class@0x1010, lambda@0x1018, cme:0x1020) PatchPoint NoSingletonClass(Class@0x1010) - v63:BasicObject = CCallWithFrame v43, :RubyVM::FrozenCore.lambda@0x1048, block=0x1050 + v64:BasicObject = CCallWithFrame v43, :RubyVM::FrozenCore.lambda@0x1048, block=0x1050 v46:BasicObject = GetLocal :a, l0, EP@6 v47:BasicObject = GetLocal :_b, l0, EP@5 v48:BasicObject = GetLocal :_c, l0, EP@4 v49:BasicObject = GetLocal :formatted, l0, EP@3 CheckInterrupts - Return v63 + Return v64 "); } @@ -9802,10 +9820,11 @@ mod hir_opt_tests { v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(TestFrozen@0x1010, a@0x1018, cme:0x1020) PatchPoint NoSingletonClass(TestFrozen@0x1010) - v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048 - v27:Fixnum[1] = Const Value(1) + v25:CShape = LoadField v20, :_shape_id@0x1048 + v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049) + v28:Fixnum[1] = Const Value(1) CheckInterrupts - Return v27 + Return v28 "); } @@ -9843,10 +9862,11 @@ mod hir_opt_tests { v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(TestMultiIvars@0x1010, b@0x1018, cme:0x1020) PatchPoint NoSingletonClass(TestMultiIvars@0x1010) - v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048 - v27:Fixnum[20] = Const Value(20) + v25:CShape = LoadField v20, :_shape_id@0x1048 + v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049) + v28:Fixnum[20] = Const Value(20) CheckInterrupts - Return v27 + Return v28 "); } @@ -9882,10 +9902,11 @@ mod hir_opt_tests { v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(TestFrozenStr@0x1010, name@0x1018, cme:0x1020) PatchPoint NoSingletonClass(TestFrozenStr@0x1010) - v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048 - v27:StringExact[VALUE(0x1050)] = Const Value(VALUE(0x1050)) + v25:CShape = LoadField v20, :_shape_id@0x1048 + v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049) + v28:StringExact[VALUE(0x1050)] = Const Value(VALUE(0x1050)) CheckInterrupts - Return v27 + Return v28 "); } @@ -9921,10 +9942,11 @@ mod hir_opt_tests { v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(TestFrozenNil@0x1010, value@0x1018, cme:0x1020) PatchPoint NoSingletonClass(TestFrozenNil@0x1010) - v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048 - v27:NilClass = Const Value(nil) + v25:CShape = LoadField v20, :_shape_id@0x1048 + v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049) + v28:NilClass = Const Value(nil) CheckInterrupts - Return v27 + Return v28 "); } @@ -9960,10 +9982,11 @@ mod hir_opt_tests { v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(TestUnfrozen@0x1010, a@0x1018, cme:0x1020) PatchPoint NoSingletonClass(TestUnfrozen@0x1010) - v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048 - v26:BasicObject = LoadField v25, :@a@0x1049 + v25:CShape = LoadField v20, :_shape_id@0x1048 + v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049) + v27:BasicObject = LoadField v20, :@a@0x104a CheckInterrupts - Return v26 + Return v27 "); } @@ -9999,10 +10022,11 @@ mod hir_opt_tests { v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(TestAttrReader@0x1010, value@0x1018, cme:0x1020) PatchPoint NoSingletonClass(TestAttrReader@0x1010) - v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048 - v27:Fixnum[42] = Const Value(42) + v25:CShape = LoadField v20, :_shape_id@0x1048 + v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049) + v28:Fixnum[42] = Const Value(42) CheckInterrupts - Return v27 + Return v28 "); } @@ -10038,10 +10062,11 @@ mod hir_opt_tests { v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(TestFrozenSym@0x1010, sym@0x1018, cme:0x1020) PatchPoint NoSingletonClass(TestFrozenSym@0x1010) - v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048 - v27:StaticSymbol[:hello] = Const Value(VALUE(0x1050)) + v25:CShape = LoadField v20, :_shape_id@0x1048 + v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049) + v28:StaticSymbol[:hello] = Const Value(VALUE(0x1050)) CheckInterrupts - Return v27 + Return v28 "); } @@ -10077,10 +10102,11 @@ mod hir_opt_tests { v20:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(TestFrozenBool@0x1010, flag@0x1018, cme:0x1020) PatchPoint NoSingletonClass(TestFrozenBool@0x1010) - v25:HeapObject[VALUE(0x1008)] = GuardShape v20, 0x1048 - v27:TrueClass = Const Value(true) + v25:CShape = LoadField v20, :_shape_id@0x1048 + v26:CShape[0x1049] = GuardBitEquals v25, CShape(0x1049) + v28:TrueClass = Const Value(true) CheckInterrupts - Return v27 + Return v28 "); } @@ -10114,10 +10140,11 @@ mod hir_opt_tests { PatchPoint MethodRedefined(TestDynamic@0x1000, val@0x1008, cme:0x1010) PatchPoint NoSingletonClass(TestDynamic@0x1000) v21:HeapObject[class_exact:TestDynamic] = GuardType v9, HeapObject[class_exact:TestDynamic] - v24:HeapObject[class_exact:TestDynamic] = GuardShape v21, 0x1038 - v25:BasicObject = LoadField v24, :@val@0x1039 + v24:CShape = LoadField v21, :_shape_id@0x1038 + v25:CShape[0x1039] = GuardBitEquals v24, CShape(0x1039) + v26:BasicObject = LoadField v21, :@val@0x103a CheckInterrupts - Return v25 + Return v26 "); } @@ -10154,20 +10181,22 @@ mod hir_opt_tests { v28:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(TestNestedAccess@0x1010, x@0x1018, cme:0x1020) PatchPoint NoSingletonClass(TestNestedAccess@0x1010) - v39:HeapObject[VALUE(0x1008)] = GuardShape v28, 0x1048 - v50:Fixnum[100] = Const Value(100) + v39:CShape = LoadField v28, :_shape_id@0x1048 + v40:CShape[0x1049] = GuardBitEquals v39, CShape(0x1049) + v52:Fixnum[100] = Const Value(100) PatchPoint SingleRactorMode PatchPoint StableConstantNames(0x1050, NESTED_FROZEN) v34:HeapObject[VALUE(0x1008)] = Const Value(VALUE(0x1008)) PatchPoint MethodRedefined(TestNestedAccess@0x1010, y@0x1058, cme:0x1060) PatchPoint NoSingletonClass(TestNestedAccess@0x1010) - v42:HeapObject[VALUE(0x1008)] = GuardShape v34, 0x1048 - v51:Fixnum[200] = Const Value(200) + v43:CShape = LoadField v34, :_shape_id@0x1048 + v44:CShape[0x1049] = GuardBitEquals v43, CShape(0x1049) + v53:Fixnum[200] = Const Value(200) PatchPoint MethodRedefined(Integer@0x1088, +@0x1090, cme:0x1098) - v52:Fixnum[300] = Const Value(300) + v54:Fixnum[300] = Const Value(300) IncrCounter inline_cfunc_optimized_send_count CheckInterrupts - Return v52 + Return v54 "); } diff --git a/zjit/src/stats.rs b/zjit/src/stats.rs index 68eeac456b38a2..01bd6e2f597ec8 100644 --- a/zjit/src/stats.rs +++ b/zjit/src/stats.rs @@ -190,6 +190,7 @@ make_counters! { exit_guard_bit_equals_failure, exit_guard_int_equals_failure, exit_guard_shape_failure, + exit_expandarray_failure, exit_guard_not_frozen_failure, exit_guard_not_shared_failure, exit_guard_less_failure, @@ -509,8 +510,8 @@ pub fn side_exit_counter(reason: crate::hir::SideExitReason) -> Counter { BoxFixnumOverflow => exit_box_fixnum_overflow, GuardType(_) => exit_guard_type_failure, GuardTypeNot(_) => exit_guard_type_not_failure, - GuardBitEquals(_) => exit_guard_bit_equals_failure, GuardShape(_) => exit_guard_shape_failure, + ExpandArray => exit_expandarray_failure, GuardNotFrozen => exit_guard_not_frozen_failure, GuardNotShared => exit_guard_not_shared_failure, GuardLess => exit_guard_less_failure,