| /* | |
| * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. | |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| * | |
| * This code is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. Oracle designates this | |
| * particular file as subject to the "Classpath" exception as provided | |
| * by Oracle in the LICENSE file that accompanied this code. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| /** | |
| * <p>Provides low-level access to memory and functions outside the Java runtime. | |
| * | |
| * <h2 id="fma">Foreign memory access</h2> | |
| * | |
| * <p> | |
| * The main abstraction introduced to support foreign memory access is | |
| * {@link java.lang.foreign.MemorySegment}, that models a contiguous region of memory, | |
| * residing either inside or outside the Java heap. Memory segments are typically | |
| * allocated using an {@link java.lang.foreign.Arena}, which controls the lifetime of | |
| * the regions of memory backing the segments it allocates. The contents of a | |
| * memory segment can be described using a {@link java.lang.foreign.MemoryLayout memory layout}, | |
| * which provides basic operations to query sizes, offsets, and alignment constraints. | |
| * Memory layouts also provide an alternate, more abstract way, to | |
| * <a href=MemorySegment.html#segment-deref>access memory segments</a> using | |
| * {@linkplain java.lang.foreign.MemoryLayout#varHandle(java.lang.foreign.MemoryLayout.PathElement...) var handles}, | |
| * which can be computed using <a href="MemoryLayout.html#layout-paths"><em>layout paths</em></a>. | |
| * <p> | |
| * For example, to allocate an off-heap region of memory big enough to hold 10 values of | |
| * the primitive type {@code int}, and fill it with values ranging from {@code 0} to | |
| * {@code 9}, we can use the following code: | |
| * | |
| * {@snippet lang = java: | |
| * try (Arena arena = Arena.ofConfined()) { | |
| * MemorySegment segment = arena.allocate(10 * 4); | |
| * for (int i = 0 ; i < 10 ; i++) { | |
| * segment.setAtIndex(ValueLayout.JAVA_INT, i, i); | |
| * } | |
| * } | |
| * } | |
| * | |
| * This code creates a <em>native</em> memory segment, that is, a memory segment backed | |
| * by off-heap memory; the size of the segment is 40 bytes, enough to store 10 values of | |
| * the primitive type {@code int}. The native segment is allocated using a | |
| * {@linkplain java.lang.foreign.Arena#ofConfined() confined arena}. As such, access to | |
| * the native segment is restricted to the current thread (the thread that created the | |
| * arena). Moreover, when the arena is closed, the native segment is invalidated, and | |
| * its backing region of memory is deallocated. Note the use of the <em>try-with-resources</em> | |
| * construct: this idiom ensures that the off-heap region of memory backing the native | |
| * segment will be released at the end of the block, according to the semantics described | |
| * in Section {@jls 14.20.3} of <cite>The Java Language Specification</cite>. | |
| * <p> | |
| * Memory segments provide strong safety guarantees when it comes to memory access. | |
| * First, when accessing a memory segment, the access coordinates are validated | |
| * (upon access), to make sure that access does not occur at any address that resides | |
| * <em>outside</em> the boundaries of the memory segment used by the access 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>. | |
| * <p> | |
| * Additionally, to prevent a region of memory from being accessed <em>after</em> it has | |
| * been deallocated (i.e. <em>use-after-free</em>), a segment is also validated | |
| * (upon access) to make sure that the arena from which it has been obtained has not | |
| * been closed. We call this guarantee <em>temporal safety</em>. | |
| * <p> | |
| * Together, spatial and temporal safety ensure that each memory access operation either | |
| * succeeds - and accesses a valid location within the region of memory backing the | |
| * memory segment - or fails. | |
| * | |
| * <h2 id="ffa">Foreign function access</h2> | |
| * | |
| * The key abstractions introduced to support foreign function access are | |
| * {@link java.lang.foreign.SymbolLookup}, {@link java.lang.foreign.FunctionDescriptor} and | |
| * {@link java.lang.foreign.Linker}. The first is used to look up symbols inside | |
| * libraries; the second is used to model the signature of foreign functions, while the | |
| * third is used to link 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 C/C++ 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: | |
| * | |
| * {@snippet lang = java: | |
| * Linker linker = Linker.nativeLinker(); | |
| * SymbolLookup stdlib = linker.defaultLookup(); | |
| * MethodHandle strlen = linker.downcallHandle( | |
| * stdlib.findOrThrow("strlen"), | |
| * FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS) | |
| * ); | |
| * | |
| * try (Arena arena = Arena.ofConfined()) { | |
| * MemorySegment cString = arena.allocateFrom("Hello"); | |
| * long len = (long)strlen.invokeExact(cString); // 5 | |
| * } | |
| *} | |
| * | |
| * Here, we obtain a {@linkplain java.lang.foreign.Linker#nativeLinker() native linker} | |
| * and we use it to {@linkplain java.lang.foreign.SymbolLookup#findOrThrow(java.lang.String) look up} | |
| * the {@code strlen} function in the standard C library; a <em>downcall method handle</em> | |
| * targeting said function is subsequently | |
| * {@linkplain java.lang.foreign.Linker#downcallHandle(FunctionDescriptor, Linker.Option...) obtained}. | |
| * To complete the linking successfully, we must provide a | |
| * {@link java.lang.foreign.FunctionDescriptor} instance, describing the signature of the | |
| * {@code strlen} function. From this information, the linker will uniquely determine | |
| * the sequence of steps which will turn the method handle invocation (here performed | |
| * using {@link java.lang.invoke.MethodHandle#invokeExact(java.lang.Object...)}) | |
| * into a foreign function call, according to the rules specified by the ABI of the | |
| * underlying platform. | |
| * <p> | |
| * The {@link java.lang.foreign.Arena} class also provides many useful methods for | |
| * interacting with foreign code, such as | |
| * {@linkplain java.lang.foreign.SegmentAllocator#allocateFrom(java.lang.String) converting} | |
| * Java strings into zero-terminated, UTF-8 strings, as demonstrated in the above example. | |
| * | |
| * @apiNote Usual memory model guarantees (see {@jls 17.4}) do not apply when accessing | |
| * native memory segments as these segments are backed by off-heap regions of memory. | |
| * | |
| * @spec jni/index.html Java Native Interface Specification | |
| * | |
| * @since 22 | |
| */ | |
| package java.lang.foreign; | |