8278607: Misc issues in foreign API javadoc
Reviewed-by: sundar
This commit is contained in:
parent
918e339785
commit
d6b5544e74
@ -55,7 +55,7 @@ import java.util.Optional;
|
||||
* {@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 @@ import java.util.Optional;
|
||||
* <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 @@ import java.util.Optional;
|
||||
* 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 @@ import java.util.Optional;
|
||||
*
|
||||
* <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 @@ public sealed interface CLinker extends SymbolLookup permits Windowsx64Linker, S
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ package jdk.incubator.foreign;
|
||||
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 one of the following ways:
|
||||
* <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 @@ import java.util.stream.Stream;
|
||||
* 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 @@ import java.util.stream.Stream;
|
||||
* 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 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||
|
||||
/**
|
||||
* 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 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||
|
||||
/**
|
||||
* 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 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||
|
||||
/**
|
||||
* 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 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||
|
||||
/**
|
||||
* 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 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||
|
||||
/**
|
||||
* 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 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||
|
||||
/**
|
||||
* 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 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||
|
||||
/**
|
||||
* 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 @@ 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:
|
||||
* {@snippet lang=java :
|
||||
* ResourceScope scope = ...
|
||||
* SegmentAllocator implicitAllocator = (size, align) -> MemorySegment.allocateNative(size, align, ResourceScope.newImplicitScope());
|
||||
* }
|
||||
*
|
||||
|
@ -59,7 +59,8 @@ import java.util.function.Consumer;
|
||||
sealed public interface VaList extends Addressable permits WinVaList, SysVVaList, LinuxAArch64VaList, MacOsAArch64VaList, SharedUtils.EmptyVaList {
|
||||
|
||||
/**
|
||||
* Reads the next value as an {@code int} and advances this variable argument list's position.
|
||||
* Reads the next value as an {@code int} and advances this variable argument list's position. The behavior of this
|
||||
* method is equivalent to the C {@code va_arg} function.
|
||||
*
|
||||
* @param layout the layout of the value to be read.
|
||||
* @return the {@code int} value read from this variable argument list.
|
||||
@ -69,7 +70,8 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList
|
||||
int nextVarg(ValueLayout.OfInt layout);
|
||||
|
||||
/**
|
||||
* Reads the next value as a {@code long} and advances this variable argument list's position.
|
||||
* Reads the next value as a {@code long} and advances this variable argument list's position. The behavior of this
|
||||
* method is equivalent to the C {@code va_arg} function.
|
||||
*
|
||||
* @param layout the layout of the value to be read.
|
||||
* @return the {@code long} value read from this variable argument list.
|
||||
@ -79,7 +81,8 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList
|
||||
long nextVarg(ValueLayout.OfLong layout);
|
||||
|
||||
/**
|
||||
* Reads the next value as a {@code double} and advances this variable argument list's position.
|
||||
* Reads the next value as a {@code double} and advances this variable argument list's position. The behavior of this
|
||||
* method is equivalent to the C {@code va_arg} function.
|
||||
*
|
||||
* @param layout the layout of the value
|
||||
* @return the {@code double} value read from this variable argument list.
|
||||
@ -89,7 +92,8 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList
|
||||
double nextVarg(ValueLayout.OfDouble layout);
|
||||
|
||||
/**
|
||||
* Reads the next value as a {@code MemoryAddress} and advances this variable argument list's position.
|
||||
* Reads the next value as a {@code MemoryAddress} and advances this variable argument list's position. The behavior of this
|
||||
* method is equivalent to the C {@code va_arg} function.
|
||||
*
|
||||
* @param layout the layout of the value to be read.
|
||||
* @return the {@code MemoryAddress} value read from this variable argument list.
|
||||
@ -99,7 +103,13 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList
|
||||
MemoryAddress nextVarg(ValueLayout.OfAddress layout);
|
||||
|
||||
/**
|
||||
* Reads the next value as a {@code MemorySegment}, and advances this variable argument list's position.
|
||||
* Reads the next value as a {@code MemorySegment}, and advances this variable argument list's position. The behavior of this
|
||||
* method is equivalent to the C {@code va_arg} function. The provided group layout must correspond to a C struct or union
|
||||
* type.
|
||||
* <p>
|
||||
* How the value is read in the returned segment is ABI-dependent: calling this method on a group layout
|
||||
* with member layouts {@code L_1, L_2, ... L_n} is not guaranteed to be semantically equivalent to perform distinct
|
||||
* calls to {@code nextVarg} for each of the layouts in {@code L_1, L_2, ... L_n}.
|
||||
* <p>
|
||||
* The memory segment returned by this method will be allocated using the given {@link SegmentAllocator}.
|
||||
*
|
||||
@ -129,9 +139,12 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList
|
||||
|
||||
/**
|
||||
* Copies this variable argument list at its current position into a new variable argument list associated
|
||||
* with the same scope as this variable argument list. Copying is useful to
|
||||
* traverse the variable argument list elements, starting from the current position, without affecting the state
|
||||
* of the original variable argument list, essentially allowing the elements to be traversed multiple times.
|
||||
* with the same scope as this variable argument list. The behavior of this method is equivalent to the C
|
||||
* {@code va_copy} function.
|
||||
* <p>
|
||||
* Copying is useful to traverse the variable argument list elements, starting from the current position,
|
||||
* without affecting the state of the original variable argument list, essentially allowing the elements to be
|
||||
* traversed multiple times.
|
||||
*
|
||||
* @return a copy of this variable argument list.
|
||||
* @throws IllegalStateException if the scope associated with this variable argument list has been closed, or if access occurs from
|
||||
@ -187,8 +200,8 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList
|
||||
* 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 @@ import java.util.OptionalLong;
|
||||
|
||||
/**
|
||||
* 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. For example, the C type {@code char*} can refer to a single {@code char} value,
|
||||
* or an array of {@code char} values, of given size. Nor do said pointers 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:
|
||||
|
Loading…
Reference in New Issue
Block a user