Skip to content

Commit 1f9c110

Browse files
committed
8301958: Reduce Arrays.copyOf/-Range overheads
Reviewed-by: alanb, smarks
1 parent cb81073 commit 1f9c110

File tree

2 files changed

+188
-30
lines changed

2 files changed

+188
-30
lines changed

Diff for: src/java.base/share/classes/java/util/Arrays.java

+168-16
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
package java.util;
2727

2828
import jdk.internal.util.ArraysSupport;
29+
import jdk.internal.vm.annotation.ForceInline;
2930
import jdk.internal.vm.annotation.IntrinsicCandidate;
3031

3132
import java.io.Serializable;
@@ -3534,12 +3535,22 @@ public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]>
35343535
* @since 1.6
35353536
*/
35363537
public static byte[] copyOf(byte[] original, int newLength) {
3538+
if (newLength == original.length) {
3539+
return copyOf(original);
3540+
}
35373541
byte[] copy = new byte[newLength];
35383542
System.arraycopy(original, 0, copy, 0,
35393543
Math.min(original.length, newLength));
35403544
return copy;
35413545
}
35423546

3547+
@ForceInline
3548+
private static byte[] copyOf(byte[] original) {
3549+
byte[] copy = new byte[original.length];
3550+
System.arraycopy(original, 0, copy, 0, original.length);
3551+
return copy;
3552+
}
3553+
35433554
/**
35443555
* Copies the specified array, truncating or padding with zeros (if necessary)
35453556
* so the copy has the specified length. For all indices that are
@@ -3558,12 +3569,22 @@ public static byte[] copyOf(byte[] original, int newLength) {
35583569
* @since 1.6
35593570
*/
35603571
public static short[] copyOf(short[] original, int newLength) {
3572+
if (newLength == original.length) {
3573+
return copyOf(original);
3574+
}
35613575
short[] copy = new short[newLength];
35623576
System.arraycopy(original, 0, copy, 0,
35633577
Math.min(original.length, newLength));
35643578
return copy;
35653579
}
35663580

3581+
@ForceInline
3582+
private static short[] copyOf(short[] original) {
3583+
short[] copy = new short[original.length];
3584+
System.arraycopy(original, 0, copy, 0, original.length);
3585+
return copy;
3586+
}
3587+
35673588
/**
35683589
* Copies the specified array, truncating or padding with zeros (if necessary)
35693590
* so the copy has the specified length. For all indices that are
@@ -3582,12 +3603,22 @@ public static short[] copyOf(short[] original, int newLength) {
35823603
* @since 1.6
35833604
*/
35843605
public static int[] copyOf(int[] original, int newLength) {
3606+
if (newLength == original.length) {
3607+
return copyOf(original);
3608+
}
35853609
int[] copy = new int[newLength];
35863610
System.arraycopy(original, 0, copy, 0,
35873611
Math.min(original.length, newLength));
35883612
return copy;
35893613
}
35903614

3615+
@ForceInline
3616+
private static int[] copyOf(int[] original) {
3617+
int[] copy = new int[original.length];
3618+
System.arraycopy(original, 0, copy, 0, original.length);
3619+
return copy;
3620+
}
3621+
35913622
/**
35923623
* Copies the specified array, truncating or padding with zeros (if necessary)
35933624
* so the copy has the specified length. For all indices that are
@@ -3606,12 +3637,22 @@ public static int[] copyOf(int[] original, int newLength) {
36063637
* @since 1.6
36073638
*/
36083639
public static long[] copyOf(long[] original, int newLength) {
3640+
if (newLength == original.length) {
3641+
return copyOf(original);
3642+
}
36093643
long[] copy = new long[newLength];
36103644
System.arraycopy(original, 0, copy, 0,
36113645
Math.min(original.length, newLength));
36123646
return copy;
36133647
}
36143648

