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

Alignment of heap segments is not enforced correctly

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 18
    • core-libs
    • None
    • behavioral
    • minimal
    • The changes described in this CSR might create some incompatibilities when working with aligned layouts and heap segments. However, given all layout constants in ValueLayout are unaligned, we expect the compatibility impact to be rather small.
    • Java API

      Summary

      The Foreign Memory Access API should enforce alignment constraints regardless of the memory segment being accessed, regardless of whether the segment is backed by on-heap or off-heap memory.

      Problem

      Checking alignment constraints of on-heap segments is problematic; unlike off-heap segments, for which a concrete, physical address, can always be obtained (and checked for alignment constraints), the base address of a on-heap segment is virtualized and the alignment constraints of such virtualized address are, ultimately, implementation-dependent. The Foreign Memory Access API performs alignment checks on heap segments by simply looking at the access offset within the heap segment. However, the offset of elements in a heap array can be implementation-dependent, as it is determined by layout decisions which depend on the size of the header of an array instance. This means that it is possible for some dereference/copy operation to fail on certain platforms, but not on others. For instance, trying to read or write aligned long values from a memory segment backed by a byte[] array might work or not, depending on the layout of the byte[] instance.

      For more details please refer to:

      https://mail.openjdk.java.net/pipermail/panama-dev/2021-November/015852.html

      Solution

      The solution is to introduce, for heap segments, an additional "maximum alignment" constraint - that is, the maximum alignment of addresses generated for elements of an array backing a given heap segments. This maximum alignment depends on the element type of the array backing the memory segment: for instance:

      • maxAlign(byte[]) = maxAlign(boolean[]) = 1
      • maxAlign(short[]) = maxAlign(char[]) = 2
      • maxAlign(int[]) = maxAlign(float[]) = 4
      • maxAlign(long[]) = maxAlign(double[]) = 8

      Whereas, for off-heap segments we have that:

      • maxAlign() = 0

      Given this, we can redefine the alignment check for all memory segments as follows:

      void checkAlignment(MemorySegment segment, long address, MemoryLayout layout) {
          if (((address | maxAlign(segment)) % layout.byteAlignment()) != 0) {
              throw new IllegalArgumentException("unaligned access!");
          }
      }

      Note that, when access is off-heap, the above formula degenerates to the one used previously (e.g. (address % layout.byteAlignment) != 0). However, if access is on-heap, the maximum align for the on-heap segment will effectively introduce "noise" in the alignment calculation, so that accessing elements with alignment greater than that of the element type backing the on-heap memory segments will be rejected (regardless of the platform).

      Specification

      Javadoc (as of December 16th, 2021): http://cr.openjdk.java.net/~mcimadamore/8278897/v1/javadoc/jdk/incubator/foreign/package-summary.html

      Specdiff (as of December 16th, 2021): http://cr.openjdk.java.net/~mcimadamore/8278897/v1/specdiff_out/overview-summary.html

      A specdiff of the changes (as of December 16th, 2021) is also attached to this CSR.

            mcimadamore Maurizio Cimadamore
            mcimadamore Maurizio Cimadamore
            Paul Sandoz
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: