diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/CLinker.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/CLinker.java index f5f1a6dc313..745e27691dd 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/CLinker.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/CLinker.java @@ -181,9 +181,9 @@ public sealed interface CLinker extends SymbolLookup permits Windowsx64Linker, S * to allocate structs returned by-value. *

* Calling this method is equivalent to the following code: -

{@code
-    linker.downcallHandle(function).bindTo(symbol);
-}
+ * {@snippet lang=java : + * linker.downcallHandle(function).bindTo(symbol); + * } * * @param symbol downcall symbol. * @param function the function descriptor. diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java index ce1a77c41b3..4856a66008d 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java @@ -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 @@ import java.nio.ByteOrder; * 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: - *
{@code
-MemoryAddress address = ...
-int value = address.get(ValueLayout.JAVA_INT, 0);
- * }
+ * {@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: - *
{@code
-MemoryAddress address = ...
-int value = address.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0);
- * }
+ * {@snippet lang=java : + * MemoryAddress address = ... + * int value = address.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0); + * } * * All the dereference methods in this class are restricted: since * a memory address does not feature temporal nor spatial bounds, the runtime has no way to check the correctness diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryHandles.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryHandles.java index f4489ecd601..f24f5c7bc6e 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryHandles.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryHandles.java @@ -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 @@ import java.util.Objects; * to the segment, at which dereference should occur. *

* As an example, consider the memory layout expressed by a {@link GroupLayout} instance constructed as follows: - *

