Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8295045

Implementation of Foreign Function and Memory API (Second Preview)

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 20
    • core-libs
    • None
    • source, binary, behavioral
    • medium
    • The removal of `Addressable` and `MemoryAddress` will likely require changes to code using the Foreign Function and Memory API (especially the native interop part).
    • Java API
    • SE

      Summary

      This CSR refers to the second preview iteration of the Foreign Function & Memory (FFM) API originally targeted for Java 19, with the goal of further refining and consolidating the FFM API.

      Problem

      Feedback on the incubating API revealed the following issues:

      • The separation between MemorySegment and MemoryAddress can be confusing, as a MemoryAddress effectively acts as a zero-length memory segment;
      • The MemorySession interface has some issues:
        • Not all sessions are closeable, despite the interface implements AutoCloseable;
        • APIs sometimes need to use non-closeable session views to protect against clients closing sessions using the MemorySegment::session accessor;
        • Some of the predicates in MemorySession are leaking too much information (e.g. MemorySession::ownerThread).
      • The memory layout hierarchy is not exhaustive, which leads to problem when used in combination with pattern matching;
      • The naming of the method SymbolLookup::lookup is unfortunate, as the same word lookup is used both in the noun form (class name) and the verb form (method name).
      • There is no way to allow restricted operations on a module in a custom layer, as the command line option only works for modules in the boot layer;
      • The Linker API needs ways for clients to customize the properties of the downcall method handles. Some examples of this:
        • Mark a downcall method handle as "trivial" - that is, a method handle that performs little computation, does not block and does not upcall to Java (e.g. getpid);
        • Request that the Linker saves the state of certain native variables, such as errno or LastError (as these might get overwritten during normal JVM operation);
        • Request that one or more by-reference parameters in a downcall might be pinned heap segments. That is, memory segments backed by on-heap region of memory which should not be moved for the duration of the call;
        • Specify custom calling conventions (e.g. fastcall);
        • Tweak the safety parameters of the API, to achieve different safety vs. performance trade-offs (e.g. avoid keeping alive by-reference parameters).

      Solution

      Here we describe the main changes brought forward in this CSR:

      • MemoryAddress and Addressable are removed from the FFM API. Instead, zero-length memory segments are used whenever the FFM API needs to model "raw" addresses coming from native code. This simplifies the FFM API, removing an ambiguous abstraction as well as some duplication in the API (see accessor methods in MemoryAddress). The rationale behind these changes is described in [1].

      • MemorySession has been replaced with SegmentScope, a pure lifetime abstraction which does not implement AutoCloseable and SegmentAllocator. A SegmentScope controls which threads have access to a memory segment and when. A scope that can be used to allocate segments that are never allocated is the global scope (SegmentScope::global). Or, clients can obtain a scope, the automatic scope (SegmentScope::auto) that can be used to allocate segments that are deallocated automatically, by the garbage collector. Clients requiring deterministic deallocation must use the new Arena abstraction. An Arena provides a scope - the arena scope (Arena::scope). When the arena is closed, the arena scope becomes not alive, thus invalidating all the segments associated with the arena scope. This allows us to remove support for non-closeable memory session views (MemorySession::asNonCloseable, MemorySession::isCloseable, MemorySession::equals, MemorySession::hashCode). The rationale behind these changes is described in [2].

      • The MemorySession::ownerThread() method has been replaced with a more focussed predicate SegmentScope:isOwnedBy(Thread)

      • The SegmentAllocator::newNativeArena factory methods have been replaced with a more basic SegmentAllocator::slicingAllocator(MemorySegment) factory. The new slicing allocator is less powerful than the allocator it replaces, but also simpler to understand, and also much easier to build upon.

      • To allow for "unsafe" access of zero-length memory segments, a new method has been added to ValueLayout.OfAddress, namely asUnbounded. This new restricted method takes an address layout and creates a new unbounded address layout. When using an unbounded layout to dereference memory, or construct downcall method handles, the FFM API will create memory segments with maximal length (i.e. Long.MAX_VALUE, rather than zero-length memory segments, which can therefore be accessed.

      • Several changes to the MemoryLayout hierarchy:

        • The hierarchy is now defined in terms of sealed interfaces
        • Three new types have been added: PaddingLayout, StructLayout and UnionLayout (the latter two are a subtype of GroupLayout);
        • Several predicate methods (isPadding, isStruct, isUnion) have been dropped in favor of pattern matching (which now works as expected).
      • The SymbolLookup::lookup method has been renamed to SymbolLookup::find;
      • A new method, on ModuleLayer.Controller has been added to enable native access on a module in a custom layer;
      • The new interface Linker.Option has been introduced. This is a tag interface accepted in Linker::downcallHandle. At the moment, only a single option is provided, to specify variadic function calls (because of this, the FunctionDescriptor interface has been simplified, and is now a simple carrier of arguments/return layouts). More linker options will follow.

      Specification

      A specdiff and javadoc of the changes as of November 30th, 2022 are available below:

      A delta of the specdiff between what has been previously submitted is available here:

      References

      1. http://cr.openjdk.java.net/~mcimadamore/panama/segment_address.html
      2. http://cr.openjdk.java.net/~mcimadamore/panama/session_arenas.html

            mcimadamore Maurizio Cimadamore
            mcimadamore Maurizio Cimadamore
            Jorn Vernee, Per-Ake Minborg
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: