mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8193085: Vectorize the nio Buffer equals and compareTo implementations
Reviewed-by: alanb
This commit is contained in:
parent
038b5f571c
commit
fb9db6b02d
13 changed files with 1122 additions and 195 deletions
|
@ -63,38 +63,38 @@ class Bits { // package-private
|
|||
|
||||
// -- Unsafe access --
|
||||
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
|
||||
|
||||
static Unsafe unsafe() {
|
||||
return unsafe;
|
||||
return UNSAFE;
|
||||
}
|
||||
|
||||
|
||||
// -- Processor and memory-system properties --
|
||||
|
||||
private static final ByteOrder byteOrder
|
||||
= unsafe.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
|
||||
private static final ByteOrder BYTE_ORDER
|
||||
= UNSAFE.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
|
||||
|
||||
static ByteOrder byteOrder() {
|
||||
return byteOrder;
|
||||
return BYTE_ORDER;
|
||||
}
|
||||
|
||||
private static int pageSize = -1;
|
||||
private static int PAGE_SIZE = -1;
|
||||
|
||||
static int pageSize() {
|
||||
if (pageSize == -1)
|
||||
pageSize = unsafe().pageSize();
|
||||
return pageSize;
|
||||
if (PAGE_SIZE == -1)
|
||||
PAGE_SIZE = unsafe().pageSize();
|
||||
return PAGE_SIZE;
|
||||
}
|
||||
|
||||
static int pageCount(long size) {
|
||||
return (int)(size + (long)pageSize() - 1L) / pageSize();
|
||||
}
|
||||
|
||||
private static boolean unaligned = unsafe.unalignedAccess();
|
||||
private static boolean UNALIGNED = UNSAFE.unalignedAccess();
|
||||
|
||||
static boolean unaligned() {
|
||||
return unaligned;
|
||||
return UNALIGNED;
|
||||
}
|
||||
|
||||
|
||||
|
@ -103,11 +103,11 @@ class Bits { // package-private
|
|||
// A user-settable upper limit on the maximum amount of allocatable
|
||||
// direct buffer memory. This value may be changed during VM
|
||||
// initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
|
||||
private static volatile long maxMemory = VM.maxDirectMemory();
|
||||
private static final AtomicLong reservedMemory = new AtomicLong();
|
||||
private static final AtomicLong totalCapacity = new AtomicLong();
|
||||
private static final AtomicLong count = new AtomicLong();
|
||||
private static volatile boolean memoryLimitSet;
|
||||
private static volatile long MAX_MEMORY = VM.maxDirectMemory();
|
||||
private static final AtomicLong RESERVED_MEMORY = new AtomicLong();
|
||||
private static final AtomicLong TOTAL_CAPACITY = new AtomicLong();
|
||||
private static final AtomicLong COUNT = new AtomicLong();
|
||||
private static volatile boolean MEMORY_LIMIT_SET;
|
||||
|
||||
// max. number of sleeps during try-reserving with exponentially
|
||||
// increasing delay before throwing OutOfMemoryError:
|
||||
|
@ -120,9 +120,9 @@ class Bits { // package-private
|
|||
// which a process may access. All sizes are specified in bytes.
|
||||
static void reserveMemory(long size, int cap) {
|
||||
|
||||
if (!memoryLimitSet && VM.initLevel() >= 1) {
|
||||
maxMemory = VM.maxDirectMemory();
|
||||
memoryLimitSet = true;
|
||||
if (!MEMORY_LIMIT_SET && VM.initLevel() >= 1) {
|
||||
MAX_MEMORY = VM.maxDirectMemory();
|
||||
MEMORY_LIMIT_SET = true;
|
||||
}
|
||||
|
||||
// optimist!
|
||||
|
@ -200,10 +200,10 @@ class Bits { // package-private
|
|||
// actual memory usage, which will differ when buffers are page
|
||||
// aligned.
|
||||
long totalCap;
|
||||
while (cap <= maxMemory - (totalCap = totalCapacity.get())) {
|
||||
if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) {
|
||||
reservedMemory.addAndGet(size);
|
||||
count.incrementAndGet();
|
||||
while (cap <= MAX_MEMORY - (totalCap = TOTAL_CAPACITY.get())) {
|
||||
if (TOTAL_CAPACITY.compareAndSet(totalCap, totalCap + cap)) {
|
||||
RESERVED_MEMORY.addAndGet(size);
|
||||
COUNT.incrementAndGet();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -213,9 +213,9 @@ class Bits { // package-private
|
|||
|
||||
|
||||
static void unreserveMemory(long size, int cap) {
|
||||
long cnt = count.decrementAndGet();
|
||||
long reservedMem = reservedMemory.addAndGet(-size);
|
||||
long totalCap = totalCapacity.addAndGet(-cap);
|
||||
long cnt = COUNT.decrementAndGet();
|
||||
long reservedMem = RESERVED_MEMORY.addAndGet(-size);
|
||||
long totalCap = TOTAL_CAPACITY.addAndGet(-cap);
|
||||
assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0;
|
||||
}
|
||||
|
||||
|
@ -234,15 +234,15 @@ class Bits { // package-private
|
|||
}
|
||||
@Override
|
||||
public long getCount() {
|
||||
return Bits.count.get();
|
||||
return Bits.COUNT.get();
|
||||
}
|
||||
@Override
|
||||
public long getTotalCapacity() {
|
||||
return Bits.totalCapacity.get();
|
||||
return Bits.TOTAL_CAPACITY.get();
|
||||
}
|
||||
@Override
|
||||
public long getMemoryUsed() {
|
||||
return Bits.reservedMemory.get();
|
||||
return Bits.RESERVED_MEMORY.get();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
package java.nio;
|
||||
|
||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
import java.util.Spliterator;
|
||||
|
||||
|
@ -181,6 +182,8 @@ import java.util.Spliterator;
|
|||
*/
|
||||
|
||||
public abstract class Buffer {
|
||||
// Cached unsafe-access object
|
||||
static final Unsafe UNSAFE = Bits.unsafe();
|
||||
|
||||
/**
|
||||
* The characteristics of Spliterators that traverse and split elements
|
||||
|
@ -616,6 +619,14 @@ public abstract class Buffer {
|
|||
|
||||
// -- Package-private methods for bounds checking, etc. --
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the base reference, paired with the address
|
||||
* field, which in combination can be used for unsafe access into a heap
|
||||
* buffer or direct byte buffer (and views of).
|
||||
*/
|
||||
abstract Object base();
|
||||
|
||||
/**
|
||||
* Checks the current position against the limit, throwing a {@link
|
||||
* BufferUnderflowException} if it is not smaller than the limit, and then
|
||||
|
|
198
src/java.base/share/classes/java/nio/BufferMismatch.java
Normal file
198
src/java.base/share/classes/java/nio/BufferMismatch.java
Normal file
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.nio;
|
||||
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
|
||||
/**
|
||||
* Mismatch methods for buffers
|
||||
*/
|
||||
final class BufferMismatch {
|
||||
|
||||
static int mismatch(ByteBuffer a, int aOff, ByteBuffer b, int bOff, int length) {
|
||||
int i = 0;
|
||||
if (length > 7) {
|
||||
i = ArraysSupport.vectorizedMismatch(
|
||||
a.base(), a.address + aOff,
|
||||
b.base(), b.address + bOff,
|
||||
length,
|
||||
ArraysSupport.LOG2_ARRAY_BYTE_INDEX_SCALE);
|
||||
if (i >= 0) return i;
|
||||
i = length - ~i;
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
if (a.get(aOff + i) != b.get(bOff + i))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(CharBuffer a, int aOff, CharBuffer b, int bOff, int length) {
|
||||
int i = 0;
|
||||
// Ensure only heap or off-heap buffer instances use the
|
||||
// vectorized mismatch. If either buffer is a StringCharBuffer
|
||||
// (order is null) then the slow path is taken
|
||||
if (length > 3 && a.charRegionOrder() == b.charRegionOrder()
|
||||
&& a.charRegionOrder() != null && b.charRegionOrder() != null) {
|
||||
i = ArraysSupport.vectorizedMismatch(
|
||||
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE),
|
||||
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE),
|
||||
length,
|
||||
ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE);
|
||||
if (i >= 0) return i;
|
||||
i = length - ~i;
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
if (a.get(aOff + i) != b.get(bOff + i))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(ShortBuffer a, int aOff, ShortBuffer b, int bOff, int length) {
|
||||
int i = 0;
|
||||
if (length > 3 && a.order() == b.order()) {
|
||||
i = ArraysSupport.vectorizedMismatch(
|
||||
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE),
|
||||
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE),
|
||||
length,
|
||||
ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE);
|
||||
if (i >= 0) return i;
|
||||
i = length - ~i;
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
if (a.get(aOff + i) != b.get(bOff + i))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(IntBuffer a, int aOff, IntBuffer b, int bOff, int length) {
|
||||
int i = 0;
|
||||
if (length > 1 && a.order() == b.order()) {
|
||||
i = ArraysSupport.vectorizedMismatch(
|
||||
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE),
|
||||
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE),
|
||||
length,
|
||||
ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE);
|
||||
if (i >= 0) return i;
|
||||
i = length - ~i;
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
if (a.get(aOff + i) != b.get(bOff + i))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(FloatBuffer a, int aOff, FloatBuffer b, int bOff, int length) {
|
||||
int i = 0;
|
||||
if (length > 1 && a.order() == b.order()) {
|
||||
i = ArraysSupport.vectorizedMismatch(
|
||||
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),
|
||||
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),
|
||||
length,
|
||||
ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE);
|
||||
// Mismatched
|
||||
if (i >= 0) {
|
||||
// Check if mismatch is not associated with two NaN values; and
|
||||
// is not associated with +0 and -0
|
||||
float av = a.get(aOff + i);
|
||||
float bv = b.get(bOff + i);
|
||||
if (av != bv && (!Float.isNaN(av) || !Float.isNaN(bv)))
|
||||
return i;
|
||||
|
||||
// Fall back to slow mechanism
|
||||
// ISSUE: Consider looping over vectorizedMismatch adjusting ranges
|
||||
// However, requires that returned value be relative to input ranges
|
||||
i++;
|
||||
}
|
||||
// Matched
|
||||
else {
|
||||
i = length - ~i;
|
||||
}
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
float av = a.get(aOff + i);
|
||||
float bv = b.get(bOff + i);
|
||||
if (av != bv && (!Float.isNaN(av) || !Float.isNaN(bv)))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(LongBuffer a, int aOff, LongBuffer b, int bOff, int length) {
|
||||
int i = 0;
|
||||
if (length > 0 && a.order() == b.order()) {
|
||||
i = ArraysSupport.vectorizedMismatch(
|
||||
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE),
|
||||
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE),
|
||||
length,
|
||||
ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE);
|
||||
return i >= 0 ? i : -1;
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
if (a.get(aOff + i) != b.get(bOff + i))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(DoubleBuffer a, int aOff, DoubleBuffer b, int bOff, int length) {
|
||||
int i = 0;
|
||||
if (length > 0 && a.order() == b.order()) {
|
||||
i = ArraysSupport.vectorizedMismatch(
|
||||
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),
|
||||
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),
|
||||
length,
|
||||
ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE);
|
||||
// Mismatched
|
||||
if (i >= 0) {
|
||||
// Check if mismatch is not associated with two NaN values; and
|
||||
// is not associated with +0 and -0
|
||||
double av = a.get(aOff + i);
|
||||
double bv = b.get(bOff + i);
|
||||
if (av != bv && (!Double.isNaN(av) || !Double.isNaN(bv)))
|
||||
return i;
|
||||
|
||||
// Fall back to slow mechanism
|
||||
// ISSUE: Consider looping over vectorizedMismatch adjusting ranges
|
||||
// However, requires that returned value be relative to input ranges
|
||||
i++;
|
||||
}
|
||||
// Matched
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
double av = a.get(aOff + i);
|
||||
double bv = b.get(bOff + i);
|
||||
if (av != bv && (!Double.isNaN(av) || !Double.isNaN(bv)))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -36,9 +36,6 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
|
||||
#if[rw]
|
||||
|
||||
// Cached unsafe-access object
|
||||
private static final Unsafe unsafe = Bits.unsafe();
|
||||
|
||||
protected final ByteBuffer bb;
|
||||
|
||||
#end[rw]
|
||||
|
@ -74,6 +71,11 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
#end[rw]
|
||||
}
|
||||
|
||||
@Override
|
||||
Object base() {
|
||||
return bb.hb;
|
||||
}
|
||||
|
||||
public $Type$Buffer slice() {
|
||||
int pos = this.position();
|
||||
int lim = this.limit();
|
||||
|
@ -117,20 +119,20 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
}
|
||||
|
||||
public $type$ get() {
|
||||
$memtype$ x = unsafe.get$Memtype$Unaligned(bb.hb, byteOffset(nextGetIndex()),
|
||||
$memtype$ x = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(nextGetIndex()),
|
||||
{#if[boB]?true:false});
|
||||
return $fromBits$(x);
|
||||
}
|
||||
|
||||
public $type$ get(int i) {
|
||||
$memtype$ x = unsafe.get$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)),
|
||||
$memtype$ x = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)),
|
||||
{#if[boB]?true:false});
|
||||
return $fromBits$(x);
|
||||
}
|
||||
|
||||
#if[streamableType]
|
||||
$type$ getUnchecked(int i) {
|
||||
$memtype$ x = unsafe.get$Memtype$Unaligned(bb.hb, byteOffset(i),
|
||||
$memtype$ x = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(i),
|
||||
{#if[boB]?true:false});
|
||||
return $fromBits$(x);
|
||||
}
|
||||
|
@ -141,7 +143,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
public $Type$Buffer put($type$ x) {
|
||||
#if[rw]
|
||||
$memtype$ y = $toBits$(x);
|
||||
unsafe.put$Memtype$Unaligned(bb.hb, byteOffset(nextPutIndex()), y,
|
||||
UNSAFE.put$Memtype$Unaligned(bb.hb, byteOffset(nextPutIndex()), y,
|
||||
{#if[boB]?true:false});
|
||||
return this;
|
||||
#else[rw]
|
||||
|
@ -152,7 +154,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
public $Type$Buffer put(int i, $type$ x) {
|
||||
#if[rw]
|
||||
$memtype$ y = $toBits$(x);
|
||||
unsafe.put$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)), y,
|
||||
UNSAFE.put$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)), y,
|
||||
{#if[boB]?true:false});
|
||||
return this;
|
||||
#else[rw]
|
||||
|
@ -241,4 +243,9 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
|||
#end[boL]
|
||||
}
|
||||
|
||||
#if[char]
|
||||
ByteOrder charRegionOrder() {
|
||||
return order();
|
||||
}
|
||||
#end[char]
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ class XXX {
|
|||
#if[rw]
|
||||
|
||||
private $type$ get$Type$(long a) {
|
||||
$memtype$ x = unsafe.get$Memtype$Unaligned(null, a, bigEndian);
|
||||
$memtype$ x = UNSAFE.get$Memtype$Unaligned(null, a, bigEndian);
|
||||
return $fromBits$(x);
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ class XXX {
|
|||
private ByteBuffer put$Type$(long a, $type$ x) {
|
||||
#if[rw]
|
||||
$memtype$ y = $toBits$(x);
|
||||
unsafe.put$Memtype$Unaligned(null, a, y, bigEndian);
|
||||
UNSAFE.put$Memtype$Unaligned(null, a, y, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -81,7 +81,7 @@ class XXX {
|
|||
int rem = (off <= lim ? lim - off : 0);
|
||||
|
||||
int size = rem >> $LG_BYTES_PER_VALUE$;
|
||||
if (!unaligned && ((address + off) % $BYTES_PER_VALUE$ != 0)) {
|
||||
if (!UNALIGNED && ((address + off) % $BYTES_PER_VALUE$ != 0)) {
|
||||
return (bigEndian
|
||||
? ($Type$Buffer)(new ByteBufferAs$Type$Buffer$RW$B(this,
|
||||
-1,
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
package java.nio;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.misc.VM;
|
||||
import jdk.internal.ref.Cleaner;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
|
@ -45,14 +44,11 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
|
||||
#if[rw]
|
||||
|
||||
// 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);
|
||||
private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class);
|
||||
|
||||
// Cached unaligned-access capability
|
||||
protected static final boolean unaligned = Bits.unaligned();
|
||||
protected static final boolean UNALIGNED = Bits.unaligned();
|
||||
|
||||
// Base address, used in all indexing calculations
|
||||
// NOTE: moved up to Buffer.java for speed in JNI GetDirectBufferAddress
|
||||
|
@ -73,8 +69,6 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
implements Runnable
|
||||
{
|
||||
|
||||
private static Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
||||
private long address;
|
||||
private long size;
|
||||
private int capacity;
|
||||
|
@ -91,7 +85,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
// Paranoia
|
||||
return;
|
||||
}
|
||||
unsafe.freeMemory(address);
|
||||
UNSAFE.freeMemory(address);
|
||||
address = 0;
|
||||
Bits.unreserveMemory(size, capacity);
|
||||
}
|
||||
|
@ -124,12 +118,12 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
|
||||
long base = 0;
|
||||
try {
|
||||
base = unsafe.allocateMemory(size);
|
||||
base = UNSAFE.allocateMemory(size);
|
||||
} catch (OutOfMemoryError x) {
|
||||
Bits.unreserveMemory(size, cap);
|
||||
throw x;
|
||||
}
|
||||
unsafe.setMemory(base, size, (byte) 0);
|
||||
UNSAFE.setMemory(base, size, (byte) 0);
|
||||
if (pa && (base % ps != 0)) {
|
||||
// Round up to page boundary
|
||||
address = base + ps - (base & (ps - 1));
|
||||
|
@ -206,6 +200,11 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
#end[rw]
|
||||
}
|
||||
|
||||
@Override
|
||||
Object base() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public $Type$Buffer slice() {
|
||||
int pos = this.position();
|
||||
int lim = this.limit();
|
||||
|
@ -258,16 +257,16 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
}
|
||||
|
||||
public $type$ get() {
|
||||
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(nextGetIndex()))));
|
||||
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(nextGetIndex()))));
|
||||
}
|
||||
|
||||
public $type$ get(int i) {
|
||||
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(checkIndex(i)))));
|
||||
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(checkIndex(i)))));
|
||||
}
|
||||
|
||||
#if[streamableType]
|
||||
$type$ getUnchecked(int i) {
|
||||
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(i))));
|
||||
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(i))));
|
||||
}
|
||||
#end[streamableType]
|
||||
|
||||
|
@ -282,10 +281,10 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
if (length > rem)
|
||||
throw new BufferUnderflowException();
|
||||
|
||||
long dstOffset = arrayBaseOffset + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||
long dstOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||
#if[!byte]
|
||||
if (order() != ByteOrder.nativeOrder())
|
||||
unsafe.copySwapMemory(null,
|
||||
UNSAFE.copySwapMemory(null,
|
||||
ix(pos),
|
||||
dst,
|
||||
dstOffset,
|
||||
|
@ -293,7 +292,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
(long)1 << $LG_BYTES_PER_VALUE$);
|
||||
else
|
||||
#end[!byte]
|
||||
unsafe.copyMemory(null,
|
||||
UNSAFE.copyMemory(null,
|
||||
ix(pos),
|
||||
dst,
|
||||
dstOffset,
|
||||
|
@ -312,7 +311,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
|
||||
public $Type$Buffer put($type$ x) {
|
||||
#if[rw]
|
||||
unsafe.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x)));
|
||||
UNSAFE.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x)));
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -321,7 +320,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
|
||||
public $Type$Buffer put(int i, $type$ x) {
|
||||
#if[rw]
|
||||
unsafe.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x)));
|
||||
UNSAFE.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x)));
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -347,7 +346,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
|
||||
if (srem > rem)
|
||||
throw new BufferOverflowException();
|
||||
unsafe.copyMemory(sb.ix(spos), ix(pos), (long)srem << $LG_BYTES_PER_VALUE$);
|
||||
UNSAFE.copyMemory(sb.ix(spos), ix(pos), (long)srem << $LG_BYTES_PER_VALUE$);
|
||||
sb.position(spos + srem);
|
||||
position(pos + srem);
|
||||
} else if (src.hb != null) {
|
||||
|
@ -380,10 +379,10 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
if (length > rem)
|
||||
throw new BufferOverflowException();
|
||||
|
||||
long srcOffset = arrayBaseOffset + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||
long srcOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||
#if[!byte]
|
||||
if (order() != ByteOrder.nativeOrder())
|
||||
unsafe.copySwapMemory(src,
|
||||
UNSAFE.copySwapMemory(src,
|
||||
srcOffset,
|
||||
null,
|
||||
ix(pos),
|
||||
|
@ -391,7 +390,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
(long)1 << $LG_BYTES_PER_VALUE$);
|
||||
else
|
||||
#end[!byte]
|
||||
unsafe.copyMemory(src,
|
||||
UNSAFE.copyMemory(src,
|
||||
srcOffset,
|
||||
null,
|
||||
ix(pos),
|
||||
|
@ -413,7 +412,7 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
|
||||
unsafe.copyMemory(ix(pos), ix(0), (long)rem << $LG_BYTES_PER_VALUE$);
|
||||
UNSAFE.copyMemory(ix(pos), ix(0), (long)rem << $LG_BYTES_PER_VALUE$);
|
||||
position(rem);
|
||||
limit(capacity());
|
||||
discardMark();
|
||||
|
@ -490,17 +489,22 @@ class Direct$Type$Buffer$RW$$BO$
|
|||
|
||||
#end[!byte]
|
||||
|
||||
#if[char]
|
||||
ByteOrder charRegionOrder() {
|
||||
return order();
|
||||
}
|
||||
#end[char]
|
||||
|
||||
|
||||
#if[byte]
|
||||
|
||||
byte _get(int i) { // package-private
|
||||
return unsafe.getByte(address + i);
|
||||
return UNSAFE.getByte(address + i);
|
||||
}
|
||||
|
||||
void _put(int i, byte b) { // package-private
|
||||
#if[rw]
|
||||
unsafe.putByte(address + i, b);
|
||||
UNSAFE.putByte(address + i, b);
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
#end[rw]
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
|
||||
package java.nio;
|
||||
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
/**
|
||||
#if[rw]
|
||||
* A read/write Heap$Type$Buffer.
|
||||
|
@ -43,6 +41,11 @@ import jdk.internal.misc.Unsafe;
|
|||
class Heap$Type$Buffer$RW$
|
||||
extends {#if[ro]?Heap}$Type$Buffer
|
||||
{
|
||||
// Cached array base offset
|
||||
private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class);
|
||||
|
||||
// Cached array base offset
|
||||
private static final long ARRAY_INDEX_SCALE = UNSAFE.arrayIndexScale($type$[].class);
|
||||
|
||||
// For speed these fields are actually declared in X-Buffer;
|
||||
// these declarations are here as documentation
|
||||
|
@ -53,16 +56,6 @@ class Heap$Type$Buffer$RW$
|
|||
#end[rw]
|
||||
*/
|
||||
|
||||
#if[byte]
|
||||
|
||||
// Cached unsafe-access object
|
||||
private static final Unsafe unsafe = Bits.unsafe();
|
||||
|
||||
// Cached array base offset
|
||||
private static final long arrayBaseOffset = unsafe.arrayBaseOffset($type$[].class);
|
||||
|
||||
#end[byte]
|
||||
|
||||
Heap$Type$Buffer$RW$(int cap, int lim) { // package-private
|
||||
#if[rw]
|
||||
super(-1, 0, lim, cap, new $type$[cap], 0);
|
||||
|
@ -70,13 +63,11 @@ class Heap$Type$Buffer$RW$
|
|||
hb = new $type$[cap];
|
||||
offset = 0;
|
||||
*/
|
||||
this.address = ARRAY_BASE_OFFSET;
|
||||
#else[rw]
|
||||
super(cap, lim);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
#if[byte]
|
||||
this.address = arrayBaseOffset;
|
||||
#end[byte]
|
||||
}
|
||||
|
||||
Heap$Type$Buffer$RW$($type$[] buf, int off, int len) { // package-private
|
||||
|
@ -86,13 +77,11 @@ class Heap$Type$Buffer$RW$
|
|||
hb = buf;
|
||||
offset = 0;
|
||||
*/
|
||||
this.address = ARRAY_BASE_OFFSET;
|
||||
#else[rw]
|
||||
super(buf, off, len);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
#if[byte]
|
||||
this.address = arrayBaseOffset;
|
||||
#end[byte]
|
||||
}
|
||||
|
||||
protected Heap$Type$Buffer$RW$($type$[] buf,
|
||||
|
@ -105,13 +94,11 @@ class Heap$Type$Buffer$RW$
|
|||
hb = buf;
|
||||
offset = off;
|
||||
*/
|
||||
this.address = ARRAY_BASE_OFFSET + off * ARRAY_INDEX_SCALE;
|
||||
#else[rw]
|
||||
super(buf, mark, pos, lim, cap, off);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
#if[byte]
|
||||
this.address = arrayBaseOffset + off;
|
||||
#end[byte]
|
||||
}
|
||||
|
||||
public $Type$Buffer slice() {
|
||||
|
@ -296,18 +283,18 @@ class Heap$Type$Buffer$RW$
|
|||
#if[rw]
|
||||
|
||||
public char getChar() {
|
||||
return unsafe.getCharUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
|
||||
return UNSAFE.getCharUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
|
||||
}
|
||||
|
||||
public char getChar(int i) {
|
||||
return unsafe.getCharUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
|
||||
return UNSAFE.getCharUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
|
||||
}
|
||||
|
||||
#end[rw]
|
||||
|
||||
public $Type$Buffer putChar(char x) {
|
||||
#if[rw]
|
||||
unsafe.putCharUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
|
||||
UNSAFE.putCharUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -316,7 +303,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putChar(int i, char x) {
|
||||
#if[rw]
|
||||
unsafe.putCharUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
|
||||
UNSAFE.putCharUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -347,18 +334,18 @@ class Heap$Type$Buffer$RW$
|
|||
#if[rw]
|
||||
|
||||
public short getShort() {
|
||||
return unsafe.getShortUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
|
||||
return UNSAFE.getShortUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
|
||||
}
|
||||
|
||||
public short getShort(int i) {
|
||||
return unsafe.getShortUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
|
||||
return UNSAFE.getShortUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
|
||||
}
|
||||
|
||||
#end[rw]
|
||||
|
||||
public $Type$Buffer putShort(short x) {
|
||||
#if[rw]
|
||||
unsafe.putShortUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
|
||||
UNSAFE.putShortUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -367,7 +354,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putShort(int i, short x) {
|
||||
#if[rw]
|
||||
unsafe.putShortUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
|
||||
UNSAFE.putShortUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -398,18 +385,18 @@ class Heap$Type$Buffer$RW$
|
|||
#if[rw]
|
||||
|
||||
public int getInt() {
|
||||
return unsafe.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
|
||||
return UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
|
||||
}
|
||||
|
||||
public int getInt(int i) {
|
||||
return unsafe.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
|
||||
return UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
|
||||
}
|
||||
|
||||
#end[rw]
|
||||
|
||||
public $Type$Buffer putInt(int x) {
|
||||
#if[rw]
|
||||
unsafe.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), x, bigEndian);
|
||||
UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -418,7 +405,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putInt(int i, int x) {
|
||||
#if[rw]
|
||||
unsafe.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), x, bigEndian);
|
||||
UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -449,18 +436,18 @@ class Heap$Type$Buffer$RW$
|
|||
#if[rw]
|
||||
|
||||
public long getLong() {
|
||||
return unsafe.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
|
||||
return UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
|
||||
}
|
||||
|
||||
public long getLong(int i) {
|
||||
return unsafe.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
|
||||
return UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
|
||||
}
|
||||
|
||||
#end[rw]
|
||||
|
||||
public $Type$Buffer putLong(long x) {
|
||||
#if[rw]
|
||||
unsafe.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), x, bigEndian);
|
||||
UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -469,7 +456,7 @@ class Heap$Type$Buffer$RW$
|
|||
|
||||
public $Type$Buffer putLong(int i, long x) {
|
||||
#if[rw]
|
||||
unsafe.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), x, bigEndian);
|
||||
UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -500,12 +487,12 @@ class Heap$Type$Buffer$RW$
|
|||
#if[rw]
|
||||
|
||||
public float getFloat() {
|
||||
int x = unsafe.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
|
||||
int x = UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
|
||||
return Float.intBitsToFloat(x);
|
||||
}
|
||||
|
||||
public float getFloat(int i) {
|
||||
int x = unsafe.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
|
||||
int x = UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
|
||||
return Float.intBitsToFloat(x);
|
||||
}
|
||||
|
||||
|
@ -514,7 +501,7 @@ class Heap$Type$Buffer$RW$
|
|||
public $Type$Buffer putFloat(float x) {
|
||||
#if[rw]
|
||||
int y = Float.floatToRawIntBits(x);
|
||||
unsafe.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), y, bigEndian);
|
||||
UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), y, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -524,7 +511,7 @@ class Heap$Type$Buffer$RW$
|
|||
public $Type$Buffer putFloat(int i, float x) {
|
||||
#if[rw]
|
||||
int y = Float.floatToRawIntBits(x);
|
||||
unsafe.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), y, bigEndian);
|
||||
UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), y, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -555,12 +542,12 @@ class Heap$Type$Buffer$RW$
|
|||
#if[rw]
|
||||
|
||||
public double getDouble() {
|
||||
long x = unsafe.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
|
||||
long x = UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
|
||||
return Double.longBitsToDouble(x);
|
||||
}
|
||||
|
||||
public double getDouble(int i) {
|
||||
long x = unsafe.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
|
||||
long x = UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
|
||||
return Double.longBitsToDouble(x);
|
||||
}
|
||||
|
||||
|
@ -569,7 +556,7 @@ class Heap$Type$Buffer$RW$
|
|||
public $Type$Buffer putDouble(double x) {
|
||||
#if[rw]
|
||||
long y = Double.doubleToRawLongBits(x);
|
||||
unsafe.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), y, bigEndian);
|
||||
UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), y, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -579,7 +566,7 @@ class Heap$Type$Buffer$RW$
|
|||
public $Type$Buffer putDouble(int i, double x) {
|
||||
#if[rw]
|
||||
long y = Double.doubleToRawLongBits(x);
|
||||
unsafe.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), y, bigEndian);
|
||||
UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), y, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
|
@ -643,7 +630,11 @@ class Heap$Type$Buffer$RW$
|
|||
public ByteOrder order() {
|
||||
return ByteOrder.nativeOrder();
|
||||
}
|
||||
|
||||
#end[!byte]
|
||||
#if[char]
|
||||
|
||||
ByteOrder charRegionOrder() {
|
||||
return order();
|
||||
}
|
||||
#end[char]
|
||||
}
|
||||
|
|
|
@ -127,4 +127,30 @@ class StringCharBuffer // package-private
|
|||
return ByteOrder.nativeOrder();
|
||||
}
|
||||
|
||||
ByteOrder charRegionOrder() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean equals(Object ob) {
|
||||
if (this == ob)
|
||||
return true;
|
||||
if (!(ob instanceof CharBuffer))
|
||||
return false;
|
||||
CharBuffer that = (CharBuffer)ob;
|
||||
if (this.remaining() != that.remaining())
|
||||
return false;
|
||||
return BufferMismatch.mismatch(this, this.position(),
|
||||
that, that.position(),
|
||||
this.remaining()) < 0;
|
||||
}
|
||||
|
||||
public int compareTo(CharBuffer that) {
|
||||
int i = BufferMismatch.mismatch(this, this.position(),
|
||||
that, that.position(),
|
||||
Math.min(this.remaining(), that.remaining()));
|
||||
if (i >= 0) {
|
||||
return Character.compare(this.get(this.position() + i), that.get(this.position() + i));
|
||||
}
|
||||
return this.remaining() - that.remaining();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ import java.util.stream.StreamSupport;
|
|||
import java.util.stream.$Streamtype$Stream;
|
||||
#end[streamableType]
|
||||
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
|
||||
/**
|
||||
* $A$ $type$ buffer.
|
||||
*
|
||||
|
@ -287,6 +289,11 @@ public abstract class $Type$Buffer
|
|||
this(mark, pos, lim, cap, null, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
Object base() {
|
||||
return hb;
|
||||
}
|
||||
|
||||
#if[byte]
|
||||
|
||||
/**
|
||||
|
@ -1297,19 +1304,9 @@ public abstract class $Type$Buffer
|
|||
$Type$Buffer that = ($Type$Buffer)ob;
|
||||
if (this.remaining() != that.remaining())
|
||||
return false;
|
||||
int p = this.position();
|
||||
for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
|
||||
if (!equals(this.get(i), that.get(j)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean equals($type$ x, $type$ y) {
|
||||
#if[floatingPointType]
|
||||
return (x == y) || ($Fulltype$.isNaN(x) && $Fulltype$.isNaN(y));
|
||||
#else[floatingPointType]
|
||||
return x == y;
|
||||
#end[floatingPointType]
|
||||
return BufferMismatch.mismatch(this, this.position(),
|
||||
that, that.position(),
|
||||
this.remaining()) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1336,11 +1333,11 @@ public abstract class $Type$Buffer
|
|||
* is less than, equal to, or greater than the given buffer
|
||||
*/
|
||||
public int compareTo($Type$Buffer that) {
|
||||
int n = this.position() + Math.min(this.remaining(), that.remaining());
|
||||
for (int i = this.position(), j = that.position(); i < n; i++, j++) {
|
||||
int cmp = compare(this.get(i), that.get(j));
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
int i = BufferMismatch.mismatch(this, this.position(),
|
||||
that, that.position(),
|
||||
Math.min(this.remaining(), that.remaining()));
|
||||
if (i >= 0) {
|
||||
return compare(this.get(this.position() + i), that.get(this.position() + i));
|
||||
}
|
||||
return this.remaining() - that.remaining();
|
||||
}
|
||||
|
@ -1571,6 +1568,12 @@ public abstract class $Type$Buffer
|
|||
|
||||
#end[!byte]
|
||||
|
||||
#if[char]
|
||||
// The order or null if the buffer does not cover a memory region,
|
||||
// such as StringCharBuffer
|
||||
abstract ByteOrder charRegionOrder();
|
||||
#end[char]
|
||||
|
||||
#if[byte]
|
||||
|
||||
boolean bigEndian // package-private
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
package java.util;
|
||||
|
||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2017 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -22,7 +22,7 @@
|
|||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.util;
|
||||
package jdk.internal.util;
|
||||
|
||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
@ -50,19 +50,19 @@ import jdk.internal.misc.Unsafe;
|
|||
* responsibility of the caller (direct or otherwise) to perform such checks
|
||||
* before calling this method.
|
||||
*/
|
||||
class ArraysSupport {
|
||||
public class ArraysSupport {
|
||||
static final Unsafe U = Unsafe.getUnsafe();
|
||||
|
||||
private static final boolean BIG_ENDIAN = U.isBigEndian();
|
||||
|
||||
private static final int LOG2_ARRAY_BOOLEAN_INDEX_SCALE = exactLog2(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE);
|
||||
private static final int LOG2_ARRAY_BYTE_INDEX_SCALE = exactLog2(Unsafe.ARRAY_BYTE_INDEX_SCALE);
|
||||
private static final int LOG2_ARRAY_CHAR_INDEX_SCALE = exactLog2(Unsafe.ARRAY_CHAR_INDEX_SCALE);
|
||||
private static final int LOG2_ARRAY_SHORT_INDEX_SCALE = exactLog2(Unsafe.ARRAY_SHORT_INDEX_SCALE);
|
||||
private static final int LOG2_ARRAY_INT_INDEX_SCALE = exactLog2(Unsafe.ARRAY_INT_INDEX_SCALE);
|
||||
private static final int LOG2_ARRAY_LONG_INDEX_SCALE = exactLog2(Unsafe.ARRAY_LONG_INDEX_SCALE);
|
||||
private static final int LOG2_ARRAY_FLOAT_INDEX_SCALE = exactLog2(Unsafe.ARRAY_FLOAT_INDEX_SCALE);
|
||||
private static final int LOG2_ARRAY_DOUBLE_INDEX_SCALE = exactLog2(Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
|
||||
public static final int LOG2_ARRAY_BOOLEAN_INDEX_SCALE = exactLog2(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE);
|
||||
public static final int LOG2_ARRAY_BYTE_INDEX_SCALE = exactLog2(Unsafe.ARRAY_BYTE_INDEX_SCALE);
|
||||
public static final int LOG2_ARRAY_CHAR_INDEX_SCALE = exactLog2(Unsafe.ARRAY_CHAR_INDEX_SCALE);
|
||||
public static final int LOG2_ARRAY_SHORT_INDEX_SCALE = exactLog2(Unsafe.ARRAY_SHORT_INDEX_SCALE);
|
||||
public static final int LOG2_ARRAY_INT_INDEX_SCALE = exactLog2(Unsafe.ARRAY_INT_INDEX_SCALE);
|
||||
public static final int LOG2_ARRAY_LONG_INDEX_SCALE = exactLog2(Unsafe.ARRAY_LONG_INDEX_SCALE);
|
||||
public static final int LOG2_ARRAY_FLOAT_INDEX_SCALE = exactLog2(Unsafe.ARRAY_FLOAT_INDEX_SCALE);
|
||||
public static final int LOG2_ARRAY_DOUBLE_INDEX_SCALE = exactLog2(Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
|
||||
|
||||
private static final int LOG2_BYTE_BIT_SIZE = exactLog2(Byte.SIZE);
|
||||
|
||||
|
@ -107,10 +107,10 @@ class ArraysSupport {
|
|||
* the tail of the two arrays.
|
||||
*/
|
||||
@HotSpotIntrinsicCandidate
|
||||
static int vectorizedMismatch(Object a, long aOffset,
|
||||
Object b, long bOffset,
|
||||
int length,
|
||||
int log2ArrayIndexScale) {
|
||||
public static int vectorizedMismatch(Object a, long aOffset,
|
||||
Object b, long bOffset,
|
||||
int length,
|
||||
int log2ArrayIndexScale) {
|
||||
// assert a.getClass().isArray();
|
||||
// assert b.getClass().isArray();
|
||||
// assert 0 <= length <= sizeOf(a)
|
||||
|
@ -161,9 +161,9 @@ class ArraysSupport {
|
|||
// Booleans
|
||||
// Each boolean element takes up one byte
|
||||
|
||||
static int mismatch(boolean[] a,
|
||||
boolean[] b,
|
||||
int length) {
|
||||
public static int mismatch(boolean[] a,
|
||||
boolean[] b,
|
||||
int length) {
|
||||
int i = 0;
|
||||
if (length > 7) {
|
||||
i = vectorizedMismatch(
|
||||
|
@ -181,9 +181,9 @@ class ArraysSupport {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(boolean[] a, int aFromIndex,
|
||||
boolean[] b, int bFromIndex,
|
||||
int length) {
|
||||
public static int mismatch(boolean[] a, int aFromIndex,
|
||||
boolean[] b, int bFromIndex,
|
||||
int length) {
|
||||
int i = 0;
|
||||
if (length > 7) {
|
||||
int aOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET + aFromIndex;
|
||||
|
@ -219,9 +219,9 @@ class ArraysSupport {
|
|||
* no mismatch. The index will be within the range of (inclusive) 0 to
|
||||
* (exclusive) the smaller of the two array lengths.
|
||||
*/
|
||||
static int mismatch(byte[] a,
|
||||
byte[] b,
|
||||
int length) {
|
||||
public static int mismatch(byte[] a,
|
||||
byte[] b,
|
||||
int length) {
|
||||
// ISSUE: defer to index receiving methods if performance is good
|
||||
// assert length <= a.length
|
||||
// assert length <= b.length
|
||||
|
@ -264,9 +264,9 @@ class ArraysSupport {
|
|||
* otherwise -1 if no mismatch. The index will be within the range of
|
||||
* (inclusive) 0 to (exclusive) the smaller of the two array bounds.
|
||||
*/
|
||||
static int mismatch(byte[] a, int aFromIndex,
|
||||
byte[] b, int bFromIndex,
|
||||
int length) {
|
||||
public static int mismatch(byte[] a, int aFromIndex,
|
||||
byte[] b, int bFromIndex,
|
||||
int length) {
|
||||
// assert 0 <= aFromIndex < a.length
|
||||
// assert 0 <= aFromIndex + length <= a.length
|
||||
// assert 0 <= bFromIndex < b.length
|
||||
|
@ -295,9 +295,9 @@ class ArraysSupport {
|
|||
|
||||
// Chars
|
||||
|
||||
static int mismatch(char[] a,
|
||||
char[] b,
|
||||
int length) {
|
||||
public static int mismatch(char[] a,
|
||||
char[] b,
|
||||
int length) {
|
||||
int i = 0;
|
||||
if (length > 3) {
|
||||
i = vectorizedMismatch(
|
||||
|
@ -315,9 +315,9 @@ class ArraysSupport {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(char[] a, int aFromIndex,
|
||||
char[] b, int bFromIndex,
|
||||
int length) {
|
||||
public static int mismatch(char[] a, int aFromIndex,
|
||||
char[] b, int bFromIndex,
|
||||
int length) {
|
||||
int i = 0;
|
||||
if (length > 3) {
|
||||
int aOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE);
|
||||
|
@ -340,9 +340,9 @@ class ArraysSupport {
|
|||
|
||||
// Shorts
|
||||
|
||||
static int mismatch(short[] a,
|
||||
short[] b,
|
||||
int length) {
|
||||
public static int mismatch(short[] a,
|
||||
short[] b,
|
||||
int length) {
|
||||
int i = 0;
|
||||
if (length > 3) {
|
||||
i = vectorizedMismatch(
|
||||
|
@ -360,9 +360,9 @@ class ArraysSupport {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(short[] a, int aFromIndex,
|
||||
short[] b, int bFromIndex,
|
||||
int length) {
|
||||
public static int mismatch(short[] a, int aFromIndex,
|
||||
short[] b, int bFromIndex,
|
||||
int length) {
|
||||
int i = 0;
|
||||
if (length > 3) {
|
||||
int aOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE);
|
||||
|
@ -385,9 +385,9 @@ class ArraysSupport {
|
|||
|
||||
// Ints
|
||||
|
||||
static int mismatch(int[] a,
|
||||
int[] b,
|
||||
int length) {
|
||||
public static int mismatch(int[] a,
|
||||
int[] b,
|
||||
int length) {
|
||||
int i = 0;
|
||||
if (length > 1) {
|
||||
i = vectorizedMismatch(
|
||||
|
@ -405,9 +405,9 @@ class ArraysSupport {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(int[] a, int aFromIndex,
|
||||
int[] b, int bFromIndex,
|
||||
int length) {
|
||||
public static int mismatch(int[] a, int aFromIndex,
|
||||
int[] b, int bFromIndex,
|
||||
int length) {
|
||||
int i = 0;
|
||||
if (length > 1) {
|
||||
int aOffset = Unsafe.ARRAY_INT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_INT_INDEX_SCALE);
|
||||
|
@ -430,15 +430,15 @@ class ArraysSupport {
|
|||
|
||||
// Floats
|
||||
|
||||
static int mismatch(float[] a,
|
||||
float[] b,
|
||||
int length) {
|
||||
public static int mismatch(float[] a,
|
||||
float[] b,
|
||||
int length) {
|
||||
return mismatch(a, 0, b, 0, length);
|
||||
}
|
||||
|
||||
static int mismatch(float[] a, int aFromIndex,
|
||||
float[] b, int bFromIndex,
|
||||
int length) {
|
||||
public static int mismatch(float[] a, int aFromIndex,
|
||||
float[] b, int bFromIndex,
|
||||
int length) {
|
||||
int i = 0;
|
||||
if (length > 1) {
|
||||
int aOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE);
|
||||
|
@ -475,9 +475,9 @@ class ArraysSupport {
|
|||
|
||||
// Long
|
||||
|
||||
static int mismatch(long[] a,
|
||||
long[] b,
|
||||
int length) {
|
||||
public static int mismatch(long[] a,
|
||||
long[] b,
|
||||
int length) {
|
||||
if (length == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -488,9 +488,9 @@ class ArraysSupport {
|
|||
return i >= 0 ? i : -1;
|
||||
}
|
||||
|
||||
static int mismatch(long[] a, int aFromIndex,
|
||||
long[] b, int bFromIndex,
|
||||
int length) {
|
||||
public static int mismatch(long[] a, int aFromIndex,
|
||||
long[] b, int bFromIndex,
|
||||
int length) {
|
||||
if (length == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -506,15 +506,15 @@ class ArraysSupport {
|
|||
|
||||
// Double
|
||||
|
||||
static int mismatch(double[] a,
|
||||
double[] b,
|
||||
int length) {
|
||||
public static int mismatch(double[] a,
|
||||
double[] b,
|
||||
int length) {
|
||||
return mismatch(a, 0, b, 0, length);
|
||||
}
|
||||
|
||||
static int mismatch(double[] a, int aFromIndex,
|
||||
double[] b, int bFromIndex,
|
||||
int length) {
|
||||
public static int mismatch(double[] a, int aFromIndex,
|
||||
double[] b, int bFromIndex,
|
||||
int length) {
|
||||
if (length == 0) {
|
||||
return -1;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue