Skip to content

Commit 6bb71d9

Browse files
author
Brian Burkhalter
committedApr 29, 2021
8264762: ByteBuffer.byteOrder(BIG_ENDIAN).asXBuffer.put(Xarray) and ByteBuffer.byteOrder(nativeOrder()).asXBuffer.put(Xarray) are slow
Reviewed-by: alanb, psandoz, chegar
1 parent f0f6b0d commit 6bb71d9

File tree

2 files changed

+108
-203
lines changed

2 files changed

+108
-203
lines changed
 

‎src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template

-169
Original file line numberDiff line numberDiff line change
@@ -344,82 +344,6 @@ class Direct$Type$Buffer$RW$$BO$
344344
}
345345
}
346346
#end[streamableType]
347-
348-
public $Type$Buffer get($type$[] dst, int offset, int length) {
349-
#if[rw]
350-
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
351-
Objects.checkFromIndexSize(offset, length, dst.length);
352-
int pos = position();
353-
int lim = limit();
354-
assert (pos <= lim);
355-
int rem = (pos <= lim ? lim - pos : 0);
356-
if (length > rem)
357-
throw new BufferUnderflowException();
358-
359-
long dstOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
360-
try {
361-
#if[!byte]
362-
if (order() != ByteOrder.nativeOrder())
363-
SCOPED_MEMORY_ACCESS.copySwapMemory(scope(), null, null,
364-
ix(pos),
365-
dst,
366-
dstOffset,
367-
(long)length << $LG_BYTES_PER_VALUE$,
368-
(long)1 << $LG_BYTES_PER_VALUE$);
369-
else
370-
#end[!byte]
371-
SCOPED_MEMORY_ACCESS.copyMemory(scope(), null, null,
372-
ix(pos),
373-
dst,
374-
dstOffset,
375-
(long)length << $LG_BYTES_PER_VALUE$);
376-
} finally {
377-
Reference.reachabilityFence(this);
378-
}
379-
position(pos + length);
380-
} else {
381-
super.get(dst, offset, length);
382-
}
383-
return this;
384-
#else[rw]
385-
throw new ReadOnlyBufferException();
386-
#end[rw]
387-
}
388-
389-
public $Type$Buffer get(int index, $type$[] dst, int offset, int length) {
390-
#if[rw]
391-
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
392-
Objects.checkFromIndexSize(index, length, limit());
393-
Objects.checkFromIndexSize(offset, length, dst.length);
394-
395-
long dstOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
396-
try {
397-
#if[!byte]
398-
if (order() != ByteOrder.nativeOrder())
399-
SCOPED_MEMORY_ACCESS.copySwapMemory(scope(), null, null,
400-
ix(index),
401-
dst,
402-
dstOffset,
403-
(long)length << $LG_BYTES_PER_VALUE$,
404-
(long)1 << $LG_BYTES_PER_VALUE$);
405-
else
406-
#end[!byte]
407-
SCOPED_MEMORY_ACCESS.copyMemory(scope(), null, null,
408-
ix(index),
409-
dst,
410-
dstOffset,
411-
(long)length << $LG_BYTES_PER_VALUE$);
412-
} finally {
413-
Reference.reachabilityFence(this);
414-
}
415-
} else {
416-
super.get(index, dst, offset, length);
417-
}
418-
return this;
419-
#else[rw]
420-
throw new ReadOnlyBufferException();
421-
#end[rw]
422-
}
423347
#end[rw]
424348

425349
public $Type$Buffer put($type$ x) {
@@ -448,99 +372,6 @@ class Direct$Type$Buffer$RW$$BO$
448372
#end[rw]
449373
}
450374

451-
public $Type$Buffer put($Type$Buffer src) {
452-
#if[rw]
453-
super.put(src);
454-
return this;
455-
#else[rw]
456-
throw new ReadOnlyBufferException();
457-
#end[rw]
458-
}
459-
460-
public $Type$Buffer put(int index, $Type$Buffer src, int offset, int length) {
461-
#if[rw]
462-
super.put(index, src, offset, length);
463-
return this;
464-
#else[rw]
465-
throw new ReadOnlyBufferException();
466-
#end[rw]
467-
}
468-
469-
public $Type$Buffer put($type$[] src, int offset, int length) {
470-
#if[rw]
471-
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
472-
Objects.checkFromIndexSize(offset, length, src.length);
473-
int pos = position();
474-
int lim = limit();
475-
assert (pos <= lim);
476-
int rem = (pos <= lim ? lim - pos : 0);
477-
if (length > rem)
478-
throw new BufferOverflowException();
479-
480-
long srcOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
481-
try {
482-
#if[!byte]
483-
if (order() != ByteOrder.nativeOrder())
484-
SCOPED_MEMORY_ACCESS.copySwapMemory(null, scope(), src,
485-
srcOffset,
486-
null,
487-
ix(pos),
488-
(long)length << $LG_BYTES_PER_VALUE$,
489-
(long)1 << $LG_BYTES_PER_VALUE$);
490-
else
491-
#end[!byte]
492-
SCOPED_MEMORY_ACCESS.copyMemory(null, scope(), src,
493-
srcOffset,
494-
null,
495-
ix(pos),
496-
(long)length << $LG_BYTES_PER_VALUE$);
497-
} finally {
498-
Reference.reachabilityFence(this);
499-
}
500-
position(pos + length);
501-
} else {
502-
super.put(src, offset, length);
503-
}
504-
return this;
505-
#else[rw]
506-
throw new ReadOnlyBufferException();
507-
#end[rw]
508-
}
509-
510-
public $Type$Buffer put(int index, $type$[] src, int offset, int length) {
511-
#if[rw]
512-
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
513-
Objects.checkFromIndexSize(index, length, limit());
514-
Objects.checkFromIndexSize(offset, length, src.length);
515-
516-
517-
long srcOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
518-
try {
519-
#if[!byte]
520-
if (order() != ByteOrder.nativeOrder())
521-
SCOPED_MEMORY_ACCESS.copySwapMemory(null, scope(), src,
522-
srcOffset,
523-
null,
524-
ix(index),
525-
(long)length << $LG_BYTES_PER_VALUE$,
526-
(long)1 << $LG_BYTES_PER_VALUE$);
527-
else
528-
#end[!byte]
529-
SCOPED_MEMORY_ACCESS.copyMemory(
530-
null, scope(), src,
531-
srcOffset, null, ix(index), (long)length << $LG_BYTES_PER_VALUE$);
532-
} finally {
533-
Reference.reachabilityFence(this);
534-
}
535-
} else {
536-
super.put(index, src, offset, length);
537-
}
538-
return this;
539-
#else[rw]
540-
throw new ReadOnlyBufferException();
541-
#end[rw]
542-
}
543-
544375
public {#if[byte]?Mapped$Type$Buffer:$Type$Buffer} compact() {
545376
#if[rw]
546377
int pos = position();

‎src/java.base/share/classes/java/nio/X-Buffer.java.template

+108-34
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ public abstract class $Type$Buffer
268268
extends Buffer
269269
implements Comparable<$Type$Buffer>{#if[char]?, Appendable, CharSequence, Readable}
270270
{
271+
// Cached array base offset
272+
private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class);
271273

272274
// These fields are declared here rather than in Heap-X-Buffer in order to
273275
// reduce the number of virtual method invocations needed to access these
@@ -791,11 +793,13 @@ public abstract class $Type$Buffer
791793
*/
792794
public $Type$Buffer get($type$[] dst, int offset, int length) {
793795
Objects.checkFromIndexSize(offset, length, dst.length);
794-
if (length > remaining())
796+
int pos = position();
797+
if (length > limit() - pos)
795798
throw new BufferUnderflowException();
796-
int end = offset + length;
797-
for (int i = offset; i < end; i++)
798-
dst[i] = get();
799+
800+
getArray(pos, dst, offset, length);
801+
802+
position(pos + length);
799803
return this;
800804
}
801805

@@ -869,9 +873,9 @@ public abstract class $Type$Buffer
869873
public $Type$Buffer get(int index, $type$[] dst, int offset, int length) {
870874
Objects.checkFromIndexSize(index, length, limit());
871875
Objects.checkFromIndexSize(offset, length, dst.length);
872-
int end = offset + length;
873-
for (int i = offset, j = index; i < end; i++, j++)
874-
dst[i] = get(j);
876+
877+
getArray(index, dst, offset, length);
878+
875879
return this;
876880
}
877881

@@ -906,6 +910,40 @@ public abstract class $Type$Buffer
906910
return get(index, dst, 0, dst.length);
907911
}
908912

913+
private $Type$Buffer getArray(int index, $type$[] dst, int offset, int length) {
914+
if (
915+
#if[char]
916+
isAddressable() &&
917+
#end[char]
918+
((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
919+
long bufAddr = address + ((long)index << $LG_BYTES_PER_VALUE$);
920+
long dstOffset =
921+
ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
922+
long len = (long)length << $LG_BYTES_PER_VALUE$;
923+
924+
try {
925+
#if[!byte]
926+
if (order() != ByteOrder.nativeOrder())
927+
SCOPED_MEMORY_ACCESS.copySwapMemory(
928+
scope(), null, base(), bufAddr,
929+
dst, dstOffset, len, $Fulltype$.BYTES);
930+
else
931+
#end[!byte]
932+
SCOPED_MEMORY_ACCESS.copyMemory(
933+
scope(), null, base(), bufAddr,
934+
dst, dstOffset, len);
935+
} finally {
936+
Reference.reachabilityFence(this);
937+
}
938+
} else {
939+
int end = offset + length;
940+
for (int i = offset, j = index; i < end; i++, j++) {
941+
dst[i] = get(j);
942+
}
943+
}
944+
return this;
945+
}
946+
909947
// -- Bulk put operations --
910948

911949
/**
@@ -1038,8 +1076,8 @@ public abstract class $Type$Buffer
10381076
}
10391077

10401078
void putBuffer(int pos, $Type$Buffer src, int srcPos, int n) {
1079+
#if[rw]
10411080
Object srcBase = src.base();
1042-
10431081
#if[char]
10441082
if (src.isAddressable()) {
10451083
#else[char]
@@ -1053,29 +1091,21 @@ public abstract class $Type$Buffer
10531091
long addr = address + ((long)pos << $LG_BYTES_PER_VALUE$);
10541092
long len = (long)n << $LG_BYTES_PER_VALUE$;
10551093

1094+
try {
10561095
#if[!byte]
1057-
if (this.order() == src.order()) {
1096+
if (this.order() != src.order())
1097+
SCOPED_MEMORY_ACCESS.copySwapMemory(
1098+
src.scope(), scope(), srcBase, srcAddr,
1099+
base, addr, len, $Fulltype$.BYTES);
1100+
else
10581101
#end[!byte]
1059-
try {
10601102
SCOPED_MEMORY_ACCESS.copyMemory(
1061-
src.scope(), scope(), srcBase,
1062-
srcAddr, base, addr, len);
1063-
} finally {
1064-
Reference.reachabilityFence(src);
1065-
Reference.reachabilityFence(this);
1066-
}
1067-
#if[!byte]
1068-
} else {
1069-
try {
1070-
SCOPED_MEMORY_ACCESS.copySwapMemory(
1071-
src.scope(), scope(), srcBase,
1072-
srcAddr, base, addr, len, (long)1 << $LG_BYTES_PER_VALUE$);
1073-
} finally {
1074-
Reference.reachabilityFence(src);
1075-
Reference.reachabilityFence(this);
1076-
}
1103+
src.scope(), scope(), srcBase, srcAddr,
1104+
base, addr, len);
1105+
} finally {
1106+
Reference.reachabilityFence(src);
1107+
Reference.reachabilityFence(this);
10771108
}
1078-
#end[!byte]
10791109
#if[char]
10801110
} else { // src.isAddressable() == false
10811111
assert StringCharBuffer.class.isInstance(src);
@@ -1084,6 +1114,9 @@ public abstract class $Type$Buffer
10841114
put(i, src.get(j));
10851115
}
10861116
#end[char]
1117+
#else[rw]
1118+
throw new ReadOnlyBufferException();
1119+
#end[rw]
10871120
}
10881121

10891122
/**
@@ -1138,12 +1171,16 @@ public abstract class $Type$Buffer
11381171
* If this buffer is read-only
11391172
*/
11401173
public $Type$Buffer put($type$[] src, int offset, int length) {
1174+
if (isReadOnly())
1175+
throw new ReadOnlyBufferException();
11411176
Objects.checkFromIndexSize(offset, length, src.length);
1142-
if (length > remaining())
1177+
int pos = position();
1178+
if (length > limit() - pos)
11431179
throw new BufferOverflowException();
1144-
int end = offset + length;
1145-
for (int i = offset; i < end; i++)
1146-
this.put(src[i]);
1180+
1181+
putArray(pos, src, offset, length);
1182+
1183+
position(pos + length);
11471184
return this;
11481185
}
11491186

@@ -1223,9 +1260,9 @@ public abstract class $Type$Buffer
12231260
throw new ReadOnlyBufferException();
12241261
Objects.checkFromIndexSize(index, length, limit());
12251262
Objects.checkFromIndexSize(offset, length, src.length);
1226-
int end = offset + length;
1227-
for (int i = offset, j = index; i < end; i++, j++)
1228-
this.put(j, src[i]);
1263+
1264+
putArray(index, src, offset, length);
1265+
12291266
return this;
12301267
}
12311268

@@ -1262,6 +1299,43 @@ public abstract class $Type$Buffer
12621299
return put(index, src, 0, src.length);
12631300
}
12641301

1302+
private $Type$Buffer putArray(int index, $type$[] src, int offset, int length) {
1303+
#if[rw]
1304+
if (
1305+
#if[char]
1306+
isAddressable() &&
1307+
#end[char]
1308+
((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
1309+
long bufAddr = address + ((long)index << $LG_BYTES_PER_VALUE$);
1310+
long srcOffset =
1311+
ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
1312+
long len = (long)length << $LG_BYTES_PER_VALUE$;
1313+
1314+
try {
1315+
#if[!byte]
1316+
if (order() != ByteOrder.nativeOrder())
1317+
SCOPED_MEMORY_ACCESS.copySwapMemory(
1318+
null, scope(), src, srcOffset,
1319+
base(), bufAddr, len, $Fulltype$.BYTES);
1320+
else
1321+
#end[!byte]
1322+
SCOPED_MEMORY_ACCESS.copyMemory(
1323+
null, scope(), src, srcOffset,
1324+
base(), bufAddr, len);
1325+
} finally {
1326+
Reference.reachabilityFence(this);
1327+
}
1328+
} else {
1329+
int end = offset + length;
1330+
for (int i = offset, j = index; i < end; i++, j++)
1331+
this.put(j, src[i]);
1332+
}
1333+
return this;
1334+
#else[rw]
1335+
throw new ReadOnlyBufferException();
1336+
#end[rw]
1337+
}
1338+
12651339
#if[char]
12661340

12671341
/**

0 commit comments

Comments
 (0)
Please sign in to comment.