Skip to content
This repository has been archived by the owner. It is now read-only.

8278607: Misc issues in foreign API javadoc #17

Closed
wants to merge 4 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -55,7 +55,7 @@
* {@linkplain #downcallHandle(FunctionDescriptor) Linking a foreign function} is a process which requires a function descriptor,
* a set of memory layouts which, together, specify the signature of the foreign function to be linked, and returns,
* when complete, a downcall method handle, that is, a method handle that can be used to invoke the target native function.
* The Java {@link java.lang.invoke.MethodType method type} associated with the returned method handle is
* The Java {@linkplain java.lang.invoke.MethodType method type} associated with the returned method handle is
* {@linkplain #downcallType(FunctionDescriptor) derived} from the argument and return layouts in the function descriptor.
* More specifically, given each layout {@code L} in the function descriptor, a corresponding carrier {@code C} is inferred,
* as described below:
@@ -69,7 +69,8 @@
* <li>or, if {@code L} is a {@link GroupLayout}, then {@code C} is set to {@code MemorySegment.class}</li>
* </ul>
* <p>
* The downcall method handle type, derived as above, might be decorated by additional leading parameters:
* The downcall method handle type, derived as above, might be decorated by additional leading parameters,
* in the given order if both are present:
* <ul>
* <li>If the downcall method handle is created {@linkplain #downcallHandle(FunctionDescriptor) without specifying a native symbol},
* the downcall method handle type features a leading parameter of type {@link NativeSymbol}, from which the
@@ -91,7 +92,7 @@
* handle and a function descriptor; in this case, the set of memory layouts in the function descriptor
* specify the signature of the function pointer associated with the upcall stub.
* <p>
* The type of the provided method handle has to match the Java {@link java.lang.invoke.MethodType method type}
* The type of the provided method handle has to match the Java {@linkplain java.lang.invoke.MethodType method type}
* associated with the upcall stub, which is derived from the argument and return layouts in the function descriptor.
* More specifically, given each layout {@code L} in the function descriptor, a corresponding carrier {@code C} is inferred, as described below:
* <ul>
@@ -109,7 +110,7 @@
*
* <h2>System lookup</h2>
*
* This class implements the {@link SymbolLookup} interface; as such clients can {@linkplain #lookup(String) lookup} symbols
* This class implements the {@link SymbolLookup} interface; as such clients can {@linkplain #lookup(String) look up} symbols
* in the standard libraries associated with this linker. The set of symbols available for lookup is unspecified,
* as it depends on the platform and on the operating system.
*
@@ -163,7 +164,7 @@ static CLinker systemCLinker() {
}

/**
* Lookup a symbol in the standard libraries associated with this linker.
* Look up a symbol in the standard libraries associated with this linker.
* The set of symbols available for lookup is unspecified, as it depends on the platform and on the operating system.
* @return a symbol in the standard libraries associated with this linker.
*/
@@ -29,14 +29,16 @@
import jdk.internal.foreign.MemoryAddressImpl;
import jdk.internal.reflect.CallerSensitive;

import java.lang.invoke.MethodHandle;
import java.nio.ByteOrder;

/**
* A memory address models a reference into a memory location. Memory addresses are typically obtained in three ways:
* A memory address models a reference into a memory location. Memory addresses are typically obtained in onw of the following ways:
Copy link

@TheMode TheMode Dec 13, 2021

Choose a reason for hiding this comment

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

Should perhaps be one :)

* <ul>
* <li>By calling {@link Addressable#address()} on an instance of type {@link Addressable} (e.g. a memory segment);</li>
* <li>By invoking a {@linkplain CLinker#downcallHandle(FunctionDescriptor) downcall method handle} which returns a pointer;</li>
* <li>By reading an address from memory, e.g. via {@link MemorySegment#get(ValueLayout.OfAddress, long)}.</li>
* <li>By the invocation of an {@linkplain CLinker#upcallStub(MethodHandle, FunctionDescriptor, ResourceScope) upcall stub} which accepts a pointer.
* </ul>
* A memory address is backed by a raw machine pointer, expressed as a {@linkplain #toRawLongValue() long value}.
*
@@ -56,7 +56,7 @@
* A memory segment models a contiguous region of memory. A memory segment is associated with both spatial
* and temporal bounds (e.g. a {@link ResourceScope}). Spatial bounds ensure that memory access operations on a memory segment cannot affect a memory location
* which falls <em>outside</em> the boundaries of the memory segment being accessed. Temporal bounds ensure that memory access
* operations on a segment cannot occur after the resource scope associated with a memory segment has been closed (see {@link ResourceScope#close()}).
* operations on a segment cannot occur <em>after</em> the resource scope associated with a memory segment has been closed (see {@link ResourceScope#close()}).
* <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 Object#equals(Object) equal} as interchangeable and should not
@@ -157,7 +157,7 @@
* scope, it can only be accessed by the thread which owns the scope.
* <p>
* Heap and buffer segments are always associated with a <em>global</em>, shared scope. This scope cannot be closed,
* and can be considered as <em>always alive</em>.
* and segments associated with it can be considered as <em>always alive</em>.
*
* <h2>Memory segment views</h2>
*
@@ -217,11 +217,11 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
* The returned spliterator splits this segment according to the specified element layout; that is,
* if the supplied layout has size N, then calling {@link Spliterator#trySplit()} will result in a spliterator serving
* approximately {@code S/N/2} elements (depending on whether N is even or not), where {@code S} is the size of
* this segment. As such, splitting is possible as long as {@code S/N >= 2}. The spliterator returns segments that feature the same
* scope as this given segment.
* this segment. As such, splitting is possible as long as {@code S/N >= 2}. The spliterator returns segments that
* are associated with the same scope as this segment.
* <p>
* The returned spliterator effectively allows to slice this segment into disjoint sub-segments, which can then
* be processed in parallel by multiple threads.
* The returned spliterator effectively allows to slice this segment into disjoint {@linkplain #asSlice(long, long) slices},
* which can then be processed in parallel by multiple threads.
*
* @param elementLayout the layout to be used for splitting.
* @return the element spliterator for this segment
@@ -679,7 +679,7 @@ static MemorySegment ofByteBuffer(ByteBuffer bb) {

/**
* Creates a new array memory segment that models the memory associated with a given heap-allocated byte array.
* The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
* The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope.
*
* @param arr the primitive array backing the array memory segment.
* @return a new array memory segment.
@@ -690,7 +690,7 @@ static MemorySegment ofArray(byte[] arr) {

/**
* Creates a new array memory segment that models the memory associated with a given heap-allocated char array.
* The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
* The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope.
*
* @param arr the primitive array backing the array memory segment.
* @return a new array memory segment.
@@ -701,7 +701,7 @@ static MemorySegment ofArray(char[] arr) {

/**
* Creates a new array memory segment that models the memory associated with a given heap-allocated short array.
* The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
* The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope.
*
* @param arr the primitive array backing the array memory segment.
* @return a new array memory segment.
@@ -712,7 +712,7 @@ static MemorySegment ofArray(short[] arr) {

/**
* Creates a new array memory segment that models the memory associated with a given heap-allocated int array.
* The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
* The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope.
*
* @param arr the primitive array backing the array memory segment.
* @return a new array memory segment.
@@ -723,7 +723,7 @@ static MemorySegment ofArray(int[] arr) {

/**
* Creates a new array memory segment that models the memory associated with a given heap-allocated float array.
* The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
* The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope.
*
* @param arr the primitive array backing the array memory segment.
* @return a new array memory segment.
@@ -734,7 +734,7 @@ static MemorySegment ofArray(float[] arr) {

/**
* Creates a new array memory segment that models the memory associated with a given heap-allocated long array.
* The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
* The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope.
*
* @param arr the primitive array backing the array memory segment.
* @return a new array memory segment.
@@ -745,7 +745,7 @@ static MemorySegment ofArray(long[] arr) {

/**
* Creates a new array memory segment that models the memory associated with a given heap-allocated double array.
* The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
* The returned segment is associated with the {@linkplain ResourceScope#globalScope() global} resource scope.
*
* @param arr the primitive array backing the array memory segment.
* @return a new array memory segment.
@@ -456,7 +456,6 @@ static SegmentAllocator nativeAllocator(ResourceScope scope) {
* Returns a native allocator which allocates segments in independent {@linkplain ResourceScope#newImplicitScope() implicit scopes}.
* Equivalent to (but likely more efficient than) the following code:
* {@snippet lang=java :
* ResourceScope scope = ...
* SegmentAllocator implicitAllocator = (size, align) -> MemorySegment.allocateNative(size, align, ResourceScope.newImplicitScope());
* }
*
@@ -187,8 +187,8 @@ static VaList ofAddress(MemoryAddress address, ResourceScope scope) {
* of the underlying variable argument list.
* @param scope scope the scope to be associated with the new variable arity list.
* @return a new variable argument list.
* @throws IllegalStateException if the scope associated with {@code allocator} has been already closed,
* or if access occurs from a thread other than the thread owning that scope.
* @throws IllegalStateException if {@code scope} has been already closed, or if access occurs from a thread other
* than the thread owning {@code scope}.
*/
static VaList make(Consumer<Builder> actions, ResourceScope scope) {
Objects.requireNonNull(actions);
@@ -41,7 +41,7 @@

/**
* A value layout. A value layout is used to model the memory layout associated with values of basic data types, such as <em>integral</em> types
* (either signed or unsigned) and <em>floating-point</em> types. Each value layout has a size, a {@linkplain ByteOrder byte order})
* (either signed or unsigned) and <em>floating-point</em> types. Each value layout has a size, an alignment, a {@linkplain ByteOrder byte order})
* and a <em>carrier</em>, that is, the Java type that should be used when {@linkplain MemorySegment#get(OfInt, long) accessing}
* a memory region using the value layout.
* <p>
@@ -86,7 +86,7 @@
* <h3><a id="safety"></a>Safety</h3>
*
* This API provides strong safety guarantees when it comes to memory access. First, when dereferencing a memory segment,
* the access coordinates are validated (upon access), to make sure that access does not occur at an address which resides
* the access coordinates are validated (upon access), to make sure that access does not occur at any address which resides
* <em>outside</em> the boundaries of the memory segment used by the dereference operation. We call this guarantee <em>spatial safety</em>;
* in other words, access to memory segments is bounds-checked, in the same way as array access is, as described in
* Section {@jls 15.10.4} of <cite>The Java Language Specification</cite>.
@@ -99,10 +99,10 @@
* <h2>Foreign function access</h2>
* The key abstractions introduced to support foreign function access are {@link jdk.incubator.foreign.SymbolLookup},
* {@link jdk.incubator.foreign.MemoryAddress} and {@link jdk.incubator.foreign.CLinker}.
* The first is used to lookup symbols inside native libraries; the second is used to model native addresses (more on that later),
* The first is used to look up symbols inside native libraries; the second is used to model native addresses (more on that later),
* while the third provides linking capabilities which allows modelling foreign functions as {@link java.lang.invoke.MethodHandle} instances,
* so that clients can perform foreign function calls directly in Java, without the need for intermediate layers of native
* code (as it's the case with the <a href="{@docRoot}/../specs/jni/index.html">Java Native Interface (JNI)</a>).
* code (as is the case with the <a href="{@docRoot}/../specs/jni/index.html">Java Native Interface (JNI)</a>).
* <p>
* 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:
@@ -122,7 +122,7 @@
* }
*
* 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
* to {@linkplain jdk.incubator.foreign.CLinker#lookup(java.lang.String) look up} the {@code strlen} symbol in the
* standard C library; a <em>downcall method handle</em> targeting said symbol is subsequently
* {@linkplain jdk.incubator.foreign.CLinker#downcallHandle(jdk.incubator.foreign.FunctionDescriptor) obtained}.
* To complete the linking successfully, we must provide a {@link jdk.incubator.foreign.FunctionDescriptor} instance,
@@ -138,9 +138,9 @@
* <h3>Foreign addresses</h3>
*
* When a memory segment is created from Java code, the segment properties (spatial bounds, temporal bounds and confinement)
* are fully known at segment creation. But when interacting with native libraries, clients will often receive <em>raw</em> pointers;
* such pointers have no spatial bounds (example: does the C type {@code char*} refer to a single {@code char} value,
* or an array of {@code char} values, of given size?), no notion of temporal bounds, nor thread-confinement.
* are fully known at segment creation. But when interacting with native libraries, clients will often receive <em>raw</em> pointers.
* such pointers have no spatial bounds (does the C type {@code char*} refer to a single {@code char} value,
* or an array of {@code char} values, of given size?). Nor do they have any notion of temporal bounds or thread-confinement.
* <p>
* Raw pointers are modelled using the {@link jdk.incubator.foreign.MemoryAddress} class. When clients receive a
* memory address instance from a foreign function call, they can perform memory dereference on it directly,
@@ -167,7 +167,7 @@
* }
*
* <h3>Upcalls</h3>
* The {@link jdk.incubator.foreign.CLinker} interface also allows to turn an existing method handle (which might point
* The {@link jdk.incubator.foreign.CLinker} interface also allows clients 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:
*
@@ -193,7 +193,7 @@
* 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
* {@linkplain jdk.incubator.foreign.CLinker#upcallType(jdk.incubator.foreign.FunctionDescriptor) derive} a method type
* that can be used to lookup the method handle for {@code IntComparator.intCompare}.
* that can be used to look up the method handle for {@code IntComparator.intCompare}.
* <p>
* 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: