1 /*
   2  *  Copyright (c) 2019, 2021, 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 package jdk.incubator.foreign;
  28 
  29 import java.io.UncheckedIOException;
  30 import java.lang.reflect.Array;
  31 import java.nio.ByteBuffer;
  32 
  33 import jdk.internal.foreign.AbstractMemorySegmentImpl;
  34 import jdk.internal.foreign.HeapMemorySegmentImpl;
  35 import jdk.internal.foreign.MappedMemorySegmentImpl;
  36 import jdk.internal.foreign.ResourceScopeImpl;
  37 import jdk.internal.foreign.NativeMemorySegmentImpl;
  38 import jdk.internal.foreign.Utils;
  39 import jdk.internal.foreign.abi.SharedUtils;
  40 import jdk.internal.misc.ScopedMemoryAccess;
  41 import jdk.internal.misc.Unsafe;
  42 import jdk.internal.reflect.CallerSensitive;
  43 import jdk.internal.reflect.Reflection;
  44 import jdk.internal.vm.annotation.ForceInline;
  45 
  46 import java.io.IOException;
  47 import java.nio.ByteOrder;
  48 import java.nio.channels.FileChannel;
  49 import java.nio.charset.StandardCharsets;
  50 import java.nio.file.Path;
  51 import java.util.Objects;
  52 import java.util.Spliterator;
  53 import java.util.stream.Stream;
  54 
  55 /**
  56  * A memory segment models a contiguous region of memory. A memory segment is associated with both spatial
  57  * and temporal bounds (e.g. a {@link ResourceScope}). Spatial bounds ensure that memory access operations on a memory segment cannot affect a memory location
  58  * which falls <em>outside</em> the boundaries of the memory segment being accessed. Temporal bounds ensure that memory access
  59  * operations on a segment cannot occur after the resource scope associated with a memory segment has been closed (see {@link ResourceScope#close()}).
  60  * <p>
  61  * All implementations of this interface must be <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>;
  62  * programmers should treat instances that are {@linkplain Object#equals(Object) equal} as interchangeable and should not
  63  * use instances for synchronization, or unpredictable behavior may occur. For example, in a future release,
  64  * synchronization may fail. The {@code equals} method should be used for comparisons.
  65  * <p>
  66  * Non-platform classes should not implement {@linkplain MemorySegment} directly.
  67  *
  68  * <p> Unless otherwise specified, passing a {@code null} argument, or an array argument containing one or more {@code null}
  69  * elements to a method in this class causes a {@link NullPointerException NullPointerException} to be thrown. </p>
  70  *
  71  * <h2>Constructing memory segments</h2>
  72  *
  73  * There are multiple ways to obtain a memory segment. First, memory segments backed by off-heap memory can
  74  * be allocated using one of the many factory methods provided (see {@link MemorySegment#allocateNative(MemoryLayout, ResourceScope)},
  75  * {@link MemorySegment#allocateNative(long, ResourceScope)} and {@link MemorySegment#allocateNative(long, long, ResourceScope)}). Memory segments obtained
  76  * in this way are called <em>native memory segments</em>.
  77  * <p>
  78  * It is also possible to obtain a memory segment backed by an existing heap-allocated Java array,
  79  * using one of the provided factory methods (e.g. {@link MemorySegment#ofArray(int[])}). Memory segments obtained
  80  * in this way are called <em>array memory segments</em>.
  81  * <p>
  82  * It is possible to obtain a memory segment backed by an existing Java byte buffer (see {@link ByteBuffer}),
  83  * using the factory method {@link MemorySegment#ofByteBuffer(ByteBuffer)}.
  84  * Memory segments obtained in this way are called <em>buffer memory segments</em>. Note that buffer memory segments might
  85  * be backed by native memory (as in the case of native memory segments) or heap memory (as in the case of array memory segments),
  86  * depending on the characteristics of the byte buffer instance the segment is associated with. For instance, a buffer memory
  87  * segment obtained from a byte buffer created with the {@link ByteBuffer#allocateDirect(int)} method will be backed
  88  * by native memory.
  89  *
  90  * <h2>Mapping memory segments from files</h2>
  91  *
  92  * It is also possible to obtain a native memory segment backed by a memory-mapped file using the factory method
  93  * {@link MemorySegment#mapFile(Path, long, long, FileChannel.MapMode, ResourceScope)}. Such native memory segments are
  94  * called <em>mapped memory segments</em>; mapped memory segments are associated with an underlying file descriptor.
  95  * <p>
  96  * Contents of mapped memory segments can be {@linkplain #force() persisted} and {@linkplain #load() loaded} to and from the underlying file;
  97  * these capabilities are suitable replacements for some capabilities in the {@link java.nio.MappedByteBuffer} class.
  98  * Note that, while it is possible to map a segment into a byte buffer (see {@link MemorySegment#asByteBuffer()}),
  99  * and then call e.g. {@link java.nio.MappedByteBuffer#force()} that way, this can only be done when the source segment
 100  * is small enough, due to the size limitation inherent to the ByteBuffer API.
 101  * <p>
 102  * Clients requiring sophisticated, low-level control over mapped memory segments, should consider writing
 103  * custom mapped memory segment factories; using {@link CLinker}, e.g. on Linux, it is possible to call {@code mmap}
 104  * with the desired parameters; the returned address can be easily wrapped into a memory segment, using
 105  * {@link MemoryAddress#ofLong(long)} and {@link MemorySegment#ofAddressNative(MemoryAddress, long, ResourceScope)}.
 106  *
 107  * <h2>Restricted native segments</h2>
 108  *
 109  * Sometimes it is necessary to turn a memory address obtained from native code into a memory segment with
 110  * full spatial, temporal and confinement bounds. To do this, clients can {@link #ofAddressNative(MemoryAddress, long, ResourceScope) obtain}
 111  * a native segment <em>unsafely</em> from a give memory address, by providing the segment size, as well as the segment {@linkplain ResourceScope scope}.
 112  * This is a <a href="package-summary.html#restricted"><em>restricted</em></a> operation and should be used with
 113  * caution: for instance, an incorrect segment size could result in a VM crash when attempting to dereference
 114  * the memory segment.
 115  *
 116  * <h2>Dereference</h2>
 117  *
 118  * A memory segment can be read or written using various methods provided in this class (e.g. {@link #get(ValueLayout.OfInt, long)}).
 119  * Each dereference method takes a {@linkplain jdk.incubator.foreign.ValueLayout value layout}, which specifies the size,
 120  * alignment constraints, byte order as well as the Java type associated with the dereference operation, and an offset.
 121  * For instance, to read an int from a segment, using {@link ByteOrder#nativeOrder() default endianness}, the following code can be used:
 122  * <blockquote><pre>{@code
 123 MemorySegment segment = ...
 124 int value = segment.get(ValueLayout.JAVA_INT, 0);
 125  * }</pre></blockquote>
 126  *
 127  * If the value to be read is stored in memory using {@link ByteOrder#BIG_ENDIAN big-endian} encoding, the dereference operation
 128  * can be expressed as follows:
 129  * <blockquote><pre>{@code
 130 MemorySegment segment = ...
 131 int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0);
 132  * }</pre></blockquote>
 133  *
 134  * For more complex dereference operations (e.g. structured memory access), clients can obtain a <em>memory access var handle</em>,
 135  * that is, a var handle that accepts a segment and, optionally, one or more additional {@code long} coordinates. Memory
 136  * access var handles can be obtained from {@linkplain MemoryLayout#varHandle(MemoryLayout.PathElement...) memory layouts}
 137  * by providing a so called <a href="MemoryLayout.html#layout-paths"><em>layout path</em></a>.
 138  * Alternatively, clients can obtain raw memory access var handles from a given
 139  * {@linkplain MemoryHandles#varHandle(ValueLayout) value layout}, and then adapt it using the var handle combinator
 140  * functions defined in the {@link MemoryHandles} class.
 141  *
 142  * <h2>Lifecycle and confinement</h2>
 143  *
 144  * Memory segments are associated with a resource scope (see {@link ResourceScope}), which can be accessed using
 145  * the {@link #scope()} method. As for all resources associated with a resource scope, a segment cannot be
 146  * accessed after its corresponding scope has been closed. For instance, the following code will result in an
 147  * exception:
 148  * <blockquote><pre>{@code
 149 MemorySegment segment = null;
 150 try (ResourceScope scope = ResourceScope.newConfinedScope()) {
 151     segment = MemorySegment.allocateNative(8, scope);
 152 }
 153 segment.get(ValueLayout.JAVA_LONG, 0); // already closed!
 154  * }</pre></blockquote>
 155  * Additionally, access to a memory segment is subject to the thread-confinement checks enforced by the owning scope; that is,
 156  * if the segment is associated with a shared scope, it can be accessed by multiple threads; if it is associated with a confined
 157  * scope, it can only be accessed by the thread which owns the scope.
 158  * <p>
 159  * Heap and buffer segments are always associated with a <em>global</em>, shared scope. This scope cannot be closed,
 160  * and can be considered as <em>always alive</em>.
 161  *
 162  * <h2>Memory segment views</h2>
 163  *
 164  * Memory segments support <em>views</em>. For instance, it is possible to create an <em>immutable</em> view of a memory segment, as follows:
 165  * <blockquote><pre>{@code
 166 MemorySegment segment = ...
 167 MemorySegment roSegment = segment.asReadOnly();
 168  * }</pre></blockquote>
 169  * It is also possible to create views whose spatial bounds are stricter than the ones of the original segment
 170  * (see {@link MemorySegment#asSlice(long, long)}).
 171  * <p>
 172  * Temporal bounds of the original segment are inherited by the views; that is, when the scope associated with a segment
 173  * is closed, all the views associated with that segment will also be rendered inaccessible.
 174  * <p>
 175  * To allow for interoperability with existing code, a byte buffer view can be obtained from a memory segment
 176  * (see {@link #asByteBuffer()}). This can be useful, for instance, for those clients that want to keep using the
 177  * {@link ByteBuffer} API, but need to operate on large memory segments. Byte buffers obtained in such a way support
 178  * the same spatial and temporal access restrictions associated with the memory segment from which they originated.
 179  *
 180  * <h2>Stream support</h2>
 181  *
 182  * A client might obtain a {@link Stream} from a segment, which can then be used to slice the segment (according to a given
 183  * element layout) and even allow multiple threads to work in parallel on disjoint segment slices
 184  * (to do this, the segment has to be associated with a shared scope). The following code can be used to sum all int
 185  * values in a memory segment in parallel:
 186  *
 187  * <blockquote><pre>{@code
 188 try (ResourceScope scope = ResourceScope.newSharedScope()) {
 189     SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT);
 190     MemorySegment segment = MemorySegment.allocateNative(SEQUENCE_LAYOUT, scope);
 191     int sum = segment.elements(ValueLayout.JAVA_INT).parallel()
 192                            .mapToInt(s -> s.get(ValueLayout.JAVA_INT, 0))
 193                            .sum();
 194 }
 195  * }</pre></blockquote>
 196  *
 197  * @implSpec
 198  * Implementations of this interface are immutable, thread-safe and <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>.
 199  */
 200 public sealed interface MemorySegment extends Addressable permits AbstractMemorySegmentImpl {
 201 
 202     /**
 203      * The base memory address associated with this native memory segment.
 204      * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment.
 205      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
 206      * a thread other than the thread owning that scope.
 207      * @return The base memory address.
 208      */
 209     @Override
 210     MemoryAddress address();
 211 
 212     /**
 213      * Returns a spliterator for this memory segment. The returned spliterator reports {@link Spliterator#SIZED},
 214      * {@link Spliterator#SUBSIZED}, {@link Spliterator#IMMUTABLE}, {@link Spliterator#NONNULL} and {@link Spliterator#ORDERED}
 215      * characteristics.
 216      * <p>
 217      * The returned spliterator splits this segment according to the specified element layout; that is,
 218      * if the supplied layout has size N, then calling {@link Spliterator#trySplit()} will result in a spliterator serving
 219      * approximately {@code S/N/2} elements (depending on whether N is even or not), where {@code S} is the size of
 220      * this segment. As such, splitting is possible as long as {@code S/N >= 2}. The spliterator returns segments that feature the same
 221      * scope as this given segment.
 222      * <p>
 223      * The returned spliterator effectively allows to slice this segment into disjoint sub-segments, which can then
 224      * be processed in parallel by multiple threads.
 225      *
 226      * @param elementLayout the layout to be used for splitting.
 227      * @return the element spliterator for this segment
 228      * @throws IllegalArgumentException if the {@code elementLayout} size is zero, or the segment size modulo the
 229      * {@code elementLayout} size is greater than zero.
 230      */
 231     Spliterator<MemorySegment> spliterator(MemoryLayout elementLayout);
 232 
 233     /**
 234      * Returns a sequential {@code Stream} over disjoint slices (whose size matches that of the specified layout)
 235      * in this segment. Calling this method is equivalent to the following code:
 236      * <blockquote><pre>{@code
 237     StreamSupport.stream(segment.spliterator(elementLayout), false);
 238      * }</pre></blockquote>
 239      *
 240      * @param elementLayout the layout to be used for splitting.
 241      * @return a sequential {@code Stream} over disjoint slices in this segment.
 242      * @throws IllegalArgumentException if the {@code elementLayout} size is zero, or the segment size modulo the
 243      * {@code elementLayout} size is greater than zero.
 244      */
 245     Stream<MemorySegment> elements(MemoryLayout elementLayout);
 246 
 247     /**
 248      * Returns the resource scope associated with this memory segment.
 249      * @return the resource scope associated with this memory segment.
 250      */
 251     ResourceScope scope();
 252 
 253     /**
 254      * The size (in bytes) of this memory segment.
 255      * @return The size (in bytes) of this memory segment.
 256      */
 257     long byteSize();
 258 
 259     /**
 260      * Obtains a new memory segment view whose base address is the same as the base address of this segment plus a given offset,
 261      * and whose new size is specified by the given argument.
 262      *
 263      * @see #asSlice(long)
 264      *
 265      * @param offset The new segment base offset (relative to the current segment base address), specified in bytes.
 266      * @param newSize The new segment size, specified in bytes.
 267      * @return a new memory segment view with updated base/limit addresses.
 268      * @throws IndexOutOfBoundsException if {@code offset < 0}, {@code offset > byteSize()}, {@code newSize < 0}, or {@code newSize > byteSize() - offset}
 269      */
 270     MemorySegment asSlice(long offset, long newSize);
 271 
 272     /**
 273      * Obtains a new memory segment view whose base address is the same as the base address of this segment plus a given offset,
 274      * and whose new size is computed by subtracting the specified offset from this segment size.
 275      * <p>
 276      * Equivalent to the following code:
 277      * <pre>{@code
 278     asSlice(offset, byteSize() - offset);
 279      * }</pre>
 280      *
 281      * @see #asSlice(long, long)
 282      *
 283      * @param offset The new segment base offset (relative to the current segment base address), specified in bytes.
 284      * @return a new memory segment view with updated base/limit addresses.
 285      * @throws IndexOutOfBoundsException if {@code offset < 0}, or {@code offset > byteSize()}.
 286      */
 287     default MemorySegment asSlice(long offset) {
 288         return asSlice(offset, byteSize() - offset);
 289     }
 290 
 291     /**
 292      * Is this segment read-only?
 293      * @return {@code true}, if this segment is read-only.
 294      * @see #asReadOnly()
 295      */
 296     boolean isReadOnly();
 297 
 298     /**
 299      * Obtains a read-only view of this segment. The resulting segment will be identical to this one, but
 300      * attempts to overwrite the contents of the returned segment will cause runtime exceptions.
 301      * @return a read-only view of this segment
 302      * @see #isReadOnly()
 303      */
 304     MemorySegment asReadOnly();
 305 
 306     /**
 307      * Is this a native segment? Returns true if this segment is a native memory segment,
 308      * created using the {@link #allocateNative(long, ResourceScope)} (and related) factory, or a buffer segment
 309      * derived from a direct {@link java.nio.ByteBuffer} using the {@link #ofByteBuffer(ByteBuffer)} factory,
 310      * or if this is a {@linkplain #isMapped() mapped} segment.
 311      * @return {@code true} if this segment is native segment.
 312      */
 313     boolean isNative();
 314 
 315     /**
 316      * Is this a mapped segment? Returns true if this segment is a mapped memory segment,
 317      * created using the {@link #mapFile(Path, long, long, FileChannel.MapMode, ResourceScope)} factory, or a buffer segment
 318      * derived from a {@link java.nio.MappedByteBuffer} using the {@link #ofByteBuffer(ByteBuffer)} factory.
 319      * @return {@code true} if this segment is a mapped segment.
 320      */
 321     boolean isMapped();
 322 
 323     /**
 324      * Returns a slice of this segment that is the overlap between this and
 325      * the provided segment.
 326      *
 327      * <p>Two segments S1 and S2 are said to overlap if it is possible to find
 328      * at least two slices L1 (from S1) and L2 (from S2) that are backed by the
 329      * same memory region. As such, it is not possible for a
 330      * {@link #isNative() native} segment to overlap with a heap segment; in
 331      * this case, or when no overlap occurs, {@code null} is returned.
 332      *
 333      * @param other the segment to test for an overlap with this segment.
 334      * @return a slice of this segment, or {@code null} if no overlap occurs.
 335      */
 336     MemorySegment asOverlappingSlice(MemorySegment other);
 337 
 338     /**
 339      * Returns the offset, in bytes, of the provided segment, relative to this
 340      * segment.
 341      *
 342      * <p>The offset is relative to the base address of this segment and can be
 343      * a negative or positive value. For instance, if both segments are native
 344      * segments, the resulting offset can be computed as follows:
 345      *
 346      * <pre>{@code
 347      * other.baseAddress().toRawLongValue() - segment.baseAddress().toRawLongValue()
 348      * }</pre>
 349      *
 350      * If the segments share the same base address, {@code 0} is returned. If
 351      * {@code other} is a slice of this segment, the offset is always
 352      * {@code 0 <= x < this.byteSize()}.
 353      *
 354      * @param other the segment to retrieve an offset to.
 355      * @return the relative offset, in bytes, of the provided segment.
 356      */
 357     long segmentOffset(MemorySegment other);
 358 
 359     /**
 360      * Fills a value into this memory segment.
 361      * <p>
 362      * More specifically, the given value is filled into each address of this
 363      * segment. Equivalent to (but likely more efficient than) the following code:
 364      *
 365      * <pre>{@code
 366 byteHandle = MemoryLayout.ofSequence(ValueLayout.JAVA_BYTE)
 367          .varHandle(byte.class, MemoryLayout.PathElement.sequenceElement());
 368 for (long l = 0; l < segment.byteSize(); l++) {
 369      byteHandle.set(segment.address(), l, value);
 370 }
 371      * }</pre>
 372      *
 373      * without any regard or guarantees on the ordering of particular memory
 374      * elements being set.
 375      * <p>
 376      * Fill can be useful to initialize or reset the memory of a segment.
 377      *
 378      * @param value the value to fill into this segment
 379      * @return this memory segment
 380      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
 381      * a thread other than the thread owning that scope.
 382      * @throws UnsupportedOperationException if this segment is read-only (see {@link #isReadOnly()}).
 383      */
 384     MemorySegment fill(byte value);
 385 
 386     /**
 387      * Performs an element-wise bulk copy from given source segment to this segment. More specifically, the bytes at
 388      * offset {@code 0} through {@code src.byteSize() - 1} in the source segment are copied into this segment
 389      * at offset {@code 0} through {@code src.byteSize() - 1}.
 390      * <p>
 391      * Calling this method is equivalent to the following code:
 392      * <blockquote><pre>{@code
 393     MemorySegment.copy(src, 0, this, 0, src.byteSize);
 394      * }</pre></blockquote>
 395      * @param src the source segment.
 396      * @throws IndexOutOfBoundsException if {@code src.byteSize() > this.byteSize()}.
 397      * @throws IllegalArgumentException if the element layouts have different sizes, if the source segment size is not
 398      * a multiple of the source element layout size, if the source segment is incompatible with the alignment constraints
 399      * in the source element layout, or if this segment is incompatible with the alignment constraints
 400      * in the destination element layout.
 401      * @throws IllegalStateException if either the scope associated with the source segment or the scope associated
 402      * with this segment have been already closed, or if access occurs from a thread other than the thread owning either
 403      * scopes.
 404      * @throws UnsupportedOperationException if this segment is read-only (see {@link #isReadOnly()}).
 405      * @return this segment.
 406      */
 407     default MemorySegment copyFrom(MemorySegment src) {
 408         MemorySegment.copy(src, 0, this, 0, src.byteSize());
 409         return this;
 410     }
 411 
 412     /**
 413      * Finds and returns the offset, in bytes, of the first mismatch between
 414      * this segment and a given other segment. The offset is relative to the
 415      * {@linkplain #address() base address} of each segment and will be in the
 416      * range of 0 (inclusive) up to the {@linkplain #byteSize() size} (in bytes) of
 417      * the smaller memory segment (exclusive).
 418      * <p>
 419      * If the two segments share a common prefix then the returned offset is
 420      * the length of the common prefix, and it follows that there is a mismatch
 421      * between the two segments at that offset within the respective segments.
 422      * If one segment is a proper prefix of the other, then the returned offset is
 423      * the smallest of the segment sizes, and it follows that the offset is only
 424      * valid for the larger segment. Otherwise, there is no mismatch and {@code
 425      * -1} is returned.
 426      *
 427      * @param other the segment to be tested for a mismatch with this segment
 428      * @return the relative offset, in bytes, of the first mismatch between this
 429      * and the given other segment, otherwise -1 if no mismatch
 430      * @throws IllegalStateException if either the scope associated with this segment or the scope associated
 431      * with the {@code other} segment have been already closed, or if access occurs from a thread other than the thread
 432      * owning either scopes.
 433      */
 434     long mismatch(MemorySegment other);
 435 
 436     /**
 437      * Tells whether the contents of this mapped segment is resident in physical
 438      * memory.
 439      *
 440      * <p> A return value of {@code true} implies that it is highly likely
 441      * that all the data in this segment is resident in physical memory and
 442      * may therefore be accessed without incurring any virtual-memory page
 443      * faults or I/O operations.  A return value of {@code false} does not
 444      * necessarily imply that this segment's content is not resident in physical
 445      * memory.
 446      *
 447      * <p> The returned value is a hint, rather than a guarantee, because the
 448      * underlying operating system may have paged out some of this segment's data
 449      * by the time that an invocation of this method returns.  </p>
 450      *
 451      * @return  {@code true} if it is likely that the contents of this segment
 452      *          is resident in physical memory
 453      *
 454      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
 455      * a thread other than the thread owning that scope.
 456      * @throws UnsupportedOperationException if this segment is not a mapped memory segment, e.g. if
 457      * {@code isMapped() == false}.
 458      */
 459     boolean isLoaded();
 460 
 461     /**
 462      * Loads the contents of this mapped segment into physical memory.
 463      *
 464      * <p> This method makes a best effort to ensure that, when it returns,
 465      * this contents of this segment is resident in physical memory.  Invoking this
 466      * method may cause some number of page faults and I/O operations to
 467      * occur. </p>
 468      *
 469      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
 470      * a thread other than the thread owning that scope.
 471      * @throws UnsupportedOperationException if this segment is not a mapped memory segment, e.g. if
 472      * {@code isMapped() == false}.
 473      */
 474     void load();
 475 
 476     /**
 477      * Unloads the contents of this mapped segment from physical memory.
 478      *
 479      * <p> This method makes a best effort to ensure that the contents of this segment are
 480      * are no longer resident in physical memory. Accessing this segment's contents
 481      * after invoking this method may cause some number of page faults and I/O operations to
 482      * occur (as this segment's contents might need to be paged back in). </p>
 483      *
 484      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
 485      * a thread other than the thread owning that scope.
 486      * @throws UnsupportedOperationException if this segment is not a mapped memory segment, e.g. if
 487      * {@code isMapped() == false}.
 488      */
 489     void unload();
 490 
 491     /**
 492      * Forces any changes made to the contents of this mapped segment to be written to the
 493      * storage device described by the mapped segment's file descriptor.
 494      *
 495      * <p> If the file descriptor associated with this mapped segment resides on a local storage
 496      * device then when this method returns it is guaranteed that all changes
 497      * made to this segment since it was created, or since this method was last
 498      * invoked, will have been written to that device.
 499      *
 500      * <p> If the file descriptor associated with this mapped segment does not reside on a local device then
 501      * no such guarantee is made.
 502      *
 503      * <p> If this segment was not mapped in read/write mode ({@link
 504      * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then
 505      * invoking this method may have no effect. In particular, the
 506      * method has no effect for segments mapped in read-only or private
 507      * mapping modes. This method may or may not have an effect for
 508      * implementation-specific mapping modes.
 509      * </p>
 510      *
 511      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
 512      * a thread other than the thread owning that scope.
 513      * @throws UnsupportedOperationException if this segment is not a mapped memory segment, e.g. if
 514      * {@code isMapped() == false}.
 515      * @throws UncheckedIOException if there is an I/O error writing the contents of this segment to the associated storage device
 516      */
 517     void force();
 518 
 519     /**
 520      * Wraps this segment in a {@link ByteBuffer}. Some properties of the returned buffer are linked to
 521      * the properties of this segment. For instance, if this segment is <em>immutable</em>
 522      * (e.g. the segment is a read-only segment, see {@link #isReadOnly()}), then the resulting buffer is <em>read-only</em>
 523      * (see {@link ByteBuffer#isReadOnly()}). Additionally, if this is a native memory segment, the resulting buffer is
 524      * <em>direct</em> (see {@link ByteBuffer#isDirect()}).
 525      * <p>
 526      * The returned buffer's position (see {@link ByteBuffer#position()}) is initially set to zero, while
 527      * the returned buffer's capacity and limit (see {@link ByteBuffer#capacity()} and {@link ByteBuffer#limit()}, respectively)
 528      * are set to this segment' size (see {@link MemorySegment#byteSize()}). For this reason, a byte buffer cannot be
 529      * returned if this segment' size is greater than {@link Integer#MAX_VALUE}.
 530      * <p>
 531      * The life-cycle of the returned buffer will be tied to that of this segment. That is, accessing the returned buffer
 532      * after the scope associated with this segment has been closed (see {@link ResourceScope#close()}), will throw an {@link IllegalStateException}.
 533      * <p>
 534      * If this segment is associated with a confined scope, calling read/write I/O operations on the resulting buffer
 535      * might result in an unspecified exception being thrown. Examples of such problematic operations are
 536      * {@link java.nio.channels.AsynchronousSocketChannel#read(ByteBuffer)} and
 537      * {@link java.nio.channels.AsynchronousSocketChannel#write(ByteBuffer)}.
 538      * <p>
 539      * Finally, the resulting buffer's byte order is {@link java.nio.ByteOrder#BIG_ENDIAN}; this can be changed using
 540      * {@link ByteBuffer#order(java.nio.ByteOrder)}.
 541      *
 542      * @return a {@link ByteBuffer} view of this memory segment.
 543      * @throws UnsupportedOperationException if this segment cannot be mapped onto a {@link ByteBuffer} instance,
 544      * e.g. because it models a heap-based segment that is not based on a {@code byte[]}), or if its size is greater
 545      * than {@link Integer#MAX_VALUE}.
 546      */
 547     ByteBuffer asByteBuffer();
 548 
 549     /**
 550      * Copy the contents of this memory segment into a fresh byte array.
 551      * @param elementLayout the source element layout. If the byte order associated with the layout is
 552      * different from the native order, a byte swap operation will be performed on each array element.
 553      * @return a fresh byte array copy of this memory segment.
 554      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
 555      * a thread other than the thread owning that scope, or if this segment's contents cannot be copied into a {@link byte[]} instance,
 556      * e.g. its size is greater than {@link Integer#MAX_VALUE}.
 557      */
 558     byte[] toArray(ValueLayout.OfByte elementLayout);
 559 
 560     /**
 561      * Copy the contents of this memory segment into a fresh short array.
 562      * @param elementLayout the source element layout. If the byte order associated with the layout is
 563      * different from the native order, a byte swap operation will be performed on each array element.
 564      * @return a fresh short array copy of this memory segment.
 565      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
 566      * a thread other than the thread owning that scope, or if this segment's contents cannot be copied into a {@link short[]} instance,
 567      * e.g. because {@code byteSize() % 2 != 0}, or {@code byteSize() / 2 > Integer#MAX_VALUE}
 568      */
 569     short[] toArray(ValueLayout.OfShort elementLayout);
 570 
 571     /**
 572      * Copy the contents of this memory segment into a fresh char array.
 573      * @param elementLayout the source element layout. If the byte order associated with the layout is
 574      * different from the native order, a byte swap operation will be performed on each array element.
 575      * @return a fresh char array copy of this memory segment.
 576      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
 577      * a thread other than the thread owning that scope, or if this segment's contents cannot be copied into a {@link char[]} instance,
 578      * e.g. because {@code byteSize() % 2 != 0}, or {@code byteSize() / 2 > Integer#MAX_VALUE}.
 579      */
 580     char[] toArray(ValueLayout.OfChar elementLayout);
 581 
 582     /**
 583      * Copy the contents of this memory segment into a fresh int array.
 584      * @param elementLayout the source element layout. If the byte order associated with the layout is
 585      * different from the native order, a byte swap operation will be performed on each array element.
 586      * @return a fresh int array copy of this memory segment.
 587      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
 588      * a thread other than the thread owning that scope, or if this segment's contents cannot be copied into a {@link int[]} instance,
 589      * e.g. because {@code byteSize() % 4 != 0}, or {@code byteSize() / 4 > Integer#MAX_VALUE}.
 590      */
 591     int[] toArray(ValueLayout.OfInt elementLayout);
 592 
 593     /**
 594      * Copy the contents of this memory segment into a fresh float array.
 595      * @param elementLayout the source element layout. If the byte order associated with the layout is
 596      * different from the native order, a byte swap operation will be performed on each array element.
 597      * @return a fresh float array copy of this memory segment.
 598      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
 599      * a thread other than the thread owning that scope, or if this segment's contents cannot be copied into a {@link float[]} instance,
 600      * e.g. because {@code byteSize() % 4 != 0}, or {@code byteSize() / 4 > Integer#MAX_VALUE}.
 601      */
 602     float[] toArray(ValueLayout.OfFloat elementLayout);
 603 
 604     /**
 605      * Copy the contents of this memory segment into a fresh long array.
 606      * @param elementLayout the source element layout. If the byte order associated with the layout is
 607      * different from the native order, a byte swap operation will be performed on each array element.
 608      * @return a fresh long array copy of this memory segment.
 609      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
 610      * a thread other than the thread owning that scope, or if this segment's contents cannot be copied into a {@link long[]} instance,
 611      * e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer#MAX_VALUE}.
 612      */
 613     long[] toArray(ValueLayout.OfLong elementLayout);
 614 
 615     /**
 616      * Copy the contents of this memory segment into a fresh double array.
 617      * @param elementLayout the source element layout. If the byte order associated with the layout is
 618      * different from the native order, a byte swap operation will be performed on each array element.
 619      * @return a fresh double array copy of this memory segment.
 620      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
 621      * a thread other than the thread owning that scope, or if this segment's contents cannot be copied into a {@link double[]} instance,
 622      * e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer#MAX_VALUE}.
 623      */
 624     double[] toArray(ValueLayout.OfDouble elementLayout);
 625 
 626     /**
 627      * Reads a UTF-8 encoded, null-terminated string from this segment at given offset.
 628      * <p>
 629      * This method always replaces malformed-input and unmappable-character
 630      * sequences with this charset's default replacement string.  The {@link
 631      * java.nio.charset.CharsetDecoder} class should be used when more control
 632      * over the decoding process is required.
 633      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
 634      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
 635      * @return a Java UTF-8 string containing all the bytes read from the given starting address up to (but not including)
 636      * the first {@code '\0'} terminator character (assuming one is found).
 637      * @throws IllegalArgumentException if the size of the native string is greater than the largest string supported by the platform.
 638      * @throws IllegalStateException if the size of the native string is greater than the size of this segment,
 639      * or if the scope associated with this segment has been closed, or if access occurs from a thread other than the thread owning that scope.
 640      */
 641     default String getUtf8String(long offset) {
 642         return SharedUtils.toJavaStringInternal(this, offset);
 643     }
 644 
 645     /**
 646      * Writes a UTF-8 encoded, null-terminated string into this segment at given offset.
 647      * <p>
 648      * This method always replaces malformed-input and unmappable-character
 649      * sequences with this charset's default replacement string.  The {@link
 650      * java.nio.charset.CharsetDecoder} class should be used when more control
 651      * over the decoding process is required.
 652      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
 653      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
 654      * @param str the Java string to be written into this segment.
 655      * @throws IllegalArgumentException if the size of the native string is greater than the largest string supported by the platform.
 656      * @throws IllegalStateException if the size of the native string is greater than the size of this segment,
 657      * or if the scope associated with this segment has been closed, or if access occurs from a thread other than the thread owning that scope.
 658      */
 659     default void setUtf8String(long offset, String str) {
 660         Utils.toCString(str.getBytes(StandardCharsets.UTF_8), SegmentAllocator.prefixAllocator(asSlice(offset)));
 661     }
 662 
 663 
 664     /**
 665      * Creates a new buffer memory segment that models the memory associated with the given byte
 666      * buffer. The segment starts relative to the buffer's position (inclusive)
 667      * and ends relative to the buffer's limit (exclusive).
 668      * <p>
 669      * If the buffer is {@link ByteBuffer#isReadOnly() read-only}, the resulting segment will also be
 670      * {@link ByteBuffer#isReadOnly() read-only}. The scope associated with this segment can either be the
 671      * {@linkplain ResourceScope#globalScope() global} resource scope, in case the buffer has been created independently,
 672      * or some other resource scope, in case the buffer has been obtained using {@link #asByteBuffer()}.
 673      * <p>
 674      * The resulting memory segment keeps a reference to the backing buffer, keeping it <em>reachable</em>.
 675      *
 676      * @param bb the byte buffer backing the buffer memory segment.
 677      * @return a new buffer memory segment.
 678      */
 679     static MemorySegment ofByteBuffer(ByteBuffer bb) {
 680         return AbstractMemorySegmentImpl.ofBuffer(bb);
 681     }
 682 
 683     /**
 684      * Creates a new array memory segment that models the memory associated with a given heap-allocated byte array.
 685      * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
 686      *
 687      * @param arr the primitive array backing the array memory segment.
 688      * @return a new array memory segment.
 689      */
 690     static MemorySegment ofArray(byte[] arr) {
 691         return HeapMemorySegmentImpl.OfByte.fromArray(arr);
 692     }
 693 
 694     /**
 695      * Creates a new array memory segment that models the memory associated with a given heap-allocated char array.
 696      * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
 697      *
 698      * @param arr the primitive array backing the array memory segment.
 699      * @return a new array memory segment.
 700      */
 701     static MemorySegment ofArray(char[] arr) {
 702         return HeapMemorySegmentImpl.OfChar.fromArray(arr);
 703     }
 704 
 705     /**
 706      * Creates a new array memory segment that models the memory associated with a given heap-allocated short array.
 707      * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
 708      *
 709      * @param arr the primitive array backing the array memory segment.
 710      * @return a new array memory segment.
 711      */
 712     static MemorySegment ofArray(short[] arr) {
 713         return HeapMemorySegmentImpl.OfShort.fromArray(arr);
 714     }
 715 
 716     /**
 717      * Creates a new array memory segment that models the memory associated with a given heap-allocated int array.
 718      * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
 719      *
 720      * @param arr the primitive array backing the array memory segment.
 721      * @return a new array memory segment.
 722      */
 723     static MemorySegment ofArray(int[] arr) {
 724         return HeapMemorySegmentImpl.OfInt.fromArray(arr);
 725     }
 726 
 727     /**
 728      * Creates a new array memory segment that models the memory associated with a given heap-allocated float array.
 729      * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
 730      *
 731      * @param arr the primitive array backing the array memory segment.
 732      * @return a new array memory segment.
 733      */
 734     static MemorySegment ofArray(float[] arr) {
 735         return HeapMemorySegmentImpl.OfFloat.fromArray(arr);
 736     }
 737 
 738     /**
 739      * Creates a new array memory segment that models the memory associated with a given heap-allocated long array.
 740      * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
 741      *
 742      * @param arr the primitive array backing the array memory segment.
 743      * @return a new array memory segment.
 744      */
 745     static MemorySegment ofArray(long[] arr) {
 746         return HeapMemorySegmentImpl.OfLong.fromArray(arr);
 747     }
 748 
 749     /**
 750      * Creates a new array memory segment that models the memory associated with a given heap-allocated double array.
 751      * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
 752      *
 753      * @param arr the primitive array backing the array memory segment.
 754      * @return a new array memory segment.
 755      */
 756     static MemorySegment ofArray(double[] arr) {
 757         return HeapMemorySegmentImpl.OfDouble.fromArray(arr);
 758     }
 759 
 760 
 761     /**
 762      * Creates a new native memory segment with given size and resource scope, and whose base address is this address.
 763      * This method can be useful when interacting with custom
 764      * native memory sources (e.g. custom allocators), where an address to some
 765      * underlying memory region is typically obtained from native code (often as a plain {@code long} value).
 766      * The returned segment is not read-only (see {@link MemorySegment#isReadOnly()}), and is associated with the
 767      * provided resource scope.
 768      * <p>
 769      * Clients should ensure that the address and bounds refers to a valid region of memory that is accessible for reading and,
 770      * if appropriate, writing; an attempt to access an invalid memory location from Java code will either return an arbitrary value,
 771      * have no visible effect, or cause an unspecified exception to be thrown.
 772      * <p>
 773      * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
 774      * Restricted methods are unsafe, and, if used incorrectly, their use might crash
 775      * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on
 776      * restricted methods, and use safe and supported functionalities, where possible.
 777      *
 778      *
 779      * @param address the returned segment's base address.
 780      * @param bytesSize the desired size.
 781      * @param scope the native segment scope.
 782      * @return a new native memory segment with given base address, size and scope.
 783      * @throws IllegalArgumentException if {@code bytesSize <= 0}.
 784      * @throws IllegalStateException if the provided scope has been already closed,
 785      * or if access occurs from a thread other than the thread owning the scope.
 786      * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option
 787      * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or
 788      * {@code ALL-UNNAMED} in case {@code M} is an unnamed module.
 789      */
 790     @CallerSensitive
 791     static MemorySegment ofAddressNative(MemoryAddress address, long bytesSize, ResourceScope scope) {
 792         Reflection.ensureNativeAccess(Reflection.getCallerClass());
 793         Objects.requireNonNull(address);
 794         Objects.requireNonNull(scope);
 795         if (bytesSize <= 0) {
 796             throw new IllegalArgumentException("Invalid size : " + bytesSize);
 797         }
 798         return NativeMemorySegmentImpl.makeNativeSegmentUnchecked(address, bytesSize, (ResourceScopeImpl)scope);
 799     }
 800 
 801     /**
 802      * Creates a new native memory segment that models a newly allocated block of off-heap memory with given layout
 803      * and resource scope. A client is responsible make sure that the resource scope associated with the returned segment is closed
 804      * when the segment is no longer in use. Failure to do so will result in off-heap memory leaks.
 805      * <p>
 806      * This is equivalent to the following code:
 807      * <blockquote><pre>{@code
 808     allocateNative(layout.bytesSize(), layout.bytesAlignment(), scope);
 809      * }</pre></blockquote>
 810      * <p>
 811      * The block of off-heap memory associated with the returned native memory segment is initialized to zero.
 812      *
 813      * @param layout the layout of the off-heap memory block backing the native memory segment.
 814      * @param scope the segment scope.
 815      * @return a new native memory segment.
 816      * @throws IllegalArgumentException if the specified layout has illegal size or alignment constraint.
 817      * @throws IllegalStateException if {@code scope} has been already closed, or if access occurs from a thread other
 818      * than the thread owning {@code scope}.
 819      */
 820     static MemorySegment allocateNative(MemoryLayout layout, ResourceScope scope) {
 821         Objects.requireNonNull(scope);
 822         Objects.requireNonNull(layout);
 823         return allocateNative(layout.byteSize(), layout.byteAlignment(), scope);
 824     }
 825 
 826     /**
 827      * Creates a new native memory segment that models a newly allocated block of off-heap memory with given size (in bytes)
 828      * and resource scope. A client is responsible make sure that the resource scope associated with the returned segment is closed
 829      * when the segment is no longer in use. Failure to do so will result in off-heap memory leaks.
 830      * <p>
 831      * This is equivalent to the following code:
 832      * <blockquote><pre>{@code
 833     allocateNative(bytesSize, 1, scope);
 834      * }</pre></blockquote>
 835      * <p>
 836      * The block of off-heap memory associated with the returned native memory segment is initialized to zero.
 837      *
 838      * @param bytesSize the size (in bytes) of the off-heap memory block backing the native memory segment.
 839      * @param scope the segment scope.
 840      * @return a new native memory segment.
 841      * @throws IllegalArgumentException if {@code bytesSize <= 0}.
 842      * @throws IllegalStateException if {@code scope} has been already closed, or if access occurs from a thread other
 843      * than the thread owning {@code scope}.
 844      */
 845     static MemorySegment allocateNative(long bytesSize, ResourceScope scope) {
 846         return allocateNative(bytesSize, 1, scope);
 847     }
 848 
 849     /**
 850      * Creates a new native memory segment that models a newly allocated block of off-heap memory with given size
 851      * (in bytes), alignment constraint (in bytes) and resource scope. A client is responsible make sure that the resource
 852      * scope associated with the returned segment is closed when the segment is no longer in use.
 853      * Failure to do so will result in off-heap memory leaks.
 854      * <p>
 855      * The block of off-heap memory associated with the returned native memory segment is initialized to zero.
 856      *
 857      * @param bytesSize the size (in bytes) of the off-heap memory block backing the native memory segment.
 858      * @param alignmentBytes the alignment constraint (in bytes) of the off-heap memory block backing the native memory segment.
 859      * @param scope the segment scope.
 860      * @return a new native memory segment.
 861      * @throws IllegalArgumentException if {@code bytesSize <= 0}, {@code alignmentBytes <= 0}, or if {@code alignmentBytes}
 862      * is not a power of 2.
 863      * @throws IllegalStateException if {@code scope} has been already closed, or if access occurs from a thread other
 864      * than the thread owning {@code scope}.
 865      */
 866     static MemorySegment allocateNative(long bytesSize, long alignmentBytes, ResourceScope scope) {
 867         Objects.requireNonNull(scope);
 868         if (bytesSize <= 0) {
 869             throw new IllegalArgumentException("Invalid allocation size : " + bytesSize);
 870         }
 871 
 872         if (alignmentBytes <= 0 ||
 873                 ((alignmentBytes & (alignmentBytes - 1)) != 0L)) {
 874             throw new IllegalArgumentException("Invalid alignment constraint : " + alignmentBytes);
 875         }
 876 
 877         return NativeMemorySegmentImpl.makeNativeSegment(bytesSize, alignmentBytes, (ResourceScopeImpl) scope);
 878     }
 879 
 880     /**
 881      * Creates a new mapped memory segment that models a memory-mapped region of a file from a given path.
 882      * <p>
 883      * If the specified mapping mode is {@linkplain FileChannel.MapMode#READ_ONLY READ_ONLY}, the resulting segment
 884      * will be read-only (see {@link #isReadOnly()}).
 885      * <p>
 886      * The content of a mapped memory segment can change at any time, for example
 887      * if the content of the corresponding region of the mapped file is changed by
 888      * this (or another) program.  Whether such changes occur, and when they
 889      * occur, is operating-system dependent and therefore unspecified.
 890      * <p>
 891      * All or part of a mapped memory segment may become
 892      * inaccessible at any time, for example if the backing mapped file is truncated.  An
 893      * attempt to access an inaccessible region of a mapped memory segment will not
 894      * change the segment's content and will cause an unspecified exception to be
 895      * thrown either at the time of the access or at some later time.  It is
 896      * therefore strongly recommended that appropriate precautions be taken to
 897      * avoid the manipulation of a mapped file by this (or another) program, except to read or write
 898      * the file's content.
 899      *
 900      * @implNote When obtaining a mapped segment from a newly created file, the initialization state of the contents of the block
 901      * of mapped memory associated with the returned mapped memory segment is unspecified and should not be relied upon.
 902      *
 903      * @param path the path to the file to memory map.
 904      * @param bytesOffset the offset (expressed in bytes) within the file at which the mapped segment is to start.
 905      * @param bytesSize the size (in bytes) of the mapped memory backing the memory segment.
 906      * @param mapMode a file mapping mode, see {@link FileChannel#map(FileChannel.MapMode, long, long)}; the mapping mode
 907      *                might affect the behavior of the returned memory mapped segment (see {@link #force()}).
 908      * @param scope the segment scope.
 909      * @return a new mapped memory segment.
 910      * @throws IllegalArgumentException if {@code bytesOffset < 0}, {@code bytesSize < 0}, or if {@code path} is not associated
 911      * with the default file system.
 912      * @throws IllegalStateException if {@code scope} has been already closed, or if access occurs from a thread other
 913      * than the thread owning {@code scope}.
 914      * @throws UnsupportedOperationException if an unsupported map mode is specified.
 915      * @throws IOException if the specified path does not point to an existing file, or if some other I/O error occurs.
 916      * @throws  SecurityException If a security manager is installed, and it denies an unspecified permission required by the implementation.
 917      * In the case of the default provider, the {@link SecurityManager#checkRead(String)} method is invoked to check
 918      * read access if the file is opened for reading. The {@link SecurityManager#checkWrite(String)} method is invoked to check
 919      * write access if the file is opened for writing.
 920      */
 921     static MemorySegment mapFile(Path path, long bytesOffset, long bytesSize, FileChannel.MapMode mapMode, ResourceScope scope) throws IOException {
 922         Objects.requireNonNull(scope);
 923         return MappedMemorySegmentImpl.makeMappedSegment(path, bytesOffset, bytesSize, mapMode, (ResourceScopeImpl) scope);
 924     }
 925 
 926     /**
 927      * Performs a bulk copy from source segment to destination segment. More specifically, the bytes at offset
 928      * {@code srcOffset} through {@code srcOffset + bytes - 1} in the source segment are copied into the destination
 929      * segment at offset {@code dstOffset} through {@code dstOffset + bytes - 1}.
 930      * <p>
 931      * If the source segment overlaps with this segment, then the copying is performed as if the bytes at
 932      * offset {@code srcOffset} through {@code srcOffset + bytes - 1} in the source segment were first copied into a
 933      * temporary segment with size {@code bytes}, and then the contents of the temporary segment were copied into
 934      * the destination segment at offset {@code dstOffset} through {@code dstOffset + bytes - 1}.
 935      * <p>
 936      * The result of a bulk copy is unspecified if, in the uncommon case, the source segment and the destination segment
 937      * do not overlap, but refer to overlapping regions of the same backing storage using different addresses.
 938      * For example, this may occur if the same file is {@linkplain MemorySegment#mapFile mapped} to two segments.
 939      * <p>
 940      * Calling this method is equivalent to the following code:
 941      * <blockquote><pre>{@code
 942     MemorySegment.copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes);
 943      * }</pre></blockquote>
 944      * @param srcSegment the source segment.
 945      * @param srcOffset the starting offset, in bytes, of the source segment.
 946      * @param dstSegment the destination segment.
 947      * @param dstOffset the starting offset, in bytes, of the destination segment.
 948      * @param bytes the number of bytes to be copied.
 949      * @throws IllegalStateException if either the scope associated with the source segment or the scope associated
 950      * with the destination segment have been already closed, or if access occurs from a thread other than the thread
 951      * owning either scopes.
 952      * @throws IndexOutOfBoundsException if {@code srcOffset + bytes > srcSegment.byteSize()} or if
 953      * {@code dstOffset + bytes > dstSegment.byteSize()}, or if either {@code srcOffset}, {@code dstOffset}
 954      * or {@code bytes} are {@code < 0}.
 955      * @throws UnsupportedOperationException if the destination segment is read-only (see {@link #isReadOnly()}).
 956      */
 957     @ForceInline
 958     static void copy(MemorySegment srcSegment, long srcOffset, MemorySegment dstSegment, long dstOffset, long bytes) {
 959         copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes);
 960     }
 961 
 962     /**
 963      * Performs a bulk copy from source segment to destination segment. More specifically, if {@code S} is the byte size
 964      * of the element layouts, the bytes at offset {@code srcOffset} through {@code srcOffset + (elementCount * S) - 1}
 965      * in the source segment are copied into the destination segment at offset {@code dstOffset} through {@code dstOffset + (elementCount * S) - 1}.
 966      * <p>
 967      * The copy occurs in an element-wise fashion: the bytes in the source segment are interpreted as a sequence of elements
 968      * whose layout is {@code srcElementLayout}, whereas the bytes in the destination segment are interpreted as a sequence of
 969      * elements whose layout is {@code dstElementLayout}. Both element layouts must have same size {@code S}.
 970      * If the byte order of the two element layouts differ, the bytes corresponding to each element to be copied
 971      * are swapped accordingly during the copy operation.
 972      * <p>
 973      * If the source segment overlaps with this segment, then the copying is performed as if the bytes at
 974      * offset {@code srcOffset} through {@code srcOffset + (elementCount * S) - 1} in the source segment were first copied into a
 975      * temporary segment with size {@code bytes}, and then the contents of the temporary segment were copied into
 976      * the destination segment at offset {@code dstOffset} through {@code dstOffset + (elementCount * S) - 1}.
 977      * <p>
 978      * The result of a bulk copy is unspecified if, in the uncommon case, the source segment and the destination segment
 979      * do not overlap, but refer to overlapping regions of the same backing storage using different addresses.
 980      * For example, this may occur if the same file is {@linkplain MemorySegment#mapFile mapped} to two segments.
 981      * @param srcSegment the source segment.
 982      * @param srcElementLayout the element layout associated with the source segment.
 983      * @param srcOffset the starting offset, in bytes, of the source segment.
 984      * @param dstSegment the destination segment.
 985      * @param dstElementLayout the element layout associated with the destination segment.
 986      * @param dstOffset the starting offset, in bytes, of the destination segment.
 987      * @param elementCount the number of elements to be copied.
 988      * @throws IllegalArgumentException if the element layouts have different sizes, if the source offset is incompatible
 989      * with the alignment constraints in the source element layout, or if the destination offset is incompatible with the
 990      * alignment constraints in the destination element layout.
 991      * @throws IllegalStateException if either the scope associated with the source segment or the scope associated
 992      * with the destination segment have been already closed, or if access occurs from a thread other than the thread
 993      * owning either scopes.
 994      * @throws IndexOutOfBoundsException if {@code srcOffset + (elementCount * S) > srcSegment.byteSize()} or if
 995      * {@code dstOffset + (elementCount * S) > dstSegment.byteSize()}, where {@code S} is the byte size
 996      * of the element layouts, or if either {@code srcOffset}, {@code dstOffset} or {@code elementCount} are {@code < 0}.
 997      * @throws UnsupportedOperationException if the destination segment is read-only (see {@link #isReadOnly()}).
 998      */
 999     @ForceInline
