RFR: 8287244: Add bound check in indexed memory access var handle [v2]

Maurizio Cimadamore mcimadamore at openjdk.java.net
Tue May 24 17:58:04 UTC 2022


On Tue, 24 May 2022 17:43:52 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

>> src/java.base/share/classes/java/lang/foreign/MemoryLayout.java line 374:
>> 
>>> 372:      *
>>> 373:      * Additionally, the provided dynamic values must conform to some bound which is derived from the layout path, that is,
>>> 374:      * {@code 0 <= x_i <= b_i}, where {@code 0 <= i <= n}, or {@link IndexOutOfBoundsException} is thrown.
>> 
>> Suggestion:
>> 
>>      * {@code 0 <= x_i < b_i}, where {@code 1 <= i <= n}, or {@link IndexOutOfBoundsException} is thrown.
>> 
>> We refer later to `B` being an exclusive upper bound (computed using `ceilDiv`).
>
> Indices start at zero. The ceilDiv operation is needed so that the operation returns the first index outisde the range (it's a bit subtle, sorry, but I don't know how else to express).

Here's a concrete example:

Consider a sequence layout with 6 elements. Then:

element count = 6
valid indices 0, 1, 2, 3, 4, 5

Now consider a var handle that is obtained by calling the path element method, passing the following parameters

start = 1
step = 2

This sets up the following mapping between logical an physical indices:

0 -> 1
1 -> 3
2 -> 5

Where on the LHS we have the logical index (the one passed to the VH) and on the RHS we have the actual index it is translated to.

Note that the index map has three elements. So the upper bound (exclusive) of the index map is 3 - that is, we can pass indices 0, 1, 2.

According to the formula shown in the javadoc:

B = ceilDiv((elementCount - start) / step);

so:

B = ceilDiv((6 - 1) / 2)
    = ceilDiv(5 / 2)

Note how, w/o ceilDiv we'd get 2 (the last valid index), and not 3 (the first invalid index).

-------------

PR: https://git.openjdk.java.net/jdk/pull/8868


More information about the core-libs-dev mailing list