< prev index next >

src/java.base/share/classes/java/lang/foreign/MemorySegment.java

Print this page
@@ -24,19 +24,17 @@
   */
  
  package java.lang.foreign;
  
  import java.io.UncheckedIOException;
- import java.lang.foreign.Linker.Option;
- import java.lang.invoke.MethodHandle;
- import java.lang.invoke.MethodHandles;
  import java.nio.Buffer;
  import java.nio.ByteBuffer;
  import java.nio.ByteOrder;
  import java.nio.CharBuffer;
  import java.nio.channels.FileChannel;
- import java.nio.channels.FileChannel.*;
+ import java.nio.channels.FileChannel.MapMode;
+ import java.nio.charset.Charset;
  import java.nio.charset.StandardCharsets;
  import java.util.Arrays;
  import java.util.Objects;
  import java.util.Optional;
  import java.util.Spliterator;

@@ -44,14 +42,12 @@
  import java.util.stream.Stream;
  import jdk.internal.foreign.AbstractMemorySegmentImpl;
  import jdk.internal.foreign.HeapMemorySegmentImpl;
  import jdk.internal.foreign.MemorySessionImpl;
  import jdk.internal.foreign.NativeMemorySegmentImpl;
+ import jdk.internal.foreign.StringSupport;
  import jdk.internal.foreign.Utils;
- import jdk.internal.foreign.abi.SharedUtils;
- import jdk.internal.foreign.layout.ValueLayouts;
- import jdk.internal.javac.PreviewFeature;
  import jdk.internal.reflect.CallerSensitive;
  import jdk.internal.vm.annotation.ForceInline;
  
  /**
   * A memory segment provides access to a contiguous region of memory.

@@ -125,36 +121,51 @@
   * {@snippet lang=java :
   * MemorySegment segment = ...
   * int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0);
   * }
   *
-  * For more complex access operations (e.g. structured memory access), clients can obtain a
-  * {@linkplain MethodHandles#memorySegmentViewVarHandle(ValueLayout) var handle}
-  * that accepts a segment and a {@code long} offset. More complex var handles
-  * can be obtained by adapting a segment var handle view using the var handle combinator functions defined in the
-  * {@link java.lang.invoke.MethodHandles} class:
+  * More complex access operations can be implemented using var handles. The {@link ValueLayout#varHandle()}
+  * method can be used to obtain a var handle that can be used to get/set values represented by the given value layout on a memory segment.
+  * A var handle obtained from a layout supports several additional <a href=MemoryLayout.html#access-mode-restrictions>
+  * access modes</a>. More importantly, var handles can be <em>combined</em> with method handles to express complex access
+  * operations. For instance, a var handle that can be used to access an element of an {@code int} array at a given logical
+  * index can be created as follows:
   *
-  * {@snippet lang=java :
+  * {@snippet lang=java:
   * MemorySegment segment = ...
-  * VarHandle intHandle = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_INT);
-  * MethodHandle multiplyExact = MethodHandles.lookup()
-  *                                           .findStatic(Math.class, "multiplyExact",
-  *                                                                   MethodType.methodType(long.class, long.class, long.class));
-  * intHandle = MethodHandles.filterCoordinates(intHandle, 1,
-  *                                             MethodHandles.insertArguments(multiplyExact, 0, ValueLayout.JAVA_INT.byteSize()));
-  * int value = (int) intHandle.get(segment, 3L); // get int element at offset 3 * 4 = 12
+  * VarHandle intHandle = ValueLayout.JAVA_INT.varHandle(); // (MemorySegment, long)
+  * MethodHandle scale = ValueLayout.JAVA_INT.scaleHandle(); // <base offset> + <index> * JAVA_INT.byteSize()
+  *
+  * intHandle = MethodHandles.filterCoordinates(intHandle, 1, scale);
+  * int value = (int) intHandle.get(segment, 0L, 3L); // get int element at offset 0 + 3 * 4 = 12
   * }
   *
-  * Alternatively, complex var handles can 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>:
+  * To make the process of creating these var handles easier, the method
+  * {@link MemoryLayout#varHandle(MemoryLayout.PathElement...)} can be used, by providing it a so called
+  * <a href="MemoryLayout.html#layout-paths"><em>layout path</em></a>. A layout path, consisting of several <em>layout
+  * path elements</em>, selects a value layout to be accessed, which can be nested inside another memory layout. For example,
+  * we can express the access to an element of an {@code int} array using layout paths like so:
   *
   * {@snippet lang=java :
   * MemorySegment segment = ...
-  * VarHandle intHandle = ValueLayout.JAVA_INT.arrayElementVarHandle();
-  * int value = (int) intHandle.get(segment, 3L); // get int element at offset 3 * 4 = 12
+  * MemoryLayout segmentLayout = MemoryLayout.structLayout(
+  *     ValueLayout.JAVA_INT.withName("size"),
+  *     MemoryLayout.sequenceLayout(4, ValueLayout.JAVA_INT).withName("data") // array of 4 elements
+  * );
+  * VarHandle intHandle = segmentLayout.varHandle(MemoryLayout.PathElemenet.groupElement("data"),
+  *                                               MemoryLayout.PathElement.sequenceElement());
+  * int value = (int) intHandle.get(segment, 0L, 3L); // get int element at offset 0 + offsetof(data) + 3 * 4 = 12
   * }
+  * Where {@code offsetof(data)} is the offset of the {@code data} element layout of the {@code segmentLayout} layout
+  *
+  * Both the var handle returned by {@link ValueLayout#varHandle()} and
+  * {@link MemoryLayout#varHandle(MemoryLayout.PathElement...)}, as well as the method handle returned by
+  * {@link MemoryLayout#byteOffsetHandle(MemoryLayout.PathElement...)} and {@link MemoryLayout#sliceHandle(MemoryLayout.PathElement...)}
+  * feature a <em>base offset</em> parameter. This parameter represents a base offset for the offset computation. This
+  * parameter allows a client to combine these handles further with additional offset computations. This is demonstrated
+  * in the first of the two examples above, where {@code intHandle} is combined with a
+  * {@linkplain MemoryLayout#scaleHandle() scale handle} obtained from {@code ValueLayout.JAVA_INT}.
   *
   * <h2 id="slicing">Slicing memory segments</h2>
   *
   * Memory segments support {@linkplain MemorySegment#asSlice(long, long) slicing}. Slicing a memory segment
   * returns a new memory segment that is backed by the same region of memory as the original. The address of the sliced

@@ -369,11 +380,11 @@
   *     <li>The size of the segment is zero. any attempt to access these segments will fail with {@link IndexOutOfBoundsException}.
   *     This is a crucial safety feature: as these segments are associated with a region
   *     of memory whose size is not known, any access operations involving these segments cannot be validated.
   *     In effect, a zero-length memory segment <em>wraps</em> an address, and it cannot be used without explicit intent
   *     (see below);</li>
-  *     <li>The segment is associated with a fresh scope that is always alive. Thus, while zero-length
+  *     <li>The segment is associated with a scope that is always alive. Thus, while zero-length
   *     memory segments cannot be accessed directly, they can be passed, opaquely, to other pointer-accepting foreign functions.</li>
   * </ul>
   * <p>
   * To demonstrate how clients can work with zero-length memory segments, consider the case of a client that wants
   * to read a pointer from some memory segment. This can be done via the

@@ -431,13 +442,12 @@
   * the memory segment.
   *
   * @implSpec
   * Implementations of this interface are immutable, thread-safe and <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>.
   *
-  * @since 19
+  * @since 22
   */
- @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
  public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
  
      /**
       * {@return the address of this memory segment}
       *

@@ -594,12 +604,11 @@
      /**
       * Returns a new memory segment that has the same address and scope as this segment, but with the provided size.
       * <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.
+      * the JVM or, worse, silently result in memory corruption.
       *
       * @param newSize the size of the returned segment.
       * @return a new memory segment that has the same address and scope as this segment, but the new
       * provided size.
       * @throws IllegalArgumentException if {@code newSize < 0}.

@@ -622,17 +631,16 @@
       * invalid. This cleanup action receives a fresh memory segment that is obtained from this segment as follows:
       * {@snippet lang=java :
       * MemorySegment cleanupSegment = MemorySegment.ofAddress(this.address())
       *                                             .reinterpret(byteSize());
       * }
-      * That is, the cleanup action receives a segment that is associated with a fresh scope that is always alive,
+      * That is, the cleanup action receives a segment that is associated with a scope that is always alive,
       * and is accessible from any thread. The size of the segment accepted by the cleanup action is {@link #byteSize()}.
       * <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.
+      * the JVM or, worse, silently result in memory corruption.
       *
       * @apiNote The cleanup action (if present) should take care not to leak the received segment to external
       * clients which might access the segment after its backing region of memory is no longer available. Furthermore,
       * if the provided scope is the scope of an {@linkplain Arena#ofAuto() automatic arena}, the cleanup action
       * must not prevent the scope from becoming <a href="../../../java/lang/ref/package.html#reachability">unreachable</a>.

@@ -661,17 +669,16 @@
       * invalid. This cleanup action receives a fresh memory segment that is obtained from this segment as follows:
       * {@snippet lang=java :
       * MemorySegment cleanupSegment = MemorySegment.ofAddress(this.address())
       *                                             .reinterpret(newSize);
       * }
-      * That is, the cleanup action receives a segment that is associated with a fresh scope that is always alive,
+      * That is, the cleanup action receives a segment that is associated with a scope that is always alive,
       * and is accessible from any thread. The size of the segment accepted by the cleanup action is {@code newSize}.
       * <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.
+      * the JVM or, worse, silently result in memory corruption.
       *
       * @apiNote The cleanup action (if present) should take care not to leak the received segment to external
       * clients which might access the segment after its backing region of memory is no longer available. Furthermore,
       * if the provided scope is the scope of an {@linkplain Arena#ofAuto() automatic arena}, the cleanup action
       * must not prevent the scope from becoming <a href="../../../java/lang/ref/package.html#reachability">unreachable</a>.

@@ -733,43 +740,19 @@
       * @param other the segment to test for an overlap with this segment.
       * @return a slice of this segment (where overlapping occurs).
       */
      Optional<MemorySegment> asOverlappingSlice(MemorySegment other);
  
-     /**
-      * Returns the offset, in bytes, of the provided segment, relative to this
-      * segment.
-      *
-      * <p>The offset is relative to the address of this segment and can be
-      * a negative or positive value. For instance, if both segments are native
-      * segments, or heap segments backed by the same array, the resulting offset
-      * can be computed as follows:
-      *
-      * {@snippet lang=java :
-      * other.address() - address()
-      * }
-      *
-      * If the segments share the same 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.
-      * @throws UnsupportedOperationException if the two segments cannot be compared, e.g. because they are of
-      * different kinds, or because they are backed by different Java arrays.
-      * @return the relative offset, in bytes, of the provided segment.
-      */
-     long segmentOffset(MemorySegment other);
- 
      /**
       * Fills the contents of this memory segment with the given value.
       * <p>
       * More specifically, the given value is written into each address of this
       * segment. Equivalent to (but likely more efficient than) the following code:
       *
       * {@snippet lang=java :
       * for (long offset = 0; offset < segment.byteSize(); offset++) {
-      *     byteHandle.set(ValueLayout.JAVA_BYTE, offset, value);
+      *     segment.set(ValueLayout.JAVA_BYTE, offset, value);
       * }
       * }
       *
       * But without any regard or guarantees on the ordering of particular memory
       * elements being set.

@@ -1066,56 +1049,127 @@
       * e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer.MAX_VALUE}.
       */
      double[] toArray(ValueLayout.OfDouble elementLayout);
  
      /**
-      * Reads a UTF-8 encoded, null-terminated string from this segment at the given offset.
+      * Reads a null-terminated string from this segment at the given offset, using the
+      * {@linkplain StandardCharsets#UTF_8 UTF-8} charset.
       * <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.
+      * Calling this method is equivalent to the following code:
+      * {@snippet lang = java:
+      * getString(offset, StandardCharsets.UTF_8);
+      *}
+      *
       * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
       * @return a Java string constructed from 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 UTF-8 string is greater than the largest string supported by the platform.
-      * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code offset > byteSize() - S}, where {@code S} is the size of the UTF-8
-      * string (including the terminator character).
+      * @throws IllegalArgumentException if the size of the string is greater than the largest string supported by the platform.
+      * @throws IndexOutOfBoundsException     if {@code offset < 0}.
+      * @throws IndexOutOfBoundsException     if {@code offset > byteSize() - (B + 1)}, where {@code B} is the size,
+      * in bytes, of the string encoded using UTF-8 charset {@code str.getBytes(StandardCharsets.UTF_8).length}).
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       */
-     default String getUtf8String(long offset) {
-         return SharedUtils.toJavaStringInternal(this, offset);
+     default String getString(long offset) {
+         return getString(offset, sun.nio.cs.UTF_8.INSTANCE);
      }
  
      /**
-      * Writes the given string into this segment at the given offset, converting it to a null-terminated byte sequence using UTF-8 encoding.
+      * Reads a null-terminated string from this segment at the given offset, using the provided charset.
       * <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 address) at which this access operation will occur.
+      * @param charset the charset used to {@linkplain Charset#newDecoder() decode} the string bytes.
+      * @return a Java string constructed from 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 string is greater than the largest string supported by the platform.
+      * @throws IndexOutOfBoundsException     if {@code offset < 0}.
+      * @throws IndexOutOfBoundsException     if {@code offset > byteSize() - (B + N)}, where:
+      * <ul>
+      *     <li>{@code B} is the size, in bytes, of the string encoded using the provided charset
+      *     (e.g. {@code str.getBytes(charset).length});</li>
+      *     <li>{@code N} is the size (in bytes) of the terminator char according to the provided charset. For instance,
+      *     this is 1 for {@link StandardCharsets#US_ASCII} and 2 for {@link StandardCharsets#UTF_16}.</li>
+      * </ul>
+      * @throws IllegalStateException         if the {@linkplain #scope() scope} associated with this segment is not
+      *                                       {@linkplain Scope#isAlive() alive}.
+      * @throws WrongThreadException          if this method is called from a thread {@code T},
+      *                                       such that {@code isAccessibleBy(T) == false}.
+      * @throws UnsupportedOperationException if {@code charset} is not a {@linkplain StandardCharsets standard charset}.
+      */
+     default String getString(long offset, Charset charset) {
+         Objects.requireNonNull(charset);
+         return StringSupport.read(this, offset, charset);
+     }
+ 
+     /**
+      * Writes the given string into this segment at the given offset, converting it to a null-terminated byte sequence
+      * using the {@linkplain StandardCharsets#UTF_8 UTF-8} charset.
       * <p>
-      * If the given string contains any {@code '\0'} characters, they will be
-      * copied as well. This means that, depending on the method used to read
-      * the string, such as {@link MemorySegment#getUtf8String(long)}, the string
-      * will appear truncated when read again.
+      * Calling this method is equivalent to the following code:
+      * {@snippet lang = java:
+      * setString(offset, str, StandardCharsets.UTF_8);
+      *}
       * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
       *               the final address of this write operation can be expressed as {@code address() + offset}.
       * @param str the Java string to be written into this segment.
-      * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code offset > byteSize() - str.getBytes().length() + 1}.
+      * @throws IndexOutOfBoundsException     if {@code offset < 0}.
+      * @throws IndexOutOfBoundsException     if {@code offset > byteSize() - (B + 1)}, where {@code B} is the size,
+      * in bytes, of the string encoded using UTF-8 charset {@code str.getBytes(StandardCharsets.UTF_8).length}).
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       */
-     default void setUtf8String(long offset, String str) {
-         Utils.toCString(str.getBytes(StandardCharsets.UTF_8), SegmentAllocator.prefixAllocator(asSlice(offset)));
+     default void setString(long offset, String str) {
+         Objects.requireNonNull(str);
+         setString(offset, str, sun.nio.cs.UTF_8.INSTANCE);
      }
  
+     /**
+      * Writes the given string into this segment at the given offset, converting it to a null-terminated byte sequence
+      * using the provided charset.
+      * <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.
+      * <p>
+      * If the given string contains any {@code '\0'} characters, they will be
+      * copied as well. This means that, depending on the method used to read
+      * the string, such as {@link MemorySegment#getString(long)}, the string
+      * will appear truncated when read again.
+      *
+      * @param offset  offset in bytes (relative to this segment address) at which this access operation will occur.
+      *                the final address of this write operation can be expressed as {@code address() + offset}.
+      * @param str     the Java string to be written into this segment.
+      * @param charset the charset used to {@linkplain Charset#newEncoder() encode} the string bytes.
+      * @throws IndexOutOfBoundsException     if {@code offset < 0}.
+      * @throws IndexOutOfBoundsException     if {@code offset > byteSize() - (B + N)}, where:
+      * <ul>
+      *     <li>{@code B} is the size, in bytes, of the string encoded using the provided charset
+      *     (e.g. {@code str.getBytes(charset).length});</li>
+      *     <li>{@code N} is the size (in bytes) of the terminator char according to the provided charset. For instance,
+      *     this is 1 for {@link StandardCharsets#US_ASCII} and 2 for {@link StandardCharsets#UTF_16}.</li>
+      * </ul>
+      * @throws IllegalStateException         if the {@linkplain #scope() scope} associated with this segment is not
+      *                                       {@linkplain Scope#isAlive() alive}.
+      * @throws WrongThreadException          if this method is called from a thread {@code T},
+      *                                       such that {@code isAccessibleBy(T) == false}.
+      * @throws UnsupportedOperationException if {@code charset} is not a {@linkplain StandardCharsets standard charset}.
+      */
+     default void setString(long offset, String str, Charset charset) {
+         Objects.requireNonNull(charset);
+         Objects.requireNonNull(str);
+         StringSupport.write(this, offset, charset, str);
+     }
  
      /**
       * Creates a memory segment that is backed by the same region of memory that backs the given {@link Buffer} instance.
       * The segment starts relative to the buffer's position (inclusive) and ends relative to the buffer's limit (exclusive).
       * <p>

@@ -1275,12 +1329,13 @@
       * such that {@code srcSegment.isAccessibleBy(T) == false}.
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code dstSegment.isAccessibleBy(T) == false}.
-      * @throws IndexOutOfBoundsException if {@code srcOffset > srcSegment.byteSize() - bytes} or if
-      * {@code dstOffset > dstSegment.byteSize() - bytes}, or if either {@code srcOffset}, {@code dstOffset}
+      * @throws IndexOutOfBoundsException if {@code srcOffset > srcSegment.byteSize() - bytes}.
+      * @throws IndexOutOfBoundsException if {@code dstOffset > dstSegment.byteSize() - bytes}.
+      * @throws IndexOutOfBoundsException if either {@code srcOffset}, {@code dstOffset}
       * or {@code bytes} are {@code < 0}.
       * @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      static void copy(MemorySegment srcSegment, long srcOffset,

@@ -1314,21 +1369,25 @@
       * @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 (resp. destination) segment/offset are
       * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the source
-      * (resp. destination) element layout, or if the source (resp. destination) element layout alignment is greater than its size.
+      * (resp. destination) element layout.
+      * @throws IllegalArgumentException if {@code srcElementLayout.byteAlignment() > srcElementLayout.byteSize()}.
+      * @throws IllegalArgumentException if {@code dstElementLayout.byteAlignment() > dstElementLayout.byteSize()}.
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
-      * such that {@code srcSegment().isAccessibleBy(T) == false}.
+      * such that {@code srcSegment.isAccessibleBy(T) == false}.
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
-      * such that {@code dstSegment().isAccessibleBy(T) == false}.
+      * such that {@code dstSegment.isAccessibleBy(T) == false}.
       * @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}.
-      * @throws IndexOutOfBoundsException if {@code elementCount * srcLayout.byteSize()} or {@code elementCount * dtsLayout.byteSize()} overflows.
+      * @throws IndexOutOfBoundsException if {@code elementCount * srcLayout.byteSize()} overflows.
+      * @throws IndexOutOfBoundsException if {@code elementCount * dtsLayout.byteSize()} overflows.
+      * @throws IndexOutOfBoundsException if {@code srcOffset > srcSegment.byteSize() - (elementCount * srcLayout.byteSize())}.
       * @throws IndexOutOfBoundsException if {@code dstOffset > dstSegment.byteSize() - (elementCount * dstLayout.byteSize())}.
       * @throws IndexOutOfBoundsException if either {@code srcOffset}, {@code dstOffset} or {@code elementCount} are {@code < 0}.
       */
      @ForceInline
      static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long srcOffset,

@@ -1355,11 +1414,11 @@
       * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default byte get(ValueLayout.OfByte layout, long offset) {
-         return (byte) ((ValueLayouts.OfByteImpl) layout).accessHandle().get(this, offset);
+         return (byte) layout.varHandle().get(this, offset);
      }
  
      /**
       * Writes a byte into this segment at the given offset, with the given layout.
       *

@@ -1375,11 +1434,11 @@
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void set(ValueLayout.OfByte layout, long offset, byte value) {
-         ((ValueLayouts.OfByteImpl) layout).accessHandle().set(this, offset, value);
+         layout.varHandle().set(this, offset, value);
      }
  
      /**
       * Reads a boolean from this segment at the given offset, with the given layout.
       *

@@ -1394,11 +1453,11 @@
       * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default boolean get(ValueLayout.OfBoolean layout, long offset) {
-         return (boolean) ((ValueLayouts.OfBooleanImpl) layout).accessHandle().get(this, offset);
+         return (boolean) layout.varHandle().get(this, offset);
      }
  
      /**
       * Writes a boolean into this segment at the given offset, with the given layout.
       *

@@ -1414,11 +1473,11 @@
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void set(ValueLayout.OfBoolean layout, long offset, boolean value) {
-         ((ValueLayouts.OfBooleanImpl) layout).accessHandle().set(this, offset, value);
+         layout.varHandle().set(this, offset, value);
      }
  
      /**
       * Reads a char from this segment at the given offset, with the given layout.
       *

@@ -1433,11 +1492,11 @@
       * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default char get(ValueLayout.OfChar layout, long offset) {
-         return (char) ((ValueLayouts.OfCharImpl) layout).accessHandle().get(this, offset);
+         return (char) layout.varHandle().get(this, offset);
      }
  
      /**
       * Writes a char into this segment at the given offset, with the given layout.
       *

@@ -1453,11 +1512,11 @@
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void set(ValueLayout.OfChar layout, long offset, char value) {
-         ((ValueLayouts.OfCharImpl) layout).accessHandle().set(this, offset, value);
+         layout.varHandle().set(this, offset, value);
      }
  
      /**
       * Reads a short from this segment at the given offset, with the given layout.
       *

@@ -1472,11 +1531,11 @@
       * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default short get(ValueLayout.OfShort layout, long offset) {
-         return (short) ((ValueLayouts.OfShortImpl) layout).accessHandle().get(this, offset);
+         return (short) layout.varHandle().get(this, offset);
      }
  
      /**
       * Writes a short into this segment at the given offset, with the given layout.
       *

@@ -1492,11 +1551,11 @@
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void set(ValueLayout.OfShort layout, long offset, short value) {
-         ((ValueLayouts.OfShortImpl) layout).accessHandle().set(this, offset, value);
+         layout.varHandle().set(this, offset, value);
      }
  
      /**
       * Reads an int from this segment at the given offset, with the given layout.
       *

@@ -1511,11 +1570,11 @@
       * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default int get(ValueLayout.OfInt layout, long offset) {
-         return (int) ((ValueLayouts.OfIntImpl) layout).accessHandle().get(this, offset);
+         return (int) layout.varHandle().get(this, offset);
      }
  
      /**
       * Writes an int into this segment at the given offset, with the given layout.
       *

@@ -1531,11 +1590,11 @@
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void set(ValueLayout.OfInt layout, long offset, int value) {
-         ((ValueLayouts.OfIntImpl) layout).accessHandle().set(this, offset, value);
+         layout.varHandle().set(this, offset, value);
      }
  
      /**
       * Reads a float from this segment at the given offset, with the given layout.
       *

@@ -1550,11 +1609,11 @@
       * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default float get(ValueLayout.OfFloat layout, long offset) {
-         return (float)((ValueLayouts.OfFloatImpl) layout).accessHandle().get(this, offset);
+         return (float)layout.varHandle().get(this, offset);
      }
  
      /**
       * Writes a float into this segment at the given offset, with the given layout.
       *

@@ -1570,11 +1629,11 @@
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void set(ValueLayout.OfFloat layout, long offset, float value) {
-         ((ValueLayouts.OfFloatImpl) layout).accessHandle().set(this, offset, value);
+         layout.varHandle().set(this, offset, value);
      }
  
      /**
       * Reads a long from this segment at the given offset, with the given layout.
       *

@@ -1589,11 +1648,11 @@
       * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default long get(ValueLayout.OfLong layout, long offset) {
-         return (long) ((ValueLayouts.OfLongImpl) layout).accessHandle().get(this, offset);
+         return (long) layout.varHandle().get(this, offset);
      }
  
      /**
       * Writes a long into this segment at the given offset, with the given layout.
       *

@@ -1609,11 +1668,11 @@
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void set(ValueLayout.OfLong layout, long offset, long value) {
-         ((ValueLayouts.OfLongImpl) layout).accessHandle().set(this, offset, value);
+         layout.varHandle().set(this, offset, value);
      }
  
      /**
       * Reads a double from this segment at the given offset, with the given layout.
       *

@@ -1628,11 +1687,11 @@
       * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default double get(ValueLayout.OfDouble layout, long offset) {
-         return (double) ((ValueLayouts.OfDoubleImpl) layout).accessHandle().get(this, offset);
+         return (double) layout.varHandle().get(this, offset);
      }
  
      /**
       * Writes a double into this segment at the given offset, with the given layout.
       *

@@ -1648,16 +1707,16 @@
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void set(ValueLayout.OfDouble layout, long offset, double value) {
-         ((ValueLayouts.OfDoubleImpl) layout).accessHandle().set(this, offset, value);
+         layout.varHandle().set(this, offset, value);
      }
  
      /**
       * Reads an address from this segment at the given offset, with the given layout. The read address is wrapped in
-      * a native segment, associated with a fresh scope that is always alive. Under normal conditions,
+      * a native segment, associated with a scope that is always alive. Under normal conditions,
       * the size of the returned segment is {@code 0}. However, if the provided address layout has a
       * {@linkplain AddressLayout#targetLayout() target layout} {@code T}, then the size of the returned segment
       * is set to {@code T.byteSize()}.
       * @param layout the layout of the region of memory to be read.
       * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.

@@ -1673,11 +1732,11 @@
       * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in {@code T}.
       * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default MemorySegment get(AddressLayout layout, long offset) {
-         return (MemorySegment) ((ValueLayouts.OfAddressImpl) layout).accessHandle().get(this, offset);
+         return (MemorySegment) layout.varHandle().get(this, offset);
      }
  
      /**
       * Writes an address into this segment at the given offset, with the given layout.
       *

@@ -1694,11 +1753,11 @@
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       * @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment.
       */
      @ForceInline
      default void set(AddressLayout layout, long offset, MemorySegment value) {
-         ((ValueLayouts.OfAddressImpl) layout).accessHandle().set(this, offset, value);
+         layout.varHandle().set(this, offset, value);
      }
  
      /**
       * Reads a byte from this segment at the given index, scaled by the given layout size.
       *

@@ -1709,20 +1768,20 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default byte getAtIndex(ValueLayout.OfByte layout, long index) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         return (byte) ((ValueLayouts.OfByteImpl) layout).accessHandle().get(this, index * layout.byteSize());
+         return (byte) layout.varHandle().get(this, index * layout.byteSize());
      }
  
      /**
       * Reads a boolean from this segment at the given index, scaled by the given layout size.
       *

@@ -1733,20 +1792,20 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default boolean getAtIndex(ValueLayout.OfBoolean layout, long index) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         return (boolean) ((ValueLayouts.OfBooleanImpl) layout).accessHandle().get(this, index * layout.byteSize());
+         return (boolean) layout.varHandle().get(this, index * layout.byteSize());
      }
  
      /**
       * Reads a char from this segment at the given index, scaled by the given layout size.
       *

@@ -1757,20 +1816,20 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default char getAtIndex(ValueLayout.OfChar layout, long index) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         return (char) ((ValueLayouts.OfCharImpl) layout).accessHandle().get(this, index * layout.byteSize());
+         return (char) layout.varHandle().get(this, index * layout.byteSize());
      }
  
      /**
       * Writes a char into this segment at the given index, scaled by the given layout size.
       *

@@ -1781,21 +1840,21 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void setAtIndex(ValueLayout.OfChar layout, long index, char value) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         ((ValueLayouts.OfCharImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
+         layout.varHandle().set(this, index * layout.byteSize(), value);
      }
  
      /**
       * Reads a short from this segment at the given index, scaled by the given layout size.
       *

@@ -1806,20 +1865,20 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default short getAtIndex(ValueLayout.OfShort layout, long index) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         return (short) ((ValueLayouts.OfShortImpl) layout).accessHandle().get(this, index * layout.byteSize());
+         return (short) layout.varHandle().get(this, index * layout.byteSize());
      }
  
      /**
       * Writes a byte into this segment at the given index, scaled by the given layout size.
       *

@@ -1830,21 +1889,21 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void setAtIndex(ValueLayout.OfByte layout, long index, byte value) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         ((ValueLayouts.OfByteImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
+         layout.varHandle().set(this, index * layout.byteSize(), value);
  
      }
  
      /**
       * Writes a boolean into this segment at the given index, scaled by the given layout size.

@@ -1856,21 +1915,21 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void setAtIndex(ValueLayout.OfBoolean layout, long index, boolean value) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         ((ValueLayouts.OfBooleanImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
+         layout.varHandle().set(this, index * layout.byteSize(), value);
      }
  
      /**
       * Writes a short into this segment at the given index, scaled by the given layout size.
       *

@@ -1881,21 +1940,21 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void setAtIndex(ValueLayout.OfShort layout, long index, short value) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         ((ValueLayouts.OfShortImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
+         layout.varHandle().set(this, index * layout.byteSize(), value);
      }
  
      /**
       * Reads an int from this segment at the given index, scaled by the given layout size.
       *

@@ -1906,20 +1965,20 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default int getAtIndex(ValueLayout.OfInt layout, long index) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         return (int) ((ValueLayouts.OfIntImpl) layout).accessHandle().get(this, index * layout.byteSize());
+         return (int) layout.varHandle().get(this, index * layout.byteSize());
      }
  
      /**
       * Writes an int into this segment at the given index, scaled by the given layout size.
       *

@@ -1930,21 +1989,21 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void setAtIndex(ValueLayout.OfInt layout, long index, int value) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         ((ValueLayouts.OfIntImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
+         layout.varHandle().set(this, index * layout.byteSize(), value);
      }
  
      /**
       * Reads a float from this segment at the given index, scaled by the given layout size.
       *

@@ -1955,20 +2014,20 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default float getAtIndex(ValueLayout.OfFloat layout, long index) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         return (float) ((ValueLayouts.OfFloatImpl) layout).accessHandle().get(this, index * layout.byteSize());
+         return (float) layout.varHandle().get(this, index * layout.byteSize());
      }
  
      /**
       * Writes a float into this segment at the given index, scaled by the given layout size.
       *

@@ -1979,21 +2038,21 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void setAtIndex(ValueLayout.OfFloat layout, long index, float value) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         ((ValueLayouts.OfFloatImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
+         layout.varHandle().set(this, index * layout.byteSize(), value);
      }
  
      /**
       * Reads a long from this segment at the given index, scaled by the given layout size.
       *

@@ -2004,20 +2063,20 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default long getAtIndex(ValueLayout.OfLong layout, long index) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         return (long) ((ValueLayouts.OfLongImpl) layout).accessHandle().get(this, index * layout.byteSize());
+         return (long) layout.varHandle().get(this, index * layout.byteSize());
      }
  
      /**
       * Writes a long into this segment at the given index, scaled by the given layout size.
       *

@@ -2028,21 +2087,21 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void setAtIndex(ValueLayout.OfLong layout, long index, long value) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         ((ValueLayouts.OfLongImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
+         layout.varHandle().set(this, index * layout.byteSize(), value);
      }
  
      /**
       * Reads a double from this segment at the given index, scaled by the given layout size.
       *

@@ -2053,20 +2112,20 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default double getAtIndex(ValueLayout.OfDouble layout, long index) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         return (double) ((ValueLayouts.OfDoubleImpl) layout).accessHandle().get(this, index * layout.byteSize());
+         return (double) layout.varHandle().get(this, index * layout.byteSize());
      }
  
      /**
       * Writes a double into this segment at the given index, scaled by the given layout size.
       *

@@ -2077,26 +2136,26 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       */
      @ForceInline
      default void setAtIndex(ValueLayout.OfDouble layout, long index, double value) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         ((ValueLayouts.OfDoubleImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
+         layout.varHandle().set(this, index * layout.byteSize(), value);
      }
  
      /**
       * Reads an address from this segment at the given at the given index, scaled by the given layout size. The read address is wrapped in
-      * a native segment, associated with a fresh scope that is always alive. Under normal conditions,
+      * a native segment, associated with a scope that is always alive. Under normal conditions,
       * the size of the returned segment is {@code 0}. However, if the provided address layout has a
       * {@linkplain AddressLayout#targetLayout() target layout} {@code T}, then the size of the returned segment
       * is set to {@code T.byteSize()}.
       * @param layout the layout of the region of memory to be read.
       * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation

@@ -2105,23 +2164,23 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IllegalArgumentException if provided address layout has a {@linkplain AddressLayout#targetLayout() target layout}
       * {@code T}, and the address of the returned segment
       * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in {@code T}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       */
      @ForceInline
      default MemorySegment getAtIndex(AddressLayout layout, long index) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         return (MemorySegment) ((ValueLayouts.OfAddressImpl) layout).accessHandle().get(this, index * layout.byteSize());
+         return (MemorySegment) layout.varHandle().get(this, index * layout.byteSize());
      }
  
      /**
       * Writes an address into this segment at the given index, scaled by the given layout size.
       *

@@ -2132,22 +2191,22 @@
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
       * such that {@code isAccessibleBy(T) == false}.
       * @throws IllegalArgumentException if the access operation is
-      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
-      * or if the layout alignment is greater than its size.
+      * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
+      * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
       * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
       * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
       * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
       * @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment.
       */
      @ForceInline
      default void setAtIndex(AddressLayout layout, long index, MemorySegment value) {
          Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
          // note: we know size is a small value (as it comes from ValueLayout::byteSize())
-         ((ValueLayouts.OfAddressImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
+         layout.varHandle().set(this, index * layout.byteSize(), value);
      }
  
      /**
       * Compares the specified object with this memory segment for equality. Returns {@code true} if and only if the specified
       * object is also a memory segment, and if the two segments refer to the same location, in some region of memory.

@@ -2192,11 +2251,11 @@
       * @param dstIndex the starting index of the destination array.
       * @param elementCount the number of array elements to be copied.
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
-      * such that {@code srcSegment().isAccessibleBy(T) == false}.
+      * such that {@code srcSegment.isAccessibleBy(T) == false}.
       * @throws  IllegalArgumentException if {@code dstArray} is not an array, or if it is an array but whose type is not supported.
       * @throws IllegalArgumentException if the destination array component type does not match {@code srcLayout.carrier()}.
       * @throws IllegalArgumentException if {@code offset} is <a href="MemorySegment.html#segment-alignment">incompatible
       * with the alignment constraint</a> in the source element layout.
       * @throws IllegalArgumentException if {@code srcLayout.byteAlignment() > srcLayout.byteSize()}.

@@ -2231,11 +2290,11 @@
       * @param dstOffset the starting offset, in bytes, of the destination segment.
       * @param elementCount the number of array elements to be copied.
       * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
       * {@linkplain Scope#isAlive() alive}.
       * @throws WrongThreadException if this method is called from a thread {@code T},
-      * such that {@code dstSegment().isAccessibleBy(T) == false}.
+      * such that {@code dstSegment.isAccessibleBy(T) == false}.
       * @throws  IllegalArgumentException if {@code srcArray} is not an array, or if it is an array but whose type is not supported.
       * @throws IllegalArgumentException if the source array component type does not match {@code srcLayout.carrier()}.
       * @throws IllegalArgumentException if {@code offset} is <a href="MemorySegment.html#segment-alignment">incompatible
       * with the alignment constraint</a> in the source element layout.
       * @throws IllegalArgumentException if {@code dstLayout.byteAlignment() > dstLayout.byteSize()}.

@@ -2305,12 +2364,31 @@
       * cannot be accessed if its associated scope is not {@linkplain #isAlive() alive}. A new scope is typically
       * obtained indirectly, by creating a new {@linkplain Arena arena}.
       * <p>
       * Scope instances can be compared for equality. That is, two scopes
       * are considered {@linkplain #equals(Object)} if they denote the same lifetime.
+      * <p>
+      * If two memory segments are obtained from the same {@linkplain #ofBuffer(Buffer) buffer}
+      * or {@linkplain #ofArray(int[]) array}, the scopes associated with said segments are considered
+      * {@linkplain #equals(Object) equal}, as the two segments have the same lifetime:
+      * {@snippet lang=java :
+      * byte[] arr = new byte[10];
+      * MemorySegment segment1 = MemorySegment.ofArray(arr);
+      * MemorySegment segment2 = MemorySegment.ofArray(arr);
+      * assert segment1.scope().equals(segment2.scope());
+      * }
+      * <p>
+      * If two distinct memory segments are <a href="#wrapping-addresses">zero-length memory segments</a>, their scopes
+      * are always considered {@linkplain #equals(Object) equal}:
+      * {@snippet lang=java :
+      * MemorySegment segment1 = MemorySegment.ofAddress(42L);
+      * MemorySegment segment2 = MemorySegment.ofAddress(1000L);
+      * assert segment1.scope().equals(segment2.scope());
+      * }
+      * The scope of a zero-length memory segment can always be overridden using the
+      * {@link MemorySegment#reinterpret(Arena, Consumer)} method.
       */
-     @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
      sealed interface Scope permits MemorySessionImpl {
          /**
           * {@return {@code true}, if the regions of memory backing the memory segments associated with this scope are
           * still valid}
           */
< prev index next >