summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vm_insnhelper.c6
-rw-r--r--yjit/src/codegen.rs35
-rw-r--r--yjit/src/stats.rs1
3 files changed, 42 insertions, 0 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index f4aeb7fc34..ca4cca4707 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -6939,6 +6939,12 @@ vm_opt_aset_with(VALUE recv, VALUE key, VALUE val)
}
}
+VALUE
+rb_vm_opt_aset_with(VALUE recv, VALUE key, VALUE value)
+{
+ return vm_opt_aset_with(recv, key, value);
+}
+
static VALUE
vm_opt_length(VALUE recv, int bop)
{
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index b608f98462..7cc4aff473 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -3891,6 +3891,40 @@ fn gen_opt_aref(
}
}
+fn gen_opt_aset_with(
+ jit: &mut JITState,
+ asm: &mut Assembler,
+) -> Option<CodegenStatus> {
+ // We might allocate or raise
+ jit_prepare_non_leaf_call(jit, asm);
+
+ let key_opnd = Opnd::Value(jit.get_arg(0));
+ let recv_opnd = asm.stack_opnd(1);
+ let value_opnd = asm.stack_opnd(0);
+
+ extern "C" {
+ fn rb_vm_opt_aset_with(recv: VALUE, key: VALUE, value: VALUE) -> VALUE;
+ }
+
+ let val_opnd = asm.ccall(
+ rb_vm_opt_aset_with as *const u8,
+ vec![
+ recv_opnd,
+ key_opnd,
+ value_opnd,
+ ],
+ );
+ asm.stack_pop(2); // Keep it on stack during GC
+
+ asm.cmp(val_opnd, Qundef.into());
+ asm.je(Target::side_exit(Counter::opt_aset_with_qundef));
+
+ let top = asm.stack_push(Type::Unknown);
+ asm.mov(top, val_opnd);
+
+ return Some(KeepCompiling);
+}
+
fn gen_opt_aset(
jit: &mut JITState,
asm: &mut Assembler,
@@ -10753,6 +10787,7 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
YARVINSN_opt_aref => Some(gen_opt_aref),
YARVINSN_opt_aset => Some(gen_opt_aset),
YARVINSN_opt_aref_with => Some(gen_opt_aref_with),
+ YARVINSN_opt_aset_with => Some(gen_opt_aset_with),
YARVINSN_opt_mult => Some(gen_opt_mult),
YARVINSN_opt_div => Some(gen_opt_div),
YARVINSN_opt_ltlt => Some(gen_opt_ltlt),
diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs
index 8cbf3ab317..ba84b7a549 100644
--- a/yjit/src/stats.rs
+++ b/yjit/src/stats.rs
@@ -520,6 +520,7 @@ make_counters! {
opt_aset_not_hash,
opt_aref_with_qundef,
+ opt_aset_with_qundef,
opt_case_dispatch_megamorphic,