提交 70763cd4 编写于 作者: A alanb

6570619: (bf) DirectByteBuffer.get/put(byte[]) does not scale well

Reviewed-by: iris
上级 1b95ba6d
......@@ -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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册