6570619: (bf) DirectByteBuffer.get/put(byte[]) does not scale well
Reviewed-by: iris
--- a/jdk/make/java/java/mapfile-vers Fri Aug 29 14:33:05 2008 -0700
+++ b/jdk/make/java/java/mapfile-vers Sun Aug 31 18:32:59 2008 +0100
@@ -222,8 +222,6 @@
Java_java_lang_UNIXProcess_waitForProcessExit;
Java_java_lang_UNIXProcess_forkAndExec;
Java_java_lang_UNIXProcess_destroyProcess;
- Java_java_nio_Bits_copyFromByteArray;
- Java_java_nio_Bits_copyToByteArray;
Java_java_nio_Bits_copyFromShortArray;
Java_java_nio_Bits_copyToShortArray;
Java_java_nio_Bits_copyFromIntArray;
--- a/jdk/src/share/classes/java/nio/Bits.java Fri Aug 29 14:33:05 2008 -0700
+++ b/jdk/src/share/classes/java/nio/Bits.java Sun Aug 31 18:32:59 2008 +0100
@@ -735,14 +735,68 @@
static final int JNI_COPY_TO_ARRAY_THRESHOLD = 6;
static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6;
+ // This number limits the number of bytes to copy per call to Unsafe's
+ // copyMemory method. A limit is imposed to allow for safepoint polling
+ // during a large copy
+ static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L;
+
// These methods do no bounds checking. Verification that the copy will not
// result in memory corruption should be done prior to invocation.
// All positions and lengths are specified in bytes.
- static native void copyFromByteArray(Object src, long srcPos, long dstAddr,
- long length);
- static native void copyToByteArray(long srcAddr, Object dst, long dstPos,
- long length);
+ /**
+ * Copy from given source array to destination address.
+ *
+ * @param src
+ * source array
+ * @param srcBaseOffset
+ * offset of first element of storage in source array
+ * @param srcPos
+ * offset within source array of the first element to read
+ * @param dstAddr
+ * destination address
+ * @param length
+ * number of bytes to copy
+ */
+ static void copyFromArray(Object src, long srcBaseOffset, long srcPos,
+ long dstAddr, long length)
+ {
+ long offset = srcBaseOffset + srcPos;
+ while (length > 0) {
+ long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
+ unsafe.copyMemory(src, offset, null, dstAddr, size);
+ length -= size;
+ offset += size;
+ dstAddr += size;
+ }
+ }
+
+ /**
+ * Copy from source address into given destination array.
+ *
+ * @param srcAddr
+ * source address
+ * @param dst
+ * destination array
+ * @param dstBaseOffset
+ * offset of first element of storage in destination array
+ * @param dstPos
+ * offset within destination array of the first element to write
+ * @param length
+ * number of bytes to copy
+ */
+ static void copyToArray(long srcAddr, Object dst, long dstBaseOffset, long dstPos,
+ long length)
+ {
+ long offset = dstBaseOffset + dstPos;
+ while (length > 0) {
+ long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
+ unsafe.copyMemory(null, srcAddr, dst, offset, size);
+ length -= size;
+ srcAddr += size;
+ offset += size;
+ }
+ }
static void copyFromCharArray(Object src, long srcPos, long dstAddr,
long length)
--- a/jdk/src/share/classes/java/nio/Direct-X-Buffer.java Fri Aug 29 14:33:05 2008 -0700
+++ b/jdk/src/share/classes/java/nio/Direct-X-Buffer.java Sun Aug 31 18:32:59 2008 +0100
@@ -47,6 +47,9 @@
// Cached unsafe-access object
protected static final Unsafe unsafe = Bits.unsafe();
+ // Cached array base offset
+ private static final long arrayBaseOffset = (long)unsafe.arrayBaseOffset($type$[].class);
+
// Cached unaligned-access capability
protected static final boolean unaligned = Bits.unaligned();
@@ -242,14 +245,16 @@
if (length > rem)
throw new BufferUnderflowException();
+#if[!byte]
if (order() != ByteOrder.nativeOrder())
Bits.copyTo$Memtype$Array(ix(pos), dst,
offset << $LG_BYTES_PER_VALUE$,
length << $LG_BYTES_PER_VALUE$);
else
- Bits.copyToByteArray(ix(pos), dst,
- offset << $LG_BYTES_PER_VALUE$,
- length << $LG_BYTES_PER_VALUE$);
+#end[!byte]
+ Bits.copyToArray(ix(pos), dst, arrayBaseOffset,
+ offset << $LG_BYTES_PER_VALUE$,
+ length << $LG_BYTES_PER_VALUE$);
position(pos + length);
} else {
super.get(dst, offset, length);
@@ -332,12 +337,14 @@
if (length > rem)
throw new BufferOverflowException();
+#if[!byte]
if (order() != ByteOrder.nativeOrder())
Bits.copyFrom$Memtype$Array(src, offset << $LG_BYTES_PER_VALUE$,
ix(pos), length << $LG_BYTES_PER_VALUE$);
else
- Bits.copyFromByteArray(src, offset << $LG_BYTES_PER_VALUE$,
- ix(pos), length << $LG_BYTES_PER_VALUE$);
+#end[!byte]
+ Bits.copyFromArray(src, arrayBaseOffset, offset << $LG_BYTES_PER_VALUE$,
+ ix(pos), length << $LG_BYTES_PER_VALUE$);
position(pos + length);
} else {
super.put(src, offset, length);
--- a/jdk/src/share/native/java/nio/Bits.c Fri Aug 29 14:33:05 2008 -0700
+++ b/jdk/src/share/native/java/nio/Bits.c Sun Aug 31 18:32:59 2008 +0100
@@ -68,46 +68,6 @@
((jlong)SWAPINT((jint)((x) >> 32)) & 0xffffffff)))
JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyFromByteArray(JNIEnv *env, jobject this, jobject src,
- jlong srcPos, jlong dstAddr, jlong length)
-{
- jbyte *bytes;
- size_t size;
-
- while (length > 0) {
- size = (length > MBYTE ? MBYTE : length);
-
- GETCRITICAL(bytes, env, src);
- memcpy((void *)dstAddr, bytes + srcPos, size);
- RELEASECRITICAL(bytes, env, src, JNI_ABORT);
-
- length -= size;
- dstAddr += size;
- srcPos += size;
- }
-}
-
-JNIEXPORT void JNICALL
-Java_java_nio_Bits_copyToByteArray(JNIEnv *env, jobject this, jlong srcAddr,
- jobject dst, jlong dstPos, jlong length)
-{
- jbyte *bytes;
- size_t size;
-
- while (length > 0) {
- size = (length > MBYTE ? MBYTE : length);
-
- GETCRITICAL(bytes, env, dst);
- memcpy(bytes + dstPos, (void *)srcAddr, size);
- RELEASECRITICAL(bytes, env, dst, 0);
-
- length -= size;
- srcAddr += size;
- dstPos += size;
- }
-}
-
-JNIEXPORT void JNICALL
Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jobject this, jobject src,
jlong srcPos, jlong dstAddr, jlong length)
{