-
CSR
-
Resolution: Approved
-
P3
-
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 aSegmentAllocator::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
- csr of
-
JDK-8321786 SegmentAllocator:allocateFrom(ValueLayout, MemorySegment,ValueLayout,long,long) spec mismatch in exception scenario
-
- Resolved
-