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.
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.
MemorySegmentis too powerful: this allows clients of a
MemorySegmentto 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
ValueLayoutdoes not reflect real alignment (e.g. all constants are 1-byte aligned)
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
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.MemoryHandleshas been dropped and all the var handle combinators moved where they belong, namely
jdk.incubator.foreign.SymbolLookuphas been dropped. Instead a new lookup (final) instance method has been added to
ResourceScopeabstraction, present in previous iterations of the API has been renamed to
MemorySession. This is to reflect the fact that a
MemorySessionis not always associated with a lexical scope (e.g. a a try-with-resources block).
MemorySessionnow supports an
isCloseablepredicate; 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::whileAlivewhich takes a
Runnable, 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::arrayElementVarHandlewhich 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
ValueLayoutnow feature the correct alignment.
A specdiff and a javadoc of the changes as of February 21th, 2022 has been attached to this CSR.