8287244: Add bound check in indexed memory access var handle

Reviewed-by: psandoz, jvernee
This commit is contained in:
Maurizio Cimadamore 2022-05-26 08:34:49 +00:00
parent f710393e35
commit f58c9a659b
4 changed files with 87 additions and 22 deletions

View file

@ -369,6 +369,9 @@ public sealed interface MemoryLayout permits AbstractLayout, SequenceLayout, Gro
* arguments, whereas {@code c_1}, {@code c_2}, ... {@code c_m} are <em>static</em> offset constants
* and {@code s_1}, {@code s_2}, ... {@code s_n} are <em>static</em> stride constants which are derived from
* the layout path.
* <p>
* Additionally, the provided dynamic values must conform to some bound which is derived from the layout path, that is,
* {@code 0 <= x_i < b_i}, where {@code 1 <= i <= n}, or {@link IndexOutOfBoundsException} is thrown.
*
* @apiNote the resulting var handle will feature an additional {@code long} access coordinate for every
* unspecified sequence access component contained in this layout path. Moreover, the resulting var handle
@ -515,6 +518,7 @@ public sealed interface MemoryLayout permits AbstractLayout, SequenceLayout, Gro
* Returns a path element which selects the element layout in a <em>range</em> of positions in a sequence layout.
* The range is expressed as a pair of starting index (inclusive) {@code S} and step factor (which can also be negative)
* {@code F}.
* <p>
* If a path with free dimensions {@code n} is combined with the path element returned by this method,
* the number of free dimensions of the resulting path will be {@code 1 + n}. If the free dimension associated
* with this path is bound by an index {@code I}, the resulting accessed offset can be obtained with the following
@ -525,6 +529,14 @@ public sealed interface MemoryLayout permits AbstractLayout, SequenceLayout, Gro
* }</pre></blockquote>
*
* where {@code E} is the size (in bytes) of the sequence element layout.
* <p>
* Additionally, if {@code C} is the sequence element count, it follows that {@code 0 <= I < B},
* where {@code B} is computed as follows:
*
* <ul>
* <li>if {@code F > 0}, then {@code B = ceilDiv(C - S, F)}</li>
* <li>if {@code F < 0}, then {@code B = ceilDiv(-(S + 1), -F)}</li>
* </ul>
*
* @param start the index of the first sequence element to be selected.
* @param step the step factor at which subsequence sequence elements are to be selected.
@ -544,8 +556,19 @@ public sealed interface MemoryLayout permits AbstractLayout, SequenceLayout, Gro
/**
* Returns a path element which selects an unspecified element layout in a sequence layout.
* <p>
* If a path with free dimensions {@code n} is combined with the path element returned by this method,
* the number of free dimensions of the resulting path will be {@code 1 + n}.
* the number of free dimensions of the resulting path will be {@code 1 + n}. If the free dimension associated
* with this path is bound by an index {@code I}, the resulting accessed offset can be obtained with the following
* formula:
*
* <blockquote><pre>{@code
* E * I
* }</pre></blockquote>
*
* where {@code E} is the size (in bytes) of the sequence element layout.
* <p>
* Additionally, if {@code C} is the sequence element count, it follows that {@code 0 <= I < C}.
*
* @return a path element which selects an unspecified sequence element layout.
*/

View file

@ -137,7 +137,7 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout {
* Can be used to access a multi-dimensional array whose layout is as follows:
*
* {@snippet lang=java :
* MemoryLayout arrayLayout = MemoryLayout.sequenceLayout(-1,
* SequenceLayout arrayLayout = MemoryLayout.sequenceLayout(-1,
* MemoryLayout.sequenceLayout(10,
* MemoryLayout.sequenceLayout(20, ValueLayout.JAVA_INT)));
* }
@ -151,6 +151,22 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout {
* offset = (10 * 20 * 4 * x) + (20 * 4 * y) + (4 * z)
* }</pre></blockquote>
*
* Additionally, the values of {@code x}, {@code y} and {@code z} are constrained as follows:
* <ul>
* <li>{@code 0 <= x < arrayLayout.elementCount() }</li>
* <li>{@code 0 <= y < 10 }</li>
* <li>{@code 0 <= z < 20 }</li>
* </ul>
* <p>
* Consider the following access expressions:
* {@snippet lang=java :
* int value1 = arrayHandle.get(10, 2, 4); // ok, accessed offset = 8176
* int value2 = arrayHandle.get(0, 0, 30); // out of bounds value for z
* }
* In the first case, access is well-formed, as the values for {@code x}, {@code y} and {@code z} conform to
* the bounds specified above. In the second case, access fails with {@link IndexOutOfBoundsException},
* as the value for {@code z} is outside its specified bounds.
*
* @param shape the size of each nested array dimension.
* @return a var handle which can be used to dereference a multi-dimensional array, featuring {@code shape.length + 1}
* {@code long} coordinates.