Project

General

Profile

« Previous | Next » 

Revision 6e06d0d1

Added by jeremyevans (Jeremy Evans) almost 2 years ago

Add concattoarray VM instruction

This instruction is similar to concatarray, but assumes the first
object is already an array, and appends to it directly. This is
different than concatarray, which will create a new array instead
of appending to an existing array.

Additionally, for both concatarray and concattoarray, if the second
argument cannot be converted to an array, then just push it onto
the array, instead of creating a new array to wrap it, and then
using concat array. This saves an array allocation in that case.

This allows f(*a, *a, *1) to allocate only a single array on the
caller side (which can be reused on the callee side in the case of
def f(*a)). Prior to this commit, f(*a, *a, *1) would generate
4 arrays:

  • a dupped by splatarray true
  • a dupped again by first concatarray
  • 1 wrapped in array by third splatarray
  • result of [*a, *a] dupped by second concatarray

Instructions Before for a = []; f(*a, *a, *1):

0000 newarray 0 ( 1)[Li] 0002 setlocal_WC_0 a@0 0004 putself 0005 getlocal_WC_0 a@0 0007 splatarray true 0009 getlocal_WC_0 a@0 0011 splatarray false 0013 concatarray 0014 putobject_INT2FIX_1_ 0015 splatarray false 0017 concatarray 0018 opt_send_without_block <calldata!mid:g, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL> 0020 leave 

Instructions After for a = []; f(*a, *a, *1):

0000 newarray 0 ( 1)[Li] 0002 setlocal_WC_0 a@0 0004 putself 0005 getlocal_WC_0 a@0 0007 splatarray true 0009 getlocal_WC_0 a@0 0011 concattoarray 0012 putobject_INT2FIX_1_ 0013 concattoarray 0014 opt_send_without_block <calldata!mid:f, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL> 0016 leave