diff options
| author | nozomemein <b8yukifsukeo999n@gmail.com> | 2026-01-09 09:56:11 +0900 |
|---|---|---|
| committer | Takashi Kokubun <takashikkbn@gmail.com> | 2026-01-15 09:00:53 -0800 |
| commit | 065db7cf61cfb69d869f4b403b49b1efc314eead (patch) | |
| tree | 0194a4b4e1375b6bd7076b58944441b376d852f5 | |
| parent | 11edc286d837f66b37433e7d51c8b8f500e1be84 (diff) | |
ZJIT: Rename ArrayArefFixnum -> ArrayAref
| -rw-r--r-- | zjit/src/codegen.rs | 7 | ||||
| -rw-r--r-- | zjit/src/cruby_methods.rs | 3 | ||||
| -rw-r--r-- | zjit/src/hir.rs | 23 | ||||
| -rw-r--r-- | zjit/src/hir/opt_tests.rs | 45 | ||||
| -rw-r--r-- | zjit/src/hir/tests.rs | 8 | ||||
| -rw-r--r-- | zjit/src/hir_type/mod.rs | 11 |
6 files changed, 60 insertions, 37 deletions
diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index 16ac2573f2..25cccd1bd1 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -374,7 +374,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio Insn::NewRange { low, high, flag, state } => gen_new_range(jit, asm, opnd!(low), opnd!(high), *flag, &function.frame_state(*state)), Insn::NewRangeFixnum { low, high, flag, state } => gen_new_range_fixnum(asm, opnd!(low), opnd!(high), *flag, &function.frame_state(*state)), Insn::ArrayDup { val, state } => gen_array_dup(asm, opnd!(val), &function.frame_state(*state)), - Insn::ArrayArefFixnum { array, index, .. } => gen_aref_fixnum(asm, opnd!(array), opnd!(index)), + Insn::ArrayAref { array, index, .. } => gen_array_aref(asm, opnd!(array), opnd!(index)), Insn::ArrayAset { array, index, val } => { no_output!(gen_array_aset(asm, opnd!(array), opnd!(index), opnd!(val))) } @@ -1560,13 +1560,12 @@ fn gen_new_array( } /// Compile array access (`array[index]`) -fn gen_aref_fixnum( +fn gen_array_aref( asm: &mut Assembler, array: Opnd, index: Opnd, ) -> lir::Opnd { - let unboxed_idx = asm.rshift(index, Opnd::UImm(1)); - asm_ccall!(asm, rb_ary_entry, array, unboxed_idx) + asm_ccall!(asm, rb_ary_entry, array, index) } fn gen_array_aset( diff --git a/zjit/src/cruby_methods.rs b/zjit/src/cruby_methods.rs index 40b9d13854..5f89a5f20e 100644 --- a/zjit/src/cruby_methods.rs +++ b/zjit/src/cruby_methods.rs @@ -326,7 +326,8 @@ fn inline_array_aref(fun: &mut hir::Function, block: hir::BlockId, recv: hir::In if let &[index] = args { if fun.likely_a(index, types::Fixnum, state) { let index = fun.coerce_to(block, index, types::Fixnum, state); - let result = fun.push_insn(block, hir::Insn::ArrayArefFixnum { array: recv, index }); + let index = fun.push_insn(block, hir::Insn::UnboxFixnum { val: index }); + let result = fun.push_insn(block, hir::Insn::ArrayAref { array: recv, index }); return Some(result); } } diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 48f85c4f23..4a81ce641c 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -759,7 +759,7 @@ pub enum Insn { ArrayExtend { left: InsnId, right: InsnId, state: InsnId }, /// Push `val` onto `array`, where `array` is already `Array`. ArrayPush { array: InsnId, val: InsnId, state: InsnId }, - ArrayArefFixnum { array: InsnId, index: InsnId }, + ArrayAref { array: InsnId, index: InsnId }, ArrayAset { array: InsnId, index: InsnId, val: InsnId }, ArrayPop { array: InsnId, state: InsnId }, /// Return the length of the array as a C `long` ([`types::CInt64`]) @@ -1163,8 +1163,8 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { } Ok(()) } - Insn::ArrayArefFixnum { array, index, .. } => { - write!(f, "ArrayArefFixnum {array}, {index}") + Insn::ArrayAref { array, index, .. } => { + write!(f, "ArrayAref {array}, {index}") } Insn::ArrayAset { array, index, val, ..} => { write!(f, "ArrayAset {array}, {index}, {val}") @@ -2150,7 +2150,7 @@ impl Function { &NewHash { ref elements, state } => NewHash { elements: find_vec!(elements), state: find!(state) }, &NewRange { low, high, flag, state } => NewRange { low: find!(low), high: find!(high), flag, state: find!(state) }, &NewRangeFixnum { low, high, flag, state } => NewRangeFixnum { low: find!(low), high: find!(high), flag, state: find!(state) }, - &ArrayArefFixnum { array, index } => ArrayArefFixnum { array: find!(array), index: find!(index) }, + &ArrayAref { array, index } => ArrayAref { array: find!(array), index: find!(index) }, &ArrayAset { array, index, val } => ArrayAset { array: find!(array), index: find!(index), val: find!(val) }, &ArrayPop { array, state } => ArrayPop { array: find!(array), state: find!(state) }, &ArrayLength { array } => ArrayLength { array: find!(array) }, @@ -2263,7 +2263,7 @@ impl Function { Insn::ToRegexp { .. } => types::RegexpExact, Insn::NewArray { .. } => types::ArrayExact, Insn::ArrayDup { .. } => types::ArrayExact, - Insn::ArrayArefFixnum { .. } => types::BasicObject, + Insn::ArrayAref { .. } => types::BasicObject, Insn::ArrayPop { .. } => types::BasicObject, Insn::ArrayLength { .. } => types::CInt64, Insn::HashAref { .. } => types::BasicObject, @@ -4073,11 +4073,11 @@ impl Function { _ => None, }) } - Insn::ArrayArefFixnum { array, index } if self.type_of(array).ruby_object_known() + Insn::ArrayAref { array, index } if self.type_of(array).ruby_object_known() && self.type_of(index).ruby_object_known() => { let array_obj = self.type_of(array).ruby_object().unwrap(); if array_obj.is_frozen() { - let index = self.type_of(index).fixnum_value().unwrap(); + let index = self.type_of(index).cint64_value().unwrap(); let val = unsafe { rb_yarv_ary_entry_internal(array_obj, index) }; self.new_insn(Insn::Const { val: Const::Value(val) }) } else { @@ -4271,7 +4271,7 @@ impl Function { worklist.push_back(val); worklist.push_back(state); } - &Insn::ArrayArefFixnum { array, index } => { + &Insn::ArrayAref { array, index } => { worklist.push_back(array); worklist.push_back(index); } @@ -4995,9 +4995,9 @@ impl Function { | Insn::ArrayLength { array, .. } => { self.assert_subtype(insn_id, array, types::Array) } - Insn::ArrayArefFixnum { array, index } => { + Insn::ArrayAref { array, index } => { self.assert_subtype(insn_id, array, types::Array)?; - self.assert_subtype(insn_id, index, types::Fixnum) + self.assert_subtype(insn_id, index, types::CInt64) } Insn::ArrayAset { array, index, .. } => { self.assert_subtype(insn_id, array, types::ArrayExact)?; @@ -6544,7 +6544,8 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> { // TODO(max): Add a short-cut path for long indices into an array where the // index is known to be in-bounds let index = fun.push_insn(block, Insn::Const { val: Const::Value(VALUE::fixnum_from_usize(i.try_into().unwrap())) }); - let element = fun.push_insn(block, Insn::ArrayArefFixnum { array, index }); + let index = fun.push_insn(block, Insn::UnboxFixnum { val: index }); + let element = fun.push_insn(block, Insn::ArrayAref { array, index }); state.stack_push(element); } } diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs index 138bbde718..4086a57833 100644 --- a/zjit/src/hir/opt_tests.rs +++ b/zjit/src/hir/opt_tests.rs @@ -1606,10 +1606,11 @@ mod hir_opt_tests { PatchPoint NoSingletonClass(Array@0x1000) PatchPoint MethodRedefined(Array@0x1000, []@0x1008, cme:0x1010) v25:ArrayExact = GuardType v9, ArrayExact - v26:BasicObject = ArrayArefFixnum v25, v14 + v26:CInt64 = UnboxFixnum v14 + v27:BasicObject = ArrayAref v25, v26 IncrCounter inline_cfunc_optimized_send_count CheckInterrupts - Return v26 + Return v27 "); assert_snapshot!(inspect("test [1,2,3]"), @"1"); } @@ -4734,10 +4735,11 @@ mod hir_opt_tests { v13:Fixnum[0] = Const Value(0) PatchPoint NoSingletonClass(Array@0x1010) PatchPoint MethodRedefined(Array@0x1010, []@0x1018, cme:0x1020) - v27:BasicObject = ArrayArefFixnum v23, v13 + v27:CInt64 = UnboxFixnum v13 + v28:BasicObject = ArrayAref v23, v27 IncrCounter inline_cfunc_optimized_send_count CheckInterrupts - Return v27 + Return v28 "); // TODO(max): Check the result of `S[0] = 5; test` using `inspect` to make sure that we // actually do the load at run-time. @@ -4763,10 +4765,11 @@ mod hir_opt_tests { v13:Fixnum[1] = Const Value(1) PatchPoint NoSingletonClass(Array@0x1008) PatchPoint MethodRedefined(Array@0x1008, []@0x1010, cme:0x1018) - v26:Fixnum[5] = Const Value(5) + v24:CInt64 = UnboxFixnum v13 + v25:BasicObject = ArrayAref v11, v24 IncrCounter inline_cfunc_optimized_send_count CheckInterrupts - Return v26 + Return v25 "); } @@ -4790,10 +4793,11 @@ mod hir_opt_tests { v13:Fixnum[-3] = Const Value(-3) PatchPoint NoSingletonClass(Array@0x1008) PatchPoint MethodRedefined(Array@0x1008, []@0x1010, cme:0x1018) - v26:Fixnum[4] = Const Value(4) + v24:CInt64 = UnboxFixnum v13 + v25:BasicObject = ArrayAref v11, v24 IncrCounter inline_cfunc_optimized_send_count CheckInterrupts - Return v26 + Return v25 "); } @@ -4817,10 +4821,11 @@ mod hir_opt_tests { v13:Fixnum[-10] = Const Value(-10) PatchPoint NoSingletonClass(Array@0x1008) PatchPoint MethodRedefined(Array@0x1008, []@0x1010, cme:0x1018) - v26:NilClass = Const Value(nil) + v24:CInt64 = UnboxFixnum v13 + v25:BasicObject = ArrayAref v11, v24 IncrCounter inline_cfunc_optimized_send_count CheckInterrupts - Return v26 + Return v25 "); } @@ -4844,10 +4849,11 @@ mod hir_opt_tests { v13:Fixnum[10] = Const Value(10) PatchPoint NoSingletonClass(Array@0x1008) PatchPoint MethodRedefined(Array@0x1008, []@0x1010, cme:0x1018) - v26:NilClass = Const Value(nil) + v24:CInt64 = UnboxFixnum v13 + v25:BasicObject = ArrayAref v11, v24 IncrCounter inline_cfunc_optimized_send_count CheckInterrupts - Return v26 + Return v25 "); } @@ -6735,10 +6741,11 @@ mod hir_opt_tests { v19:Fixnum[0] = Const Value(0) PatchPoint NoSingletonClass(Array@0x1008) PatchPoint MethodRedefined(Array@0x1008, []@0x1010, cme:0x1018) - v30:BasicObject = ArrayArefFixnum v14, v19 + v30:CInt64 = UnboxFixnum v19 + v31:BasicObject = ArrayAref v14, v30 IncrCounter inline_cfunc_optimized_send_count CheckInterrupts - Return v30 + Return v31 "); } @@ -6766,10 +6773,11 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Array@0x1000, []@0x1008, cme:0x1010) v27:ArrayExact = GuardType v11, ArrayExact v28:Fixnum = GuardType v12, Fixnum - v29:BasicObject = ArrayArefFixnum v27, v28 + v29:CInt64 = UnboxFixnum v28 + v30:BasicObject = ArrayAref v27, v29 IncrCounter inline_cfunc_optimized_send_count CheckInterrupts - Return v29 + Return v30 "); } @@ -6798,10 +6806,11 @@ mod hir_opt_tests { PatchPoint MethodRedefined(C@0x1000, []@0x1008, cme:0x1010) v27:ArraySubclass[class_exact:C] = GuardType v11, ArraySubclass[class_exact:C] v28:Fixnum = GuardType v12, Fixnum - v29:BasicObject = ArrayArefFixnum v27, v28 + v29:CInt64 = UnboxFixnum v28 + v30:BasicObject = ArrayAref v27, v29 IncrCounter inline_cfunc_optimized_send_count CheckInterrupts - Return v29 + Return v30 "); } diff --git a/zjit/src/hir/tests.rs b/zjit/src/hir/tests.rs index 14a7777623..6a26b69051 100644 --- a/zjit/src/hir/tests.rs +++ b/zjit/src/hir/tests.rs @@ -3566,9 +3566,11 @@ pub mod hir_build_tests { v22:CInt64 = ArrayLength v21 v23:CInt64[2] = GuardBitEquals v22, CInt64(2) v24:Fixnum[1] = Const Value(1) - v25:BasicObject = ArrayArefFixnum v21, v24 - v26:Fixnum[0] = Const Value(0) - v27:BasicObject = ArrayArefFixnum v21, v26 + v25:CInt64 = UnboxFixnum v24 + v26:BasicObject = ArrayAref v21, v25 + v27:Fixnum[0] = Const Value(0) + v28:CInt64 = UnboxFixnum v27 + v29:BasicObject = ArrayAref v21, v28 PatchPoint NoEPEscape(test) CheckInterrupts Return v13 diff --git a/zjit/src/hir_type/mod.rs b/zjit/src/hir_type/mod.rs index 061fe16578..d339674d98 100644 --- a/zjit/src/hir_type/mod.rs +++ b/zjit/src/hir_type/mod.rs @@ -395,6 +395,17 @@ impl Type { } } + pub fn cint64_value(&self) -> Option<i64> { + if self.is_subtype(types::CInt64) { + match self.spec { + Specialization::Int(val) => Some(val as i64), + _ => None, + } + } else { + None + } + } + /// Return true if the Type has object specialization and false otherwise. pub fn ruby_object_known(&self) -> bool { matches!(self.spec, Specialization::Object(_)) |
