6570619: (bf) DirectByteBuffer.get/put(byte[]) does not scale well
authoralanb
Sun, 31 Aug 2008 18:32:59 +0100
changeset 1151 4070cecdb99d
parent 1149 1e32392ecafa
child 1152 29d6145d1097
6570619: (bf) DirectByteBuffer.get/put(byte[]) does not scale well Reviewed-by: iris
jdk/make/java/java/mapfile-vers
jdk/src/share/classes/java/nio/Bits.java
jdk/src/share/classes/java/nio/Direct-X-Buffer.java
jdk/src/share/native/java/nio/Bits.c
--- 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)
 {