aboutsummaryrefslogtreecommitdiffstats
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
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.
-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;
+ }
+ }
}
}