JDK-8318966 : Some methods make promises about Java array element alignment that are too strong
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Affected Version: 22
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2023-10-27
  • Updated: 2024-02-21
  • Resolved: 2024-02-14
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 23
23 b10Fixed
Related Reports
CSR :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Sub Tasks
JDK-8325879 :  
Description
The following methods:

- MethodHandles::byteArrayViewVarHandle
- MethodHandles::byteBufferViewVarHandle
- ByteBuffer::alignedSlice
- ByteBuffer::alignmentOffset

Make too many promises about the alignment of underlying heap memory (the elements of an underlying byte[]). A JVM implementation at most guarantees that the elements of a Java array are aligned to their natural alignment. e.g for byte[] that is the size of a 'byte', which is 1 byte. While some VM implementations choose to align array elements at an 8-byte boundary, this is by no means mandated by the JVM spec. However, the specification of the mentioned methods guarantees that accesses will be aligned for certain offsets when accessing heap memory (Java arrays). It is possible for there to exist valid JVM implementations on which these methods will not work (and can never work reliably) according to their specification.

The underlying issue is that the array elements of a byte[] can at most be assumed to be be 1-byte aligned (no alignment, really). That means the start of the array elements can be located at any memory address. The base address of the array elements can also change due to a garbage collector moving the array object around (i.e. the base address is unstable). Therefore, at whichever offset we access this array, the physical memory location of the access can also be located at 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).

- MethodHandles::byteArrayViewVarHandle returns a var handle that allows accessing a byte[] using a larger primitive type, such as int or long. These accesses are never guaranteed to be aligned, since the alignment requirement of the larger primitive types is always larger than the guaranteed alignment of the elements of the byte array. However, the method specification promises that accesses at certain offsets will be aligned (which is incorrect).
- MethodHandles::byteBufferViewVarHandle accesses can only be guaranteed to be aligned when the byte buffer is direct (i.e. off-heap). Since in that case the underlying memory address is stable, we can compute the offsets at which the accesses will be aligned with certainty. However, for heap byte buffers, we run into the problem described above.
- ByteBuffer::alignedSlice depends directly on ByteBuffer::alignmentOffset, and the latter purports to be able to guarantee alignment when accessing heap memory. This is again not possible due to the problem described above, so there is no guarantee that an actual access at the returned slice/offset will be aligned.

See also prior discussion relating to the FFM API: https://mail.openjdk.org/pipermail/panama-dev/2021-November/015852.html
And the existing FFM API javadoc: https://download.java.net/java/early_access/jdk22/docs/api/java.base/java/lang/foreign/MemorySegment.html#segment-alignment (see section starting with "If the segment being accessed is a heap segment, ...")
Comments
Changeset: 9c852df6 Author: Jorn Vernee <jvernee@openjdk.org> Date: 2024-02-14 14:30:54 +0000 URL: https://git.openjdk.org/jdk/commit/9c852df6aa019f63d6fae733d7a73521b7151dd0
14-02-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/16681 Date: 2023-11-15 22:46:03 +0000
16-11-2023