1 /* 2 * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 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 73 * {@linkplain #load() loaded} to and from the underlying memory-mapped file. 74 * <p> 75 * Both kinds of segments are read and written using the same methods, known as <a href="#segment-deref">access operations</a>. 76 * An access operation on a memory segment always and only provides access to the region for which the segment was obtained. 77 * 78 * <h2 id="segment-characteristics">Characteristics of memory segments</h2> 79 * 80 * Every memory segment has an {@linkplain #address() address}, expressed as a {@code long} value. 81 * The nature of a segment's address depends on the kind of the segment: 82 * <ul> 83 * <li>The address of a heap segment is not a physical address, but rather an offset within the region of memory 84 * which backs the segment. The region is inside the Java heap, so garbage collection might cause the region to be 85 * relocated in physical memory over time, but this is not exposed to clients of the {@code MemorySegment} API who 86 * see a stable <em>virtualized</em> address for a heap segment backed by the region. 87 * A heap segment obtained from one of the {@link #ofArray(int[])} factory methods has an address of zero.</li> 88 * <li>The address of a native segment (including mapped segments) denotes the physical address of the region of 89 * memory which backs the segment.</li> 90 * </ul> 91 * <p> 92 * Every memory segment has a {@linkplain #byteSize() size}. The size of a heap segment is derived from the Java array 93 * from which it is obtained. This size is predictable across Java runtimes. 94 * The size of a native segment is either passed explicitly 95 * (as in {@link Arena#allocate(long, long)}) or derived from a {@link MemoryLayout} 96 * (as in {@link Arena#allocate(MemoryLayout)}). The size of a memory segment is typically 97 * a positive number but may be <a href="#wrapping-addresses">zero</a>, but never negative. 98 * <p> 99 * The address and size of a memory segment jointly ensure that access operations on the segment cannot fall 100 * <em>outside</em> the boundaries of the region of memory which backs the segment. 101 * That is, a memory segment has <em>spatial bounds</em>. 102 * <p> 103 * Every memory segment is associated with a {@linkplain Scope scope}. This ensures that access operations 104 * on a memory segment cannot occur when the region of memory which backs the memory segment is no longer available 105 * (e.g., after the scope associated with the accessed memory segment is no longer {@linkplain Scope#isAlive() alive}). 106 * That is, a memory segment has <em>temporal bounds</em>. 107 * <p> 108 * Finally, access operations on a memory segment can be subject to additional thread-confinement checks. 109 * Heap segments can be accessed from any thread. Conversely, native segments can only be accessed compatibly with the 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 176 * is inherited by its slices; that is, when the scope associated with {@code segment} is no longer {@linkplain Scope#isAlive() alive}, 177 * {@code slice} will also be become inaccessible. 178 * <p> 179 * A client might obtain a {@link Stream} from a segment, which can then be used to slice the segment (according to a given 180 * element layout) and even allow multiple threads to work in parallel on disjoint segment slices 181 * (to do this, the segment has to be {@linkplain MemorySegment#isAccessibleBy(Thread) accessible} 182 * from multiple threads). The following code can be used to sum all int values in a memory segment in parallel: 183 * 184 * {@snippet lang = java: 185 * try (Arena arena = Arena.ofShared()) { 186 * SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT); 187 * MemorySegment segment = arena.allocate(SEQUENCE_LAYOUT); 188 * int sum = segment.elements(ValueLayout.JAVA_INT).parallel() 189 * .mapToInt(s -> s.get(ValueLayout.JAVA_INT, 0)) 190 * .sum(); 191 * } 192 *} 193 * 194 * <h2 id="segment-alignment">Alignment</h2> 195 * 196 * Access operations on a memory segment are constrained not only by the spatial and temporal bounds of the segment, 197 * but also by the <em>alignment constraint</em> of the value layout specified to the operation. An access operation can 198 * access only those offsets in the segment that denote addresses in physical memory which are <em>aligned</em> according 199 * to the layout. An address in physical memory is <em>aligned</em> according to a layout if the address is an integer 200 * multiple of the layout's alignment constraint. For example, the address 1000 is aligned according to an 8-byte alignment 201 * constraint (because 1000 is an integer multiple of 8), and to a 4-byte alignment constraint, and to a 2-byte alignment 202 * constraint; in contrast, the address 1004 is aligned according to a 4-byte alignment constraint, and to a 2-byte alignment 203 * constraint, but not to an 8-byte alignment constraint. 204 * Access operations are required to respect alignment because it can impact the performance of access operations, and 205 * can also determine which access operations are available at a given physical address. For instance, 206 * {@linkplain java.lang.invoke.VarHandle#compareAndSet(Object...) atomic access operations} operations using 207 * {@link java.lang.invoke.VarHandle} are only permitted at aligned addresses. In addition, alignment 208 * applies to an access operation whether the segment being accessed is a native segment or a heap segment. 209 * <p> 210 * If the segment being accessed is a native segment, then its {@linkplain #address() address} in physical memory can be 211 * combined with the offset to obtain the <em>target address</em> in physical memory. The pseudo-function below demonstrates this: 212 * 213 * {@snippet lang = java: 214 * boolean isAligned(MemorySegment segment, long offset, MemoryLayout layout) { 215 * return ((segment.address() + offset) % layout.byteAlignment()) == 0; 216 * } 217 * } 218 * 219 * For example: 220 * <ul> 221 * <li>A native segment with address 1000 can be accessed at offsets 0, 8, 16, 24, etc under an 8-byte alignment constraint, 222 * because the target addresses (1000, 1008, 1016, 1024) are 8-byte aligned. 223 * Access at offsets 1-7 or 9-15 or 17-23 is disallowed because the target addresses would not be 8-byte aligned.</li> 224 * <li>A native segment with address 1000 can be accessed at offsets 0, 4, 8, 12, etc under a 4-byte alignment constraint, 225 * because the target addresses (1000, 1004, 1008, 1012) are 4-byte aligned. 226 * Access at offsets 1-3 or 5-7 or 9-11 is disallowed because the target addresses would not be 4-byte aligned.</li> 227 * <li>A native segment with address 1000 can be accessed at offsets 0, 2, 4, 6, etc under a 2-byte alignment constraint, 228 * because the target addresses (1000, 1002, 1004, 1006) are 2-byte aligned. 229 * Access at offsets 1 or 3 or 5 is disallowed because the target addresses would not be 2-byte aligned.</li> 230 * <li>A native segment with address 1004 can be accessed at offsets 0, 4, 8, 12, etc under a 4-byte alignment constraint, 231 * and at offsets 0, 2, 4, 6, etc under a 2-byte alignment constraint. 232 * Under an 8-byte alignment constraint, it can be accessed at offsets 4, 12, 20, 28, etc.</li> 233 * <li>A native segment with address 1006 can be accessed at offsets 0, 2, 4, 6, etc under a 2-byte alignment constraint. 234 * Under a 4-byte alignment constraint, it can be accessed at offsets 2, 6, 10, 14, etc. 235 * Under an 8-byte alignment constraint, it can be accessed at offsets 2, 10, 18, 26, etc. 236 * <li>A native segment with address 1007 can be accessed at offsets 0, 1, 2, 3, etc under a 1-byte alignment constraint. 237 * Under a 2-byte alignment constraint, it can be accessed at offsets 1, 3, 5, 7, etc. 238 * Under a 4-byte alignment constraint, it can be accessed at offsets 1, 5, 9, 13, etc. 239 * Under an 8-byte alignment constraint, it can be accessed at offsets 1, 9, 17, 25, etc.</li> 240 * </ul> 241 * <p> 242 * The alignment constraint used to access a segment is typically dictated by the shape of the data structure stored 243 * in the segment. For example, if the programmer wishes to store a sequence of 8-byte values in a native segment, then 244 * the segment should be allocated by specifying a 8-byte alignment constraint, either via {@link Arena#allocate(long, long)} 245 * or {@link Arena#allocate(MemoryLayout)}. These factories ensure that the off-heap region of memory backing 246 * the returned segment has a starting address that is 8-byte aligned. Subsequently, the programmer can access the 247 * segment at the offsets of interest -- 0, 8, 16, 24, etc -- in the knowledge that every such access is aligned. 248 * <p> 249 * If the segment being accessed is a heap segment, then determining whether access is aligned is more complex. 250 * The address of the segment in physical memory is not known, and is not even fixed (it may change when the segment 251 * is relocated during garbage collection). This means that the address cannot be combined with the specified offset to 252 * determine a target address in physical memory. Since the alignment constraint <em>always</em> refers to alignment of 253 * addresses in physical memory, it is not possible in principle to determine if any offset in a heap segment is aligned. 254 * For example, suppose the programmer chooses a 8-byte alignment constraint and tries 255 * to access offset 16 in a heap segment. If the heap segment's address 0 corresponds to physical address 1000, 256 * then the target address (1016) would be aligned, but if address 0 corresponds to physical address 1004, 257 * then the target address (1020) would not be aligned. It is undesirable to allow access to target addresses that are 258 * aligned according to the programmer's chosen alignment constraint, but might not be predictably aligned in physical memory 259 * (e.g. because of platform considerations and/or garbage collection behavior). 260 * <p> 261 * In practice, the Java runtime lays out arrays in memory so that each n-byte element occurs at an n-byte 262 * aligned physical address (except for {@code long[]} and {@code double[]}, where alignment is platform-dependent, as explained 263 * below). The runtime preserves this invariant even if the array is relocated during garbage collection. 264 * Access operations rely on this invariant to determine if the specified offset in a heap segment refers to an aligned 265 * address in physical memory. For example: 266 * <ul> 267 * <li>The starting physical address of a {@code short[]} array will be 2-byte aligned (e.g. 1006) so that successive 268 * short elements occur at 2-byte aligned addresses (e.g. 1006, 1008, 1010, 1012, etc). A heap segment backed by a 269 * {@code short[]} array can be accessed at offsets 0, 2, 4, 6, etc under a 2-byte alignment constraint. The segment cannot 270 * be accessed at <em>any</em> offset under a 4-byte alignment constraint, because there is no guarantee that the target 271 * address would be 4-byte aligned, e.g., offset 0 would correspond to physical address 1006 while offset 1 would correspond 272 * to physical address 1007. Similarly, the segment cannot be accessed at any offset under an 8-byte alignment constraint, 273 * because because there is no guarantee that the target address would be 8-byte aligned, e.g., offset 2 would correspond 274 * to physical address 1008 but offset 4 would correspond to physical address 1010.</li> 275 * <li>The starting physical address of a {@code long[]} array will be 8-byte aligned (e.g. 1000) on 64-bit platforms, 276 * so that successive long elements occur at 8-byte aligned addresses (e.g., 1000, 1008, 1016, 1024, etc.) On 64-bit platforms, 277 * a heap segment backed by a {@code long[]} array can be accessed at offsets 0, 8, 16, 24, etc under an 8-byte alignment 278 * constraint. In addition, the segment can be accessed at offsets 0, 4, 8, 12, etc under a 4-byte alignment constraint, 279 * because the target addresses (1000, 1004, 1008, 1012) are 4-byte aligned. And, the segment can be accessed at offsets 280 * 0, 2, 4, 6, etc under a 2-byte alignment constraint, because the target addresses (e.g. 1000, 1002, 1004, 1006) are 2-byte aligned.</li> 281 * <li>The starting physical address of a {@code long[]} array will be 4-byte aligned (e.g. 1004) on 32-bit platforms, 282 * so that successive long elements occur at 4-byte aligned addresses (e.g., 1004, 1008, 1012, 1016, etc.) On 32-bit 283 * platforms, a heap segment backed by a {@code long[]} array can be accessed at offsets 0, 4, 8, 12, etc under a 4-byte 284 * alignment constraint, because the target addresses (1004, 1008, 1012, 1016) are 4-byte aligned. And, the segment 285 * can be accessed at offsets 0, 2, 4, 6, etc under a 2-byte alignment constraint, because the target addresses 286 * (e.g. 1000, 1002, 1004, 1006) are 2-byte aligned.</li> 287 * </ul> 288 * <p> 289 * In other words, heap segments feature a (platform-dependent) <em>maximum</em> alignment which is derived from the 290 * size of the elements of the Java array backing the segment, as shown in the following table: 291 * 292 * <blockquote><table class="plain"> 293 * <caption style="display:none">Maximum alignment of heap segments</caption> 294 * <thead> 295 * <tr> 296 * <th scope="col">Array type (of backing region)</th> 297 * <th scope="col">Maximum supported alignment (in bytes)</th> 298 * </tr> 299 * </thead> 300 * <tbody> 301 * <tr><th scope="row" style="font-weight:normal">{@code boolean[]}</th> 302 * <td style="text-align:center;">{@code ValueLayout.JAVA_BOOLEAN.byteAlignment()}</td></tr> 303 * <tr><th scope="row" style="font-weight:normal">{@code byte[]}</th> 304 * <td style="text-align:center;">{@code ValueLayout.JAVA_BYTE.byteAlignment()}</td></tr> 305 * <tr><th scope="row" style="font-weight:normal">{@code char[]}</th> 306 * <td style="text-align:center;">{@code ValueLayout.JAVA_CHAR.byteAlignment()}</td></tr> 307 * <tr><th scope="row" style="font-weight:normal">{@code short[]}</th> 308 * <td style="text-align:center;">{@code ValueLayout.JAVA_SHORT.byteAlignment()}</td></tr> 309 * <tr><th scope="row" style="font-weight:normal">{@code int[]}</th> 310 * <td style="text-align:center;">{@code ValueLayout.JAVA_INT.byteAlignment()}</td></tr> 311 * <tr><th scope="row" style="font-weight:normal">{@code float[]}</th> 312 * <td style="text-align:center;">{@code ValueLayout.JAVA_FLOAT.byteAlignment()}</td></tr> 313 * <tr><th scope="row" style="font-weight:normal">{@code long[]}</th> 314 * <td style="text-align:center;">{@code ValueLayout.JAVA_LONG.byteAlignment()}</td></tr> 315 * <tr><th scope="row" style="font-weight:normal">{@code double[]}</th> 316 * <td style="text-align:center;">{@code ValueLayout.JAVA_DOUBLE.byteAlignment()}</td></tr> 317 * </tbody> 318 * </table></blockquote> 319 * 320 * Heap segments can only be accessed using a layout whose alignment is smaller or equal to the 321 * maximum alignment associated with the heap segment. Attempting to access a heap segment using a layout 322 * whose alignment is greater than the maximum alignment associated with the heap segment will fail, 323 * as demonstrated in the following example: 324 * 325 * {@snippet lang=java : 326 * MemorySegment byteSegment = MemorySegment.ofArray(new byte[10]); 327 * byteSegment.get(ValueLayout.JAVA_INT, 0); // fails: ValueLayout.JAVA_INT.byteAlignment() > ValueLayout.JAVA_BYTE.byteAlignment() 328 * } 329 * 330 * In such circumstances, clients have two options. They can use a heap segment backed by a different array 331 * type (e.g. {@code long[]}), capable of supporting greater maximum alignment. More specifically, the maximum alignment 332 * associated with {@code long[]} is set to {@code ValueLayout.JAVA_LONG.byteAlignment()} which is a platform-dependent 333 * value (set to {@code ValueLayout.ADDRESS.byteSize()}). That is, {@code long[]}) is guaranteed to provide at least 334 * 8-byte alignment in 64-bit platforms, but only 4-byte alignment in 32-bit platforms: 335 * 336 * {@snippet lang=java : 337 * MemorySegment longSegment = MemorySegment.ofArray(new long[10]); 338 * longSegment.get(ValueLayout.JAVA_INT, 0); // ok: ValueLayout.JAVA_INT.byteAlignment() <= ValueLayout.JAVA_LONG.byteAlignment() 339 * } 340 * 341 * Alternatively, they can invoke the access operation with an <em>unaligned layout</em>. 342 * All unaligned layout constants (e.g. {@link ValueLayout#JAVA_INT_UNALIGNED}) have their alignment constraint set to 1: 343 * {@snippet lang=java : 344 * MemorySegment byteSegment = MemorySegment.ofArray(new byte[10]); 345 * byteSegment.get(ValueLayout.JAVA_INT_UNALIGNED, 0); // ok: ValueLayout.JAVA_INT_UNALIGNED.byteAlignment() == ValueLayout.JAVA_BYTE.byteAlignment() 346 * } 347 * 348 * <h2 id="wrapping-addresses">Zero-length memory segments</h2> 349 * 350 * When interacting with <a href="package-summary.html#ffa">foreign functions</a>, it is common for those functions 351 * to allocate a region of memory and return a pointer to that region. Modeling the region of memory with a memory segment 352 * is challenging because the Java runtime has no insight into the size of the region. Only the address of the start of 353 * the region, stored in the pointer, is available. For example, a C function with return type {@code char*} might return 354 * a pointer to a region containing a single {@code char} value, or to a region containing an array of {@code char} values, 355 * where the size of the array might be provided in a separate parameter. The size of the array is not readily apparent 356 * to the code calling the foreign function and hoping to use its result. In addition to having no insight 357 * into the size of the region of memory backing a pointer returned from a foreign function, it also has no insight 358 * into the lifetime intended for said region of memory by the foreign function that allocated it. 359 * <p> 360 * The {@code MemorySegment} API uses <em>zero-length memory segments</em> to represent: 361 * <ul> 362 * <li>pointers <a href="Linker.html#by-ref">returned from a foreign function</a>;</li> 363 * <li>pointers <a href="Linker.html#function-pointers">passed by a foreign function to an upcall stub</a>; and</li> 364 * <li>pointers read from a memory segment (more on that below).</li> 365 * </ul> 366 * The address of the zero-length segment is the address stored in the pointer. The spatial and temporal bounds of the 367 * zero-length segment are as follows: 368 * <ul> 369 * <li>The size of the segment is zero. any attempt to access these segments will fail with {@link IndexOutOfBoundsException}. 370 * This is a crucial safety feature: as these segments are associated with a region 371 * of memory whose size is not known, any access operations involving these segments cannot be validated. 372 * In effect, a zero-length memory segment <em>wraps</em> an address, and it cannot be used without explicit intent 373 * (see below);</li> 374 * <li>The segment is associated with a fresh scope that is always alive. Thus, while zero-length 375 * memory segments cannot be accessed directly, they can be passed, opaquely, to other pointer-accepting foreign functions.</li> 376 * </ul> 377 * <p> 378 * To demonstrate how clients can work with zero-length memory segments, consider the case of a client that wants 379 * to read a pointer from some memory segment. This can be done via the 380 * {@linkplain MemorySegment#get(AddressLayout, long)} access method. This method accepts an 381 * {@linkplain AddressLayout address layout} (e.g. {@link ValueLayout#ADDRESS}), the layout of the pointer 382 * to be read. For instance on a 64-bit platform, the size of an address layout is 8 bytes. The access operation 383 * also accepts an offset, expressed in bytes, which indicates the position (relative to the start of the memory segment) 384 * at which the pointer is stored. The access operation returns a zero-length native memory segment, backed by a region 385 * of memory whose starting address is the 64-bit value read at the specified offset. 386 * <p> 387 * The returned zero-length memory segment cannot be accessed directly by the client: since the size of the segment 388 * is zero, any access operation would result in out-of-bounds access. Instead, the client must, <em>unsafely</em>, 389 * assign new spatial bounds to the zero-length memory segment. This can be done via the 390 * {@link #reinterpret(long)} method, as follows: 391 * 392 * {@snippet lang = java: 393 * MemorySegment z = segment.get(ValueLayout.ADDRESS, ...); // size = 0 394 * MemorySegment ptr = z.reinterpret(16); // size = 16 395 * int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // ok 396 *} 397 * <p> 398 * In some cases, the client might additionally want to assign new temporal bounds to a zero-length memory segment. 399 * This can be done via the {@link #reinterpret(long, Arena, Consumer)} method, which returns a 400 * new native segment with the desired size and the same temporal bounds as those of the provided arena: 401 * 402 * {@snippet lang = java: 403 * MemorySegment ptr = null; 404 * try (Arena arena = Arena.ofConfined()) { 405 * MemorySegment z = segment.get(ValueLayout.ADDRESS, ...); // size = 0, scope = always alive 406 * ptr = z.reinterpret(16, arena, null); // size = 4, scope = arena.scope() 407 * int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // ok 408 * } 409 * int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // throws IllegalStateException 410 *} 411 * 412 * Alternatively, if the size of the region of memory backing the zero-length memory segment is known statically, 413 * the client can overlay a {@linkplain AddressLayout#withTargetLayout(MemoryLayout) target layout} on the address 414 * layout used when reading a pointer. The target layout is then used to dynamically 415 * <em>expand</em> the size of the native memory segment returned by the access operation, so that the size 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 */ 459 Optional<Object> heapBase(); 460 461 /** 462 * Returns a spliterator for this memory segment. The returned spliterator reports {@link Spliterator#SIZED}, 463 * {@link Spliterator#SUBSIZED}, {@link Spliterator#IMMUTABLE}, {@link Spliterator#NONNULL} and {@link Spliterator#ORDERED} 464 * characteristics. 465 * <p> 466 * The returned spliterator splits this segment according to the specified element layout; that is, 467 * if the supplied layout has size N, then calling {@link Spliterator#trySplit()} will result in a spliterator serving 468 * approximately {@code S/N} elements (depending on whether N is even or not), where {@code S} is the size of 469 * this segment. As such, splitting is possible as long as {@code S/N >= 2}. The spliterator returns segments that 470 * have the same lifetime as that of this segment. 471 * <p> 472 * The returned spliterator effectively allows to slice this segment into disjoint {@linkplain #asSlice(long, long) slices}, 473 * which can then be processed in parallel by multiple threads. 474 * 475 * @param elementLayout the layout to be used for splitting. 476 * @return the element spliterator for this segment 477 * @throws IllegalArgumentException if {@code elementLayout.byteSize() == 0}. 478 * @throws IllegalArgumentException if {@code byteSize() % elementLayout.byteSize() != 0}. 479 * @throws IllegalArgumentException if {@code elementLayout.byteSize() % elementLayout.byteAlignment() != 0}. 480 * @throws IllegalArgumentException if this segment is <a href="MemorySegment.html#segment-alignment">incompatible 481 * with the alignment constraint</a> in the provided layout. 482 */ 483 Spliterator<MemorySegment> spliterator(MemoryLayout elementLayout); 484 485 /** 486 * Returns a sequential {@code Stream} over disjoint slices (whose size matches that of the specified layout) 487 * in this segment. Calling this method is equivalent to the following code: 488 * {@snippet lang=java : 489 * StreamSupport.stream(segment.spliterator(elementLayout), false); 490 * } 491 * 492 * @param elementLayout the layout to be used for splitting. 493 * @return a sequential {@code Stream} over disjoint slices in this segment. 494 * @throws IllegalArgumentException if {@code elementLayout.byteSize() == 0}. 495 * @throws IllegalArgumentException if {@code byteSize() % elementLayout.byteSize() != 0}. 496 * @throws IllegalArgumentException if {@code elementLayout.byteSize() % elementLayout.byteAlignment() != 0}. 497 * @throws IllegalArgumentException if this segment is <a href="MemorySegment.html#segment-alignment">incompatible 498 * with the alignment constraint</a> in the provided layout. 499 */ 500 Stream<MemorySegment> elements(MemoryLayout elementLayout); 501 502 /** 503 * {@return the scope associated with this memory segment} 504 */ 505 Scope scope(); 506 507 /** 508 * {@return {@code true} if this segment can be accessed from the provided thread} 509 * @param thread the thread to be tested. 510 */ 511 boolean isAccessibleBy(Thread thread); 512 513 /** 514 * {@return the size (in bytes) of this memory segment} 515 */ 516 long byteSize(); 517 518 /** 519 * Returns a slice of this memory segment, at the given offset. The returned segment's address is the address 520 * of this segment plus the given offset; its size is specified by the given argument. 521 * <p> 522 * Equivalent to the following code: 523 * {@snippet lang=java : 524 * asSlice(offset, newSize, 1); 525 * } 526 * 527 * @see #asSlice(long, long, long) 528 * 529 * @param offset The new segment base offset (relative to the address of this segment), specified in bytes. 530 * @param newSize The new segment size, specified in bytes. 531 * @return a slice of this memory segment. 532 * @throws IndexOutOfBoundsException if {@code offset < 0}, {@code offset > byteSize()}, {@code newSize < 0}, 533 * or {@code newSize > byteSize() - offset} 534 */ 535 MemorySegment asSlice(long offset, long newSize); 536 537 /** 538 * Returns a slice of this memory segment, at the given offset, with the provided alignment constraint. 539 * The returned segment's address is the address of this segment plus the given offset; its size is specified by the given argument. 540 * 541 * @param offset The new segment base offset (relative to the address of this segment), specified in bytes. 542 * @param newSize The new segment size, specified in bytes. 543 * @param byteAlignment The alignment constraint (in bytes) of the returned slice. 544 * @return a slice of this memory segment. 545 * @throws IndexOutOfBoundsException if {@code offset < 0}, {@code offset > byteSize()}, {@code newSize < 0}, 546 * or {@code newSize > byteSize() - offset} 547 * @throws IllegalArgumentException if this segment cannot be accessed at {@code offset} under 548 * the provided alignment constraint. 549 * @throws IllegalArgumentException if {@code byteAlignment <= 0}, or if {@code byteAlignment} is not a power of 2. 550 */ 551 MemorySegment asSlice(long offset, long newSize, long byteAlignment); 552 553 /** 554 * Returns a slice of this memory segment with the given layout, at the given offset. The returned segment's address is the address 555 * of this segment plus the given offset; its size is the same as the size of the provided layout. 556 * <p> 557 * Equivalent to the following code: 558 * {@snippet lang=java : 559 * asSlice(offset, layout.byteSize(), layout.byteAlignment()); 560 * } 561 * 562 * @see #asSlice(long, long, long) 563 * 564 * @param offset The new segment base offset (relative to the address of this segment), specified in bytes. 565 * @param layout The layout of the segment slice. 566 * @throws IndexOutOfBoundsException if {@code offset < 0}, {@code offset > byteSize()}, 567 * or {@code layout.byteSize() > byteSize() - offset} 568 * @throws IllegalArgumentException if this segment cannot be accessed at {@code offset} under 569 * the alignment constraint specified by {@code layout}. 570 * @return a slice of this memory segment. 571 */ 572 default MemorySegment asSlice(long offset, MemoryLayout layout) { 573 Objects.requireNonNull(layout); 574 return asSlice(offset, layout.byteSize(), layout.byteAlignment()); 575 } 576 577 /** 578 * Returns a slice of this memory segment, at the given offset. The returned segment's address is the address 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 693 /** 694 * {@return {@code true}, if this segment is read-only} 695 * @see #asReadOnly() 696 */ 697 boolean isReadOnly(); 698 699 /** 700 * Returns a read-only view of this segment. The resulting segment will be identical to this one, but 701 * attempts to overwrite the contents of the returned segment will cause runtime exceptions. 702 * @return a read-only view of this segment 703 * @see #isReadOnly() 704 */ 705 MemorySegment asReadOnly(); 706 707 /** 708 * Returns {@code true} if this segment is a native segment. A native segment is 709 * created e.g. using the {@link Arena#allocate(long, long)} (and related) factory, or by 710 * {@linkplain #ofBuffer(Buffer) wrapping} a {@linkplain ByteBuffer#allocateDirect(int) direct buffer}. 711 * @return {@code true} if this segment is native segment. 712 */ 713 boolean isNative(); 714 715 /** 716 * Returns {@code true} if this segment is a mapped segment. A mapped memory segment is created e.g. using the 717 * {@link FileChannel#map(FileChannel.MapMode, long, long, Arena)} factory, or by 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 791 * offset {@code 0} through {@code src.byteSize() - 1} in the source segment are copied into this segment 792 * at offset {@code 0} through {@code src.byteSize() - 1}. 793 * <p> 794 * Calling this method is equivalent to the following code: 795 * {@snippet lang=java : 796 * MemorySegment.copy(src, 0, this, 0, src.byteSize()); 797 * } 798 * @param src the source segment. 799 * @throws IndexOutOfBoundsException if {@code src.byteSize() > this.byteSize()}. 800 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 801 * {@linkplain Scope#isAlive() alive}. 802 * @throws WrongThreadException if this method is called from a thread {@code T}, 803 * such that {@code isAccessibleBy(T) == false}. 804 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code src} is not 805 * {@linkplain Scope#isAlive() alive}. 806 * @throws WrongThreadException if this method is called from a thread {@code T}, 807 * such that {@code src.isAccessibleBy(T) == false}. 808 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 809 * @return this segment. 810 */ 811 default MemorySegment copyFrom(MemorySegment src) { 812 MemorySegment.copy(src, 0, this, 0, src.byteSize()); 813 return this; 814 } 815 816 /** 817 * Finds and returns the offset, in bytes, of the first mismatch between 818 * this segment and the given other segment. The offset is relative to the 819 * {@linkplain #address() address} of each segment and will be in the 820 * range of 0 (inclusive) up to the {@linkplain #byteSize() size} (in bytes) of 821 * the smaller memory segment (exclusive). 822 * <p> 823 * If the two segments share a common prefix then the returned offset is 824 * the length of the common prefix, and it follows that there is a mismatch 825 * between the two segments at that offset within the respective segments. 826 * If one segment is a proper prefix of the other, then the returned offset is 827 * the smallest of the segment sizes, and it follows that the offset is only 828 * valid for the larger segment. Otherwise, there is no mismatch and {@code 829 * -1} is returned. 830 * 831 * @param other the segment to be tested for a mismatch with this segment. 832 * @return the relative offset, in bytes, of the first mismatch between this 833 * and the given other segment, otherwise -1 if no mismatch. 834 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 835 * {@linkplain Scope#isAlive() alive}. 836 * @throws WrongThreadException if this method is called from a thread {@code T}, 837 * such that {@code isAccessibleBy(T) == false}. 838 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code other} is not 839 * {@linkplain Scope#isAlive() alive}. 840 * @throws WrongThreadException if this method is called from a thread {@code T}, 841 * such that {@code other.isAccessibleBy(T) == false}. 842 */ 843 default long mismatch(MemorySegment other) { 844 Objects.requireNonNull(other); 845 return MemorySegment.mismatch(this, 0, byteSize(), other, 0, other.byteSize()); 846 } 847 848 /** 849 * Determines whether the contents of this mapped segment is resident in physical 850 * memory. 851 * 852 * <p> A return value of {@code true} implies that it is highly likely 853 * that all the data in this segment is resident in physical memory and 854 * may therefore be accessed without incurring any virtual-memory page 855 * faults or I/O operations. A return value of {@code false} does not 856 * necessarily imply that this segment's content is not resident in physical 857 * memory. 858 * 859 * <p> The returned value is a hint, rather than a guarantee, because the 860 * underlying operating system may have paged out some of this segment's data 861 * by the time that an invocation of this method returns. </p> 862 * 863 * @return {@code true} if it is likely that the contents of this segment 864 * is resident in physical memory 865 * 866 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 867 * {@linkplain Scope#isAlive() alive}. 868 * @throws WrongThreadException if this method is called from a thread {@code T}, 869 * such that {@code isAccessibleBy(T) == false}. 870 * @throws UnsupportedOperationException if this segment is not a mapped memory segment, e.g. if 871 * {@code isMapped() == false}. 872 */ 873 boolean isLoaded(); 874 875 /** 876 * Loads the contents of this mapped segment into physical memory. 877 * 878 * <p> This method makes a best effort to ensure that, when it returns, 879 * this contents of this segment is resident in physical memory. Invoking this 880 * method may cause some number of page faults and I/O operations to 881 * occur. </p> 882 * 883 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 884 * {@linkplain Scope#isAlive() alive}. 885 * @throws WrongThreadException if this method is called from a thread {@code T}, 886 * such that {@code isAccessibleBy(T) == false}. 887 * @throws UnsupportedOperationException if this segment is not a mapped memory segment, e.g. if 888 * {@code isMapped() == false}. 889 */ 890 void load(); 891 892 /** 893 * Unloads the contents of this mapped segment from physical memory. 894 * 895 * <p> This method makes a best effort to ensure that the contents of this segment are 896 * are no longer resident in physical memory. Accessing this segment's contents 897 * after invoking this method may cause some number of page faults and I/O operations to 898 * occur (as this segment's contents might need to be paged back in). </p> 899 * 900 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 901 * {@linkplain Scope#isAlive() alive}. 902 * @throws WrongThreadException if this method is called from a thread {@code T}, 903 * such that {@code isAccessibleBy(T) == false}. 904 * @throws UnsupportedOperationException if this segment is not a mapped memory segment, e.g. if 905 * {@code isMapped() == false}. 906 */ 907 void unload(); 908 909 /** 910 * Forces any changes made to the contents of this mapped segment to be written to the 911 * storage device described by the mapped segment's file descriptor. 912 * 913 * <p> If the file descriptor associated with this mapped segment resides on a local storage 914 * device then when this method returns it is guaranteed that all changes 915 * made to this segment since it was created, or since this method was last 916 * invoked, will have been written to that device. 917 * 918 * <p> If the file descriptor associated with this mapped segment does not reside on a local device then 919 * no such guarantee is made. 920 * 921 * <p> If this segment was not mapped in read/write mode ({@link 922 * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then 923 * invoking this method may have no effect. In particular, the 924 * method has no effect for segments mapped in read-only or private 925 * mapping modes. This method may or may not have an effect for 926 * implementation-specific mapping modes. 927 * </p> 928 * 929 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 930 * {@linkplain Scope#isAlive() alive}. 931 * @throws WrongThreadException if this method is called from a thread {@code T}, 932 * such that {@code isAccessibleBy(T) == false}. 933 * @throws UnsupportedOperationException if this segment is not a mapped memory segment, e.g. if 934 * {@code isMapped() == false}. 935 * @throws UncheckedIOException if there is an I/O error writing the contents of this segment to the associated storage device 936 */ 937 void force(); 938 939 /** 940 * Wraps this segment in a {@link ByteBuffer}. Some properties of the returned buffer are linked to 941 * the properties of this segment. More specifically, the resulting buffer has the following characteristics: 942 * <ul> 943 * <li>It is {@linkplain ByteBuffer#isReadOnly() read-only}, if this segment is a 944 * {@linkplain #isReadOnly() read-only segment};</li> 945 * <li>Its {@linkplain ByteBuffer#position() position} is set to zero; 946 * <li>Its {@linkplain ByteBuffer#capacity() capacity} and {@linkplain ByteBuffer#limit() limit} 947 * are both set to this segment' {@linkplain MemorySegment#byteSize() size}. For this reason, a byte buffer 948 * cannot be returned if this segment's size is greater than {@link Integer#MAX_VALUE};</li> 949 * <li>It is a {@linkplain ByteBuffer#isDirect() direct buffer}, if this is a native segment.</li> 950 * </ul> 951 * <p> 952 * The life-cycle of the returned buffer is tied to that of this segment. That is, accessing the returned buffer 953 * after the scope associated with this segment is no longer {@linkplain Scope#isAlive() alive}, will 954 * throw an {@link IllegalStateException}. Similarly, accessing the returned buffer from a thread {@code T} 955 * such that {@code isAccessible(T) == false} will throw a {@link WrongThreadException}. 956 * <p> 957 * If this segment is {@linkplain #isAccessibleBy(Thread) accessible} from a single thread, calling read/write I/O 958 * operations on the resulting buffer might result in unspecified exceptions being thrown. Examples of such problematic operations are 959 * {@link java.nio.channels.AsynchronousSocketChannel#read(ByteBuffer)} and 960 * {@link java.nio.channels.AsynchronousSocketChannel#write(ByteBuffer)}. 961 * <p> 962 * Finally, the resulting buffer's byte order is {@link java.nio.ByteOrder#BIG_ENDIAN}; this can be changed using 963 * {@link ByteBuffer#order(java.nio.ByteOrder)}. 964 * 965 * @return a {@link ByteBuffer} view of this memory segment. 966 * @throws UnsupportedOperationException if this segment cannot be mapped onto a {@link ByteBuffer} instance, 967 * e.g. if it is a heap segment backed by an array other than {@code byte[]}), or if its size is greater 968 * than {@link Integer#MAX_VALUE}. 969 */ 970 ByteBuffer asByteBuffer(); 971 972 /** 973 * Copy the contents of this memory segment into a new byte array. 974 * @param elementLayout the source element layout. If the byte order associated with the layout is 975 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 976 * @return a new byte array whose contents are copied from this memory segment. 977 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 978 * {@linkplain Scope#isAlive() alive}. 979 * @throws WrongThreadException if this method is called from a thread {@code T}, 980 * such that {@code isAccessibleBy(T) == false}. 981 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code byte[]} instance, 982 * e.g. its size is greater than {@link Integer#MAX_VALUE}. 983 */ 984 byte[] toArray(ValueLayout.OfByte elementLayout); 985 986 /** 987 * Copy the contents of this memory segment into a new short array. 988 * @param elementLayout the source element layout. If the byte order associated with the layout is 989 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 990 * @return a new short array whose contents are copied from this memory segment. 991 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 992 * {@linkplain Scope#isAlive() alive}. 993 * @throws WrongThreadException if this method is called from a thread {@code T}, 994 * such that {@code isAccessibleBy(T) == false}. 995 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code short[]} instance, 996 * e.g. because {@code byteSize() % 2 != 0}, or {@code byteSize() / 2 > Integer.MAX_VALUE} 997 */ 998 short[] toArray(ValueLayout.OfShort elementLayout); 999 1000 /** 1001 * Copy the contents of this memory segment into a new char array. 1002 * @param elementLayout the source element layout. If the byte order associated with the layout is 1003 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 1004 * @return a new char array whose contents are copied from this memory segment. 1005 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1006 * {@linkplain Scope#isAlive() alive}. 1007 * @throws WrongThreadException if this method is called from a thread {@code T}, 1008 * such that {@code isAccessibleBy(T) == false}. 1009 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code char[]} instance, 1010 * e.g. because {@code byteSize() % 2 != 0}, or {@code byteSize() / 2 > Integer.MAX_VALUE}. 1011 */ 1012 char[] toArray(ValueLayout.OfChar elementLayout); 1013 1014 /** 1015 * Copy the contents of this memory segment into a new int array. 1016 * @param elementLayout the source element layout. If the byte order associated with the layout is 1017 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 1018 * @return a new int array whose contents are copied from this memory segment. 1019 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1020 * {@linkplain Scope#isAlive() alive}. 1021 * @throws WrongThreadException if this method is called from a thread {@code T}, 1022 * such that {@code isAccessibleBy(T) == false}. 1023 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code int[]} instance, 1024 * e.g. because {@code byteSize() % 4 != 0}, or {@code byteSize() / 4 > Integer.MAX_VALUE}. 1025 */ 1026 int[] toArray(ValueLayout.OfInt elementLayout); 1027 1028 /** 1029 * Copy the contents of this memory segment into a new float array. 1030 * @param elementLayout the source element layout. If the byte order associated with the layout is 1031 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 1032 * @return a new float array whose contents are copied from this memory segment. 1033 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1034 * {@linkplain Scope#isAlive() alive}. 1035 * @throws WrongThreadException if this method is called from a thread {@code T}, 1036 * such that {@code isAccessibleBy(T) == false}. 1037 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code float[]} instance, 1038 * e.g. because {@code byteSize() % 4 != 0}, or {@code byteSize() / 4 > Integer.MAX_VALUE}. 1039 */ 1040 float[] toArray(ValueLayout.OfFloat elementLayout); 1041 1042 /** 1043 * Copy the contents of this memory segment into a new long array. 1044 * @param elementLayout the source element layout. If the byte order associated with the layout is 1045 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 1046 * @return a new long array whose contents are copied from this memory segment. 1047 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1048 * {@linkplain Scope#isAlive() alive}. 1049 * @throws WrongThreadException if this method is called from a thread {@code T}, 1050 * such that {@code isAccessibleBy(T) == false}. 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. 1137 * For example, buffers directly or indirectly obtained via 1138 * ({@link CharBuffer#wrap(CharSequence)} or {@link CharBuffer#wrap(char[], int, int)} 1139 * are not backed by an array. 1140 */ 1141 static MemorySegment ofBuffer(Buffer buffer) { 1142 return AbstractMemorySegmentImpl.ofBuffer(buffer); 1143 } 1144 1145 /** 1146 * Creates a heap segment backed by the on-heap region of memory that holds the given byte array. 1147 * The scope of the returned segment is a fresh scope that is always alive, and keeps the given array reachable. 1148 * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. 1149 * 1150 * @param byteArray the primitive array backing the heap memory segment. 1151 * @return a heap memory segment backed by a byte array. 1152 */ 1153 static MemorySegment ofArray(byte[] byteArray) { 1154 return HeapMemorySegmentImpl.OfByte.fromArray(byteArray); 1155 } 1156 1157 /** 1158 * Creates a heap segment backed by the on-heap region of memory that holds the given char array. 1159 * The scope of the returned segment is a fresh scope that is always alive, and keeps the given array reachable. 1160 * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. 1161 * 1162 * @param charArray the primitive array backing the heap segment. 1163 * @return a heap memory segment backed by a char array. 1164 */ 1165 static MemorySegment ofArray(char[] charArray) { 1166 return HeapMemorySegmentImpl.OfChar.fromArray(charArray); 1167 } 1168 1169 /** 1170 * Creates a heap segment backed by the on-heap region of memory that holds the given short array. 1171 * The scope of the returned segment is a fresh scope that is always alive, and keeps the given array reachable. 1172 * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. 1173 * 1174 * @param shortArray the primitive array backing the heap segment. 1175 * @return a heap memory segment backed by a short array. 1176 */ 1177 static MemorySegment ofArray(short[] shortArray) { 1178 return HeapMemorySegmentImpl.OfShort.fromArray(shortArray); 1179 } 1180 1181 /** 1182 * Creates a heap segment backed by the on-heap region of memory that holds the given int array. 1183 * The scope of the returned segment is a fresh scope that is always alive, and keeps the given array reachable. 1184 * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. 1185 * 1186 * @param intArray the primitive array backing the heap segment. 1187 * @return a heap memory segment backed by an int array. 1188 */ 1189 static MemorySegment ofArray(int[] intArray) { 1190 return HeapMemorySegmentImpl.OfInt.fromArray(intArray); 1191 } 1192 1193 /** 1194 * Creates a heap segment backed by the on-heap region of memory that holds the given float array. 1195 * The scope of the returned segment is a fresh scope that is always alive, and keeps the given array reachable. 1196 * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. 1197 * 1198 * @param floatArray the primitive array backing the heap segment. 1199 * @return a heap memory segment backed by a float array. 1200 */ 1201 static MemorySegment ofArray(float[] floatArray) { 1202 return HeapMemorySegmentImpl.OfFloat.fromArray(floatArray); 1203 } 1204 1205 /** 1206 * Creates a heap segment backed by the on-heap region of memory that holds the given long array. 1207 * The scope of the returned segment is a fresh scope that is always alive, and keeps the given array reachable. 1208 * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. 1209 * 1210 * @param longArray the primitive array backing the heap segment. 1211 * @return a heap memory segment backed by a long array. 1212 */ 1213 static MemorySegment ofArray(long[] longArray) { 1214 return HeapMemorySegmentImpl.OfLong.fromArray(longArray); 1215 } 1216 1217 /** 1218 * Creates a heap segment backed by the on-heap region of memory that holds the given double array. 1219 * The scope of the returned segment is a fresh scope that is always alive, and keeps the given array reachable. 1220 * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. 1221 * 1222 * @param doubleArray the primitive array backing the heap segment. 1223 * @return a heap memory segment backed by a double array. 1224 */ 1225 static MemorySegment ofArray(double[] doubleArray) { 1226 return HeapMemorySegmentImpl.OfDouble.fromArray(doubleArray); 1227 } 1228 1229 /** 1230 * A zero-length native segment modelling the {@code NULL} address. 1231 */ 1232 MemorySegment NULL = new NativeMemorySegmentImpl(); 1233 1234 /** 1235 * Creates a zero-length native segment from the given {@linkplain #address() address value}. 1236 * The returned segment is associated with a scope that is always alive, and is accessible from any thread. 1237 * <p> 1238 * On 32-bit platforms, the given address value will be normalized such that the 1239 * highest-order ("leftmost") 32 bits of the {@link MemorySegment#address() address} 1240 * of the returned memory segment are set to zero. 1241 * 1242 * @param address the address of the returned native segment. 1243 * @return a zero-length native segment with the given address. 1244 */ 1245 static MemorySegment ofAddress(long address) { 1246 return NativeMemorySegmentImpl.makeNativeSegmentUnchecked(address, 0); 1247 } 1248 1249 /** 1250 * Performs a bulk copy from source segment to destination segment. More specifically, the bytes at offset 1251 * {@code srcOffset} through {@code srcOffset + bytes - 1} in the source segment are copied into the destination 1252 * segment at offset {@code dstOffset} through {@code dstOffset + bytes - 1}. 1253 * <p> 1254 * If the source segment overlaps with the destination segment, then the copying is performed as if the bytes at 1255 * offset {@code srcOffset} through {@code srcOffset + bytes - 1} in the source segment were first copied into a 1256 * temporary segment with size {@code bytes}, and then the contents of the temporary segment were copied into 1257 * the destination segment at offset {@code dstOffset} through {@code dstOffset + bytes - 1}. 1258 * <p> 1259 * The result of a bulk copy is unspecified if, in the uncommon case, the source segment and the destination segment 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. 2169 * @return {@code true} if the specified object is equal to this memory segment. 2170 * @see #mismatch(MemorySegment) 2171 */ 2172 @Override 2173 boolean equals(Object that); 2174 2175 /** 2176 * {@return the hash code value for 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, 2257 dstSegment, dstLayout, dstOffset, 2258 elementCount); 2259 } 2260 2261 /** 2262 * Finds and returns the relative offset, in bytes, of the first mismatch between the source and the destination 2263 * segments. More specifically, the bytes at offset {@code srcFromOffset} through {@code srcToOffset - 1} in the 2264 * source segment are compared against the bytes at offset {@code dstFromOffset} through {@code dstToOffset - 1} 2265 * in the destination segment. 2266 * <p> 2267 * If the two segments, over the specified ranges, share a common prefix then the returned offset is the length 2268 * of the common prefix, and it follows that there is a mismatch between the two segments at that relative offset 2269 * within the respective segments. If one segment is a proper prefix of the other, over the specified ranges, 2270 * then the returned offset is the smallest range, and it follows that the relative offset is only 2271 * valid for the segment with the larger range. Otherwise, there is no mismatch and {@code -1} is returned. 2272 * 2273 * @param srcSegment the source segment. 2274 * @param srcFromOffset the offset (inclusive) of the first byte in the source segment to be tested. 2275 * @param srcToOffset the offset (exclusive) of the last byte in the source segment to be tested. 2276 * @param dstSegment the destination segment. 2277 * @param dstFromOffset the offset (inclusive) of the first byte in the destination segment to be tested. 2278 * @param dstToOffset the offset (exclusive) of the last byte in the destination segment to be tested. 2279 * @return the relative offset, in bytes, of the first mismatch between the source and destination segments, 2280 * otherwise -1 if no mismatch. 2281 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not 2282 * {@linkplain Scope#isAlive() alive}. 2283 * @throws WrongThreadException if this method is called from a thread {@code T}, 2284 * such that {@code srcSegment.isAccessibleBy(T) == false}. 2285 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not 2286 * {@linkplain Scope#isAlive() alive}. 2287 * @throws WrongThreadException if this method is called from a thread {@code T}, 2288 * such that {@code dstSegment.isAccessibleBy(T) == false}. 2289 * @throws IndexOutOfBoundsException if {@code srcFromOffset < 0}, {@code srcToOffset < srcFromOffset} or 2290 * {@code srcToOffset > srcSegment.byteSize()} 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. 2332 * @see #equals(Object) 2333 */ 2334 @Override 2335 int hashCode(); 2336 } 2337 }