3649+
@ForceInline
3650+
private static long[] copyOf(long[] original) {
3651+
long[] copy = new long[original.length];
3652+
System.arraycopy(original, 0, copy, 0, original.length);
3653+
return copy;
3654+
}
3655+
36153656
/**
36163657
* Copies the specified array, truncating or padding with null characters (if necessary)
36173658
* so the copy has the specified length. For all indices that are valid
@@ -3630,12 +3671,22 @@ public static long[] copyOf(long[] original, int newLength) {
36303671
* @since 1.6
36313672
*/
36323673
public static char[] copyOf(char[] original, int newLength) {
3674+
if (newLength == original.length) {
3675+
return copyOf(original);
3676+
}
36333677
char[] copy = new char[newLength];
36343678
System.arraycopy(original, 0, copy, 0,
36353679
Math.min(original.length, newLength));
36363680
return copy;
36373681
}
36383682

3683+
@ForceInline
3684+
private static char[] copyOf(char[] original) {
3685+
char[] copy = new char[original.length];
3686+
System.arraycopy(original, 0, copy, 0, original.length);
3687+
return copy;
3688+
}
3689+
36393690
/**
36403691
* Copies the specified array, truncating or padding with zeros (if necessary)
36413692
* so the copy has the specified length. For all indices that are
@@ -3654,12 +3705,22 @@ public static char[] copyOf(char[] original, int newLength) {
36543705
* @since 1.6
36553706
*/
36563707
public static float[] copyOf(float[] original, int newLength) {
3708+
if (newLength == original.length) {
3709+
return copyOf(original);
3710+
}
36573711
float[] copy = new float[newLength];
36583712
System.arraycopy(original, 0, copy, 0,
36593713
Math.min(original.length, newLength));
36603714
return copy;
36613715
}
36623716

3717+
@ForceInline
3718+
private static float[] copyOf(float[] original) {
3719+
float[] copy = new float[original.length];
3720+
System.arraycopy(original, 0, copy, 0, original.length);
3721+
return copy;
3722+
}
3723+
36633724
/**
36643725
* Copies the specified array, truncating or padding with zeros (if necessary)
36653726
* so the copy has the specified length. For all indices that are
@@ -3678,12 +3739,22 @@ public static float[] copyOf(float[] original, int newLength) {
36783739
* @since 1.6
36793740
*/
36803741
public static double[] copyOf(double[] original, int newLength) {
3742+
if (newLength == original.length) {
3743+
return copyOf(original);
3744+
}
36813745
double[] copy = new double[newLength];
36823746
System.arraycopy(original, 0, copy, 0,
36833747
Math.min(original.length, newLength));
36843748
return copy;
36853749
}
36863750

3751+
@ForceInline
3752+
private static double[] copyOf(double[] original) {
3753+
double[] copy = new double[original.length];
3754+
System.arraycopy(original, 0, copy, 0, original.length);
3755+
return copy;
3756+
}
3757+
36873758
/**
36883759
* Copies the specified array, truncating or padding with {@code false} (if necessary)
36893760
* so the copy has the specified length. For all indices that are
@@ -3702,12 +3773,22 @@ public static double[] copyOf(double[] original, int newLength) {
37023773
* @since 1.6
37033774
*/
37043775
public static boolean[] copyOf(boolean[] original, int newLength) {
3776+
if (newLength == original.length) {
3777+
return copyOf(original);
3778+
}
37053779
boolean[] copy = new boolean[newLength];
37063780
System.arraycopy(original, 0, copy, 0,
37073781
Math.min(original.length, newLength));
37083782
return copy;
37093783
}
37103784

