aboutsummaryrefslogtreecommitdiffstats
path: root/compile.c
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2023-11-06 13:03:02 -0800
committerJeremy Evans <code@jeremyevans.net>2023-12-07 11:27:55 -0800
commit5e33f2b0e4c262ed0c7e524b11d020438c41f532 (patch)
tree0692f0120d7b5dc8ac08c5034d992f5c90f9249b /compile.c
parent95615872e32156d9add8fd3afd136dd73fd6aa1a (diff)
downloadruby-5e33f2b0e4c262ed0c7e524b11d020438c41f532.tar.gz
Eliminate array allocation for f(*a, kw: 1)
In cases where the compiler can detect the hash is static, it would use duphash for the hash part. As the hash is static, there is no need to allocate an array.
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/compile.c b/compile.c
index 2a56579b98..f6236ebcc5 100644
--- a/compile.c
+++ b/compile.c
@@ -3917,6 +3917,29 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
}
}
}
+ } else if (IS_NEXT_INSN_ID(niobj, duphash)) {
+ niobj = niobj->next;
+
+ /*
+ * Eliminate array allocation for f(*a, kw: 1)
+ *
+ * splatarray true
+ * duphash
+ * send ARGS_SPLAT|KW_SPLAT|KW_SPLAT_MUT and not ARGS_BLOCKARG
+ * =>
+ * splatarray false
+ * duphash
+ * send
+ */
+ if (IS_NEXT_INSN_ID(niobj, send)) {
+ niobj = niobj->next;
+ unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
+
+ if ((flag & VM_CALL_ARGS_SPLAT) && (flag & VM_CALL_KW_SPLAT) &&
+ (flag & VM_CALL_KW_SPLAT_MUT) && !(flag & VM_CALL_ARGS_BLOCKARG)) {
+ OPERAND_AT(iobj, 0) = Qfalse;
+ }
+ }
}
}