# HG changeset patch # User alanb # Date 1220203979 -3600 # Node ID 4070cecdb99d3e41aac9e1c79d30fc64a75b1e0d # Parent 1e32392ecafaff2a9e0df1dc75f82a8e30a18aa0 6570619: (bf) DirectByteBuffer.get/put(byte[]) does not scale well Reviewed-by: iris diff -r 1e32392ecafa -r 4070cecdb99d jdk/make/java/java/mapfile-vers --- 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; diff -r 1e32392ecafa -r 4070cecdb99d jdk/src/share/classes/java/nio/Bits.java --- 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) diff -r 1e32392ecafa -r 4070cecdb99d jdk/src/share/classes/java/nio/Direct-X-Buffer.java --- 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); diff -r 1e32392ecafa -r 4070cecdb99d jdk/src/share/native/java/nio/Bits.c --- 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) {