1 /*
   2  *  Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
   3  *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  *  This code is free software; you can redistribute it and/or modify it
   6  *  under the terms of the GNU General Public License version 2 only, as
   7  *  published by the Free Software Foundation.  Oracle designates this
   8  *  particular file as subject to the "Classpath" exception as provided
   9  *  by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  *  This code is distributed in the hope that it will be useful, but WITHOUT
  12  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  *  version 2 for more details (a copy is included in the LICENSE file that
  15  *  accompanied this code).
  16  *
  17  *  You should have received a copy of the GNU General Public License version
  18  *  2 along with this work; if not, write to the Free Software Foundation,
  19  *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  *   Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  *  or visit www.oracle.com if you need additional information or have any
  23  *  questions.
  24  *
  25  */
  26 
  27 /**
  28  * <p> Classes to support low-level, safe and efficient memory access. For example:
  29  *
  30  * <pre>{@code
  31 static final VarHandle intHandle = MemoryHandles.varHandle(int.class, ByteOrder.BIG_ENDIAN);
  32 
  33 try (MemorySegment segment = MemorySegment.allocateNative(10 * 4)) {
  34    MemoryAddress base = segment.baseAddress();
  35    for (long i = 0 ; i < 10 ; i++) {
  36      intHandle.set(base.offset(i * 4), (int)i);
  37    }
  38  }
  39  * }</pre>
  40  *
  41  * Here we create a var handle, namely {@code intHandle}, to manipulate values of the primitive type {@code int}, at
  42  * a given memory location. We then create a <em>native</em> memory segment, that is, a memory segment backed by
  43  * off-heap memory; the size of the segment is 40 bytes, enough to store 10 values of the primitive type {@code int}.
  44  * The segment is created inside a <em>try-with-resources</em> construct: this idiom ensures that all the memory resources
  45  * associated with the segment will be released at the end of the block. Inside the try-with-resources block, we initialize
  46  * the contents of the memory segment; more specifically, if we view the memory segment as a set of 10 adjacent slots,
  47  * {@code s[i]}, where {@code 0 <= i < 10}, where the size of each slot is exactly 4 bytes, the initialization logic above will set each slot
  48  * so that {@code s[i] = i}, again where {@code 0 <= i < 10}.
  49  *
  50  * <p>
  51  * The key abstractions introduced by this package are {@link jdk.incubator.foreign.MemorySegment} and {@link jdk.incubator.foreign.MemoryAddress}.
  52  * The first models a contiguous memory region, which can reside either inside or outside the Java heap; the latter models an address - that is,
  53  * an offset inside a given segment. A memory address represents the main access coordinate of a memory access var handle, which can be obtained
  54  * using the combinator methods defined in the {@link jdk.incubator.foreign.MemoryHandles} class. Finally, the {@link jdk.incubator.foreign.MemoryLayout} class
  55  * hierarchy enables description of <em>memory layouts</em> and basic operations such as computing the size in bytes of a given
  56  * layout, obtain its alignment requirements, and so on. Memory layouts also provide an alternate, more abstract way, to produce
  57  * memory access var handles, e.g. using <a href="MemoryLayout.html#layout-paths"><em>layout paths</em></a>.
  58  *
  59  * <h2><a id="deallocation"></a>Deterministic deallocation</h2>
  60  *
  61  * When writing code that manipulates memory segments, especially if backed by memory which resides outside the Java heap, it is
  62  * crucial that the resources associated with a memory segment are released when the segment is no longer in use, by calling the {@link jdk.incubator.foreign.MemorySegment#close()}
  63  * method either explicitly, or implicitly, by relying on try-with-resources construct (as demonstrated in the example above).
  64  * Closing a given memory segment is an <em>atomic</em> operation which can either succeed - and result in the underlying
  65  * memory associated with the segment to be released, or <em>fail</em> with an exception.
  66  * <p>
  67  * The deterministic deallocation model differs significantly from the implicit strategies adopted within other APIs, most
  68  * notably the {@link java.nio.ByteBuffer} API: in that case, when a native byte buffer is created (see {@link java.nio.ByteBuffer#allocateDirect(int)}),
  69  * the underlying memory is not released until the byte buffer reference becomes <em>unreachable</em>. While implicit deallocation
  70  * models such as this can be very convenient - clients do not have to remember to <em>close</em> a direct buffer - such models can also make it
  71  * hard for clients to ensure that the memory associated with a direct buffer has indeed been released.
  72  *
  73  * <h2><a id="safety"></a>Safety</h2>
  74  *
  75  * This API provides strong safety guarantees when it comes to memory access. First, when dereferencing a memory segment using
  76  * a memory address, such an address is validated (upon access), to make sure that it does not point to a memory location
  77  * which resides <em>outside</em> the boundaries of the memory segment it refers to. We call this guarantee <em>spatial safety</em>.
  78  * <p>
  79  * Since memory segments can be closed (see above), a memory address is also validated (upon access) to make sure that
  80  * the segment it belongs to has not been closed prematurely. We call this guarantee <em>temporal safety</em>. Note that,
  81  * in the general case, guaranteeing temporal safety can be hard, as multiple threads could attempt to access and/or close
  82  * the same memory segment concurrently. The memory access API addresses this problem by imposing strong
  83  * <a href="MemorySegment.html#thread-confinement"><em>thread-confinement</em></a> guarantees on memory segments: each
  84  * memory segment is associated with an owner thread, which is the only thread that can either access or close the segment.
  85  * A thread other than the owner thread will have to explicitly <em>acquire</em> a segment in order to be able to use it.
  86  * <p>
  87  * Together, spatial and temporal safety ensure that each memory access operation either succeeds - and accesses a valid
  88  * memory location - or fails.
  89  */
  90 package jdk.incubator.foreign;