Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8318966

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

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 23
    • 22
    • core-libs
    • None

      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, ...")

        There are no Sub-Tasks for this issue.

            jvernee Jorn Vernee
            jvernee Jorn Vernee
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: