Summary
Change the specification and implementation of MethodHandles::byteArrayViewVarHandle
, MethodHandles::byteBufferViewVarHandle
, ByteBuffer::alignedSlice
, and ByteBuffer::alignmentOffset
to weaken the guarantees they make about the alignment of Java array elements, in order to bring them in line with the guarantees made by an arbitrary JVM implementation.
Problem
The JVM spec makes no guarantees about the alignment of Java array elements. At most we can assume that the elements are naturally aligned (i.e. aligned according to their size). The named methods are affected by the alignment guarantees for the elements of a byte[]
which are 1-byte aligned (i.e. not aligned, really). The issue with the named methods is that they guarantee alignment when a byte[]</code> is (indirectly) accessed through another primitive type like <code class="prettyprint" >int</code> or <code class="prettyprint" >long</code> (a so-called 'mismatched access'). Given the minimal alignment guarantees of <code class="prettyprint" >byte[]
elements, making any such guarantees about the alignment of accesses is incorrect, as they might not hold on all JVM implementations.
The fact that byte[]
elements can at most be assumed to be 1-byte aligned, means the start of the array elements can be located at any memory address. This memory address can also change due to a garbage collector moving the array object around (i.e. the address is unstable). Therefore, at whichever offset we access this array, the memory address of the access can also be any memory address, and is also unstable. We can not make any guarantees about the alignment of an arbitrary, unstable memory address. Therefore, we can not make any guarantees that accesses at certain offsets will be aligned (or not).
Solution
The proposed solution is to relax the guarantees made by the named methods, so that these methods behave consistently on all valid implementations of the JVM.
MethodHandles::byteArrayViewVarHandle
: we can not guarantee any alignment for the accesses. Which means we can only reliably support plain get and set access modes. The javadoc text explaining which other access modes are supported, or how to compute aligned offsets into the array is dropped, as it is not guaranteed to be correct on all JVM implementations. The implementation of the returned VarHandle is changed to throw anUnsupportedOperationException
for the unsupported access modes, as mandated by the spec of VarHandle (https://github.com/openjdk/jdk/blob/ffa35d8cf181cfbcb54497e997dbd18a9b62b97e/src/java.base/share/classes/java/lang/invoke/VarHandle.java#L189-L191).MethodHandles::byteBufferViewVarHandle
: the implementation/spec is incorrect when accessing a heap buffer (wrapping abyte[]
), for the same reasons asbyteArrayViewVarHandle
. The spec is changed to specify that when accessing a heap buffer, only plain get and set access modes are supported. The implementation of the returned var handle is changed to throw anIllegalStateException
when an access is attempted on a heap buffer using an access mode other than plain get or set. Note that we don't throw an outrightUnsupportedOperationException
for this case, since whether the access modes are supported depends on the byte buffer instance being used.ByteBuffer::alignedSlice
andByteBuffer::alignmentOffset
: The former method depends directly on the latter for all its alignment computations. We change the implementation of the latter method to throw anUnsupportedOperationException
for all unit sizes greater than 1, when the buffer is non-direct.
These decisions are also informed by similar conclusions reached in the design of the FFM API. See the existing FFM javadoc on alignment: https://download.java.net/java/early_access/jdk22/docs/api/java.base/java/lang/foreign/MemorySegment.html#segment-alignment (in particular, see the section starting with "If the segment being accessed is a heap segment, ...")
Specification
Specdiff: https://cr.openjdk.org/~jvernee/alignedOffset_specdiff/v3/overview-summary.html
- csr of
-
JDK-8318966 Some methods make promises about Java array element alignment that are too strong
- Resolved