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[]` is (indirectly) accessed through another primitive type like `int` or `long` (a so-called 'mismatched access'). Given the minimal alignment guarantees of `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 an `UnsupportedOperationException` 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 a `byte[]`), for the same reasons as `byteArrayViewVarHandle`. 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 an `IllegalStateException` 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 outright `UnsupportedOperationException` for this case, since whether the access modes are supported depends on the byte buffer instance being used.
- `ByteBuffer::alignedSlice` and `ByteBuffer::alignmentOffset`: The former method depends directly on the latter for all its alignment computations. We change the implementation of the latter method to throw an `UnsupportedOperationException` 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