3737 ***** END LICENSE BLOCK *****/
3838package org .jruby ;
3939
40+ import java .io .IOException ;
41+ import java .lang .reflect .Array ;
42+ import java .math .BigInteger ;
43+ import java .util .ArrayList ;
44+ import java .util .Arrays ;
45+ import java .util .Collection ;
46+ import java .util .Comparator ;
47+ import java .util .IdentityHashMap ;
48+ import java .util .Iterator ;
49+ import java .util .List ;
50+ import java .util .ListIterator ;
51+ import java .util .RandomAccess ;
4052import org .jcodings .specific .USASCIIEncoding ;
4153import org .jruby .anno .JRubyClass ;
4254import org .jruby .anno .JRubyMethod ;
6981import org .jruby .util .TypeConverter ;
7082import org .jruby .util .cli .Options ;
7183
72- import java .io .IOException ;
73- import java .lang .reflect .Array ;
74- import java .math .BigInteger ;
75- import java .util .ArrayList ;
76- import java .util .Arrays ;
77- import java .util .Collection ;
78- import java .util .Comparator ;
79- import java .util .IdentityHashMap ;
80- import java .util .Iterator ;
81- import java .util .List ;
82- import java .util .ListIterator ;
83- import java .util .RandomAccess ;
84-
84+ import static org .jruby .RubyEnumerator .SizeFn ;
8585import static org .jruby .RubyEnumerator .enumeratorize ;
8686import static org .jruby .RubyEnumerator .enumeratorizeWithSize ;
8787import static org .jruby .runtime .Helpers .arrayOf ;
8888import static org .jruby .runtime .Helpers .hashEnd ;
8989import static org .jruby .runtime .Helpers .murmurCombine ;
9090import static org .jruby .runtime .Visibility .PRIVATE ;
91- import static org .jruby .RubyEnumerator .SizeFn ;
9291
9392/**
9493 * The implementation of the built-in class Array in Ruby.
@@ -246,37 +245,59 @@ public static RubyArray newEmptyArray(Ruby runtime) {
246245 *
247246 */
248247 public static RubyArray newArray (Ruby runtime , IRubyObject [] args ) {
249- switch (args .length ) {
250- case 0 :
251- return newEmptyArray (runtime );
252- case 1 :
253- if (USE_PACKED_ARRAYS ) return new RubyArrayOneObject (runtime , args [0 ]);
254- break ;
255- case 2 :
256- if (USE_PACKED_ARRAYS ) return new RubyArrayTwoObject (runtime , args [0 ], args [1 ]);
257- break ;
248+ final int size = args .length ;
249+ if (size == 0 ) {
250+ return newEmptyArray (runtime );
258251 }
259- RubyArray arr = new RubyArray (runtime , new IRubyObject [args .length ]);
260- System .arraycopy (args , 0 , arr .values , 0 , args .length );
261- arr .realLength = args .length ;
262- return arr ;
252+ return isPackedArray (size ) ? packedArray (runtime , args )
253+ : new RubyArray (runtime , args .clone ());
254+ }
255+
256+ public static RubyArray newArray (Ruby runtime , Collection <? extends IRubyObject > collection ) {
257+ if (collection .isEmpty ()) {
258+ return newEmptyArray (runtime );
259+ }
260+ final IRubyObject [] arr = collection .toArray (IRubyObject .NULL_ARRAY );
261+ return isPackedArray (collection ) ? packedArray (runtime , arr ) : new RubyArray (runtime , arr );
263262 }
264263
264+ public static RubyArray newArray (Ruby runtime , List <? extends IRubyObject > list ) {
265+ if (list .isEmpty ()) {
266+ return newEmptyArray (runtime );
267+ }
268+ return isPackedArray (list ) ? packedArray (runtime , list )
269+ : new RubyArray (runtime , list .toArray (IRubyObject .NULL_ARRAY ));
270+ }
271+
272+ private static RubyArray packedArray (final Ruby runtime , final IRubyObject [] args ) {
273+ if (args .length == 1 ) {
274+ return new RubyArrayOneObject (runtime , args [0 ]);
275+ } else {
276+ return new RubyArrayTwoObject (runtime , args [0 ], args [1 ]);
277+ }
278+ }
279+
280+ private static RubyArray packedArray (final Ruby runtime , final List <? extends IRubyObject > args ) {
281+ if (args .size () == 1 ) {
282+ return new RubyArrayOneObject (runtime , args .get (0 ));
283+ } else {
284+ return new RubyArrayTwoObject (runtime , args .get (0 ), args .get (1 ));
285+ }
286+ }
287+
288+ private static boolean isPackedArray (final int size ) {
289+ return USE_PACKED_ARRAYS && size <= 2 ;
290+ }
291+
292+ private static boolean isPackedArray (final Collection <? extends IRubyObject > collection ) {
293+ return USE_PACKED_ARRAYS && collection .size () <= 2 ;
294+ }
295+
265296 /**
266297 * @see RubyArray#newArrayMayCopy(Ruby, IRubyObject[], int, int)
267298 */
268299 public static RubyArray newArrayMayCopy (Ruby runtime , IRubyObject ... args ) {
269- switch (args .length ) {
270- case 0 :
271- return newEmptyArray (runtime );
272- case 1 :
273- if (USE_PACKED_ARRAYS ) return new RubyArrayOneObject (runtime , args [0 ]);
274- break ;
275- case 2 :
276- if (USE_PACKED_ARRAYS ) return new RubyArrayTwoObject (runtime , args [0 ], args [1 ]);
277- break ;
278- }
279- return newArrayNoCopy (runtime , args , 0 , args .length );
300+ return newArrayMayCopy (runtime , args , 0 , args .length );
280301 }
281302
282303 /**
@@ -299,15 +320,16 @@ public static RubyArray newArrayMayCopy(Ruby runtime, IRubyObject[] args, int st
299320 * @return an array referencing the given elements
300321 */
301322 public static RubyArray newArrayMayCopy (Ruby runtime , IRubyObject [] args , int start , int length ) {
302- switch (length ) {
303- case 0 :
304- return newEmptyArray (runtime );
305- case 1 :
306- if (USE_PACKED_ARRAYS ) return new RubyArrayOneObject (runtime , args [start ]);
307- break ;
308- case 2 :
309- if (USE_PACKED_ARRAYS ) return new RubyArrayTwoObject (runtime , args [start ], args [start + 1 ]);
310- break ;
323+ if (length == 0 ) {
324+ return newEmptyArray (runtime );
325+ }
326+ if (USE_PACKED_ARRAYS ) {
327+ if (length == 1 ) {
328+ return new RubyArrayOneObject (runtime , args [start ]);
329+ }
330+ if (length == 2 ) {
331+ return new RubyArrayTwoObject (runtime , args [start ], args [start + 1 ]);
332+ }
311333 }
312334 return newArrayNoCopy (runtime , args , start , length );
313335 }
@@ -334,35 +356,6 @@ public static RubyArray newArrayNoCopyLight(Ruby runtime, IRubyObject[] args) {
334356 return arr ;
335357 }
336358
337- public static RubyArray newArray (Ruby runtime , Collection <? extends IRubyObject > collection ) {
338- // This may seem inefficient for packed arrays, but the cost of this versus is not really worse
339- // than the cost of constructing and walking an Iterator.
340- IRubyObject [] values = collection .toArray (new IRubyObject [collection .size ()]);
341- switch (values .length ) {
342- case 0 : return newEmptyArray (runtime );
343- case 1 :
344- if (USE_PACKED_ARRAYS ) return new RubyArrayOneObject (runtime , values [0 ]);
345- break ;
346- case 2 :
347- if (USE_PACKED_ARRAYS ) return new RubyArrayTwoObject (runtime , values [0 ], values [1 ]);
348- break ;
349- }
350- return new RubyArray (runtime , values );
351- }
352-
353- public static RubyArray newArray (Ruby runtime , List <? extends IRubyObject > list ) {
354- switch (list .size ()) {
355- case 0 : return newEmptyArray (runtime );
356- case 1 :
357- if (USE_PACKED_ARRAYS ) return new RubyArrayOneObject (runtime , list .get (0 ));
358- break ;
359- case 2 :
360- if (USE_PACKED_ARRAYS ) return new RubyArrayTwoObject (runtime , list .get (0 ), list .get (1 ));
361- break ;
362- }
363- return new RubyArray (runtime , list .toArray (new IRubyObject [list .size ()]));
364- }
365-
366359 public static final int ARRAY_DEFAULT_SIZE = 16 ;
367360
368361 // volatile to ensure that initial nil-fill is visible to other threads
@@ -3828,7 +3821,7 @@ public IRubyObject size(IRubyObject[] args) {
38283821 };
38293822 }
38303823
3831- private IRubyObject binomialCoefficient (ThreadContext context , long comb , long size ) {
3824+ private static IRubyObject binomialCoefficient (ThreadContext context , long comb , long size ) {
38323825 Ruby runtime = context .runtime ;
38333826 if (comb > size - comb ) {
38343827 comb = size - comb ;
@@ -4029,7 +4022,7 @@ public IRubyObject size(IRubyObject[] args) {
40294022 };
40304023 }
40314024
4032- private IRubyObject descendingFactorial (ThreadContext context , long from , long howMany ) {
4025+ private static IRubyObject descendingFactorial (ThreadContext context , long from , long howMany ) {
40334026 Ruby runtime = context .runtime ;
40344027 IRubyObject cnt = howMany >= 0 ? RubyFixnum .one (runtime ) : RubyFixnum .zero (runtime );
40354028 CallSite op_times = sites (context ).op_times ;
@@ -4059,7 +4052,7 @@ public IRubyObject shuffle_bang(ThreadContext context, IRubyObject[] args) {
40594052 if (args .length > 0 ) {
40604053 IRubyObject hash = TypeConverter .checkHashType (context .runtime , args [args .length - 1 ]);
40614054 if (!hash .isNil ()) {
4062- IRubyObject [] rets = ArgsUtil .extractKeywordArgs (context , (RubyHash ) hash , new String [] { "random" } );
4055+ IRubyObject [] rets = ArgsUtil .extractKeywordArgs (context , (RubyHash ) hash , "random" );
40634056 if (!rets [0 ].isNil ()) randgen = rets [0 ];
40644057 }
40654058 }
@@ -4100,7 +4093,7 @@ public IRubyObject sample(ThreadContext context, IRubyObject[] args) {
41004093 if (args .length > 0 ) {
41014094 IRubyObject hash = TypeConverter .checkHashType (context .runtime , args [args .length - 1 ]);
41024095 if (!hash .isNil ()) {
4103- IRubyObject [] rets = ArgsUtil .extractKeywordArgs (context , (RubyHash ) hash , new String [] { "random" } );
4096+ IRubyObject [] rets = ArgsUtil .extractKeywordArgs (context , (RubyHash ) hash , "random" );
41044097 if (!rets [0 ].isNil ()) randgen = rets [0 ];
41054098 args = ArraySupport .newCopy (args , args .length - 1 );
41064099 }
@@ -4792,7 +4785,7 @@ public IRubyObject min(ThreadContext context, IRubyObject num, Block block) {
47924785 }
47934786
47944787 private static final int optimizedCmp (ThreadContext context , IRubyObject a , IRubyObject b , int token , CachingCallSite op_cmp , CallSite op_gt , CallSite op_lt ) {
4795- if (token == (( RubyBasicObject ) a ) .getMetaClass ().generation ) {
4788+ if (token == a .getMetaClass ().generation ) {
47964789 if (a instanceof RubyFixnum && b instanceof RubyFixnum ) {
47974790 long aLong = ((RubyFixnum ) a ).getLongValue ();
47984791 long bLong = ((RubyFixnum ) b ).getLongValue ();
0 commit comments