CSR :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
Summary ------- Provide an incubator module, jdk.incubator.foreign, which contains an API, referred to as the Memory Access API, that is designed to facilitate safe and structured access to off-heap and on-heap memory. This API provides the fundamental building blocks to replace JNI. Problem ------- To date, there is no optimal solution for accessing off-heap memory. While access to off-heap memory is possible using the ByteBuffer API, such an API has certain limitations (stateful-ness, addressing space bound by the 2G limit, non-deterministic deallocation, structural access) which makes it unsuitable as a general off-heap API, especially when it comes to interoperating with native code. Other alternatives are available, such as Unsafe (efficient, but not supported) or JNI (supported but inefficient), but ultimately no ideal solution and/or API exists. Solution -------- The memory access API addresses the aforementioned problems by providing a memory access API that is *general* (can be used both for off-heap and on-heap access), *safe* (uses of this API cannot cause any hard JVM crash) and *efficient* (this is achieved by making *immutability* and *deterministic-deallocation* two central design choices of the API). Such an API lends itself well to all cases where e.g. the ByteBuffer API is currently used to access off-heap memory; since this new API doesn't incur in the 2G addressing space limit, it is particularly apt to model persistent memory (see https://openjdk.java.net/jeps/352). In addition, since this API separates memory segment descriptions from the way in which such segments are accessed, it also lends well to use cases where the same memory segment needs to be shared across multiple views or *slices* (a common use case in tensor programming, or access to multi-dimensional arrays of values). Specification ------------- The implementation of the memory access API exports the following interfaces in the package jdk.incubator.foreign, defined in module jdk.incubator.foreign: ``` MemorySegment Models a contiguous region of memory MemoryAddress Models an offset within a memory segment MemoryLayout Models (optional) descriptions of the contents of a memory segment MemoryLayout.PathElement Constructs layout paths which can be helpful to retrieve offset to a specific layout element ``` A `MemorySegment` is a *static* and *immutable* description of a region of memory. A `MemorySegment` is always associated with *spatial bounds* (e.g. the minimum and maximum address within the segment) as well as *temporal bounds* (which define when it is *safe* to access the segment). To support deterministic-deallocaton, memory segments support the `AutoCloseable` interface, so that they can be *closed* when no longer in use (closing a memory segment might trigger deallocation of the memory resources, if any, associated with the segment). A `MemoryLayout` is a programmatic description of a memory segment contents. The `MemoryLayout` interface provide ways to mechanically derive information from layouts, using so called *layout paths* - that is, given a toplevel layout, and a *path* (expressed as a list of `PathElement` instances), it is possible to derive information such as the offset of the selected layout elements within the toplevel layout; or the `VarHandle` accessor required to access the selected layout elements given a `MemoryAddress` instance which points to a memory segment with the toplevel layout. Additionally, the implementation of the memory access API will export the following classes: ``` GroupLayout Models compound layouts (e.g. structs or unions) SequenceLayout Models array layouts. ValueLayout Models value layouts - e.g. sequence of bits MemoryHandles Defines several factory methods for constructing and combining memory access var handles MemoryLayouts Defines useful (and common) layout constants. ``` The first three classes are specific subclasses implementing the `MemoryLayout` interface. Each of those classes provide access to specific properties; for instance a `SequenceLayout` has an (optional) element count, and a sequence element layout. The `MemoryHandles` class defines several factories and combinators for the `VarHandle` instances which can be used to access memory segments. Similarly, the `MemoryLayouts` class contains several layout constants that can be useful to developers. When the memory access API exits the incubating stage, we plan to make at least the following adjustments: * move the functionality from the `jdk.incubator.foreign` module to `java.base` * rename the `jdk.incubator.foreign` package to `java.foreign` * move the combinators/factories in `MemoryHandles` into `java.lang.invoke.MethodHandles` * move some of the constants in `MemoryLayouts` (such as `JAVA_INT`, `JAVA_FLOAT` and so forth) into the corresponding primitive wrapper class (e.g. `MemoryLayouts::JAVA_INT` will become `Integer::LAYOUT`) The javadoc for the package with the implementation (updated live) is available at http://cr.openjdk.java.net/~mcimadamore/panama/memaccess_javadoc ; a copy (as of December 9, 2019) is also attached here. More details can be found in the JEP issue - https://bugs.openjdk.java.net/browse/JDK-8227446
|