3785+
@ForceInline
3786+
private static boolean[] copyOf(boolean[] original) {
3787+
boolean[] copy = new boolean[original.length];
3788+
System.arraycopy(original, 0, copy, 0, original.length);
3789+
return copy;
3790+
}
3791+
37113792
/**
37123793
* Copies the specified range of the specified array into a new array.
37133794
* The initial index of the range ({@code from}) must lie between zero
@@ -3789,6 +3870,13 @@ public static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? exte
37893870
return copy;
37903871
}
37913872

3873+
@ForceInline
3874+
private static void checkLength(int from, int to) {
3875+
if (to < from) {
3876+
throw new IllegalArgumentException(from + " > " + to);
3877+
}
3878+
}
3879+
37923880
/**
37933881
* Copies the specified range of the specified array into a new array.
37943882
* The initial index of the range ({@code from}) must lie between zero
@@ -3816,9 +3904,17 @@ public static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? exte
38163904
* @since 1.6
38173905
*/
38183906
public static byte[] copyOfRange(byte[] original, int from, int to) {
3907+
// Tickle the JIT to fold special cases optimally
3908+
if (from != 0 || to != original.length)
3909+
return copyOfRangeByte(original, from, to);
3910+
else // from == 0 && to == original.length
3911+
return copyOf(original);
3912+
}
3913+
3914+
@ForceInline
3915+
private static byte[] copyOfRangeByte(byte[] original, int from, int to) {
3916+
checkLength(from, to);
38193917
int newLength = to - from;
3820-
if (newLength < 0)
3821-
throw new IllegalArgumentException(from + " > " + to);
38223918
byte[] copy = new byte[newLength];
38233919
System.arraycopy(original, from, copy, 0,
38243920
Math.min(original.length - from, newLength));
@@ -3852,9 +3948,17 @@ public static byte[] copyOfRange(byte[] original, int from, int to) {
38523948
* @since 1.6
38533949
*/
38543950
public static short[] copyOfRange(short[] original, int from, int to) {
3951+
// Tickle the JIT to fold special cases optimally
3952+
if (from != 0 || to != original.length)
3953+
return copyOfRangeShort(original, from, to);
3954+
else // from == 0 && to == original.length
3955+
return copyOf(original);
3956+
}
3957+
3958+
@ForceInline
3959+
private static short[] copyOfRangeShort(short[] original, int from, int to) {
3960+
checkLength(from, to);
38553961
int newLength = to - from;
3856-
if (newLength < 0)
3857-
throw new IllegalArgumentException(from + " > " + to);
38583962
short[] copy = new short[newLength];
38593963
System.arraycopy(original, from, copy, 0,
38603964
Math.min(original.length - from, newLength));
@@ -3888,9 +3992,17 @@ public static short[] copyOfRange(short[] original, int from, int to) {
38883992
* @since 1.6
38893993
*/
38903994
public static int[] copyOfRange(int[] original, int from, int to) {
3995+
// Tickle the JIT to fold special cases optimally
3996+
if (from != 0 || to != original.length)
3997+
return copyOfRangeInt(original, from, to);
3998+
else // from == 0 && to == original.length
3999+
return copyOf(original);
4000+
}
4001+
4002+
@ForceInline
4003+
private static int[] copyOfRangeInt(int[] original, int from, int to) {
4004+
checkLength(from, to);
38914005
int newLength = to - from;
3892-
if (newLength < 0)
3893-
throw new IllegalArgumentException(from + " > " + to);
38944006
int[] copy = new int[newLength];
38954007
System.arraycopy(original, from, copy, 0,
38964008
Math.min(original.length - from, newLength));
@@ -3924,9 +4036,17 @@ public static int[] copyOfRange(int[] original, int from, int to) {
39244036
* @since 1.6
39254037
*/
39264038
public static long[] copyOfRange(long[] original, int from, int to) {
4039+
// Tickle the JIT to fold special cases optimally
4040+
if (from != 0 || to != original.length)
4041+
return copyOfRangeLong(original, from, to);
4042+
else // from == 0 && to == original.length
4043+
return copyOf(original);
4044+
}
4045+
4046+
@ForceInline
4047+
private static long[] copyOfRangeLong(long[] original, int from, int to) {
4048+
checkLength(from, to);
39274049
int newLength = to - from;
3928-
if (newLength < 0)
3929-
throw new IllegalArgumentException(from + " > " + to);
39304050
long[] copy = new long[newLength];
39314051
System.arraycopy(original, from, copy, 0,
39324052
Math.min(original.length - from, newLength));
@@ -3960,9 +4080,17 @@ public static long[] copyOfRange(long[] original, int from, int to) {
39604080
* @since 1.6
39614081
*/
39624082
public static char[] copyOfRange(char[] original, int from, int to) {
4083+
// Tickle the JIT to fold special cases optimally
4084+
if (from != 0 || to != original.length)
4085+
return copyOfRangeChar(original, from, to);
4086+
else // from == 0 && to == original.length
4087+
return copyOf(original);
4088+
}
4089+
4090+
@ForceInline
4091+
private static char[] copyOfRangeChar(char[] original, int from, int to) {
4092+
checkLength(from, to);
39634093
int newLength = to - from;
3964-
if (newLength < 0)
3965-
throw new IllegalArgumentException(from + " > " + to);
39664094
char[] copy = new char[newLength];
39674095
System.arraycopy(original, from, copy, 0,
39684096
Math.min(original.length - from, newLength));
@@ -3996,9 +4124,17 @@ public static char[] copyOfRange(char[] original, int from, int to) {
39964124
* @since 1.6
39974125
*/
39984126
public static float[] copyOfRange(float[] original, int from, int to) {
4127+
// Tickle the JIT to fold special cases optimally
4128+
if (from != 0 || to != original.length)
4129+
return copyOfRangeFloat(original, from, to);
4130+
else // from == 0 && to == original.length
4131+
return copyOf(original);
4132+
}
4133+
4134+
@ForceInline
4135+
private static float[] copyOfRangeFloat(float[] original, int from, int to) {
4136+
checkLength(from, to);
39994137
int newLength = to - from;
4000-
if (newLength < 0)
4001-
throw new IllegalArgumentException(from + " > " + to);
40024138
float[] copy = new float[newLength];
40034139
System.arraycopy(original, from, copy, 0,
40044140
Math.min(original.length - from, newLength));
@@ -4032,9 +4168,17 @@ public static float[] copyOfRange(float[] original, int from, int to) {
40324168
* @since 1.6
40334169
*/
40344170
public static double[] copyOfRange(double[] original, int from, int to) {
4171+
// Tickle the JIT to fold special cases optimally
4172+
if (from != 0 || to != original.length)
4173+
return copyOfRangeDouble(original, from, to);
4174+
else // from == 0 && to == original.length
4175+
return copyOf(original);
4176+
}
4177+
4178+
@ForceInline
4179+
private static double[] copyOfRangeDouble(double[] original, int from, int to) {
4180+
checkLength(from, to);
40354181
int newLength = to - from;
4036-
if (newLength < 0)
4037-
throw new IllegalArgumentException(from + " > " + to);
40384182
double[] copy = new double[newLength];
40394183
System.arraycopy(original, from, copy, 0,
40404184
Math.min(original.length - from, newLength));
@@ -4068,9 +4212,17 @@ public static double[] copyOfRange(double[] original, int from, int to) {
40684212
* @since 1.6
40694213
*/
40704214
public static boolean[] copyOfRange(boolean[] original, int from, int to) {
4215+
// Tickle the JIT to fold special cases optimally
4216+
if (from != 0 || to != original.length)
4217+
return copyOfRangeBoolean(original, from, to);
4218+
else // from == 0 && to == original.length
4219+
return copyOf(original);
4220+
}
4221+
4222+
@ForceInline
4223+
private static boolean[] copyOfRangeBoolean(boolean[] original, int from, int to) {
4224+
checkLength(from, to);
40714225
int newLength = to - from;
4072-
if (newLength < 0)
4073-
throw new IllegalArgumentException(from + " > " + to);
40744226
boolean[] copy = new boolean[newLength];
40754227
System.arraycopy(original, from, copy, 0,
40764228
Math.min(original.length - from, newLength));

0 commit comments

Comments
 (0)