1000     static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long srcOffset, MemorySegment dstSegment,
1001                      ValueLayout dstElementLayout, long dstOffset, long elementCount) {
1002         Objects.requireNonNull(srcSegment);
1003         Objects.requireNonNull(srcElementLayout);
1004         Objects.requireNonNull(dstSegment);
1005         Objects.requireNonNull(dstElementLayout);
1006         AbstractMemorySegmentImpl srcImpl = (AbstractMemorySegmentImpl)srcSegment;
1007         AbstractMemorySegmentImpl dstImpl = (AbstractMemorySegmentImpl)dstSegment;
1008         if (srcElementLayout.byteSize() != dstElementLayout.byteSize()) {
1009             throw new IllegalArgumentException("Source and destination layouts must have same sizes");
1010         }
1011         if (srcOffset % srcElementLayout.byteAlignment() != 0) {
1012             throw new IllegalArgumentException("Source segment incompatible with alignment constraints");
1013         }
1014         if (dstOffset % dstElementLayout.byteAlignment() != 0) {
1015             throw new IllegalArgumentException("Target segment incompatible with alignment constraints");
1016         }
1017         long size = elementCount * srcElementLayout.byteSize();
1018         srcImpl.checkAccess(srcOffset, size, true);
1019         dstImpl.checkAccess(dstOffset, size, false);
1020         if (srcElementLayout.byteSize() == 1 || srcElementLayout.order() == dstElementLayout.order()) {
1021             ScopedMemoryAccess.getScopedMemoryAccess().copyMemory(srcImpl.scope(), dstImpl.scope(),
1022                     srcImpl.unsafeGetBase(), srcImpl.unsafeGetOffset() + srcOffset,
1023                     dstImpl.unsafeGetBase(), dstImpl.unsafeGetOffset() + dstOffset, size);
1024         } else {
1025             ScopedMemoryAccess.getScopedMemoryAccess().copySwapMemory(srcImpl.scope(), dstImpl.scope(),
1026                     srcImpl.unsafeGetBase(), srcImpl.unsafeGetOffset() + srcOffset,
1027                     dstImpl.unsafeGetBase(), dstImpl.unsafeGetOffset() + dstOffset, size, srcElementLayout.byteSize());
1028         }
1029     }
1030 
1031     /**
1032      * Reads a byte from this segment and offset with given layout.
1033      *
1034      * @param layout the layout of the memory region to be read.
1035      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1036      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
1037      * @return a byte value read from this address.
1038      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1039      * a thread other than the thread owning that scope.
1040      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1041      * memory segment.
1042      */
1043     @ForceInline
1044     default byte get(ValueLayout.OfByte layout, long offset) {
1045         return (byte)layout.accessHandle().get(this, offset);
1046     }
1047 
1048     /**
1049      * Writes a byte to this segment and offset with given layout.
1050      *
1051      * @param layout the layout of the memory region to be written.
1052      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1053      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
1054      * @param value the byte value to be written.
1055      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1056      * a thread other than the thread owning that scope.
1057      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1058      */
1059     @ForceInline
1060     default void set(ValueLayout.OfByte layout, long offset, byte value) {
1061         layout.accessHandle().set(this, offset, value);
1062     }
1063 
1064     /**
1065      * Reads a boolean from this segment and offset with given layout.
1066      *
1067      * @param layout the layout of the memory region to be read.
1068      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1069      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
1070      * @return a boolean value read from this address.
1071      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1072      * a thread other than the thread owning that scope.
1073      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1074      * memory segment.
1075      */
1076     @ForceInline
1077     default boolean get(ValueLayout.OfBoolean layout, long offset) {
1078         return (boolean)layout.accessHandle().get(this, offset);
1079     }
1080 
1081     /**
1082      * Writes a boolean to this segment and offset with given layout.
1083      *
1084      * @param layout the layout of the memory region to be written.
1085      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1086      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
1087      * @param value the byte value to be written.
1088      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1089      * a thread other than the thread owning that scope.
1090      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1091      */
1092     @ForceInline
1093     default void set(ValueLayout.OfBoolean layout, long offset, boolean value) {
1094         layout.accessHandle().set(this, offset, value);
1095     }
1096 
1097     /**
1098      * Reads a char from this segment and offset with given layout.
1099      *
1100      * @param layout the layout of the memory region to be read.
1101      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1102      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
1103      * @return a char value read from this address.
1104      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1105      * a thread other than the thread owning that scope.
1106      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1107      * memory segment.
1108      */
1109     @ForceInline
1110     default char get(ValueLayout.OfChar layout, long offset) {
1111         return (char)layout.accessHandle().get(this, offset);
1112     }
1113 
1114     /**
1115      * Writes a char to this segment and offset with given layout.
1116      *
1117      * @param layout the layout of the memory region to be written.
1118      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1119      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
1120      * @param value the byte value to be written.
1121      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1122      * a thread other than the thread owning that scope.
1123      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1124      */
1125     @ForceInline
1126     default void set(ValueLayout.OfChar layout, long offset, char value) {
1127         layout.accessHandle().set(this, offset, value);
1128     }
1129 
1130     /**
1131      * Reads a short from this segment and offset with given layout.
1132      *
1133      * @param layout the layout of the memory region to be read.
1134      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1135      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
1136      * @return a short value read from this address.
1137      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1138      * a thread other than the thread owning that scope.
1139      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1140      * memory segment.
1141      */
1142     @ForceInline
1143     default short get(ValueLayout.OfShort layout, long offset) {
1144         return (short)layout.accessHandle().get(this, offset);
1145     }
1146 
1147     /**
1148      * Writes a short to this segment and offset with given layout.
1149      *
1150      * @param layout the layout of the memory region to be written.
1151      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1152      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
1153      * @param value the byte value to be written.
1154      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1155      * a thread other than the thread owning that scope.
1156      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1157      */
1158     @ForceInline
1159     default void set(ValueLayout.OfShort layout, long offset, short value) {
1160         layout.accessHandle().set(this, offset, value);
1161     }
1162 
1163     /**
1164      * Reads an int from this segment and offset with given layout.
1165      *
1166      * @param layout the layout of the memory region to be read.
1167      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1168      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
1169      * @return an int value read from this address.
1170      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1171      * a thread other than the thread owning that scope.
1172      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1173      * memory segment.
1174      */
1175     @ForceInline
1176     default int get(ValueLayout.OfInt layout, long offset) {
1177         return (int)layout.accessHandle().get(this, offset);
1178     }
1179 
1180     /**
1181      * Writes an int to this segment and offset with given layout.
1182      *
1183      * @param layout the layout of the memory region to be written.
1184      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1185      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
1186      * @param value the byte value to be written.
1187      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1188      * a thread other than the thread owning that scope.
1189      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1190      */
1191     @ForceInline
1192     default void set(ValueLayout.OfInt layout, long offset, int value) {
1193         layout.accessHandle().set(this, offset, value);
1194     }
1195 
1196     /**
1197      * Reads a float from this segment and offset with given layout.
1198      *
1199      * @param layout the layout of the memory region to be read.
1200      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1201      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
1202      * @return a float value read from this address.
1203      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1204      * a thread other than the thread owning that scope.
1205      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1206      * memory segment.
1207      */
1208     @ForceInline
1209     default float get(ValueLayout.OfFloat layout, long offset) {
1210         return (float)layout.accessHandle().get(this, offset);
1211     }
1212 
1213     /**
1214      * Writes a float to this segment and offset with given layout.
1215      *
1216      * @param layout the layout of the memory region to be written.
1217      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1218      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
1219      * @param value the byte value to be written.
1220      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1221      * a thread other than the thread owning that scope.
1222      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1223      */
1224     @ForceInline
1225     default void set(ValueLayout.OfFloat layout, long offset, float value) {
1226         layout.accessHandle().set(this, offset, value);
1227     }
1228 
1229     /**
1230      * Reads a long from this segment and offset with given layout.
1231      *
1232      * @param layout the layout of the memory region to be read.
1233      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1234      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
1235      * @return a long value read from this address.
1236      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1237      * a thread other than the thread owning that scope.
1238      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1239      * memory segment.
1240      */
1241     @ForceInline
1242     default long get(ValueLayout.OfLong layout, long offset) {
1243         return (long)layout.accessHandle().get(this, offset);
1244     }
1245 
1246     /**
1247      * Writes a long to this segment and offset with given layout.
1248      *
1249      * @param layout the layout of the memory region to be written.
1250      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1251      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
1252      * @param value the byte value to be written.
1253      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1254      * a thread other than the thread owning that scope.
1255      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1256      */
1257     @ForceInline
1258     default void set(ValueLayout.OfLong layout, long offset, long value) {
1259         layout.accessHandle().set(this, offset, value);
1260     }
1261 
1262     /**
1263      * Reads a double from this segment and offset with given layout.
1264      *
1265      * @param layout the layout of the memory region to be read.
1266      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1267      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
1268      * @return a double value read from this address.
1269      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1270      * a thread other than the thread owning that scope.
1271      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1272      * memory segment.
1273      */
1274     @ForceInline
1275     default double get(ValueLayout.OfDouble layout, long offset) {
1276         return (double)layout.accessHandle().get(this, offset);
1277     }
1278 
1279     /**
1280      * Writes a double to this segment and offset with given layout.
1281      *
1282      * @param layout the layout of the memory region to be written.
1283      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1284      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
1285      * @param value the byte value to be written.
1286      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1287      * a thread other than the thread owning that scope.
1288      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1289      */
1290     @ForceInline
1291     default void set(ValueLayout.OfDouble layout, long offset, double value) {
1292         layout.accessHandle().set(this, offset, value);
1293     }
1294 
1295     /**
1296      * Reads an address from this segment and offset with given layout.
1297      *
1298      * @param layout the layout of the memory region to be read.
1299      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1300      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
1301      * @return an address value read from this address.
1302      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1303      * a thread other than the thread owning that scope.
1304      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1305      * memory segment.
1306      */
1307     @ForceInline
1308     default MemoryAddress get(ValueLayout.OfAddress layout, long offset) {
1309         return (MemoryAddress)layout.accessHandle().get(this, offset);
1310     }
1311 
1312     /**
1313      * Writes an address to this segment and offset with given layout.
1314      *
1315      * @param layout the layout of the memory region to be written.
1316      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1317      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
1318      * @param value the byte value to be written.
1319      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1320      * a thread other than the thread owning that scope.
1321      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1322      */
1323     @ForceInline
1324     default void set(ValueLayout.OfAddress layout, long offset, Addressable value) {
1325         layout.accessHandle().set(this, offset, value.address());
1326     }
1327 
1328     /**
1329      * Reads a char from this segment and index, scaled by given layout size.
1330      *
1331      * @param layout the layout of the memory region to be read.
1332      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1333      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
1334      * @return a char value read from this address.
1335      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1336      * a thread other than the thread owning that scope.
1337      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1338      * memory segment.
1339      */
1340     @ForceInline
1341     default char getAtIndex(ValueLayout.OfChar layout, long index) {
1342         return (char)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize()));
1343     }
1344 
1345     /**
1346      * Writes a char to this segment and index, scaled by given layout size.
1347      *
1348      * @param layout the layout of the memory region to be written.
1349      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1350      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
1351      * @param value the byte value to be written.
1352      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1353      * a thread other than the thread owning that scope.
1354      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1355      */
1356     @ForceInline
1357     default void setAtIndex(ValueLayout.OfChar layout, long index, char value) {
1358         layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value);
1359     }
1360 
1361     /**
1362      * Reads a short from this segment and index, scaled by given layout size.
1363      *
1364      * @param layout the layout of the memory region to be read.
1365      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1366      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
1367      * @return a short value read from this address.
1368      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1369      * a thread other than the thread owning that scope.
1370      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1371      * memory segment.
1372      */
1373     @ForceInline
1374     default short getAtIndex(ValueLayout.OfShort layout, long index) {
1375         return (short)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize()));
1376     }
1377 
1378     /**
1379      * Writes a short to this segment and index, scaled by given layout size.
1380      *
1381      * @param layout the layout of the memory region to be written.
1382      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1383      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
1384      * @param value the byte value to be written.
1385      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1386      * a thread other than the thread owning that scope.
1387      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1388      */
1389     @ForceInline
1390     default void setAtIndex(ValueLayout.OfShort layout, long index, short value) {
1391         layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value);
1392     }
1393 
1394     /**
1395      * Reads an int from this segment and index, scaled by given layout size.
1396      *
1397      * @param layout the layout of the memory region to be read.
1398      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1399      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
1400      * @return an int value read from this address.
1401      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1402      * a thread other than the thread owning that scope.
1403      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1404      * memory segment.
1405      */
1406     @ForceInline
1407     default int getAtIndex(ValueLayout.OfInt layout, long index) {
1408         return (int)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize()));
1409     }
1410 
1411     /**
1412      * Writes an int to this segment and index, scaled by given layout size.
1413      *
1414      * @param layout the layout of the memory region to be written.
1415      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1416      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
1417      * @param value the byte value to be written.
1418      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1419      * a thread other than the thread owning that scope.
1420      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1421      */
1422     @ForceInline
1423     default void setAtIndex(ValueLayout.OfInt layout, long index, int value) {
1424         layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value);
1425     }
1426 
1427     /**
1428      * Reads a float from this segment and index, scaled by given layout size.
1429      *
1430      * @param layout the layout of the memory region to be read.
1431      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1432      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
1433      * @return a float value read from this address.
1434      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1435      * a thread other than the thread owning that scope.
1436      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1437      * memory segment.
1438      */
1439     @ForceInline
1440     default float getAtIndex(ValueLayout.OfFloat layout, long index) {
1441         return (float)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize()));
1442     }
1443 
1444     /**
1445      * Writes a float to this segment and index, scaled by given layout size.
1446      *
1447      * @param layout the layout of the memory region to be written.
1448      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1449      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
1450      * @param value the byte value to be written.
1451      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1452      * a thread other than the thread owning that scope.
1453      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1454      */
1455     @ForceInline
1456     default void setAtIndex(ValueLayout.OfFloat layout, long index, float value) {
1457         layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value);
1458     }
1459 
1460     /**
1461      * Reads a long from this segment and index, scaled by given layout size.
1462      *
1463      * @param layout the layout of the memory region to be read.
1464      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1465      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
1466      * @return a long value read from this address.
1467      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1468      * a thread other than the thread owning that scope.
1469      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1470      * memory segment.
1471      */
1472     @ForceInline
1473     default long getAtIndex(ValueLayout.OfLong layout, long index) {
1474         return (long)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize()));
1475     }
1476 
1477     /**
1478      * Writes a long to this segment and index, scaled by given layout size.
1479      *
1480      * @param layout the layout of the memory region to be written.
1481      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1482      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
1483      * @param value the byte value to be written.
1484      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1485      * a thread other than the thread owning that scope.
1486      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1487      */
1488     @ForceInline
1489     default void setAtIndex(ValueLayout.OfLong layout, long index, long value) {
1490         layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value);
1491     }
1492 
1493     /**
1494      * Reads a double from this segment and index, scaled by given layout size.
1495      *
1496      * @param layout the layout of the memory region to be read.
1497      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1498      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
1499      * @return a double value read from this address.
1500      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1501      * a thread other than the thread owning that scope.
1502      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1503      * memory segment.
1504      */
1505     @ForceInline
1506     default double getAtIndex(ValueLayout.OfDouble layout, long index) {
1507         return (double)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize()));
1508     }
1509 
1510     /**
1511      * Writes a double to this segment and index, scaled by given layout size.
1512      *
1513      * @param layout the layout of the memory region to be written.
1514      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1515      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
1516      * @param value the byte value to be written.
1517      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1518      * a thread other than the thread owning that scope.
1519      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1520      */
1521     @ForceInline
1522     default void setAtIndex(ValueLayout.OfDouble layout, long index, double value) {
1523         layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value);
1524     }
1525 
1526     /**
1527      * Reads an address from this segment and index, scaled by given layout size.
1528      *
1529      * @param layout the layout of the memory region to be read.
1530      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1531      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
1532      * @return an address value read from this address.
1533      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1534      * a thread other than the thread owning that scope.
1535      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1536      * memory segment.
1537      */
1538     @ForceInline
1539     default MemoryAddress getAtIndex(ValueLayout.OfAddress layout, long index) {
1540         return (MemoryAddress)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize()));
1541     }
1542 
1543     /**
1544      * Writes an address to this segment and index, scaled by given layout size.
1545      *
1546      * @param layout the layout of the memory region to be written.
1547      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
1548      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
1549      * @param value the byte value to be written.
1550      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
1551      * a thread other than the thread owning that scope.
1552      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
1553      */
1554     @ForceInline
1555     default void setAtIndex(ValueLayout.OfAddress layout, long index, Addressable value) {
1556         layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value.address());
1557     }
1558 
1559 
1560     /**
1561      * Copies a number of elements from a source segment to a destination array,
1562      * starting at a given segment offset (expressed in bytes), and a given array index, using the given source element layout.
1563      * Supported array types are {@code byte[]}, {@code char[]},{@code short[]},{@code int[]},{@code float[]},{@code long[]} and {@code double[]}.
1564      * @param srcSegment the source segment.
1565      * @param srcLayout the source element layout. If the byte order associated with the layout is
1566      * different from the native order, a byte swap operation will be performed on each array element.
1567      * @param srcOffset the starting offset, in bytes, of the source segment.
1568      * @param dstArray the destination array.
1569      * @param dstIndex the starting index of the destination array.
1570      * @param elementCount the number of array elements to be copied.
1571      * @throws  IllegalArgumentException if {@code dstArray} is not an array, or if it is an array but whose type is not supported,
1572      * or if the destination array component type does not match the carrier of the source element layout.
1573      */
1574     @ForceInline
1575     static void copy(
1576             MemorySegment srcSegment, ValueLayout srcLayout, long srcOffset,
1577             Object dstArray, int dstIndex, int elementCount) {
1578         Objects.requireNonNull(srcSegment);
1579         Objects.requireNonNull(dstArray);
1580         Objects.requireNonNull(srcLayout);
1581         long baseAndScale = getBaseAndScale(dstArray.getClass());
1582         if (dstArray.getClass().componentType() != srcLayout.carrier()) {
1583             throw new IllegalArgumentException("Incompatible value layout: " + srcLayout);
1584         }
1585         int dstBase = (int)baseAndScale;
1586         int dstWidth = (int)(baseAndScale >> 32);
1587         AbstractMemorySegmentImpl srcImpl = (AbstractMemorySegmentImpl)srcSegment;
1588         srcImpl.checkAccess(srcOffset, elementCount * dstWidth, true);
1589         Objects.checkFromIndexSize(dstIndex, elementCount, Array.getLength(dstArray));
1590         if (dstWidth == 1 || srcLayout.order() == ByteOrder.nativeOrder()) {
1591             ScopedMemoryAccess.getScopedMemoryAccess().copyMemory(srcImpl.scope(), null,
1592                     srcImpl.unsafeGetBase(), srcImpl.unsafeGetOffset() + srcOffset,
1593                     dstArray, dstBase + (dstIndex * dstWidth), elementCount * dstWidth);
1594         } else {
1595             ScopedMemoryAccess.getScopedMemoryAccess().copySwapMemory(srcImpl.scope(), null,
1596                     srcImpl.unsafeGetBase(), srcImpl.unsafeGetOffset() + srcOffset,
1597                     dstArray, dstBase + (dstIndex * dstWidth), elementCount * dstWidth, dstWidth);
1598         }
1599     }
1600 
1601     /**
1602      * Copies a number of elements from a source array to a destination segment,
1603      * starting at a given array index, and a given segment offset (expressed in bytes), using the given destination element layout.
1604      * Supported array types are {@code byte[]}, {@code char[]},{@code short[]},{@code int[]},{@code float[]},{@code long[]} and {@code double[]}.
1605      * @param srcArray the source array.
1606      * @param srcIndex the starting index of the source array.
1607      * @param dstSegment the destination segment.
1608      * @param dstLayout the destination element layout. If the byte order associated with the layout is
1609      * different from the native order, a byte swap operation will be performed on each array element.
1610      * @param dstOffset the starting offset, in bytes, of the destination segment.
1611      * @param elementCount the number of array elements to be copied.
1612      * @throws  IllegalArgumentException if {@code srcArray} is not an array, or if it is an array but whose type is not supported,
1613      * or if the source array component type does not match the carrier of the destination element layout.
1614      */
1615     @ForceInline
1616     static void copy(
1617             Object srcArray, int srcIndex,
1618             MemorySegment dstSegment, ValueLayout dstLayout, long dstOffset, int elementCount) {
1619         Objects.requireNonNull(srcArray);
1620         Objects.requireNonNull(dstSegment);
1621         Objects.requireNonNull(dstLayout);
1622         long baseAndScale = getBaseAndScale(srcArray.getClass());
1623         if (srcArray.getClass().componentType() != dstLayout.carrier()) {
1624             throw new IllegalArgumentException("Incompatible value layout: " + dstLayout);
1625         }
1626         int srcBase = (int)baseAndScale;
1627         int srcWidth = (int)(baseAndScale >> 32);
1628         Objects.checkFromIndexSize(srcIndex, elementCount, Array.getLength(srcArray));
1629         AbstractMemorySegmentImpl destImpl = (AbstractMemorySegmentImpl)dstSegment;
1630         destImpl.checkAccess(dstOffset, elementCount * srcWidth, false);
1631         if (srcWidth == 1 || dstLayout.order() == ByteOrder.nativeOrder()) {
1632             ScopedMemoryAccess.getScopedMemoryAccess().copyMemory(null, destImpl.scope(),
1633                     srcArray, srcBase + (srcIndex * srcWidth),
1634                     destImpl.unsafeGetBase(), destImpl.unsafeGetOffset() + dstOffset, elementCount * srcWidth);
1635         } else {
1636             ScopedMemoryAccess.getScopedMemoryAccess().copySwapMemory(null, destImpl.scope(),
1637                     srcArray, srcBase + (srcIndex * srcWidth),
1638                     destImpl.unsafeGetBase(), destImpl.unsafeGetOffset() + dstOffset, elementCount * srcWidth, srcWidth);
1639         }
1640     }
1641 
1642     private static long getBaseAndScale(Class<?> arrayType) {
1643         if (arrayType.equals(byte[].class)) {
1644             return (long)Unsafe.ARRAY_BYTE_BASE_OFFSET | ((long)Unsafe.ARRAY_BYTE_INDEX_SCALE << 32);
1645         } else if (arrayType.equals(char[].class)) {
1646             return (long)Unsafe.ARRAY_CHAR_BASE_OFFSET | ((long)Unsafe.ARRAY_CHAR_INDEX_SCALE << 32);
1647         } else if (arrayType.equals(short[].class)) {
1648             return (long)Unsafe.ARRAY_SHORT_BASE_OFFSET | ((long)Unsafe.ARRAY_SHORT_INDEX_SCALE << 32);
1649         } else if (arrayType.equals(int[].class)) {
1650             return (long)Unsafe.ARRAY_INT_BASE_OFFSET | ((long) Unsafe.ARRAY_INT_INDEX_SCALE << 32);
1651         } else if (arrayType.equals(float[].class)) {
1652             return (long)Unsafe.ARRAY_FLOAT_BASE_OFFSET | ((long)Unsafe.ARRAY_FLOAT_INDEX_SCALE << 32);
1653         } else if (arrayType.equals(long[].class)) {
1654             return (long)Unsafe.ARRAY_LONG_BASE_OFFSET | ((long)Unsafe.ARRAY_LONG_INDEX_SCALE << 32);
1655         } else if (arrayType.equals(double[].class)) {
1656             return (long)Unsafe.ARRAY_DOUBLE_BASE_OFFSET | ((long)Unsafe.ARRAY_DOUBLE_INDEX_SCALE << 32);
1657         } else {
1658             throw new IllegalArgumentException("Not a supported array class: " + arrayType.getSimpleName());
1659         }
1660     }
1661 }