aboutsummaryrefslogtreecommitdiffstats
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2022-06-06 17:27:56 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2023-04-18 17:16:22 -0700
commitc5fc1ce975ecdf1c6818714e47579c5d3531c4ca (patch)
tree77a0f348d00a99281f826dac90e1d288c3139051 /vm_insnhelper.c
parent3016f30c956413268655dcb25dbe5041684f9528 (diff)
downloadruby-c5fc1ce975ecdf1c6818714e47579c5d3531c4ca.tar.gz
Emit special instruction for array literal + .(hash|min|max)
This commit introduces a new instruction `opt_newarray_send` which is used when there is an array literal followed by either the `hash`, `min`, or `max` method. ``` [a, b, c].hash ``` Will emit an `opt_newarray_send` instruction. This instruction falls back to a method call if the "interested" method has been monkey patched. Here are some examples of the instructions generated: ``` $ ./miniruby --dump=insns -e '[@a, @b].max' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE) 0000 getinstancevariable :@a, <is:0> ( 1)[Li] 0003 getinstancevariable :@b, <is:1> 0006 opt_newarray_send 2, :max 0009 leave $ ./miniruby --dump=insns -e '[@a, @b].min' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE) 0000 getinstancevariable :@a, <is:0> ( 1)[Li] 0003 getinstancevariable :@b, <is:1> 0006 opt_newarray_send 2, :min 0009 leave $ ./miniruby --dump=insns -e '[@a, @b].hash' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,13)> (catch: FALSE) 0000 getinstancevariable :@a, <is:0> ( 1)[Li] 0003 getinstancevariable :@b, <is:1> 0006 opt_newarray_send 2, :hash 0009 leave ``` [Feature #18897] [ruby-core:109147] Co-authored-by: John Hawthorn <jhawthorn@github.com>
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index f4894225d7..c9805377ff 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -5377,6 +5377,18 @@ rb_vm_opt_newarray_min(rb_execution_context_t *ec, rb_num_t num, const VALUE *pt
return vm_opt_newarray_min(ec, num, ptr);
}
+static VALUE
+vm_opt_newarray_hash(rb_execution_context_t *ec, rb_num_t num, const VALUE *ptr)
+{
+ // If Array#hash is _not_ monkeypatched, use the optimized call
+ if (BASIC_OP_UNREDEFINED_P(BOP_HASH, ARRAY_REDEFINED_OP_FLAG)) {
+ return rb_ary_hash_values(num, ptr);
+ }
+ else {
+ return rb_vm_call_with_refinements(ec, rb_ary_new4(num, ptr), idHash, 0, NULL, RB_NO_KEYWORDS);
+ }
+}
+
#undef id_cmp
#define IMEMO_CONST_CACHE_SHAREABLE IMEMO_FL_USER0