8318966: Some methods make promises about Java array element alignment that are too strong

Reviewed-by: psandoz, mcimadamore
This commit is contained in:
Jorn Vernee 2024-02-14 14:30:54 +00:00
parent 737b4c515e
commit 9c852df6aa
19 changed files with 1850 additions and 4678 deletions

View file

@ -4513,48 +4513,18 @@ return mh1;
* or greater than the {@code byte[]} array length minus the size (in bytes) * or greater than the {@code byte[]} array length minus the size (in bytes)
* of {@code T}. * of {@code T}.
* <p> * <p>
* Access of bytes at an index may be aligned or misaligned for {@code T}, * Only plain {@linkplain VarHandle.AccessMode#GET get} and {@linkplain VarHandle.AccessMode#SET set}
* with respect to the underlying memory address, {@code A} say, associated * access modes are supported by the returned var handle. For all other access modes, an
* with the array and index. * {@link UnsupportedOperationException} will be thrown.
* If access is misaligned then access for anything other than the *
* {@code get} and {@code set} access modes will result in an * @apiNote if access modes other than plain access are required, clients should
* {@code IllegalStateException}. In such cases atomic access is only * consider using off-heap memory through
* guaranteed with respect to the largest power of two that divides the GCD * {@linkplain java.nio.ByteBuffer#allocateDirect(int) direct byte buffers} or
* of {@code A} and the size (in bytes) of {@code T}. * off-heap {@linkplain java.lang.foreign.MemorySegment memory segments},
* If access is aligned then following access modes are supported and are * or memory segments backed by a
* guaranteed to support atomic access: * {@linkplain java.lang.foreign.MemorySegment#ofArray(long[]) {@code long[]}},
* <ul> * for which stronger alignment guarantees can be made.
* <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).
* @param viewArrayClass the view array class, with a component type of * @param viewArrayClass the view array class, with a component type of
* type {@code T} * type {@code T}
* @param byteOrder the endianness of the view array elements, as * @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 * or greater than the {@code ByteBuffer} limit minus the size (in bytes) of
* {@code T}. * {@code T}.
* <p> * <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 respect to the underlying memory address, {@code A} say, associated
* with the {@code ByteBuffer} and index. * with the {@code ByteBuffer} and index.
* If access is misaligned then access for anything other than the * If access is misaligned then access for anything other than the

View file

@ -49,7 +49,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess(); static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
static final int ALIGN = $BoxType$.BYTES - 1; static final int ALIGN = $BoxType$.BYTES - 1;
static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess(); static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();
#if[floatingPoint] #if[floatingPoint]
@ -115,14 +115,6 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
return Preconditions.checkIndex(index, ba.length - ALIGN, Preconditions.AIOOBE_FORMATTER); 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 @ForceInline
static $type$ get(VarHandle ob, Object oba, int index) { static $type$ get(VarHandle ob, Object oba, int index) {
ArrayHandle handle = (ArrayHandle)ob; ArrayHandle handle = (ArrayHandle)ob;
@ -160,419 +152,6 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
#end[floatingPoint] #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); 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; return address;
} }
@ForceInline
static Object checkNullHeapBase(Object hb) {
if (hb != null) {
throw new IllegalStateException("Atomic access not supported for heap buffer");
}
return hb;
}
@ForceInline @ForceInline
static $type$ get(VarHandle ob, Object obb, int index) { static $type$ get(VarHandle ob, Object obb, int index) {
ByteBufferHandle handle = (ByteBufferHandle)ob; ByteBufferHandle handle = (ByteBufferHandle)ob;
@ -677,7 +264,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be, return convEndian(handle.be,
SCOPED_MEMORY_ACCESS.get$RawType$Volatile(session(bb), 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)))); address(bb, index(bb, index))));
} }
@ -686,7 +273,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob; ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
SCOPED_MEMORY_ACCESS.put$RawType$Volatile(session(bb), 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)), address(bb, indexRO(bb, index)),
convEndian(handle.be, value)); convEndian(handle.be, value));
} }
@ -697,7 +284,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be, return convEndian(handle.be,
SCOPED_MEMORY_ACCESS.get$RawType$Acquire(session(bb), 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)))); address(bb, index(bb, index))));
} }
@ -706,7 +293,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob; ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
SCOPED_MEMORY_ACCESS.put$RawType$Release(session(bb), 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)), address(bb, indexRO(bb, index)),
convEndian(handle.be, value)); convEndian(handle.be, value));
} }
@ -717,7 +304,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be, return convEndian(handle.be,
SCOPED_MEMORY_ACCESS.get$RawType$Opaque(session(bb), 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)))); address(bb, index(bb, index))));
} }
@ -726,7 +313,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob; ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
SCOPED_MEMORY_ACCESS.put$RawType$Opaque(session(bb), 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)), address(bb, indexRO(bb, index)),
convEndian(handle.be, value)); 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) { static boolean compareAndSet(VarHandle ob, Object obb, int index, $type$ expected, $type$ value) {
ByteBufferHandle handle = (ByteBufferHandle)ob; ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); 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), 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)), address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value)); convEndian(handle.be, expected), convEndian(handle.be, value));
#end[Object]
} }
@ForceInline @ForceInline
@ -755,7 +335,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be, return convEndian(handle.be,
SCOPED_MEMORY_ACCESS.compareAndExchange$RawType$(session(bb), 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)), address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value))); 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); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be, return convEndian(handle.be,
SCOPED_MEMORY_ACCESS.compareAndExchange$RawType$Acquire(session(bb), 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)), address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value))); 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); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be, return convEndian(handle.be,
SCOPED_MEMORY_ACCESS.compareAndExchange$RawType$Release(session(bb), 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)), address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value))); convEndian(handle.be, expected), convEndian(handle.be, value)));
} }
@ -787,7 +367,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob; ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$Plain(session(bb), 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)), address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value)); convEndian(handle.be, expected), convEndian(handle.be, value));
} }
@ -797,7 +377,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob; ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$(session(bb), 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)), address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value)); convEndian(handle.be, expected), convEndian(handle.be, value));
} }
@ -807,7 +387,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob; ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$Acquire(session(bb), 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)), address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value)); convEndian(handle.be, expected), convEndian(handle.be, value));
} }
@ -817,7 +397,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob; ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$Release(session(bb), 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)), address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value)); 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) { static $type$ getAndSet(VarHandle ob, Object obb, int index, $type$ value) {
ByteBufferHandle handle = (ByteBufferHandle)ob; ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); 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, return convEndian(handle.be,
SCOPED_MEMORY_ACCESS.getAndSet$RawType$(session(bb), 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)), address(bb, indexRO(bb, index)),
convEndian(handle.be, value))); convEndian(handle.be, value)));
#end[Object]
} }
@ForceInline @ForceInline
@ -847,7 +419,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be, return convEndian(handle.be,
SCOPED_MEMORY_ACCESS.getAndSet$RawType$Acquire(session(bb), 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)), address(bb, indexRO(bb, index)),
convEndian(handle.be, value))); convEndian(handle.be, value)));
} }
@ -858,7 +430,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be, return convEndian(handle.be,
SCOPED_MEMORY_ACCESS.getAndSet$RawType$Release(session(bb), 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)), address(bb, indexRO(bb, index)),
convEndian(handle.be, value))); convEndian(handle.be, value)));
} }
@ -871,7 +443,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) { if (handle.be == BE) {
return SCOPED_MEMORY_ACCESS.getAndAdd$RawType$(session(bb), 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)), address(bb, indexRO(bb, index)),
delta); delta);
} else { } else {
@ -885,7 +457,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) { if (handle.be == BE) {
return SCOPED_MEMORY_ACCESS.getAndAdd$RawType$Acquire(session(bb), 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)), address(bb, indexRO(bb, index)),
delta); delta);
} else { } else {
@ -899,7 +471,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) { if (handle.be == BE) {
return SCOPED_MEMORY_ACCESS.getAndAdd$RawType$Release(session(bb), 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)), address(bb, indexRO(bb, index)),
delta); delta);
} else { } else {
@ -910,7 +482,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline @ForceInline
static $type$ getAndAddConvEndianWithCAS(ByteBuffer bb, int index, $type$ delta) { static $type$ getAndAddConvEndianWithCAS(ByteBuffer bb, int index, $type$ delta) {
$type$ nativeExpectedValue, expectedValue; $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)); long offset = address(bb, indexRO(bb, index));
do { do {
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(session(bb), base, offset); 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); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) { if (handle.be == BE) {
return SCOPED_MEMORY_ACCESS.getAndBitwiseOr$RawType$(session(bb), 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)), address(bb, indexRO(bb, index)),
value); value);
} else { } else {
@ -942,7 +514,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) { if (handle.be == BE) {
return SCOPED_MEMORY_ACCESS.getAndBitwiseOr$RawType$Release(session(bb), 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)), address(bb, indexRO(bb, index)),
value); value);
} else { } else {
@ -956,7 +528,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) { if (handle.be == BE) {
return SCOPED_MEMORY_ACCESS.getAndBitwiseOr$RawType$Acquire(session(bb), 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)), address(bb, indexRO(bb, index)),
value); value);
} else { } else {
@ -967,7 +539,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline @ForceInline
static $type$ getAndBitwiseOrConvEndianWithCAS(ByteBuffer bb, int index, $type$ value) { static $type$ getAndBitwiseOrConvEndianWithCAS(ByteBuffer bb, int index, $type$ value) {
$type$ nativeExpectedValue, expectedValue; $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)); long offset = address(bb, indexRO(bb, index));
do { do {
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(session(bb), base, offset); 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); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) { if (handle.be == BE) {
return SCOPED_MEMORY_ACCESS.getAndBitwiseAnd$RawType$(session(bb), 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)), address(bb, indexRO(bb, index)),
value); value);
} else { } else {
@ -997,7 +569,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) { if (handle.be == BE) {
return SCOPED_MEMORY_ACCESS.getAndBitwiseAnd$RawType$Release(session(bb), 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)), address(bb, indexRO(bb, index)),
value); value);
} else { } else {
@ -1011,7 +583,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) { if (handle.be == BE) {
return SCOPED_MEMORY_ACCESS.getAndBitwiseAnd$RawType$Acquire(session(bb), 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)), address(bb, indexRO(bb, index)),
value); value);
} else { } else {
@ -1022,7 +594,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline @ForceInline
static $type$ getAndBitwiseAndConvEndianWithCAS(ByteBuffer bb, int index, $type$ value) { static $type$ getAndBitwiseAndConvEndianWithCAS(ByteBuffer bb, int index, $type$ value) {
$type$ nativeExpectedValue, expectedValue; $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)); long offset = address(bb, indexRO(bb, index));
do { do {
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(session(bb), base, offset); 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); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) { if (handle.be == BE) {
return SCOPED_MEMORY_ACCESS.getAndBitwiseXor$RawType$(session(bb), 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)), address(bb, indexRO(bb, index)),
value); value);
} else { } else {
@ -1053,7 +625,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) { if (handle.be == BE) {
return SCOPED_MEMORY_ACCESS.getAndBitwiseXor$RawType$Release(session(bb), 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)), address(bb, indexRO(bb, index)),
value); value);
} else { } else {
@ -1067,7 +639,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb); ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) { if (handle.be == BE) {
return SCOPED_MEMORY_ACCESS.getAndBitwiseXor$RawType$Acquire(session(bb), 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)), address(bb, indexRO(bb, index)),
value); value);
} else { } else {
@ -1078,7 +650,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline @ForceInline
static $type$ getAndBitwiseXorConvEndianWithCAS(ByteBuffer bb, int index, $type$ value) { static $type$ getAndBitwiseXorConvEndianWithCAS(ByteBuffer bb, int index, $type$ value) {
$type$ nativeExpectedValue, expectedValue; $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)); long offset = address(bb, indexRO(bb, index));
do { do {
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(session(bb), base, offset); nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(session(bb), base, offset);

View file

@ -1557,7 +1557,7 @@ public abstract sealed class $Type$Buffer
super.position(newPosition); super.position(newPosition);
return this; return this;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
* @since 9 * @since 9
@ -1571,13 +1571,13 @@ public abstract sealed class $Type$Buffer
super.limit(newLimit); super.limit(newLimit);
return this; return this;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
* @since 9 * @since 9
*/ */
@Override @Override
public public
#if[!byte] #if[!byte]
final final
#end[!byte] #end[!byte]
@ -1591,7 +1591,7 @@ public abstract sealed class $Type$Buffer
* @since 9 * @since 9
*/ */
@Override @Override
public public
#if[!byte] #if[!byte]
final final
#end[!byte] #end[!byte]
@ -1605,7 +1605,7 @@ public abstract sealed class $Type$Buffer
* @since 9 * @since 9
*/ */
@Override @Override
public public
#if[!byte] #if[!byte]
final final
#end[!byte] #end[!byte]
@ -1619,7 +1619,7 @@ public abstract sealed class $Type$Buffer
* @since 9 * @since 9
*/ */
@Override @Override
public public
#if[!byte] #if[!byte]
final final
#end[!byte] #end[!byte]
@ -1633,7 +1633,7 @@ public abstract sealed class $Type$Buffer
* @since 9 * @since 9
*/ */
@Override @Override
public public
#if[!byte] #if[!byte]
final final
#end[!byte] #end[!byte]
@ -2208,15 +2208,11 @@ public abstract sealed class $Type$Buffer
* alignmentOffset(index + (unitSize - value), unitSize) == 0 * alignmentOffset(index + (unitSize - value), unitSize) == 0
* } * }
* must hold. * must hold.
* *
* @apiNote * @apiNote
* This method may be utilized to determine if unit size bytes from an * This method may be utilized to determine if unit size bytes from an
* index can be accessed atomically, if supported by the native platform. * 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 * @param index
* The index to query for alignment offset, must be non-negative, no * The index to query for alignment offset, must be non-negative, no
* upper bounds check is performed * upper bounds check is performed
@ -2231,13 +2227,7 @@ public abstract sealed class $Type$Buffer
* {@code 2} * {@code 2}
* *
* @throws UnsupportedOperationException * @throws UnsupportedOperationException
* If the native platform does not guarantee stable alignment offset * If the buffer is non-direct, and {@code unitSize > 1}
* 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.
* *
* @see #alignedSlice(int) * @see #alignedSlice(int)
* @since 9 * @since 9
@ -2247,7 +2237,7 @@ public abstract sealed class $Type$Buffer
throw new IllegalArgumentException("Index less than zero: " + index); throw new IllegalArgumentException("Index less than zero: " + index);
if (unitSize < 1 || (unitSize & (unitSize - 1)) != 0) if (unitSize < 1 || (unitSize & (unitSize - 1)) != 0)
throw new IllegalArgumentException("Unit size not a power of two: " + unitSize); 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); throw new UnsupportedOperationException("Unit size unsupported for non-direct buffers: " + unitSize);
return (int) ((address + index) & (unitSize - 1)); 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 * from index, that is a multiple of the unit size, may be accessed
* atomically, if supported by the native platform. * 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 * @param unitSize
* The unit size in bytes, must be a power of {@code 2} * 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} * If the unit size not a power of {@code 2}
* *
* @throws UnsupportedOperationException * @throws UnsupportedOperationException
* If the native platform does not guarantee stable aligned slices * If the buffer is non-direct, and {@code unitSize > 1}
* 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.
* *
* @see #alignmentOffset(int, int) * @see #alignmentOffset(int, int)
* @see #slice() * @see #slice()

View file

@ -159,8 +159,11 @@ public abstract class VarHandleBaseByteArrayTest extends VarHandleBaseTest {
} }
static class VarHandleSource extends Source<VarHandle> { static class VarHandleSource extends Source<VarHandle> {
VarHandleSource(VarHandle vh, MemoryMode... modes) { final boolean supportsAtomicAccess;
VarHandleSource(VarHandle vh, boolean supportsAtomicAccess, MemoryMode... modes) {
super(vh, modes); super(vh, modes);
this.supportsAtomicAccess = supportsAtomicAccess;
} }
boolean matches(ByteArrayViewSource<?> bav) { boolean matches(ByteArrayViewSource<?> bav) {

View file

@ -72,12 +72,12 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
arrayType = int[].class; arrayType = int[].class;
} }
VarHandleSource aeh = new VarHandleSource( VarHandleSource aeh = new VarHandleSource(
MethodHandles.byteArrayViewVarHandle(arrayType, bo), MethodHandles.byteArrayViewVarHandle(arrayType, bo), false,
endianess, MemoryMode.READ_WRITE); endianess, MemoryMode.READ_WRITE);
vhss.add(aeh); vhss.add(aeh);
VarHandleSource bbh = new VarHandleSource( VarHandleSource bbh = new VarHandleSource(
MethodHandles.byteBufferViewVarHandle(arrayType, bo), MethodHandles.byteBufferViewVarHandle(arrayType, bo), true,
endianess, MemoryMode.READ_WRITE); endianess, MemoryMode.READ_WRITE);
vhss.add(bbh); vhss.add(bbh);
} }
@ -114,38 +114,48 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE)); if (vhs.supportsAtomicAccess) {
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
} else {
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
}
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE));
} }
@Test(dataProvider = "typesProvider") @Test(dataProvider = "typesProvider")
@ -180,9 +190,6 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
cases.add(new VarHandleSourceAccessTestCase( cases.add(new VarHandleSourceAccessTestCase(
"index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h), "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
false)); false));
cases.add(new VarHandleSourceAccessTestCase(
"misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
false));
} }
else { else {
ByteBufferSource bbs = (ByteBufferSource) bav; ByteBufferSource bbs = (ByteBufferSource) bav;
@ -207,9 +214,11 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
cases.add(new VarHandleSourceAccessTestCase( cases.add(new VarHandleSourceAccessTestCase(
"index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h), "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
false)); false));
cases.add(new VarHandleSourceAccessTestCase( if (bbs.s.isDirect()) {
"misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h), cases.add(new VarHandleSourceAccessTestCase(
false)); "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
false));
}
} }
} }
} }
@ -243,33 +252,6 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
checkNPE(() -> { checkNPE(() -> {
vh.set(array, ci, VALUE_1); vh.set(array, ci, VALUE_1);
}); });
checkNPE(() -> {
char x = (char) vh.getVolatile(array, ci);
});
checkNPE(() -> {
char x = (char) vh.getAcquire(array, ci);
});
checkNPE(() -> {
char x = (char) vh.getOpaque(array, ci);
});
checkNPE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkNPE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkNPE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
} }
static void testArrayNPE(ByteBufferSource bs, VarHandleSource vhs) { static void testArrayNPE(ByteBufferSource bs, VarHandleSource vhs) {
@ -423,7 +405,7 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
}); });
} }
if (readOnly) { if (readOnly && array.isDirect()) {
checkROBE(() -> { checkROBE(() -> {
vh.setVolatile(array, ci, VALUE_1); vh.setVolatile(array, ci, VALUE_1);
}); });
@ -435,6 +417,11 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
checkROBE(() -> { checkROBE(() -> {
vh.setOpaque(array, ci, VALUE_1); vh.setOpaque(array, ci, VALUE_1);
}); });
}
if (array.isDirect()) {
checkUOE(() -> { checkUOE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
}); });
@ -478,7 +465,6 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
checkUOE(() -> { checkUOE(() -> {
char o = (char) vh.getAndSetRelease(array, ci, VALUE_1); char o = (char) vh.getAndSetRelease(array, ci, VALUE_1);
}); });
checkUOE(() -> { checkUOE(() -> {
char o = (char) vh.getAndAdd(array, ci, VALUE_1); char o = (char) vh.getAndAdd(array, ci, VALUE_1);
}); });
@ -490,7 +476,6 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
checkUOE(() -> { checkUOE(() -> {
char o = (char) vh.getAndAddRelease(array, ci, VALUE_1); char o = (char) vh.getAndAddRelease(array, ci, VALUE_1);
}); });
checkUOE(() -> { checkUOE(() -> {
char o = (char) vh.getAndBitwiseOr(array, ci, VALUE_1); char o = (char) vh.getAndBitwiseOr(array, ci, VALUE_1);
}); });
@ -526,8 +511,18 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
checkUOE(() -> { checkUOE(() -> {
char o = (char) vh.getAndBitwiseXorRelease(array, ci, VALUE_1); char o = (char) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
}); });
} } else {
else { checkISE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkISE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkISE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
checkUOE(() -> { checkUOE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
}); });
@ -636,33 +631,6 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
checkAIOOBE(() -> { checkAIOOBE(() -> {
vh.set(array, ci, VALUE_1); vh.set(array, ci, VALUE_1);
}); });
checkAIOOBE(() -> {
char x = (char) vh.getVolatile(array, ci);
});
checkAIOOBE(() -> {
char x = (char) vh.getAcquire(array, ci);
});
checkAIOOBE(() -> {
char x = (char) vh.getOpaque(array, ci);
});
checkAIOOBE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkAIOOBE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkAIOOBE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
} }
} }
@ -686,74 +654,35 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
}); });
} }
checkIOOBE(() -> { if (array.isDirect()) {
char x = (char) vh.getVolatile(array, ci);
});
checkIOOBE(() -> {
char x = (char) vh.getAcquire(array, ci);
});
checkIOOBE(() -> {
char x = (char) vh.getOpaque(array, ci);
});
if (!readOnly) {
checkIOOBE(() -> { checkIOOBE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkIOOBE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkIOOBE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
}
}
}
static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
VarHandle vh = vhs.s;
byte[] array = bs.s;
int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
int length = array.length - SIZE + 1;
for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
final int ci = i;
if (!iAligned) {
checkISE(() -> {
char x = (char) vh.getVolatile(array, ci); char x = (char) vh.getVolatile(array, ci);
}); });
checkISE(() -> { checkIOOBE(() -> {
char x = (char) vh.getAcquire(array, ci); char x = (char) vh.getAcquire(array, ci);
}); });
checkISE(() -> { checkIOOBE(() -> {
char x = (char) vh.getOpaque(array, ci); char x = (char) vh.getOpaque(array, ci);
}); });
checkISE(() -> { if (!readOnly) {
vh.setVolatile(array, ci, VALUE_1); checkIOOBE(() -> {
}); vh.setVolatile(array, ci, VALUE_1);
});
checkISE(() -> { checkIOOBE(() -> {
vh.setRelease(array, ci, VALUE_1); vh.setRelease(array, ci, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
vh.setOpaque(array, ci, VALUE_1); vh.setOpaque(array, ci, VALUE_1);
}); });
}
} }
} }
} }
@ -795,9 +724,6 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
checkISE(() -> { checkISE(() -> {
vh.setOpaque(array, ci, VALUE_1); vh.setOpaque(array, ci, VALUE_1);
}); });
} }
} }
} }
@ -807,45 +733,15 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
VarHandle vh = vhs.s; VarHandle vh = vhs.s;
byte[] array = bs.s; byte[] array = bs.s;
int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
bs.fill((byte) 0xff); bs.fill((byte) 0xff);
int length = array.length - SIZE + 1; int length = array.length - SIZE + 1;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
// Plain // Plain
{ {
vh.set(array, i, VALUE_1); vh.set(array, i, VALUE_1);
char x = (char) vh.get(array, i); char x = (char) vh.get(array, i);
assertEquals(x, VALUE_1, "get char value"); assertEquals(x, VALUE_1, "get char value");
} }
if (iAligned) {
// Volatile
{
vh.setVolatile(array, i, VALUE_2);
char x = (char) vh.getVolatile(array, i);
assertEquals(x, VALUE_2, "setVolatile char value");
}
// Lazy
{
vh.setRelease(array, i, VALUE_1);
char x = (char) vh.getAcquire(array, i);
assertEquals(x, VALUE_1, "setRelease char value");
}
// Opaque
{
vh.setOpaque(array, i, VALUE_2);
char x = (char) vh.getOpaque(array, i);
assertEquals(x, VALUE_2, "setOpaque char value");
}
}
} }
} }
@ -854,12 +750,10 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
VarHandle vh = vhs.s; VarHandle vh = vhs.s;
ByteBuffer array = bs.s; ByteBuffer array = bs.s;
int misalignmentAtZero = array.alignmentOffset(0, SIZE);
bs.fill((byte) 0xff); bs.fill((byte) 0xff);
int length = array.limit() - SIZE + 1; int length = array.limit() - SIZE + 1;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; boolean iAligned = array.isDirect() ? ((i + array.alignmentOffset(0, SIZE)) & (SIZE - 1)) == 0 : false;
// Plain // Plain
{ {
@ -899,15 +793,13 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
VarHandle vh = vhs.s; VarHandle vh = vhs.s;
ByteBuffer array = bs.s; ByteBuffer array = bs.s;
int misalignmentAtZero = array.alignmentOffset(0, SIZE);
ByteBuffer bb = ByteBuffer.allocate(SIZE); ByteBuffer bb = ByteBuffer.allocate(SIZE);
bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
bs.fill(bb.putChar(0, VALUE_2).array()); bs.fill(bb.putChar(0, VALUE_2).array());
int length = array.limit() - SIZE + 1; int length = array.limit() - SIZE + 1;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; boolean iAligned = array.isDirect() ? ((i + array.alignmentOffset(0, SIZE)) & (SIZE - 1)) == 0 : false;
char v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) char v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
? rotateLeft(VALUE_2, (i % SIZE) << 3) ? rotateLeft(VALUE_2, (i % SIZE) << 3)

View file

@ -72,12 +72,12 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
arrayType = int[].class; arrayType = int[].class;
} }
VarHandleSource aeh = new VarHandleSource( VarHandleSource aeh = new VarHandleSource(
MethodHandles.byteArrayViewVarHandle(arrayType, bo), MethodHandles.byteArrayViewVarHandle(arrayType, bo), false,
endianess, MemoryMode.READ_WRITE); endianess, MemoryMode.READ_WRITE);
vhss.add(aeh); vhss.add(aeh);
VarHandleSource bbh = new VarHandleSource( VarHandleSource bbh = new VarHandleSource(
MethodHandles.byteBufferViewVarHandle(arrayType, bo), MethodHandles.byteBufferViewVarHandle(arrayType, bo), true,
endianess, MemoryMode.READ_WRITE); endianess, MemoryMode.READ_WRITE);
vhss.add(bbh); vhss.add(bbh);
} }
@ -114,38 +114,62 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE)); if (vhs.supportsAtomicAccess) {
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
} else {
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
}
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET)); if (vhs.supportsAtomicAccess) {
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
} else {
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
}
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE));
} }
@Test(dataProvider = "typesProvider") @Test(dataProvider = "typesProvider")
@ -180,9 +204,6 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
cases.add(new VarHandleSourceAccessTestCase( cases.add(new VarHandleSourceAccessTestCase(
"index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h), "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
false)); false));
cases.add(new VarHandleSourceAccessTestCase(
"misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
false));
} }
else { else {
ByteBufferSource bbs = (ByteBufferSource) bav; ByteBufferSource bbs = (ByteBufferSource) bav;
@ -207,9 +228,11 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
cases.add(new VarHandleSourceAccessTestCase( cases.add(new VarHandleSourceAccessTestCase(
"index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h), "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
false)); false));
cases.add(new VarHandleSourceAccessTestCase( if (bbs.s.isDirect()) {
"misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h), cases.add(new VarHandleSourceAccessTestCase(
false)); "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
false));
}
} }
} }
} }
@ -243,76 +266,6 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
checkNPE(() -> { checkNPE(() -> {
vh.set(array, ci, VALUE_1); vh.set(array, ci, VALUE_1);
}); });
checkNPE(() -> {
double x = (double) vh.getVolatile(array, ci);
});
checkNPE(() -> {
double x = (double) vh.getAcquire(array, ci);
});
checkNPE(() -> {
double x = (double) vh.getOpaque(array, ci);
});
checkNPE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkNPE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkNPE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
checkNPE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkNPE(() -> {
double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
});
checkNPE(() -> {
double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
});
checkNPE(() -> {
double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
});
checkNPE(() -> {
boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
});
checkNPE(() -> {
boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkNPE(() -> {
boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
});
checkNPE(() -> {
boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
});
checkNPE(() -> {
double o = (double) vh.getAndSet(array, ci, VALUE_1);
});
checkNPE(() -> {
double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
});
checkNPE(() -> {
double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
});
} }
static void testArrayNPE(ByteBufferSource bs, VarHandleSource vhs) { static void testArrayNPE(ByteBufferSource bs, VarHandleSource vhs) {
@ -404,6 +357,49 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
byte[] array = bs.s; byte[] array = bs.s;
int ci = 1; int ci = 1;
checkUOE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkUOE(() -> {
double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
});
checkUOE(() -> {
double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
});
checkUOE(() -> {
double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
});
checkUOE(() -> {
boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
});
checkUOE(() -> {
boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkUOE(() -> {
boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
});
checkUOE(() -> {
boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
});
checkUOE(() -> {
double o = (double) vh.getAndSet(array, ci, VALUE_1);
});
checkUOE(() -> {
double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
});
checkUOE(() -> {
double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
});
checkUOE(() -> { checkUOE(() -> {
double o = (double) vh.getAndAdd(array, ci, VALUE_1); double o = (double) vh.getAndAdd(array, ci, VALUE_1);
@ -466,7 +462,7 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
}); });
} }
if (readOnly) { if (readOnly && array.isDirect()) {
checkROBE(() -> { checkROBE(() -> {
vh.setVolatile(array, ci, VALUE_1); vh.setVolatile(array, ci, VALUE_1);
}); });
@ -478,7 +474,6 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
checkROBE(() -> { checkROBE(() -> {
vh.setOpaque(array, ci, VALUE_1); vh.setOpaque(array, ci, VALUE_1);
}); });
checkROBE(() -> { checkROBE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
}); });
@ -524,6 +519,9 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
}); });
}
if (array.isDirect()) {
checkUOE(() -> { checkUOE(() -> {
double o = (double) vh.getAndAdd(array, ci, VALUE_1); double o = (double) vh.getAndAdd(array, ci, VALUE_1);
}); });
@ -535,7 +533,6 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
checkUOE(() -> { checkUOE(() -> {
double o = (double) vh.getAndAddRelease(array, ci, VALUE_1); double o = (double) vh.getAndAddRelease(array, ci, VALUE_1);
}); });
checkUOE(() -> { checkUOE(() -> {
double o = (double) vh.getAndBitwiseOr(array, ci, VALUE_1); double o = (double) vh.getAndBitwiseOr(array, ci, VALUE_1);
}); });
@ -571,8 +568,61 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
checkUOE(() -> { checkUOE(() -> {
double o = (double) vh.getAndBitwiseXorRelease(array, ci, VALUE_1); double o = (double) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
}); });
} } else {
else { checkISE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkISE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkISE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
checkISE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkISE(() -> {
double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
});
checkISE(() -> {
double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
});
checkISE(() -> {
double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
});
checkISE(() -> {
boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
});
checkISE(() -> {
boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkISE(() -> {
boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
});
checkISE(() -> {
boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
});
checkISE(() -> {
double o = (double) vh.getAndSet(array, ci, VALUE_1);
});
checkISE(() -> {
double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
});
checkISE(() -> {
double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
});
checkUOE(() -> { checkUOE(() -> {
double o = (double) vh.getAndAdd(array, ci, VALUE_1); double o = (double) vh.getAndAdd(array, ci, VALUE_1);
}); });
@ -638,77 +688,6 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
checkAIOOBE(() -> { checkAIOOBE(() -> {
vh.set(array, ci, VALUE_1); vh.set(array, ci, VALUE_1);
}); });
checkAIOOBE(() -> {
double x = (double) vh.getVolatile(array, ci);
});
checkAIOOBE(() -> {
double x = (double) vh.getAcquire(array, ci);
});
checkAIOOBE(() -> {
double x = (double) vh.getOpaque(array, ci);
});
checkAIOOBE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkAIOOBE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkAIOOBE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
checkAIOOBE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkAIOOBE(() -> {
double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
});
checkAIOOBE(() -> {
double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
});
checkAIOOBE(() -> {
double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
});
checkAIOOBE(() -> {
boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
});
checkAIOOBE(() -> {
boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkAIOOBE(() -> {
boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
});
checkAIOOBE(() -> {
boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
});
checkAIOOBE(() -> {
double o = (double) vh.getAndSet(array, ci, VALUE_1);
});
checkAIOOBE(() -> {
double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
});
checkAIOOBE(() -> {
double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
});
} }
} }
@ -732,161 +711,78 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
}); });
} }
checkIOOBE(() -> { if (array.isDirect()) {
double x = (double) vh.getVolatile(array, ci);
});
checkIOOBE(() -> {
double x = (double) vh.getAcquire(array, ci);
});
checkIOOBE(() -> {
double x = (double) vh.getOpaque(array, ci);
});
if (!readOnly) {
checkIOOBE(() -> { checkIOOBE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkIOOBE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkIOOBE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
checkIOOBE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkIOOBE(() -> {
double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
});
checkIOOBE(() -> {
double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
});
checkIOOBE(() -> {
double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
});
checkIOOBE(() -> {
boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
});
checkIOOBE(() -> {
boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkIOOBE(() -> {
boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
});
checkIOOBE(() -> {
boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
});
checkIOOBE(() -> {
double o = (double) vh.getAndSet(array, ci, VALUE_1);
});
checkIOOBE(() -> {
double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
});
checkIOOBE(() -> {
double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
});
}
}
}
static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
VarHandle vh = vhs.s;
byte[] array = bs.s;
int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
int length = array.length - SIZE + 1;
for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
final int ci = i;
if (!iAligned) {
checkISE(() -> {
double x = (double) vh.getVolatile(array, ci); double x = (double) vh.getVolatile(array, ci);
}); });
checkISE(() -> { checkIOOBE(() -> {
double x = (double) vh.getAcquire(array, ci); double x = (double) vh.getAcquire(array, ci);
}); });
checkISE(() -> { checkIOOBE(() -> {
double x = (double) vh.getOpaque(array, ci); double x = (double) vh.getOpaque(array, ci);
}); });
checkISE(() -> { if (!readOnly) {
vh.setVolatile(array, ci, VALUE_1); checkIOOBE(() -> {
}); vh.setVolatile(array, ci, VALUE_1);
});
checkISE(() -> { checkIOOBE(() -> {
vh.setRelease(array, ci, VALUE_1); vh.setRelease(array, ci, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
vh.setOpaque(array, ci, VALUE_1); vh.setOpaque(array, ci, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
}); });
checkISE(() -> { checkIOOBE(() -> {
double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1); double r = (double) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2); boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
}); });
checkISE(() -> { checkIOOBE(() -> {
boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
}); });
checkISE(() -> { checkIOOBE(() -> {
boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
}); });
checkISE(() -> { checkIOOBE(() -> {
boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
}); });
checkISE(() -> { checkIOOBE(() -> {
double o = (double) vh.getAndSet(array, ci, VALUE_1); double o = (double) vh.getAndSet(array, ci, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1); double o = (double) vh.getAndSetAcquire(array, ci, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
double o = (double) vh.getAndSetRelease(array, ci, VALUE_1); double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
}); });
}
} }
} }
} }
@ -928,7 +824,6 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
checkISE(() -> { checkISE(() -> {
vh.setOpaque(array, ci, VALUE_1); vh.setOpaque(array, ci, VALUE_1);
}); });
checkISE(() -> { checkISE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
}); });
@ -972,8 +867,6 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
checkISE(() -> { checkISE(() -> {
double o = (double) vh.getAndSetRelease(array, ci, VALUE_1); double o = (double) vh.getAndSetRelease(array, ci, VALUE_1);
}); });
} }
} }
} }
@ -983,204 +876,15 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
VarHandle vh = vhs.s; VarHandle vh = vhs.s;
byte[] array = bs.s; byte[] array = bs.s;
int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
bs.fill((byte) 0xff); bs.fill((byte) 0xff);
int length = array.length - SIZE + 1; int length = array.length - SIZE + 1;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
// Plain // Plain
{ {
vh.set(array, i, VALUE_1); vh.set(array, i, VALUE_1);
double x = (double) vh.get(array, i); double x = (double) vh.get(array, i);
assertEquals(x, VALUE_1, "get double value"); assertEquals(x, VALUE_1, "get double value");
} }
if (iAligned) {
// Volatile
{
vh.setVolatile(array, i, VALUE_2);
double x = (double) vh.getVolatile(array, i);
assertEquals(x, VALUE_2, "setVolatile double value");
}
// Lazy
{
vh.setRelease(array, i, VALUE_1);
double x = (double) vh.getAcquire(array, i);
assertEquals(x, VALUE_1, "setRelease double value");
}
// Opaque
{
vh.setOpaque(array, i, VALUE_2);
double x = (double) vh.getOpaque(array, i);
assertEquals(x, VALUE_2, "setOpaque double value");
}
vh.set(array, i, VALUE_1);
// Compare
{
boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
assertEquals(r, true, "success compareAndSet double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_2, "success compareAndSet double value");
}
{
boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
assertEquals(r, false, "failing compareAndSet double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_2, "failing compareAndSet double value");
}
{
double r = (double) vh.compareAndExchange(array, i, VALUE_2, VALUE_1);
assertEquals(r, VALUE_2, "success compareAndExchange double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_1, "success compareAndExchange double value");
}
{
double r = (double) vh.compareAndExchange(array, i, VALUE_2, VALUE_3);
assertEquals(r, VALUE_1, "failing compareAndExchange double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_1, "failing compareAndExchange double value");
}
{
double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
assertEquals(r, VALUE_1, "success compareAndExchangeAcquire double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_2, "success compareAndExchangeAcquire double value");
}
{
double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire double value");
}
{
double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
assertEquals(r, VALUE_2, "success compareAndExchangeRelease double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_1, "success compareAndExchangeRelease double value");
}
{
double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
assertEquals(r, VALUE_1, "failing compareAndExchangeRelease double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_1, "failing compareAndExchangeRelease double value");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2);
if (!success) weakDelay();
}
assertEquals(success, true, "success weakCompareAndSetPlain double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_2, "success weakCompareAndSetPlain double value");
}
{
boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3);
assertEquals(success, false, "failing weakCompareAndSetPlain double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain double value");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
if (!success) weakDelay();
}
assertEquals(success, true, "success weakCompareAndSetAcquire double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire double");
}
{
boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3);
assertEquals(success, false, "failing weakCompareAndSetAcquire double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire double value");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
if (!success) weakDelay();
}
assertEquals(success, true, "success weakCompareAndSetRelease double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_2, "success weakCompareAndSetRelease double");
}
{
boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3);
assertEquals(success, false, "failing weakCompareAndSetRelease double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease double value");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1);
if (!success) weakDelay();
}
assertEquals(success, true, "success weakCompareAndSet double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_1, "success weakCompareAndSet double");
}
{
boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3);
assertEquals(success, false, "failing weakCompareAndSet double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_1, "failing weakCompareAndSet double value");
}
// Compare set and get
{
vh.set(array, i, VALUE_1);
double o = (double) vh.getAndSet(array, i, VALUE_2);
assertEquals(o, VALUE_1, "getAndSet double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_2, "getAndSet double value");
}
{
vh.set(array, i, VALUE_1);
double o = (double) vh.getAndSetAcquire(array, i, VALUE_2);
assertEquals(o, VALUE_1, "getAndSetAcquire double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_2, "getAndSetAcquire double value");
}
{
vh.set(array, i, VALUE_1);
double o = (double) vh.getAndSetRelease(array, i, VALUE_2);
assertEquals(o, VALUE_1, "getAndSetRelease double");
double x = (double) vh.get(array, i);
assertEquals(x, VALUE_2, "getAndSetRelease double value");
}
}
} }
} }
@ -1189,12 +893,10 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
VarHandle vh = vhs.s; VarHandle vh = vhs.s;
ByteBuffer array = bs.s; ByteBuffer array = bs.s;
int misalignmentAtZero = array.alignmentOffset(0, SIZE);
bs.fill((byte) 0xff); bs.fill((byte) 0xff);
int length = array.limit() - SIZE + 1; int length = array.limit() - SIZE + 1;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; boolean iAligned = array.isDirect() ? ((i + array.alignmentOffset(0, SIZE)) & (SIZE - 1)) == 0 : false;
// Plain // Plain
{ {
@ -1393,15 +1095,13 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
VarHandle vh = vhs.s; VarHandle vh = vhs.s;
ByteBuffer array = bs.s; ByteBuffer array = bs.s;
int misalignmentAtZero = array.alignmentOffset(0, SIZE);
ByteBuffer bb = ByteBuffer.allocate(SIZE); ByteBuffer bb = ByteBuffer.allocate(SIZE);
bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
bs.fill(bb.putDouble(0, VALUE_2).array()); bs.fill(bb.putDouble(0, VALUE_2).array());
int length = array.limit() - SIZE + 1; int length = array.limit() - SIZE + 1;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; boolean iAligned = array.isDirect() ? ((i + array.alignmentOffset(0, SIZE)) & (SIZE - 1)) == 0 : false;
double v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) double v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
? rotateLeft(VALUE_2, (i % SIZE) << 3) ? rotateLeft(VALUE_2, (i % SIZE) << 3)

View file

@ -72,12 +72,12 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
arrayType = int[].class; arrayType = int[].class;
} }
VarHandleSource aeh = new VarHandleSource( VarHandleSource aeh = new VarHandleSource(
MethodHandles.byteArrayViewVarHandle(arrayType, bo), MethodHandles.byteArrayViewVarHandle(arrayType, bo), false,
endianess, MemoryMode.READ_WRITE); endianess, MemoryMode.READ_WRITE);
vhss.add(aeh); vhss.add(aeh);
VarHandleSource bbh = new VarHandleSource( VarHandleSource bbh = new VarHandleSource(
MethodHandles.byteBufferViewVarHandle(arrayType, bo), MethodHandles.byteBufferViewVarHandle(arrayType, bo), true,
endianess, MemoryMode.READ_WRITE); endianess, MemoryMode.READ_WRITE);
vhss.add(bbh); vhss.add(bbh);
} }
@ -114,38 +114,62 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE)); if (vhs.supportsAtomicAccess) {
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
} else {
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
}
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET)); if (vhs.supportsAtomicAccess) {
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
} else {
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
}
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE));
} }
@Test(dataProvider = "typesProvider") @Test(dataProvider = "typesProvider")
@ -180,9 +204,6 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
cases.add(new VarHandleSourceAccessTestCase( cases.add(new VarHandleSourceAccessTestCase(
"index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h), "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
false)); false));
cases.add(new VarHandleSourceAccessTestCase(
"misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
false));
} }
else { else {
ByteBufferSource bbs = (ByteBufferSource) bav; ByteBufferSource bbs = (ByteBufferSource) bav;
@ -207,9 +228,11 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
cases.add(new VarHandleSourceAccessTestCase( cases.add(new VarHandleSourceAccessTestCase(
"index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h), "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
false)); false));
cases.add(new VarHandleSourceAccessTestCase( if (bbs.s.isDirect()) {
"misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h), cases.add(new VarHandleSourceAccessTestCase(
false)); "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
false));
}
} }
} }
} }
@ -243,76 +266,6 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
checkNPE(() -> { checkNPE(() -> {
vh.set(array, ci, VALUE_1); vh.set(array, ci, VALUE_1);
}); });
checkNPE(() -> {
float x = (float) vh.getVolatile(array, ci);
});
checkNPE(() -> {
float x = (float) vh.getAcquire(array, ci);
});
checkNPE(() -> {
float x = (float) vh.getOpaque(array, ci);
});
checkNPE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkNPE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkNPE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
checkNPE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkNPE(() -> {
float r = (float) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
});
checkNPE(() -> {
float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
});
checkNPE(() -> {
float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
});
checkNPE(() -> {
boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
});
checkNPE(() -> {
boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkNPE(() -> {
boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
});
checkNPE(() -> {
boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
});
checkNPE(() -> {
float o = (float) vh.getAndSet(array, ci, VALUE_1);
});
checkNPE(() -> {
float o = (float) vh.getAndSetAcquire(array, ci, VALUE_1);
});
checkNPE(() -> {
float o = (float) vh.getAndSetRelease(array, ci, VALUE_1);
});
} }
static void testArrayNPE(ByteBufferSource bs, VarHandleSource vhs) { static void testArrayNPE(ByteBufferSource bs, VarHandleSource vhs) {
@ -404,6 +357,49 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
byte[] array = bs.s; byte[] array = bs.s;
int ci = 1; int ci = 1;
checkUOE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkUOE(() -> {
float r = (float) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
});
checkUOE(() -> {
float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
});
checkUOE(() -> {
float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
});
checkUOE(() -> {
boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
});
checkUOE(() -> {
boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkUOE(() -> {
boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
});
checkUOE(() -> {
boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
});
checkUOE(() -> {
float o = (float) vh.getAndSet(array, ci, VALUE_1);
});
checkUOE(() -> {
float o = (float) vh.getAndSetAcquire(array, ci, VALUE_1);
});
checkUOE(() -> {
float o = (float) vh.getAndSetRelease(array, ci, VALUE_1);
});
checkUOE(() -> { checkUOE(() -> {
float o = (float) vh.getAndAdd(array, ci, VALUE_1); float o = (float) vh.getAndAdd(array, ci, VALUE_1);
@ -466,7 +462,7 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
}); });
} }
if (readOnly) { if (readOnly && array.isDirect()) {
checkROBE(() -> { checkROBE(() -> {
vh.setVolatile(array, ci, VALUE_1); vh.setVolatile(array, ci, VALUE_1);
}); });
@ -478,7 +474,6 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
checkROBE(() -> { checkROBE(() -> {
vh.setOpaque(array, ci, VALUE_1); vh.setOpaque(array, ci, VALUE_1);
}); });
checkROBE(() -> { checkROBE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
}); });
@ -524,6 +519,9 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
}); });
}
if (array.isDirect()) {
checkUOE(() -> { checkUOE(() -> {
float o = (float) vh.getAndAdd(array, ci, VALUE_1); float o = (float) vh.getAndAdd(array, ci, VALUE_1);
}); });
@ -535,7 +533,6 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
checkUOE(() -> { checkUOE(() -> {
float o = (float) vh.getAndAddRelease(array, ci, VALUE_1); float o = (float) vh.getAndAddRelease(array, ci, VALUE_1);
}); });
checkUOE(() -> { checkUOE(() -> {
float o = (float) vh.getAndBitwiseOr(array, ci, VALUE_1); float o = (float) vh.getAndBitwiseOr(array, ci, VALUE_1);
}); });
@ -571,8 +568,61 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
checkUOE(() -> { checkUOE(() -> {
float o = (float) vh.getAndBitwiseXorRelease(array, ci, VALUE_1); float o = (float) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
}); });
} } else {
else { checkISE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkISE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkISE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
checkISE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkISE(() -> {
float r = (float) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
});
checkISE(() -> {
float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
});
checkISE(() -> {
float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
});
checkISE(() -> {
boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
});
checkISE(() -> {
boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkISE(() -> {
boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
});
checkISE(() -> {
boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
});
checkISE(() -> {
float o = (float) vh.getAndSet(array, ci, VALUE_1);
});
checkISE(() -> {
float o = (float) vh.getAndSetAcquire(array, ci, VALUE_1);
});
checkISE(() -> {
float o = (float) vh.getAndSetRelease(array, ci, VALUE_1);
});
checkUOE(() -> { checkUOE(() -> {
float o = (float) vh.getAndAdd(array, ci, VALUE_1); float o = (float) vh.getAndAdd(array, ci, VALUE_1);
}); });
@ -638,77 +688,6 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
checkAIOOBE(() -> { checkAIOOBE(() -> {
vh.set(array, ci, VALUE_1); vh.set(array, ci, VALUE_1);
}); });
checkAIOOBE(() -> {
float x = (float) vh.getVolatile(array, ci);
});
checkAIOOBE(() -> {
float x = (float) vh.getAcquire(array, ci);
});
checkAIOOBE(() -> {
float x = (float) vh.getOpaque(array, ci);
});
checkAIOOBE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkAIOOBE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkAIOOBE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
checkAIOOBE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkAIOOBE(() -> {
float r = (float) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
});
checkAIOOBE(() -> {
float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
});
checkAIOOBE(() -> {
float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
});
checkAIOOBE(() -> {
boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
});
checkAIOOBE(() -> {
boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkAIOOBE(() -> {
boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
});
checkAIOOBE(() -> {
boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
});
checkAIOOBE(() -> {
float o = (float) vh.getAndSet(array, ci, VALUE_1);
});
checkAIOOBE(() -> {
float o = (float) vh.getAndSetAcquire(array, ci, VALUE_1);
});
checkAIOOBE(() -> {
float o = (float) vh.getAndSetRelease(array, ci, VALUE_1);
});
} }
} }
@ -732,161 +711,78 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
}); });
} }
checkIOOBE(() -> { if (array.isDirect()) {
float x = (float) vh.getVolatile(array, ci);
});
checkIOOBE(() -> {
float x = (float) vh.getAcquire(array, ci);
});
checkIOOBE(() -> {
float x = (float) vh.getOpaque(array, ci);
});
if (!readOnly) {
checkIOOBE(() -> { checkIOOBE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkIOOBE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkIOOBE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
checkIOOBE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkIOOBE(() -> {
float r = (float) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
});
checkIOOBE(() -> {
float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
});
checkIOOBE(() -> {
float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
});
checkIOOBE(() -> {
boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
});
checkIOOBE(() -> {
boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
});
checkIOOBE(() -> {
boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
});
checkIOOBE(() -> {
boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
});
checkIOOBE(() -> {
float o = (float) vh.getAndSet(array, ci, VALUE_1);
});
checkIOOBE(() -> {
float o = (float) vh.getAndSetAcquire(array, ci, VALUE_1);
});
checkIOOBE(() -> {
float o = (float) vh.getAndSetRelease(array, ci, VALUE_1);
});
}
}
}
static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
VarHandle vh = vhs.s;
byte[] array = bs.s;
int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
int length = array.length - SIZE + 1;
for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
final int ci = i;
if (!iAligned) {
checkISE(() -> {
float x = (float) vh.getVolatile(array, ci); float x = (float) vh.getVolatile(array, ci);
}); });
checkISE(() -> { checkIOOBE(() -> {
float x = (float) vh.getAcquire(array, ci); float x = (float) vh.getAcquire(array, ci);
}); });
checkISE(() -> { checkIOOBE(() -> {
float x = (float) vh.getOpaque(array, ci); float x = (float) vh.getOpaque(array, ci);
}); });
checkISE(() -> { if (!readOnly) {
vh.setVolatile(array, ci, VALUE_1); checkIOOBE(() -> {
}); vh.setVolatile(array, ci, VALUE_1);
});
checkISE(() -> { checkIOOBE(() -> {
vh.setRelease(array, ci, VALUE_1); vh.setRelease(array, ci, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
vh.setOpaque(array, ci, VALUE_1); vh.setOpaque(array, ci, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
}); });
checkISE(() -> { checkIOOBE(() -> {
float r = (float) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1); float r = (float) vh.compareAndExchange(array, ci, VALUE_2, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1); float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1); float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2); boolean r = vh.weakCompareAndSetPlain(array, ci, VALUE_1, VALUE_2);
}); });
checkISE(() -> { checkIOOBE(() -> {
boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2); boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
}); });
checkISE(() -> { checkIOOBE(() -> {
boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2); boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
}); });
checkISE(() -> { checkIOOBE(() -> {
boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2); boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
}); });
checkISE(() -> { checkIOOBE(() -> {
float o = (float) vh.getAndSet(array, ci, VALUE_1); float o = (float) vh.getAndSet(array, ci, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
float o = (float) vh.getAndSetAcquire(array, ci, VALUE_1); float o = (float) vh.getAndSetAcquire(array, ci, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
float o = (float) vh.getAndSetRelease(array, ci, VALUE_1); float o = (float) vh.getAndSetRelease(array, ci, VALUE_1);
}); });
}
} }
} }
} }
@ -928,7 +824,6 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
checkISE(() -> { checkISE(() -> {
vh.setOpaque(array, ci, VALUE_1); vh.setOpaque(array, ci, VALUE_1);
}); });
checkISE(() -> { checkISE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
}); });
@ -972,8 +867,6 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
checkISE(() -> { checkISE(() -> {
float o = (float) vh.getAndSetRelease(array, ci, VALUE_1); float o = (float) vh.getAndSetRelease(array, ci, VALUE_1);
}); });
} }
} }
} }
@ -983,204 +876,15 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
VarHandle vh = vhs.s; VarHandle vh = vhs.s;
byte[] array = bs.s; byte[] array = bs.s;
int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
bs.fill((byte) 0xff); bs.fill((byte) 0xff);
int length = array.length - SIZE + 1; int length = array.length - SIZE + 1;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
// Plain // Plain
{ {
vh.set(array, i, VALUE_1); vh.set(array, i, VALUE_1);
float x = (float) vh.get(array, i); float x = (float) vh.get(array, i);
assertEquals(x, VALUE_1, "get float value"); assertEquals(x, VALUE_1, "get float value");
} }
if (iAligned) {
// Volatile
{
vh.setVolatile(array, i, VALUE_2);
float x = (float) vh.getVolatile(array, i);
assertEquals(x, VALUE_2, "setVolatile float value");
}
// Lazy
{
vh.setRelease(array, i, VALUE_1);
float x = (float) vh.getAcquire(array, i);
assertEquals(x, VALUE_1, "setRelease float value");
}
// Opaque
{
vh.setOpaque(array, i, VALUE_2);
float x = (float) vh.getOpaque(array, i);
assertEquals(x, VALUE_2, "setOpaque float value");
}
vh.set(array, i, VALUE_1);
// Compare
{
boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
assertEquals(r, true, "success compareAndSet float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_2, "success compareAndSet float value");
}
{
boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
assertEquals(r, false, "failing compareAndSet float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_2, "failing compareAndSet float value");
}
{
float r = (float) vh.compareAndExchange(array, i, VALUE_2, VALUE_1);
assertEquals(r, VALUE_2, "success compareAndExchange float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_1, "success compareAndExchange float value");
}
{
float r = (float) vh.compareAndExchange(array, i, VALUE_2, VALUE_3);
assertEquals(r, VALUE_1, "failing compareAndExchange float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_1, "failing compareAndExchange float value");
}
{
float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
assertEquals(r, VALUE_1, "success compareAndExchangeAcquire float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_2, "success compareAndExchangeAcquire float value");
}
{
float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire float value");
}
{
float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
assertEquals(r, VALUE_2, "success compareAndExchangeRelease float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_1, "success compareAndExchangeRelease float value");
}
{
float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
assertEquals(r, VALUE_1, "failing compareAndExchangeRelease float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_1, "failing compareAndExchangeRelease float value");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2);
if (!success) weakDelay();
}
assertEquals(success, true, "success weakCompareAndSetPlain float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_2, "success weakCompareAndSetPlain float value");
}
{
boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3);
assertEquals(success, false, "failing weakCompareAndSetPlain float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain float value");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
if (!success) weakDelay();
}
assertEquals(success, true, "success weakCompareAndSetAcquire float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire float");
}
{
boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3);
assertEquals(success, false, "failing weakCompareAndSetAcquire float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire float value");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
if (!success) weakDelay();
}
assertEquals(success, true, "success weakCompareAndSetRelease float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_2, "success weakCompareAndSetRelease float");
}
{
boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3);
assertEquals(success, false, "failing weakCompareAndSetRelease float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease float value");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1);
if (!success) weakDelay();
}
assertEquals(success, true, "success weakCompareAndSet float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_1, "success weakCompareAndSet float");
}
{
boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3);
assertEquals(success, false, "failing weakCompareAndSet float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_1, "failing weakCompareAndSet float value");
}
// Compare set and get
{
vh.set(array, i, VALUE_1);
float o = (float) vh.getAndSet(array, i, VALUE_2);
assertEquals(o, VALUE_1, "getAndSet float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_2, "getAndSet float value");
}
{
vh.set(array, i, VALUE_1);
float o = (float) vh.getAndSetAcquire(array, i, VALUE_2);
assertEquals(o, VALUE_1, "getAndSetAcquire float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_2, "getAndSetAcquire float value");
}
{
vh.set(array, i, VALUE_1);
float o = (float) vh.getAndSetRelease(array, i, VALUE_2);
assertEquals(o, VALUE_1, "getAndSetRelease float");
float x = (float) vh.get(array, i);
assertEquals(x, VALUE_2, "getAndSetRelease float value");
}
}
} }
} }
@ -1189,12 +893,10 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
VarHandle vh = vhs.s; VarHandle vh = vhs.s;
ByteBuffer array = bs.s; ByteBuffer array = bs.s;
int misalignmentAtZero = array.alignmentOffset(0, SIZE);
bs.fill((byte) 0xff); bs.fill((byte) 0xff);
int length = array.limit() - SIZE + 1; int length = array.limit() - SIZE + 1;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; boolean iAligned = array.isDirect() ? ((i + array.alignmentOffset(0, SIZE)) & (SIZE - 1)) == 0 : false;
// Plain // Plain
{ {
@ -1393,15 +1095,13 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
VarHandle vh = vhs.s; VarHandle vh = vhs.s;
ByteBuffer array = bs.s; ByteBuffer array = bs.s;
int misalignmentAtZero = array.alignmentOffset(0, SIZE);
ByteBuffer bb = ByteBuffer.allocate(SIZE); ByteBuffer bb = ByteBuffer.allocate(SIZE);
bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
bs.fill(bb.putFloat(0, VALUE_2).array()); bs.fill(bb.putFloat(0, VALUE_2).array());
int length = array.limit() - SIZE + 1; int length = array.limit() - SIZE + 1;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; boolean iAligned = array.isDirect() ? ((i + array.alignmentOffset(0, SIZE)) & (SIZE - 1)) == 0 : false;
float v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) float v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
? rotateLeft(VALUE_2, (i % SIZE) << 3) ? rotateLeft(VALUE_2, (i % SIZE) << 3)

View file

@ -72,12 +72,12 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
arrayType = int[].class; arrayType = int[].class;
} }
VarHandleSource aeh = new VarHandleSource( VarHandleSource aeh = new VarHandleSource(
MethodHandles.byteArrayViewVarHandle(arrayType, bo), MethodHandles.byteArrayViewVarHandle(arrayType, bo), false,
endianess, MemoryMode.READ_WRITE); endianess, MemoryMode.READ_WRITE);
vhss.add(aeh); vhss.add(aeh);
VarHandleSource bbh = new VarHandleSource( VarHandleSource bbh = new VarHandleSource(
MethodHandles.byteBufferViewVarHandle(arrayType, bo), MethodHandles.byteBufferViewVarHandle(arrayType, bo), true,
endianess, MemoryMode.READ_WRITE); endianess, MemoryMode.READ_WRITE);
vhss.add(bbh); vhss.add(bbh);
} }
@ -114,38 +114,48 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE)); if (vhs.supportsAtomicAccess) {
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE)); assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
} else {
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE));
}
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE));
assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE));
} }
@Test(dataProvider = "typesProvider") @Test(dataProvider = "typesProvider")
@ -180,9 +190,6 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
cases.add(new VarHandleSourceAccessTestCase( cases.add(new VarHandleSourceAccessTestCase(
"index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h), "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
false)); false));
cases.add(new VarHandleSourceAccessTestCase(
"misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
false));
} }
else { else {
ByteBufferSource bbs = (ByteBufferSource) bav; ByteBufferSource bbs = (ByteBufferSource) bav;
@ -207,9 +214,11 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
cases.add(new VarHandleSourceAccessTestCase( cases.add(new VarHandleSourceAccessTestCase(
"index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h), "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
false)); false));
cases.add(new VarHandleSourceAccessTestCase( if (bbs.s.isDirect()) {
"misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h), cases.add(new VarHandleSourceAccessTestCase(
false)); "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
false));
}
} }
} }
} }
@ -243,33 +252,6 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
checkNPE(() -> { checkNPE(() -> {
vh.set(array, ci, VALUE_1); vh.set(array, ci, VALUE_1);
}); });
checkNPE(() -> {
short x = (short) vh.getVolatile(array, ci);
});
checkNPE(() -> {
short x = (short) vh.getAcquire(array, ci);
});
checkNPE(() -> {
short x = (short) vh.getOpaque(array, ci);
});
checkNPE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkNPE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkNPE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
} }
static void testArrayNPE(ByteBufferSource bs, VarHandleSource vhs) { static void testArrayNPE(ByteBufferSource bs, VarHandleSource vhs) {
@ -423,7 +405,7 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
}); });
} }
if (readOnly) { if (readOnly && array.isDirect()) {
checkROBE(() -> { checkROBE(() -> {
vh.setVolatile(array, ci, VALUE_1); vh.setVolatile(array, ci, VALUE_1);
}); });
@ -435,6 +417,11 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
checkROBE(() -> { checkROBE(() -> {
vh.setOpaque(array, ci, VALUE_1); vh.setOpaque(array, ci, VALUE_1);
}); });
}
if (array.isDirect()) {
checkUOE(() -> { checkUOE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
}); });
@ -478,7 +465,6 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
checkUOE(() -> { checkUOE(() -> {
short o = (short) vh.getAndSetRelease(array, ci, VALUE_1); short o = (short) vh.getAndSetRelease(array, ci, VALUE_1);
}); });
checkUOE(() -> { checkUOE(() -> {
short o = (short) vh.getAndAdd(array, ci, VALUE_1); short o = (short) vh.getAndAdd(array, ci, VALUE_1);
}); });
@ -490,7 +476,6 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
checkUOE(() -> { checkUOE(() -> {
short o = (short) vh.getAndAddRelease(array, ci, VALUE_1); short o = (short) vh.getAndAddRelease(array, ci, VALUE_1);
}); });
checkUOE(() -> { checkUOE(() -> {
short o = (short) vh.getAndBitwiseOr(array, ci, VALUE_1); short o = (short) vh.getAndBitwiseOr(array, ci, VALUE_1);
}); });
@ -526,8 +511,18 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
checkUOE(() -> { checkUOE(() -> {
short o = (short) vh.getAndBitwiseXorRelease(array, ci, VALUE_1); short o = (short) vh.getAndBitwiseXorRelease(array, ci, VALUE_1);
}); });
} } else {
else { checkISE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkISE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkISE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
checkUOE(() -> { checkUOE(() -> {
boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
}); });
@ -636,33 +631,6 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
checkAIOOBE(() -> { checkAIOOBE(() -> {
vh.set(array, ci, VALUE_1); vh.set(array, ci, VALUE_1);
}); });
checkAIOOBE(() -> {
short x = (short) vh.getVolatile(array, ci);
});
checkAIOOBE(() -> {
short x = (short) vh.getAcquire(array, ci);
});
checkAIOOBE(() -> {
short x = (short) vh.getOpaque(array, ci);
});
checkAIOOBE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkAIOOBE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkAIOOBE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
} }
} }
@ -686,74 +654,35 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
}); });
} }
checkIOOBE(() -> { if (array.isDirect()) {
short x = (short) vh.getVolatile(array, ci);
});
checkIOOBE(() -> {
short x = (short) vh.getAcquire(array, ci);
});
checkIOOBE(() -> {
short x = (short) vh.getOpaque(array, ci);
});
if (!readOnly) {
checkIOOBE(() -> { checkIOOBE(() -> {
vh.setVolatile(array, ci, VALUE_1);
});
checkIOOBE(() -> {
vh.setRelease(array, ci, VALUE_1);
});
checkIOOBE(() -> {
vh.setOpaque(array, ci, VALUE_1);
});
}
}
}
static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
VarHandle vh = vhs.s;
byte[] array = bs.s;
int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
int length = array.length - SIZE + 1;
for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
final int ci = i;
if (!iAligned) {
checkISE(() -> {
short x = (short) vh.getVolatile(array, ci); short x = (short) vh.getVolatile(array, ci);
}); });
checkISE(() -> { checkIOOBE(() -> {
short x = (short) vh.getAcquire(array, ci); short x = (short) vh.getAcquire(array, ci);
}); });
checkISE(() -> { checkIOOBE(() -> {
short x = (short) vh.getOpaque(array, ci); short x = (short) vh.getOpaque(array, ci);
}); });
checkISE(() -> { if (!readOnly) {
vh.setVolatile(array, ci, VALUE_1); checkIOOBE(() -> {
}); vh.setVolatile(array, ci, VALUE_1);
});
checkISE(() -> { checkIOOBE(() -> {
vh.setRelease(array, ci, VALUE_1); vh.setRelease(array, ci, VALUE_1);
}); });
checkISE(() -> { checkIOOBE(() -> {
vh.setOpaque(array, ci, VALUE_1); vh.setOpaque(array, ci, VALUE_1);
}); });
}
} }
} }
} }
@ -795,9 +724,6 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
checkISE(() -> { checkISE(() -> {
vh.setOpaque(array, ci, VALUE_1); vh.setOpaque(array, ci, VALUE_1);
}); });
} }
} }
} }
@ -807,45 +733,15 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
VarHandle vh = vhs.s; VarHandle vh = vhs.s;
byte[] array = bs.s; byte[] array = bs.s;
int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
bs.fill((byte) 0xff); bs.fill((byte) 0xff);
int length = array.length - SIZE + 1; int length = array.length - SIZE + 1;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
// Plain // Plain
{ {
vh.set(array, i, VALUE_1); vh.set(array, i, VALUE_1);
short x = (short) vh.get(array, i); short x = (short) vh.get(array, i);
assertEquals(x, VALUE_1, "get short value"); assertEquals(x, VALUE_1, "get short value");
} }
if (iAligned) {
// Volatile
{
vh.setVolatile(array, i, VALUE_2);
short x = (short) vh.getVolatile(array, i);
assertEquals(x, VALUE_2, "setVolatile short value");
}
// Lazy
{
vh.setRelease(array, i, VALUE_1);
short x = (short) vh.getAcquire(array, i);
assertEquals(x, VALUE_1, "setRelease short value");
}
// Opaque
{
vh.setOpaque(array, i, VALUE_2);
short x = (short) vh.getOpaque(array, i);
assertEquals(x, VALUE_2, "setOpaque short value");
}
}
} }
} }
@ -854,12 +750,10 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
VarHandle vh = vhs.s; VarHandle vh = vhs.s;
ByteBuffer array = bs.s; ByteBuffer array = bs.s;
int misalignmentAtZero = array.alignmentOffset(0, SIZE);
bs.fill((byte) 0xff); bs.fill((byte) 0xff);
int length = array.limit() - SIZE + 1; int length = array.limit() - SIZE + 1;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; boolean iAligned = array.isDirect() ? ((i + array.alignmentOffset(0, SIZE)) & (SIZE - 1)) == 0 : false;
// Plain // Plain
{ {
@ -899,15 +793,13 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
VarHandle vh = vhs.s; VarHandle vh = vhs.s;
ByteBuffer array = bs.s; ByteBuffer array = bs.s;
int misalignmentAtZero = array.alignmentOffset(0, SIZE);
ByteBuffer bb = ByteBuffer.allocate(SIZE); ByteBuffer bb = ByteBuffer.allocate(SIZE);
bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
bs.fill(bb.putShort(0, VALUE_2).array()); bs.fill(bb.putShort(0, VALUE_2).array());
int length = array.limit() - SIZE + 1; int length = array.limit() - SIZE + 1;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0; boolean iAligned = array.isDirect() ? ((i + array.alignmentOffset(0, SIZE)) & (SIZE - 1)) == 0 : false;
short v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) short v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
? rotateLeft(VALUE_2, (i % SIZE) << 3) ? rotateLeft(VALUE_2, (i % SIZE) << 3)

View file

@ -384,7 +384,7 @@ public class Basic$Type$
// unit size not a power of two // unit size not a power of two
catchIllegalArgument(b, () -> b.alignmentOffset(0, _us)); catchIllegalArgument(b, () -> b.alignmentOffset(0, _us));
} else { } else {
if (direct || us <= 8) { if (direct || us == 1) {
b.alignmentOffset(0, us); b.alignmentOffset(0, us);
} else { } else {
// unit size > 8 with non-direct buffer // unit size > 8 with non-direct buffer
@ -394,12 +394,11 @@ public class Basic$Type$
} }
} }
// Probe for long misalignment at index zero for a newly created buffer
ByteBuffer empty =
direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0);
int longMisalignmentAtZero = empty.alignmentOffset(0, 8);
if (direct) { if (direct) {
// Probe for long misalignment at index zero for a newly created buffer
ByteBuffer empty = ByteBuffer.allocateDirect(0);
int longMisalignmentAtZero = empty.alignmentOffset(0, 8);
// Freshly created direct byte buffers should be aligned at index 0 // Freshly created direct byte buffers should be aligned at index 0
// for ref and primitive values (see Unsafe.allocateMemory) // for ref and primitive values (see Unsafe.allocateMemory)
if (longMisalignmentAtZero != 0) { if (longMisalignmentAtZero != 0) {
@ -407,78 +406,67 @@ public class Basic$Type$
+ " for ref and primitive values " + " for ref and primitive values "
+ longMisalignmentAtZero); + longMisalignmentAtZero);
} }
} else {
// For heap byte buffers misalignment may occur on 32-bit systems
// where Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 == 4 and not 0
// Note the GC will preserve alignment of the base address of the
// array
if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8
!= longMisalignmentAtZero) {
fail("Heap byte buffer misaligned at index 0"
+ " for ref and primitive values "
+ longMisalignmentAtZero);
}
}
// Ensure test buffer is correctly aligned at index 0 // Ensure test buffer is correctly aligned at index 0
if (b.alignmentOffset(0, 8) != longMisalignmentAtZero) if (b.alignmentOffset(0, 8) != longMisalignmentAtZero)
fail("Test input buffer not correctly aligned at index 0", b); fail("Test input buffer not correctly aligned at index 0", b);
// Test misalignment values // Test misalignment values
for (int us : new int[]{1, 2, 4, 8}) { for (int us : new int[]{1, 2, 4, 8}) {
for (int i = 0; i < us * 2; i++) { for (int i = 0; i < us * 2; i++) {
int am = b.alignmentOffset(i, us); int am = b.alignmentOffset(i, us);
int expectedAm = (longMisalignmentAtZero + i) % us; int expectedAm = (longMisalignmentAtZero + i) % us;
if (am != expectedAm) { if (am != expectedAm) {
String f = "b.alignmentOffset(%d, %d) == %d incorrect, expected %d"; String f = "b.alignmentOffset(%d, %d) == %d incorrect, expected %d";
fail(String.format(f, i, us, am, expectedAm)); fail(String.format(f, i, us, am, expectedAm));
}
} }
} }
}
// Created aligned slice to test against // Created aligned slice to test against
int ap = 8 - longMisalignmentAtZero; int ap = 8 - longMisalignmentAtZero;
int al = b.limit() - b.alignmentOffset(b.limit(), 8); int al = b.limit() - b.alignmentOffset(b.limit(), 8);
ByteBuffer ab = b.position(ap).limit(al). ByteBuffer ab = b.position(ap).limit(al).
slice(); slice();
if (ab.limit() == 0) { if (ab.limit() == 0) {
fail("Test input buffer not sufficiently sized to cover" + fail("Test input buffer not sufficiently sized to cover" +
" an aligned region for all values", b); " an aligned region for all values", b);
} }
if (ab.alignmentOffset(0, 8) != 0) if (ab.alignmentOffset(0, 8) != 0)
fail("Aligned test input buffer not correctly aligned at index 0", ab); fail("Aligned test input buffer not correctly aligned at index 0", ab);
for (int us : new int[]{1, 2, 4, 8}) { for (int us : new int[]{1, 2, 4, 8}) {
for (int p = 1; p < 16; p++) { for (int p = 1; p < 16; p++) {
int l = ab.limit() - p; int l = ab.limit() - p;
ByteBuffer as = ab.slice().position(p).limit(l). ByteBuffer as = ab.slice().position(p).limit(l).
alignedSlice(us); alignedSlice(us);
ck(as, 0, as.position()); ck(as, 0, as.position());
ck(as, as.capacity(), as.limit()); ck(as, as.capacity(), as.limit());
if (b.isDirect() != as.isDirect()) if (b.isDirect() != as.isDirect())
fail("Lost direction", as); fail("Lost direction", as);
if (b.isReadOnly() != as.isReadOnly()) if (b.isReadOnly() != as.isReadOnly())
fail("Lost read-only", as); fail("Lost read-only", as);
if (as.alignmentOffset(0, us) != 0) if (as.alignmentOffset(0, us) != 0)
fail("Buffer not correctly aligned at index 0", as); fail("Buffer not correctly aligned at index 0", as);
if (as.alignmentOffset(as.limit(), us) != 0) if (as.alignmentOffset(as.limit(), us) != 0)
fail("Buffer not correctly aligned at limit", as); fail("Buffer not correctly aligned at limit", as);
int p_mod = ab.alignmentOffset(p, us); int p_mod = ab.alignmentOffset(p, us);
int l_mod = ab.alignmentOffset(l, us); int l_mod = ab.alignmentOffset(l, us);
// Round up position // Round up position
p = (p_mod > 0) ? p + (us - p_mod) : p; p = (p_mod > 0) ? p + (us - p_mod) : p;
// Round down limit // Round down limit
l = l - l_mod; l = l - l_mod;
int ec = l - p; int ec = l - p;
if (as.limit() != ec) { if (as.limit() != ec) {
fail("Buffer capacity incorrect, expected: " + ec, as); fail("Buffer capacity incorrect, expected: " + ec, as);
}
} }
} }
} }

