< prev index next >

src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java

Print this page
@@ -1,7 +1,7 @@
  /*
-  *  Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+  *  Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
   *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   *  This code is free software; you can redistribute it and/or modify it
   *  under the terms of the GNU General Public License version 2 only, as
   *  published by the Free Software Foundation.  Oracle designates this

@@ -25,22 +25,30 @@
   */
  
  package jdk.incubator.foreign;
  
  import java.io.UncheckedIOException;
+ import java.lang.reflect.Array;
  import java.nio.ByteBuffer;
  
  import jdk.internal.foreign.AbstractMemorySegmentImpl;
  import jdk.internal.foreign.HeapMemorySegmentImpl;
  import jdk.internal.foreign.MappedMemorySegmentImpl;
  import jdk.internal.foreign.ResourceScopeImpl;
  import jdk.internal.foreign.NativeMemorySegmentImpl;
+ import jdk.internal.foreign.Utils;
+ import jdk.internal.foreign.abi.SharedUtils;
+ import jdk.internal.misc.ScopedMemoryAccess;
+ import jdk.internal.misc.Unsafe;
  import jdk.internal.reflect.CallerSensitive;
  import jdk.internal.reflect.Reflection;
+ import jdk.internal.vm.annotation.ForceInline;
  
  import java.io.IOException;
+ import java.nio.ByteOrder;
  import java.nio.channels.FileChannel;
+ import java.nio.charset.StandardCharsets;
  import java.nio.file.Path;
  import java.util.Objects;
  import java.util.Spliterator;
  import java.util.stream.Stream;
  

