summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--insns.def2
-rw-r--r--zjit/src/cruby_bindings.inc.rs14
-rw-r--r--zjit/src/hir.rs59
-rw-r--r--zjit/src/profile.rs2
4 files changed, 71 insertions, 6 deletions
diff --git a/insns.def b/insns.def
index eef0d3f5dc..b895bffe22 100644
--- a/insns.def
+++ b/insns.def
@@ -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),