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

SegmentAllocator:allocateFrom(ValueLayout, MemorySegment,ValueLayout,long,long) spec mismatch in exception scenario

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 22, 23
    • core-libs
    • None
    • behavioral
    • minimal
    • It is unlikely user code catch runtime exceptions like this. That said, there might be a handful such odd cases. In many cases, no change is required as specification has been tweaked to adhere to the currently implemented behavior.
    • Java API
    • SE

      Summary

      Change, harmonize and/or specify the Exception type thrown by certain FFM methods in MemorySegment and SegmentAllocator if invariants were violated.

      Problem

      There were inconsistencies in the Exception types being specified:

      • The SegmentAllocator::allocateFrom is defined as a SegmentAllocator::allocate(layout, size) + MemorySegment::copy, the exceptions thrown should reflect the ones thrown by these two methods, in order (to simplify code refactoring).
      • All the memory segment accessors miss a throws IIOBE for when offset/index < 0

      Solution

      The specifications were amended and a small number of implementation changes were made to reflect these changes.

      Specification

      SegmentAllocator (this is the main change proposed for this CSR)

      diff --git a/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java b/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java
      index 6be9d949ea65..6c9cf51bee8b 100644
      --- a/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java
      +++ b/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java
      @@ -33,6 +33,7 @@
       import jdk.internal.foreign.ArenaImpl;
       import jdk.internal.foreign.SlicingAllocator;
       import jdk.internal.foreign.StringSupport;
      +import jdk.internal.foreign.Utils;
       import jdk.internal.vm.annotation.ForceInline;
      
       /**
      @@ -390,9 +391,10 @@ default MemorySegment allocateFrom(AddressLayout layout, MemorySegment value) {
            *         with {@code source} is not {@linkplain MemorySegment.Scope#isAlive() alive}
            * @throws WrongThreadException if this method is called from a thread {@code T},
            *         such that {@code source.isAccessibleBy(T) == false}
      -     * @throws IndexOutOfBoundsException if {@code elementCount * sourceElementLayout.byteSize()} overflows
      +     * @throws IllegalArgumentException if {@code elementCount * sourceElementLayout.byteSize()} overflows
      +     * @throws IllegalArgumentException if {@code elementCount < 0}
            * @throws IndexOutOfBoundsException if {@code sourceOffset > source.byteSize() - (elementCount * sourceElementLayout.byteSize())}
      -     * @throws IndexOutOfBoundsException if either {@code sourceOffset} or {@code elementCount} are {@code < 0}
      +     * @throws IndexOutOfBoundsException if {@code sourceOffset < 0}
            */
           @ForceInline
           default MemorySegment allocateFrom(ValueLayout elementLayout,

      MemorySegment (these changes are just fixing simple omissions in the existing API javadoc for segment getters/setters):

      diff --git a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java
      index da255b9912b2..01477cfc7359 100644
      --- a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java
      +++ b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java
      @@ -44,6 +44,7 @@
       import jdk.internal.foreign.AbstractMemorySegmentImpl;
       import jdk.internal.foreign.MemorySessionImpl;
       import jdk.internal.foreign.SegmentFactories;
      +import jdk.internal.foreign.Utils;
       import jdk.internal.javac.Restricted;
       import jdk.internal.reflect.CallerSensitive;
       import jdk.internal.vm.annotation.ForceInline;
      @@ -1591,6 +1592,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            */
           byte get(ValueLayout.OfByte layout, long offset);
      
      @@ -1609,6 +1611,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            * @throws IllegalArgumentException if this segment is
            *         {@linkplain #isReadOnly() read-only}
            */
      @@ -1629,6 +1632,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            */
           boolean get(ValueLayout.OfBoolean layout, long offset);
      
      @@ -1647,6 +1651,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            * @throws IllegalArgumentException if this segment is
            *         {@linkplain #isReadOnly() read-only}
            */
      @@ -1667,6 +1672,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            */
           char get(ValueLayout.OfChar layout, long offset);
      
      @@ -1685,6 +1691,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            * @throws IllegalArgumentException if this segment is
            *         {@linkplain #isReadOnly() read-only}
            */
      @@ -1705,6 +1712,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            */
           short get(ValueLayout.OfShort layout, long offset);
      
      @@ -1723,6 +1731,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            * @throws IllegalArgumentException if this segment is
            *         {@linkplain #isReadOnly() read-only}
            */
      @@ -1743,6 +1752,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            */
           int get(ValueLayout.OfInt layout, long offset);
      
      @@ -1761,6 +1771,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            * @throws IllegalArgumentException if this segment is
            *         {@linkplain #isReadOnly() read-only}
            */
      @@ -1781,6 +1792,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            */
           float get(ValueLayout.OfFloat layout, long offset);
      
      @@ -1799,6 +1811,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            * @throws IllegalArgumentException if this segment is
            *         {@linkplain #isReadOnly() read-only}
            */
      @@ -1819,6 +1832,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            */
           long get(ValueLayout.OfLong layout, long offset);
      
      @@ -1837,6 +1851,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            * @throws IllegalArgumentException if this segment is
            *         {@linkplain #isReadOnly() read-only}
            */
      @@ -1857,6 +1872,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            */
           double get(ValueLayout.OfDouble layout, long offset);
      
      @@ -1875,6 +1891,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            * @throws IllegalArgumentException if this segment is
            *         {@linkplain #isReadOnly() read-only}
            */
      @@ -1905,6 +1922,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in {@code T}
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            */
           MemorySegment get(AddressLayout layout, long offset);
      
      @@ -1923,6 +1941,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a>
            *         in the provided layout
            * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}
      +     *         or {@code offset < 0}
            * @throws UnsupportedOperationException if this segment is
            *         {@linkplain #isReadOnly() read-only}
            * @throws IllegalArgumentException if {@code value} is not a
      @@ -1951,6 +1970,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            */
           byte getAtIndex(ValueLayout.OfByte layout, long index);
      
      @@ -1973,6 +1993,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            */
           boolean getAtIndex(ValueLayout.OfBoolean layout, long index);
      
      @@ -1995,6 +2016,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            */
           char getAtIndex(ValueLayout.OfChar layout, long index);
      
      @@ -2017,6 +2039,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}
            */
           void setAtIndex(ValueLayout.OfChar layout, long index, char value);
      @@ -2040,6 +2063,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            */
           short getAtIndex(ValueLayout.OfShort layout, long index);
      
      @@ -2061,6 +2085,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            * @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
            */
           void setAtIndex(ValueLayout.OfByte layout, long index, byte value);
      @@ -2084,6 +2109,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            * @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
            */
           void setAtIndex(ValueLayout.OfBoolean layout, long index, boolean value);
      @@ -2107,6 +2133,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            * @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
            */
           void setAtIndex(ValueLayout.OfShort layout, long index, short value);
      @@ -2130,6 +2157,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            */
           int getAtIndex(ValueLayout.OfInt layout, long index);
      
      @@ -2152,6 +2180,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            * @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
            */
           void setAtIndex(ValueLayout.OfInt layout, long index, int value);
      @@ -2175,6 +2204,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            */
           float getAtIndex(ValueLayout.OfFloat layout, long index);
      
      @@ -2197,6 +2227,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            * @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
            */
           void setAtIndex(ValueLayout.OfFloat layout, long index, float value);
      @@ -2220,6 +2251,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            */
           long getAtIndex(ValueLayout.OfLong layout, long index);
      
      @@ -2242,6 +2274,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            * @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
            */
           void setAtIndex(ValueLayout.OfLong layout, long index, long value);
      @@ -2265,6 +2298,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            */
           double getAtIndex(ValueLayout.OfDouble layout, long index);
      
      @@ -2287,6 +2321,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            * @throws IllegalArgumentException if this segment is {@linkplain #isReadOnly() read-only}
            */
           void setAtIndex(ValueLayout.OfDouble layout, long index, double value);
      @@ -2319,6 +2354,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            *         in {@code T}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            */
           MemorySegment getAtIndex(AddressLayout layout, long index);
      
      @@ -2341,6 +2377,7 @@ static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long sr
            * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize()} overflows
            * @throws IndexOutOfBoundsException if {@code index * layout.byteSize() > byteSize() - layout.byteSize()}
      +     *         or {@code index < 0}
            * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}
            * @throws IllegalArgumentException if {@code value} is not a {@linkplain #isNative() native} segment
            * @throws IllegalArgumentException if this segment is
      

            pminborg Per-Ake Minborg
            kganapureddy Krushnareddy Ganapureddy
            Maurizio Cimadamore
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: