summaryrefslogtreecommitdiffstats
path: root/luni/src/main
diff options
context:
space:
mode:
authorJeff Hao <jeffhao@google.com>2014-06-26 20:27:24 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-06-26 17:56:55 +0000
commit42a6d80d91d8f33162b8946e6fc05e8b43833ca7 (patch)
tree505a01f51e399bfe13bdf66623fb14139f56a1d5 /luni/src/main
parent236f03fdc589f800623f1830ff1aa2b640c6a1ef (diff)
parentf14b3694de2011c0c44beac9e0f8b9871ba888db (diff)
downloadlibcore-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.java429
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.