8264762: ByteBuffer.byteOrder(BIG_ENDIAN).asXBuffer.put(Xarray) and ByteBuffer.byteOrder(nativeOrder()).asXBuffer.put(Xarray) are slow
Reviewed-by: alanb, psandoz, chegar
This commit is contained in:
parent
f0f6b0d919
commit
6bb71d9e25
@ -344,82 +344,6 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
}
|
||||
}
|
||||
#end[streamableType]
|
||||
|
||||
public $Type$Buffer get($type$[] dst, int offset, int length) {
|
||||
#if[rw]
|
||||
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
|
||||
Objects.checkFromIndexSize(offset, length, dst.length);
|
||||
int pos = position();
|
||||
int lim = limit();
|
||||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
if (length > rem)
|
||||
throw new BufferUnderflowException();
|
||||
|
||||
long dstOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||
try {
|
||||
#if[!byte]
|
||||
if (order() != ByteOrder.nativeOrder())
|
||||
SCOPED_MEMORY_ACCESS.copySwapMemory(scope(), null, null,
|
||||
ix(pos),
|
||||
dst,
|
||||
dstOffset,
|
||||
(long)length << $LG_BYTES_PER_VALUE$,
|
||||
(long)1 << $LG_BYTES_PER_VALUE$);
|
||||
else
|
||||
#end[!byte]
|
||||
SCOPED_MEMORY_ACCESS.copyMemory(scope(), null, null,
|
||||
ix(pos),
|
||||
dst,
|
||||
dstOffset,
|
||||
(long)length << $LG_BYTES_PER_VALUE$);
|
||||
} finally {
|
||||
Reference.reachabilityFence(this);
|
||||
}
|
||||
position(pos + length);
|
||||
} else {
|
||||
super.get(dst, offset, length);
|
||||
}
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
public $Type$Buffer get(int index, $type$[] dst, int offset, int length) {
|
||||
#if[rw]
|
||||
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
|
||||
Objects.checkFromIndexSize(index, length, limit());
|
||||
Objects.checkFromIndexSize(offset, length, dst.length);
|
||||
|
||||
long dstOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||
try {
|
||||
#if[!byte]
|
||||
if (order() != ByteOrder.nativeOrder())
|
||||
SCOPED_MEMORY_ACCESS.copySwapMemory(scope(), null, null,
|
||||
ix(index),
|
||||
dst,
|
||||
dstOffset,
|
||||
(long)length << $LG_BYTES_PER_VALUE$,
|
||||
(long)1 << $LG_BYTES_PER_VALUE$);
|
||||
else
|
||||
#end[!byte]
|
||||
SCOPED_MEMORY_ACCESS.copyMemory(scope(), null, null,
|
||||
ix(index),
|
||||
dst,
|
||||
dstOffset,
|
||||
(long)length << $LG_BYTES_PER_VALUE$);
|
||||
} finally {
|
||||
Reference.reachabilityFence(this);
|
||||
}
|
||||
} else {
|
||||
super.get(index, dst, offset, length);
|
||||
}
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
#end[rw]
|
||||
}
|
||||
#end[rw]
|
||||
|
||||
public $Type$Buffer put($type$ x) {
|
||||
@ -448,99 +372,6 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
public $Type$Buffer put($Type$Buffer src) {
|
||||
#if[rw]
|
||||
super.put(src);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
public $Type$Buffer put(int index, $Type$Buffer src, int offset, int length) {
|
||||
#if[rw]
|
||||
super.put(index, src, offset, length);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
public $Type$Buffer put($type$[] src, int offset, int length) {
|
||||
#if[rw]
|
||||
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
|
||||
Objects.checkFromIndexSize(offset, length, src.length);
|
||||
int pos = position();
|
||||
int lim = limit();
|
||||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
if (length > rem)
|
||||
throw new BufferOverflowException();
|
||||
|
||||
long srcOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||
try {
|
||||
#if[!byte]
|
||||
if (order() != ByteOrder.nativeOrder())
|
||||
SCOPED_MEMORY_ACCESS.copySwapMemory(null, scope(), src,
|
||||
srcOffset,
|
||||
null,
|
||||
ix(pos),
|
||||
(long)length << $LG_BYTES_PER_VALUE$,
|
||||
(long)1 << $LG_BYTES_PER_VALUE$);
|
||||
else
|
||||
#end[!byte]
|
||||
SCOPED_MEMORY_ACCESS.copyMemory(null, scope(), src,
|
||||
srcOffset,
|
||||
null,
|
||||
ix(pos),
|
||||
(long)length << $LG_BYTES_PER_VALUE$);
|
||||
} finally {
|
||||
Reference.reachabilityFence(this);
|
||||
}
|
||||
position(pos + length);
|
||||
} else {
|
||||
super.put(src, offset, length);
|
||||
}
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
public $Type$Buffer put(int index, $type$[] src, int offset, int length) {
|
||||
#if[rw]
|
||||
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
|
||||
Objects.checkFromIndexSize(index, length, limit());
|
||||
Objects.checkFromIndexSize(offset, length, src.length);
|
||||
|
||||
|
||||
long srcOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||
try {
|
||||
#if[!byte]
|
||||
if (order() != ByteOrder.nativeOrder())
|
||||
SCOPED_MEMORY_ACCESS.copySwapMemory(null, scope(), src,
|
||||
srcOffset,
|
||||
null,
|
||||
ix(index),
|
||||
(long)length << $LG_BYTES_PER_VALUE$,
|
||||
(long)1 << $LG_BYTES_PER_VALUE$);
|
||||
else
|
||||
#end[!byte]
|
||||
SCOPED_MEMORY_ACCESS.copyMemory(
|
||||
null, scope(), src,
|
||||
srcOffset, null, ix(index), (long)length << $LG_BYTES_PER_VALUE$);
|
||||
} finally {
|
||||
Reference.reachabilityFence(this);
|
||||
}
|
||||
} else {
|
||||
super.put(index, src, offset, length);
|
||||
}
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
public {#if[byte]?Mapped$Type$Buffer:$Type$Buffer} compact() {
|
||||
#if[rw]
|
||||
int pos = position();
|
||||
|
@ -268,6 +268,8 @@ public abstract class $Type$Buffer
|
||||
extends Buffer
|
||||
implements Comparable<$Type$Buffer>{#if[char]?, Appendable, CharSequence, Readable}
|
||||
{
|
||||
// Cached array base offset
|
||||
private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class);
|
||||
|
||||
// These fields are declared here rather than in Heap-X-Buffer in order to
|
||||
// reduce the number of virtual method invocations needed to access these
|
||||
@ -791,11 +793,13 @@ public abstract class $Type$Buffer
|
||||
*/
|
||||
public $Type$Buffer get($type$[] dst, int offset, int length) {
|
||||
Objects.checkFromIndexSize(offset, length, dst.length);
|
||||
if (length > remaining())
|
||||
int pos = position();
|
||||
if (length > limit() - pos)
|
||||
throw new BufferUnderflowException();
|
||||
int end = offset + length;
|
||||
for (int i = offset; i < end; i++)
|
||||
dst[i] = get();
|
||||
|
||||
getArray(pos, dst, offset, length);
|
||||
|
||||
position(pos + length);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -869,9 +873,9 @@ public abstract class $Type$Buffer
|
||||
public $Type$Buffer get(int index, $type$[] dst, int offset, int length) {
|
||||
Objects.checkFromIndexSize(index, length, limit());
|
||||
Objects.checkFromIndexSize(offset, length, dst.length);
|
||||
int end = offset + length;
|
||||
for (int i = offset, j = index; i < end; i++, j++)
|
||||
dst[i] = get(j);
|
||||
|
||||
getArray(index, dst, offset, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -906,6 +910,40 @@ public abstract class $Type$Buffer
|
||||
return get(index, dst, 0, dst.length);
|
||||
}
|
||||
|
||||
private $Type$Buffer getArray(int index, $type$[] dst, int offset, int length) {
|
||||
if (
|
||||
#if[char]
|
||||
isAddressable() &&
|
||||
#end[char]
|
||||
((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
|
||||
long bufAddr = address + ((long)index << $LG_BYTES_PER_VALUE$);
|
||||
long dstOffset =
|
||||
ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||
long len = (long)length << $LG_BYTES_PER_VALUE$;
|
||||
|
||||
try {
|
||||
#if[!byte]
|
||||
if (order() != ByteOrder.nativeOrder())
|
||||
SCOPED_MEMORY_ACCESS.copySwapMemory(
|
||||
scope(), null, base(), bufAddr,
|
||||
dst, dstOffset, len, $Fulltype$.BYTES);
|
||||
else
|
||||
#end[!byte]
|
||||
SCOPED_MEMORY_ACCESS.copyMemory(
|
||||
scope(), null, base(), bufAddr,
|
||||
dst, dstOffset, len);
|
||||
} finally {
|
||||
Reference.reachabilityFence(this);
|
||||
}
|
||||
} else {
|
||||
int end = offset + length;
|
||||
for (int i = offset, j = index; i < end; i++, j++) {
|
||||
dst[i] = get(j);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
// -- Bulk put operations --
|
||||
|
||||
/**
|
||||
@ -1038,8 +1076,8 @@ public abstract class $Type$Buffer
|
||||
}
|
||||
|
||||
void putBuffer(int pos, $Type$Buffer src, int srcPos, int n) {
|
||||
#if[rw]
|
||||
Object srcBase = src.base();
|
||||
|
||||
#if[char]
|
||||
if (src.isAddressable()) {
|
||||
#else[char]
|
||||
@ -1053,29 +1091,21 @@ public abstract class $Type$Buffer
|
||||
long addr = address + ((long)pos << $LG_BYTES_PER_VALUE$);
|
||||
long len = (long)n << $LG_BYTES_PER_VALUE$;
|
||||
|
||||
try {
|
||||
#if[!byte]
|
||||
if (this.order() == src.order()) {
|
||||
#end[!byte]
|
||||
try {
|
||||
SCOPED_MEMORY_ACCESS.copyMemory(
|
||||
src.scope(), scope(), srcBase,
|
||||
srcAddr, base, addr, len);
|
||||
} finally {
|
||||
Reference.reachabilityFence(src);
|
||||
Reference.reachabilityFence(this);
|
||||
}
|
||||
#if[!byte]
|
||||
} else {
|
||||
try {
|
||||
if (this.order() != src.order())
|
||||
SCOPED_MEMORY_ACCESS.copySwapMemory(
|
||||
src.scope(), scope(), srcBase,
|
||||
srcAddr, base, addr, len, (long)1 << $LG_BYTES_PER_VALUE$);
|
||||
} finally {
|
||||
Reference.reachabilityFence(src);
|
||||
Reference.reachabilityFence(this);
|
||||
}
|
||||
}
|
||||
src.scope(), scope(), srcBase, srcAddr,
|
||||
base, addr, len, $Fulltype$.BYTES);
|
||||
else
|
||||
#end[!byte]
|
||||
SCOPED_MEMORY_ACCESS.copyMemory(
|
||||
src.scope(), scope(), srcBase, srcAddr,
|
||||
base, addr, len);
|
||||
} finally {
|
||||
Reference.reachabilityFence(src);
|
||||
Reference.reachabilityFence(this);
|
||||
}
|
||||
#if[char]
|
||||
} else { // src.isAddressable() == false
|
||||
assert StringCharBuffer.class.isInstance(src);
|
||||
@ -1084,6 +1114,9 @@ public abstract class $Type$Buffer
|
||||
put(i, src.get(j));
|
||||
}
|
||||
#end[char]
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1138,12 +1171,16 @@ public abstract class $Type$Buffer
|
||||
* If this buffer is read-only
|
||||
*/
|
||||
public $Type$Buffer put($type$[] src, int offset, int length) {
|
||||
if (isReadOnly())
|
||||
throw new ReadOnlyBufferException();
|
||||
Objects.checkFromIndexSize(offset, length, src.length);
|
||||
if (length > remaining())
|
||||
int pos = position();
|
||||
if (length > limit() - pos)
|
||||
throw new BufferOverflowException();
|
||||
int end = offset + length;
|
||||
for (int i = offset; i < end; i++)
|
||||
this.put(src[i]);
|
||||
|
||||
putArray(pos, src, offset, length);
|
||||
|
||||
position(pos + length);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -1223,9 +1260,9 @@ public abstract class $Type$Buffer
|
||||
throw new ReadOnlyBufferException();
|
||||
Objects.checkFromIndexSize(index, length, limit());
|
||||
Objects.checkFromIndexSize(offset, length, src.length);
|
||||
int end = offset + length;
|
||||
for (int i = offset, j = index; i < end; i++, j++)
|
||||
this.put(j, src[i]);
|
||||
|
||||
putArray(index, src, offset, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -1262,6 +1299,43 @@ public abstract class $Type$Buffer
|
||||
return put(index, src, 0, src.length);
|
||||
}
|
||||
|
||||
private $Type$Buffer putArray(int index, $type$[] src, int offset, int length) {
|
||||
#if[rw]
|
||||
if (
|
||||
#if[char]
|
||||
isAddressable() &&
|
||||
#end[char]
|
||||
((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
|
||||
long bufAddr = address + ((long)index << $LG_BYTES_PER_VALUE$);
|
||||
long srcOffset =
|
||||
ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||
long len = (long)length << $LG_BYTES_PER_VALUE$;
|
||||
|
||||
try {
|
||||
#if[!byte]
|
||||
if (order() != ByteOrder.nativeOrder())
|
||||
SCOPED_MEMORY_ACCESS.copySwapMemory(
|
||||
null, scope(), src, srcOffset,
|
||||
base(), bufAddr, len, $Fulltype$.BYTES);
|
||||
else
|
||||
#end[!byte]
|
||||
SCOPED_MEMORY_ACCESS.copyMemory(
|
||||
null, scope(), src, srcOffset,
|
||||
base(), bufAddr, len);
|
||||
} finally {
|
||||
Reference.reachabilityFence(this);
|
||||
}
|
||||
} else {
|
||||
int end = offset + length;
|
||||
for (int i = offset, j = index; i < end; i++, j++)
|
||||
this.put(j, src[i]);
|
||||
}
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
#if[char]
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user