Feature #18897
closedAdd a new instruction for sending messages to ephemeral stack arrays
Description
This feature is an alternative to Feature #18825. Instead of adding a new instruction specifically for the .hash
method, this patch replaces opt_newarray_max
and opt_newarray_min
with a new instruction opt_newarray_send
. opt_newarray_send
only operates on arrays that will temporarily be on the Ruby stack.
Take the following code for example:
[@a, @b].max
[@a, @b].min
[@a, @b].hash
In all three cases the compiler can detect that we have an array literal pushed on the stack and instead of allocating a new array and calling the corresponding method, we emit the opt_newarray_send
instruction which knows that the contents of the array will temporarily be on the stack (as min
, max
, and hash
will not push the array back on the stack).
If any of these methods are monkeypatched, opt_newarray_send
will allocate a Ruby array and fall back to doing a normal method call.
The benefit of this instruction is that we can avoid allocating a Ruby array and also avoid pushing a stack frame. The downside is that elimination of the frame might be a problem for profilers, but min
and max
already eliminate this frame so maybe it's fine.
The above code will emit the following instructions:
$ cat test.rb
[@a, @b].max
[@a, @b].min
[@a, @b].hash
$ ./miniruby --dump=insns test.rb
== disasm: #<ISeq:<main>@test.rb:1 (1,0)-(3,13)> (catch: FALSE)
0000 getinstancevariable :@a, <is:0> ( 1)[Li]
0003 getinstancevariable :@b, <is:1>
0006 opt_newarray_send 2, :max
0009 pop
0010 getinstancevariable :@a, <is:0> ( 2)[Li]
0013 getinstancevariable :@b, <is:1>
0016 opt_newarray_send 2, :min
0019 pop
0020 getinstancevariable :@a, <is:0> ( 3)[Li]
0023 getinstancevariable :@b, <is:1>
0026 opt_newarray_send 2, :hash
0029 leave
Files