View file

@ -384,7 +384,7 @@ public class BasicByte
// unit size not a power of two // unit size not a power of two
catchIllegalArgument(b, () -> b.alignmentOffset(0, _us)); catchIllegalArgument(b, () -> b.alignmentOffset(0, _us));
} else { } else {
if (direct || us <= 8) { if (direct || us == 1) {
b.alignmentOffset(0, us); b.alignmentOffset(0, us);
} else { } else {
// unit size > 8 with non-direct buffer // unit size > 8 with non-direct buffer
@ -394,12 +394,11 @@ public class BasicByte
} }
} }
// Probe for long misalignment at index zero for a newly created buffer
ByteBuffer empty =
direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0);
int longMisalignmentAtZero = empty.alignmentOffset(0, 8);
if (direct) { if (direct) {
// Probe for long misalignment at index zero for a newly created buffer
ByteBuffer empty = ByteBuffer.allocateDirect(0);
int longMisalignmentAtZero = empty.alignmentOffset(0, 8);
// Freshly created direct byte buffers should be aligned at index 0 // Freshly created direct byte buffers should be aligned at index 0
// for ref and primitive values (see Unsafe.allocateMemory) // for ref and primitive values (see Unsafe.allocateMemory)
if (longMisalignmentAtZero != 0) { if (longMisalignmentAtZero != 0) {
@ -407,78 +406,67 @@ public class BasicByte
+ " for ref and primitive values " + " for ref and primitive values "
+ longMisalignmentAtZero); + longMisalignmentAtZero);
} }
} else {
// For heap byte buffers misalignment may occur on 32-bit systems
// where Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 == 4 and not 0
// Note the GC will preserve alignment of the base address of the
// array
if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8
!= longMisalignmentAtZero) {
fail("Heap byte buffer misaligned at index 0"
+ " for ref and primitive values "
+ longMisalignmentAtZero);
}
}
// Ensure test buffer is correctly aligned at index 0 // Ensure test buffer is correctly aligned at index 0
if (b.alignmentOffset(0, 8) != longMisalignmentAtZero) if (b.alignmentOffset(0, 8) != longMisalignmentAtZero)
fail("Test input buffer not correctly aligned at index 0", b); fail("Test input buffer not correctly aligned at index 0", b);
// Test misalignment values // Test misalignment values
for (int us : new int[]{1, 2, 4, 8}) { for (int us : new int[]{1, 2, 4, 8}) {
for (int i = 0; i < us * 2; i++) { for (int i = 0; i < us * 2; i++) {
int am = b.alignmentOffset(i, us); int am = b.alignmentOffset(i, us);
int expectedAm = (longMisalignmentAtZero + i) % us; int expectedAm = (longMisalignmentAtZero + i) % us;
if (am != expectedAm) { if (am != expectedAm) {
String f = "b.alignmentOffset(%d, %d) == %d incorrect, expected %d"; String f = "b.alignmentOffset(%d, %d) == %d incorrect, expected %d";
fail(String.format(f, i, us, am, expectedAm)); fail(String.format(f, i, us, am, expectedAm));
}
} }
} }
}
// Created aligned slice to test against // Created aligned slice to test against
int ap = 8 - longMisalignmentAtZero; int ap = 8 - longMisalignmentAtZero;
int al = b.limit() - b.alignmentOffset(b.limit(), 8); int al = b.limit() - b.alignmentOffset(b.limit(), 8);
ByteBuffer ab = b.position(ap).limit(al). ByteBuffer ab = b.position(ap).limit(al).
slice(); slice();
if (ab.limit() == 0) { if (ab.limit() == 0) {
fail("Test input buffer not sufficiently sized to cover" + fail("Test input buffer not sufficiently sized to cover" +
" an aligned region for all values", b); " an aligned region for all values", b);
} }
if (ab.alignmentOffset(0, 8) != 0) if (ab.alignmentOffset(0, 8) != 0)
fail("Aligned test input buffer not correctly aligned at index 0", ab); fail("Aligned test input buffer not correctly aligned at index 0", ab);
for (int us : new int[]{1, 2, 4, 8}) { for (int us : new int[]{1, 2, 4, 8}) {
for (int p = 1; p < 16; p++) { for (int p = 1; p < 16; p++) {
int l = ab.limit() - p; int l = ab.limit() - p;
ByteBuffer as = ab.slice().position(p).limit(l). ByteBuffer as = ab.slice().position(p).limit(l).
alignedSlice(us); alignedSlice(us);
ck(as, 0, as.position()); ck(as, 0, as.position());
ck(as, as.capacity(), as.limit()); ck(as, as.capacity(), as.limit());
if (b.isDirect() != as.isDirect()) if (b.isDirect() != as.isDirect())
fail("Lost direction", as); fail("Lost direction", as);
if (b.isReadOnly() != as.isReadOnly()) if (b.isReadOnly() != as.isReadOnly())
fail("Lost read-only", as); fail("Lost read-only", as);
if (as.alignmentOffset(0, us) != 0) if (as.alignmentOffset(0, us) != 0)
fail("Buffer not correctly aligned at index 0", as); fail("Buffer not correctly aligned at index 0", as);
if (as.alignmentOffset(as.limit(), us) != 0) if (as.alignmentOffset(as.limit(), us) != 0)
fail("Buffer not correctly aligned at limit", as); fail("Buffer not correctly aligned at limit", as);
int p_mod = ab.alignmentOffset(p, us); int p_mod = ab.alignmentOffset(p, us);
int l_mod = ab.alignmentOffset(l, us); int l_mod = ab.alignmentOffset(l, us);
// Round up position // Round up position
p = (p_mod > 0) ? p + (us - p_mod) : p; p = (p_mod > 0) ? p + (us - p_mod) : p;
// Round down limit // Round down limit
l = l - l_mod; l = l - l_mod;
int ec = l - p; int ec = l - p;
if (as.limit() != ec) { if (as.limit() != ec) {
fail("Buffer capacity incorrect, expected: " + ec, as); fail("Buffer capacity incorrect, expected: " + ec, as);
}
} }
} }
} }

View file

@ -527,18 +527,6 @@ public class BasicChar

View file

@ -527,18 +527,6 @@ public class BasicDouble

View file

@ -527,18 +527,6 @@ public class BasicFloat

View file

@ -527,18 +527,6 @@ public class BasicInt

View file

@ -527,18 +527,6 @@ public class BasicLong

View file

@ -527,18 +527,6 @@ public class BasicShort