From c5fc1ce975ecdf1c6818714e47579c5d3531c4ca Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 6 Jun 2022 17:27:56 -0700 Subject: 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: #@-e:1 (1,0)-(1,12)> (catch: FALSE) 0000 getinstancevariable :@a, ( 1)[Li] 0003 getinstancevariable :@b, 0006 opt_newarray_send 2, :max 0009 leave $ ./miniruby --dump=insns -e '[@a, @b].min' == disasm: #@-e:1 (1,0)-(1,12)> (catch: FALSE) 0000 getinstancevariable :@a, ( 1)[Li] 0003 getinstancevariable :@b, 0006 opt_newarray_send 2, :min 0009 leave $ ./miniruby --dump=insns -e '[@a, @b].hash' == disasm: #@-e:1 (1,0)-(1,13)> (catch: FALSE) 0000 getinstancevariable :@a, ( 1)[Li] 0003 getinstancevariable :@b, 0006 opt_newarray_send 2, :hash 0009 leave ``` [Feature #18897] [ruby-core:109147] Co-authored-by: John Hawthorn --- vm_insnhelper.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'vm_insnhelper.c') 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 -- cgit v1.2.1