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]
|
#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]
|
#end[rw]
|
||||||
|
|
||||||
public $Type$Buffer put($type$ x) {
|
public $Type$Buffer put($type$ x) {
|
||||||
@ -448,99 +372,6 @@ class Direct$Type$Buffer$RW$$BO$
|
|||||||
#end[rw]
|
#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() {
|
public {#if[byte]?Mapped$Type$Buffer:$Type$Buffer} compact() {
|
||||||
#if[rw]
|
#if[rw]
|
||||||
int pos = position();
|
int pos = position();
|
||||||
|
@ -268,6 +268,8 @@ public abstract class $Type$Buffer
|
|||||||
extends Buffer
|
extends Buffer
|
||||||
implements Comparable<$Type$Buffer>{#if[char]?, Appendable, CharSequence, Readable}
|
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
|
// 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
|
// 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) {
|
public $Type$Buffer get($type$[] dst, int offset, int length) {
|
||||||
Objects.checkFromIndexSize(offset, length, dst.length);
|
Objects.checkFromIndexSize(offset, length, dst.length);
|
||||||
if (length > remaining())
|
int pos = position();
|
||||||
|
if (length > limit() - pos)
|
||||||
throw new BufferUnderflowException();
|
throw new BufferUnderflowException();
|
||||||
int end = offset + length;
|
|
||||||
for (int i = offset; i < end; i++)
|
getArray(pos, dst, offset, length);
|
||||||
dst[i] = get();
|
|
||||||
|
position(pos + length);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -869,9 +873,9 @@ public abstract class $Type$Buffer
|
|||||||
public $Type$Buffer get(int index, $type$[] dst, int offset, int length) {
|
public $Type$Buffer get(int index, $type$[] dst, int offset, int length) {
|
||||||
Objects.checkFromIndexSize(index, length, limit());
|
Objects.checkFromIndexSize(index, length, limit());
|
||||||
Objects.checkFromIndexSize(offset, length, dst.length);
|
Objects.checkFromIndexSize(offset, length, dst.length);
|
||||||
int end = offset + length;
|
|
||||||
for (int i = offset, j = index; i < end; i++, j++)
|
getArray(index, dst, offset, length);
|
||||||
dst[i] = get(j);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -906,6 +910,40 @@ public abstract class $Type$Buffer
|
|||||||
return get(index, dst, 0, dst.length);
|
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 --
|
// -- Bulk put operations --
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1038,8 +1076,8 @@ public abstract class $Type$Buffer
|
|||||||
}
|
}
|
||||||
|
|
||||||
void putBuffer(int pos, $Type$Buffer src, int srcPos, int n) {
|
void putBuffer(int pos, $Type$Buffer src, int srcPos, int n) {
|
||||||
|
#if[rw]
|
||||||
Object srcBase = src.base();
|
Object srcBase = src.base();
|
||||||
|
|
||||||
#if[char]
|
#if[char]
|
||||||
if (src.isAddressable()) {
|
if (src.isAddressable()) {
|
||||||
#else[char]
|
#else[char]
|
||||||
@ -1053,29 +1091,21 @@ public abstract class $Type$Buffer
|
|||||||
long addr = address + ((long)pos << $LG_BYTES_PER_VALUE$);
|
long addr = address + ((long)pos << $LG_BYTES_PER_VALUE$);
|
||||||
long len = (long)n << $LG_BYTES_PER_VALUE$;
|
long len = (long)n << $LG_BYTES_PER_VALUE$;
|
||||||
|
|
||||||
|
try {
|
||||||
#if[!byte]
|
#if[!byte]
|
||||||
if (this.order() == src.order()) {
|
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 {
|
|
||||||
SCOPED_MEMORY_ACCESS.copySwapMemory(
|
SCOPED_MEMORY_ACCESS.copySwapMemory(
|
||||||
src.scope(), scope(), srcBase,
|
src.scope(), scope(), srcBase, srcAddr,
|
||||||
srcAddr, base, addr, len, (long)1 << $LG_BYTES_PER_VALUE$);
|
base, addr, len, $Fulltype$.BYTES);
|
||||||
} finally {
|
else
|
||||||
Reference.reachabilityFence(src);
|
|
||||||
Reference.reachabilityFence(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#end[!byte]
|
#end[!byte]
|
||||||
|
SCOPED_MEMORY_ACCESS.copyMemory(
|
||||||
|
src.scope(), scope(), srcBase, srcAddr,
|
||||||
|
base, addr, len);
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(src);
|
||||||
|
Reference.reachabilityFence(this);
|
||||||
|
}
|
||||||
#if[char]
|
#if[char]
|
||||||
} else { // src.isAddressable() == false
|
} else { // src.isAddressable() == false
|
||||||
assert StringCharBuffer.class.isInstance(src);
|
assert StringCharBuffer.class.isInstance(src);
|
||||||
@ -1084,6 +1114,9 @@ public abstract class $Type$Buffer
|
|||||||
put(i, src.get(j));
|
put(i, src.get(j));
|
||||||
}
|
}
|
||||||
#end[char]
|
#end[char]
|
||||||
|
#else[rw]
|
||||||
|
throw new ReadOnlyBufferException();
|
||||||
|
#end[rw]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1138,12 +1171,16 @@ public abstract class $Type$Buffer
|
|||||||
* If this buffer is read-only
|
* If this buffer is read-only
|
||||||
*/
|
*/
|
||||||
public $Type$Buffer put($type$[] src, int offset, int length) {
|
public $Type$Buffer put($type$[] src, int offset, int length) {
|
||||||
|
if (isReadOnly())
|
||||||
|
throw new ReadOnlyBufferException();
|
||||||
Objects.checkFromIndexSize(offset, length, src.length);
|
Objects.checkFromIndexSize(offset, length, src.length);
|
||||||
if (length > remaining())
|
int pos = position();
|
||||||
|
if (length > limit() - pos)
|
||||||
throw new BufferOverflowException();
|
throw new BufferOverflowException();
|
||||||
int end = offset + length;
|
|
||||||
for (int i = offset; i < end; i++)
|
putArray(pos, src, offset, length);
|
||||||
this.put(src[i]);
|
|
||||||
|
position(pos + length);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1223,9 +1260,9 @@ public abstract class $Type$Buffer
|
|||||||
throw new ReadOnlyBufferException();
|
throw new ReadOnlyBufferException();
|
||||||
Objects.checkFromIndexSize(index, length, limit());
|
Objects.checkFromIndexSize(index, length, limit());
|
||||||
Objects.checkFromIndexSize(offset, length, src.length);
|
Objects.checkFromIndexSize(offset, length, src.length);
|
||||||
int end = offset + length;
|
|
||||||
for (int i = offset, j = index; i < end; i++, j++)
|
putArray(index, src, offset, length);
|
||||||
this.put(j, src[i]);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1262,6 +1299,43 @@ public abstract class $Type$Buffer
|
|||||||
return put(index, src, 0, src.length);
|
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]
|
#if[char]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user