Skip to content
Permalink
Browse files
8278433: Use snippets in jdk.incubator.foreign documentation
Reviewed-by: mcimadamore
  • Loading branch information
FrauBoes committed Dec 9, 2021
1 parent 1ea766d commit 84baea753a01428d9dc5befa5f23d4ac853a7bbc
Showing 10 changed files with 289 additions and 290 deletions.
@@ -181,9 +181,9 @@ default Optional<NativeSymbol> lookup(String name) {
* to allocate structs returned by-value.
* <p>
* Calling this method is equivalent to the following code:
<blockquote><pre>{@code
linker.downcallHandle(function).bindTo(symbol);
}</pre></blockquote>
* {@snippet lang=java :
* linker.downcallHandle(function).bindTo(symbol);
* }
*
* @param symbol downcall symbol.
* @param function the function descriptor.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,17 +46,17 @@
* Each dereference method takes a {@linkplain jdk.incubator.foreign.ValueLayout value layout}, which specifies the size,
* alignment constraints, byte order as well as the Java type associated with the dereference operation, and an offset.
* For instance, to read an int from a segment, using {@link ByteOrder#nativeOrder() default endianness}, the following code can be used:
* <blockquote><pre>{@code
MemoryAddress address = ...
int value = address.get(ValueLayout.JAVA_INT, 0);
* }</pre></blockquote>
* {@snippet lang=java :
* MemoryAddress address = ...
* int value = address.get(ValueLayout.JAVA_INT, 0);
* }
*
* If the value to be read is stored in memory using {@link ByteOrder#BIG_ENDIAN big-endian} encoding, the dereference operation
* can be expressed as follows:
* <blockquote><pre>{@code
MemoryAddress address = ...
int value = address.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0);
* }</pre></blockquote>
* {@snippet lang=java :
* MemoryAddress address = ...
* int value = address.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0);
* }
*
* All the dereference methods in this class are <a href="package-summary.html#restricted"><em>restricted</em></a>: since
* a memory address does not feature temporal nor spatial bounds, the runtime has no way to check the correctness
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -47,17 +47,17 @@
* to the segment, at which dereference should occur.
* <p>
* As an example, consider the memory layout expressed by a {@link GroupLayout} instance constructed as follows:
* <blockquote><pre>{@code
GroupLayout seq = MemoryLayout.structLayout(
MemoryLayout.paddingLayout(32),
ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN).withName("value")
);
* }</pre></blockquote>
* {@snippet lang=java :
* GroupLayout seq = MemoryLayout.structLayout(
* MemoryLayout.paddingLayout(32),
* ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN).withName("value")
* );
* }
* To access the member layout named {@code value}, we can construct a memory access var handle as follows:
* <blockquote><pre>{@code
VarHandle handle = MemoryHandles.varHandle(ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); //(MemorySegment, long) -> int
handle = MemoryHandles.insertCoordinates(handle, 1, 4); //(MemorySegment) -> int
* }</pre></blockquote>
* {@snippet lang=java :
* VarHandle handle = MemoryHandles.varHandle(ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); //(MemorySegment, long) -> int
* handle = MemoryHandles.insertCoordinates(handle, 1, 4); //(MemorySegment) -> int
* }
*
* <p> Unless otherwise specified, passing a {@code null} argument, or an array argument containing one or more {@code null}
* elements to a method in this class causes a {@link NullPointerException NullPointerException} to be thrown. </p>
@@ -177,13 +177,13 @@ public static VarHandle varHandle(ValueLayout layout) {
* example, it is often convenient to model an <i>unsigned short</i> as a
* Java {@code int} to avoid dealing with negative values, which would be
* the case if modeled as a Java {@code short}. This is illustrated in the following example:
* <blockquote><pre>{@code
MemorySegment segment = MemorySegment.allocateNative(2, ResourceScope.newImplicitScope());
VarHandle SHORT_VH = ValueLayout.JAVA_SHORT.varHandle();
VarHandle INT_VH = MemoryHandles.asUnsigned(SHORT_VH, int.class);
SHORT_VH.set(segment, (short)-1);
INT_VH.get(segment); // returns 65535
* }</pre></blockquote>
* {@snippet lang=java :
* MemorySegment segment = MemorySegment.allocateNative(2, ResourceScope.newImplicitScope());
* VarHandle SHORT_VH = ValueLayout.JAVA_SHORT.varHandle();
* VarHandle INT_VH = MemoryHandles.asUnsigned(SHORT_VH, int.class);
* SHORT_VH.set(segment, (short)-1);
* INT_VH.get(segment); // returns 65535
* }
* <p>
* When calling e.g. {@link VarHandle#set(Object...)} on the resulting var
* handle, the incoming value (of type {@code adaptedType}) is converted by a
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,24 +58,24 @@
* <p>
* For instance, consider the following struct declaration in C:
*
* <blockquote><pre>{@code
typedef struct {
char kind;
int value;
} TaggedValues[5];
* }</pre></blockquote>
* {@snippet lang=c :
* typedef struct {
* char kind;
* int value;
* } TaggedValues[5];
* }
*
* The above declaration can be modelled using a layout object, as follows:
*
* <blockquote><pre>{@code
SequenceLayout taggedValues = MemoryLayout.sequenceLayout(5,
MemoryLayout.structLayout(
ValueLayout.JAVA_BYTE.withName("kind"),
MemoryLayout.paddingLayout(24),
ValueLayout.JAVA_INT.withName("value")
)
).withName("TaggedValues");
* }</pre></blockquote>
* {@snippet lang=java :
* SequenceLayout taggedValues = MemoryLayout.sequenceLayout(5,
* MemoryLayout.structLayout(
* ValueLayout.JAVA_BYTE.withName("kind"),
* MemoryLayout.paddingLayout(24),
* ValueLayout.JAVA_INT.withName("value")
* )
* ).withName("TaggedValues");
* }
* <p>
* All implementations of this interface must be <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>;
* programmers should treat instances that are {@linkplain #equals(Object) equal} as interchangeable and should not
@@ -129,42 +129,42 @@
* Such <em>layout paths</em> can be constructed programmatically using the methods in this class.
* For instance, given the {@code taggedValues} layout instance constructed as above, we can obtain the offset,
* in bits, of the member layout named <code>value</code> in the <em>first</em> sequence element, as follows:
* <blockquote><pre>{@code
long valueOffset = taggedValues.bitOffset(PathElement.sequenceElement(0),
PathElement.groupElement("value")); // yields 32
* }</pre></blockquote>
* {@snippet lang=java :
* long valueOffset = taggedValues.bitOffset(PathElement.sequenceElement(0),
* PathElement.groupElement("value")); // yields 32
* }
*
* Similarly, we can select the member layout named {@code value}, as follows:
* <blockquote><pre>{@code
MemoryLayout value = taggedValues.select(PathElement.sequenceElement(),
PathElement.groupElement("value"));
* }</pre></blockquote>
* {@snippet lang=java :
* MemoryLayout value = taggedValues.select(PathElement.sequenceElement(),
* PathElement.groupElement("value"));
* }
*
* And, we can also replace the layout named {@code value} with another layout, as follows:
* <blockquote><pre>{@code
MemoryLayout taggedValuesWithHole = taggedValues.map(l -> MemoryLayout.paddingLayout(32),
PathElement.sequenceElement(), PathElement.groupElement("value"));
* }</pre></blockquote>
* {@snippet lang=java :
* MemoryLayout taggedValuesWithHole = taggedValues.map(l -> MemoryLayout.paddingLayout(32),
* PathElement.sequenceElement(), PathElement.groupElement("value"));
* }
*
* That is, the above declaration is identical to the following, more verbose one:
* <blockquote><pre>{@code
MemoryLayout taggedValuesWithHole = MemoryLayout.sequenceLayout(5,
MemoryLayout.structLayout(
ValueLayout.JAVA_BYTE.withName("kind"),
MemoryLayout.paddingLayout(32),
MemoryLayout.paddingLayout(32)
));
* }</pre></blockquote>
* {@snippet lang=java :
* MemoryLayout taggedValuesWithHole = MemoryLayout.sequenceLayout(5,
* MemoryLayout.structLayout(
* ValueLayout.JAVA_BYTE.withName("kind"),
* MemoryLayout.paddingLayout(32),
* MemoryLayout.paddingLayout(32)
* ));
* }
*
* Layout paths can feature one or more <em>free dimensions</em>. For instance, a layout path traversing
* an unspecified sequence element (that is, where one of the path component was obtained with the
* {@link PathElement#sequenceElement()} method) features an additional free dimension, which will have to be bound at runtime.
* This is important when obtaining memory access var handle from layouts, as in the following code:
*
* <blockquote><pre>{@code
VarHandle valueHandle = taggedValues.varHandle(PathElement.sequenceElement(),
PathElement.groupElement("value"));
* }</pre></blockquote>
* {@snippet lang=java :
* VarHandle valueHandle = taggedValues.varHandle(PathElement.sequenceElement(),
* PathElement.groupElement("value"));
* }
*
* Since the layout path constructed in the above example features exactly one free dimension (as it doesn't specify
* <em>which</em> member layout named {@code value} should be selected from the enclosing sequence layout),
@@ -177,12 +177,12 @@
* offsets of elements of a sequence at different indices, by supplying these indices when invoking the method handle.
* For instance:
*
* <blockquote><pre>{@code
MethodHandle offsetHandle = taggedValues.byteOffsetHandle(PathElement.sequenceElement(),
PathElement.groupElement("kind"));
long offset1 = (long) offsetHandle.invokeExact(1L); // 8
long offset2 = (long) offsetHandle.invokeExact(2L); // 16
* }</pre></blockquote>
* {@snippet lang=java :
* MethodHandle offsetHandle = taggedValues.byteOffsetHandle(PathElement.sequenceElement(),
* PathElement.groupElement("kind"));
* long offset1 = (long) offsetHandle.invokeExact(1L); // 8
* long offset2 = (long) offsetHandle.invokeExact(2L); // 16
* }
*
* <h2>Layout attributes</h2>
*
@@ -330,7 +330,7 @@ default long bitOffset(PathElement... elements) {
* <p>The final offset returned by the method handle is computed as follows:
*
* <blockquote><pre>{@code
offset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
* offset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
* }</pre></blockquote>
*
* where {@code x_1}, {@code x_2}, ... {@code x_n} are <em>dynamic</em> values provided as {@code long}
@@ -381,8 +381,8 @@ default long byteOffset(PathElement... elements) {
* <p>The final offset returned by the method handle is computed as follows:
*
* <blockquote><pre>{@code
bitOffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
offset = bitOffset / 8
* bitOffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
* offset = bitOffset / 8
* }</pre></blockquote>
*
* where {@code x_1}, {@code x_2}, ... {@code x_n} are <em>dynamic</em> values provided as {@code long}
@@ -413,15 +413,15 @@ default MethodHandle byteOffsetHandle(PathElement... elements) {
* The final memory location accessed by the returned memory access var handle can be computed as follows:
*
* <blockquote><pre>{@code
address = base + offset
* address = base + offset
* }</pre></blockquote>
*
* where {@code base} denotes the base address expressed by the {@link MemorySegment} access coordinate
* (see {@link MemorySegment#address()} and {@link MemoryAddress#toRawLongValue()}) and {@code offset}
* can be expressed in the following form:
*
* <blockquote><pre>{@code
offset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
* offset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
* }</pre></blockquote>
*
* where {@code x_1}, {@code x_2}, ... {@code x_n} are <em>dynamic</em> values provided as {@code long}
@@ -458,8 +458,8 @@ default VarHandle varHandle(PathElement... elements) {
* <p>The offset of the returned segment is computed as follows:
*
* <blockquote><pre>{@code
bitOffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
offset = bitOffset / 8
* bitOffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)
* offset = bitOffset / 8
* }</pre></blockquote>
*
* where {@code x_1}, {@code x_2}, ... {@code x_n} are <em>dynamic</em> values provided as {@code long}
@@ -468,9 +468,9 @@ default VarHandle varHandle(PathElement... elements) {
* the layout path.
*
* <p>After the offset is computed, the returned segment is created as if by calling:
* <blockquote><pre>{@code
segment.asSlice(offset, layout.byteSize());
* }</pre></blockquote>
* {@snippet lang=java :
* segment.asSlice(offset, layout.byteSize());
* }
*
* where {@code segment} is the segment to be sliced, and where {@code layout} is the layout selected by the given
* layout path, as per {@link MemoryLayout#select(PathElement...)}.
@@ -599,7 +599,7 @@ static PathElement sequenceElement(long index) {
* 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 * (S + I * F)
* E * (S + I * F)
* }</pre></blockquote>
* where {@code E} is the size (in bytes) of the sequence element layout.
*

1 comment on commit 84baea7

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 84baea7 Dec 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.