@@ -84,32 +92,67 @@
   * It is also possible to obtain a native memory segment backed by a memory-mapped file using the factory method
   * {@link MemorySegment#mapFile(Path, long, long, FileChannel.MapMode, ResourceScope)}. Such native memory segments are
   * called <em>mapped memory segments</em>; mapped memory segments are associated with an underlying file descriptor.
   * <p>
   * Contents of mapped memory segments can be {@linkplain #force() persisted} and {@linkplain #load() loaded} to and from the underlying file;
-  * these capabilities are suitable replacements for some of the functionality in the {@link java.nio.MappedByteBuffer} class.
+  * these capabilities are suitable replacements for some capabilities in the {@link java.nio.MappedByteBuffer} class.
   * Note that, while it is possible to map a segment into a byte buffer (see {@link MemorySegment#asByteBuffer()}),
   * and then call e.g. {@link java.nio.MappedByteBuffer#force()} that way, this can only be done when the source segment
   * is small enough, due to the size limitation inherent to the ByteBuffer API.
   * <p>
   * Clients requiring sophisticated, low-level control over mapped memory segments, should consider writing
   * custom mapped memory segment factories; using {@link CLinker}, e.g. on Linux, it is possible to call {@code mmap}
   * with the desired parameters; the returned address can be easily wrapped into a memory segment, using
-  * {@link MemoryAddress#ofLong(long)} and {@link MemoryAddress#asSegment(long, Runnable, ResourceScope)}.
+  * {@link MemoryAddress#ofLong(long)} and {@link MemorySegment#ofAddressNative(MemoryAddress, long, ResourceScope)}.
+  *
+  * <h2>Restricted native segments</h2>
+  *
+  * Sometimes it is necessary to turn a memory address obtained from native code into a memory segment with
+  * full spatial, temporal and confinement bounds. To do this, clients can {@link #ofAddressNative(MemoryAddress, long, ResourceScope) obtain}
+  * a native segment <em>unsafely</em> from a give memory address, by providing the segment size, as well as the segment {@linkplain ResourceScope scope}.
+  * This is a <a href="package-summary.html#restricted"><em>restricted</em></a> operation and should be used with
+  * caution: for instance, an incorrect segment size could result in a VM crash when attempting to dereference
+  * the memory segment.
+  *
+  * <h2>Dereference</h2>
+  *
+  * A memory segment can be read or written using various methods provided in this class (e.g. {@link #get(ValueLayout.OfInt, long)}).
+  * Each dereference method takes a {@linkplain jdk.incubator.foreign.ValueLayout value layout}, which specifies the size,
+  * alignment constraints, byte order as well as the Java type associated with the dereference operation, and an offset.
+  * For instance, to read an int from a segment, using {@link ByteOrder#nativeOrder() default endianness}, the following code can be used:
+  * <blockquote><pre>{@code
+ MemorySegment segment = ...
+ int value = segment.get(ValueLayout.JAVA_INT, 0);
+  * }</pre></blockquote>
+  *
+  * If the value to be read is stored in memory using {@link ByteOrder#BIG_ENDIAN big-endian} encoding, the dereference operation
+  * can be expressed as follows:
+  * <blockquote><pre>{@code
+ MemorySegment segment = ...
+ int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0);
+  * }</pre></blockquote>
+  *
+  * For more complex dereference operations (e.g. structured memory access), clients can obtain a <em>memory access var handle</em>,
+  * that is, a var handle that accepts a segment and, optionally, one or more additional {@code long} coordinates. Memory
+  * access var handles can be obtained from {@linkplain MemoryLayout#varHandle(MemoryLayout.PathElement...) memory layouts}
+  * by providing a so called <a href="MemoryLayout.html#layout-paths"><em>layout path</em></a>.
+  * Alternatively, clients can obtain raw memory access var handles from a given
+  * {@linkplain MemoryHandles#varHandle(ValueLayout) value layout}, and then adapt it using the var handle combinator
+  * functions defined in the {@link MemoryHandles} class.
   *
   * <h2>Lifecycle and confinement</h2>
   *
   * Memory segments are associated with a resource scope (see {@link ResourceScope}), which can be accessed using
   * the {@link #scope()} method. As for all resources associated with a resource scope, a segment cannot be
   * accessed after its corresponding scope has been closed. For instance, the following code will result in an
   * exception:
   * <blockquote><pre>{@code
  MemorySegment segment = null;
  try (ResourceScope scope = ResourceScope.newConfinedScope()) {
-     segment = MemorySegment.allocateNative(8, 1, scope);
+     segment = MemorySegment.allocateNative(8, scope);
  }
- MemoryAccess.getLong(segment); // already closed!
+ segment.get(ValueLayout.JAVA_LONG, 0); // already closed!
   * }</pre></blockquote>
   * Additionally, access to a memory segment is subject to the thread-confinement checks enforced by the owning scope; that is,
   * if the segment is associated with a shared scope, it can be accessed by multiple threads; if it is associated with a confined
   * scope, it can only be accessed by the thread which owns the scope.
   * <p>

@@ -141,27 +184,28 @@
   * (to do this, the segment has to be associated with a shared scope). The following code can be used to sum all int
   * values in a memory segment in parallel:
   *
   * <blockquote><pre>{@code
  try (ResourceScope scope = ResourceScope.newSharedScope()) {
-     SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, MemoryLayouts.JAVA_INT);
+     SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT);
      MemorySegment segment = MemorySegment.allocateNative(SEQUENCE_LAYOUT, scope);
-     VarHandle VH_int = SEQUENCE_LAYOUT.elementLayout().varHandle(int.class);
-     int sum = segment.elements(MemoryLayouts.JAVA_INT).parallel()
-                            .mapToInt(s -> (int)VH_int.get(s.address()))
+     int sum = segment.elements(ValueLayout.JAVA_INT).parallel()
+                            .mapToInt(s -> s.get(ValueLayout.JAVA_INT, 0))
                             .sum();
  }
   * }</pre></blockquote>
   *
   * @implSpec
   * Implementations of this interface are immutable, thread-safe and <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>.
   */
  public sealed interface MemorySegment extends Addressable permits AbstractMemorySegmentImpl {
  
      /**
-      * The base memory address associated with this memory segment.
-      * The returned memory address is associated with same resource scope as that associated with this segment.
+      * The base memory address associated with this native memory segment.
+      * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
       * @return The base memory address.
       */
      @Override
      MemoryAddress address();
  

@@ -215,85 +259,37 @@
      /**
       * Obtains a new memory segment view whose base address is the same as the base address of this segment plus a given offset,
       * and whose new size is specified by the given argument.
       *
       * @see #asSlice(long)
-      * @see #asSlice(MemoryAddress)
-      * @see #asSlice(MemoryAddress, long)
       *
       * @param offset The new segment base offset (relative to the current segment base address), specified in bytes.
       * @param newSize The new segment size, specified in bytes.
       * @return a new memory segment view with updated base/limit addresses.
       * @throws IndexOutOfBoundsException if {@code offset < 0}, {@code offset > byteSize()}, {@code newSize < 0}, or {@code newSize > byteSize() - offset}
       */
      MemorySegment asSlice(long offset, long newSize);
  
-     /**
-      * Obtains a new memory segment view whose base address is the given address, and whose new size is specified by the given argument.
-      * <p>
-      * Equivalent to the following code:
-      * <pre>{@code
-     asSlice(newBase.segmentOffset(this), newSize);
-      * }</pre>
-      *
-      * @see #asSlice(long)
-      * @see #asSlice(MemoryAddress)
-      * @see #asSlice(long, long)
-      *
-      * @param newBase The new segment base address.
-      * @param newSize The new segment size, specified in bytes.
-      * @return a new memory segment view with updated base/limit addresses.
-      * @throws IndexOutOfBoundsException if {@code offset < 0}, {@code offset > byteSize()}, {@code newSize < 0}, or {@code newSize > byteSize() - offset}
-      */
-     default MemorySegment asSlice(MemoryAddress newBase, long newSize) {
-         Objects.requireNonNull(newBase);
-         return asSlice(newBase.segmentOffset(this), newSize);
-     }
- 
      /**
       * Obtains a new memory segment view whose base address is the same as the base address of this segment plus a given offset,
       * and whose new size is computed by subtracting the specified offset from this segment size.
       * <p>
       * Equivalent to the following code:
       * <pre>{@code
      asSlice(offset, byteSize() - offset);
       * }</pre>
       *
-      * @see #asSlice(MemoryAddress)
-      * @see #asSlice(MemoryAddress, long)
       * @see #asSlice(long, long)
       *
       * @param offset The new segment base offset (relative to the current segment base address), specified in bytes.
       * @return a new memory segment view with updated base/limit addresses.
       * @throws IndexOutOfBoundsException if {@code offset < 0}, or {@code offset > byteSize()}.
       */
      default MemorySegment asSlice(long offset) {
          return asSlice(offset, byteSize() - offset);
      }
  
-     /**
-      * Obtains a new memory segment view whose base address is the given address, and whose new size is computed by subtracting
-      * the address offset relative to this segment (see {@link MemoryAddress#segmentOffset(MemorySegment)}) from this segment size.
-      * <p>
-      * Equivalent to the following code:
-      * <pre>{@code
-     asSlice(newBase.segmentOffset(this));
-      * }</pre>
-      *
-      * @see #asSlice(long)
-      * @see #asSlice(MemoryAddress, long)
-      * @see #asSlice(long, long)
-      *
-      * @param newBase The new segment base offset (relative to the current segment base address), specified in bytes.
-      * @return a new memory segment view with updated base/limit addresses.
-      * @throws IndexOutOfBoundsException if {@code address.segmentOffset(this) < 0}, or {@code address.segmentOffset(this) > byteSize()}.
-      */
-     default MemorySegment asSlice(MemoryAddress newBase) {
-         Objects.requireNonNull(newBase);
-         return asSlice(newBase.segmentOffset(this));
-     }
- 
      /**
       * Is this segment read-only?
       * @return {@code true}, if this segment is read-only.
       * @see #asReadOnly()
       */

@@ -322,18 +318,54 @@
       * derived from a {@link java.nio.MappedByteBuffer} using the {@link #ofByteBuffer(ByteBuffer)} factory.
       * @return {@code true} if this segment is a mapped segment.
       */
      boolean isMapped();
  
+     /**
+      * Returns a slice of this segment that is the overlap between this and
+      * the provided segment.
+      *
+      * <p>Two segments S1 and S2 are said to overlap if it is possible to find
+      * at least two slices L1 (from S1) and L2 (from S2) that are backed by the
+      * same memory region. As such, it is not possible for a
+      * {@link #isNative() native} segment to overlap with a heap segment; in
+      * this case, or when no overlap occurs, {@code null} is returned.
+      *
+      * @param other the segment to test for an overlap with this segment.
+      * @return a slice of this segment, or {@code null} if no overlap occurs.
+      */
+     MemorySegment asOverlappingSlice(MemorySegment other);
+ 
+     /**
+      * Returns the offset, in bytes, of the provided segment, relative to this
+      * segment.
+      *
+      * <p>The offset is relative to the base address of this segment and can be
+      * a negative or positive value. For instance, if both segments are native
+      * segments, the resulting offset can be computed as follows:
+      *
+      * <pre>{@code
+      * other.baseAddress().toRawLongValue() - segment.baseAddress().toRawLongValue()
+      * }</pre>
+      *
+      * If the segments share the same base address, {@code 0} is returned. If
+      * {@code other} is a slice of this segment, the offset is always
+      * {@code 0 <= x < this.byteSize()}.
+      *
+      * @param other the segment to retrieve an offset to.
+      * @return the relative offset, in bytes, of the provided segment.
+      */
+     long segmentOffset(MemorySegment other);
+ 
      /**
       * Fills a value into this memory segment.
       * <p>
       * More specifically, the given value is filled into each address of this
       * segment. Equivalent to (but likely more efficient than) the following code:
       *
       * <pre>{@code
- byteHandle = MemoryLayout.ofSequence(MemoryLayouts.JAVA_BYTE)
+ byteHandle = MemoryLayout.ofSequence(ValueLayout.JAVA_BYTE)
           .varHandle(byte.class, MemoryLayout.PathElement.sequenceElement());
  for (long l = 0; l < segment.byteSize(); l++) {
       byteHandle.set(segment.address(), l, value);
  }
       * }</pre>

@@ -344,49 +376,53 @@
       * Fill can be useful to initialize or reset the memory of a segment.
       *
       * @param value the value to fill into this segment
       * @return this memory segment
       * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
-      * a thread other than the thread owning that scope,
+      * a thread other than the thread owning that scope.
       * @throws UnsupportedOperationException if this segment is read-only (see {@link #isReadOnly()}).
       */
      MemorySegment fill(byte value);
  
      /**
-      * Performs a bulk copy from given source segment to this segment. More specifically, the bytes at
+      * Performs an element-wise bulk copy from given source segment to this segment. More specifically, the bytes at
       * offset {@code 0} through {@code src.byteSize() - 1} in the source segment are copied into this segment
       * at offset {@code 0} through {@code src.byteSize() - 1}.
-      * If the source segment overlaps with this segment, then the copying is performed as if the bytes at
-      * offset {@code 0} through {@code src.byteSize() - 1} in the source segment were first copied into a
-      * temporary segment with size {@code bytes}, and then the contents of the temporary segment were copied into
-      * this segment at offset {@code 0} through {@code src.byteSize() - 1}.
       * <p>
-      * The result of a bulk copy is unspecified if, in the uncommon case, the source segment and this segment
-      * do not overlap, but refer to overlapping regions of the same backing storage using different addresses.
-      * For example, this may occur if the same file is {@linkplain MemorySegment#mapFile mapped} to two segments.
-      *
+      * Calling this method is equivalent to the following code:
+      * <blockquote><pre>{@code
+     MemorySegment.copy(src, 0, this, 0, src.byteSize);
+      * }</pre></blockquote>
       * @param src the source segment.
       * @throws IndexOutOfBoundsException if {@code src.byteSize() > this.byteSize()}.
+      * @throws IllegalArgumentException if the element layouts have different sizes, if the source segment size is not
+      * a multiple of the source element layout size, if the source segment is incompatible with the alignment constraints
+      * in the source element layout, or if this segment is incompatible with the alignment constraints
+      * in the destination element layout.
       * @throws IllegalStateException if either the scope associated with the source segment or the scope associated
       * with this segment have been already closed, or if access occurs from a thread other than the thread owning either
       * scopes.
       * @throws UnsupportedOperationException if this segment is read-only (see {@link #isReadOnly()}).
+      * @return this segment.
       */
-     void copyFrom(MemorySegment src);
+     default MemorySegment copyFrom(MemorySegment src) {
+         MemorySegment.copy(src, 0, this, 0, src.byteSize());
+         return this;
+     }
  
      /**
       * Finds and returns the offset, in bytes, of the first mismatch between
       * this segment and a given other segment. The offset is relative to the
       * {@linkplain #address() base address} of each segment and will be in the
       * range of 0 (inclusive) up to the {@linkplain #byteSize() size} (in bytes) of
       * the smaller memory segment (exclusive).
       * <p>
       * If the two segments share a common prefix then the returned offset is
-      * the length of the common prefix and it follows that there is a mismatch
+      * the length of the common prefix, and it follows that there is a mismatch
       * between the two segments at that offset within the respective segments.
-      * If one segment is a proper prefix of the other then the returned offset is
-      * the smaller of the segment sizes, and it follows that the offset is only
+      * If one segment is a proper prefix of the other, then the returned offset is
+      * the smallest of the segment sizes, and it follows that the offset is only
       * valid for the larger segment. Otherwise, there is no mismatch and {@code
       * -1} is returned.
       *
       * @param other the segment to be tested for a mismatch with this segment
       * @return the relative offset, in bytes, of the first mismatch between this

@@ -396,15 +432,15 @@
       * owning either scopes.
       */
      long mismatch(MemorySegment other);
  
      /**
-      * Tells whether or not the contents of this mapped segment is resident in physical
+      * Tells whether the contents of this mapped segment is resident in physical
       * memory.
       *
       * <p> A return value of {@code true} implies that it is highly likely
-      * that all of the data in this segment is resident in physical memory and
+      * that all the data in this segment is resident in physical memory and
       * may therefore be accessed without incurring any virtual-memory page
       * faults or I/O operations.  A return value of {@code false} does not
       * necessarily imply that this segment's content is not resident in physical
       * memory.
       *

@@ -479,23 +515,23 @@
       * @throws UncheckedIOException if there is an I/O error writing the contents of this segment to the associated storage device
       */
      void force();
  
      /**
-      * Wraps this segment in a {@link ByteBuffer}. Some of the properties of the returned buffer are linked to
+      * Wraps this segment in a {@link ByteBuffer}. Some properties of the returned buffer are linked to
       * the properties of this segment. For instance, if this segment is <em>immutable</em>
       * (e.g. the segment is a read-only segment, see {@link #isReadOnly()}), then the resulting buffer is <em>read-only</em>
-      * (see {@link ByteBuffer#isReadOnly()}. Additionally, if this is a native memory segment, the resulting buffer is
+      * (see {@link ByteBuffer#isReadOnly()}). Additionally, if this is a native memory segment, the resulting buffer is
       * <em>direct</em> (see {@link ByteBuffer#isDirect()}).
       * <p>
-      * The returned buffer's position (see {@link ByteBuffer#position()} is initially set to zero, while
+      * The returned buffer's position (see {@link ByteBuffer#position()}) is initially set to zero, while
       * the returned buffer's capacity and limit (see {@link ByteBuffer#capacity()} and {@link ByteBuffer#limit()}, respectively)
       * are set to this segment' size (see {@link MemorySegment#byteSize()}). For this reason, a byte buffer cannot be
       * returned if this segment' size is greater than {@link Integer#MAX_VALUE}.
       * <p>
       * The life-cycle of the returned buffer will be tied to that of this segment. That is, accessing the returned buffer
-      * after the scope associated with this segment has been closed (see {@link ResourceScope#close()}, will throw an {@link IllegalStateException}.
+      * after the scope associated with this segment has been closed (see {@link ResourceScope#close()}), will throw an {@link IllegalStateException}.
       * <p>
       * If this segment is associated with a confined scope, calling read/write I/O operations on the resulting buffer
       * might result in an unspecified exception being thrown. Examples of such problematic operations are
       * {@link java.nio.channels.AsynchronousSocketChannel#read(ByteBuffer)} and
       * {@link java.nio.channels.AsynchronousSocketChannel#write(ByteBuffer)}.

@@ -503,87 +539,139 @@
       * Finally, the resulting buffer's byte order is {@link java.nio.ByteOrder#BIG_ENDIAN}; this can be changed using
       * {@link ByteBuffer#order(java.nio.ByteOrder)}.
       *
       * @return a {@link ByteBuffer} view of this memory segment.
       * @throws UnsupportedOperationException if this segment cannot be mapped onto a {@link ByteBuffer} instance,
-      * e.g. because it models an heap-based segment that is not based on a {@code byte[]}), or if its size is greater
+      * e.g. because it models a heap-based segment that is not based on a {@code byte[]}), or if its size is greater
       * than {@link Integer#MAX_VALUE}.
       */
      ByteBuffer asByteBuffer();
  
      /**
       * Copy the contents of this memory segment into a fresh byte array.
+      * @param elementLayout the source element layout. If the byte order associated with the layout is
+      * different from the native order, a byte swap operation will be performed on each array element.
       * @return a fresh byte array copy of this memory segment.
       * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
       * a thread other than the thread owning that scope, or if this segment's contents cannot be copied into a {@link byte[]} instance,
       * e.g. its size is greater than {@link Integer#MAX_VALUE}.
       */
-     byte[] toByteArray();
+     byte[] toArray(ValueLayout.OfByte elementLayout);
  
      /**
       * Copy the contents of this memory segment into a fresh short array.
+      * @param elementLayout the source element layout. If the byte order associated with the layout is
+      * different from the native order, a byte swap operation will be performed on each array element.
       * @return a fresh short array copy of this memory segment.
       * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
       * a thread other than the thread owning that scope, or if this segment's contents cannot be copied into a {@link short[]} instance,
       * e.g. because {@code byteSize() % 2 != 0}, or {@code byteSize() / 2 > Integer#MAX_VALUE}
       */
-     short[] toShortArray();
+     short[] toArray(ValueLayout.OfShort elementLayout);
  
      /**
       * Copy the contents of this memory segment into a fresh char array.
+      * @param elementLayout the source element layout. If the byte order associated with the layout is
+      * different from the native order, a byte swap operation will be performed on each array element.
       * @return a fresh char array copy of this memory segment.
       * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
       * a thread other than the thread owning that scope, or if this segment's contents cannot be copied into a {@link char[]} instance,
       * e.g. because {@code byteSize() % 2 != 0}, or {@code byteSize() / 2 > Integer#MAX_VALUE}.
       */
-     char[] toCharArray();
+     char[] toArray(ValueLayout.OfChar elementLayout);
  
      /**
       * Copy the contents of this memory segment into a fresh int array.
+      * @param elementLayout the source element layout. If the byte order associated with the layout is
+      * different from the native order, a byte swap operation will be performed on each array element.
       * @return a fresh int array copy of this memory segment.
       * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
       * a thread other than the thread owning that scope, or if this segment's contents cannot be copied into a {@link int[]} instance,
       * e.g. because {@code byteSize() % 4 != 0}, or {@code byteSize() / 4 > Integer#MAX_VALUE}.
       */
-     int[] toIntArray();
+     int[] toArray(ValueLayout.OfInt elementLayout);
  
      /**
       * Copy the contents of this memory segment into a fresh float array.
+      * @param elementLayout the source element layout. If the byte order associated with the layout is
+      * different from the native order, a byte swap operation will be performed on each array element.
       * @return a fresh float array copy of this memory segment.
       * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
       * a thread other than the thread owning that scope, or if this segment's contents cannot be copied into a {@link float[]} instance,
       * e.g. because {@code byteSize() % 4 != 0}, or {@code byteSize() / 4 > Integer#MAX_VALUE}.
       */
-     float[] toFloatArray();
+     float[] toArray(ValueLayout.OfFloat elementLayout);
  
      /**
       * Copy the contents of this memory segment into a fresh long array.
+      * @param elementLayout the source element layout. If the byte order associated with the layout is
+      * different from the native order, a byte swap operation will be performed on each array element.
       * @return a fresh long array copy of this memory segment.
       * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
       * a thread other than the thread owning that scope, or if this segment's contents cannot be copied into a {@link long[]} instance,
       * e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer#MAX_VALUE}.
       */
-     long[] toLongArray();
+     long[] toArray(ValueLayout.OfLong elementLayout);
  
      /**
       * Copy the contents of this memory segment into a fresh double array.
+      * @param elementLayout the source element layout. If the byte order associated with the layout is
+      * different from the native order, a byte swap operation will be performed on each array element.
       * @return a fresh double array copy of this memory segment.
       * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
       * a thread other than the thread owning that scope, or if this segment's contents cannot be copied into a {@link double[]} instance,
       * e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer#MAX_VALUE}.
       */
-     double[] toDoubleArray();
+     double[] toArray(ValueLayout.OfDouble elementLayout);
  
      /**
-      * Creates a new confined buffer memory segment that models the memory associated with the given byte
+      * Reads a UTF-8 encoded, null-terminated string from this segment at given offset.
+      * <p>
+      * This method always replaces malformed-input and unmappable-character
+      * sequences with this charset's default replacement string.  The {@link
+      * java.nio.charset.CharsetDecoder} class should be used when more control
+      * over the decoding process is required.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @return a Java UTF-8 string containing all the bytes read from the given starting address up to (but not including)
+      * the first {@code '\0'} terminator character (assuming one is found).
+      * @throws IllegalArgumentException if the size of the native string is greater than the largest string supported by the platform.
+      * @throws IllegalStateException if the size of the native string is greater than the size of this segment,
+      * 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.
+      */
+     default String getUtf8String(long offset) {
+         return SharedUtils.toJavaStringInternal(this, offset);
+     }
+ 
+     /**
+      * Writes a UTF-8 encoded, null-terminated string into this segment at given offset.
+      * <p>
+      * This method always replaces malformed-input and unmappable-character
+      * sequences with this charset's default replacement string.  The {@link
+      * java.nio.charset.CharsetDecoder} class should be used when more control
+      * over the decoding process is required.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @param str the Java string to be written into this segment.
+      * @throws IllegalArgumentException if the size of the native string is greater than the largest string supported by the platform.
+      * @throws IllegalStateException if the size of the native string is greater than the size of this segment,
+      * 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.
+      */
+     default void setUtf8String(long offset, String str) {
+         Utils.toCString(str.getBytes(StandardCharsets.UTF_8), SegmentAllocator.prefixAllocator(asSlice(offset)));
+     }
+ 
+ 
+     /**
+      * Creates a new buffer memory segment that models the memory associated with the given byte
       * buffer. The segment starts relative to the buffer's position (inclusive)
       * and ends relative to the buffer's limit (exclusive).
       * <p>
       * If the buffer is {@link ByteBuffer#isReadOnly() read-only}, the resulting segment will also be
       * {@link ByteBuffer#isReadOnly() read-only}. The scope associated with this segment can either be the
       * {@linkplain ResourceScope#globalScope() global} resource scope, in case the buffer has been created independently,
-      * or to some other (possibly closeable) resource scope, in case the buffer has been obtained using {@link #asByteBuffer()}.
+      * or some other resource scope, in case the buffer has been obtained using {@link #asByteBuffer()}.
       * <p>
       * The resulting memory segment keeps a reference to the backing buffer, keeping it <em>reachable</em>.
       *
       * @param bb the byte buffer backing the buffer memory segment.
       * @return a new buffer memory segment.

@@ -591,88 +679,129 @@
      static MemorySegment ofByteBuffer(ByteBuffer bb) {
          return AbstractMemorySegmentImpl.ofBuffer(bb);
      }
  
      /**
-      * Creates a new confined array memory segment that models the memory associated with a given heap-allocated byte array.
+      * Creates a new array memory segment that models the memory associated with a given heap-allocated byte array.
       * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
       *
       * @param arr the primitive array backing the array memory segment.
       * @return a new array memory segment.
       */
      static MemorySegment ofArray(byte[] arr) {
          return HeapMemorySegmentImpl.OfByte.fromArray(arr);
      }
  
      /**
-      * Creates a new confined array memory segment that models the memory associated with a given heap-allocated char array.
+      * Creates a new array memory segment that models the memory associated with a given heap-allocated char array.
       * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
       *
       * @param arr the primitive array backing the array memory segment.
       * @return a new array memory segment.
       */
      static MemorySegment ofArray(char[] arr) {
          return HeapMemorySegmentImpl.OfChar.fromArray(arr);
      }
  
      /**
-      * Creates a new confined array memory segment that models the memory associated with a given heap-allocated short array.
+      * Creates a new array memory segment that models the memory associated with a given heap-allocated short array.
       * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
       *
       * @param arr the primitive array backing the array memory segment.
       * @return a new array memory segment.
       */
      static MemorySegment ofArray(short[] arr) {
          return HeapMemorySegmentImpl.OfShort.fromArray(arr);
      }
  
      /**
-      * Creates a new confined array memory segment that models the memory associated with a given heap-allocated int array.
+      * Creates a new array memory segment that models the memory associated with a given heap-allocated int array.
       * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
       *
       * @param arr the primitive array backing the array memory segment.
       * @return a new array memory segment.
       */
      static MemorySegment ofArray(int[] arr) {
          return HeapMemorySegmentImpl.OfInt.fromArray(arr);
      }
  
      /**
-      * Creates a new confined array memory segment that models the memory associated with a given heap-allocated float array.
+      * Creates a new array memory segment that models the memory associated with a given heap-allocated float array.
       * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
       *
       * @param arr the primitive array backing the array memory segment.
       * @return a new array memory segment.
       */
      static MemorySegment ofArray(float[] arr) {
          return HeapMemorySegmentImpl.OfFloat.fromArray(arr);
      }
  
      /**
-      * Creates a new confined array memory segment that models the memory associated with a given heap-allocated long array.
+      * Creates a new array memory segment that models the memory associated with a given heap-allocated long array.
       * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
       *
       * @param arr the primitive array backing the array memory segment.
       * @return a new array memory segment.
       */
      static MemorySegment ofArray(long[] arr) {
          return HeapMemorySegmentImpl.OfLong.fromArray(arr);
      }
  
      /**
-      * Creates a new confined array memory segment that models the memory associated with a given heap-allocated double array.
+      * Creates a new array memory segment that models the memory associated with a given heap-allocated double array.
       * The returned segment's resource scope is set to the {@linkplain ResourceScope#globalScope() global} resource scope.
       *
       * @param arr the primitive array backing the array memory segment.
       * @return a new array memory segment.
       */
      static MemorySegment ofArray(double[] arr) {
          return HeapMemorySegmentImpl.OfDouble.fromArray(arr);
      }
  
+ 
+     /**
+      * Creates a new native memory segment with given size and resource scope, and whose base address is this address.
+      * This method can be useful when interacting with custom
+      * native memory sources (e.g. custom allocators), where an address to some
+      * underlying memory region is typically obtained from native code (often as a plain {@code long} value).
+      * The returned segment is not read-only (see {@link MemorySegment#isReadOnly()}), and is associated with the
+      * provided resource scope.
+      * <p>
+      * Clients should ensure that the address and bounds refers to a valid region of memory that is accessible for reading and,
+      * if appropriate, writing; an attempt to access an invalid memory location from Java code will either return an arbitrary value,
+      * have no visible effect, or cause an unspecified exception to be thrown.
+      * <p>
+      * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
+      * Restricted methods are unsafe, and, if used incorrectly, their use might crash
+      * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on
+      * restricted methods, and use safe and supported functionalities, where possible.
+      *
+      *
+      * @param address the returned segment's base address.
+      * @param bytesSize the desired size.
+      * @param scope the native segment scope.
+      * @return a new native memory segment with given base address, size and scope.
+      * @throws IllegalArgumentException if {@code bytesSize <= 0}.
+      * @throws IllegalStateException if the provided scope has been already closed,
+      * or if access occurs from a thread other than the thread owning the scope.
+      * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option
+      * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or
+      * {@code ALL-UNNAMED} in case {@code M} is an unnamed module.
+      */
+     @CallerSensitive
+     static MemorySegment ofAddressNative(MemoryAddress address, long bytesSize, ResourceScope scope) {
+         Reflection.ensureNativeAccess(Reflection.getCallerClass());
+         Objects.requireNonNull(address);
+         Objects.requireNonNull(scope);
+         if (bytesSize <= 0) {
+             throw new IllegalArgumentException("Invalid size : " + bytesSize);
+         }
+         return NativeMemorySegmentImpl.makeNativeSegmentUnchecked(address, bytesSize, (ResourceScopeImpl)scope);
+     }
+ 
      /**
-      * Creates a new confined native memory segment that models a newly allocated block of off-heap memory with given layout
+      * Creates a new native memory segment that models a newly allocated block of off-heap memory with given layout
       * and resource scope. A client is responsible make sure that the resource scope associated with the returned segment is closed
       * when the segment is no longer in use. Failure to do so will result in off-heap memory leaks.
       * <p>
       * This is equivalent to the following code:
       * <blockquote><pre>{@code

@@ -693,11 +822,11 @@
          Objects.requireNonNull(layout);
          return allocateNative(layout.byteSize(), layout.byteAlignment(), scope);
      }
  
      /**
-      * Creates a new confined native memory segment that models a newly allocated block of off-heap memory with given size (in bytes)
+      * Creates a new native memory segment that models a newly allocated block of off-heap memory with given size (in bytes)
       * and resource scope. A client is responsible make sure that the resource scope associated with the returned segment is closed
       * when the segment is no longer in use. Failure to do so will result in off-heap memory leaks.
       * <p>
       * This is equivalent to the following code:
       * <blockquote><pre>{@code

@@ -716,11 +845,11 @@
      static MemorySegment allocateNative(long bytesSize, ResourceScope scope) {
          return allocateNative(bytesSize, 1, scope);
      }
  
      /**
-      * Creates a new confined native memory segment that models a newly allocated block of off-heap memory with given size
+      * Creates a new native memory segment that models a newly allocated block of off-heap memory with given size
       * (in bytes), alignment constraint (in bytes) and resource scope. A client is responsible make sure that the resource
       * scope associated with the returned segment is closed when the segment is no longer in use.
       * Failure to do so will result in off-heap memory leaks.
       * <p>
       * The block of off-heap memory associated with the returned native memory segment is initialized to zero.

@@ -754,11 +883,11 @@
       * If the specified mapping mode is {@linkplain FileChannel.MapMode#READ_ONLY READ_ONLY}, the resulting segment
       * will be read-only (see {@link #isReadOnly()}).
       * <p>
       * The content of a mapped memory segment can change at any time, for example
       * if the content of the corresponding region of the mapped file is changed by
-      * this (or another) program.  Whether or not such changes occur, and when they
+      * this (or another) program.  Whether such changes occur, and when they
       * occur, is operating-system dependent and therefore unspecified.
       * <p>
       * All or part of a mapped memory segment may become
       * inaccessible at any time, for example if the backing mapped file is truncated.  An
       * attempt to access an inaccessible region of a mapped memory segment will not

@@ -772,50 +901,761 @@
       * of mapped memory associated with the returned mapped memory segment is unspecified and should not be relied upon.
       *
       * @param path the path to the file to memory map.
       * @param bytesOffset the offset (expressed in bytes) within the file at which the mapped segment is to start.
       * @param bytesSize the size (in bytes) of the mapped memory backing the memory segment.
-      * @param mapMode a file mapping mode, see {@link FileChannel#map(FileChannel.MapMode, long, long)}; the chosen mapping mode
+      * @param mapMode a file mapping mode, see {@link FileChannel#map(FileChannel.MapMode, long, long)}; the mapping mode
       *                might affect the behavior of the returned memory mapped segment (see {@link #force()}).
       * @param scope the segment scope.
-      * @return a new confined mapped memory segment.
+      * @return a new mapped memory segment.
       * @throws IllegalArgumentException if {@code bytesOffset < 0}, {@code bytesSize < 0}, or if {@code path} is not associated
       * with the default file system.
       * @throws IllegalStateException if {@code scope} has been already closed, or if access occurs from a thread other
       * than the thread owning {@code scope}.
       * @throws UnsupportedOperationException if an unsupported map mode is specified.
       * @throws IOException if the specified path does not point to an existing file, or if some other I/O error occurs.
-      * @throws  SecurityException If a security manager is installed and it denies an unspecified permission required by the implementation.
+      * @throws  SecurityException If a security manager is installed, and it denies an unspecified permission required by the implementation.
       * In the case of the default provider, the {@link SecurityManager#checkRead(String)} method is invoked to check
       * read access if the file is opened for reading. The {@link SecurityManager#checkWrite(String)} method is invoked to check
       * write access if the file is opened for writing.
       */
      static MemorySegment mapFile(Path path, long bytesOffset, long bytesSize, FileChannel.MapMode mapMode, ResourceScope scope) throws IOException {
          Objects.requireNonNull(scope);
          return MappedMemorySegmentImpl.makeMappedSegment(path, bytesOffset, bytesSize, mapMode, (ResourceScopeImpl) scope);
      }
  
      /**
-      * Returns a native memory segment whose base address is {@link MemoryAddress#NULL} and whose size is {@link Long#MAX_VALUE}.
-      * This method can be very useful when dereferencing memory addresses obtained when interacting with native libraries.
-      * The returned segment is associated with the <em>global</em> resource scope (see {@link ResourceScope#globalScope()}).
-      * Equivalent to (but likely more efficient than) the following code:
-      * <pre>{@code
-     MemoryAddress.NULL.asSegment(Long.MAX_VALUE)
-      * }</pre>
+      * Performs a bulk copy from source segment to destination segment. More specifically, the bytes at offset
+      * {@code srcOffset} through {@code srcOffset + bytes - 1} in the source segment are copied into the destination
+      * segment at offset {@code dstOffset} through {@code dstOffset + bytes - 1}.
       * <p>
-      * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
-      * Restricted methods are unsafe, and, if used incorrectly, their use might crash
-      * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on
-      * restricted methods, and use safe and supported functionalities, where possible.
+      * If the source segment overlaps with this segment, then the copying is performed as if the bytes at
+      * offset {@code srcOffset} through {@code srcOffset + bytes - 1} in the source segment were first copied into a
+      * temporary segment with size {@code bytes}, and then the contents of the temporary segment were copied into
+      * the destination segment at offset {@code dstOffset} through {@code dstOffset + bytes - 1}.
+      * <p>
+      * The result of a bulk copy is unspecified if, in the uncommon case, the source segment and the destination segment
+      * do not overlap, but refer to overlapping regions of the same backing storage using different addresses.
+      * For example, this may occur if the same file is {@linkplain MemorySegment#mapFile mapped} to two segments.
+      * <p>
+      * Calling this method is equivalent to the following code:
+      * <blockquote><pre>{@code
+     MemorySegment.copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes);
+      * }</pre></blockquote>
+      * @param srcSegment the source segment.
+      * @param srcOffset the starting offset, in bytes, of the source segment.
+      * @param dstSegment the destination segment.
+      * @param dstOffset the starting offset, in bytes, of the destination segment.
+      * @param bytes the number of bytes to be copied.
+      * @throws IllegalStateException if either the scope associated with the source segment or the scope associated
+      * with the destination segment have been already closed, or if access occurs from a thread other than the thread
+      * owning either scopes.
+      * @throws IndexOutOfBoundsException if {@code srcOffset + bytes > srcSegment.byteSize()} or if
+      * {@code dstOffset + bytes > dstSegment.byteSize()}, or if either {@code srcOffset}, {@code dstOffset}
+      * or {@code bytes} are {@code < 0}.
+      * @throws UnsupportedOperationException if the destination segment is read-only (see {@link #isReadOnly()}).
+      */
+     @ForceInline
+     static void copy(MemorySegment srcSegment, long srcOffset, MemorySegment dstSegment, long dstOffset, long bytes) {
+         copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes);
+     }
+ 
+     /**
+      * Performs a bulk copy from source segment to destination segment. More specifically, if {@code S} is the byte size
+      * of the element layouts, the bytes at offset {@code srcOffset} through {@code srcOffset + (elementCount * S) - 1}
+      * in the source segment are copied into the destination segment at offset {@code dstOffset} through {@code dstOffset + (elementCount * S) - 1}.
+      * <p>
+      * The copy occurs in an element-wise fashion: the bytes in the source segment are interpreted as a sequence of elements
+      * whose layout is {@code srcElementLayout}, whereas the bytes in the destination segment are interpreted as a sequence of
+      * elements whose layout is {@code dstElementLayout}. Both element layouts must have same size {@code S}.
+      * If the byte order of the two element layouts differ, the bytes corresponding to each element to be copied
+      * are swapped accordingly during the copy operation.
+      * <p>
+      * If the source segment overlaps with this segment, then the copying is performed as if the bytes at
+      * offset {@code srcOffset} through {@code srcOffset + (elementCount * S) - 1} in the source segment were first copied into a
+      * temporary segment with size {@code bytes}, and then the contents of the temporary segment were copied into
+      * the destination segment at offset {@code dstOffset} through {@code dstOffset + (elementCount * S) - 1}.
+      * <p>
+      * The result of a bulk copy is unspecified if, in the uncommon case, the source segment and the destination segment
+      * do not overlap, but refer to overlapping regions of the same backing storage using different addresses.
+      * For example, this may occur if the same file is {@linkplain MemorySegment#mapFile mapped} to two segments.
+      * @param srcSegment the source segment.
+      * @param srcElementLayout the element layout associated with the source segment.
+      * @param srcOffset the starting offset, in bytes, of the source segment.
+      * @param dstSegment the destination segment.
+      * @param dstElementLayout the element layout associated with the destination segment.
+      * @param dstOffset the starting offset, in bytes, of the destination segment.
+      * @param elementCount the number of elements to be copied.
+      * @throws IllegalArgumentException if the element layouts have different sizes, if the source offset is incompatible
+      * with the alignment constraints in the source element layout, or if the destination offset is incompatible with the
+      * alignment constraints in the destination element layout.
+      * @throws IllegalStateException if either the scope associated with the source segment or the scope associated
+      * with the destination segment have been already closed, or if access occurs from a thread other than the thread
+      * owning either scopes.
+      * @throws IndexOutOfBoundsException if {@code srcOffset + (elementCount * S) > srcSegment.byteSize()} or if
+      * {@code dstOffset + (elementCount * S) > dstSegment.byteSize()}, where {@code S} is the byte size
+      * of the element layouts, or if either {@code srcOffset}, {@code dstOffset} or {@code elementCount} are {@code < 0}.
+      * @throws UnsupportedOperationException if the destination segment is read-only (see {@link #isReadOnly()}).
+      */
+     @ForceInline
+     static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long srcOffset, MemorySegment dstSegment,
+                      ValueLayout dstElementLayout, long dstOffset, long elementCount) {
+         Objects.requireNonNull(srcSegment);
+         Objects.requireNonNull(srcElementLayout);
+         Objects.requireNonNull(dstSegment);
+         Objects.requireNonNull(dstElementLayout);
+         AbstractMemorySegmentImpl srcImpl = (AbstractMemorySegmentImpl)srcSegment;
+         AbstractMemorySegmentImpl dstImpl = (AbstractMemorySegmentImpl)dstSegment;
+         if (srcElementLayout.byteSize() != dstElementLayout.byteSize()) {
+             throw new IllegalArgumentException("Source and destination layouts must have same sizes");
+         }
+         if (srcOffset % srcElementLayout.byteAlignment() != 0) {
+             throw new IllegalArgumentException("Source segment incompatible with alignment constraints");
+         }
+         if (dstOffset % dstElementLayout.byteAlignment() != 0) {
+             throw new IllegalArgumentException("Target segment incompatible with alignment constraints");
+         }
+         long size = elementCount * srcElementLayout.byteSize();
+         srcImpl.checkAccess(srcOffset, size, true);
+         dstImpl.checkAccess(dstOffset, size, false);
+         if (srcElementLayout.byteSize() == 1 || srcElementLayout.order() == dstElementLayout.order()) {
+             ScopedMemoryAccess.getScopedMemoryAccess().copyMemory(srcImpl.scope(), dstImpl.scope(),
+                     srcImpl.unsafeGetBase(), srcImpl.unsafeGetOffset() + srcOffset,
+                     dstImpl.unsafeGetBase(), dstImpl.unsafeGetOffset() + dstOffset, size);
+         } else {
+             ScopedMemoryAccess.getScopedMemoryAccess().copySwapMemory(srcImpl.scope(), dstImpl.scope(),
+                     srcImpl.unsafeGetBase(), srcImpl.unsafeGetOffset() + srcOffset,
+                     dstImpl.unsafeGetBase(), dstImpl.unsafeGetOffset() + dstOffset, size, srcElementLayout.byteSize());
+         }
+     }
+ 
+     /**
+      * Reads a byte from this segment and offset with given layout.
       *
-      * @return a memory segment whose base address is {@link MemoryAddress#NULL} and whose size is {@link Long#MAX_VALUE}.
-      * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option
-      * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or
-      * {@code ALL-UNNAMED} in case {@code M} is an unnamed module.
+      * @param layout the layout of the memory region to be read.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @return a byte value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
       */
-     @CallerSensitive
-     static MemorySegment globalNativeSegment() {
-         Reflection.ensureNativeAccess(Reflection.getCallerClass());
-         return NativeMemorySegmentImpl.EVERYTHING;
+     @ForceInline
+     default byte get(ValueLayout.OfByte layout, long offset) {
+         return (byte)layout.accessHandle().get(this, offset);
+     }
+ 
+     /**
+      * Writes a byte to this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void set(ValueLayout.OfByte layout, long offset, byte value) {
+         layout.accessHandle().set(this, offset, value);
+     }
+ 
+     /**
+      * Reads a boolean from this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @return a boolean value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default boolean get(ValueLayout.OfBoolean layout, long offset) {
+         return (boolean)layout.accessHandle().get(this, offset);
+     }
+ 
+     /**
+      * Writes a boolean to this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void set(ValueLayout.OfBoolean layout, long offset, boolean value) {
+         layout.accessHandle().set(this, offset, value);
+     }
+ 
+     /**
+      * Reads a char from this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @return a char value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default char get(ValueLayout.OfChar layout, long offset) {
+         return (char)layout.accessHandle().get(this, offset);
+     }
+ 
+     /**
+      * Writes a char to this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void set(ValueLayout.OfChar layout, long offset, char value) {
+         layout.accessHandle().set(this, offset, value);
+     }
+ 
+     /**
+      * Reads a short from this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @return a short value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default short get(ValueLayout.OfShort layout, long offset) {
+         return (short)layout.accessHandle().get(this, offset);
+     }
+ 
+     /**
+      * Writes a short to this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void set(ValueLayout.OfShort layout, long offset, short value) {
+         layout.accessHandle().set(this, offset, value);
+     }
+ 
+     /**
+      * Reads an int from this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @return an int value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default int get(ValueLayout.OfInt layout, long offset) {
+         return (int)layout.accessHandle().get(this, offset);
+     }
+ 
+     /**
+      * Writes an int to this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void set(ValueLayout.OfInt layout, long offset, int value) {
+         layout.accessHandle().set(this, offset, value);
+     }
+ 
+     /**
+      * Reads a float from this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @return a float value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default float get(ValueLayout.OfFloat layout, long offset) {
+         return (float)layout.accessHandle().get(this, offset);
+     }
+ 
+     /**
+      * Writes a float to this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void set(ValueLayout.OfFloat layout, long offset, float value) {
+         layout.accessHandle().set(this, offset, value);
+     }
+ 
+     /**
+      * Reads a long from this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @return a long value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default long get(ValueLayout.OfLong layout, long offset) {
+         return (long)layout.accessHandle().get(this, offset);
+     }
+ 
+     /**
+      * Writes a long to this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void set(ValueLayout.OfLong layout, long offset, long value) {
+         layout.accessHandle().set(this, offset, value);
+     }
+ 
+     /**
+      * Reads a double from this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @return a double value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default double get(ValueLayout.OfDouble layout, long offset) {
+         return (double)layout.accessHandle().get(this, offset);
+     }
+ 
+     /**
+      * Writes a double to this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void set(ValueLayout.OfDouble layout, long offset, double value) {
+         layout.accessHandle().set(this, offset, value);
+     }
+ 
+     /**
+      * Reads an address from this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @return an address value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default MemoryAddress get(ValueLayout.OfAddress layout, long offset) {
+         return (MemoryAddress)layout.accessHandle().get(this, offset);
+     }
+ 
+     /**
+      * Writes an address to this segment and offset with given layout.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param offset offset in bytes (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + offset}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void set(ValueLayout.OfAddress layout, long offset, Addressable value) {
+         layout.accessHandle().set(this, offset, value.address());
+     }
+ 
+     /**
+      * Reads a char from this segment and index, scaled by given layout size.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
+      * @return a char value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default char getAtIndex(ValueLayout.OfChar layout, long index) {
+         return (char)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize()));
+     }
+ 
+     /**
+      * Writes a char to this segment and index, scaled by given layout size.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void setAtIndex(ValueLayout.OfChar layout, long index, char value) {
+         layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value);
+     }
+ 
+     /**
+      * Reads a short from this segment and index, scaled by given layout size.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
+      * @return a short value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default short getAtIndex(ValueLayout.OfShort layout, long index) {
+         return (short)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize()));
+     }
+ 
+     /**
+      * Writes a short to this segment and index, scaled by given layout size.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void setAtIndex(ValueLayout.OfShort layout, long index, short value) {
+         layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value);
+     }
+ 
+     /**
+      * Reads an int from this segment and index, scaled by given layout size.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
+      * @return an int value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default int getAtIndex(ValueLayout.OfInt layout, long index) {
+         return (int)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize()));
+     }
+ 
+     /**
+      * Writes an int to this segment and index, scaled by given layout size.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void setAtIndex(ValueLayout.OfInt layout, long index, int value) {
+         layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value);
+     }
+ 
+     /**
+      * Reads a float from this segment and index, scaled by given layout size.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
+      * @return a float value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default float getAtIndex(ValueLayout.OfFloat layout, long index) {
+         return (float)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize()));
+     }
+ 
+     /**
+      * Writes a float to this segment and index, scaled by given layout size.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void setAtIndex(ValueLayout.OfFloat layout, long index, float value) {
+         layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value);
+     }
+ 
+     /**
+      * Reads a long from this segment and index, scaled by given layout size.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
+      * @return a long value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default long getAtIndex(ValueLayout.OfLong layout, long index) {
+         return (long)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize()));
+     }
+ 
+     /**
+      * Writes a long to this segment and index, scaled by given layout size.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void setAtIndex(ValueLayout.OfLong layout, long index, long value) {
+         layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value);
+     }
+ 
+     /**
+      * Reads a double from this segment and index, scaled by given layout size.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
+      * @return a double value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default double getAtIndex(ValueLayout.OfDouble layout, long index) {
+         return (double)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize()));
+     }
+ 
+     /**
+      * Writes a double to this segment and index, scaled by given layout size.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void setAtIndex(ValueLayout.OfDouble layout, long index, double value) {
+         layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value);
+     }
+ 
+     /**
+      * Reads an address from this segment and index, scaled by given layout size.
+      *
+      * @param layout the layout of the memory region to be read.
+      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this read operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
+      * @return an address value read from this address.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      * memory segment.
+      */
+     @ForceInline
+     default MemoryAddress getAtIndex(ValueLayout.OfAddress layout, long index) {
+         return (MemoryAddress)layout.accessHandle().get(this, Utils.scaleOffset(this, index, layout.byteSize()));
+     }
+ 
+     /**
+      * Writes an address to this segment and index, scaled by given layout size.
+      *
+      * @param layout the layout of the memory region to be written.
+      * @param index index (relative to this segment). For instance, if this segment is a {@link #isNative()} segment,
+      *               the final address of this write operation can be expressed as {@code address().toRowLongValue() + (index * layout.byteSize())}.
+      * @param value the byte value to be written.
+      * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from
+      * a thread other than the thread owning that scope.
+      * @throws IndexOutOfBoundsException when the dereference operation falls outside the <em>spatial bounds</em> of the
+      */
+     @ForceInline
+     default void setAtIndex(ValueLayout.OfAddress layout, long index, Addressable value) {
+         layout.accessHandle().set(this, Utils.scaleOffset(this, index, layout.byteSize()), value.address());
+     }
+ 
+ 
+     /**
+      * Copies a number of elements from a source segment to a destination array,
+      * starting at a given segment offset (expressed in bytes), and a given array index, using the given source element layout.
+      * Supported array types are {@code byte[]}, {@code char[]},{@code short[]},{@code int[]},{@code float[]},{@code long[]} and {@code double[]}.
+      * @param srcSegment the source segment.
+      * @param srcLayout the source element layout. If the byte order associated with the layout is
+      * different from the native order, a byte swap operation will be performed on each array element.
+      * @param srcOffset the starting offset, in bytes, of the source segment.
+      * @param dstArray the destination array.
+      * @param dstIndex the starting index of the destination array.
+      * @param elementCount the number of array elements to be copied.
+      * @throws  IllegalArgumentException if {@code dstArray} is not an array, or if it is an array but whose type is not supported,
+      * or if the destination array component type does not match the carrier of the source element layout.
+      */
+     @ForceInline
+     static void copy(
+             MemorySegment srcSegment, ValueLayout srcLayout, long srcOffset,
+             Object dstArray, int dstIndex, int elementCount) {
+         Objects.requireNonNull(srcSegment);
+         Objects.requireNonNull(dstArray);
+         Objects.requireNonNull(srcLayout);
+         long baseAndScale = getBaseAndScale(dstArray.getClass());
+         if (dstArray.getClass().componentType() != srcLayout.carrier()) {
+             throw new IllegalArgumentException("Incompatible value layout: " + srcLayout);
+         }
+         int dstBase = (int)baseAndScale;
+         int dstWidth = (int)(baseAndScale >> 32);
+         AbstractMemorySegmentImpl srcImpl = (AbstractMemorySegmentImpl)srcSegment;
+         srcImpl.checkAccess(srcOffset, elementCount * dstWidth, true);
+         Objects.checkFromIndexSize(dstIndex, elementCount, Array.getLength(dstArray));
+         if (dstWidth == 1 || srcLayout.order() == ByteOrder.nativeOrder()) {
+             ScopedMemoryAccess.getScopedMemoryAccess().copyMemory(srcImpl.scope(), null,
+                     srcImpl.unsafeGetBase(), srcImpl.unsafeGetOffset() + srcOffset,
+                     dstArray, dstBase + (dstIndex * dstWidth), elementCount * dstWidth);
+         } else {
+             ScopedMemoryAccess.getScopedMemoryAccess().copySwapMemory(srcImpl.scope(), null,
+                     srcImpl.unsafeGetBase(), srcImpl.unsafeGetOffset() + srcOffset,
+                     dstArray, dstBase + (dstIndex * dstWidth), elementCount * dstWidth, dstWidth);
+         }
+     }
+ 
+     /**
+      * Copies a number of elements from a source array to a destination segment,
+      * starting at a given array index, and a given segment offset (expressed in bytes), using the given destination element layout.
+      * Supported array types are {@code byte[]}, {@code char[]},{@code short[]},{@code int[]},{@code float[]},{@code long[]} and {@code double[]}.
+      * @param srcArray the source array.
+      * @param srcIndex the starting index of the source array.
+      * @param dstSegment the destination segment.
+      * @param dstLayout the destination element layout. If the byte order associated with the layout is
+      * different from the native order, a byte swap operation will be performed on each array element.
+      * @param dstOffset the starting offset, in bytes, of the destination segment.
+      * @param elementCount the number of array elements to be copied.
+      * @throws  IllegalArgumentException if {@code srcArray} is not an array, or if it is an array but whose type is not supported,
+      * or if the source array component type does not match the carrier of the destination element layout.
+      */
+     @ForceInline
+     static void copy(
+             Object srcArray, int srcIndex,
+             MemorySegment dstSegment, ValueLayout dstLayout, long dstOffset, int elementCount) {
+         Objects.requireNonNull(srcArray);
+         Objects.requireNonNull(dstSegment);
+         Objects.requireNonNull(dstLayout);
+         long baseAndScale = getBaseAndScale(srcArray.getClass());
+         if (srcArray.getClass().componentType() != dstLayout.carrier()) {
+             throw new IllegalArgumentException("Incompatible value layout: " + dstLayout);
+         }
+         int srcBase = (int)baseAndScale;
+         int srcWidth = (int)(baseAndScale >> 32);
+         Objects.checkFromIndexSize(srcIndex, elementCount, Array.getLength(srcArray));
+         AbstractMemorySegmentImpl destImpl = (AbstractMemorySegmentImpl)dstSegment;
+         destImpl.checkAccess(dstOffset, elementCount * srcWidth, false);
+         if (srcWidth == 1 || dstLayout.order() == ByteOrder.nativeOrder()) {
+             ScopedMemoryAccess.getScopedMemoryAccess().copyMemory(null, destImpl.scope(),
+                     srcArray, srcBase + (srcIndex * srcWidth),
+                     destImpl.unsafeGetBase(), destImpl.unsafeGetOffset() + dstOffset, elementCount * srcWidth);
+         } else {
+             ScopedMemoryAccess.getScopedMemoryAccess().copySwapMemory(null, destImpl.scope(),
+                     srcArray, srcBase + (srcIndex * srcWidth),
+                     destImpl.unsafeGetBase(), destImpl.unsafeGetOffset() + dstOffset, elementCount * srcWidth, srcWidth);
+         }
+     }
+ 
+     private static long getBaseAndScale(Class<?> arrayType) {
+         if (arrayType.equals(byte[].class)) {
+             return (long)Unsafe.ARRAY_BYTE_BASE_OFFSET | ((long)Unsafe.ARRAY_BYTE_INDEX_SCALE << 32);
+         } else if (arrayType.equals(char[].class)) {
+             return (long)Unsafe.ARRAY_CHAR_BASE_OFFSET | ((long)Unsafe.ARRAY_CHAR_INDEX_SCALE << 32);
+         } else if (arrayType.equals(short[].class)) {
+             return (long)Unsafe.ARRAY_SHORT_BASE_OFFSET | ((long)Unsafe.ARRAY_SHORT_INDEX_SCALE << 32);
+         } else if (arrayType.equals(int[].class)) {
+             return (long)Unsafe.ARRAY_INT_BASE_OFFSET | ((long) Unsafe.ARRAY_INT_INDEX_SCALE << 32);
+         } else if (arrayType.equals(float[].class)) {
+             return (long)Unsafe.ARRAY_FLOAT_BASE_OFFSET | ((long)Unsafe.ARRAY_FLOAT_INDEX_SCALE << 32);
+         } else if (arrayType.equals(long[].class)) {
+             return (long)Unsafe.ARRAY_LONG_BASE_OFFSET | ((long)Unsafe.ARRAY_LONG_INDEX_SCALE << 32);
+         } else if (arrayType.equals(double[].class)) {
+             return (long)Unsafe.ARRAY_DOUBLE_BASE_OFFSET | ((long)Unsafe.ARRAY_DOUBLE_INDEX_SCALE << 32);
+         } else {
+             throw new IllegalArgumentException("Not a supported array class: " + arrayType.getSimpleName());
+         }
      }
  }
< prev index next >