6570619: (bf) DirectByteBuffer.get/put(byte[]) does not scale well
Reviewed-by: iris
This commit is contained in:
parent
ca45a0c6cc
commit
deaa5d9446
@ -222,8 +222,6 @@ SUNWprivate_1.1 {
|
||||
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;
|
||||
|
@ -735,14 +735,68 @@ class Bits { // package-private
|
||||
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)
|
||||
|
@ -47,6 +47,9 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
// 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 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
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 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
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);
|
||||
|
@ -67,46 +67,6 @@
|
||||
#define SWAPLONG(x) ((jlong)(((jlong)SWAPINT((jint)(x)) << 32) | \
|
||||
((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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user