8338728: Misc issues in memory layout javadoc

Reviewed-by: pminborg, psandoz
This commit is contained in:
Maurizio Cimadamore 2024-08-27 14:26:31 +00:00
parent 414d23cb8f
commit b25095b08e
2 changed files with 32 additions and 7 deletions
src/java.base/share/classes/java/lang/foreign
test/jdk/java/foreign

@ -664,14 +664,15 @@ public sealed interface MemoryLayout
* <p>
* If the provided layout path has size {@code m} and contains a dereference path
* element in position {@code k} (where {@code k <= m}) then two layout paths
* {@code P} and {@code P'} are derived, where P contains all the path elements from
* 0 to {@code k - 1} and {@code P'} contains all the path elements from {@code k + 1}
* to {@code m} (if any). Then, the returned var handle is computed as follows:
* {@code P} and {@code Q} are derived, where P contains all the path elements from
* 0 to {@code k - 1} and {@code Q} contains all the path elements from {@code k + 1}
* to {@code m} ({@code Q} could be an empty layout path if {@code k == m}).
* Then, the returned var handle is computed as follows:
*
* {@snippet lang = "java":
* VarHandle baseHandle = this.varHandle(P);
* MemoryLayout target = ((AddressLayout)this.select(P)).targetLayout().get();
* VarHandle targetHandle = target.varHandle(P);
* VarHandle targetHandle = target.varHandle(Q);
* targetHandle = MethodHandles.insertCoordinates(targetHandle, 1, 0L); // always access nested targets at offset 0
* targetHandle = MethodHandles.collectCoordinates(targetHandle, 0,
* baseHandle.toMethodHandle(VarHandle.AccessMode.GET));
@ -944,7 +945,7 @@ public sealed interface MemoryLayout
* 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>
* <li>if {@code F < 0}, then {@code B = ceilDiv(S + 1, -F)}</li>
* </ul>
* That is, the size of the returned open path element is {@code B}.
*
@ -972,8 +973,8 @@ public sealed interface MemoryLayout
}
/**
* {@return a path element that dereferences an address layout as its
* {@linkplain AddressLayout#targetLayout() target layout} (where set)}
* {@return a path element that selects the {@linkplain AddressLayout#targetLayout() target layout} of
* an address layout (where set)}
*/
static PathElement dereferenceElement() {
return LayoutPath.DereferenceElement.instance();

@ -119,6 +119,30 @@ public class TestDereferencePath {
}
}
static final MemoryLayout A_VALUE = MemoryLayout.structLayout(
ValueLayout.ADDRESS.withName("b")
.withTargetLayout(ValueLayout.JAVA_INT)
);
static final VarHandle a_value = A_VALUE.varHandle(
PathElement.groupElement("b"), PathElement.dereferenceElement());
@Test
public void testDerefValue() {
try (Arena arena = Arena.ofConfined()) {
// init structs
MemorySegment a = arena.allocate(A);
MemorySegment b = arena.allocate(ValueLayout.JAVA_INT);
// init struct fields
a.set(ValueLayout.ADDRESS, 0, b);
b.set(ValueLayout.JAVA_INT, 0, 42);
// dereference
int val = (int) a_value.get(a, 0L);
assertEquals(val, 42);
}
}
@Test(expectedExceptions = IllegalArgumentException.class)
void testBadDerefInSelect() {
A.select(PathElement.groupElement("b"), PathElement.dereferenceElement());