{@code
-GroupLayout seq = MemoryLayout.structLayout(
-        MemoryLayout.paddingLayout(32),
-        ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN).withName("value")
-);
- * }
+ * {@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: - *
{@code
-VarHandle handle = MemoryHandles.varHandle(ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); //(MemorySegment, long) -> int
-handle = MemoryHandles.insertCoordinates(handle, 1, 4); //(MemorySegment) -> int
- * }
+ * {@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 + * } * *

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.

@@ -177,13 +177,13 @@ public final class MemoryHandles { * example, it is often convenient to model an unsigned short 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: - *
{@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
-     * }
+ * {@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 + * } *

* When calling e.g. {@link VarHandle#set(Object...)} on the resulting var * handle, the incoming value (of type {@code adaptedType}) is converted by a diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java index 8319f22c2ab..fe0fb4e93f9 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java @@ -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 @@ import java.util.stream.Stream; *

* For instance, consider the following struct declaration in C: * - *

{@code
- typedef struct {
-     char kind;
-     int value;
- } TaggedValues[5];
- * }
+ * {@snippet lang=c : + * typedef struct { + * char kind; + * int value; + * } TaggedValues[5]; + * } * * The above declaration can be modelled using a layout object, as follows: * - *
{@code
-SequenceLayout taggedValues = MemoryLayout.sequenceLayout(5,
-    MemoryLayout.structLayout(
-        ValueLayout.JAVA_BYTE.withName("kind"),
-        MemoryLayout.paddingLayout(24),
-        ValueLayout.JAVA_INT.withName("value")
-    )
-).withName("TaggedValues");
- * }
+ * {@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"); + * } *

* All implementations of this interface must be value-based; * programmers should treat instances that are {@linkplain #equals(Object) equal} as interchangeable and should not @@ -129,42 +129,42 @@ SequenceLayout taggedValues = MemoryLayout.sequenceLayout(5, * Such layout paths 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 value in the first sequence element, as follows: - *

{@code
-long valueOffset = taggedValues.bitOffset(PathElement.sequenceElement(0),
-                                          PathElement.groupElement("value")); // yields 32
- * }
+ * {@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: - *
{@code
-MemoryLayout value = taggedValues.select(PathElement.sequenceElement(),
-                                         PathElement.groupElement("value"));
- * }
+ * {@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: - *
{@code
-MemoryLayout taggedValuesWithHole = taggedValues.map(l -> MemoryLayout.paddingLayout(32),
-                                            PathElement.sequenceElement(), PathElement.groupElement("value"));
- * }
+ * {@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: - *
{@code
-MemoryLayout taggedValuesWithHole = MemoryLayout.sequenceLayout(5,
-    MemoryLayout.structLayout(
-        ValueLayout.JAVA_BYTE.withName("kind"),
-        MemoryLayout.paddingLayout(32),
-        MemoryLayout.paddingLayout(32)
-));
- * }
+ * {@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 free dimensions. 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: * - *
{@code
-VarHandle valueHandle = taggedValues.varHandle(PathElement.sequenceElement(),
-                                               PathElement.groupElement("value"));
- * }
+ * {@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 * which member layout named {@code value} should be selected from the enclosing sequence layout), @@ -177,12 +177,12 @@ VarHandle valueHandle = taggedValues.varHandle(PathElement.sequenceElement(), * offsets of elements of a sequence at different indices, by supplying these indices when invoking the method handle. * For instance: * - *
{@code
-MethodHandle offsetHandle = taggedValues.byteOffsetHandle(PathElement.sequenceElement(),
-                                                          PathElement.groupElement("kind"));
-long offset1 = (long) offsetHandle.invokeExact(1L); // 8
-long offset2 = (long) offsetHandle.invokeExact(2L); // 16
- * }
+ * {@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 + * } * *

Layout attributes

* @@ -330,7 +330,7 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S *

The final offset returned by the method handle is computed as follows: * *

{@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)
      * }
* * where {@code x_1}, {@code x_2}, ... {@code x_n} are dynamic values provided as {@code long} @@ -381,8 +381,8 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S *

The final offset returned by the method handle is computed as follows: * *

{@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
      * }
* * where {@code x_1}, {@code x_2}, ... {@code x_n} are dynamic values provided as {@code long} @@ -413,7 +413,7 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S * The final memory location accessed by the returned memory access var handle can be computed as follows: * *
{@code
-    address = base + offset
+     * address = base + offset
      * }
* * where {@code base} denotes the base address expressed by the {@link MemorySegment} access coordinate @@ -421,7 +421,7 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S * can be expressed in the following form: * *
{@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)
      * }
* * where {@code x_1}, {@code x_2}, ... {@code x_n} are dynamic values provided as {@code long} @@ -458,8 +458,8 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S *

The offset of the returned segment is computed as follows: * *

{@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
      * }
* * where {@code x_1}, {@code x_2}, ... {@code x_n} are dynamic values provided as {@code long} @@ -468,9 +468,9 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S * the layout path. * *

After the offset is computed, the returned segment is created as if by calling: - *

{@code
-    segment.asSlice(offset, layout.byteSize());
-     * }
+ * {@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 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S * with this path is bound by an index {@code I}, the resulting accessed offset can be obtained with the following * formula: *
{@code
-E * (S + I * F)
+         * E * (S + I * F)
          * }
* where {@code E} is the size (in bytes) of the sequence element layout. * diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java index cd0f1181863..2a577cfc296 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java @@ -119,17 +119,17 @@ import java.util.stream.Stream; * 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: - *
{@code
-MemorySegment segment = ...
-int value = segment.get(ValueLayout.JAVA_INT, 0);
- * }
+ * {@snippet lang=java : + * MemorySegment segment = ... + * int value = segment.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: - *
{@code
-MemorySegment segment = ...
-int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0);
- * }
+ * {@snippet lang=java : + * MemorySegment segment = ... + * int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0); + * } * * For more complex dereference operations (e.g. structured memory access), clients can obtain a memory access var handle, * that is, a var handle that accepts a segment and, optionally, one or more additional {@code long} coordinates. Memory @@ -145,13 +145,13 @@ int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0); * the {@link #scope()} method. As for all resources associated with a resource scope, a segment cannot be * accessed after its corresponding scope has been closed. For instance, the following code will result in an * exception: - *
{@code
-MemorySegment segment = null;
-try (ResourceScope scope = ResourceScope.newConfinedScope()) {
-    segment = MemorySegment.allocateNative(8, scope);
-}
-segment.get(ValueLayout.JAVA_LONG, 0); // already closed!
- * }
+ * {@snippet lang=java : + * MemorySegment segment = null; + * try (ResourceScope scope = ResourceScope.newConfinedScope()) { + * segment = MemorySegment.allocateNative(8, scope); + * } + * segment.get(ValueLayout.JAVA_LONG, 0); // already closed! + * } * Additionally, access to a memory segment is subject to the thread-confinement checks enforced by the owning scope; that is, * if the segment is associated with a shared scope, it can be accessed by multiple threads; if it is associated with a confined * scope, it can only be accessed by the thread which owns the scope. @@ -162,10 +162,10 @@ segment.get(ValueLayout.JAVA_LONG, 0); // already closed! *

Memory segment views

* * Memory segments support views. For instance, it is possible to create an immutable view of a memory segment, as follows: - *
{@code
-MemorySegment segment = ...
-MemorySegment roSegment = segment.asReadOnly();
- * }
+ * {@snippet lang=java : + * MemorySegment segment = ... + * MemorySegment roSegment = segment.asReadOnly(); + * } * It is also possible to create views whose spatial bounds are stricter than the ones of the original segment * (see {@link MemorySegment#asSlice(long, long)}). *

@@ -184,15 +184,15 @@ MemorySegment roSegment = segment.asReadOnly(); * (to do this, the segment has to be associated with a shared scope). The following code can be used to sum all int * values in a memory segment in parallel: * - *

{@code
-try (ResourceScope scope = ResourceScope.newSharedScope()) {
-    SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT);
-    MemorySegment segment = MemorySegment.allocateNative(SEQUENCE_LAYOUT, scope);
-    int sum = segment.elements(ValueLayout.JAVA_INT).parallel()
-                           .mapToInt(s -> s.get(ValueLayout.JAVA_INT, 0))
-                           .sum();
-}
- * }
+ * {@snippet lang=java : + * try (ResourceScope scope = ResourceScope.newSharedScope()) { + * SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT); + * MemorySegment segment = MemorySegment.allocateNative(SEQUENCE_LAYOUT, scope); + * int sum = segment.elements(ValueLayout.JAVA_INT).parallel() + * .mapToInt(s -> s.get(ValueLayout.JAVA_INT, 0)) + * .sum(); + * } + * } * * @implSpec * Implementations of this interface are immutable, thread-safe and value-based. @@ -233,9 +233,9 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory /** * Returns a sequential {@code Stream} over disjoint slices (whose size matches that of the specified layout) * in this segment. Calling this method is equivalent to the following code: - *
{@code
-    StreamSupport.stream(segment.spliterator(elementLayout), false);
-     * }
+ * {@snippet lang=java : + * StreamSupport.stream(segment.spliterator(elementLayout), false); + * } * * @param elementLayout the layout to be used for splitting. * @return a sequential {@code Stream} over disjoint slices in this segment. @@ -274,9 +274,9 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory * and whose new size is computed by subtracting the specified offset from this segment size. *

* Equivalent to the following code: - *

{@code
-    asSlice(offset, byteSize() - offset);
-     * }
+ * {@snippet lang=java : + * asSlice(offset, byteSize() - offset); + * } * * @see #asSlice(long, long) * @@ -343,9 +343,9 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory * a negative or positive value. For instance, if both segments are native * segments, the resulting offset can be computed as follows: * - *
{@code
+     * {@snippet lang=java :
      * other.baseAddress().toRawLongValue() - segment.baseAddress().toRawLongValue()
-     * }
+ * } * * If the segments share the same base address, {@code 0} is returned. If * {@code other} is a slice of this segment, the offset is always @@ -362,13 +362,13 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory * More specifically, the given value is filled into each address of this * segment. Equivalent to (but likely more efficient than) the following code: * - *
{@code
-byteHandle = MemoryLayout.ofSequence(ValueLayout.JAVA_BYTE)
-         .varHandle(byte.class, MemoryLayout.PathElement.sequenceElement());
-for (long l = 0; l < segment.byteSize(); l++) {
-     byteHandle.set(segment.address(), l, value);
-}
-     * }
+ * {@snippet lang=java : + * byteHandle = MemoryLayout.ofSequence(ValueLayout.JAVA_BYTE) + * .varHandle(byte.class, MemoryLayout.PathElement.sequenceElement()); + * for (long l = 0; l < segment.byteSize(); l++) { + * byteHandle.set(segment.address(), l, value); + * } + * } * * without any regard or guarantees on the ordering of particular memory * elements being set. @@ -389,9 +389,9 @@ for (long l = 0; l < segment.byteSize(); l++) { * at offset {@code 0} through {@code src.byteSize() - 1}. *

* Calling this method is equivalent to the following code: - *

{@code
-    MemorySegment.copy(src, 0, this, 0, src.byteSize);
-     * }
+ * {@snippet lang=java : + * MemorySegment.copy(src, 0, this, 0, src.byteSize); + * } * @param src the source segment. * @throws IndexOutOfBoundsException if {@code src.byteSize() > this.byteSize()}. * @throws IllegalStateException if either the scope associated with the source segment or the scope associated @@ -801,9 +801,9 @@ for (long l = 0; l < segment.byteSize(); l++) { * when the segment is no longer in use. Failure to do so will result in off-heap memory leaks. *

* This is equivalent to the following code: - *

{@code
-    allocateNative(layout.bytesSize(), layout.bytesAlignment(), scope);
-     * }
+ * {@snippet lang=java : + * allocateNative(layout.bytesSize(), layout.bytesAlignment(), scope); + * } *

* The block of off-heap memory associated with the returned native memory segment is initialized to zero. * @@ -826,9 +826,9 @@ for (long l = 0; l < segment.byteSize(); l++) { * when the segment is no longer in use. Failure to do so will result in off-heap memory leaks. *

* This is equivalent to the following code: - *

{@code
-    allocateNative(bytesSize, 1, scope);
-     * }
+ * {@snippet lang=java : + * allocateNative(bytesSize, 1, scope); + * } *

* The block of off-heap memory associated with the returned native memory segment is initialized to zero. * @@ -935,9 +935,9 @@ for (long l = 0; l < segment.byteSize(); l++) { * For example, this may occur if the same file is {@linkplain MemorySegment#mapFile mapped} to two segments. *

* Calling this method is equivalent to the following code: - *

{@code
-    MemorySegment.copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes);
-     * }
+ * {@snippet lang=java : + * MemorySegment.copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes); + * } * @param srcSegment the source segment. * @param srcOffset the starting offset, in bytes, of the source segment. * @param dstSegment the destination segment. diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ResourceScope.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ResourceScope.java index f2fb32a0594..24665c7dfe9 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ResourceScope.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ResourceScope.java @@ -103,15 +103,15 @@ import java.util.Spliterator; * segment and allow multiple threads to work in parallel on disjoint segment slices. The following code can be used to sum * all int values in a memory segment in parallel: * - *
{@code
-try (ResourceScope scope = ResourceScope.newSharedScope()) {
-    SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT);
-    MemorySegment segment = MemorySegment.allocateNative(SEQUENCE_LAYOUT, scope);
-    int sum = segment.elements(ValueLayout.JAVA_INT).parallel()
-                        .mapToInt(s -> s.get(ValueLayout.JAVA_INT, 0))
-                        .sum();
-}
- * }
+ * {@snippet lang=java : + * try (ResourceScope scope = ResourceScope.newSharedScope()) { + * SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT); + * MemorySegment segment = MemorySegment.allocateNative(SEQUENCE_LAYOUT, scope); + * int sum = segment.elements(ValueLayout.JAVA_INT).parallel() + * .mapToInt(s -> s.get(ValueLayout.JAVA_INT, 0)) + * .sum(); + * } + * } * *

* Shared resource scopes, while powerful, must be used with caution: if one or more threads accesses @@ -131,13 +131,13 @@ try (ResourceScope scope = ResourceScope.newSharedScope()) { * This can be useful when clients need to perform a critical operation on a memory segment, during which they have * to ensure that the scope associated with that segment will not be closed; this can be done as follows: * - *

{@code
-MemorySegment segment = ...
-try (ResourceScope criticalScope = ResourceScope.newConfinedScope()) {
-    criticalScope.keepAlive(segment.scope());
-    
-}
- * }
+ * {@snippet lang=java : + * MemorySegment segment = ... + * try (ResourceScope criticalScope = ResourceScope.newConfinedScope()) { + * criticalScope.keepAlive(segment.scope()); + * + * } + * } * * Note that a resource scope does not become unreachable * until all the scopes it depends on have been closed. @@ -239,9 +239,9 @@ public sealed interface ResourceScope extends AutoCloseable permits ResourceScop /** * Creates a new shared scope, managed by a private {@link Cleaner} instance. Equivalent to (but likely more efficient than) * the following code: - *
{@code
-    newSharedScope(Cleaner.create());
-     * }
+ * {@snippet lang=java : + * newSharedScope(Cleaner.create()); + * } * @return a shared scope, managed by a private {@link Cleaner} instance. */ static ResourceScope newImplicitScope() { diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SegmentAllocator.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SegmentAllocator.java index 622308da088..d2f112c5d37 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SegmentAllocator.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SegmentAllocator.java @@ -339,9 +339,9 @@ public interface SegmentAllocator { /** * Returns a native unbounded arena-based allocator, with predefined block size and maximum arena size, * associated with the provided scope. Equivalent to the following code: - *
{@code
-    SegmentAllocator.newNativeArena(Long.MAX_VALUE, predefinedBlockSize, scope);
-     * }
+ * {@snippet lang=java : + * SegmentAllocator.newNativeArena(Long.MAX_VALUE, predefinedBlockSize, scope); + * } * * @param scope the scope associated with the segments returned by the arena-based allocator. * @return a new unbounded arena-based allocator @@ -355,9 +355,9 @@ public interface SegmentAllocator { /** * Returns a native unbounded arena-based allocator, with block size set to the specified arena size, associated with * the provided scope, with given arena size. Equivalent to the following code: - *
{@code
-    SegmentAllocator.newNativeArena(arenaSize, arenaSize, scope);
-     * }
+ * {@snippet lang=java : + * SegmentAllocator.newNativeArena(arenaSize, arenaSize, scope); + * } * * @param arenaSize the size (in bytes) of the allocation arena. * @param scope the scope associated with the segments returned by the arena-based allocator. @@ -416,10 +416,10 @@ public interface SegmentAllocator { * each new allocation request will return a new slice starting at the segment offset {@code 0} (alignment * constraints are ignored by this allocator), hence the name prefix allocator. * Equivalent to (but likely more efficient than) the following code: - *
{@code
-    MemorySegment segment = ...
-    SegmentAllocator prefixAllocator = (size, align) -> segment.asSlice(0, size);
-     * }
+ * {@snippet lang=java : + * MemorySegment segment = ... + * SegmentAllocator prefixAllocator = (size, align) -> segment.asSlice(0, size); + * } *

* This allocator can be useful to limit allocation requests in case a client * knows that they have fully processed the contents of the allocated segment before the subsequent allocation request @@ -439,10 +439,10 @@ public interface SegmentAllocator { /** * Returns a native allocator, associated with the provided scope. Equivalent to (but likely more efficient than) * the following code: - *

{@code
-    ResourceScope scope = ...
-    SegmentAllocator nativeAllocator = (size, align) -> MemorySegment.allocateNative(size, align, scope);
-     * }
+ * {@snippet lang=java : + * ResourceScope scope = ... + * SegmentAllocator nativeAllocator = (size, align) -> MemorySegment.allocateNative(size, align, scope); + * } * * @param scope the scope associated with the returned allocator. * @return a native allocator, associated with the provided scope. @@ -455,10 +455,10 @@ public interface SegmentAllocator { /** * Returns a native allocator which allocates segments in independent {@linkplain ResourceScope#newImplicitScope() implicit scopes}. * Equivalent to (but likely more efficient than) the following code: - *
{@code
-    ResourceScope scope = ...
-    SegmentAllocator implicitAllocator = (size, align) -> MemorySegment.allocateNative(size, align, ResourceScope.newImplicitScope());
-     * }
+ * {@snippet lang=java : + * ResourceScope scope = ... + * SegmentAllocator implicitAllocator = (size, align) -> MemorySegment.allocateNative(size, align, ResourceScope.newImplicitScope()); + * } * * @return a native allocator which allocates segments in independent {@linkplain ResourceScope#newImplicitScope() implicit scopes}. */ diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java index e751830313b..13ac7192728 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java @@ -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 @@ -37,18 +37,18 @@ import java.util.OptionalLong; * A finite sequence layout can be thought of as a group layout where the sequence layout's element layout is repeated a number of times * that is equal to the sequence layout's element count. In other words this layout: * - *
{@code
-MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN));
- * }
+ * {@snippet lang=java : + * MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); + * } * * is equivalent to the following layout: * - *
{@code
-MemoryLayout.structLayout(
-    ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN),
-    ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN),
-    ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN));
- * }
+ * {@snippet lang=java : + * MemoryLayout.structLayout( + * ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), + * ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), + * ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); + * } * *

* This is a value-based @@ -119,22 +119,22 @@ public final class SequenceLayout extends AbstractLayout implements MemoryLayout * as the flattened projection of this sequence layout. *

* For instance, given a sequence layout of the kind: - *

{@code
-    var seq = MemoryLayout.sequenceLayout(4, MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT));
-     * }
+ * {@snippet lang=java : + * var seq = MemoryLayout.sequenceLayout(4, MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT)); + * } * calling {@code seq.reshape(2, 6)} will yield the following sequence layout: - *
{@code
-    var reshapeSeq = MemoryLayout.sequenceLayout(2, MemoryLayout.sequenceLayout(6, ValueLayout.JAVA_INT));
-     * }
+ * {@snippet lang=java : + * var reshapeSeq = MemoryLayout.sequenceLayout(2, MemoryLayout.sequenceLayout(6, ValueLayout.JAVA_INT)); + * } *

* If one of the provided element count is the special value {@code -1}, then the element * count in that position will be inferred from the remaining element counts and the * element count of the flattened projection of this layout. For instance, a layout equivalent to * the above {@code reshapeSeq} can also be computed in the following ways: - *

{@code
-    var reshapeSeqImplicit1 = seq.reshape(-1, 6);
-    var reshapeSeqImplicit2 = seq.reshape(2, -1);
-     * }
+ * {@snippet lang=java : + * var reshapeSeqImplicit1 = seq.reshape(-1, 6); + * var reshapeSeqImplicit2 = seq.reshape(2, -1); + * } * @param elementCounts an array of element counts, of which at most one can be {@code -1}. * @return a new sequence layout where element layouts in the flattened projection of this * sequence layout (see {@link #flatten()}) are re-arranged into one or more nested sequence layouts. @@ -195,13 +195,13 @@ public final class SequenceLayout extends AbstractLayout implements MemoryLayout * This transformation preserves the layout size; nested sequence layout in this sequence layout will * be dropped and their element counts will be incorporated into that of the returned sequence layout. * For instance, given a sequence layout of the kind: - *
{@code
-    var seq = MemoryLayout.sequenceLayout(4, MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT));
-     * }
+ * {@snippet lang=java : + * var seq = MemoryLayout.sequenceLayout(4, MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT)); + * } * calling {@code seq.flatten()} will yield the following sequence layout: - *
{@code
-    var flattenedSeq = MemoryLayout.sequenceLayout(12, ValueLayout.JAVA_INT);
-     * }
+ * {@snippet lang=java : + * var flattenedSeq = MemoryLayout.sequenceLayout(12, ValueLayout.JAVA_INT); + * } * @return a new sequence layout with the same size as this layout (but, possibly, with different * element count), whose element layout is not a sequence layout. * @throws UnsupportedOperationException if this sequence layout, or one of the nested sequence layouts being diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java index 36a3c6b5b9d..c6d63c3ca1c 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java @@ -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 @@ -516,9 +516,9 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { * A value layout constant whose size is the same as that of a machine address (e.g. {@code size_t}), * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
{@code
-    MemoryLayout.valueLayout(MemoryAddress.class, ByteOrder.nativeOrder()).withBitAlignment(8);
-     * }
+ * {@snippet lang=java : + * MemoryLayout.valueLayout(MemoryAddress.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfAddress ADDRESS = new OfAddress(ByteOrder.nativeOrder()).withBitAlignment(8); @@ -526,9 +526,9 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { * A value layout constant whose size is the same as that of a Java {@code byte}, * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
{@code
-    MemoryLayout.valueLayout(byte.class, ByteOrder.nativeOrder()).withBitAlignment(8);
-     * }
+ * {@snippet lang=java : + * MemoryLayout.valueLayout(byte.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfByte JAVA_BYTE = new OfByte(ByteOrder.nativeOrder()).withBitAlignment(8); @@ -536,9 +536,9 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { * A value layout constant whose size is the same as that of a Java {@code boolean}, * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
{@code
-    MemoryLayout.valueLayout(boolean.class, ByteOrder.nativeOrder()).withBitAlignment(8);
-     * }
+ * {@snippet lang=java : + * MemoryLayout.valueLayout(boolean.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfBoolean JAVA_BOOLEAN = new OfBoolean(ByteOrder.nativeOrder()).withBitAlignment(8); @@ -546,9 +546,9 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { * A value layout constant whose size is the same as that of a Java {@code char}, * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
{@code
-    MemoryLayout.valueLayout(char.class, ByteOrder.nativeOrder()).withBitAlignment(8);
-     * }
+ * {@snippet lang=java : + * MemoryLayout.valueLayout(char.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfChar JAVA_CHAR = new OfChar(ByteOrder.nativeOrder()).withBitAlignment(8); @@ -556,9 +556,9 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { * A value layout constant whose size is the same as that of a Java {@code short}, * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
{@code
-    MemoryLayout.valueLayout(short.class, ByteOrder.nativeOrder()).withBitAlignment(8);
-     * }
+ * {@snippet lang=java : + * MemoryLayout.valueLayout(short.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfShort JAVA_SHORT = new OfShort(ByteOrder.nativeOrder()).withBitAlignment(8); @@ -566,9 +566,9 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { * A value layout constant whose size is the same as that of a Java {@code int}, * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
{@code
-    MemoryLayout.valueLayout(int.class, ByteOrder.nativeOrder()).withBitAlignment(8);
-     * }
+ * {@snippet lang=java : + * MemoryLayout.valueLayout(int.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfInt JAVA_INT = new OfInt(ByteOrder.nativeOrder()).withBitAlignment(8); @@ -576,9 +576,9 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { * A value layout constant whose size is the same as that of a Java {@code long}, * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
{@code
-    MemoryLayout.valueLayout(long.class, ByteOrder.nativeOrder()).withBitAlignment(8);
-     * }
+ * {@snippet lang=java : + * MemoryLayout.valueLayout(long.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfLong JAVA_LONG = new OfLong(ByteOrder.nativeOrder()) .withBitAlignment(8); @@ -587,9 +587,9 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { * A value layout constant whose size is the same as that of a Java {@code float}, * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
{@code
-    MemoryLayout.valueLayout(float.class, ByteOrder.nativeOrder()).withBitAlignment(8);
-     * }
+ * {@snippet lang=java : + * MemoryLayout.valueLayout(float.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfFloat JAVA_FLOAT = new OfFloat(ByteOrder.nativeOrder()).withBitAlignment(8); @@ -597,9 +597,9 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { * A value layout constant whose size is the same as that of a Java {@code double}, * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: - *
{@code
-    MemoryLayout.valueLayout(double.class, ByteOrder.nativeOrder()).withBitAlignment(8);
-     * }
+ * {@snippet lang=java : + * MemoryLayout.valueLayout(double.class, ByteOrder.nativeOrder()).withBitAlignment(8); + * } */ public static final OfDouble JAVA_DOUBLE = new OfDouble(ByteOrder.nativeOrder()).withBitAlignment(8); } diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/package-info.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/package-info.java index 82bc2f53d4b..a6d140e4266 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/package-info.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/package-info.java @@ -43,12 +43,12 @@ * For example, to allocate an off-heap memory region big enough to hold 10 values of the primitive type {@code int}, and fill it with values * ranging from {@code 0} to {@code 9}, we can use the following code: * - *
{@code
-MemorySegment segment = MemorySegment.allocateNative(10 * 4, ResourceScope.newImplicitScope());
-for (int i = 0 ; i < 10 ; i++) {
-   segment.setAtIndex(ValueLayout.JAVA_INT, i, i);
-}
- * }
+ * {@snippet lang=java : + * MemorySegment segment = MemorySegment.allocateNative(10 * 4, ResourceScope.newImplicitScope()); + * for (int i = 0 ; i < 10 ; i++) { + * segment.setAtIndex(ValueLayout.JAVA_INT, i, i); + * } + * } * * This code creates a native memory segment, that is, a memory segment backed by * off-heap memory; the size of the segment is 40 bytes, enough to store 10 values of the primitive type {@code int}. @@ -69,14 +69,14 @@ for (int i = 0 ; i < 10 ; i++) { * Clients that operate under these assumptions might want to programmatically release the memory associated * with a memory segment. This can be done, using the {@link jdk.incubator.foreign.ResourceScope} abstraction, as shown below: * - *
{@code
-try (ResourceScope scope = ResourceScope.newConfinedScope()) {
-    MemorySegment segment = MemorySegment.allocateNative(10 * 4, scope);
-    for (int i = 0 ; i < 10 ; i++) {
-        segment.setAtIndex(ValueLayout.JAVA_INT, i, i);
-    }
-}
- * }
+ * {@snippet lang=java : + * try (ResourceScope scope = ResourceScope.newConfinedScope()) { + * MemorySegment segment = MemorySegment.allocateNative(10 * 4, scope); + * for (int i = 0 ; i < 10 ; i++) { + * segment.setAtIndex(ValueLayout.JAVA_INT, i, i); + * } + * } + * } * * This example is almost identical to the prior one; this time we first create a so called resource scope, * which is used to bind the life-cycle of the segment created immediately afterwards. Note the use of the @@ -107,19 +107,19 @@ try (ResourceScope scope = ResourceScope.newConfinedScope()) { * For example, to compute the length of a string using the C standard library function {@code strlen} on a Linux x64 platform, * we can use the following code: * - *
{@code
-      var linker = CLinker.systemCLinker();
-      MethodHandle strlen = linker.downcallHandle(
-        linker.lookup("strlen").get(),
-        FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS)
-      );
-
-      try (var scope = ResourceScope.newConfinedScope()) {
-         var cString = MemorySegment.allocateNative(5 + 1, scope);
-         cString.setUtf8String("Hello");
-         long len = (long)strlen.invoke(cString); // 5
-      }
- * }
+ * {@snippet lang=java : + * var linker = CLinker.systemCLinker(); + * MethodHandle strlen = linker.downcallHandle( + * linker.lookup("strlen").get(), + * FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS) + * ); + * + * try (var scope = ResourceScope.newConfinedScope()) { + * var cString = MemorySegment.allocateNative(5 + 1, scope); + * cString.setUtf8String("Hello"); + * long len = (long)strlen.invoke(cString); // 5 + * } + * } * * Here, we obtain a {@linkplain jdk.incubator.foreign.CLinker#systemCLinker() linker instance} and we use it * to {@linkplain jdk.incubator.foreign.CLinker#lookup(java.lang.String) lookup} the {@code strlen} symbol in the @@ -148,11 +148,10 @@ try (ResourceScope scope = ResourceScope.newConfinedScope()) { * {@linkplain jdk.incubator.foreign.MemoryAddress#get(jdk.incubator.foreign.ValueLayout.OfInt, long) dereference methods} * provided: * - *
{@code
-...
-MemoryAddress addr = ... //obtain address from native code
-int x = addr.get(ValueLayout.JAVA_INT, 0);
- * }
+ * {@snippet lang=java : + * MemoryAddress addr = ... //obtain address from native code + * int x = addr.get(ValueLayout.JAVA_INT, 0); + * } * * Alternatively, the client can * {@linkplain jdk.incubator.foreign.MemorySegment#ofAddress(jdk.incubator.foreign.MemoryAddress, long, jdk.incubator.foreign.ResourceScope) create} @@ -160,36 +159,36 @@ int x = addr.get(ValueLayout.JAVA_INT, 0); * for instance, be available in the documentation of the foreign function which produced the native address. * Here is how an unsafe segment can be created from a native address: * - *
{@code
-ResourceScope scope = ... // initialize a resource scope object
-MemoryAddress addr = ... //obtain address from native code
-MemorySegment segment = MemorySegment.ofAddress(addr, 4, scope); // segment is 4 bytes long
-int x = segment.get(ValueLayout.JAVA_INT, 0);
- * }
+ * {@snippet lang=java : + * ResourceScope scope = ... // initialize a resource scope object + * MemoryAddress addr = ... //obtain address from native code + * MemorySegment segment = MemorySegment.ofAddress(addr, 4, scope); // segment is 4 bytes long + * int x = segment.get(ValueLayout.JAVA_INT, 0); + * } * *

Upcalls

* The {@link jdk.incubator.foreign.CLinker} interface also allows to turn an existing method handle (which might point * to a Java method) into a memory address, so that Java code can effectively be passed to other foreign functions. * For instance, we can write a method that compares two integer values, as follows: * - *
{@code
-class IntComparator {
-    static int intCompare(MemoryAddress addr1, MemoryAddress addr2) {
-        return addr1.get(ValueLayout.JAVA_INT, 0) - addr2.get(ValueLayout.JAVA_INT, 0);
-    }
-}
- * }
+ * {@snippet lang=java : + * class IntComparator { + * static int intCompare(MemoryAddress addr1, MemoryAddress addr2) { + * return addr1.get(ValueLayout.JAVA_INT, 0) - addr2.get(ValueLayout.JAVA_INT, 0); + * } + * } + * } * * The above method dereferences two memory addresses containing an integer value, and performs a simple comparison * by returning the difference between such values. We can then obtain a method handle which targets the above static * method, as follows: * - *
{@code
-FunctionDescriptor intCompareDescriptor = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
-MethodHandle intCompareHandle = MethodHandles.lookup().findStatic(IntComparator.class,
-                                                   "intCompare",
-                                                   CLinker.upcallType(comparFunction));
- * }
+ * {@snippet lang=java : + * FunctionDescriptor intCompareDescriptor = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS); + * MethodHandle intCompareHandle = MethodHandles.lookup().findStatic(IntComparator.class, + * "intCompare", + * CLinker.upcallType(comparFunction)); + * } * * As before, we need to create a {@link jdk.incubator.foreign.FunctionDescriptor} instance, this time describing the signature * of the function pointer we want to create. The descriptor can be used to @@ -199,12 +198,12 @@ MethodHandle intCompareHandle = MethodHandles.lookup().findStatic(IntComparator. * Now that we have a method handle instance, we can turn it into a fresh function pointer, * using the {@link jdk.incubator.foreign.CLinker} interface, as follows: * - *
{@code
-ResourceScope scope = ...
-Addressable comparFunc = CLinker.systemCLinker().upcallStub(
-     intCompareHandle, intCompareDescriptor, scope);
-);
- * }
+ * {@snippet lang=java : + * ResourceScope scope = ... + * Addressable comparFunc = CLinker.systemCLinker().upcallStub( + * intCompareHandle, intCompareDescriptor, scope); + * ); + * } * * The {@link jdk.incubator.foreign.FunctionDescriptor} instance created in the previous step is then used to * {@linkplain jdk.incubator.foreign.CLinker#upcallStub(java.lang.invoke.MethodHandle, jdk.incubator.foreign.FunctionDescriptor, jdk.incubator.foreign.ResourceScope) create}