mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8318966: Some methods make promises about Java array element alignment that are too strong
Reviewed-by: psandoz, mcimadamore
This commit is contained in:
parent
737b4c515e
commit
9c852df6aa
19 changed files with 1850 additions and 4678 deletions
|
@ -4513,48 +4513,18 @@ return mh1;
|
|||
* or greater than the {@code byte[]} array length minus the size (in bytes)
|
||||
* of {@code T}.
|
||||
* <p>
|
||||
* Access of bytes at an index may be aligned or misaligned for {@code T},
|
||||
* with respect to the underlying memory address, {@code A} say, associated
|
||||
* with the array and index.
|
||||
* If access is misaligned then access for anything other than the
|
||||
* {@code get} and {@code set} access modes will result in an
|
||||
* {@code IllegalStateException}. In such cases atomic access is only
|
||||
* guaranteed with respect to the largest power of two that divides the GCD
|
||||
* of {@code A} and the size (in bytes) of {@code T}.
|
||||
* If access is aligned then following access modes are supported and are
|
||||
* guaranteed to support atomic access:
|
||||
* <ul>
|
||||
* <li>read write access modes for all {@code T}, with the exception of
|
||||
* access modes {@code get} and {@code set} for {@code long} and
|
||||
* {@code double} on 32-bit platforms.
|
||||
* <li>atomic update access modes for {@code int}, {@code long},
|
||||
* {@code float} or {@code double}.
|
||||
* (Future major platform releases of the JDK may support additional
|
||||
* types for certain currently unsupported access modes.)
|
||||
* <li>numeric atomic update access modes for {@code int} and {@code long}.
|
||||
* (Future major platform releases of the JDK may support additional
|
||||
* numeric types for certain currently unsupported access modes.)
|
||||
* <li>bitwise atomic update access modes for {@code int} and {@code long}.
|
||||
* (Future major platform releases of the JDK may support additional
|
||||
* numeric types for certain currently unsupported access modes.)
|
||||
* </ul>
|
||||
* <p>
|
||||
* Misaligned access, and therefore atomicity guarantees, may be determined
|
||||
* for {@code byte[]} arrays without operating on a specific array. Given
|
||||
* an {@code index}, {@code T} and its corresponding boxed type,
|
||||
* {@code T_BOX}, misalignment may be determined as follows:
|
||||
* <pre>{@code
|
||||
* int sizeOfT = T_BOX.BYTES; // size in bytes of T
|
||||
* int misalignedAtZeroIndex = ByteBuffer.wrap(new byte[0]).
|
||||
* alignmentOffset(0, sizeOfT);
|
||||
* int misalignedAtIndex = (misalignedAtZeroIndex + index) % sizeOfT;
|
||||
* boolean isMisaligned = misalignedAtIndex != 0;
|
||||
* }</pre>
|
||||
* <p>
|
||||
* If the variable type is {@code float} or {@code double} then atomic
|
||||
* update access modes compare values using their bitwise representation
|
||||
* (see {@link Float#floatToRawIntBits} and
|
||||
* {@link Double#doubleToRawLongBits}, respectively).
|
||||
* Only plain {@linkplain VarHandle.AccessMode#GET get} and {@linkplain VarHandle.AccessMode#SET set}
|
||||
* access modes are supported by the returned var handle. For all other access modes, an
|
||||
* {@link UnsupportedOperationException} will be thrown.
|
||||
*
|
||||
* @apiNote if access modes other than plain access are required, clients should
|
||||
* consider using off-heap memory through
|
||||
* {@linkplain java.nio.ByteBuffer#allocateDirect(int) direct byte buffers} or
|
||||
* off-heap {@linkplain java.lang.foreign.MemorySegment memory segments},
|
||||
* or memory segments backed by a
|
||||
* {@linkplain java.lang.foreign.MemorySegment#ofArray(long[]) {@code long[]}},
|
||||
* for which stronger alignment guarantees can be made.
|
||||
*
|
||||
* @param viewArrayClass the view array class, with a component type of
|
||||
* type {@code T}
|
||||
* @param byteOrder the endianness of the view array elements, as
|
||||
|
@ -4600,7 +4570,13 @@ return mh1;
|
|||
* or greater than the {@code ByteBuffer} limit minus the size (in bytes) of
|
||||
* {@code T}.
|
||||
* <p>
|
||||
* Access of bytes at an index may be aligned or misaligned for {@code T},
|
||||
* For heap byte buffers, access is always unaligned. As a result, only the plain
|
||||
* {@linkplain VarHandle.AccessMode#GET get}
|
||||
* and {@linkplain VarHandle.AccessMode#SET set} access modes are supported by the
|
||||
* returned var handle. For all other access modes, an {@link IllegalStateException}
|
||||
* will be thrown.
|
||||
* <p>
|
||||
* For direct buffers only, access of bytes at an index may be aligned or misaligned for {@code T},
|
||||
* with respect to the underlying memory address, {@code A} say, associated
|
||||
* with the {@code ByteBuffer} and index.
|
||||
* If access is misaligned then access for anything other than the
|
||||
|
|
|
@ -49,7 +49,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||
|
||||
static final int ALIGN = $BoxType$.BYTES - 1;
|
||||
|
||||
|
||||
static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();
|
||||
|
||||
#if[floatingPoint]
|
||||
|
@ -115,14 +115,6 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
return Preconditions.checkIndex(index, ba.length - ALIGN, Preconditions.AIOOBE_FORMATTER);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static long address(byte[] ba, int index) {
|
||||
long address = ((long) index) + Unsafe.ARRAY_BYTE_BASE_OFFSET;
|
||||
if ((address & ALIGN) != 0)
|
||||
throw newIllegalStateExceptionForMisalignedAccess(index);
|
||||
return address;
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ get(VarHandle ob, Object oba, int index) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
|
@ -160,419 +152,6 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
#end[floatingPoint]
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getVolatile(VarHandle ob, Object oba, int index) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
return convEndian(handle.be,
|
||||
UNSAFE.get$RawType$Volatile(
|
||||
ba,
|
||||
address(ba, index(ba, index))));
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static void setVolatile(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
UNSAFE.put$RawType$Volatile(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, value));
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAcquire(VarHandle ob, Object oba, int index) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
return convEndian(handle.be,
|
||||
UNSAFE.get$RawType$Acquire(
|
||||
ba,
|
||||
address(ba, index(ba, index))));
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static void setRelease(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
UNSAFE.put$RawType$Release(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, value));
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getOpaque(VarHandle ob, Object oba, int index) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
return convEndian(handle.be,
|
||||
UNSAFE.get$RawType$Opaque(
|
||||
ba,
|
||||
address(ba, index(ba, index))));
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static void setOpaque(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
UNSAFE.put$RawType$Opaque(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, value));
|
||||
}
|
||||
#if[CAS]
|
||||
|
||||
@ForceInline
|
||||
static boolean compareAndSet(VarHandle ob, Object oba, int index, $type$ expected, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
#if[Object]
|
||||
return UNSAFE.compareAndSetReference(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value));
|
||||
#else[Object]
|
||||
return UNSAFE.compareAndSet$RawType$(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value));
|
||||
#end[Object]
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ compareAndExchange(VarHandle ob, Object oba, int index, $type$ expected, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
return convEndian(handle.be,
|
||||
UNSAFE.compareAndExchange$RawType$(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value)));
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ compareAndExchangeAcquire(VarHandle ob, Object oba, int index, $type$ expected, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
return convEndian(handle.be,
|
||||
UNSAFE.compareAndExchange$RawType$Acquire(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value)));
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ compareAndExchangeRelease(VarHandle ob, Object oba, int index, $type$ expected, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
return convEndian(handle.be,
|
||||
UNSAFE.compareAndExchange$RawType$Release(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value)));
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static boolean weakCompareAndSetPlain(VarHandle ob, Object oba, int index, $type$ expected, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
return UNSAFE.weakCompareAndSet$RawType$Plain(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value));
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static boolean weakCompareAndSet(VarHandle ob, Object oba, int index, $type$ expected, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
return UNSAFE.weakCompareAndSet$RawType$(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value));
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static boolean weakCompareAndSetAcquire(VarHandle ob, Object oba, int index, $type$ expected, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
return UNSAFE.weakCompareAndSet$RawType$Acquire(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value));
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static boolean weakCompareAndSetRelease(VarHandle ob, Object oba, int index, $type$ expected, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
return UNSAFE.weakCompareAndSet$RawType$Release(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value));
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndSet(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
#if[Object]
|
||||
return convEndian(handle.be,
|
||||
UNSAFE.getAndSetReference(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, value)));
|
||||
#else[Object]
|
||||
return convEndian(handle.be,
|
||||
UNSAFE.getAndSet$RawType$(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, value)));
|
||||
#end[Object]
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndSetAcquire(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
return convEndian(handle.be,
|
||||
UNSAFE.getAndSet$RawType$Acquire(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, value)));
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndSetRelease(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
return convEndian(handle.be,
|
||||
UNSAFE.getAndSet$RawType$Release(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
convEndian(handle.be, value)));
|
||||
}
|
||||
#end[CAS]
|
||||
#if[AtomicAdd]
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndAdd(VarHandle ob, Object oba, int index, $type$ delta) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
if (handle.be == BE) {
|
||||
return UNSAFE.getAndAdd$RawType$(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
delta);
|
||||
} else {
|
||||
return getAndAddConvEndianWithCAS(ba, index, delta);
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndAddAcquire(VarHandle ob, Object oba, int index, $type$ delta) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
if (handle.be == BE) {
|
||||
return UNSAFE.getAndAdd$RawType$Acquire(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
delta);
|
||||
} else {
|
||||
return getAndAddConvEndianWithCAS(ba, index, delta);
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndAddRelease(VarHandle ob, Object oba, int index, $type$ delta) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
if (handle.be == BE) {
|
||||
return UNSAFE.getAndAdd$RawType$Release(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
delta);
|
||||
} else {
|
||||
return getAndAddConvEndianWithCAS(ba, index, delta);
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndAddConvEndianWithCAS(byte[] ba, int index, $type$ delta) {
|
||||
$type$ nativeExpectedValue, expectedValue;
|
||||
long offset = address(ba, index(ba, index));
|
||||
do {
|
||||
nativeExpectedValue = UNSAFE.get$RawType$Volatile(ba, offset);
|
||||
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
|
||||
} while (!UNSAFE.weakCompareAndSet$RawType$(ba, offset,
|
||||
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue + delta)));
|
||||
return expectedValue;
|
||||
}
|
||||
#end[AtomicAdd]
|
||||
#if[Bitwise]
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndBitwiseOr(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
if (handle.be == BE) {
|
||||
return UNSAFE.getAndBitwiseOr$RawType$(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
value);
|
||||
} else {
|
||||
return getAndBitwiseOrConvEndianWithCAS(ba, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndBitwiseOrRelease(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
if (handle.be == BE) {
|
||||
return UNSAFE.getAndBitwiseOr$RawType$Release(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
value);
|
||||
} else {
|
||||
return getAndBitwiseOrConvEndianWithCAS(ba, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndBitwiseOrAcquire(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
if (handle.be == BE) {
|
||||
return UNSAFE.getAndBitwiseOr$RawType$Acquire(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
value);
|
||||
} else {
|
||||
return getAndBitwiseOrConvEndianWithCAS(ba, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndBitwiseOrConvEndianWithCAS(byte[] ba, int index, $type$ value) {
|
||||
$type$ nativeExpectedValue, expectedValue;
|
||||
long offset = address(ba, index(ba, index));
|
||||
do {
|
||||
nativeExpectedValue = UNSAFE.get$RawType$Volatile(ba, offset);
|
||||
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
|
||||
} while (!UNSAFE.weakCompareAndSet$RawType$(ba, offset,
|
||||
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue | value)));
|
||||
return expectedValue;
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndBitwiseAnd(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
if (handle.be == BE) {
|
||||
return UNSAFE.getAndBitwiseAnd$RawType$(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
value);
|
||||
} else {
|
||||
return getAndBitwiseAndConvEndianWithCAS(ba, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndBitwiseAndRelease(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
if (handle.be == BE) {
|
||||
return UNSAFE.getAndBitwiseAnd$RawType$Release(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
value);
|
||||
} else {
|
||||
return getAndBitwiseAndConvEndianWithCAS(ba, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndBitwiseAndAcquire(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
if (handle.be == BE) {
|
||||
return UNSAFE.getAndBitwiseAnd$RawType$Acquire(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
value);
|
||||
} else {
|
||||
return getAndBitwiseAndConvEndianWithCAS(ba, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndBitwiseAndConvEndianWithCAS(byte[] ba, int index, $type$ value) {
|
||||
$type$ nativeExpectedValue, expectedValue;
|
||||
long offset = address(ba, index(ba, index));
|
||||
do {
|
||||
nativeExpectedValue = UNSAFE.get$RawType$Volatile(ba, offset);
|
||||
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
|
||||
} while (!UNSAFE.weakCompareAndSet$RawType$(ba, offset,
|
||||
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue & value)));
|
||||
return expectedValue;
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndBitwiseXor(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
if (handle.be == BE) {
|
||||
return UNSAFE.getAndBitwiseXor$RawType$(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
value);
|
||||
} else {
|
||||
return getAndBitwiseXorConvEndianWithCAS(ba, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndBitwiseXorRelease(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
if (handle.be == BE) {
|
||||
return UNSAFE.getAndBitwiseXor$RawType$Release(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
value);
|
||||
} else {
|
||||
return getAndBitwiseXorConvEndianWithCAS(ba, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndBitwiseXorAcquire(VarHandle ob, Object oba, int index, $type$ value) {
|
||||
ArrayHandle handle = (ArrayHandle)ob;
|
||||
byte[] ba = (byte[]) oba;
|
||||
if (handle.be == BE) {
|
||||
return UNSAFE.getAndBitwiseXor$RawType$Acquire(
|
||||
ba,
|
||||
address(ba, index(ba, index)),
|
||||
value);
|
||||
} else {
|
||||
return getAndBitwiseXorConvEndianWithCAS(ba, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ getAndBitwiseXorConvEndianWithCAS(byte[] ba, int index, $type$ value) {
|
||||
$type$ nativeExpectedValue, expectedValue;
|
||||
long offset = address(ba, index(ba, index));
|
||||
do {
|
||||
nativeExpectedValue = UNSAFE.get$RawType$Volatile(ba, offset);
|
||||
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
|
||||
} while (!UNSAFE.weakCompareAndSet$RawType$(ba, offset,
|
||||
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue ^ value)));
|
||||
return expectedValue;
|
||||
}
|
||||
#end[Bitwise]
|
||||
|
||||
static final VarForm FORM = new VarForm(ArrayHandle.class, byte[].class, $type$.class, int.class);
|
||||
}
|
||||
|
||||
|
@ -634,6 +213,14 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
return address;
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static Object checkNullHeapBase(Object hb) {
|
||||
if (hb != null) {
|
||||
throw new IllegalStateException("Atomic access not supported for heap buffer");
|
||||
}
|
||||
return hb;
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
static $type$ get(VarHandle ob, Object obb, int index) {
|
||||
ByteBufferHandle handle = (ByteBufferHandle)ob;
|
||||
|
@ -677,7 +264,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
return convEndian(handle.be,
|
||||
SCOPED_MEMORY_ACCESS.get$RawType$Volatile(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, index(bb, index))));
|
||||
}
|
||||
|
||||
|
@ -686,7 +273,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBufferHandle handle = (ByteBufferHandle)ob;
|
||||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
SCOPED_MEMORY_ACCESS.put$RawType$Volatile(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, value));
|
||||
}
|
||||
|
@ -697,7 +284,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
return convEndian(handle.be,
|
||||
SCOPED_MEMORY_ACCESS.get$RawType$Acquire(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, index(bb, index))));
|
||||
}
|
||||
|
||||
|
@ -706,7 +293,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBufferHandle handle = (ByteBufferHandle)ob;
|
||||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
SCOPED_MEMORY_ACCESS.put$RawType$Release(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, value));
|
||||
}
|
||||
|
@ -717,7 +304,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
return convEndian(handle.be,
|
||||
SCOPED_MEMORY_ACCESS.get$RawType$Opaque(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, index(bb, index))));
|
||||
}
|
||||
|
||||
|
@ -726,7 +313,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBufferHandle handle = (ByteBufferHandle)ob;
|
||||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
SCOPED_MEMORY_ACCESS.put$RawType$Opaque(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, value));
|
||||
}
|
||||
|
@ -736,17 +323,10 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
static boolean compareAndSet(VarHandle ob, Object obb, int index, $type$ expected, $type$ value) {
|
||||
ByteBufferHandle handle = (ByteBufferHandle)ob;
|
||||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
#if[Object]
|
||||
return SCOPED_MEMORY_ACCESS.compareAndSetReference(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value));
|
||||
#else[Object]
|
||||
return SCOPED_MEMORY_ACCESS.compareAndSet$RawType$(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value));
|
||||
#end[Object]
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
|
@ -755,7 +335,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
return convEndian(handle.be,
|
||||
SCOPED_MEMORY_ACCESS.compareAndExchange$RawType$(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value)));
|
||||
}
|
||||
|
@ -766,7 +346,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
return convEndian(handle.be,
|
||||
SCOPED_MEMORY_ACCESS.compareAndExchange$RawType$Acquire(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value)));
|
||||
}
|
||||
|
@ -777,7 +357,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
return convEndian(handle.be,
|
||||
SCOPED_MEMORY_ACCESS.compareAndExchange$RawType$Release(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value)));
|
||||
}
|
||||
|
@ -787,7 +367,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBufferHandle handle = (ByteBufferHandle)ob;
|
||||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$Plain(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value));
|
||||
}
|
||||
|
@ -797,7 +377,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBufferHandle handle = (ByteBufferHandle)ob;
|
||||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value));
|
||||
}
|
||||
|
@ -807,7 +387,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBufferHandle handle = (ByteBufferHandle)ob;
|
||||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$Acquire(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value));
|
||||
}
|
||||
|
@ -817,7 +397,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBufferHandle handle = (ByteBufferHandle)ob;
|
||||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$Release(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, expected), convEndian(handle.be, value));
|
||||
}
|
||||
|
@ -826,19 +406,11 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
static $type$ getAndSet(VarHandle ob, Object obb, int index, $type$ value) {
|
||||
ByteBufferHandle handle = (ByteBufferHandle)ob;
|
||||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
#if[Object]
|
||||
return convEndian(handle.be,
|
||||
SCOPED_MEMORY_ACCESS.getAndSetReference(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, value)));
|
||||
#else[Object]
|
||||
return convEndian(handle.be,
|
||||
SCOPED_MEMORY_ACCESS.getAndSet$RawType$(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, value)));
|
||||
#end[Object]
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
|
@ -847,7 +419,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
return convEndian(handle.be,
|
||||
SCOPED_MEMORY_ACCESS.getAndSet$RawType$Acquire(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, value)));
|
||||
}
|
||||
|
@ -858,7 +430,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
return convEndian(handle.be,
|
||||
SCOPED_MEMORY_ACCESS.getAndSet$RawType$Release(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
convEndian(handle.be, value)));
|
||||
}
|
||||
|
@ -871,7 +443,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
if (handle.be == BE) {
|
||||
return SCOPED_MEMORY_ACCESS.getAndAdd$RawType$(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
delta);
|
||||
} else {
|
||||
|
@ -885,7 +457,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
if (handle.be == BE) {
|
||||
return SCOPED_MEMORY_ACCESS.getAndAdd$RawType$Acquire(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
delta);
|
||||
} else {
|
||||
|
@ -899,7 +471,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
if (handle.be == BE) {
|
||||
return SCOPED_MEMORY_ACCESS.getAndAdd$RawType$Release(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
delta);
|
||||
} else {
|
||||
|
@ -910,7 +482,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
@ForceInline
|
||||
static $type$ getAndAddConvEndianWithCAS(ByteBuffer bb, int index, $type$ delta) {
|
||||
$type$ nativeExpectedValue, expectedValue;
|
||||
Object base = UNSAFE.getReference(bb, BYTE_BUFFER_HB);
|
||||
Object base = checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB));
|
||||
long offset = address(bb, indexRO(bb, index));
|
||||
do {
|
||||
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(session(bb), base, offset);
|
||||
|
@ -928,7 +500,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
if (handle.be == BE) {
|
||||
return SCOPED_MEMORY_ACCESS.getAndBitwiseOr$RawType$(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
value);
|
||||
} else {
|
||||
|
@ -942,7 +514,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
if (handle.be == BE) {
|
||||
return SCOPED_MEMORY_ACCESS.getAndBitwiseOr$RawType$Release(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
value);
|
||||
} else {
|
||||
|
@ -956,7 +528,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
if (handle.be == BE) {
|
||||
return SCOPED_MEMORY_ACCESS.getAndBitwiseOr$RawType$Acquire(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
value);
|
||||
} else {
|
||||
|
@ -967,7 +539,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
@ForceInline
|
||||
static $type$ getAndBitwiseOrConvEndianWithCAS(ByteBuffer bb, int index, $type$ value) {
|
||||
$type$ nativeExpectedValue, expectedValue;
|
||||
Object base = UNSAFE.getReference(bb, BYTE_BUFFER_HB);
|
||||
Object base = checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB));
|
||||
long offset = address(bb, indexRO(bb, index));
|
||||
do {
|
||||
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(session(bb), base, offset);
|
||||
|
@ -983,7 +555,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
if (handle.be == BE) {
|
||||
return SCOPED_MEMORY_ACCESS.getAndBitwiseAnd$RawType$(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
value);
|
||||
} else {
|
||||
|
@ -997,7 +569,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
if (handle.be == BE) {
|
||||
return SCOPED_MEMORY_ACCESS.getAndBitwiseAnd$RawType$Release(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
value);
|
||||
} else {
|
||||
|
@ -1011,7 +583,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
if (handle.be == BE) {
|
||||
return SCOPED_MEMORY_ACCESS.getAndBitwiseAnd$RawType$Acquire(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
value);
|
||||
} else {
|
||||
|
@ -1022,7 +594,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
@ForceInline
|
||||
static $type$ getAndBitwiseAndConvEndianWithCAS(ByteBuffer bb, int index, $type$ value) {
|
||||
$type$ nativeExpectedValue, expectedValue;
|
||||
Object base = UNSAFE.getReference(bb, BYTE_BUFFER_HB);
|
||||
Object base = checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB));
|
||||
long offset = address(bb, indexRO(bb, index));
|
||||
do {
|
||||
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(session(bb), base, offset);
|
||||
|
@ -1039,7 +611,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
if (handle.be == BE) {
|
||||
return SCOPED_MEMORY_ACCESS.getAndBitwiseXor$RawType$(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
value);
|
||||
} else {
|
||||
|
@ -1053,7 +625,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
if (handle.be == BE) {
|
||||
return SCOPED_MEMORY_ACCESS.getAndBitwiseXor$RawType$Release(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
value);
|
||||
} else {
|
||||
|
@ -1067,7 +639,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
|
||||
if (handle.be == BE) {
|
||||
return SCOPED_MEMORY_ACCESS.getAndBitwiseXor$RawType$Acquire(session(bb),
|
||||
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
|
||||
checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB)),
|
||||
address(bb, indexRO(bb, index)),
|
||||
value);
|
||||
} else {
|
||||
|
@ -1078,7 +650,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
|
|||
@ForceInline
|
||||
static $type$ getAndBitwiseXorConvEndianWithCAS(ByteBuffer bb, int index, $type$ value) {
|
||||
$type$ nativeExpectedValue, expectedValue;
|
||||
Object base = UNSAFE.getReference(bb, BYTE_BUFFER_HB);
|
||||
Object base = checkNullHeapBase(UNSAFE.getReference(bb, BYTE_BUFFER_HB));
|
||||
long offset = address(bb, indexRO(bb, index));
|
||||
do {
|
||||
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(session(bb), base, offset);
|
||||
|
|
|
@ -1557,7 +1557,7 @@ public abstract sealed class $Type$Buffer
|
|||
super.position(newPosition);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
|
@ -1571,13 +1571,13 @@ public abstract sealed class $Type$Buffer
|
|||
super.limit(newLimit);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
public
|
||||
#if[!byte]
|
||||
final
|
||||
#end[!byte]
|
||||
|
@ -1591,7 +1591,7 @@ public abstract sealed class $Type$Buffer
|
|||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
public
|
||||
#if[!byte]
|
||||
final
|
||||
#end[!byte]
|
||||
|
@ -1605,7 +1605,7 @@ public abstract sealed class $Type$Buffer
|
|||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
public
|
||||
#if[!byte]
|
||||
final
|
||||
#end[!byte]
|
||||
|
@ -1619,7 +1619,7 @@ public abstract sealed class $Type$Buffer
|
|||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
public
|
||||
#if[!byte]
|
||||
final
|
||||
#end[!byte]
|
||||
|
@ -1633,7 +1633,7 @@ public abstract sealed class $Type$Buffer
|
|||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
public
|
||||
#if[!byte]
|
||||
final
|
||||
#end[!byte]
|
||||
|
@ -2208,15 +2208,11 @@ public abstract sealed class $Type$Buffer
|
|||
* alignmentOffset(index + (unitSize - value), unitSize) == 0
|
||||
* }
|
||||
* must hold.
|
||||
*
|
||||
*
|
||||
* @apiNote
|
||||
* This method may be utilized to determine if unit size bytes from an
|
||||
* index can be accessed atomically, if supported by the native platform.
|
||||
*
|
||||
* @implNote
|
||||
* This implementation throws {@code UnsupportedOperationException} for
|
||||
* non-direct buffers when the given unit size is greater then {@code 8}.
|
||||
*
|
||||
* @param index
|
||||
* The index to query for alignment offset, must be non-negative, no
|
||||
* upper bounds check is performed
|
||||
|
@ -2231,13 +2227,7 @@ public abstract sealed class $Type$Buffer
|
|||
* {@code 2}
|
||||
*
|
||||
* @throws UnsupportedOperationException
|
||||
* If the native platform does not guarantee stable alignment offset
|
||||
* values for the given unit size when managing the memory regions
|
||||
* of buffers of the same kind as this buffer (direct or
|
||||
* non-direct). For example, if garbage collection would result
|
||||
* in the moving of a memory region covered by a non-direct buffer
|
||||
* from one location to another and both locations have different
|
||||
* alignment characteristics.
|
||||
* If the buffer is non-direct, and {@code unitSize > 1}
|
||||
*
|
||||
* @see #alignedSlice(int)
|
||||
* @since 9
|
||||
|
@ -2247,7 +2237,7 @@ public abstract sealed class $Type$Buffer
|
|||
throw new IllegalArgumentException("Index less than zero: " + index);
|
||||
if (unitSize < 1 || (unitSize & (unitSize - 1)) != 0)
|
||||
throw new IllegalArgumentException("Unit size not a power of two: " + unitSize);
|
||||
if (unitSize > 8 && !isDirect())
|
||||
if (unitSize > 1 && !isDirect())
|
||||
throw new UnsupportedOperationException("Unit size unsupported for non-direct buffers: " + unitSize);
|
||||
|
||||
return (int) ((address + index) & (unitSize - 1));
|
||||
|
@ -2287,10 +2277,6 @@ public abstract sealed class $Type$Buffer
|
|||
* from index, that is a multiple of the unit size, may be accessed
|
||||
* atomically, if supported by the native platform.
|
||||
*
|
||||
* @implNote
|
||||
* This implementation throws {@code UnsupportedOperationException} for
|
||||
* non-direct buffers when the given unit size is greater then {@code 8}.
|
||||
*
|
||||
* @param unitSize
|
||||
* The unit size in bytes, must be a power of {@code 2}
|
||||
*
|
||||
|
@ -2300,13 +2286,7 @@ public abstract sealed class $Type$Buffer
|
|||
* If the unit size not a power of {@code 2}
|
||||
*
|
||||
* @throws UnsupportedOperationException
|
||||
* If the native platform does not guarantee stable aligned slices
|
||||
* for the given unit size when managing the memory regions
|
||||
* of buffers of the same kind as this buffer (direct or
|
||||
* non-direct). For example, if garbage collection would result
|
||||
* in the moving of a memory region covered by a non-direct buffer
|
||||
* from one location to another and both locations have different
|
||||
* alignment characteristics.
|
||||
* If the buffer is non-direct, and {@code unitSize > 1}
|
||||
*
|
||||
* @see #alignmentOffset(int, int)
|
||||
* @see #slice()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue