Summary
This CSR refers to the latest iteration of the Foreign Function & Memory API originally targeted for Java 17, with the goal of further refining and consolidating the API into a preview API.
Problem
Make the Foreign Function & Memory API a preview API. In addition to some minor, necessary API differences and renamings (listed in the section below), feedback on the incubating API revealed the following issues:
- Making a full scope abstraction available when operating on e.g.
MemorySegment
is too powerful: this allows clients of aMemorySegment
to close a scope associated with a segment (which also brings down other resources associated with the same scope). - The mechanism for keeping a scope alive (
ResourceScope::keepAlive
) is not constrained enough to be truly useful. For instance, the ad-hoc nature of temporal dependencies makes it impossible to capture temporal dependencies between scopes in a static graph. This problem is discussed here. - Memory layouts support can have unbounded size; this was introduced with the idea to support C's variable length arrays in structs, but was never used in full. In all cases where an unbounded sequence layout was used, a zero-length sequence layout could be used instead.
- Closing a shared scope could issue exceptions at both the closing and the accessing sites, or make the resource temporarily inaccessible for a certain period of time.
- Alignment of constants in
ValueLayout
does not reflect real alignment (e.g. all constants are 1-byte aligned)
Solution
Here we describe the main changes brought forward in this CSR:
First, as the API is no longer an incubating API, all classes have been moved into a package under the
java.base
module, namelyjava/lang/foreign
;Some abstractions in the previous iterations of the API have been removed, to achieve a tighter coupling with other JDK APIs. More specifically:
jdk.incubator.foreign.MemoryHandles
has been dropped and all the var handle combinators moved where they belong, namelyjava.lang.invoke.MethodHandles
jdk.incubator.foreign.SymbolLookup
has been dropped. Instead a new lookup (final) instance method has been added tojava.lang.ClassLoader
The
ResourceScope
abstraction, present in previous iterations of the API has been renamed toMemorySession
. This is to reflect the fact that aMemorySession
is not always associated with a lexical scope (e.g. a a try-with-resources block).MemorySession
now supports anisCloseable
predicate; namely, not all sessions can be closed. For instance, implicit and global sessions cannot be closed, and this is now reflected in the API. This also allows us to associate non-closeable session views with resources such as memory segments, which allows clients to access most of the details of a segment scope, without allowing the client to close the scope.The API for keeping sessions alive has been simplified a lot; there's now only a method called
MemorySession::whileAlive
which takes aRunnable
, and executes its action while the session is kept alive.Support for unbounded sequence layouts has been dropped, with resulting simplifications in the layout API. To reduce some of the boilerplate associated with creating strided array element var handles (which were frequently created using unbounded sequence layouts), the API now offers a dedicated factory method:
MemoryLayout::arrayElementVarHandle
which allows clients to create the same strided var handles as before, without the need to manually wrap the element layout in a fictional container/sequence layout.The logic for closing shared sessions has been improved; as a result closing a shared scope while another thread is accessing a resource associated with that scope will only result in a failure on the accessing thread.
All constants in
ValueLayout
now feature the correct alignment.
Specification
A specdiff and a javadoc of the changes as of February 21th, 2022 has been attached to this CSR.
- csr of
-
JDK-8282191 Implementation of Foreign Function & Memory API (Preview)
-
- Resolved
-
- relates to
-
JDK-8288761 SegmentAllocator:allocate(long bytesSize) not throwing IAEx when bytesSize < 0
-
- Resolved
-
-
JDK-8288850 SegmentAllocator:allocate() can return null some cases
-
- Resolved
-
-
JDK-8289188 SegmentAllocator:allocateArray(*) default behavior mismatch to spec
-
- Resolved
-
-
JDK-8289365 SegmentAllocator:allocateArray(MemoryLayout, count) does not throw IAEx when count is -1
-
- Resolved
-
-
JDK-8289187 SegmentAllocator:allocateArray throws IllegalArgumentException in some cases
-
- Closed
-
-
JDK-8295045 Implementation of Foreign Function and Memory API (Second Preview)
-
- Closed
-
-
JDK-8312523 Implementation of Foreign Function & Memory API
-
- Closed
-