9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.foreign;
27
28 import java.io.UncheckedIOException;
29 import java.lang.foreign.Linker.Option;
30 import java.lang.invoke.MethodHandle;
31 import java.lang.invoke.MethodHandles;
32 import java.nio.Buffer;
33 import java.nio.ByteBuffer;
34 import java.nio.ByteOrder;
35 import java.nio.CharBuffer;
36 import java.nio.channels.FileChannel;
37 import java.nio.channels.FileChannel.*;
38 import java.nio.charset.StandardCharsets;
39 import java.util.Arrays;
40 import java.util.Objects;
41 import java.util.Optional;
42 import java.util.Spliterator;
43 import java.util.function.Consumer;
44 import java.util.stream.Stream;
45 import jdk.internal.foreign.AbstractMemorySegmentImpl;
46 import jdk.internal.foreign.HeapMemorySegmentImpl;
47 import jdk.internal.foreign.MemorySessionImpl;
48 import jdk.internal.foreign.NativeMemorySegmentImpl;
49 import jdk.internal.foreign.Utils;
50 import jdk.internal.foreign.abi.SharedUtils;
51 import jdk.internal.foreign.layout.ValueLayouts;
52 import jdk.internal.javac.PreviewFeature;
53 import jdk.internal.reflect.CallerSensitive;
54 import jdk.internal.vm.annotation.ForceInline;
55
56 /**
57 * A memory segment provides access to a contiguous region of memory.
58 * <p>
59 * There are two kinds of memory segments:
60 * <ul>
61 * <li>A <em>heap segment</em> is backed by, and provides access to, a region of memory inside the Java heap (an "on-heap" region).</li>
62 * <li>A <em>native segment</em> is backed by, and provides access to, a region of memory outside the Java heap (an "off-heap" region).</li>
63 * </ul>
64 * Heap segments can be obtained by calling one of the {@link MemorySegment#ofArray(int[])} factory methods.
65 * These methods return a memory segment backed by the on-heap region that holds the specified Java array.
66 * <p>
67 * Native segments can be obtained by calling one of the {@link Arena#allocate(long, long)}
68 * factory methods, which return a memory segment backed by a newly allocated off-heap region with the given size
69 * and aligned to the given alignment constraint. Alternatively, native segments can be obtained by
70 * {@link FileChannel#map(MapMode, long, long, Arena) mapping} a file into a new off-heap region
71 * (in some systems, this operation is sometimes referred to as {@code mmap}).
72 * Segments obtained in this way are called <em>mapped</em> segments, and their contents can be {@linkplain #force() persisted} and
110 * <a href="Arena.html#thread-confinement">confinement characteristics</a> of the arena used to obtain them.
111 *
112 * <h2 id="segment-deref">Accessing memory segments</h2>
113 *
114 * A memory segment can be read or written using various access operations provided in this class (e.g. {@link #get(ValueLayout.OfInt, long)}).
115 * Each access operation takes a {@linkplain ValueLayout value layout}, which specifies the size and shape of the value,
116 * and an offset, expressed in bytes.
117 * For instance, to read an int from a segment, using {@linkplain ByteOrder#nativeOrder() default endianness}, the following code can be used:
118 * {@snippet lang=java :
119 * MemorySegment segment = ...
120 * int value = segment.get(ValueLayout.JAVA_INT, 0);
121 * }
122 *
123 * If the value to be read is stored in memory using {@linkplain ByteOrder#BIG_ENDIAN big-endian} encoding, the access operation
124 * can be expressed as follows:
125 * {@snippet lang=java :
126 * MemorySegment segment = ...
127 * int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0);
128 * }
129 *
130 * For more complex access operations (e.g. structured memory access), clients can obtain a
131 * {@linkplain MethodHandles#memorySegmentViewVarHandle(ValueLayout) var handle}
132 * that accepts a segment and a {@code long} offset. More complex var handles
133 * can be obtained by adapting a segment var handle view using the var handle combinator functions defined in the
134 * {@link java.lang.invoke.MethodHandles} class:
135 *
136 * {@snippet lang=java :
137 * MemorySegment segment = ...
138 * VarHandle intHandle = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_INT);
139 * MethodHandle multiplyExact = MethodHandles.lookup()
140 * .findStatic(Math.class, "multiplyExact",
141 * MethodType.methodType(long.class, long.class, long.class));
142 * intHandle = MethodHandles.filterCoordinates(intHandle, 1,
143 * MethodHandles.insertArguments(multiplyExact, 0, ValueLayout.JAVA_INT.byteSize()));
144 * int value = (int) intHandle.get(segment, 3L); // get int element at offset 3 * 4 = 12
145 * }
146 *
147 * Alternatively, complex var handles can can be obtained
148 * from {@linkplain MemoryLayout#varHandle(MemoryLayout.PathElement...) memory layouts}
149 * by providing a so called <a href="MemoryLayout.html#layout-paths"><em>layout path</em></a>:
150 *
151 * {@snippet lang=java :
152 * MemorySegment segment = ...
153 * VarHandle intHandle = ValueLayout.JAVA_INT.arrayElementVarHandle();
154 * int value = (int) intHandle.get(segment, 3L); // get int element at offset 3 * 4 = 12
155 * }
156 *
157 * <h2 id="slicing">Slicing memory segments</h2>
158 *
159 * Memory segments support {@linkplain MemorySegment#asSlice(long, long) slicing}. Slicing a memory segment
160 * returns a new memory segment that is backed by the same region of memory as the original. The address of the sliced
161 * segment is derived from the address of the original segment, by adding an offset (expressed in bytes). The size of
162 * the sliced segment is either derived implicitly (by subtracting the specified offset from the size of the original segment),
163 * or provided explicitly. In other words, a sliced segment has <em>stricter</em> spatial bounds than those of the original segment:
164 * {@snippet lang = java:
165 * Arena arena = ...
166 * MemorySegment segment = arena.allocate(100);
167 * MemorySegment slice = segment.asSlice(50, 10);
168 * slice.get(ValueLayout.JAVA_INT, 20); // Out of bounds!
169 * arena.close();
170 * slice.get(ValueLayout.JAVA_INT, 0); // Already closed!
171 *}
172 * The above code creates a native segment that is 100 bytes long; then, it creates a slice that starts at offset 50
173 * of {@code segment}, and is 10 bytes long. That is, the address of the {@code slice} is {@code segment.address() + 50},
174 * and its size is 10. As a result, attempting to read an int value at offset 20 of the
175 * {@code slice} segment will result in an exception. The {@linkplain Arena temporal bounds} of the original segment
416 * of the segment is the same as the size of the target layout. In other words, the returned segment is no
417 * longer a zero-length memory segment, and the pointer it represents can be dereferenced directly:
418 *
419 * {@snippet lang = java:
420 * AddressLayout intArrPtrLayout = ValueLayout.ADDRESS.withTargetLayout(
421 * MemoryLayout.sequenceLayout(4, ValueLayout.JAVA_INT)); // layout for int (*ptr)[4]
422 * MemorySegment ptr = segment.get(intArrPtrLayout, ...); // size = 16
423 * int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // ok
424 *}
425 * <p>
426 * All the methods which can be used to manipulate zero-length memory segments
427 * ({@link #reinterpret(long)}, {@link #reinterpret(Arena, Consumer)}, {@link #reinterpret(long, Arena, Consumer)} and
428 * {@link AddressLayout#withTargetLayout(MemoryLayout)}) are
429 * <a href="package-summary.html#restricted"><em>restricted</em></a> methods, and should be used with caution:
430 * assigning a segment incorrect spatial and/or temporal bounds could result in a VM crash when attempting to access
431 * the memory segment.
432 *
433 * @implSpec
434 * Implementations of this interface are immutable, thread-safe and <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>.
435 *
436 * @since 19
437 */
438 @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
439 public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
440
441 /**
442 * {@return the address of this memory segment}
443 *
444 * @apiNote When using this method to pass a segment address to some external operation (e.g. a JNI function),
445 * clients must ensure that the segment is kept <a href="../../../java/lang/ref/package.html#reachability">reachable</a>
446 * for the entire duration of the operation. A failure to do so might result in the premature deallocation of the
447 * region of memory backing the memory segment, in case the segment has been allocated with an
448 * {@linkplain Arena#ofAuto() automatic arena}.
449 */
450 long address();
451
452 /**
453 * Returns the Java object stored in the on-heap region of memory backing this memory segment, if any. For instance, if this
454 * memory segment is a heap segment created with the {@link #ofArray(byte[])} factory method, this method will return the
455 * {@code byte[]} object which was used to obtain the segment. This method returns an empty {@code Optional} value
456 * if either this segment is a {@linkplain #isNative() native} segment, or if this segment is {@linkplain #isReadOnly() read-only}.
457 * @return the Java object associated with this memory segment, if any.
458 */
579 * of this segment plus the given offset; its size is computed by subtracting the specified offset from this segment size.
580 * <p>
581 * Equivalent to the following code:
582 * {@snippet lang=java :
583 * asSlice(offset, byteSize() - offset);
584 * }
585 *
586 * @see #asSlice(long, long)
587 *
588 * @param offset The new segment base offset (relative to the address of this segment), specified in bytes.
589 * @return a slice of this memory segment.
590 * @throws IndexOutOfBoundsException if {@code offset < 0}, or {@code offset > byteSize()}.
591 */
592 MemorySegment asSlice(long offset);
593
594 /**
595 * Returns a new memory segment that has the same address and scope as this segment, but with the provided size.
596 * <p>
597 * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
598 * Restricted methods are unsafe, and, if used incorrectly, their use might crash
599 * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on
600 * restricted methods, and use safe and supported functionalities, where possible.
601 *
602 * @param newSize the size of the returned segment.
603 * @return a new memory segment that has the same address and scope as this segment, but the new
604 * provided size.
605 * @throws IllegalArgumentException if {@code newSize < 0}.
606 * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment.
607 * @throws IllegalCallerException If the caller is in a module that does not have native access enabled.
608 */
609 @CallerSensitive
610 MemorySegment reinterpret(long newSize);
611
612 /**
613 * Returns a new memory segment with the same address and size as this segment, but with the provided scope.
614 * As such, the returned segment cannot be accessed after the provided arena has been closed.
615 * Moreover, the returned segment can be accessed compatibly with the confinement restrictions associated with the
616 * provided arena: that is, if the provided arena is a {@linkplain Arena#ofConfined() confined arena},
617 * the returned segment can only be accessed by the arena's owner thread, regardless of the confinement restrictions
618 * associated with this segment. In other words, this method returns a segment that behaves as if it had been allocated
619 * using the provided arena.
620 * <p>
621 * Clients can specify an optional cleanup action that should be executed when the provided scope becomes
622 * invalid. This cleanup action receives a fresh memory segment that is obtained from this segment as follows:
623 * {@snippet lang=java :
624 * MemorySegment cleanupSegment = MemorySegment.ofAddress(this.address())
625 * .reinterpret(byteSize());
626 * }
627 * That is, the cleanup action receives a segment that is associated with a fresh scope that is always alive,
628 * and is accessible from any thread. The size of the segment accepted by the cleanup action is {@link #byteSize()}.
629 * <p>
630 * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
631 * Restricted methods are unsafe, and, if used incorrectly, their use might crash
632 * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on
633 * restricted methods, and use safe and supported functionalities, where possible.
634 *
635 * @apiNote The cleanup action (if present) should take care not to leak the received segment to external
636 * clients which might access the segment after its backing region of memory is no longer available. Furthermore,
637 * if the provided scope is the scope of an {@linkplain Arena#ofAuto() automatic arena}, the cleanup action
638 * must not prevent the scope from becoming <a href="../../../java/lang/ref/package.html#reachability">unreachable</a>.
639 * A failure to do so will permanently prevent the regions of memory allocated by the automatic arena from being deallocated.
640 *
641 * @param arena the arena to be associated with the returned segment.
642 * @param cleanup the cleanup action that should be executed when the provided arena is closed (can be {@code null}).
643 * @return a new memory segment with unbounded size.
644 * @throws IllegalStateException if {@code arena.scope().isAlive() == false}.
645 * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment.
646 * @throws IllegalCallerException If the caller is in a module that does not have native access enabled.
647 */
648 @CallerSensitive
649 MemorySegment reinterpret(Arena arena, Consumer<MemorySegment> cleanup);
650
651 /**
652 * Returns a new segment with the same address as this segment, but with the provided size and scope.
653 * As such, the returned segment cannot be accessed after the provided arena has been closed.
654 * Moreover, if the returned segment can be accessed compatibly with the confinement restrictions associated with the
655 * provided arena: that is, if the provided arena is a {@linkplain Arena#ofConfined() confined arena},
656 * the returned segment can only be accessed by the arena's owner thread, regardless of the confinement restrictions
657 * associated with this segment. In other words, this method returns a segment that behaves as if it had been allocated
658 * using the provided arena.
659 * <p>
660 * Clients can specify an optional cleanup action that should be executed when the provided scope becomes
661 * invalid. This cleanup action receives a fresh memory segment that is obtained from this segment as follows:
662 * {@snippet lang=java :
663 * MemorySegment cleanupSegment = MemorySegment.ofAddress(this.address())
664 * .reinterpret(newSize);
665 * }
666 * That is, the cleanup action receives a segment that is associated with a fresh scope that is always alive,
667 * and is accessible from any thread. The size of the segment accepted by the cleanup action is {@code newSize}.
668 * <p>
669 * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
670 * Restricted methods are unsafe, and, if used incorrectly, their use might crash
671 * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on
672 * restricted methods, and use safe and supported functionalities, where possible.
673 *
674 * @apiNote The cleanup action (if present) should take care not to leak the received segment to external
675 * clients which might access the segment after its backing region of memory is no longer available. Furthermore,
676 * if the provided scope is the scope of an {@linkplain Arena#ofAuto() automatic arena}, the cleanup action
677 * must not prevent the scope from becoming <a href="../../../java/lang/ref/package.html#reachability">unreachable</a>.
678 * A failure to do so will permanently prevent the regions of memory allocated by the automatic arena from being deallocated.
679 *
680 * @param newSize the size of the returned segment.
681 * @param arena the arena to be associated with the returned segment.
682 * @param cleanup the cleanup action that should be executed when the provided arena is closed (can be {@code null}).
683 * @return a new segment that has the same address as this segment, but with new size and its scope set to
684 * that of the provided arena.
685 * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment.
686 * @throws IllegalArgumentException if {@code newSize < 0}.
687 * @throws IllegalStateException if {@code arena.scope().isAlive() == false}.
688 * @throws IllegalCallerException If the caller is in a module that does not have native access enabled.
689 */
690 @CallerSensitive
691 MemorySegment reinterpret(long newSize, Arena arena, Consumer<MemorySegment> cleanup);
692
718 * {@linkplain #ofBuffer(Buffer) wrapping} a {@linkplain java.nio.MappedByteBuffer mapped byte buffer}.
719 * @return {@code true} if this segment is a mapped segment.
720 */
721 boolean isMapped();
722
723 /**
724 * Returns a slice of this segment that is the overlap between this and
725 * the provided segment.
726 *
727 * <p>Two segments {@code S1} and {@code S2} are said to overlap if it is possible to find
728 * at least two slices {@code L1} (from {@code S1}) and {@code L2} (from {@code S2}) that are backed by the
729 * same region of memory. As such, it is not possible for a
730 * {@linkplain #isNative() native} segment to overlap with a heap segment; in
731 * this case, or when no overlap occurs, an empty {@code Optional} is returned.
732 *
733 * @param other the segment to test for an overlap with this segment.
734 * @return a slice of this segment (where overlapping occurs).
735 */
736 Optional<MemorySegment> asOverlappingSlice(MemorySegment other);
737
738 /**
739 * Returns the offset, in bytes, of the provided segment, relative to this
740 * segment.
741 *
742 * <p>The offset is relative to the address of this segment and can be
743 * a negative or positive value. For instance, if both segments are native
744 * segments, or heap segments backed by the same array, the resulting offset
745 * can be computed as follows:
746 *
747 * {@snippet lang=java :
748 * other.address() - address()
749 * }
750 *
751 * If the segments share the same address, {@code 0} is returned. If
752 * {@code other} is a slice of this segment, the offset is always
753 * {@code 0 <= x < this.byteSize()}.
754 *
755 * @param other the segment to retrieve an offset to.
756 * @throws UnsupportedOperationException if the two segments cannot be compared, e.g. because they are of
757 * different kinds, or because they are backed by different Java arrays.
758 * @return the relative offset, in bytes, of the provided segment.
759 */
760 long segmentOffset(MemorySegment other);
761
762 /**
763 * Fills the contents of this memory segment with the given value.
764 * <p>
765 * More specifically, the given value is written into each address of this
766 * segment. Equivalent to (but likely more efficient than) the following code:
767 *
768 * {@snippet lang=java :
769 * for (long offset = 0; offset < segment.byteSize(); offset++) {
770 * byteHandle.set(ValueLayout.JAVA_BYTE, offset, value);
771 * }
772 * }
773 *
774 * But without any regard or guarantees on the ordering of particular memory
775 * elements being set.
776 * <p>
777 * This method can be useful to initialize or reset the contents of a memory segment.
778 *
779 * @param value the value to write into this segment.
780 * @return this memory segment.
781 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
782 * {@linkplain Scope#isAlive() alive}.
783 * @throws WrongThreadException if this method is called from a thread {@code T},
784 * such that {@code isAccessibleBy(T) == false}.
785 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
786 */
787 MemorySegment fill(byte value);
788
789 /**
790 * Performs a bulk copy from given source segment to this segment. More specifically, the bytes at
1051 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code long[]} instance,
1052 * e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer.MAX_VALUE}.
1053 */
1054 long[] toArray(ValueLayout.OfLong elementLayout);
1055
1056 /**
1057 * Copy the contents of this memory segment into a new double array.
1058 * @param elementLayout the source element layout. If the byte order associated with the layout is
1059 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element.
1060 * @return a new double array whose contents are copied from this memory segment.
1061 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1062 * {@linkplain Scope#isAlive() alive}.
1063 * @throws WrongThreadException if this method is called from a thread {@code T},
1064 * such that {@code isAccessibleBy(T) == false}.
1065 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code double[]} instance,
1066 * e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer.MAX_VALUE}.
1067 */
1068 double[] toArray(ValueLayout.OfDouble elementLayout);
1069
1070 /**
1071 * Reads a UTF-8 encoded, null-terminated string from this segment at the given offset.
1072 * <p>
1073 * This method always replaces malformed-input and unmappable-character
1074 * sequences with this charset's default replacement string. The {@link
1075 * java.nio.charset.CharsetDecoder} class should be used when more control
1076 * over the decoding process is required.
1077 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1078 * @return a Java string constructed from the bytes read from the given starting address up to (but not including)
1079 * the first {@code '\0'} terminator character (assuming one is found).
1080 * @throws IllegalArgumentException if the size of the UTF-8 string is greater than the largest string supported by the platform.
1081 * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code offset > byteSize() - S}, where {@code S} is the size of the UTF-8
1082 * string (including the terminator character).
1083 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1084 * {@linkplain Scope#isAlive() alive}.
1085 * @throws WrongThreadException if this method is called from a thread {@code T},
1086 * such that {@code isAccessibleBy(T) == false}.
1087 */
1088 default String getUtf8String(long offset) {
1089 return SharedUtils.toJavaStringInternal(this, offset);
1090 }
1091
1092 /**
1093 * Writes the given string into this segment at the given offset, converting it to a null-terminated byte sequence using UTF-8 encoding.
1094 * <p>
1095 * This method always replaces malformed-input and unmappable-character
1096 * sequences with this charset's default replacement string. The {@link
1097 * java.nio.charset.CharsetDecoder} class should be used when more control
1098 * over the decoding process is required.
1099 * <p>
1100 * If the given string contains any {@code '\0'} characters, they will be
1101 * copied as well. This means that, depending on the method used to read
1102 * the string, such as {@link MemorySegment#getUtf8String(long)}, the string
1103 * will appear truncated when read again.
1104 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1105 * the final address of this write operation can be expressed as {@code address() + offset}.
1106 * @param str the Java string to be written into this segment.
1107 * @throws IndexOutOfBoundsException if {@code offset < 0} or {@code offset > byteSize() - str.getBytes().length() + 1}.
1108 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1109 * {@linkplain Scope#isAlive() alive}.
1110 * @throws WrongThreadException if this method is called from a thread {@code T},
1111 * such that {@code isAccessibleBy(T) == false}.
1112 */
1113 default void setUtf8String(long offset, String str) {
1114 Utils.toCString(str.getBytes(StandardCharsets.UTF_8), SegmentAllocator.prefixAllocator(asSlice(offset)));
1115 }
1116
1117
1118 /**
1119 * Creates a memory segment that is backed by the same region of memory that backs the given {@link Buffer} instance.
1120 * The segment starts relative to the buffer's position (inclusive) and ends relative to the buffer's limit (exclusive).
1121 * <p>
1122 * If the buffer is {@linkplain Buffer#isReadOnly() read-only}, the resulting segment is also
1123 * {@linkplain ByteBuffer#isReadOnly() read-only}. Moreover, if the buffer is a {@linkplain Buffer#isDirect() direct buffer},
1124 * the returned segment is a native segment; otherwise the returned memory segment is a heap segment.
1125 * <p>
1126 * If the provided buffer has been obtained by calling {@link #asByteBuffer()} on a memory segment whose
1127 * {@linkplain Scope scope} is {@code S}, the returned segment will be associated with the
1128 * same scope {@code S}. Otherwise, the scope of the returned segment is a fresh scope that is always alive.
1129 * <p>
1130 * The scope associated with the returned segment keeps the provided buffer reachable. As such, if
1131 * the provided buffer is a direct buffer, its backing memory region will not be deallocated as long as the
1132 * returned segment (or any of its slices) are kept reachable.
1133 *
1134 * @param buffer the buffer instance to be turned into a new memory segment.
1135 * @return a memory segment, derived from the given buffer instance.
1136 * @throws IllegalArgumentException if the provided {@code buffer} is a heap buffer but is not backed by an array.
1260 * do not overlap, but refer to overlapping regions of the same backing storage using different addresses.
1261 * For example, this may occur if the same file is {@linkplain FileChannel#map mapped} to two segments.
1262 * <p>
1263 * Calling this method is equivalent to the following code:
1264 * {@snippet lang=java :
1265 * MemorySegment.copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes);
1266 * }
1267 * @param srcSegment the source segment.
1268 * @param srcOffset the starting offset, in bytes, of the source segment.
1269 * @param dstSegment the destination segment.
1270 * @param dstOffset the starting offset, in bytes, of the destination segment.
1271 * @param bytes the number of bytes to be copied.
1272 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not
1273 * {@linkplain Scope#isAlive() alive}.
1274 * @throws WrongThreadException if this method is called from a thread {@code T},
1275 * such that {@code srcSegment.isAccessibleBy(T) == false}.
1276 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
1277 * {@linkplain Scope#isAlive() alive}.
1278 * @throws WrongThreadException if this method is called from a thread {@code T},
1279 * such that {@code dstSegment.isAccessibleBy(T) == false}.
1280 * @throws IndexOutOfBoundsException if {@code srcOffset > srcSegment.byteSize() - bytes} or if
1281 * {@code dstOffset > dstSegment.byteSize() - bytes}, or if either {@code srcOffset}, {@code dstOffset}
1282 * or {@code bytes} are {@code < 0}.
1283 * @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}.
1284 */
1285 @ForceInline
1286 static void copy(MemorySegment srcSegment, long srcOffset,
1287 MemorySegment dstSegment, long dstOffset, long bytes) {
1288 copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes);
1289 }
1290
1291 /**
1292 * Performs a bulk copy from source segment to destination segment. More specifically, if {@code S} is the byte size
1293 * of the element layouts, the bytes at offset {@code srcOffset} through {@code srcOffset + (elementCount * S) - 1}
1294 * in the source segment are copied into the destination segment at offset {@code dstOffset} through {@code dstOffset + (elementCount * S) - 1}.
1295 * <p>
1296 * The copy occurs in an element-wise fashion: the bytes in the source segment are interpreted as a sequence of elements
1297 * whose layout is {@code srcElementLayout}, whereas the bytes in the destination segment are interpreted as a sequence of
1298 * elements whose layout is {@code dstElementLayout}. Both element layouts must have same size {@code S}.
1299 * If the byte order of the two element layouts differ, the bytes corresponding to each element to be copied
1300 * are swapped accordingly during the copy operation.
1301 * <p>
1302 * If the source segment overlaps with the destination segment, then the copying is performed as if the bytes at
1303 * offset {@code srcOffset} through {@code srcOffset + (elementCount * S) - 1} in the source segment were first copied into a
1304 * temporary segment with size {@code bytes}, and then the contents of the temporary segment were copied into
1305 * the destination segment at offset {@code dstOffset} through {@code dstOffset + (elementCount * S) - 1}.
1306 * <p>
1307 * The result of a bulk copy is unspecified if, in the uncommon case, the source segment and the destination segment
1308 * do not overlap, but refer to overlapping regions of the same backing storage using different addresses.
1309 * For example, this may occur if the same file is {@linkplain FileChannel#map mapped} to two segments.
1310 * @param srcSegment the source segment.
1311 * @param srcElementLayout the element layout associated with the source segment.
1312 * @param srcOffset the starting offset, in bytes, of the source segment.
1313 * @param dstSegment the destination segment.
1314 * @param dstElementLayout the element layout associated with the destination segment.
1315 * @param dstOffset the starting offset, in bytes, of the destination segment.
1316 * @param elementCount the number of elements to be copied.
1317 * @throws IllegalArgumentException if the element layouts have different sizes, if the source (resp. destination) segment/offset are
1318 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the source
1319 * (resp. destination) element layout, or if the source (resp. destination) element layout alignment is greater than its size.
1320 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not
1321 * {@linkplain Scope#isAlive() alive}.
1322 * @throws WrongThreadException if this method is called from a thread {@code T},
1323 * such that {@code srcSegment().isAccessibleBy(T) == false}.
1324 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
1325 * {@linkplain Scope#isAlive() alive}.
1326 * @throws WrongThreadException if this method is called from a thread {@code T},
1327 * such that {@code dstSegment().isAccessibleBy(T) == false}.
1328 * @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}.
1329 * @throws IndexOutOfBoundsException if {@code elementCount * srcLayout.byteSize()} or {@code elementCount * dtsLayout.byteSize()} overflows.
1330 * @throws IndexOutOfBoundsException if {@code dstOffset > dstSegment.byteSize() - (elementCount * dstLayout.byteSize())}.
1331 * @throws IndexOutOfBoundsException if either {@code srcOffset}, {@code dstOffset} or {@code elementCount} are {@code < 0}.
1332 */
1333 @ForceInline
1334 static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long srcOffset,
1335 MemorySegment dstSegment, ValueLayout dstElementLayout, long dstOffset,
1336 long elementCount) {
1337 Objects.requireNonNull(srcSegment);
1338 Objects.requireNonNull(srcElementLayout);
1339 Objects.requireNonNull(dstSegment);
1340 Objects.requireNonNull(dstElementLayout);
1341 AbstractMemorySegmentImpl.copy(srcSegment, srcElementLayout, srcOffset, dstSegment, dstElementLayout, dstOffset, elementCount);
1342 }
1343
1344 /**
1345 * Reads a byte from this segment at the given offset, with the given layout.
1346 *
1347 * @param layout the layout of the region of memory to be read.
1348 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1349 * @return a byte value read from this segment.
1350 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1351 * {@linkplain Scope#isAlive() alive}.
1352 * @throws WrongThreadException if this method is called from a thread {@code T},
1353 * such that {@code isAccessibleBy(T) == false}.
1354 * @throws IllegalArgumentException if the access operation is
1355 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1356 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1357 */
1358 @ForceInline
1359 default byte get(ValueLayout.OfByte layout, long offset) {
1360 return (byte) ((ValueLayouts.OfByteImpl) layout).accessHandle().get(this, offset);
1361 }
1362
1363 /**
1364 * Writes a byte into this segment at the given offset, with the given layout.
1365 *
1366 * @param layout the layout of the region of memory to be written.
1367 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1368 * @param value the byte value to be written.
1369 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1370 * {@linkplain Scope#isAlive() alive}.
1371 * @throws WrongThreadException if this method is called from a thread {@code T},
1372 * such that {@code isAccessibleBy(T) == false}.
1373 * @throws IllegalArgumentException if the access operation is
1374 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1375 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1376 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1377 */
1378 @ForceInline
1379 default void set(ValueLayout.OfByte layout, long offset, byte value) {
1380 ((ValueLayouts.OfByteImpl) layout).accessHandle().set(this, offset, value);
1381 }
1382
1383 /**
1384 * Reads a boolean from this segment at the given offset, with the given layout.
1385 *
1386 * @param layout the layout of the region of memory to be read.
1387 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1388 * @return a boolean value read from this segment.
1389 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1390 * {@linkplain Scope#isAlive() alive}.
1391 * @throws WrongThreadException if this method is called from a thread {@code T},
1392 * such that {@code isAccessibleBy(T) == false}.
1393 * @throws IllegalArgumentException if the access operation is
1394 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1395 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1396 */
1397 @ForceInline
1398 default boolean get(ValueLayout.OfBoolean layout, long offset) {
1399 return (boolean) ((ValueLayouts.OfBooleanImpl) layout).accessHandle().get(this, offset);
1400 }
1401
1402 /**
1403 * Writes a boolean into this segment at the given offset, with the given layout.
1404 *
1405 * @param layout the layout of the region of memory to be written.
1406 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1407 * @param value the boolean value to be written.
1408 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1409 * {@linkplain Scope#isAlive() alive}.
1410 * @throws WrongThreadException if this method is called from a thread {@code T},
1411 * such that {@code isAccessibleBy(T) == false}.
1412 * @throws IllegalArgumentException if the access operation is
1413 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1414 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1415 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1416 */
1417 @ForceInline
1418 default void set(ValueLayout.OfBoolean layout, long offset, boolean value) {
1419 ((ValueLayouts.OfBooleanImpl) layout).accessHandle().set(this, offset, value);
1420 }
1421
1422 /**
1423 * Reads a char from this segment at the given offset, with the given layout.
1424 *
1425 * @param layout the layout of the region of memory to be read.
1426 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1427 * @return a char value read from this segment.
1428 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1429 * {@linkplain Scope#isAlive() alive}.
1430 * @throws WrongThreadException if this method is called from a thread {@code T},
1431 * such that {@code isAccessibleBy(T) == false}.
1432 * @throws IllegalArgumentException if the access operation is
1433 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1434 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1435 */
1436 @ForceInline
1437 default char get(ValueLayout.OfChar layout, long offset) {
1438 return (char) ((ValueLayouts.OfCharImpl) layout).accessHandle().get(this, offset);
1439 }
1440
1441 /**
1442 * Writes a char into this segment at the given offset, with the given layout.
1443 *
1444 * @param layout the layout of the region of memory to be written.
1445 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1446 * @param value the char value to be written.
1447 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1448 * {@linkplain Scope#isAlive() alive}.
1449 * @throws WrongThreadException if this method is called from a thread {@code T},
1450 * such that {@code isAccessibleBy(T) == false}.
1451 * @throws IllegalArgumentException if the access operation is
1452 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1453 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1454 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1455 */
1456 @ForceInline
1457 default void set(ValueLayout.OfChar layout, long offset, char value) {
1458 ((ValueLayouts.OfCharImpl) layout).accessHandle().set(this, offset, value);
1459 }
1460
1461 /**
1462 * Reads a short from this segment at the given offset, with the given layout.
1463 *
1464 * @param layout the layout of the region of memory to be read.
1465 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1466 * @return a short value read from this segment.
1467 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1468 * {@linkplain Scope#isAlive() alive}.
1469 * @throws WrongThreadException if this method is called from a thread {@code T},
1470 * such that {@code isAccessibleBy(T) == false}.
1471 * @throws IllegalArgumentException if the access operation is
1472 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1473 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1474 */
1475 @ForceInline
1476 default short get(ValueLayout.OfShort layout, long offset) {
1477 return (short) ((ValueLayouts.OfShortImpl) layout).accessHandle().get(this, offset);
1478 }
1479
1480 /**
1481 * Writes a short into this segment at the given offset, with the given layout.
1482 *
1483 * @param layout the layout of the region of memory to be written.
1484 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1485 * @param value the short value to be written.
1486 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1487 * {@linkplain Scope#isAlive() alive}.
1488 * @throws WrongThreadException if this method is called from a thread {@code T},
1489 * such that {@code isAccessibleBy(T) == false}.
1490 * @throws IllegalArgumentException if the access operation is
1491 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1492 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1493 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1494 */
1495 @ForceInline
1496 default void set(ValueLayout.OfShort layout, long offset, short value) {
1497 ((ValueLayouts.OfShortImpl) layout).accessHandle().set(this, offset, value);
1498 }
1499
1500 /**
1501 * Reads an int from this segment at the given offset, with the given layout.
1502 *
1503 * @param layout the layout of the region of memory to be read.
1504 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1505 * @return an int value read from this segment.
1506 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1507 * {@linkplain Scope#isAlive() alive}.
1508 * @throws WrongThreadException if this method is called from a thread {@code T},
1509 * such that {@code isAccessibleBy(T) == false}.
1510 * @throws IllegalArgumentException if the access operation is
1511 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1512 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1513 */
1514 @ForceInline
1515 default int get(ValueLayout.OfInt layout, long offset) {
1516 return (int) ((ValueLayouts.OfIntImpl) layout).accessHandle().get(this, offset);
1517 }
1518
1519 /**
1520 * Writes an int into this segment at the given offset, with the given layout.
1521 *
1522 * @param layout the layout of the region of memory to be written.
1523 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1524 * @param value the int value to be written.
1525 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1526 * {@linkplain Scope#isAlive() alive}.
1527 * @throws WrongThreadException if this method is called from a thread {@code T},
1528 * such that {@code isAccessibleBy(T) == false}.
1529 * @throws IllegalArgumentException if the access operation is
1530 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1531 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1532 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1533 */
1534 @ForceInline
1535 default void set(ValueLayout.OfInt layout, long offset, int value) {
1536 ((ValueLayouts.OfIntImpl) layout).accessHandle().set(this, offset, value);
1537 }
1538
1539 /**
1540 * Reads a float from this segment at the given offset, with the given layout.
1541 *
1542 * @param layout the layout of the region of memory to be read.
1543 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1544 * @return a float value read from this segment.
1545 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1546 * {@linkplain Scope#isAlive() alive}.
1547 * @throws WrongThreadException if this method is called from a thread {@code T},
1548 * such that {@code isAccessibleBy(T) == false}.
1549 * @throws IllegalArgumentException if the access operation is
1550 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1551 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1552 */
1553 @ForceInline
1554 default float get(ValueLayout.OfFloat layout, long offset) {
1555 return (float)((ValueLayouts.OfFloatImpl) layout).accessHandle().get(this, offset);
1556 }
1557
1558 /**
1559 * Writes a float into this segment at the given offset, with the given layout.
1560 *
1561 * @param layout the layout of the region of memory to be written.
1562 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1563 * @param value the float value to be written.
1564 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1565 * {@linkplain Scope#isAlive() alive}.
1566 * @throws WrongThreadException if this method is called from a thread {@code T},
1567 * such that {@code isAccessibleBy(T) == false}.
1568 * @throws IllegalArgumentException if the access operation is
1569 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1570 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1571 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1572 */
1573 @ForceInline
1574 default void set(ValueLayout.OfFloat layout, long offset, float value) {
1575 ((ValueLayouts.OfFloatImpl) layout).accessHandle().set(this, offset, value);
1576 }
1577
1578 /**
1579 * Reads a long from this segment at the given offset, with the given layout.
1580 *
1581 * @param layout the layout of the region of memory to be read.
1582 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1583 * @return a long value read from this segment.
1584 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1585 * {@linkplain Scope#isAlive() alive}.
1586 * @throws WrongThreadException if this method is called from a thread {@code T},
1587 * such that {@code isAccessibleBy(T) == false}.
1588 * @throws IllegalArgumentException if the access operation is
1589 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1590 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1591 */
1592 @ForceInline
1593 default long get(ValueLayout.OfLong layout, long offset) {
1594 return (long) ((ValueLayouts.OfLongImpl) layout).accessHandle().get(this, offset);
1595 }
1596
1597 /**
1598 * Writes a long into this segment at the given offset, with the given layout.
1599 *
1600 * @param layout the layout of the region of memory to be written.
1601 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1602 * @param value the long value to be written.
1603 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1604 * {@linkplain Scope#isAlive() alive}.
1605 * @throws WrongThreadException if this method is called from a thread {@code T},
1606 * such that {@code isAccessibleBy(T) == false}.
1607 * @throws IllegalArgumentException if the access operation is
1608 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1609 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1610 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1611 */
1612 @ForceInline
1613 default void set(ValueLayout.OfLong layout, long offset, long value) {
1614 ((ValueLayouts.OfLongImpl) layout).accessHandle().set(this, offset, value);
1615 }
1616
1617 /**
1618 * Reads a double from this segment at the given offset, with the given layout.
1619 *
1620 * @param layout the layout of the region of memory to be read.
1621 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1622 * @return a double value read from this segment.
1623 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1624 * {@linkplain Scope#isAlive() alive}.
1625 * @throws WrongThreadException if this method is called from a thread {@code T},
1626 * such that {@code isAccessibleBy(T) == false}.
1627 * @throws IllegalArgumentException if the access operation is
1628 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1629 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1630 */
1631 @ForceInline
1632 default double get(ValueLayout.OfDouble layout, long offset) {
1633 return (double) ((ValueLayouts.OfDoubleImpl) layout).accessHandle().get(this, offset);
1634 }
1635
1636 /**
1637 * Writes a double into this segment at the given offset, with the given layout.
1638 *
1639 * @param layout the layout of the region of memory to be written.
1640 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1641 * @param value the double value to be written.
1642 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1643 * {@linkplain Scope#isAlive() alive}.
1644 * @throws WrongThreadException if this method is called from a thread {@code T},
1645 * such that {@code isAccessibleBy(T) == false}.
1646 * @throws IllegalArgumentException if the access operation is
1647 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1648 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1649 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1650 */
1651 @ForceInline
1652 default void set(ValueLayout.OfDouble layout, long offset, double value) {
1653 ((ValueLayouts.OfDoubleImpl) layout).accessHandle().set(this, offset, value);
1654 }
1655
1656 /**
1657 * Reads an address from this segment at the given offset, with the given layout. The read address is wrapped in
1658 * a native segment, associated with a fresh scope that is always alive. Under normal conditions,
1659 * the size of the returned segment is {@code 0}. However, if the provided address layout has a
1660 * {@linkplain AddressLayout#targetLayout() target layout} {@code T}, then the size of the returned segment
1661 * is set to {@code T.byteSize()}.
1662 * @param layout the layout of the region of memory to be read.
1663 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1664 * @return a native segment wrapping an address read from this segment.
1665 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1666 * {@linkplain Scope#isAlive() alive}.
1667 * @throws WrongThreadException if this method is called from a thread {@code T},
1668 * such that {@code isAccessibleBy(T) == false}.
1669 * @throws IllegalArgumentException if the access operation is
1670 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1671 * @throws IllegalArgumentException if provided address layout has a {@linkplain AddressLayout#targetLayout() target layout}
1672 * {@code T}, and the address of the returned segment
1673 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in {@code T}.
1674 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1675 */
1676 @ForceInline
1677 default MemorySegment get(AddressLayout layout, long offset) {
1678 return (MemorySegment) ((ValueLayouts.OfAddressImpl) layout).accessHandle().get(this, offset);
1679 }
1680
1681 /**
1682 * Writes an address into this segment at the given offset, with the given layout.
1683 *
1684 * @param layout the layout of the region of memory to be written.
1685 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1686 * @param value the address value to be written.
1687 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1688 * {@linkplain Scope#isAlive() alive}.
1689 * @throws WrongThreadException if this method is called from a thread {@code T},
1690 * such that {@code isAccessibleBy(T) == false}.
1691 * @throws IllegalArgumentException if the access operation is
1692 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1693 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1694 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1695 * @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment.
1696 */
1697 @ForceInline
1698 default void set(AddressLayout layout, long offset, MemorySegment value) {
1699 ((ValueLayouts.OfAddressImpl) layout).accessHandle().set(this, offset, value);
1700 }
1701
1702 /**
1703 * Reads a byte from this segment at the given index, scaled by the given layout size.
1704 *
1705 * @param layout the layout of the region of memory to be read.
1706 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1707 * will occur can be expressed as {@code (index * layout.byteSize())}.
1708 * @return a byte value read from this segment.
1709 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1710 * {@linkplain Scope#isAlive() alive}.
1711 * @throws WrongThreadException if this method is called from a thread {@code T},
1712 * such that {@code isAccessibleBy(T) == false}.
1713 * @throws IllegalArgumentException if the access operation is
1714 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
1715 * or if the layout alignment is greater than its size.
1716 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1717 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1718 */
1719 @ForceInline
1720 default byte getAtIndex(ValueLayout.OfByte layout, long index) {
1721 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1722 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1723 return (byte) ((ValueLayouts.OfByteImpl) layout).accessHandle().get(this, index * layout.byteSize());
1724 }
1725
1726 /**
1727 * Reads a boolean from this segment at the given index, scaled by the given layout size.
1728 *
1729 * @param layout the layout of the region of memory to be read.
1730 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1731 * will occur can be expressed as {@code (index * layout.byteSize())}.
1732 * @return a boolean value read from this segment.
1733 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1734 * {@linkplain Scope#isAlive() alive}.
1735 * @throws WrongThreadException if this method is called from a thread {@code T},
1736 * such that {@code isAccessibleBy(T) == false}.
1737 * @throws IllegalArgumentException if the access operation is
1738 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
1739 * or if the layout alignment is greater than its size.
1740 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1741 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1742 */
1743 @ForceInline
1744 default boolean getAtIndex(ValueLayout.OfBoolean layout, long index) {
1745 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1746 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1747 return (boolean) ((ValueLayouts.OfBooleanImpl) layout).accessHandle().get(this, index * layout.byteSize());
1748 }
1749
1750 /**
1751 * Reads a char from this segment at the given index, scaled by the given layout size.
1752 *
1753 * @param layout the layout of the region of memory to be read.
1754 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1755 * will occur can be expressed as {@code (index * layout.byteSize())}.
1756 * @return a char value read from this segment.
1757 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1758 * {@linkplain Scope#isAlive() alive}.
1759 * @throws WrongThreadException if this method is called from a thread {@code T},
1760 * such that {@code isAccessibleBy(T) == false}.
1761 * @throws IllegalArgumentException if the access operation is
1762 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
1763 * or if the layout alignment is greater than its size.
1764 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1765 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1766 */
1767 @ForceInline
1768 default char getAtIndex(ValueLayout.OfChar layout, long index) {
1769 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1770 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1771 return (char) ((ValueLayouts.OfCharImpl) layout).accessHandle().get(this, index * layout.byteSize());
1772 }
1773
1774 /**
1775 * Writes a char into this segment at the given index, scaled by the given layout size.
1776 *
1777 * @param layout the layout of the region of memory to be written.
1778 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1779 * will occur can be expressed as {@code (index * layout.byteSize())}.
1780 * @param value the char value to be written.
1781 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1782 * {@linkplain Scope#isAlive() alive}.
1783 * @throws WrongThreadException if this method is called from a thread {@code T},
1784 * such that {@code isAccessibleBy(T) == false}.
1785 * @throws IllegalArgumentException if the access operation is
1786 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
1787 * or if the layout alignment is greater than its size.
1788 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1789 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1790 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1791 */
1792 @ForceInline
1793 default void setAtIndex(ValueLayout.OfChar layout, long index, char value) {
1794 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1795 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1796 ((ValueLayouts.OfCharImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
1797 }
1798
1799 /**
1800 * Reads a short from this segment at the given index, scaled by the given layout size.
1801 *
1802 * @param layout the layout of the region of memory to be read.
1803 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1804 * will occur can be expressed as {@code (index * layout.byteSize())}.
1805 * @return a short value read from this segment.
1806 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1807 * {@linkplain Scope#isAlive() alive}.
1808 * @throws WrongThreadException if this method is called from a thread {@code T},
1809 * such that {@code isAccessibleBy(T) == false}.
1810 * @throws IllegalArgumentException if the access operation is
1811 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
1812 * or if the layout alignment is greater than its size.
1813 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1814 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1815 */
1816 @ForceInline
1817 default short getAtIndex(ValueLayout.OfShort layout, long index) {
1818 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1819 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1820 return (short) ((ValueLayouts.OfShortImpl) layout).accessHandle().get(this, index * layout.byteSize());
1821 }
1822
1823 /**
1824 * Writes a byte into this segment at the given index, scaled by the given layout size.
1825 *
1826 * @param layout the layout of the region of memory to be written.
1827 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1828 * will occur can be expressed as {@code (index * layout.byteSize())}.
1829 * @param value the short value to be written.
1830 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1831 * {@linkplain Scope#isAlive() alive}.
1832 * @throws WrongThreadException if this method is called from a thread {@code T},
1833 * such that {@code isAccessibleBy(T) == false}.
1834 * @throws IllegalArgumentException if the access operation is
1835 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
1836 * or if the layout alignment is greater than its size.
1837 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1838 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1839 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1840 */
1841 @ForceInline
1842 default void setAtIndex(ValueLayout.OfByte layout, long index, byte value) {
1843 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1844 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1845 ((ValueLayouts.OfByteImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
1846
1847 }
1848
1849 /**
1850 * Writes a boolean into this segment at the given index, scaled by the given layout size.
1851 *
1852 * @param layout the layout of the region of memory to be written.
1853 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1854 * will occur can be expressed as {@code (index * layout.byteSize())}.
1855 * @param value the short value to be written.
1856 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1857 * {@linkplain Scope#isAlive() alive}.
1858 * @throws WrongThreadException if this method is called from a thread {@code T},
1859 * such that {@code isAccessibleBy(T) == false}.
1860 * @throws IllegalArgumentException if the access operation is
1861 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
1862 * or if the layout alignment is greater than its size.
1863 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1864 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1865 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1866 */
1867 @ForceInline
1868 default void setAtIndex(ValueLayout.OfBoolean layout, long index, boolean value) {
1869 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1870 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1871 ((ValueLayouts.OfBooleanImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
1872 }
1873
1874 /**
1875 * Writes a short into this segment at the given index, scaled by the given layout size.
1876 *
1877 * @param layout the layout of the region of memory to be written.
1878 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1879 * will occur can be expressed as {@code (index * layout.byteSize())}.
1880 * @param value the short value to be written.
1881 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1882 * {@linkplain Scope#isAlive() alive}.
1883 * @throws WrongThreadException if this method is called from a thread {@code T},
1884 * such that {@code isAccessibleBy(T) == false}.
1885 * @throws IllegalArgumentException if the access operation is
1886 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
1887 * or if the layout alignment is greater than its size.
1888 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1889 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1890 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1891 */
1892 @ForceInline
1893 default void setAtIndex(ValueLayout.OfShort layout, long index, short value) {
1894 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1895 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1896 ((ValueLayouts.OfShortImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
1897 }
1898
1899 /**
1900 * Reads an int from this segment at the given index, scaled by the given layout size.
1901 *
1902 * @param layout the layout of the region of memory to be read.
1903 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1904 * will occur can be expressed as {@code (index * layout.byteSize())}.
1905 * @return an int value read from this segment.
1906 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1907 * {@linkplain Scope#isAlive() alive}.
1908 * @throws WrongThreadException if this method is called from a thread {@code T},
1909 * such that {@code isAccessibleBy(T) == false}.
1910 * @throws IllegalArgumentException if the access operation is
1911 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
1912 * or if the layout alignment is greater than its size.
1913 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1914 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1915 */
1916 @ForceInline
1917 default int getAtIndex(ValueLayout.OfInt layout, long index) {
1918 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1919 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1920 return (int) ((ValueLayouts.OfIntImpl) layout).accessHandle().get(this, index * layout.byteSize());
1921 }
1922
1923 /**
1924 * Writes an int into this segment at the given index, scaled by the given layout size.
1925 *
1926 * @param layout the layout of the region of memory to be written.
1927 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1928 * will occur can be expressed as {@code (index * layout.byteSize())}.
1929 * @param value the int value to be written.
1930 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1931 * {@linkplain Scope#isAlive() alive}.
1932 * @throws WrongThreadException if this method is called from a thread {@code T},
1933 * such that {@code isAccessibleBy(T) == false}.
1934 * @throws IllegalArgumentException if the access operation is
1935 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
1936 * or if the layout alignment is greater than its size.
1937 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1938 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1939 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1940 */
1941 @ForceInline
1942 default void setAtIndex(ValueLayout.OfInt layout, long index, int value) {
1943 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1944 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1945 ((ValueLayouts.OfIntImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
1946 }
1947
1948 /**
1949 * Reads a float from this segment at the given index, scaled by the given layout size.
1950 *
1951 * @param layout the layout of the region of memory to be read.
1952 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1953 * will occur can be expressed as {@code (index * layout.byteSize())}.
1954 * @return a float value read from this segment.
1955 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1956 * {@linkplain Scope#isAlive() alive}.
1957 * @throws WrongThreadException if this method is called from a thread {@code T},
1958 * such that {@code isAccessibleBy(T) == false}.
1959 * @throws IllegalArgumentException if the access operation is
1960 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
1961 * or if the layout alignment is greater than its size.
1962 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1963 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1964 */
1965 @ForceInline
1966 default float getAtIndex(ValueLayout.OfFloat layout, long index) {
1967 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1968 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1969 return (float) ((ValueLayouts.OfFloatImpl) layout).accessHandle().get(this, index * layout.byteSize());
1970 }
1971
1972 /**
1973 * Writes a float into this segment at the given index, scaled by the given layout size.
1974 *
1975 * @param layout the layout of the region of memory to be written.
1976 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1977 * will occur can be expressed as {@code (index * layout.byteSize())}.
1978 * @param value the float value to be written.
1979 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1980 * {@linkplain Scope#isAlive() alive}.
1981 * @throws WrongThreadException if this method is called from a thread {@code T},
1982 * such that {@code isAccessibleBy(T) == false}.
1983 * @throws IllegalArgumentException if the access operation is
1984 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
1985 * or if the layout alignment is greater than its size.
1986 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1987 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1988 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1989 */
1990 @ForceInline
1991 default void setAtIndex(ValueLayout.OfFloat layout, long index, float value) {
1992 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1993 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1994 ((ValueLayouts.OfFloatImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
1995 }
1996
1997 /**
1998 * Reads a long from this segment at the given index, scaled by the given layout size.
1999 *
2000 * @param layout the layout of the region of memory to be read.
2001 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
2002 * will occur can be expressed as {@code (index * layout.byteSize())}.
2003 * @return a long value read from this segment.
2004 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
2005 * {@linkplain Scope#isAlive() alive}.
2006 * @throws WrongThreadException if this method is called from a thread {@code T},
2007 * such that {@code isAccessibleBy(T) == false}.
2008 * @throws IllegalArgumentException if the access operation is
2009 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
2010 * or if the layout alignment is greater than its size.
2011 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
2012 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
2013 */
2014 @ForceInline
2015 default long getAtIndex(ValueLayout.OfLong layout, long index) {
2016 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2017 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2018 return (long) ((ValueLayouts.OfLongImpl) layout).accessHandle().get(this, index * layout.byteSize());
2019 }
2020
2021 /**
2022 * Writes a long into this segment at the given index, scaled by the given layout size.
2023 *
2024 * @param layout the layout of the region of memory to be written.
2025 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
2026 * will occur can be expressed as {@code (index * layout.byteSize())}.
2027 * @param value the long value to be written.
2028 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
2029 * {@linkplain Scope#isAlive() alive}.
2030 * @throws WrongThreadException if this method is called from a thread {@code T},
2031 * such that {@code isAccessibleBy(T) == false}.
2032 * @throws IllegalArgumentException if the access operation is
2033 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
2034 * or if the layout alignment is greater than its size.
2035 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
2036 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
2037 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
2038 */
2039 @ForceInline
2040 default void setAtIndex(ValueLayout.OfLong layout, long index, long value) {
2041 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2042 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2043 ((ValueLayouts.OfLongImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
2044 }
2045
2046 /**
2047 * Reads a double from this segment at the given index, scaled by the given layout size.
2048 *
2049 * @param layout the layout of the region of memory to be read.
2050 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
2051 * will occur can be expressed as {@code (index * layout.byteSize())}.
2052 * @return a double value read from this segment.
2053 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
2054 * {@linkplain Scope#isAlive() alive}.
2055 * @throws WrongThreadException if this method is called from a thread {@code T},
2056 * such that {@code isAccessibleBy(T) == false}.
2057 * @throws IllegalArgumentException if the access operation is
2058 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
2059 * or if the layout alignment is greater than its size.
2060 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
2061 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
2062 */
2063 @ForceInline
2064 default double getAtIndex(ValueLayout.OfDouble layout, long index) {
2065 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2066 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2067 return (double) ((ValueLayouts.OfDoubleImpl) layout).accessHandle().get(this, index * layout.byteSize());
2068 }
2069
2070 /**
2071 * Writes a double into this segment at the given index, scaled by the given layout size.
2072 *
2073 * @param layout the layout of the region of memory to be written.
2074 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
2075 * will occur can be expressed as {@code (index * layout.byteSize())}.
2076 * @param value the double value to be written.
2077 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
2078 * {@linkplain Scope#isAlive() alive}.
2079 * @throws WrongThreadException if this method is called from a thread {@code T},
2080 * such that {@code isAccessibleBy(T) == false}.
2081 * @throws IllegalArgumentException if the access operation is
2082 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
2083 * or if the layout alignment is greater than its size.
2084 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
2085 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
2086 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
2087 */
2088 @ForceInline
2089 default void setAtIndex(ValueLayout.OfDouble layout, long index, double value) {
2090 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2091 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2092 ((ValueLayouts.OfDoubleImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
2093 }
2094
2095 /**
2096 * 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
2097 * a native segment, associated with a fresh scope that is always alive. Under normal conditions,
2098 * the size of the returned segment is {@code 0}. However, if the provided address layout has a
2099 * {@linkplain AddressLayout#targetLayout() target layout} {@code T}, then the size of the returned segment
2100 * is set to {@code T.byteSize()}.
2101 * @param layout the layout of the region of memory to be read.
2102 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
2103 * will occur can be expressed as {@code (index * layout.byteSize())}.
2104 * @return a native segment wrapping an address read from this segment.
2105 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
2106 * {@linkplain Scope#isAlive() alive}.
2107 * @throws WrongThreadException if this method is called from a thread {@code T},
2108 * such that {@code isAccessibleBy(T) == false}.
2109 * @throws IllegalArgumentException if the access operation is
2110 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
2111 * or if the layout alignment is greater than its size.
2112 * @throws IllegalArgumentException if provided address layout has a {@linkplain AddressLayout#targetLayout() target layout}
2113 * {@code T}, and the address of the returned segment
2114 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in {@code T}.
2115 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
2116 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
2117 */
2118 @ForceInline
2119 default MemorySegment getAtIndex(AddressLayout layout, long index) {
2120 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2121 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2122 return (MemorySegment) ((ValueLayouts.OfAddressImpl) layout).accessHandle().get(this, index * layout.byteSize());
2123 }
2124
2125 /**
2126 * Writes an address into this segment at the given index, scaled by the given layout size.
2127 *
2128 * @param layout the layout of the region of memory to be written.
2129 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
2130 * will occur can be expressed as {@code (index * layout.byteSize())}.
2131 * @param value the address value to be written.
2132 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
2133 * {@linkplain Scope#isAlive() alive}.
2134 * @throws WrongThreadException if this method is called from a thread {@code T},
2135 * such that {@code isAccessibleBy(T) == false}.
2136 * @throws IllegalArgumentException if the access operation is
2137 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout,
2138 * or if the layout alignment is greater than its size.
2139 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
2140 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
2141 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
2142 * @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment.
2143 */
2144 @ForceInline
2145 default void setAtIndex(AddressLayout layout, long index, MemorySegment value) {
2146 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2147 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2148 ((ValueLayouts.OfAddressImpl) layout).accessHandle().set(this, index * layout.byteSize(), value);
2149 }
2150
2151 /**
2152 * Compares the specified object with this memory segment for equality. Returns {@code true} if and only if the specified
2153 * object is also a memory segment, and if the two segments refer to the same location, in some region of memory.
2154 * More specifically, for two segments {@code s1} and {@code s2} to be considered equals, all the following must be true:
2155 * <ul>
2156 * <li>{@code s1.heapBase().equals(s2.heapBase())}, that is, the two segments must be of the same kind;
2157 * either both are {@linkplain #isNative() native segments}, backed by off-heap memory, or both are backed by
2158 * the same on-heap {@linkplain #heapBase() Java object};
2159 * <li>{@code s1.address() == s2.address()}, that is, the address of the two segments should be the same.
2160 * This means that the two segments either refer to the same location in some off-heap region, or they refer
2161 * to the same offset inside their associated {@linkplain #heapBase() Java object}.</li>
2162 * </ul>
2163 * @apiNote This method does not perform a structural comparison of the contents of the two memory segments. Clients can
2164 * compare memory segments structurally by using the {@link #mismatch(MemorySegment)} method instead. Note that this
2165 * method does <em>not</em> compare the temporal and spatial bounds of two segments. As such it is suitable
2166 * to check whether two segments have the same address.
2167 *
2168 * @param that the object to be compared for equality with this memory segment.
2177 */
2178 @Override
2179 int hashCode();
2180
2181
2182 /**
2183 * Copies a number of elements from a source memory segment to a destination array. The elements, whose size and alignment
2184 * constraints are specified by the given layout, are read from the source segment, starting at the given offset
2185 * (expressed in bytes), and are copied into the destination array, at the given index.
2186 * Supported array types are {@code byte[]}, {@code char[]}, {@code short[]}, {@code int[]}, {@code float[]}, {@code long[]} and {@code double[]}.
2187 * @param srcSegment the source segment.
2188 * @param srcLayout the source element layout. If the byte order associated with the layout is
2189 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element.
2190 * @param srcOffset the starting offset, in bytes, of the source segment.
2191 * @param dstArray the destination array.
2192 * @param dstIndex the starting index of the destination array.
2193 * @param elementCount the number of array elements to be copied.
2194 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not
2195 * {@linkplain Scope#isAlive() alive}.
2196 * @throws WrongThreadException if this method is called from a thread {@code T},
2197 * such that {@code srcSegment().isAccessibleBy(T) == false}.
2198 * @throws IllegalArgumentException if {@code dstArray} is not an array, or if it is an array but whose type is not supported.
2199 * @throws IllegalArgumentException if the destination array component type does not match {@code srcLayout.carrier()}.
2200 * @throws IllegalArgumentException if {@code offset} is <a href="MemorySegment.html#segment-alignment">incompatible
2201 * with the alignment constraint</a> in the source element layout.
2202 * @throws IllegalArgumentException if {@code srcLayout.byteAlignment() > srcLayout.byteSize()}.
2203 * @throws IndexOutOfBoundsException if {@code elementCount * srcLayout.byteSize()} overflows.
2204 * @throws IndexOutOfBoundsException if {@code srcOffset > srcSegment.byteSize() - (elementCount * srcLayout.byteSize())}.
2205 * @throws IndexOutOfBoundsException if {@code dstIndex > dstArray.length - elementCount}.
2206 * @throws IndexOutOfBoundsException if either {@code srcOffset}, {@code dstIndex} or {@code elementCount} are {@code < 0}.
2207 */
2208 @ForceInline
2209 static void copy(
2210 MemorySegment srcSegment, ValueLayout srcLayout, long srcOffset,
2211 Object dstArray, int dstIndex, int elementCount) {
2212 Objects.requireNonNull(srcSegment);
2213 Objects.requireNonNull(dstArray);
2214 Objects.requireNonNull(srcLayout);
2215
2216 AbstractMemorySegmentImpl.copy(srcSegment, srcLayout, srcOffset,
2217 dstArray, dstIndex,
2218 elementCount);
2219 }
2220
2221 /**
2222 * Copies a number of elements from a source array to a destination memory segment. The elements, whose size and alignment
2223 * constraints are specified by the given layout, are read from the source array, starting at the given index,
2224 * and are copied into the destination segment, at the given offset (expressed in bytes).
2225 * Supported array types are {@code byte[]}, {@code char[]}, {@code short[]}, {@code int[]}, {@code float[]}, {@code long[]} and {@code double[]}.
2226 * @param srcArray the source array.
2227 * @param srcIndex the starting index of the source array.
2228 * @param dstSegment the destination segment.
2229 * @param dstLayout the destination element layout. If the byte order associated with the layout is
2230 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element.
2231 * @param dstOffset the starting offset, in bytes, of the destination segment.
2232 * @param elementCount the number of array elements to be copied.
2233 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
2234 * {@linkplain Scope#isAlive() alive}.
2235 * @throws WrongThreadException if this method is called from a thread {@code T},
2236 * such that {@code dstSegment().isAccessibleBy(T) == false}.
2237 * @throws IllegalArgumentException if {@code srcArray} is not an array, or if it is an array but whose type is not supported.
2238 * @throws IllegalArgumentException if the source array component type does not match {@code srcLayout.carrier()}.
2239 * @throws IllegalArgumentException if {@code offset} is <a href="MemorySegment.html#segment-alignment">incompatible
2240 * with the alignment constraint</a> in the source element layout.
2241 * @throws IllegalArgumentException if {@code dstLayout.byteAlignment() > dstLayout.byteSize()}.
2242 * @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}.
2243 * @throws IndexOutOfBoundsException if {@code elementCount * dstLayout.byteSize()} overflows.
2244 * @throws IndexOutOfBoundsException if {@code dstOffset > dstSegment.byteSize() - (elementCount * dstLayout.byteSize())}.
2245 * @throws IndexOutOfBoundsException if {@code srcIndex > srcArray.length - elementCount}.
2246 * @throws IndexOutOfBoundsException if either {@code srcIndex}, {@code dstOffset} or {@code elementCount} are {@code < 0}.
2247 */
2248 @ForceInline
2249 static void copy(
2250 Object srcArray, int srcIndex,
2251 MemorySegment dstSegment, ValueLayout dstLayout, long dstOffset, int elementCount) {
2252 Objects.requireNonNull(srcArray);
2253 Objects.requireNonNull(dstSegment);
2254 Objects.requireNonNull(dstLayout);
2255
2256 AbstractMemorySegmentImpl.copy(srcArray, srcIndex,
2291 * @throws IndexOutOfBoundsException if {@code dstFromOffset < 0}, {@code dstToOffset < dstFromOffset} or
2292 * {@code dstToOffset > dstSegment.byteSize()}
2293 *
2294 * @see MemorySegment#mismatch(MemorySegment)
2295 * @see Arrays#mismatch(Object[], int, int, Object[], int, int)
2296 */
2297 static long mismatch(MemorySegment srcSegment, long srcFromOffset, long srcToOffset,
2298 MemorySegment dstSegment, long dstFromOffset, long dstToOffset) {
2299 return AbstractMemorySegmentImpl.mismatch(srcSegment, srcFromOffset, srcToOffset,
2300 dstSegment, dstFromOffset, dstToOffset);
2301 }
2302
2303 /**
2304 * A scope models the <em>lifetime</em> of all the memory segments associated with it. That is, a memory segment
2305 * cannot be accessed if its associated scope is not {@linkplain #isAlive() alive}. A new scope is typically
2306 * obtained indirectly, by creating a new {@linkplain Arena arena}.
2307 * <p>
2308 * Scope instances can be compared for equality. That is, two scopes
2309 * are considered {@linkplain #equals(Object)} if they denote the same lifetime.
2310 */
2311 @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
2312 sealed interface Scope permits MemorySessionImpl {
2313 /**
2314 * {@return {@code true}, if the regions of memory backing the memory segments associated with this scope are
2315 * still valid}
2316 */
2317 boolean isAlive();
2318
2319 /**
2320 * {@return {@code true}, if the provided object is also a scope, which models the same lifetime as that
2321 * modelled by this scope}. In that case, it is always the case that
2322 * {@code this.isAlive() == ((Scope)that).isAlive()}.
2323 * @param that the object to be tested.
2324 */
2325 @Override
2326 boolean equals(Object that);
2327
2328 /**
2329 * Returns the hash code of this scope object.
2330 * @implSpec Implementations of this method obey the general contract of {@link Object#hashCode}.
2331 * @return the hash code of this scope object.
|
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.foreign;
27
28 import java.io.UncheckedIOException;
29 import java.nio.Buffer;
30 import java.nio.ByteBuffer;
31 import java.nio.ByteOrder;
32 import java.nio.CharBuffer;
33 import java.nio.channels.FileChannel;
34 import java.nio.channels.FileChannel.MapMode;
35 import java.nio.charset.Charset;
36 import java.nio.charset.StandardCharsets;
37 import java.util.Arrays;
38 import java.util.Objects;
39 import java.util.Optional;
40 import java.util.Spliterator;
41 import java.util.function.Consumer;
42 import java.util.stream.Stream;
43 import jdk.internal.foreign.AbstractMemorySegmentImpl;
44 import jdk.internal.foreign.HeapMemorySegmentImpl;
45 import jdk.internal.foreign.MemorySessionImpl;
46 import jdk.internal.foreign.NativeMemorySegmentImpl;
47 import jdk.internal.foreign.StringSupport;
48 import jdk.internal.foreign.Utils;
49 import jdk.internal.reflect.CallerSensitive;
50 import jdk.internal.vm.annotation.ForceInline;
51
52 /**
53 * A memory segment provides access to a contiguous region of memory.
54 * <p>
55 * There are two kinds of memory segments:
56 * <ul>
57 * <li>A <em>heap segment</em> is backed by, and provides access to, a region of memory inside the Java heap (an "on-heap" region).</li>
58 * <li>A <em>native segment</em> is backed by, and provides access to, a region of memory outside the Java heap (an "off-heap" region).</li>
59 * </ul>
60 * Heap segments can be obtained by calling one of the {@link MemorySegment#ofArray(int[])} factory methods.
61 * These methods return a memory segment backed by the on-heap region that holds the specified Java array.
62 * <p>
63 * Native segments can be obtained by calling one of the {@link Arena#allocate(long, long)}
64 * factory methods, which return a memory segment backed by a newly allocated off-heap region with the given size
65 * and aligned to the given alignment constraint. Alternatively, native segments can be obtained by
66 * {@link FileChannel#map(MapMode, long, long, Arena) mapping} a file into a new off-heap region
67 * (in some systems, this operation is sometimes referred to as {@code mmap}).
68 * Segments obtained in this way are called <em>mapped</em> segments, and their contents can be {@linkplain #force() persisted} and
106 * <a href="Arena.html#thread-confinement">confinement characteristics</a> of the arena used to obtain them.
107 *
108 * <h2 id="segment-deref">Accessing memory segments</h2>
109 *
110 * A memory segment can be read or written using various access operations provided in this class (e.g. {@link #get(ValueLayout.OfInt, long)}).
111 * Each access operation takes a {@linkplain ValueLayout value layout}, which specifies the size and shape of the value,
112 * and an offset, expressed in bytes.
113 * For instance, to read an int from a segment, using {@linkplain ByteOrder#nativeOrder() default endianness}, the following code can be used:
114 * {@snippet lang=java :
115 * MemorySegment segment = ...
116 * int value = segment.get(ValueLayout.JAVA_INT, 0);
117 * }
118 *
119 * If the value to be read is stored in memory using {@linkplain ByteOrder#BIG_ENDIAN big-endian} encoding, the access operation
120 * can be expressed as follows:
121 * {@snippet lang=java :
122 * MemorySegment segment = ...
123 * int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0);
124 * }
125 *
126 * More complex access operations can be implemented using var handles. The {@link ValueLayout#varHandle()}
127 * 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.
128 * A var handle obtained from a layout supports several additional <a href=MemoryLayout.html#access-mode-restrictions>
129 * access modes</a>. More importantly, var handles can be <em>combined</em> with method handles to express complex access
130 * operations. For instance, a var handle that can be used to access an element of an {@code int} array at a given logical
131 * index can be created as follows:
132 *
133 * {@snippet lang=java:
134 * MemorySegment segment = ...
135 * VarHandle intHandle = ValueLayout.JAVA_INT.varHandle(); // (MemorySegment, long)
136 * MethodHandle scale = ValueLayout.JAVA_INT.scaleHandle(); // <base offset> + <index> * JAVA_INT.byteSize()
137 *
138 * intHandle = MethodHandles.filterCoordinates(intHandle, 1, scale);
139 * int value = (int) intHandle.get(segment, 0L, 3L); // get int element at offset 0 + 3 * 4 = 12
140 * }
141 *
142 * To make the process of creating these var handles easier, the method
143 * {@link MemoryLayout#varHandle(MemoryLayout.PathElement...)} can be used, by providing it a so called
144 * <a href="MemoryLayout.html#layout-paths"><em>layout path</em></a>. A layout path, consisting of several <em>layout
145 * path elements</em>, selects a value layout to be accessed, which can be nested inside another memory layout. For example,
146 * we can express the access to an element of an {@code int} array using layout paths like so:
147 *
148 * {@snippet lang=java :
149 * MemorySegment segment = ...
150 * MemoryLayout segmentLayout = MemoryLayout.structLayout(
151 * ValueLayout.JAVA_INT.withName("size"),
152 * MemoryLayout.sequenceLayout(4, ValueLayout.JAVA_INT).withName("data") // array of 4 elements
153 * );
154 * VarHandle intHandle = segmentLayout.varHandle(MemoryLayout.PathElemenet.groupElement("data"),
155 * MemoryLayout.PathElement.sequenceElement());
156 * int value = (int) intHandle.get(segment, 0L, 3L); // get int element at offset 0 + offsetof(data) + 3 * 4 = 12
157 * }
158 * Where {@code offsetof(data)} is the offset of the {@code data} element layout of the {@code segmentLayout} layout
159 *
160 * Both the var handle returned by {@link ValueLayout#varHandle()} and
161 * {@link MemoryLayout#varHandle(MemoryLayout.PathElement...)}, as well as the method handle returned by
162 * {@link MemoryLayout#byteOffsetHandle(MemoryLayout.PathElement...)} and {@link MemoryLayout#sliceHandle(MemoryLayout.PathElement...)}
163 * feature a <em>base offset</em> parameter. This parameter represents a base offset for the offset computation. This
164 * parameter allows a client to combine these handles further with additional offset computations. This is demonstrated
165 * in the first of the two examples above, where {@code intHandle} is combined with a
166 * {@linkplain MemoryLayout#scaleHandle() scale handle} obtained from {@code ValueLayout.JAVA_INT}.
167 *
168 * <h2 id="slicing">Slicing memory segments</h2>
169 *
170 * Memory segments support {@linkplain MemorySegment#asSlice(long, long) slicing}. Slicing a memory segment
171 * returns a new memory segment that is backed by the same region of memory as the original. The address of the sliced
172 * segment is derived from the address of the original segment, by adding an offset (expressed in bytes). The size of
173 * the sliced segment is either derived implicitly (by subtracting the specified offset from the size of the original segment),
174 * or provided explicitly. In other words, a sliced segment has <em>stricter</em> spatial bounds than those of the original segment:
175 * {@snippet lang = java:
176 * Arena arena = ...
177 * MemorySegment segment = arena.allocate(100);
178 * MemorySegment slice = segment.asSlice(50, 10);
179 * slice.get(ValueLayout.JAVA_INT, 20); // Out of bounds!
180 * arena.close();
181 * slice.get(ValueLayout.JAVA_INT, 0); // Already closed!
182 *}
183 * The above code creates a native segment that is 100 bytes long; then, it creates a slice that starts at offset 50
184 * of {@code segment}, and is 10 bytes long. That is, the address of the {@code slice} is {@code segment.address() + 50},
185 * and its size is 10. As a result, attempting to read an int value at offset 20 of the
186 * {@code slice} segment will result in an exception. The {@linkplain Arena temporal bounds} of the original segment
427 * of the segment is the same as the size of the target layout. In other words, the returned segment is no
428 * longer a zero-length memory segment, and the pointer it represents can be dereferenced directly:
429 *
430 * {@snippet lang = java:
431 * AddressLayout intArrPtrLayout = ValueLayout.ADDRESS.withTargetLayout(
432 * MemoryLayout.sequenceLayout(4, ValueLayout.JAVA_INT)); // layout for int (*ptr)[4]
433 * MemorySegment ptr = segment.get(intArrPtrLayout, ...); // size = 16
434 * int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // ok
435 *}
436 * <p>
437 * All the methods which can be used to manipulate zero-length memory segments
438 * ({@link #reinterpret(long)}, {@link #reinterpret(Arena, Consumer)}, {@link #reinterpret(long, Arena, Consumer)} and
439 * {@link AddressLayout#withTargetLayout(MemoryLayout)}) are
440 * <a href="package-summary.html#restricted"><em>restricted</em></a> methods, and should be used with caution:
441 * assigning a segment incorrect spatial and/or temporal bounds could result in a VM crash when attempting to access
442 * the memory segment.
443 *
444 * @implSpec
445 * Implementations of this interface are immutable, thread-safe and <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>.
446 *
447 * @since 22
448 */
449 public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
450
451 /**
452 * {@return the address of this memory segment}
453 *
454 * @apiNote When using this method to pass a segment address to some external operation (e.g. a JNI function),
455 * clients must ensure that the segment is kept <a href="../../../java/lang/ref/package.html#reachability">reachable</a>
456 * for the entire duration of the operation. A failure to do so might result in the premature deallocation of the
457 * region of memory backing the memory segment, in case the segment has been allocated with an
458 * {@linkplain Arena#ofAuto() automatic arena}.
459 */
460 long address();
461
462 /**
463 * Returns the Java object stored in the on-heap region of memory backing this memory segment, if any. For instance, if this
464 * memory segment is a heap segment created with the {@link #ofArray(byte[])} factory method, this method will return the
465 * {@code byte[]} object which was used to obtain the segment. This method returns an empty {@code Optional} value
466 * if either this segment is a {@linkplain #isNative() native} segment, or if this segment is {@linkplain #isReadOnly() read-only}.
467 * @return the Java object associated with this memory segment, if any.
468 */
589 * of this segment plus the given offset; its size is computed by subtracting the specified offset from this segment size.
590 * <p>
591 * Equivalent to the following code:
592 * {@snippet lang=java :
593 * asSlice(offset, byteSize() - offset);
594 * }
595 *
596 * @see #asSlice(long, long)
597 *
598 * @param offset The new segment base offset (relative to the address of this segment), specified in bytes.
599 * @return a slice of this memory segment.
600 * @throws IndexOutOfBoundsException if {@code offset < 0}, or {@code offset > byteSize()}.
601 */
602 MemorySegment asSlice(long offset);
603
604 /**
605 * Returns a new memory segment that has the same address and scope as this segment, but with the provided size.
606 * <p>
607 * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
608 * Restricted methods are unsafe, and, if used incorrectly, their use might crash
609 * the JVM or, worse, silently result in memory corruption.
610 *
611 * @param newSize the size of the returned segment.
612 * @return a new memory segment that has the same address and scope as this segment, but the new
613 * provided size.
614 * @throws IllegalArgumentException if {@code newSize < 0}.
615 * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment.
616 * @throws IllegalCallerException If the caller is in a module that does not have native access enabled.
617 */
618 @CallerSensitive
619 MemorySegment reinterpret(long newSize);
620
621 /**
622 * Returns a new memory segment with the same address and size as this segment, but with the provided scope.
623 * As such, the returned segment cannot be accessed after the provided arena has been closed.
624 * Moreover, the returned segment can be accessed compatibly with the confinement restrictions associated with the
625 * provided arena: that is, if the provided arena is a {@linkplain Arena#ofConfined() confined arena},
626 * the returned segment can only be accessed by the arena's owner thread, regardless of the confinement restrictions
627 * associated with this segment. In other words, this method returns a segment that behaves as if it had been allocated
628 * using the provided arena.
629 * <p>
630 * Clients can specify an optional cleanup action that should be executed when the provided scope becomes
631 * invalid. This cleanup action receives a fresh memory segment that is obtained from this segment as follows:
632 * {@snippet lang=java :
633 * MemorySegment cleanupSegment = MemorySegment.ofAddress(this.address())
634 * .reinterpret(byteSize());
635 * }
636 * That is, the cleanup action receives a segment that is associated with a fresh scope that is always alive,
637 * and is accessible from any thread. The size of the segment accepted by the cleanup action is {@link #byteSize()}.
638 * <p>
639 * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
640 * Restricted methods are unsafe, and, if used incorrectly, their use might crash
641 * the JVM or, worse, silently result in memory corruption.
642 *
643 * @apiNote The cleanup action (if present) should take care not to leak the received segment to external
644 * clients which might access the segment after its backing region of memory is no longer available. Furthermore,
645 * if the provided scope is the scope of an {@linkplain Arena#ofAuto() automatic arena}, the cleanup action
646 * must not prevent the scope from becoming <a href="../../../java/lang/ref/package.html#reachability">unreachable</a>.
647 * A failure to do so will permanently prevent the regions of memory allocated by the automatic arena from being deallocated.
648 *
649 * @param arena the arena to be associated with the returned segment.
650 * @param cleanup the cleanup action that should be executed when the provided arena is closed (can be {@code null}).
651 * @return a new memory segment with unbounded size.
652 * @throws IllegalStateException if {@code arena.scope().isAlive() == false}.
653 * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment.
654 * @throws IllegalCallerException If the caller is in a module that does not have native access enabled.
655 */
656 @CallerSensitive
657 MemorySegment reinterpret(Arena arena, Consumer<MemorySegment> cleanup);
658
659 /**
660 * Returns a new segment with the same address as this segment, but with the provided size and scope.
661 * As such, the returned segment cannot be accessed after the provided arena has been closed.
662 * Moreover, if the returned segment can be accessed compatibly with the confinement restrictions associated with the
663 * provided arena: that is, if the provided arena is a {@linkplain Arena#ofConfined() confined arena},
664 * the returned segment can only be accessed by the arena's owner thread, regardless of the confinement restrictions
665 * associated with this segment. In other words, this method returns a segment that behaves as if it had been allocated
666 * using the provided arena.
667 * <p>
668 * Clients can specify an optional cleanup action that should be executed when the provided scope becomes
669 * invalid. This cleanup action receives a fresh memory segment that is obtained from this segment as follows:
670 * {@snippet lang=java :
671 * MemorySegment cleanupSegment = MemorySegment.ofAddress(this.address())
672 * .reinterpret(newSize);
673 * }
674 * That is, the cleanup action receives a segment that is associated with a fresh scope that is always alive,
675 * and is accessible from any thread. The size of the segment accepted by the cleanup action is {@code newSize}.
676 * <p>
677 * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
678 * Restricted methods are unsafe, and, if used incorrectly, their use might crash
679 * the JVM or, worse, silently result in memory corruption.
680 *
681 * @apiNote The cleanup action (if present) should take care not to leak the received segment to external
682 * clients which might access the segment after its backing region of memory is no longer available. Furthermore,
683 * if the provided scope is the scope of an {@linkplain Arena#ofAuto() automatic arena}, the cleanup action
684 * must not prevent the scope from becoming <a href="../../../java/lang/ref/package.html#reachability">unreachable</a>.
685 * A failure to do so will permanently prevent the regions of memory allocated by the automatic arena from being deallocated.
686 *
687 * @param newSize the size of the returned segment.
688 * @param arena the arena to be associated with the returned segment.
689 * @param cleanup the cleanup action that should be executed when the provided arena is closed (can be {@code null}).
690 * @return a new segment that has the same address as this segment, but with new size and its scope set to
691 * that of the provided arena.
692 * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment.
693 * @throws IllegalArgumentException if {@code newSize < 0}.
694 * @throws IllegalStateException if {@code arena.scope().isAlive() == false}.
695 * @throws IllegalCallerException If the caller is in a module that does not have native access enabled.
696 */
697 @CallerSensitive
698 MemorySegment reinterpret(long newSize, Arena arena, Consumer<MemorySegment> cleanup);
699
725 * {@linkplain #ofBuffer(Buffer) wrapping} a {@linkplain java.nio.MappedByteBuffer mapped byte buffer}.
726 * @return {@code true} if this segment is a mapped segment.
727 */
728 boolean isMapped();
729
730 /**
731 * Returns a slice of this segment that is the overlap between this and
732 * the provided segment.
733 *
734 * <p>Two segments {@code S1} and {@code S2} are said to overlap if it is possible to find
735 * at least two slices {@code L1} (from {@code S1}) and {@code L2} (from {@code S2}) that are backed by the
736 * same region of memory. As such, it is not possible for a
737 * {@linkplain #isNative() native} segment to overlap with a heap segment; in
738 * this case, or when no overlap occurs, an empty {@code Optional} is returned.
739 *
740 * @param other the segment to test for an overlap with this segment.
741 * @return a slice of this segment (where overlapping occurs).
742 */
743 Optional<MemorySegment> asOverlappingSlice(MemorySegment other);
744
745 /**
746 * Fills the contents of this memory segment with the given value.
747 * <p>
748 * More specifically, the given value is written into each address of this
749 * segment. Equivalent to (but likely more efficient than) the following code:
750 *
751 * {@snippet lang=java :
752 * for (long offset = 0; offset < segment.byteSize(); offset++) {
753 * segment.set(ValueLayout.JAVA_BYTE, offset, value);
754 * }
755 * }
756 *
757 * But without any regard or guarantees on the ordering of particular memory
758 * elements being set.
759 * <p>
760 * This method can be useful to initialize or reset the contents of a memory segment.
761 *
762 * @param value the value to write into this segment.
763 * @return this memory segment.
764 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
765 * {@linkplain Scope#isAlive() alive}.
766 * @throws WrongThreadException if this method is called from a thread {@code T},
767 * such that {@code isAccessibleBy(T) == false}.
768 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
769 */
770 MemorySegment fill(byte value);
771
772 /**
773 * Performs a bulk copy from given source segment to this segment. More specifically, the bytes at
1034 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code long[]} instance,
1035 * e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer.MAX_VALUE}.
1036 */
1037 long[] toArray(ValueLayout.OfLong elementLayout);
1038
1039 /**
1040 * Copy the contents of this memory segment into a new double array.
1041 * @param elementLayout the source element layout. If the byte order associated with the layout is
1042 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element.
1043 * @return a new double array whose contents are copied from this memory segment.
1044 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1045 * {@linkplain Scope#isAlive() alive}.
1046 * @throws WrongThreadException if this method is called from a thread {@code T},
1047 * such that {@code isAccessibleBy(T) == false}.
1048 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code double[]} instance,
1049 * e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer.MAX_VALUE}.
1050 */
1051 double[] toArray(ValueLayout.OfDouble elementLayout);
1052
1053 /**
1054 * Reads a null-terminated string from this segment at the given offset, using the
1055 * {@linkplain StandardCharsets#UTF_8 UTF-8} charset.
1056 * <p>
1057 * Calling this method is equivalent to the following code:
1058 * {@snippet lang = java:
1059 * getString(offset, StandardCharsets.UTF_8);
1060 *}
1061 *
1062 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1063 * @return a Java string constructed from the bytes read from the given starting address up to (but not including)
1064 * the first {@code '\0'} terminator character (assuming one is found).
1065 * @throws IllegalArgumentException if the size of the string is greater than the largest string supported by the platform.
1066 * @throws IndexOutOfBoundsException if {@code offset < 0}.
1067 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - (B + 1)}, where {@code B} is the size,
1068 * in bytes, of the string encoded using UTF-8 charset {@code str.getBytes(StandardCharsets.UTF_8).length}).
1069 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1070 * {@linkplain Scope#isAlive() alive}.
1071 * @throws WrongThreadException if this method is called from a thread {@code T},
1072 * such that {@code isAccessibleBy(T) == false}.
1073 */
1074 default String getString(long offset) {
1075 return getString(offset, sun.nio.cs.UTF_8.INSTANCE);
1076 }
1077
1078 /**
1079 * Reads a null-terminated string from this segment at the given offset, using the provided charset.
1080 * <p>
1081 * This method always replaces malformed-input and unmappable-character
1082 * sequences with this charset's default replacement string. The {@link
1083 * java.nio.charset.CharsetDecoder} class should be used when more control
1084 * over the decoding process is required.
1085 *
1086 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1087 * @param charset the charset used to {@linkplain Charset#newDecoder() decode} the string bytes.
1088 * @return a Java string constructed from the bytes read from the given starting address up to (but not including)
1089 * the first {@code '\0'} terminator character (assuming one is found).
1090 * @throws IllegalArgumentException if the size of the string is greater than the largest string supported by the platform.
1091 * @throws IndexOutOfBoundsException if {@code offset < 0}.
1092 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - (B + N)}, where:
1093 * <ul>
1094 * <li>{@code B} is the size, in bytes, of the string encoded using the provided charset
1095 * (e.g. {@code str.getBytes(charset).length});</li>
1096 * <li>{@code N} is the size (in bytes) of the terminator char according to the provided charset. For instance,
1097 * this is 1 for {@link StandardCharsets#US_ASCII} and 2 for {@link StandardCharsets#UTF_16}.</li>
1098 * </ul>
1099 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1100 * {@linkplain Scope#isAlive() alive}.
1101 * @throws WrongThreadException if this method is called from a thread {@code T},
1102 * such that {@code isAccessibleBy(T) == false}.
1103 * @throws UnsupportedOperationException if {@code charset} is not a {@linkplain StandardCharsets standard charset}.
1104 */
1105 default String getString(long offset, Charset charset) {
1106 Objects.requireNonNull(charset);
1107 return StringSupport.read(this, offset, charset);
1108 }
1109
1110 /**
1111 * Writes the given string into this segment at the given offset, converting it to a null-terminated byte sequence
1112 * using the {@linkplain StandardCharsets#UTF_8 UTF-8} charset.
1113 * <p>
1114 * Calling this method is equivalent to the following code:
1115 * {@snippet lang = java:
1116 * setString(offset, str, StandardCharsets.UTF_8);
1117 *}
1118 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1119 * the final address of this write operation can be expressed as {@code address() + offset}.
1120 * @param str the Java string to be written into this segment.
1121 * @throws IndexOutOfBoundsException if {@code offset < 0}.
1122 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - (B + 1)}, where {@code B} is the size,
1123 * in bytes, of the string encoded using UTF-8 charset {@code str.getBytes(StandardCharsets.UTF_8).length}).
1124 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1125 * {@linkplain Scope#isAlive() alive}.
1126 * @throws WrongThreadException if this method is called from a thread {@code T},
1127 * such that {@code isAccessibleBy(T) == false}.
1128 */
1129 default void setString(long offset, String str) {
1130 Objects.requireNonNull(str);
1131 setString(offset, str, sun.nio.cs.UTF_8.INSTANCE);
1132 }
1133
1134 /**
1135 * Writes the given string into this segment at the given offset, converting it to a null-terminated byte sequence
1136 * using the provided charset.
1137 * <p>
1138 * This method always replaces malformed-input and unmappable-character
1139 * sequences with this charset's default replacement string. The {@link
1140 * java.nio.charset.CharsetDecoder} class should be used when more control
1141 * over the decoding process is required.
1142 * <p>
1143 * If the given string contains any {@code '\0'} characters, they will be
1144 * copied as well. This means that, depending on the method used to read
1145 * the string, such as {@link MemorySegment#getString(long)}, the string
1146 * will appear truncated when read again.
1147 *
1148 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1149 * the final address of this write operation can be expressed as {@code address() + offset}.
1150 * @param str the Java string to be written into this segment.
1151 * @param charset the charset used to {@linkplain Charset#newEncoder() encode} the string bytes.
1152 * @throws IndexOutOfBoundsException if {@code offset < 0}.
1153 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - (B + N)}, where:
1154 * <ul>
1155 * <li>{@code B} is the size, in bytes, of the string encoded using the provided charset
1156 * (e.g. {@code str.getBytes(charset).length});</li>
1157 * <li>{@code N} is the size (in bytes) of the terminator char according to the provided charset. For instance,
1158 * this is 1 for {@link StandardCharsets#US_ASCII} and 2 for {@link StandardCharsets#UTF_16}.</li>
1159 * </ul>
1160 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1161 * {@linkplain Scope#isAlive() alive}.
1162 * @throws WrongThreadException if this method is called from a thread {@code T},
1163 * such that {@code isAccessibleBy(T) == false}.
1164 * @throws UnsupportedOperationException if {@code charset} is not a {@linkplain StandardCharsets standard charset}.
1165 */
1166 default void setString(long offset, String str, Charset charset) {
1167 Objects.requireNonNull(charset);
1168 Objects.requireNonNull(str);
1169 StringSupport.write(this, offset, charset, str);
1170 }
1171
1172 /**
1173 * Creates a memory segment that is backed by the same region of memory that backs the given {@link Buffer} instance.
1174 * The segment starts relative to the buffer's position (inclusive) and ends relative to the buffer's limit (exclusive).
1175 * <p>
1176 * If the buffer is {@linkplain Buffer#isReadOnly() read-only}, the resulting segment is also
1177 * {@linkplain ByteBuffer#isReadOnly() read-only}. Moreover, if the buffer is a {@linkplain Buffer#isDirect() direct buffer},
1178 * the returned segment is a native segment; otherwise the returned memory segment is a heap segment.
1179 * <p>
1180 * If the provided buffer has been obtained by calling {@link #asByteBuffer()} on a memory segment whose
1181 * {@linkplain Scope scope} is {@code S}, the returned segment will be associated with the
1182 * same scope {@code S}. Otherwise, the scope of the returned segment is a fresh scope that is always alive.
1183 * <p>
1184 * The scope associated with the returned segment keeps the provided buffer reachable. As such, if
1185 * the provided buffer is a direct buffer, its backing memory region will not be deallocated as long as the
1186 * returned segment (or any of its slices) are kept reachable.
1187 *
1188 * @param buffer the buffer instance to be turned into a new memory segment.
1189 * @return a memory segment, derived from the given buffer instance.
1190 * @throws IllegalArgumentException if the provided {@code buffer} is a heap buffer but is not backed by an array.
1314 * do not overlap, but refer to overlapping regions of the same backing storage using different addresses.
1315 * For example, this may occur if the same file is {@linkplain FileChannel#map mapped} to two segments.
1316 * <p>
1317 * Calling this method is equivalent to the following code:
1318 * {@snippet lang=java :
1319 * MemorySegment.copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes);
1320 * }
1321 * @param srcSegment the source segment.
1322 * @param srcOffset the starting offset, in bytes, of the source segment.
1323 * @param dstSegment the destination segment.
1324 * @param dstOffset the starting offset, in bytes, of the destination segment.
1325 * @param bytes the number of bytes to be copied.
1326 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not
1327 * {@linkplain Scope#isAlive() alive}.
1328 * @throws WrongThreadException if this method is called from a thread {@code T},
1329 * such that {@code srcSegment.isAccessibleBy(T) == false}.
1330 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
1331 * {@linkplain Scope#isAlive() alive}.
1332 * @throws WrongThreadException if this method is called from a thread {@code T},
1333 * such that {@code dstSegment.isAccessibleBy(T) == false}.
1334 * @throws IndexOutOfBoundsException if {@code srcOffset > srcSegment.byteSize() - bytes}.
1335 * @throws IndexOutOfBoundsException if {@code dstOffset > dstSegment.byteSize() - bytes}.
1336 * @throws IndexOutOfBoundsException if either {@code srcOffset}, {@code dstOffset}
1337 * or {@code bytes} are {@code < 0}.
1338 * @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}.
1339 */
1340 @ForceInline
1341 static void copy(MemorySegment srcSegment, long srcOffset,
1342 MemorySegment dstSegment, long dstOffset, long bytes) {
1343 copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes);
1344 }
1345
1346 /**
1347 * Performs a bulk copy from source segment to destination segment. More specifically, if {@code S} is the byte size
1348 * of the element layouts, the bytes at offset {@code srcOffset} through {@code srcOffset + (elementCount * S) - 1}
1349 * in the source segment are copied into the destination segment at offset {@code dstOffset} through {@code dstOffset + (elementCount * S) - 1}.
1350 * <p>
1351 * The copy occurs in an element-wise fashion: the bytes in the source segment are interpreted as a sequence of elements
1352 * whose layout is {@code srcElementLayout}, whereas the bytes in the destination segment are interpreted as a sequence of
1353 * elements whose layout is {@code dstElementLayout}. Both element layouts must have same size {@code S}.
1354 * If the byte order of the two element layouts differ, the bytes corresponding to each element to be copied
1355 * are swapped accordingly during the copy operation.
1356 * <p>
1357 * If the source segment overlaps with the destination segment, then the copying is performed as if the bytes at
1358 * offset {@code srcOffset} through {@code srcOffset + (elementCount * S) - 1} in the source segment were first copied into a
1359 * temporary segment with size {@code bytes}, and then the contents of the temporary segment were copied into
1360 * the destination segment at offset {@code dstOffset} through {@code dstOffset + (elementCount * S) - 1}.
1361 * <p>
1362 * The result of a bulk copy is unspecified if, in the uncommon case, the source segment and the destination segment
1363 * do not overlap, but refer to overlapping regions of the same backing storage using different addresses.
1364 * For example, this may occur if the same file is {@linkplain FileChannel#map mapped} to two segments.
1365 * @param srcSegment the source segment.
1366 * @param srcElementLayout the element layout associated with the source segment.
1367 * @param srcOffset the starting offset, in bytes, of the source segment.
1368 * @param dstSegment the destination segment.
1369 * @param dstElementLayout the element layout associated with the destination segment.
1370 * @param dstOffset the starting offset, in bytes, of the destination segment.
1371 * @param elementCount the number of elements to be copied.
1372 * @throws IllegalArgumentException if the element layouts have different sizes, if the source (resp. destination) segment/offset are
1373 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the source
1374 * (resp. destination) element layout.
1375 * @throws IllegalArgumentException if {@code srcElementLayout.byteAlignment() > srcElementLayout.byteSize()}.
1376 * @throws IllegalArgumentException if {@code dstElementLayout.byteAlignment() > dstElementLayout.byteSize()}.
1377 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not
1378 * {@linkplain Scope#isAlive() alive}.
1379 * @throws WrongThreadException if this method is called from a thread {@code T},
1380 * such that {@code srcSegment.isAccessibleBy(T) == false}.
1381 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
1382 * {@linkplain Scope#isAlive() alive}.
1383 * @throws WrongThreadException if this method is called from a thread {@code T},
1384 * such that {@code dstSegment.isAccessibleBy(T) == false}.
1385 * @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}.
1386 * @throws IndexOutOfBoundsException if {@code elementCount * srcLayout.byteSize()} overflows.
1387 * @throws IndexOutOfBoundsException if {@code elementCount * dtsLayout.byteSize()} overflows.
1388 * @throws IndexOutOfBoundsException if {@code srcOffset > srcSegment.byteSize() - (elementCount * srcLayout.byteSize())}.
1389 * @throws IndexOutOfBoundsException if {@code dstOffset > dstSegment.byteSize() - (elementCount * dstLayout.byteSize())}.
1390 * @throws IndexOutOfBoundsException if either {@code srcOffset}, {@code dstOffset} or {@code elementCount} are {@code < 0}.
1391 */
1392 @ForceInline
1393 static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long srcOffset,
1394 MemorySegment dstSegment, ValueLayout dstElementLayout, long dstOffset,
1395 long elementCount) {
1396 Objects.requireNonNull(srcSegment);
1397 Objects.requireNonNull(srcElementLayout);
1398 Objects.requireNonNull(dstSegment);
1399 Objects.requireNonNull(dstElementLayout);
1400 AbstractMemorySegmentImpl.copy(srcSegment, srcElementLayout, srcOffset, dstSegment, dstElementLayout, dstOffset, elementCount);
1401 }
1402
1403 /**
1404 * Reads a byte from this segment at the given offset, with the given layout.
1405 *
1406 * @param layout the layout of the region of memory to be read.
1407 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1408 * @return a byte value read from this segment.
1409 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1410 * {@linkplain Scope#isAlive() alive}.
1411 * @throws WrongThreadException if this method is called from a thread {@code T},
1412 * such that {@code isAccessibleBy(T) == false}.
1413 * @throws IllegalArgumentException if the access operation is
1414 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1415 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1416 */
1417 @ForceInline
1418 default byte get(ValueLayout.OfByte layout, long offset) {
1419 return (byte) layout.varHandle().get(this, offset);
1420 }
1421
1422 /**
1423 * Writes a byte into this segment at the given offset, with the given layout.
1424 *
1425 * @param layout the layout of the region of memory to be written.
1426 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1427 * @param value the byte value to be written.
1428 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1429 * {@linkplain Scope#isAlive() alive}.
1430 * @throws WrongThreadException if this method is called from a thread {@code T},
1431 * such that {@code isAccessibleBy(T) == false}.
1432 * @throws IllegalArgumentException if the access operation is
1433 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1434 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1435 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1436 */
1437 @ForceInline
1438 default void set(ValueLayout.OfByte layout, long offset, byte value) {
1439 layout.varHandle().set(this, offset, value);
1440 }
1441
1442 /**
1443 * Reads a boolean from this segment at the given offset, with the given layout.
1444 *
1445 * @param layout the layout of the region of memory to be read.
1446 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1447 * @return a boolean value read from this segment.
1448 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1449 * {@linkplain Scope#isAlive() alive}.
1450 * @throws WrongThreadException if this method is called from a thread {@code T},
1451 * such that {@code isAccessibleBy(T) == false}.
1452 * @throws IllegalArgumentException if the access operation is
1453 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1454 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1455 */
1456 @ForceInline
1457 default boolean get(ValueLayout.OfBoolean layout, long offset) {
1458 return (boolean) layout.varHandle().get(this, offset);
1459 }
1460
1461 /**
1462 * Writes a boolean into this segment at the given offset, with the given layout.
1463 *
1464 * @param layout the layout of the region of memory to be written.
1465 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1466 * @param value the boolean value to be written.
1467 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1468 * {@linkplain Scope#isAlive() alive}.
1469 * @throws WrongThreadException if this method is called from a thread {@code T},
1470 * such that {@code isAccessibleBy(T) == false}.
1471 * @throws IllegalArgumentException if the access operation is
1472 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1473 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1474 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1475 */
1476 @ForceInline
1477 default void set(ValueLayout.OfBoolean layout, long offset, boolean value) {
1478 layout.varHandle().set(this, offset, value);
1479 }
1480
1481 /**
1482 * Reads a char from this segment at the given offset, with the given layout.
1483 *
1484 * @param layout the layout of the region of memory to be read.
1485 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1486 * @return a char value read from this segment.
1487 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1488 * {@linkplain Scope#isAlive() alive}.
1489 * @throws WrongThreadException if this method is called from a thread {@code T},
1490 * such that {@code isAccessibleBy(T) == false}.
1491 * @throws IllegalArgumentException if the access operation is
1492 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1493 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1494 */
1495 @ForceInline
1496 default char get(ValueLayout.OfChar layout, long offset) {
1497 return (char) layout.varHandle().get(this, offset);
1498 }
1499
1500 /**
1501 * Writes a char into this segment at the given offset, with the given layout.
1502 *
1503 * @param layout the layout of the region of memory to be written.
1504 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1505 * @param value the char value to be written.
1506 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1507 * {@linkplain Scope#isAlive() alive}.
1508 * @throws WrongThreadException if this method is called from a thread {@code T},
1509 * such that {@code isAccessibleBy(T) == false}.
1510 * @throws IllegalArgumentException if the access operation is
1511 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1512 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1513 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1514 */
1515 @ForceInline
1516 default void set(ValueLayout.OfChar layout, long offset, char value) {
1517 layout.varHandle().set(this, offset, value);
1518 }
1519
1520 /**
1521 * Reads a short from this segment at the given offset, with the given layout.
1522 *
1523 * @param layout the layout of the region of memory to be read.
1524 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1525 * @return a short value read from this segment.
1526 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1527 * {@linkplain Scope#isAlive() alive}.
1528 * @throws WrongThreadException if this method is called from a thread {@code T},
1529 * such that {@code isAccessibleBy(T) == false}.
1530 * @throws IllegalArgumentException if the access operation is
1531 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1532 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1533 */
1534 @ForceInline
1535 default short get(ValueLayout.OfShort layout, long offset) {
1536 return (short) layout.varHandle().get(this, offset);
1537 }
1538
1539 /**
1540 * Writes a short into this segment at the given offset, with the given layout.
1541 *
1542 * @param layout the layout of the region of memory to be written.
1543 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1544 * @param value the short value to be written.
1545 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1546 * {@linkplain Scope#isAlive() alive}.
1547 * @throws WrongThreadException if this method is called from a thread {@code T},
1548 * such that {@code isAccessibleBy(T) == false}.
1549 * @throws IllegalArgumentException if the access operation is
1550 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1551 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1552 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1553 */
1554 @ForceInline
1555 default void set(ValueLayout.OfShort layout, long offset, short value) {
1556 layout.varHandle().set(this, offset, value);
1557 }
1558
1559 /**
1560 * Reads an int from this segment at the given offset, with the given layout.
1561 *
1562 * @param layout the layout of the region of memory to be read.
1563 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1564 * @return an int value read from this segment.
1565 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1566 * {@linkplain Scope#isAlive() alive}.
1567 * @throws WrongThreadException if this method is called from a thread {@code T},
1568 * such that {@code isAccessibleBy(T) == false}.
1569 * @throws IllegalArgumentException if the access operation is
1570 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1571 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1572 */
1573 @ForceInline
1574 default int get(ValueLayout.OfInt layout, long offset) {
1575 return (int) layout.varHandle().get(this, offset);
1576 }
1577
1578 /**
1579 * Writes an int into this segment at the given offset, with the given layout.
1580 *
1581 * @param layout the layout of the region of memory to be written.
1582 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1583 * @param value the int value to be written.
1584 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1585 * {@linkplain Scope#isAlive() alive}.
1586 * @throws WrongThreadException if this method is called from a thread {@code T},
1587 * such that {@code isAccessibleBy(T) == false}.
1588 * @throws IllegalArgumentException if the access operation is
1589 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1590 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1591 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1592 */
1593 @ForceInline
1594 default void set(ValueLayout.OfInt layout, long offset, int value) {
1595 layout.varHandle().set(this, offset, value);
1596 }
1597
1598 /**
1599 * Reads a float from this segment at the given offset, with the given layout.
1600 *
1601 * @param layout the layout of the region of memory to be read.
1602 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1603 * @return a float value read from this segment.
1604 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1605 * {@linkplain Scope#isAlive() alive}.
1606 * @throws WrongThreadException if this method is called from a thread {@code T},
1607 * such that {@code isAccessibleBy(T) == false}.
1608 * @throws IllegalArgumentException if the access operation is
1609 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1610 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1611 */
1612 @ForceInline
1613 default float get(ValueLayout.OfFloat layout, long offset) {
1614 return (float)layout.varHandle().get(this, offset);
1615 }
1616
1617 /**
1618 * Writes a float into this segment at the given offset, with the given layout.
1619 *
1620 * @param layout the layout of the region of memory to be written.
1621 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1622 * @param value the float value to be written.
1623 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1624 * {@linkplain Scope#isAlive() alive}.
1625 * @throws WrongThreadException if this method is called from a thread {@code T},
1626 * such that {@code isAccessibleBy(T) == false}.
1627 * @throws IllegalArgumentException if the access operation is
1628 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1629 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1630 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1631 */
1632 @ForceInline
1633 default void set(ValueLayout.OfFloat layout, long offset, float value) {
1634 layout.varHandle().set(this, offset, value);
1635 }
1636
1637 /**
1638 * Reads a long from this segment at the given offset, with the given layout.
1639 *
1640 * @param layout the layout of the region of memory to be read.
1641 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1642 * @return a long value read from this segment.
1643 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1644 * {@linkplain Scope#isAlive() alive}.
1645 * @throws WrongThreadException if this method is called from a thread {@code T},
1646 * such that {@code isAccessibleBy(T) == false}.
1647 * @throws IllegalArgumentException if the access operation is
1648 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1649 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1650 */
1651 @ForceInline
1652 default long get(ValueLayout.OfLong layout, long offset) {
1653 return (long) layout.varHandle().get(this, offset);
1654 }
1655
1656 /**
1657 * Writes a long into this segment at the given offset, with the given layout.
1658 *
1659 * @param layout the layout of the region of memory to be written.
1660 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1661 * @param value the long value to be written.
1662 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1663 * {@linkplain Scope#isAlive() alive}.
1664 * @throws WrongThreadException if this method is called from a thread {@code T},
1665 * such that {@code isAccessibleBy(T) == false}.
1666 * @throws IllegalArgumentException if the access operation is
1667 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1668 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1669 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1670 */
1671 @ForceInline
1672 default void set(ValueLayout.OfLong layout, long offset, long value) {
1673 layout.varHandle().set(this, offset, value);
1674 }
1675
1676 /**
1677 * Reads a double from this segment at the given offset, with the given layout.
1678 *
1679 * @param layout the layout of the region of memory to be read.
1680 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1681 * @return a double value read from this segment.
1682 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1683 * {@linkplain Scope#isAlive() alive}.
1684 * @throws WrongThreadException if this method is called from a thread {@code T},
1685 * such that {@code isAccessibleBy(T) == false}.
1686 * @throws IllegalArgumentException if the access operation is
1687 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1688 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1689 */
1690 @ForceInline
1691 default double get(ValueLayout.OfDouble layout, long offset) {
1692 return (double) layout.varHandle().get(this, offset);
1693 }
1694
1695 /**
1696 * Writes a double into this segment at the given offset, with the given layout.
1697 *
1698 * @param layout the layout of the region of memory to be written.
1699 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1700 * @param value the double value to be written.
1701 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1702 * {@linkplain Scope#isAlive() alive}.
1703 * @throws WrongThreadException if this method is called from a thread {@code T},
1704 * such that {@code isAccessibleBy(T) == false}.
1705 * @throws IllegalArgumentException if the access operation is
1706 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1707 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1708 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1709 */
1710 @ForceInline
1711 default void set(ValueLayout.OfDouble layout, long offset, double value) {
1712 layout.varHandle().set(this, offset, value);
1713 }
1714
1715 /**
1716 * Reads an address from this segment at the given offset, with the given layout. The read address is wrapped in
1717 * a native segment, associated with a fresh scope that is always alive. Under normal conditions,
1718 * the size of the returned segment is {@code 0}. However, if the provided address layout has a
1719 * {@linkplain AddressLayout#targetLayout() target layout} {@code T}, then the size of the returned segment
1720 * is set to {@code T.byteSize()}.
1721 * @param layout the layout of the region of memory to be read.
1722 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1723 * @return a native segment wrapping an address read from this segment.
1724 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1725 * {@linkplain Scope#isAlive() alive}.
1726 * @throws WrongThreadException if this method is called from a thread {@code T},
1727 * such that {@code isAccessibleBy(T) == false}.
1728 * @throws IllegalArgumentException if the access operation is
1729 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1730 * @throws IllegalArgumentException if provided address layout has a {@linkplain AddressLayout#targetLayout() target layout}
1731 * {@code T}, and the address of the returned segment
1732 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in {@code T}.
1733 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1734 */
1735 @ForceInline
1736 default MemorySegment get(AddressLayout layout, long offset) {
1737 return (MemorySegment) layout.varHandle().get(this, offset);
1738 }
1739
1740 /**
1741 * Writes an address into this segment at the given offset, with the given layout.
1742 *
1743 * @param layout the layout of the region of memory to be written.
1744 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur.
1745 * @param value the address value to be written.
1746 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1747 * {@linkplain Scope#isAlive() alive}.
1748 * @throws WrongThreadException if this method is called from a thread {@code T},
1749 * such that {@code isAccessibleBy(T) == false}.
1750 * @throws IllegalArgumentException if the access operation is
1751 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1752 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
1753 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1754 * @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment.
1755 */
1756 @ForceInline
1757 default void set(AddressLayout layout, long offset, MemorySegment value) {
1758 layout.varHandle().set(this, offset, value);
1759 }
1760
1761 /**
1762 * Reads a byte from this segment at the given index, scaled by the given layout size.
1763 *
1764 * @param layout the layout of the region of memory to be read.
1765 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1766 * will occur can be expressed as {@code (index * layout.byteSize())}.
1767 * @return a byte value read from this segment.
1768 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1769 * {@linkplain Scope#isAlive() alive}.
1770 * @throws WrongThreadException if this method is called from a thread {@code T},
1771 * such that {@code isAccessibleBy(T) == false}.
1772 * @throws IllegalArgumentException if the access operation is
1773 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1774 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
1775 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1776 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1777 */
1778 @ForceInline
1779 default byte getAtIndex(ValueLayout.OfByte layout, long index) {
1780 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1781 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1782 return (byte) layout.varHandle().get(this, index * layout.byteSize());
1783 }
1784
1785 /**
1786 * Reads a boolean from this segment at the given index, scaled by the given layout size.
1787 *
1788 * @param layout the layout of the region of memory to be read.
1789 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1790 * will occur can be expressed as {@code (index * layout.byteSize())}.
1791 * @return a boolean value read from this segment.
1792 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1793 * {@linkplain Scope#isAlive() alive}.
1794 * @throws WrongThreadException if this method is called from a thread {@code T},
1795 * such that {@code isAccessibleBy(T) == false}.
1796 * @throws IllegalArgumentException if the access operation is
1797 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1798 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
1799 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1800 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1801 */
1802 @ForceInline
1803 default boolean getAtIndex(ValueLayout.OfBoolean layout, long index) {
1804 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1805 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1806 return (boolean) layout.varHandle().get(this, index * layout.byteSize());
1807 }
1808
1809 /**
1810 * Reads a char from this segment at the given index, scaled by the given layout size.
1811 *
1812 * @param layout the layout of the region of memory to be read.
1813 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1814 * will occur can be expressed as {@code (index * layout.byteSize())}.
1815 * @return a char value read from this segment.
1816 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1817 * {@linkplain Scope#isAlive() alive}.
1818 * @throws WrongThreadException if this method is called from a thread {@code T},
1819 * such that {@code isAccessibleBy(T) == false}.
1820 * @throws IllegalArgumentException if the access operation is
1821 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1822 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
1823 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1824 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1825 */
1826 @ForceInline
1827 default char getAtIndex(ValueLayout.OfChar layout, long index) {
1828 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1829 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1830 return (char) layout.varHandle().get(this, index * layout.byteSize());
1831 }
1832
1833 /**
1834 * Writes a char into this segment at the given index, scaled by the given layout size.
1835 *
1836 * @param layout the layout of the region of memory to be written.
1837 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1838 * will occur can be expressed as {@code (index * layout.byteSize())}.
1839 * @param value the char value to be written.
1840 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1841 * {@linkplain Scope#isAlive() alive}.
1842 * @throws WrongThreadException if this method is called from a thread {@code T},
1843 * such that {@code isAccessibleBy(T) == false}.
1844 * @throws IllegalArgumentException if the access operation is
1845 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1846 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
1847 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1848 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1849 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1850 */
1851 @ForceInline
1852 default void setAtIndex(ValueLayout.OfChar layout, long index, char value) {
1853 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1854 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1855 layout.varHandle().set(this, index * layout.byteSize(), value);
1856 }
1857
1858 /**
1859 * Reads a short from this segment at the given index, scaled by the given layout size.
1860 *
1861 * @param layout the layout of the region of memory to be read.
1862 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1863 * will occur can be expressed as {@code (index * layout.byteSize())}.
1864 * @return a short value read from this segment.
1865 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1866 * {@linkplain Scope#isAlive() alive}.
1867 * @throws WrongThreadException if this method is called from a thread {@code T},
1868 * such that {@code isAccessibleBy(T) == false}.
1869 * @throws IllegalArgumentException if the access operation is
1870 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1871 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
1872 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1873 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1874 */
1875 @ForceInline
1876 default short getAtIndex(ValueLayout.OfShort layout, long index) {
1877 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1878 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1879 return (short) layout.varHandle().get(this, index * layout.byteSize());
1880 }
1881
1882 /**
1883 * Writes a byte into this segment at the given index, scaled by the given layout size.
1884 *
1885 * @param layout the layout of the region of memory to be written.
1886 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1887 * will occur can be expressed as {@code (index * layout.byteSize())}.
1888 * @param value the short value to be written.
1889 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1890 * {@linkplain Scope#isAlive() alive}.
1891 * @throws WrongThreadException if this method is called from a thread {@code T},
1892 * such that {@code isAccessibleBy(T) == false}.
1893 * @throws IllegalArgumentException if the access operation is
1894 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1895 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
1896 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1897 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1898 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1899 */
1900 @ForceInline
1901 default void setAtIndex(ValueLayout.OfByte layout, long index, byte value) {
1902 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1903 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1904 layout.varHandle().set(this, index * layout.byteSize(), value);
1905
1906 }
1907
1908 /**
1909 * Writes a boolean into this segment at the given index, scaled by the given layout size.
1910 *
1911 * @param layout the layout of the region of memory to be written.
1912 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1913 * will occur can be expressed as {@code (index * layout.byteSize())}.
1914 * @param value the short value to be written.
1915 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1916 * {@linkplain Scope#isAlive() alive}.
1917 * @throws WrongThreadException if this method is called from a thread {@code T},
1918 * such that {@code isAccessibleBy(T) == false}.
1919 * @throws IllegalArgumentException if the access operation is
1920 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1921 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
1922 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1923 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1924 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1925 */
1926 @ForceInline
1927 default void setAtIndex(ValueLayout.OfBoolean layout, long index, boolean value) {
1928 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1929 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1930 layout.varHandle().set(this, index * layout.byteSize(), value);
1931 }
1932
1933 /**
1934 * Writes a short into this segment at the given index, scaled by the given layout size.
1935 *
1936 * @param layout the layout of the region of memory to be written.
1937 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1938 * will occur can be expressed as {@code (index * layout.byteSize())}.
1939 * @param value the short value to be written.
1940 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1941 * {@linkplain Scope#isAlive() alive}.
1942 * @throws WrongThreadException if this method is called from a thread {@code T},
1943 * such that {@code isAccessibleBy(T) == false}.
1944 * @throws IllegalArgumentException if the access operation is
1945 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1946 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
1947 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1948 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1949 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1950 */
1951 @ForceInline
1952 default void setAtIndex(ValueLayout.OfShort layout, long index, short value) {
1953 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1954 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1955 layout.varHandle().set(this, index * layout.byteSize(), value);
1956 }
1957
1958 /**
1959 * Reads an int from this segment at the given index, scaled by the given layout size.
1960 *
1961 * @param layout the layout of the region of memory to be read.
1962 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1963 * will occur can be expressed as {@code (index * layout.byteSize())}.
1964 * @return an int value read from this segment.
1965 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1966 * {@linkplain Scope#isAlive() alive}.
1967 * @throws WrongThreadException if this method is called from a thread {@code T},
1968 * such that {@code isAccessibleBy(T) == false}.
1969 * @throws IllegalArgumentException if the access operation is
1970 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1971 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
1972 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1973 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1974 */
1975 @ForceInline
1976 default int getAtIndex(ValueLayout.OfInt layout, long index) {
1977 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
1978 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
1979 return (int) layout.varHandle().get(this, index * layout.byteSize());
1980 }
1981
1982 /**
1983 * Writes an int into this segment at the given index, scaled by the given layout size.
1984 *
1985 * @param layout the layout of the region of memory to be written.
1986 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
1987 * will occur can be expressed as {@code (index * layout.byteSize())}.
1988 * @param value the int value to be written.
1989 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
1990 * {@linkplain Scope#isAlive() alive}.
1991 * @throws WrongThreadException if this method is called from a thread {@code T},
1992 * such that {@code isAccessibleBy(T) == false}.
1993 * @throws IllegalArgumentException if the access operation is
1994 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
1995 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
1996 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
1997 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
1998 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
1999 */
2000 @ForceInline
2001 default void setAtIndex(ValueLayout.OfInt layout, long index, int value) {
2002 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2003 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2004 layout.varHandle().set(this, index * layout.byteSize(), value);
2005 }
2006
2007 /**
2008 * Reads a float from this segment at the given index, scaled by the given layout size.
2009 *
2010 * @param layout the layout of the region of memory to be read.
2011 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
2012 * will occur can be expressed as {@code (index * layout.byteSize())}.
2013 * @return a float value read from this segment.
2014 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
2015 * {@linkplain Scope#isAlive() alive}.
2016 * @throws WrongThreadException if this method is called from a thread {@code T},
2017 * such that {@code isAccessibleBy(T) == false}.
2018 * @throws IllegalArgumentException if the access operation is
2019 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
2020 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
2021 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
2022 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
2023 */
2024 @ForceInline
2025 default float getAtIndex(ValueLayout.OfFloat layout, long index) {
2026 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2027 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2028 return (float) layout.varHandle().get(this, index * layout.byteSize());
2029 }
2030
2031 /**
2032 * Writes a float into this segment at the given index, scaled by the given layout size.
2033 *
2034 * @param layout the layout of the region of memory to be written.
2035 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
2036 * will occur can be expressed as {@code (index * layout.byteSize())}.
2037 * @param value the float value to be written.
2038 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
2039 * {@linkplain Scope#isAlive() alive}.
2040 * @throws WrongThreadException if this method is called from a thread {@code T},
2041 * such that {@code isAccessibleBy(T) == false}.
2042 * @throws IllegalArgumentException if the access operation is
2043 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
2044 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
2045 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
2046 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
2047 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
2048 */
2049 @ForceInline
2050 default void setAtIndex(ValueLayout.OfFloat layout, long index, float value) {
2051 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2052 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2053 layout.varHandle().set(this, index * layout.byteSize(), value);
2054 }
2055
2056 /**
2057 * Reads a long from this segment at the given index, scaled by the given layout size.
2058 *
2059 * @param layout the layout of the region of memory to be read.
2060 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
2061 * will occur can be expressed as {@code (index * layout.byteSize())}.
2062 * @return a long value read from this segment.
2063 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
2064 * {@linkplain Scope#isAlive() alive}.
2065 * @throws WrongThreadException if this method is called from a thread {@code T},
2066 * such that {@code isAccessibleBy(T) == false}.
2067 * @throws IllegalArgumentException if the access operation is
2068 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
2069 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
2070 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
2071 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
2072 */
2073 @ForceInline
2074 default long getAtIndex(ValueLayout.OfLong layout, long index) {
2075 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2076 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2077 return (long) layout.varHandle().get(this, index * layout.byteSize());
2078 }
2079
2080 /**
2081 * Writes a long into this segment at the given index, scaled by the given layout size.
2082 *
2083 * @param layout the layout of the region of memory to be written.
2084 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
2085 * will occur can be expressed as {@code (index * layout.byteSize())}.
2086 * @param value the long value to be written.
2087 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
2088 * {@linkplain Scope#isAlive() alive}.
2089 * @throws WrongThreadException if this method is called from a thread {@code T},
2090 * such that {@code isAccessibleBy(T) == false}.
2091 * @throws IllegalArgumentException if the access operation is
2092 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
2093 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
2094 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
2095 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
2096 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
2097 */
2098 @ForceInline
2099 default void setAtIndex(ValueLayout.OfLong layout, long index, long value) {
2100 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2101 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2102 layout.varHandle().set(this, index * layout.byteSize(), value);
2103 }
2104
2105 /**
2106 * Reads a double from this segment at the given index, scaled by the given layout size.
2107 *
2108 * @param layout the layout of the region of memory to be read.
2109 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
2110 * will occur can be expressed as {@code (index * layout.byteSize())}.
2111 * @return a double value read from this segment.
2112 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
2113 * {@linkplain Scope#isAlive() alive}.
2114 * @throws WrongThreadException if this method is called from a thread {@code T},
2115 * such that {@code isAccessibleBy(T) == false}.
2116 * @throws IllegalArgumentException if the access operation is
2117 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
2118 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
2119 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
2120 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
2121 */
2122 @ForceInline
2123 default double getAtIndex(ValueLayout.OfDouble layout, long index) {
2124 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2125 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2126 return (double) layout.varHandle().get(this, index * layout.byteSize());
2127 }
2128
2129 /**
2130 * Writes a double into this segment at the given index, scaled by the given layout size.
2131 *
2132 * @param layout the layout of the region of memory to be written.
2133 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
2134 * will occur can be expressed as {@code (index * layout.byteSize())}.
2135 * @param value the double value to be written.
2136 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
2137 * {@linkplain Scope#isAlive() alive}.
2138 * @throws WrongThreadException if this method is called from a thread {@code T},
2139 * such that {@code isAccessibleBy(T) == false}.
2140 * @throws IllegalArgumentException if the access operation is
2141 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
2142 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
2143 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
2144 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
2145 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
2146 */
2147 @ForceInline
2148 default void setAtIndex(ValueLayout.OfDouble layout, long index, double value) {
2149 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2150 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2151 layout.varHandle().set(this, index * layout.byteSize(), value);
2152 }
2153
2154 /**
2155 * 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
2156 * a native segment, associated with a fresh scope that is always alive. Under normal conditions,
2157 * the size of the returned segment is {@code 0}. However, if the provided address layout has a
2158 * {@linkplain AddressLayout#targetLayout() target layout} {@code T}, then the size of the returned segment
2159 * is set to {@code T.byteSize()}.
2160 * @param layout the layout of the region of memory to be read.
2161 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
2162 * will occur can be expressed as {@code (index * layout.byteSize())}.
2163 * @return a native segment wrapping an address read from this segment.
2164 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
2165 * {@linkplain Scope#isAlive() alive}.
2166 * @throws WrongThreadException if this method is called from a thread {@code T},
2167 * such that {@code isAccessibleBy(T) == false}.
2168 * @throws IllegalArgumentException if the access operation is
2169 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
2170 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
2171 * @throws IllegalArgumentException if provided address layout has a {@linkplain AddressLayout#targetLayout() target layout}
2172 * {@code T}, and the address of the returned segment
2173 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in {@code T}.
2174 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
2175 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
2176 */
2177 @ForceInline
2178 default MemorySegment getAtIndex(AddressLayout layout, long index) {
2179 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2180 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2181 return (MemorySegment) layout.varHandle().get(this, index * layout.byteSize());
2182 }
2183
2184 /**
2185 * Writes an address into this segment at the given index, scaled by the given layout size.
2186 *
2187 * @param layout the layout of the region of memory to be written.
2188 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation
2189 * will occur can be expressed as {@code (index * layout.byteSize())}.
2190 * @param value the address value to be written.
2191 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not
2192 * {@linkplain Scope#isAlive() alive}.
2193 * @throws WrongThreadException if this method is called from a thread {@code T},
2194 * such that {@code isAccessibleBy(T) == false}.
2195 * @throws IllegalArgumentException if the access operation is
2196 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
2197 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}.
2198 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
2199 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
2200 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
2201 * @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment.
2202 */
2203 @ForceInline
2204 default void setAtIndex(AddressLayout layout, long index, MemorySegment value) {
2205 Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
2206 // note: we know size is a small value (as it comes from ValueLayout::byteSize())
2207 layout.varHandle().set(this, index * layout.byteSize(), value);
2208 }
2209
2210 /**
2211 * Compares the specified object with this memory segment for equality. Returns {@code true} if and only if the specified
2212 * object is also a memory segment, and if the two segments refer to the same location, in some region of memory.
2213 * More specifically, for two segments {@code s1} and {@code s2} to be considered equals, all the following must be true:
2214 * <ul>
2215 * <li>{@code s1.heapBase().equals(s2.heapBase())}, that is, the two segments must be of the same kind;
2216 * either both are {@linkplain #isNative() native segments}, backed by off-heap memory, or both are backed by
2217 * the same on-heap {@linkplain #heapBase() Java object};
2218 * <li>{@code s1.address() == s2.address()}, that is, the address of the two segments should be the same.
2219 * This means that the two segments either refer to the same location in some off-heap region, or they refer
2220 * to the same offset inside their associated {@linkplain #heapBase() Java object}.</li>
2221 * </ul>
2222 * @apiNote This method does not perform a structural comparison of the contents of the two memory segments. Clients can
2223 * compare memory segments structurally by using the {@link #mismatch(MemorySegment)} method instead. Note that this
2224 * method does <em>not</em> compare the temporal and spatial bounds of two segments. As such it is suitable
2225 * to check whether two segments have the same address.
2226 *
2227 * @param that the object to be compared for equality with this memory segment.
2236 */
2237 @Override
2238 int hashCode();
2239
2240
2241 /**
2242 * Copies a number of elements from a source memory segment to a destination array. The elements, whose size and alignment
2243 * constraints are specified by the given layout, are read from the source segment, starting at the given offset
2244 * (expressed in bytes), and are copied into the destination array, at the given index.
2245 * Supported array types are {@code byte[]}, {@code char[]}, {@code short[]}, {@code int[]}, {@code float[]}, {@code long[]} and {@code double[]}.
2246 * @param srcSegment the source segment.
2247 * @param srcLayout the source element layout. If the byte order associated with the layout is
2248 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element.
2249 * @param srcOffset the starting offset, in bytes, of the source segment.
2250 * @param dstArray the destination array.
2251 * @param dstIndex the starting index of the destination array.
2252 * @param elementCount the number of array elements to be copied.
2253 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not
2254 * {@linkplain Scope#isAlive() alive}.
2255 * @throws WrongThreadException if this method is called from a thread {@code T},
2256 * such that {@code srcSegment.isAccessibleBy(T) == false}.
2257 * @throws IllegalArgumentException if {@code dstArray} is not an array, or if it is an array but whose type is not supported.
2258 * @throws IllegalArgumentException if the destination array component type does not match {@code srcLayout.carrier()}.
2259 * @throws IllegalArgumentException if {@code offset} is <a href="MemorySegment.html#segment-alignment">incompatible
2260 * with the alignment constraint</a> in the source element layout.
2261 * @throws IllegalArgumentException if {@code srcLayout.byteAlignment() > srcLayout.byteSize()}.
2262 * @throws IndexOutOfBoundsException if {@code elementCount * srcLayout.byteSize()} overflows.
2263 * @throws IndexOutOfBoundsException if {@code srcOffset > srcSegment.byteSize() - (elementCount * srcLayout.byteSize())}.
2264 * @throws IndexOutOfBoundsException if {@code dstIndex > dstArray.length - elementCount}.
2265 * @throws IndexOutOfBoundsException if either {@code srcOffset}, {@code dstIndex} or {@code elementCount} are {@code < 0}.
2266 */
2267 @ForceInline
2268 static void copy(
2269 MemorySegment srcSegment, ValueLayout srcLayout, long srcOffset,
2270 Object dstArray, int dstIndex, int elementCount) {
2271 Objects.requireNonNull(srcSegment);
2272 Objects.requireNonNull(dstArray);
2273 Objects.requireNonNull(srcLayout);
2274
2275 AbstractMemorySegmentImpl.copy(srcSegment, srcLayout, srcOffset,
2276 dstArray, dstIndex,
2277 elementCount);
2278 }
2279
2280 /**
2281 * Copies a number of elements from a source array to a destination memory segment. The elements, whose size and alignment
2282 * constraints are specified by the given layout, are read from the source array, starting at the given index,
2283 * and are copied into the destination segment, at the given offset (expressed in bytes).
2284 * Supported array types are {@code byte[]}, {@code char[]}, {@code short[]}, {@code int[]}, {@code float[]}, {@code long[]} and {@code double[]}.
2285 * @param srcArray the source array.
2286 * @param srcIndex the starting index of the source array.
2287 * @param dstSegment the destination segment.
2288 * @param dstLayout the destination element layout. If the byte order associated with the layout is
2289 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element.
2290 * @param dstOffset the starting offset, in bytes, of the destination segment.
2291 * @param elementCount the number of array elements to be copied.
2292 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not
2293 * {@linkplain Scope#isAlive() alive}.
2294 * @throws WrongThreadException if this method is called from a thread {@code T},
2295 * such that {@code dstSegment.isAccessibleBy(T) == false}.
2296 * @throws IllegalArgumentException if {@code srcArray} is not an array, or if it is an array but whose type is not supported.
2297 * @throws IllegalArgumentException if the source array component type does not match {@code srcLayout.carrier()}.
2298 * @throws IllegalArgumentException if {@code offset} is <a href="MemorySegment.html#segment-alignment">incompatible
2299 * with the alignment constraint</a> in the source element layout.
2300 * @throws IllegalArgumentException if {@code dstLayout.byteAlignment() > dstLayout.byteSize()}.
2301 * @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}.
2302 * @throws IndexOutOfBoundsException if {@code elementCount * dstLayout.byteSize()} overflows.
2303 * @throws IndexOutOfBoundsException if {@code dstOffset > dstSegment.byteSize() - (elementCount * dstLayout.byteSize())}.
2304 * @throws IndexOutOfBoundsException if {@code srcIndex > srcArray.length - elementCount}.
2305 * @throws IndexOutOfBoundsException if either {@code srcIndex}, {@code dstOffset} or {@code elementCount} are {@code < 0}.
2306 */
2307 @ForceInline
2308 static void copy(
2309 Object srcArray, int srcIndex,
2310 MemorySegment dstSegment, ValueLayout dstLayout, long dstOffset, int elementCount) {
2311 Objects.requireNonNull(srcArray);
2312 Objects.requireNonNull(dstSegment);
2313 Objects.requireNonNull(dstLayout);
2314
2315 AbstractMemorySegmentImpl.copy(srcArray, srcIndex,
2350 * @throws IndexOutOfBoundsException if {@code dstFromOffset < 0}, {@code dstToOffset < dstFromOffset} or
2351 * {@code dstToOffset > dstSegment.byteSize()}
2352 *
2353 * @see MemorySegment#mismatch(MemorySegment)
2354 * @see Arrays#mismatch(Object[], int, int, Object[], int, int)
2355 */
2356 static long mismatch(MemorySegment srcSegment, long srcFromOffset, long srcToOffset,
2357 MemorySegment dstSegment, long dstFromOffset, long dstToOffset) {
2358 return AbstractMemorySegmentImpl.mismatch(srcSegment, srcFromOffset, srcToOffset,
2359 dstSegment, dstFromOffset, dstToOffset);
2360 }
2361
2362 /**
2363 * A scope models the <em>lifetime</em> of all the memory segments associated with it. That is, a memory segment
2364 * cannot be accessed if its associated scope is not {@linkplain #isAlive() alive}. A new scope is typically
2365 * obtained indirectly, by creating a new {@linkplain Arena arena}.
2366 * <p>
2367 * Scope instances can be compared for equality. That is, two scopes
2368 * are considered {@linkplain #equals(Object)} if they denote the same lifetime.
2369 */
2370 sealed interface Scope permits MemorySessionImpl {
2371 /**
2372 * {@return {@code true}, if the regions of memory backing the memory segments associated with this scope are
2373 * still valid}
2374 */
2375 boolean isAlive();
2376
2377 /**
2378 * {@return {@code true}, if the provided object is also a scope, which models the same lifetime as that
2379 * modelled by this scope}. In that case, it is always the case that
2380 * {@code this.isAlive() == ((Scope)that).isAlive()}.
2381 * @param that the object to be tested.
2382 */
2383 @Override
2384 boolean equals(Object that);
2385
2386 /**
2387 * Returns the hash code of this scope object.
2388 * @implSpec Implementations of this method obey the general contract of {@link Object#hashCode}.
2389 * @return the hash code of this scope object.
|