diff options
| -rw-r--r-- | insns.def | 2 | ||||
| -rw-r--r-- | zjit/src/cruby_bindings.inc.rs | 14 | ||||
| -rw-r--r-- | zjit/src/hir.rs | 59 | ||||
| -rw-r--r-- | zjit/src/profile.rs | 2 |
4 files changed, 71 insertions, 6 deletions
@@ -1470,6 +1470,7 @@ opt_ltlt * string. Then what happens if that codepoint does not exist in the * string's encoding? Of course an exception. That's not a leaf. */ // attr bool leaf = false; /* has "invalid codepoint" exception */ +// attr bool zjit_profile = true; { val = vm_opt_ltlt(recv, obj); @@ -1537,6 +1538,7 @@ opt_aset /* This is another story than opt_aref. When vm_opt_aset() resorts * to rb_hash_aset(), which should call #hash for `obj`. */ // attr bool leaf = false; /* has rb_funcall() */ /* calls #hash */ +// attr bool zjit_profile = true; { val = vm_opt_aset(recv, obj, set); diff --git a/zjit/src/cruby_bindings.inc.rs b/zjit/src/cruby_bindings.inc.rs index ea1bf68acc..6e3ae05194 100644 --- a/zjit/src/cruby_bindings.inc.rs +++ b/zjit/src/cruby_bindings.inc.rs @@ -694,12 +694,14 @@ pub const YARVINSN_zjit_opt_lt: ruby_vminsn_type = 229; pub const YARVINSN_zjit_opt_le: ruby_vminsn_type = 230; pub const YARVINSN_zjit_opt_gt: ruby_vminsn_type = 231; pub const YARVINSN_zjit_opt_ge: ruby_vminsn_type = 232; -pub const YARVINSN_zjit_opt_and: ruby_vminsn_type = 233; -pub const YARVINSN_zjit_opt_or: ruby_vminsn_type = 234; -pub const YARVINSN_zjit_opt_aref: ruby_vminsn_type = 235; -pub const YARVINSN_zjit_opt_empty_p: ruby_vminsn_type = 236; -pub const YARVINSN_zjit_opt_not: ruby_vminsn_type = 237; -pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 238; +pub const YARVINSN_zjit_opt_ltlt: ruby_vminsn_type = 233; +pub const YARVINSN_zjit_opt_and: ruby_vminsn_type = 234; +pub const YARVINSN_zjit_opt_or: ruby_vminsn_type = 235; +pub const YARVINSN_zjit_opt_aref: ruby_vminsn_type = 236; +pub const YARVINSN_zjit_opt_aset: ruby_vminsn_type = 237; +pub const YARVINSN_zjit_opt_empty_p: ruby_vminsn_type = 238; +pub const YARVINSN_zjit_opt_not: ruby_vminsn_type = 239; +pub const VM_INSTRUCTION_SIZE: ruby_vminsn_type = 240; pub type ruby_vminsn_type = u32; pub type rb_iseq_callback = ::std::option::Option< unsafe extern "C" fn(arg1: *const rb_iseq_t, arg2: *mut ::std::os::raw::c_void), diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index e32c15702e..022451e8ab 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -12817,4 +12817,63 @@ mod opt_tests { Return v25 "); } + + #[test] + fn test_optimize_array_aset() { + eval(" + def test(arr) + arr[1] = 10 + end + test([]) + "); + assert_snapshot!(hir_string("test"), @r" + fn test@<compiled>:3: + bb0(): + EntryPoint interpreter + v1:BasicObject = LoadSelf + v2:BasicObject = GetLocal l0, SP@4 + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT(0) + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v14:Fixnum[1] = Const Value(1) + v15:Fixnum[10] = Const Value(10) + PatchPoint MethodRedefined(Array@0x1000, []=@0x1008, cme:0x1010) + PatchPoint NoSingletonClass(Array@0x1000) + v28:ArrayExact = GuardType v9, ArrayExact + v29:BasicObject = CCallVariadic []=@0x1038, v28, v14, v15 + CheckInterrupts + Return v15 + "); + } + + #[test] + fn test_optimize_array_ltlt() { + eval(" + def test(arr) + arr << 1 + end + test([]) + "); + assert_snapshot!(hir_string("test"), @r" + fn test@<compiled>:3: + bb0(): + EntryPoint interpreter + v1:BasicObject = LoadSelf + v2:BasicObject = GetLocal l0, SP@4 + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT(0) + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + v13:Fixnum[1] = Const Value(1) + PatchPoint MethodRedefined(Array@0x1000, <<@0x1008, cme:0x1010) + PatchPoint NoSingletonClass(Array@0x1000) + v26:ArrayExact = GuardType v9, ArrayExact + v27:BasicObject = CCallWithFrame <<@0x1038, v26, v13 + CheckInterrupts + Return v27 + "); + } } diff --git a/zjit/src/profile.rs b/zjit/src/profile.rs index 67f2fdc740..c2c35f687b 100644 --- a/zjit/src/profile.rs +++ b/zjit/src/profile.rs @@ -74,6 +74,8 @@ fn profile_insn(bare_opcode: ruby_vminsn_type, ec: EcPtr) { YARVINSN_opt_or => profile_operands(profiler, profile, 2), YARVINSN_opt_empty_p => profile_operands(profiler, profile, 1), YARVINSN_opt_aref => profile_operands(profiler, profile, 2), + YARVINSN_opt_ltlt => profile_operands(profiler, profile, 2), + YARVINSN_opt_aset => profile_operands(profiler, profile, 3), YARVINSN_opt_not => profile_operands(profiler, profile, 1), YARVINSN_getinstancevariable => profile_self(profiler, profile), YARVINSN_objtostring => profile_operands(profiler, profile, 1), |
