diff options
author | Jeff Hao <jeffhao@google.com> | 2014-06-26 20:27:24 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-06-26 17:56:55 +0000 |
commit | 42a6d80d91d8f33162b8946e6fc05e8b43833ca7 (patch) | |
tree | 505a01f51e399bfe13bdf66623fb14139f56a1d5 /luni/src/main | |
parent | 236f03fdc589f800623f1830ff1aa2b640c6a1ef (diff) | |
parent | f14b3694de2011c0c44beac9e0f8b9871ba888db (diff) | |
download | libcore-42a6d80d91d8f33162b8946e6fc05e8b43833ca7.zip libcore-42a6d80d91d8f33162b8946e6fc05e8b43833ca7.tar.gz libcore-42a6d80d91d8f33162b8946e6fc05e8b43833ca7.tar.bz2 |
Merge "Expanded arraycopy function to deal with more types and updated benchmarking."
Diffstat (limited to 'luni/src/main')
-rw-r--r-- | luni/src/main/java/java/lang/System.java | 429 |
1 files changed, 427 insertions, 2 deletions
diff --git a/luni/src/main/java/java/lang/System.java b/luni/src/main/java/java/lang/System.java index 185701e..3bd443f 100644 --- a/luni/src/main/java/java/lang/System.java +++ b/luni/src/main/java/java/lang/System.java @@ -171,14 +171,68 @@ public final class System { * @param length * the number of elements to be copied. */ - public static native void arraycopy(Object src, int srcPos, Object dst, int dstPos, int length); + + public static native void arraycopy(Object src, int srcPos, + Object dst, int dstPos, int length); + + /** + * The type object array length threshold below which to use a Java + * (non-native) version of arraycopy() instead of the native + * version. + */ + + private static final int ARRAYCOPY_SHORT_T_ARRAY_THRESHOLD = 32; + + /** + * An arraycopy variant that applies when both input arguments are compatible object arrays. + * + * @hide internal use only + */ + public static <T> void arraycopy(T[] src, int srcPos, T[] dst, int dstPos, int length) { + if (src.getClass() != dst.getClass() || dst.getClass() != Object[].class || + dst.getClass().isAssignableFrom(src.getClass())) { + // Call the native version if we can't easily deal with it here. + arraycopy(src, srcPos, dst, dstPos, length); + } + if (src == null) { + throw new NullPointerException("src == null"); + } + if (dst == null) { + throw new NullPointerException("dst == null"); + } + if (srcPos < 0 || dstPos < 0 || length < 0 || + srcPos > src.length - length || dstPos > dst.length - length) { + throw new ArrayIndexOutOfBoundsException( + "src.length=" + src.length + " srcPos=" + srcPos + + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); + } + if (length <= ARRAYCOPY_SHORT_T_ARRAY_THRESHOLD) { + // Copy object by object for shorter arrays. + if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { + // Copy backward (to avoid overwriting elements before + // they are copied in case of an overlap on the same + // array.) + for (int i = length - 1; i >= 0; --i) { + dst[dstPos + i] = src[srcPos + i]; + } + } else { + // Copy forward. + for (int i = 0; i < length; ++i) { + dst[dstPos + i] = src[srcPos + i]; + } + } + } else { + // Call the native version for longer arrays. + arraycopy(src, srcPos, dst, dstPos, length); + } + } /** * The char array length threshold below which to use a Java * (non-native) version of arraycopy() instead of the native * version. See b/7103825. */ - private static final int ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD = 64; + private static final int ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD = 16; /** * The char[] specialized version of arraycopy(). @@ -227,6 +281,377 @@ public final class System { char[] dst, int dstPos, int length); /** + * The byte array length threshold below which to use a Java + * (non-native) version of arraycopy() instead of the native + * version. See b/7103825. + */ + private static final int ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD = 16; + + /** + * The byte[] specialized version of arraycopy(). + * + * @hide internal use only + */ + public static void arraycopy(byte[] src, int srcPos, byte[] dst, int dstPos, int length) { + if (src == null) { + throw new NullPointerException("src == null"); + } + if (dst == null) { + throw new NullPointerException("dst == null"); + } + if (srcPos < 0 || dstPos < 0 || length < 0 || + srcPos > src.length - length || dstPos > dst.length - length) { + throw new ArrayIndexOutOfBoundsException( + "src.length=" + src.length + " srcPos=" + srcPos + + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); + } + if (length <= ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD) { + // Copy byte by byte for shorter arrays. + if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { + // Copy backward (to avoid overwriting elements before + // they are copied in case of an overlap on the same + // array.) + for (int i = length - 1; i >= 0; --i) { + dst[dstPos + i] = src[srcPos + i]; + } + } else { + // Copy forward. + for (int i = 0; i < length; ++i) { + dst[dstPos + i] = src[srcPos + i]; + } + } + } else { + // Call the native version for longer arrays. + arraycopyByteUnchecked(src, srcPos, dst, dstPos, length); + } + } + + /** + * The byte[] specialized, unchecked, native version of + * arraycopy(). This assumes error checking has been done. + */ + private static native void arraycopyByteUnchecked(byte[] src, int srcPos, + byte[] dst, int dstPos, int length); + + /** + * The short array length threshold below which to use a Java + * (non-native) version of arraycopy() instead of the native + * version. See b/7103825. + */ + private static final int ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD = 16; + + /** + * The short[] specialized version of arraycopy(). + * + * @hide internal use only + */ + public static void arraycopy(short[] src, int srcPos, short[] dst, int dstPos, int length) { + if (src == null) { + throw new NullPointerException("src == null"); + } + if (dst == null) { + throw new NullPointerException("dst == null"); + } + if (srcPos < 0 || dstPos < 0 || length < 0 || + srcPos > src.length - length || dstPos > dst.length - length) { + throw new ArrayIndexOutOfBoundsException( + "src.length=" + src.length + " srcPos=" + srcPos + + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); + } + if (length <= ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD) { + // Copy short by short for shorter arrays. + if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { + // Copy backward (to avoid overwriting elements before + // they are copied in case of an overlap on the same + // array.) + for (int i = length - 1; i >= 0; --i) { + dst[dstPos + i] = src[srcPos + i]; + } + } else { + // Copy forward. + for (int i = 0; i < length; ++i) { + dst[dstPos + i] = src[srcPos + i]; + } + } + } else { + // Call the native version for longer arrays. + arraycopyShortUnchecked(src, srcPos, dst, dstPos, length); + } + } + + /** + * The short[] specialized, unchecked, native version of + * arraycopy(). This assumes error checking has been done. + */ + private static native void arraycopyShortUnchecked(short[] src, int srcPos, + short[] dst, int dstPos, int length); + + /** + * The short array length threshold below which to use a Java + * (non-native) version of arraycopy() instead of the native + * version. See b/7103825. + */ + private static final int ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD = 32; + + /** + * The int[] specialized version of arraycopy(). + * + * @hide internal use only + */ + public static void arraycopy(int[] src, int srcPos, int[] dst, int dstPos, int length) { + if (src == null) { + throw new NullPointerException("src == null"); + } + if (dst == null) { + throw new NullPointerException("dst == null"); + } + if (srcPos < 0 || dstPos < 0 || length < 0 || + srcPos > src.length - length || dstPos > dst.length - length) { + throw new ArrayIndexOutOfBoundsException( + "src.length=" + src.length + " srcPos=" + srcPos + + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); + } + if (length <= ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD) { + // Copy int by int for shorter arrays. + if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { + // Copy backward (to avoid overwriting elements before + // they are copied in case of an overlap on the same + // array.) + for (int i = length - 1; i >= 0; --i) { + dst[dstPos + i] = src[srcPos + i]; + } + } else { + // Copy forward. + for (int i = 0; i < length; ++i) { + dst[dstPos + i] = src[srcPos + i]; + } + } + } else { + // Call the native version for longer arrays. + arraycopyIntUnchecked(src, srcPos, dst, dstPos, length); + } + } + + /** + * The int[] specialized, unchecked, native version of + * arraycopy(). This assumes error checking has been done. + */ + private static native void arraycopyIntUnchecked(int[] src, int srcPos, + int[] dst, int dstPos, int length); + + /** + * The short array length threshold below which to use a Java + * (non-native) version of arraycopy() instead of the native + * version. See b/7103825. + */ + private static final int ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD = 32; + + /** + * The long[] specialized version of arraycopy(). + * + * @hide internal use only + */ + public static void arraycopy(long[] src, int srcPos, long[] dst, int dstPos, int length) { + if (src == null) { + throw new NullPointerException("src == null"); + } + if (dst == null) { + throw new NullPointerException("dst == null"); + } + if (srcPos < 0 || dstPos < 0 || length < 0 || + srcPos > src.length - length || dstPos > dst.length - length) { + throw new ArrayIndexOutOfBoundsException( + "src.length=" + src.length + " srcPos=" + srcPos + + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); + } + if (length <= ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD) { + // Copy long by long for shorter arrays. + if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { + // Copy backward (to avoid overwriting elements before + // they are copied in case of an overlap on the same + // array.) + for (int i = length - 1; i >= 0; --i) { + dst[dstPos + i] = src[srcPos + i]; + } + } else { + // Copy forward. + for (int i = 0; i < length; ++i) { + dst[dstPos + i] = src[srcPos + i]; + } + } + } else { + // Call the native version for longer arrays. + arraycopyLongUnchecked(src, srcPos, dst, dstPos, length); + } + } + + /** + * The long[] specialized, unchecked, native version of + * arraycopy(). This assumes error checking has been done. + */ + private static native void arraycopyLongUnchecked(long[] src, int srcPos, + long[] dst, int dstPos, int length); + + /** + * The short array length threshold below which to use a Java + * (non-native) version of arraycopy() instead of the native + * version. See b/7103825. + */ + private static final int ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD = 2; + + /** + * The float[] specialized version of arraycopy(). + * + * @hide internal use only + */ + public static void arraycopy(float[] src, int srcPos, float[] dst, int dstPos, int length) { + if (src == null) { + throw new NullPointerException("src == null"); + } + if (dst == null) { + throw new NullPointerException("dst == null"); + } + if (srcPos < 0 || dstPos < 0 || length < 0 || + srcPos > src.length - length || dstPos > dst.length - length) { + throw new ArrayIndexOutOfBoundsException( + "src.length=" + src.length + " srcPos=" + srcPos + + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); + } + if (length <= ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD) { + // Copy float by float for shorter arrays. + if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { + // Copy backward (to avoid overwriting elements before + // they are copied in case of an overlap on the same + // array.) + for (int i = length - 1; i >= 0; --i) { + dst[dstPos + i] = src[srcPos + i]; + } + } else { + // Copy forward. + for (int i = 0; i < length; ++i) { + dst[dstPos + i] = src[srcPos + i]; + } + } + } else { + // Call the native version for floater arrays. + arraycopyFloatUnchecked(src, srcPos, dst, dstPos, length); + } + } + + /** + * The float[] specialized, unchecked, native version of + * arraycopy(). This assumes error checking has been done. + */ + private static native void arraycopyFloatUnchecked(float[] src, int srcPos, + float[] dst, int dstPos, int length); + + /** + * The short array length threshold below which to use a Java + * (non-native) version of arraycopy() instead of the native + * version. See b/7103825. + */ + private static final int ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD = 64; + + /** + * The double[] specialized version of arraycopy(). + * + * @hide internal use only + */ + public static void arraycopy(double[] src, int srcPos, double[] dst, int dstPos, int length) { + if (src == null) { + throw new NullPointerException("src == null"); + } + if (dst == null) { + throw new NullPointerException("dst == null"); + } + if (srcPos < 0 || dstPos < 0 || length < 0 || + srcPos > src.length - length || dstPos > dst.length - length) { + throw new ArrayIndexOutOfBoundsException( + "src.length=" + src.length + " srcPos=" + srcPos + + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); + } + if (length <= ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD) { + // Copy double by double for shorter arrays. + if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { + // Copy backward (to avoid overwriting elements before + // they are copied in case of an overlap on the same + // array.) + for (int i = length - 1; i >= 0; --i) { + dst[dstPos + i] = src[srcPos + i]; + } + } else { + // Copy forward. + for (int i = 0; i < length; ++i) { + dst[dstPos + i] = src[srcPos + i]; + } + } + } else { + // Call the native version for floater arrays. + arraycopyDoubleUnchecked(src, srcPos, dst, dstPos, length); + } + } + + /** + * The double[] specialized, unchecked, native version of + * arraycopy(). This assumes error checking has been done. + */ + private static native void arraycopyDoubleUnchecked(double[] src, int srcPos, + double[] dst, int dstPos, int length); + + /** + * The short array length threshold below which to use a Java + * (non-native) version of arraycopy() instead of the native + * version. See b/7103825. + */ + private static final int ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD = 128; + + /** + * The boolean[] specialized version of arraycopy(). + * + * @hide internal use only + */ + public static void arraycopy(boolean[] src, int srcPos, boolean[] dst, int dstPos, int length) { + if (src == null) { + throw new NullPointerException("src == null"); + } + if (dst == null) { + throw new NullPointerException("dst == null"); + } + if (srcPos < 0 || dstPos < 0 || length < 0 || + srcPos > src.length - length || dstPos > dst.length - length) { + throw new ArrayIndexOutOfBoundsException( + "src.length=" + src.length + " srcPos=" + srcPos + + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); + } + if (length <= ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD) { + // Copy boolean by boolean for shorter arrays. + if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { + // Copy backward (to avoid overwriting elements before + // they are copied in case of an overlap on the same + // array.) + for (int i = length - 1; i >= 0; --i) { + dst[dstPos + i] = src[srcPos + i]; + } + } else { + // Copy forward. + for (int i = 0; i < length; ++i) { + dst[dstPos + i] = src[srcPos + i]; + } + } + } else { + // Call the native version for floater arrays. + arraycopyBooleanUnchecked(src, srcPos, dst, dstPos, length); + } + } + + /** + * The boolean[] specialized, unchecked, native version of + * arraycopy(). This assumes error checking has been done. + */ + private static native void arraycopyBooleanUnchecked(boolean[] src, int srcPos, + boolean[] dst, int dstPos, int length); + + /** * Returns the current time in milliseconds since January 1, 1970 00:00:00.0 UTC. * * <p>This method always returns UTC times, regardless of the system's time zone. |