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.nio.Buffer; 30 import java.nio.ByteBuffer; 31 import java.nio.ByteOrder; 32 import java.nio.CharBuffer; 33 import java.nio.channels.FileChannel; 34 import java.nio.channels.FileChannel.MapMode; 35 import java.nio.charset.Charset; 36 import java.nio.charset.StandardCharsets; 37 import java.util.Arrays; 38 import java.util.Objects; 39 import java.util.Optional; 40 import java.util.Spliterator; 41 import java.util.function.Consumer; 42 import java.util.stream.Stream; 43 import jdk.internal.foreign.AbstractMemorySegmentImpl; 44 import jdk.internal.foreign.HeapMemorySegmentImpl; 45 import jdk.internal.foreign.MemorySessionImpl; 46 import jdk.internal.foreign.NativeMemorySegmentImpl; 47 import jdk.internal.foreign.StringSupport; 48 import jdk.internal.foreign.Utils; 49 import jdk.internal.reflect.CallerSensitive; 50 import jdk.internal.vm.annotation.ForceInline; 51 52 /** 53 * A memory segment provides access to a contiguous region of memory. 54 * <p> 55 * There are two kinds of memory segments: 56 * <ul> 57 * <li>A <em>heap segment</em> is backed by, and provides access to, a region of memory inside the Java heap (an "on-heap" region).</li> 58 * <li>A <em>native segment</em> is backed by, and provides access to, a region of memory outside the Java heap (an "off-heap" region).</li> 59 * </ul> 60 * Heap segments can be obtained by calling one of the {@link MemorySegment#ofArray(int[])} factory methods. 61 * These methods return a memory segment backed by the on-heap region that holds the specified Java array. 62 * <p> 63 * Native segments can be obtained by calling one of the {@link Arena#allocate(long, long)} 64 * factory methods, which return a memory segment backed by a newly allocated off-heap region with the given size 65 * and aligned to the given alignment constraint. Alternatively, native segments can be obtained by 66 * {@link FileChannel#map(MapMode, long, long, Arena) mapping} a file into a new off-heap region 67 * (in some systems, this operation is sometimes referred to as {@code mmap}). 68 * Segments obtained in this way are called <em>mapped</em> segments, and their contents can be {@linkplain #force() persisted} and 69 * {@linkplain #load() loaded} to and from the underlying memory-mapped file. 70 * <p> 71 * Both kinds of segments are read and written using the same methods, known as <a href="#segment-deref">access operations</a>. 72 * An access operation on a memory segment always and only provides access to the region for which the segment was obtained. 73 * 74 * <h2 id="segment-characteristics">Characteristics of memory segments</h2> 75 * 76 * Every memory segment has an {@linkplain #address() address}, expressed as a {@code long} value. 77 * The nature of a segment's address depends on the kind of the segment: 78 * <ul> 79 * <li>The address of a heap segment is not a physical address, but rather an offset within the region of memory 80 * which backs the segment. The region is inside the Java heap, so garbage collection might cause the region to be 81 * relocated in physical memory over time, but this is not exposed to clients of the {@code MemorySegment} API who 82 * see a stable <em>virtualized</em> address for a heap segment backed by the region. 83 * A heap segment obtained from one of the {@link #ofArray(int[])} factory methods has an address of zero.</li> 84 * <li>The address of a native segment (including mapped segments) denotes the physical address of the region of 85 * memory which backs the segment.</li> 86 * </ul> 87 * <p> 88 * Every memory segment has a {@linkplain #byteSize() size}. The size of a heap segment is derived from the Java array 89 * from which it is obtained. This size is predictable across Java runtimes. 90 * The size of a native segment is either passed explicitly 91 * (as in {@link Arena#allocate(long, long)}) or derived from a {@link MemoryLayout} 92 * (as in {@link Arena#allocate(MemoryLayout)}). The size of a memory segment is typically 93 * a positive number but may be <a href="#wrapping-addresses">zero</a>, but never negative. 94 * <p> 95 * The address and size of a memory segment jointly ensure that access operations on the segment cannot fall 96 * <em>outside</em> the boundaries of the region of memory which backs the segment. 97 * That is, a memory segment has <em>spatial bounds</em>. 98 * <p> 99 * Every memory segment is associated with a {@linkplain Scope scope}. This ensures that access operations 100 * on a memory segment cannot occur when the region of memory which backs the memory segment is no longer available 101 * (e.g., after the scope associated with the accessed memory segment is no longer {@linkplain Scope#isAlive() alive}). 102 * That is, a memory segment has <em>temporal bounds</em>. 103 * <p> 104 * Finally, access operations on a memory segment can be subject to additional thread-confinement checks. 105 * Heap segments can be accessed from any thread. Conversely, native segments can only be accessed compatibly with the 106 * <a href="Arena.html#thread-confinement">confinement characteristics</a> of the arena used to obtain them. 107 * 108 * <h2 id="segment-deref">Accessing memory segments</h2> 109 * 110 * A memory segment can be read or written using various access operations provided in this class (e.g. {@link #get(ValueLayout.OfInt, long)}). 111 * Each access operation takes a {@linkplain ValueLayout value layout}, which specifies the size and shape of the value, 112 * and an offset, expressed in bytes. 113 * For instance, to read an int from a segment, using {@linkplain ByteOrder#nativeOrder() default endianness}, the following code can be used: 114 * {@snippet lang=java : 115 * MemorySegment segment = ... 116 * int value = segment.get(ValueLayout.JAVA_INT, 0); 117 * } 118 * 119 * If the value to be read is stored in memory using {@linkplain ByteOrder#BIG_ENDIAN big-endian} encoding, the access operation 120 * can be expressed as follows: 121 * {@snippet lang=java : 122 * MemorySegment segment = ... 123 * int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0); 124 * } 125 * 126 * More complex access operations can be implemented using var handles. The {@link ValueLayout#varHandle()} 127 * method can be used to obtain a var handle that can be used to get/set values represented by the given value layout on a memory segment. 128 * A var handle obtained from a layout supports several additional <a href=MemoryLayout.html#access-mode-restrictions> 129 * access modes</a>. More importantly, var handles can be <em>combined</em> with method handles to express complex access 130 * operations. For instance, a var handle that can be used to access an element of an {@code int} array at a given logical 131 * index can be created as follows: 132 * 133 * {@snippet lang=java: 134 * MemorySegment segment = ... 135 * VarHandle intHandle = ValueLayout.JAVA_INT.varHandle(); // (MemorySegment, long) 136 * MethodHandle scale = ValueLayout.JAVA_INT.scaleHandle(); // <base offset> + <index> * JAVA_INT.byteSize() 137 * 138 * intHandle = MethodHandles.filterCoordinates(intHandle, 1, scale); 139 * int value = (int) intHandle.get(segment, 0L, 3L); // get int element at offset 0 + 3 * 4 = 12 140 * } 141 * 142 * To make the process of creating these var handles easier, the method 143 * {@link MemoryLayout#varHandle(MemoryLayout.PathElement...)} can be used, by providing it a so called 144 * <a href="MemoryLayout.html#layout-paths"><em>layout path</em></a>. A layout path, consisting of several <em>layout 145 * path elements</em>, selects a value layout to be accessed, which can be nested inside another memory layout. For example, 146 * we can express the access to an element of an {@code int} array using layout paths like so: 147 * 148 * {@snippet lang=java : 149 * MemorySegment segment = ... 150 * MemoryLayout segmentLayout = MemoryLayout.structLayout( 151 * ValueLayout.JAVA_INT.withName("size"), 152 * MemoryLayout.sequenceLayout(4, ValueLayout.JAVA_INT).withName("data") // array of 4 elements 153 * ); 154 * VarHandle intHandle = segmentLayout.varHandle(MemoryLayout.PathElemenet.groupElement("data"), 155 * MemoryLayout.PathElement.sequenceElement()); 156 * int value = (int) intHandle.get(segment, 0L, 3L); // get int element at offset 0 + offsetof(data) + 3 * 4 = 12 157 * } 158 * Where {@code offsetof(data)} is the offset of the {@code data} element layout of the {@code segmentLayout} layout 159 * 160 * Both the var handle returned by {@link ValueLayout#varHandle()} and 161 * {@link MemoryLayout#varHandle(MemoryLayout.PathElement...)}, as well as the method handle returned by 162 * {@link MemoryLayout#byteOffsetHandle(MemoryLayout.PathElement...)} and {@link MemoryLayout#sliceHandle(MemoryLayout.PathElement...)} 163 * feature a <em>base offset</em> parameter. This parameter represents a base offset for the offset computation. This 164 * parameter allows a client to combine these handles further with additional offset computations. This is demonstrated 165 * in the first of the two examples above, where {@code intHandle} is combined with a 166 * {@linkplain MemoryLayout#scaleHandle() scale handle} obtained from {@code ValueLayout.JAVA_INT}. 167 * 168 * <h2 id="slicing">Slicing memory segments</h2> 169 * 170 * Memory segments support {@linkplain MemorySegment#asSlice(long, long) slicing}. Slicing a memory segment 171 * returns a new memory segment that is backed by the same region of memory as the original. The address of the sliced 172 * segment is derived from the address of the original segment, by adding an offset (expressed in bytes). The size of 173 * the sliced segment is either derived implicitly (by subtracting the specified offset from the size of the original segment), 174 * or provided explicitly. In other words, a sliced segment has <em>stricter</em> spatial bounds than those of the original segment: 175 * {@snippet lang = java: 176 * Arena arena = ... 177 * MemorySegment segment = arena.allocate(100); 178 * MemorySegment slice = segment.asSlice(50, 10); 179 * slice.get(ValueLayout.JAVA_INT, 20); // Out of bounds! 180 * arena.close(); 181 * slice.get(ValueLayout.JAVA_INT, 0); // Already closed! 182 *} 183 * The above code creates a native segment that is 100 bytes long; then, it creates a slice that starts at offset 50 184 * of {@code segment}, and is 10 bytes long. That is, the address of the {@code slice} is {@code segment.address() + 50}, 185 * and its size is 10. As a result, attempting to read an int value at offset 20 of the 186 * {@code slice} segment will result in an exception. The {@linkplain Arena temporal bounds} of the original segment 187 * is inherited by its slices; that is, when the scope associated with {@code segment} is no longer {@linkplain Scope#isAlive() alive}, 188 * {@code slice} will also be become inaccessible. 189 * <p> 190 * A client might obtain a {@link Stream} from a segment, which can then be used to slice the segment (according to a given 191 * element layout) and even allow multiple threads to work in parallel on disjoint segment slices 192 * (to do this, the segment has to be {@linkplain MemorySegment#isAccessibleBy(Thread) accessible} 193 * from multiple threads). The following code can be used to sum all int values in a memory segment in parallel: 194 * 195 * {@snippet lang = java: 196 * try (Arena arena = Arena.ofShared()) { 197 * SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT); 198 * MemorySegment segment = arena.allocate(SEQUENCE_LAYOUT); 199 * int sum = segment.elements(ValueLayout.JAVA_INT).parallel() 200 * .mapToInt(s -> s.get(ValueLayout.JAVA_INT, 0)) 201 * .sum(); 202 * } 203 *} 204 * 205 * <h2 id="segment-alignment">Alignment</h2> 206 * 207 * Access operations on a memory segment are constrained not only by the spatial and temporal bounds of the segment, 208 * but also by the <em>alignment constraint</em> of the value layout specified to the operation. An access operation can 209 * access only those offsets in the segment that denote addresses in physical memory which are <em>aligned</em> according 210 * to the layout. An address in physical memory is <em>aligned</em> according to a layout if the address is an integer 211 * multiple of the layout's alignment constraint. For example, the address 1000 is aligned according to an 8-byte alignment 212 * constraint (because 1000 is an integer multiple of 8), and to a 4-byte alignment constraint, and to a 2-byte alignment 213 * constraint; in contrast, the address 1004 is aligned according to a 4-byte alignment constraint, and to a 2-byte alignment 214 * constraint, but not to an 8-byte alignment constraint. 215 * Access operations are required to respect alignment because it can impact the performance of access operations, and 216 * can also determine which access operations are available at a given physical address. For instance, 217 * {@linkplain java.lang.invoke.VarHandle#compareAndSet(Object...) atomic access operations} operations using 218 * {@link java.lang.invoke.VarHandle} are only permitted at aligned addresses. In addition, alignment 219 * applies to an access operation whether the segment being accessed is a native segment or a heap segment. 220 * <p> 221 * If the segment being accessed is a native segment, then its {@linkplain #address() address} in physical memory can be 222 * combined with the offset to obtain the <em>target address</em> in physical memory. The pseudo-function below demonstrates this: 223 * 224 * {@snippet lang = java: 225 * boolean isAligned(MemorySegment segment, long offset, MemoryLayout layout) { 226 * return ((segment.address() + offset) % layout.byteAlignment()) == 0; 227 * } 228 * } 229 * 230 * For example: 231 * <ul> 232 * <li>A native segment with address 1000 can be accessed at offsets 0, 8, 16, 24, etc under an 8-byte alignment constraint, 233 * because the target addresses (1000, 1008, 1016, 1024) are 8-byte aligned. 234 * Access at offsets 1-7 or 9-15 or 17-23 is disallowed because the target addresses would not be 8-byte aligned.</li> 235 * <li>A native segment with address 1000 can be accessed at offsets 0, 4, 8, 12, etc under a 4-byte alignment constraint, 236 * because the target addresses (1000, 1004, 1008, 1012) are 4-byte aligned. 237 * Access at offsets 1-3 or 5-7 or 9-11 is disallowed because the target addresses would not be 4-byte aligned.</li> 238 * <li>A native segment with address 1000 can be accessed at offsets 0, 2, 4, 6, etc under a 2-byte alignment constraint, 239 * because the target addresses (1000, 1002, 1004, 1006) are 2-byte aligned. 240 * Access at offsets 1 or 3 or 5 is disallowed because the target addresses would not be 2-byte aligned.</li> 241 * <li>A native segment with address 1004 can be accessed at offsets 0, 4, 8, 12, etc under a 4-byte alignment constraint, 242 * and at offsets 0, 2, 4, 6, etc under a 2-byte alignment constraint. 243 * Under an 8-byte alignment constraint, it can be accessed at offsets 4, 12, 20, 28, etc.</li> 244 * <li>A native segment with address 1006 can be accessed at offsets 0, 2, 4, 6, etc under a 2-byte alignment constraint. 245 * Under a 4-byte alignment constraint, it can be accessed at offsets 2, 6, 10, 14, etc. 246 * Under an 8-byte alignment constraint, it can be accessed at offsets 2, 10, 18, 26, etc. 247 * <li>A native segment with address 1007 can be accessed at offsets 0, 1, 2, 3, etc under a 1-byte alignment constraint. 248 * Under a 2-byte alignment constraint, it can be accessed at offsets 1, 3, 5, 7, etc. 249 * Under a 4-byte alignment constraint, it can be accessed at offsets 1, 5, 9, 13, etc. 250 * Under an 8-byte alignment constraint, it can be accessed at offsets 1, 9, 17, 25, etc.</li> 251 * </ul> 252 * <p> 253 * The alignment constraint used to access a segment is typically dictated by the shape of the data structure stored 254 * in the segment. For example, if the programmer wishes to store a sequence of 8-byte values in a native segment, then 255 * the segment should be allocated by specifying a 8-byte alignment constraint, either via {@link Arena#allocate(long, long)} 256 * or {@link Arena#allocate(MemoryLayout)}. These factories ensure that the off-heap region of memory backing 257 * the returned segment has a starting address that is 8-byte aligned. Subsequently, the programmer can access the 258 * segment at the offsets of interest -- 0, 8, 16, 24, etc -- in the knowledge that every such access is aligned. 259 * <p> 260 * If the segment being accessed is a heap segment, then determining whether access is aligned is more complex. 261 * The address of the segment in physical memory is not known, and is not even fixed (it may change when the segment 262 * is relocated during garbage collection). This means that the address cannot be combined with the specified offset to 263 * determine a target address in physical memory. Since the alignment constraint <em>always</em> refers to alignment of 264 * addresses in physical memory, it is not possible in principle to determine if any offset in a heap segment is aligned. 265 * For example, suppose the programmer chooses a 8-byte alignment constraint and tries 266 * to access offset 16 in a heap segment. If the heap segment's address 0 corresponds to physical address 1000, 267 * then the target address (1016) would be aligned, but if address 0 corresponds to physical address 1004, 268 * then the target address (1020) would not be aligned. It is undesirable to allow access to target addresses that are 269 * aligned according to the programmer's chosen alignment constraint, but might not be predictably aligned in physical memory 270 * (e.g. because of platform considerations and/or garbage collection behavior). 271 * <p> 272 * In practice, the Java runtime lays out arrays in memory so that each n-byte element occurs at an n-byte 273 * aligned physical address (except for {@code long[]} and {@code double[]}, where alignment is platform-dependent, as explained 274 * below). The runtime preserves this invariant even if the array is relocated during garbage collection. 275 * Access operations rely on this invariant to determine if the specified offset in a heap segment refers to an aligned 276 * address in physical memory. For example: 277 * <ul> 278 * <li>The starting physical address of a {@code short[]} array will be 2-byte aligned (e.g. 1006) so that successive 279 * short elements occur at 2-byte aligned addresses (e.g. 1006, 1008, 1010, 1012, etc). A heap segment backed by a 280 * {@code short[]} array can be accessed at offsets 0, 2, 4, 6, etc under a 2-byte alignment constraint. The segment cannot 281 * be accessed at <em>any</em> offset under a 4-byte alignment constraint, because there is no guarantee that the target 282 * address would be 4-byte aligned, e.g., offset 0 would correspond to physical address 1006 while offset 1 would correspond 283 * to physical address 1007. Similarly, the segment cannot be accessed at any offset under an 8-byte alignment constraint, 284 * because because there is no guarantee that the target address would be 8-byte aligned, e.g., offset 2 would correspond 285 * to physical address 1008 but offset 4 would correspond to physical address 1010.</li> 286 * <li>The starting physical address of a {@code long[]} array will be 8-byte aligned (e.g. 1000) on 64-bit platforms, 287 * so that successive long elements occur at 8-byte aligned addresses (e.g., 1000, 1008, 1016, 1024, etc.) On 64-bit platforms, 288 * a heap segment backed by a {@code long[]} array can be accessed at offsets 0, 8, 16, 24, etc under an 8-byte alignment 289 * constraint. In addition, the segment can be accessed at offsets 0, 4, 8, 12, etc under a 4-byte alignment constraint, 290 * because the target addresses (1000, 1004, 1008, 1012) are 4-byte aligned. And, the segment can be accessed at offsets 291 * 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> 292 * <li>The starting physical address of a {@code long[]} array will be 4-byte aligned (e.g. 1004) on 32-bit platforms, 293 * so that successive long elements occur at 4-byte aligned addresses (e.g., 1004, 1008, 1012, 1016, etc.) On 32-bit 294 * platforms, a heap segment backed by a {@code long[]} array can be accessed at offsets 0, 4, 8, 12, etc under a 4-byte 295 * alignment constraint, because the target addresses (1004, 1008, 1012, 1016) are 4-byte aligned. And, the segment 296 * can be accessed at offsets 0, 2, 4, 6, etc under a 2-byte alignment constraint, because the target addresses 297 * (e.g. 1000, 1002, 1004, 1006) are 2-byte aligned.</li> 298 * </ul> 299 * <p> 300 * In other words, heap segments feature a (platform-dependent) <em>maximum</em> alignment which is derived from the 301 * size of the elements of the Java array backing the segment, as shown in the following table: 302 * 303 * <blockquote><table class="plain"> 304 * <caption style="display:none">Maximum alignment of heap segments</caption> 305 * <thead> 306 * <tr> 307 * <th scope="col">Array type (of backing region)</th> 308 * <th scope="col">Maximum supported alignment (in bytes)</th> 309 * </tr> 310 * </thead> 311 * <tbody> 312 * <tr><th scope="row" style="font-weight:normal">{@code boolean[]}</th> 313 * <td style="text-align:center;">{@code ValueLayout.JAVA_BOOLEAN.byteAlignment()}</td></tr> 314 * <tr><th scope="row" style="font-weight:normal">{@code byte[]}</th> 315 * <td style="text-align:center;">{@code ValueLayout.JAVA_BYTE.byteAlignment()}</td></tr> 316 * <tr><th scope="row" style="font-weight:normal">{@code char[]}</th> 317 * <td style="text-align:center;">{@code ValueLayout.JAVA_CHAR.byteAlignment()}</td></tr> 318 * <tr><th scope="row" style="font-weight:normal">{@code short[]}</th> 319 * <td style="text-align:center;">{@code ValueLayout.JAVA_SHORT.byteAlignment()}</td></tr> 320 * <tr><th scope="row" style="font-weight:normal">{@code int[]}</th> 321 * <td style="text-align:center;">{@code ValueLayout.JAVA_INT.byteAlignment()}</td></tr> 322 * <tr><th scope="row" style="font-weight:normal">{@code float[]}</th> 323 * <td style="text-align:center;">{@code ValueLayout.JAVA_FLOAT.byteAlignment()}</td></tr> 324 * <tr><th scope="row" style="font-weight:normal">{@code long[]}</th> 325 * <td style="text-align:center;">{@code ValueLayout.JAVA_LONG.byteAlignment()}</td></tr> 326 * <tr><th scope="row" style="font-weight:normal">{@code double[]}</th> 327 * <td style="text-align:center;">{@code ValueLayout.JAVA_DOUBLE.byteAlignment()}</td></tr> 328 * </tbody> 329 * </table></blockquote> 330 * 331 * Heap segments can only be accessed using a layout whose alignment is smaller or equal to the 332 * maximum alignment associated with the heap segment. Attempting to access a heap segment using a layout 333 * whose alignment is greater than the maximum alignment associated with the heap segment will fail, 334 * as demonstrated in the following example: 335 * 336 * {@snippet lang=java : 337 * MemorySegment byteSegment = MemorySegment.ofArray(new byte[10]); 338 * byteSegment.get(ValueLayout.JAVA_INT, 0); // fails: ValueLayout.JAVA_INT.byteAlignment() > ValueLayout.JAVA_BYTE.byteAlignment() 339 * } 340 * 341 * In such circumstances, clients have two options. They can use a heap segment backed by a different array 342 * type (e.g. {@code long[]}), capable of supporting greater maximum alignment. More specifically, the maximum alignment 343 * associated with {@code long[]} is set to {@code ValueLayout.JAVA_LONG.byteAlignment()} which is a platform-dependent 344 * value (set to {@code ValueLayout.ADDRESS.byteSize()}). That is, {@code long[]}) is guaranteed to provide at least 345 * 8-byte alignment in 64-bit platforms, but only 4-byte alignment in 32-bit platforms: 346 * 347 * {@snippet lang=java : 348 * MemorySegment longSegment = MemorySegment.ofArray(new long[10]); 349 * longSegment.get(ValueLayout.JAVA_INT, 0); // ok: ValueLayout.JAVA_INT.byteAlignment() <= ValueLayout.JAVA_LONG.byteAlignment() 350 * } 351 * 352 * Alternatively, they can invoke the access operation with an <em>unaligned layout</em>. 353 * All unaligned layout constants (e.g. {@link ValueLayout#JAVA_INT_UNALIGNED}) have their alignment constraint set to 1: 354 * {@snippet lang=java : 355 * MemorySegment byteSegment = MemorySegment.ofArray(new byte[10]); 356 * byteSegment.get(ValueLayout.JAVA_INT_UNALIGNED, 0); // ok: ValueLayout.JAVA_INT_UNALIGNED.byteAlignment() == ValueLayout.JAVA_BYTE.byteAlignment() 357 * } 358 * 359 * <h2 id="wrapping-addresses">Zero-length memory segments</h2> 360 * 361 * When interacting with <a href="package-summary.html#ffa">foreign functions</a>, it is common for those functions 362 * to allocate a region of memory and return a pointer to that region. Modeling the region of memory with a memory segment 363 * is challenging because the Java runtime has no insight into the size of the region. Only the address of the start of 364 * the region, stored in the pointer, is available. For example, a C function with return type {@code char*} might return 365 * a pointer to a region containing a single {@code char} value, or to a region containing an array of {@code char} values, 366 * where the size of the array might be provided in a separate parameter. The size of the array is not readily apparent 367 * to the code calling the foreign function and hoping to use its result. In addition to having no insight 368 * into the size of the region of memory backing a pointer returned from a foreign function, it also has no insight 369 * into the lifetime intended for said region of memory by the foreign function that allocated it. 370 * <p> 371 * The {@code MemorySegment} API uses <em>zero-length memory segments</em> to represent: 372 * <ul> 373 * <li>pointers <a href="Linker.html#by-ref">returned from a foreign function</a>;</li> 374 * <li>pointers <a href="Linker.html#function-pointers">passed by a foreign function to an upcall stub</a>; and</li> 375 * <li>pointers read from a memory segment (more on that below).</li> 376 * </ul> 377 * The address of the zero-length segment is the address stored in the pointer. The spatial and temporal bounds of the 378 * zero-length segment are as follows: 379 * <ul> 380 * <li>The size of the segment is zero. any attempt to access these segments will fail with {@link IndexOutOfBoundsException}. 381 * This is a crucial safety feature: as these segments are associated with a region 382 * of memory whose size is not known, any access operations involving these segments cannot be validated. 383 * In effect, a zero-length memory segment <em>wraps</em> an address, and it cannot be used without explicit intent 384 * (see below);</li> 385 * <li>The segment is associated with a fresh scope that is always alive. Thus, while zero-length 386 * memory segments cannot be accessed directly, they can be passed, opaquely, to other pointer-accepting foreign functions.</li> 387 * </ul> 388 * <p> 389 * To demonstrate how clients can work with zero-length memory segments, consider the case of a client that wants 390 * to read a pointer from some memory segment. This can be done via the 391 * {@linkplain MemorySegment#get(AddressLayout, long)} access method. This method accepts an 392 * {@linkplain AddressLayout address layout} (e.g. {@link ValueLayout#ADDRESS}), the layout of the pointer 393 * to be read. For instance on a 64-bit platform, the size of an address layout is 8 bytes. The access operation 394 * also accepts an offset, expressed in bytes, which indicates the position (relative to the start of the memory segment) 395 * at which the pointer is stored. The access operation returns a zero-length native memory segment, backed by a region 396 * of memory whose starting address is the 64-bit value read at the specified offset. 397 * <p> 398 * The returned zero-length memory segment cannot be accessed directly by the client: since the size of the segment 399 * is zero, any access operation would result in out-of-bounds access. Instead, the client must, <em>unsafely</em>, 400 * assign new spatial bounds to the zero-length memory segment. This can be done via the 401 * {@link #reinterpret(long)} method, as follows: 402 * 403 * {@snippet lang = java: 404 * MemorySegment z = segment.get(ValueLayout.ADDRESS, ...); // size = 0 405 * MemorySegment ptr = z.reinterpret(16); // size = 16 406 * int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // ok 407 *} 408 * <p> 409 * In some cases, the client might additionally want to assign new temporal bounds to a zero-length memory segment. 410 * This can be done via the {@link #reinterpret(long, Arena, Consumer)} method, which returns a 411 * new native segment with the desired size and the same temporal bounds as those of the provided arena: 412 * 413 * {@snippet lang = java: 414 * MemorySegment ptr = null; 415 * try (Arena arena = Arena.ofConfined()) { 416 * MemorySegment z = segment.get(ValueLayout.ADDRESS, ...); // size = 0, scope = always alive 417 * ptr = z.reinterpret(16, arena, null); // size = 4, scope = arena.scope() 418 * int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // ok 419 * } 420 * int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // throws IllegalStateException 421 *} 422 * 423 * Alternatively, if the size of the region of memory backing the zero-length memory segment is known statically, 424 * the client can overlay a {@linkplain AddressLayout#withTargetLayout(MemoryLayout) target layout} on the address 425 * layout used when reading a pointer. The target layout is then used to dynamically 426 * <em>expand</em> the size of the native memory segment returned by the access operation, so that the size 427 * of the segment is the same as the size of the target layout. In other words, the returned segment is no 428 * longer a zero-length memory segment, and the pointer it represents can be dereferenced directly: 429 * 430 * {@snippet lang = java: 431 * AddressLayout intArrPtrLayout = ValueLayout.ADDRESS.withTargetLayout( 432 * MemoryLayout.sequenceLayout(4, ValueLayout.JAVA_INT)); // layout for int (*ptr)[4] 433 * MemorySegment ptr = segment.get(intArrPtrLayout, ...); // size = 16 434 * int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // ok 435 *} 436 * <p> 437 * All the methods which can be used to manipulate zero-length memory segments 438 * ({@link #reinterpret(long)}, {@link #reinterpret(Arena, Consumer)}, {@link #reinterpret(long, Arena, Consumer)} and 439 * {@link AddressLayout#withTargetLayout(MemoryLayout)}) are 440 * <a href="package-summary.html#restricted"><em>restricted</em></a> methods, and should be used with caution: 441 * assigning a segment incorrect spatial and/or temporal bounds could result in a VM crash when attempting to access 442 * the memory segment. 443 * 444 * @implSpec 445 * Implementations of this interface are immutable, thread-safe and <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>. 446 * 447 * @since 22 448 */ 449 public sealed interface MemorySegment permits AbstractMemorySegmentImpl { 450 451 /** 452 * {@return the address of this memory segment} 453 * 454 * @apiNote When using this method to pass a segment address to some external operation (e.g. a JNI function), 455 * clients must ensure that the segment is kept <a href="../../../java/lang/ref/package.html#reachability">reachable</a> 456 * for the entire duration of the operation. A failure to do so might result in the premature deallocation of the 457 * region of memory backing the memory segment, in case the segment has been allocated with an 458 * {@linkplain Arena#ofAuto() automatic arena}. 459 */ 460 long address(); 461 462 /** 463 * Returns the Java object stored in the on-heap region of memory backing this memory segment, if any. For instance, if this 464 * memory segment is a heap segment created with the {@link #ofArray(byte[])} factory method, this method will return the 465 * {@code byte[]} object which was used to obtain the segment. This method returns an empty {@code Optional} value 466 * if either this segment is a {@linkplain #isNative() native} segment, or if this segment is {@linkplain #isReadOnly() read-only}. 467 * @return the Java object associated with this memory segment, if any. 468 */ 469 Optional<Object> heapBase(); 470 471 /** 472 * Returns a spliterator for this memory segment. The returned spliterator reports {@link Spliterator#SIZED}, 473 * {@link Spliterator#SUBSIZED}, {@link Spliterator#IMMUTABLE}, {@link Spliterator#NONNULL} and {@link Spliterator#ORDERED} 474 * characteristics. 475 * <p> 476 * The returned spliterator splits this segment according to the specified element layout; that is, 477 * if the supplied layout has size N, then calling {@link Spliterator#trySplit()} will result in a spliterator serving 478 * approximately {@code S/N} elements (depending on whether N is even or not), where {@code S} is the size of 479 * this segment. As such, splitting is possible as long as {@code S/N >= 2}. The spliterator returns segments that 480 * have the same lifetime as that of this segment. 481 * <p> 482 * The returned spliterator effectively allows to slice this segment into disjoint {@linkplain #asSlice(long, long) slices}, 483 * which can then be processed in parallel by multiple threads. 484 * 485 * @param elementLayout the layout to be used for splitting. 486 * @return the element spliterator for this segment 487 * @throws IllegalArgumentException if {@code elementLayout.byteSize() == 0}. 488 * @throws IllegalArgumentException if {@code byteSize() % elementLayout.byteSize() != 0}. 489 * @throws IllegalArgumentException if {@code elementLayout.byteSize() % elementLayout.byteAlignment() != 0}. 490 * @throws IllegalArgumentException if this segment is <a href="MemorySegment.html#segment-alignment">incompatible 491 * with the alignment constraint</a> in the provided layout. 492 */ 493 Spliterator<MemorySegment> spliterator(MemoryLayout elementLayout); 494 495 /** 496 * Returns a sequential {@code Stream} over disjoint slices (whose size matches that of the specified layout) 497 * in this segment. Calling this method is equivalent to the following code: 498 * {@snippet lang=java : 499 * StreamSupport.stream(segment.spliterator(elementLayout), false); 500 * } 501 * 502 * @param elementLayout the layout to be used for splitting. 503 * @return a sequential {@code Stream} over disjoint slices in this segment. 504 * @throws IllegalArgumentException if {@code elementLayout.byteSize() == 0}. 505 * @throws IllegalArgumentException if {@code byteSize() % elementLayout.byteSize() != 0}. 506 * @throws IllegalArgumentException if {@code elementLayout.byteSize() % elementLayout.byteAlignment() != 0}. 507 * @throws IllegalArgumentException if this segment is <a href="MemorySegment.html#segment-alignment">incompatible 508 * with the alignment constraint</a> in the provided layout. 509 */ 510 Stream<MemorySegment> elements(MemoryLayout elementLayout); 511 512 /** 513 * {@return the scope associated with this memory segment} 514 */ 515 Scope scope(); 516 517 /** 518 * {@return {@code true} if this segment can be accessed from the provided thread} 519 * @param thread the thread to be tested. 520 */ 521 boolean isAccessibleBy(Thread thread); 522 523 /** 524 * {@return the size (in bytes) of this memory segment} 525 */ 526 long byteSize(); 527 528 /** 529 * Returns a slice of this memory segment, at the given offset. The returned segment's address is the address 530 * of this segment plus the given offset; its size is specified by the given argument. 531 * <p> 532 * Equivalent to the following code: 533 * {@snippet lang=java : 534 * asSlice(offset, newSize, 1); 535 * } 536 * 537 * @see #asSlice(long, long, long) 538 * 539 * @param offset The new segment base offset (relative to the address of this segment), specified in bytes. 540 * @param newSize The new segment size, specified in bytes. 541 * @return a slice of this memory segment. 542 * @throws IndexOutOfBoundsException if {@code offset < 0}, {@code offset > byteSize()}, {@code newSize < 0}, 543 * or {@code newSize > byteSize() - offset} 544 */ 545 MemorySegment asSlice(long offset, long newSize); 546 547 /** 548 * Returns a slice of this memory segment, at the given offset, with the provided alignment constraint. 549 * The returned segment's address is the address of this segment plus the given offset; its size is specified by the given argument. 550 * 551 * @param offset The new segment base offset (relative to the address of this segment), specified in bytes. 552 * @param newSize The new segment size, specified in bytes. 553 * @param byteAlignment The alignment constraint (in bytes) of the returned slice. 554 * @return a slice of this memory segment. 555 * @throws IndexOutOfBoundsException if {@code offset < 0}, {@code offset > byteSize()}, {@code newSize < 0}, 556 * or {@code newSize > byteSize() - offset} 557 * @throws IllegalArgumentException if this segment cannot be accessed at {@code offset} under 558 * the provided alignment constraint. 559 * @throws IllegalArgumentException if {@code byteAlignment <= 0}, or if {@code byteAlignment} is not a power of 2. 560 */ 561 MemorySegment asSlice(long offset, long newSize, long byteAlignment); 562 563 /** 564 * Returns a slice of this memory segment with the given layout, at the given offset. The returned segment's address is the address 565 * of this segment plus the given offset; its size is the same as the size of the provided layout. 566 * <p> 567 * Equivalent to the following code: 568 * {@snippet lang=java : 569 * asSlice(offset, layout.byteSize(), layout.byteAlignment()); 570 * } 571 * 572 * @see #asSlice(long, long, long) 573 * 574 * @param offset The new segment base offset (relative to the address of this segment), specified in bytes. 575 * @param layout The layout of the segment slice. 576 * @throws IndexOutOfBoundsException if {@code offset < 0}, {@code offset > byteSize()}, 577 * or {@code layout.byteSize() > byteSize() - offset} 578 * @throws IllegalArgumentException if this segment cannot be accessed at {@code offset} under 579 * the alignment constraint specified by {@code layout}. 580 * @return a slice of this memory segment. 581 */ 582 default MemorySegment asSlice(long offset, MemoryLayout layout) { 583 Objects.requireNonNull(layout); 584 return asSlice(offset, layout.byteSize(), layout.byteAlignment()); 585 } 586 587 /** 588 * Returns a slice of this memory segment, at the given offset. The returned segment's address is the address 589 * of this segment plus the given offset; its size is computed by subtracting the specified offset from this segment size. 590 * <p> 591 * Equivalent to the following code: 592 * {@snippet lang=java : 593 * asSlice(offset, byteSize() - offset); 594 * } 595 * 596 * @see #asSlice(long, long) 597 * 598 * @param offset The new segment base offset (relative to the address of this segment), specified in bytes. 599 * @return a slice of this memory segment. 600 * @throws IndexOutOfBoundsException if {@code offset < 0}, or {@code offset > byteSize()}. 601 */ 602 MemorySegment asSlice(long offset); 603 604 /** 605 * Returns a new memory segment that has the same address and scope as this segment, but with the provided size. 606 * <p> 607 * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>. 608 * Restricted methods are unsafe, and, if used incorrectly, their use might crash 609 * the JVM or, worse, silently result in memory corruption. 610 * 611 * @param newSize the size of the returned segment. 612 * @return a new memory segment that has the same address and scope as this segment, but the new 613 * provided size. 614 * @throws IllegalArgumentException if {@code newSize < 0}. 615 * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment. 616 * @throws IllegalCallerException If the caller is in a module that does not have native access enabled. 617 */ 618 @CallerSensitive 619 MemorySegment reinterpret(long newSize); 620 621 /** 622 * Returns a new memory segment with the same address and size as this segment, but with the provided scope. 623 * As such, the returned segment cannot be accessed after the provided arena has been closed. 624 * Moreover, the returned segment can be accessed compatibly with the confinement restrictions associated with the 625 * provided arena: that is, if the provided arena is a {@linkplain Arena#ofConfined() confined arena}, 626 * the returned segment can only be accessed by the arena's owner thread, regardless of the confinement restrictions 627 * associated with this segment. In other words, this method returns a segment that behaves as if it had been allocated 628 * using the provided arena. 629 * <p> 630 * Clients can specify an optional cleanup action that should be executed when the provided scope becomes 631 * invalid. This cleanup action receives a fresh memory segment that is obtained from this segment as follows: 632 * {@snippet lang=java : 633 * MemorySegment cleanupSegment = MemorySegment.ofAddress(this.address()) 634 * .reinterpret(byteSize()); 635 * } 636 * That is, the cleanup action receives a segment that is associated with a fresh scope that is always alive, 637 * and is accessible from any thread. The size of the segment accepted by the cleanup action is {@link #byteSize()}. 638 * <p> 639 * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>. 640 * Restricted methods are unsafe, and, if used incorrectly, their use might crash 641 * the JVM or, worse, silently result in memory corruption. 642 * 643 * @apiNote The cleanup action (if present) should take care not to leak the received segment to external 644 * clients which might access the segment after its backing region of memory is no longer available. Furthermore, 645 * if the provided scope is the scope of an {@linkplain Arena#ofAuto() automatic arena}, the cleanup action 646 * must not prevent the scope from becoming <a href="../../../java/lang/ref/package.html#reachability">unreachable</a>. 647 * A failure to do so will permanently prevent the regions of memory allocated by the automatic arena from being deallocated. 648 * 649 * @param arena the arena to be associated with the returned segment. 650 * @param cleanup the cleanup action that should be executed when the provided arena is closed (can be {@code null}). 651 * @return a new memory segment with unbounded size. 652 * @throws IllegalStateException if {@code arena.scope().isAlive() == false}. 653 * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment. 654 * @throws IllegalCallerException If the caller is in a module that does not have native access enabled. 655 */ 656 @CallerSensitive 657 MemorySegment reinterpret(Arena arena, Consumer<MemorySegment> cleanup); 658 659 /** 660 * Returns a new segment with the same address as this segment, but with the provided size and scope. 661 * As such, the returned segment cannot be accessed after the provided arena has been closed. 662 * Moreover, if the returned segment can be accessed compatibly with the confinement restrictions associated with the 663 * provided arena: that is, if the provided arena is a {@linkplain Arena#ofConfined() confined arena}, 664 * the returned segment can only be accessed by the arena's owner thread, regardless of the confinement restrictions 665 * associated with this segment. In other words, this method returns a segment that behaves as if it had been allocated 666 * using the provided arena. 667 * <p> 668 * Clients can specify an optional cleanup action that should be executed when the provided scope becomes 669 * invalid. This cleanup action receives a fresh memory segment that is obtained from this segment as follows: 670 * {@snippet lang=java : 671 * MemorySegment cleanupSegment = MemorySegment.ofAddress(this.address()) 672 * .reinterpret(newSize); 673 * } 674 * That is, the cleanup action receives a segment that is associated with a fresh scope that is always alive, 675 * and is accessible from any thread. The size of the segment accepted by the cleanup action is {@code newSize}. 676 * <p> 677 * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>. 678 * Restricted methods are unsafe, and, if used incorrectly, their use might crash 679 * the JVM or, worse, silently result in memory corruption. 680 * 681 * @apiNote The cleanup action (if present) should take care not to leak the received segment to external 682 * clients which might access the segment after its backing region of memory is no longer available. Furthermore, 683 * if the provided scope is the scope of an {@linkplain Arena#ofAuto() automatic arena}, the cleanup action 684 * must not prevent the scope from becoming <a href="../../../java/lang/ref/package.html#reachability">unreachable</a>. 685 * A failure to do so will permanently prevent the regions of memory allocated by the automatic arena from being deallocated. 686 * 687 * @param newSize the size of the returned segment. 688 * @param arena the arena to be associated with the returned segment. 689 * @param cleanup the cleanup action that should be executed when the provided arena is closed (can be {@code null}). 690 * @return a new segment that has the same address as this segment, but with new size and its scope set to 691 * that of the provided arena. 692 * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment. 693 * @throws IllegalArgumentException if {@code newSize < 0}. 694 * @throws IllegalStateException if {@code arena.scope().isAlive() == false}. 695 * @throws IllegalCallerException If the caller is in a module that does not have native access enabled. 696 */ 697 @CallerSensitive 698 MemorySegment reinterpret(long newSize, Arena arena, Consumer<MemorySegment> cleanup); 699 700 /** 701 * {@return {@code true}, if this segment is read-only} 702 * @see #asReadOnly() 703 */ 704 boolean isReadOnly(); 705 706 /** 707 * Returns a read-only view of this segment. The resulting segment will be identical to this one, but 708 * attempts to overwrite the contents of the returned segment will cause runtime exceptions. 709 * @return a read-only view of this segment 710 * @see #isReadOnly() 711 */ 712 MemorySegment asReadOnly(); 713 714 /** 715 * Returns {@code true} if this segment is a native segment. A native segment is 716 * created e.g. using the {@link Arena#allocate(long, long)} (and related) factory, or by 717 * {@linkplain #ofBuffer(Buffer) wrapping} a {@linkplain ByteBuffer#allocateDirect(int) direct buffer}. 718 * @return {@code true} if this segment is native segment. 719 */ 720 boolean isNative(); 721 722 /** 723 * Returns {@code true} if this segment is a mapped segment. A mapped memory segment is created e.g. using the 724 * {@link FileChannel#map(FileChannel.MapMode, long, long, Arena)} factory, or by 725 * {@linkplain #ofBuffer(Buffer) wrapping} a {@linkplain java.nio.MappedByteBuffer mapped byte buffer}. 726 * @return {@code true} if this segment is a mapped segment. 727 */ 728 boolean isMapped(); 729 730 /** 731 * Returns a slice of this segment that is the overlap between this and 732 * the provided segment. 733 * 734 * <p>Two segments {@code S1} and {@code S2} are said to overlap if it is possible to find 735 * at least two slices {@code L1} (from {@code S1}) and {@code L2} (from {@code S2}) that are backed by the 736 * same region of memory. As such, it is not possible for a 737 * {@linkplain #isNative() native} segment to overlap with a heap segment; in 738 * this case, or when no overlap occurs, an empty {@code Optional} is returned. 739 * 740 * @param other the segment to test for an overlap with this segment. 741 * @return a slice of this segment (where overlapping occurs). 742 */ 743 Optional<MemorySegment> asOverlappingSlice(MemorySegment other); 744 745 /** 746 * Fills the contents of this memory segment with the given value. 747 * <p> 748 * More specifically, the given value is written into each address of this 749 * segment. Equivalent to (but likely more efficient than) the following code: 750 * 751 * {@snippet lang=java : 752 * for (long offset = 0; offset < segment.byteSize(); offset++) { 753 * segment.set(ValueLayout.JAVA_BYTE, offset, value); 754 * } 755 * } 756 * 757 * But without any regard or guarantees on the ordering of particular memory 758 * elements being set. 759 * <p> 760 * This method can be useful to initialize or reset the contents of a memory segment. 761 * 762 * @param value the value to write into this segment. 763 * @return this memory segment. 764 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 765 * {@linkplain Scope#isAlive() alive}. 766 * @throws WrongThreadException if this method is called from a thread {@code T}, 767 * such that {@code isAccessibleBy(T) == false}. 768 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 769 */ 770 MemorySegment fill(byte value); 771 772 /** 773 * Performs a bulk copy from given source segment to this segment. More specifically, the bytes at 774 * offset {@code 0} through {@code src.byteSize() - 1} in the source segment are copied into this segment 775 * at offset {@code 0} through {@code src.byteSize() - 1}. 776 * <p> 777 * Calling this method is equivalent to the following code: 778 * {@snippet lang=java : 779 * MemorySegment.copy(src, 0, this, 0, src.byteSize()); 780 * } 781 * @param src the source segment. 782 * @throws IndexOutOfBoundsException if {@code src.byteSize() > this.byteSize()}. 783 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 784 * {@linkplain Scope#isAlive() alive}. 785 * @throws WrongThreadException if this method is called from a thread {@code T}, 786 * such that {@code isAccessibleBy(T) == false}. 787 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code src} is not 788 * {@linkplain Scope#isAlive() alive}. 789 * @throws WrongThreadException if this method is called from a thread {@code T}, 790 * such that {@code src.isAccessibleBy(T) == false}. 791 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 792 * @return this segment. 793 */ 794 default MemorySegment copyFrom(MemorySegment src) { 795 MemorySegment.copy(src, 0, this, 0, src.byteSize()); 796 return this; 797 } 798 799 /** 800 * Finds and returns the offset, in bytes, of the first mismatch between 801 * this segment and the given other segment. The offset is relative to the 802 * {@linkplain #address() address} of each segment and will be in the 803 * range of 0 (inclusive) up to the {@linkplain #byteSize() size} (in bytes) of 804 * the smaller memory segment (exclusive). 805 * <p> 806 * If the two segments share a common prefix then the returned offset is 807 * the length of the common prefix, and it follows that there is a mismatch 808 * between the two segments at that offset within the respective segments. 809 * If one segment is a proper prefix of the other, then the returned offset is 810 * the smallest of the segment sizes, and it follows that the offset is only 811 * valid for the larger segment. Otherwise, there is no mismatch and {@code 812 * -1} is returned. 813 * 814 * @param other the segment to be tested for a mismatch with this segment. 815 * @return the relative offset, in bytes, of the first mismatch between this 816 * and the given other segment, otherwise -1 if no mismatch. 817 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 818 * {@linkplain Scope#isAlive() alive}. 819 * @throws WrongThreadException if this method is called from a thread {@code T}, 820 * such that {@code isAccessibleBy(T) == false}. 821 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code other} is not 822 * {@linkplain Scope#isAlive() alive}. 823 * @throws WrongThreadException if this method is called from a thread {@code T}, 824 * such that {@code other.isAccessibleBy(T) == false}. 825 */ 826 default long mismatch(MemorySegment other) { 827 Objects.requireNonNull(other); 828 return MemorySegment.mismatch(this, 0, byteSize(), other, 0, other.byteSize()); 829 } 830 831 /** 832 * Determines whether the contents of this mapped segment is resident in physical 833 * memory. 834 * 835 * <p> A return value of {@code true} implies that it is highly likely 836 * that all the data in this segment is resident in physical memory and 837 * may therefore be accessed without incurring any virtual-memory page 838 * faults or I/O operations. A return value of {@code false} does not 839 * necessarily imply that this segment's content is not resident in physical 840 * memory. 841 * 842 * <p> The returned value is a hint, rather than a guarantee, because the 843 * underlying operating system may have paged out some of this segment's data 844 * by the time that an invocation of this method returns. </p> 845 * 846 * @return {@code true} if it is likely that the contents of this segment 847 * is resident in physical memory 848 * 849 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 850 * {@linkplain Scope#isAlive() alive}. 851 * @throws WrongThreadException if this method is called from a thread {@code T}, 852 * such that {@code isAccessibleBy(T) == false}. 853 * @throws UnsupportedOperationException if this segment is not a mapped memory segment, e.g. if 854 * {@code isMapped() == false}. 855 */ 856 boolean isLoaded(); 857 858 /** 859 * Loads the contents of this mapped segment into physical memory. 860 * 861 * <p> This method makes a best effort to ensure that, when it returns, 862 * this contents of this segment is resident in physical memory. Invoking this 863 * method may cause some number of page faults and I/O operations to 864 * occur. </p> 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 void load(); 874 875 /** 876 * Unloads the contents of this mapped segment from physical memory. 877 * 878 * <p> This method makes a best effort to ensure that the contents of this segment are 879 * are no longer resident in physical memory. Accessing this segment's contents 880 * after invoking this method may cause some number of page faults and I/O operations to 881 * occur (as this segment's contents might need to be paged back in). </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 unload(); 891 892 /** 893 * Forces any changes made to the contents of this mapped segment to be written to the 894 * storage device described by the mapped segment's file descriptor. 895 * 896 * <p> If the file descriptor associated with this mapped segment resides on a local storage 897 * device then when this method returns it is guaranteed that all changes 898 * made to this segment since it was created, or since this method was last 899 * invoked, will have been written to that device. 900 * 901 * <p> If the file descriptor associated with this mapped segment does not reside on a local device then 902 * no such guarantee is made. 903 * 904 * <p> If this segment was not mapped in read/write mode ({@link 905 * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then 906 * invoking this method may have no effect. In particular, the 907 * method has no effect for segments mapped in read-only or private 908 * mapping modes. This method may or may not have an effect for 909 * implementation-specific mapping modes. 910 * </p> 911 * 912 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 913 * {@linkplain Scope#isAlive() alive}. 914 * @throws WrongThreadException if this method is called from a thread {@code T}, 915 * such that {@code isAccessibleBy(T) == false}. 916 * @throws UnsupportedOperationException if this segment is not a mapped memory segment, e.g. if 917 * {@code isMapped() == false}. 918 * @throws UncheckedIOException if there is an I/O error writing the contents of this segment to the associated storage device 919 */ 920 void force(); 921 922 /** 923 * Wraps this segment in a {@link ByteBuffer}. Some properties of the returned buffer are linked to 924 * the properties of this segment. More specifically, the resulting buffer has the following characteristics: 925 * <ul> 926 * <li>It is {@linkplain ByteBuffer#isReadOnly() read-only}, if this segment is a 927 * {@linkplain #isReadOnly() read-only segment};</li> 928 * <li>Its {@linkplain ByteBuffer#position() position} is set to zero; 929 * <li>Its {@linkplain ByteBuffer#capacity() capacity} and {@linkplain ByteBuffer#limit() limit} 930 * are both set to this segment' {@linkplain MemorySegment#byteSize() size}. For this reason, a byte buffer 931 * cannot be returned if this segment's size is greater than {@link Integer#MAX_VALUE};</li> 932 * <li>It is a {@linkplain ByteBuffer#isDirect() direct buffer}, if this is a native segment.</li> 933 * </ul> 934 * <p> 935 * The life-cycle of the returned buffer is tied to that of this segment. That is, accessing the returned buffer 936 * after the scope associated with this segment is no longer {@linkplain Scope#isAlive() alive}, will 937 * throw an {@link IllegalStateException}. Similarly, accessing the returned buffer from a thread {@code T} 938 * such that {@code isAccessible(T) == false} will throw a {@link WrongThreadException}. 939 * <p> 940 * If this segment is {@linkplain #isAccessibleBy(Thread) accessible} from a single thread, calling read/write I/O 941 * operations on the resulting buffer might result in unspecified exceptions being thrown. Examples of such problematic operations are 942 * {@link java.nio.channels.AsynchronousSocketChannel#read(ByteBuffer)} and 943 * {@link java.nio.channels.AsynchronousSocketChannel#write(ByteBuffer)}. 944 * <p> 945 * Finally, the resulting buffer's byte order is {@link java.nio.ByteOrder#BIG_ENDIAN}; this can be changed using 946 * {@link ByteBuffer#order(java.nio.ByteOrder)}. 947 * 948 * @return a {@link ByteBuffer} view of this memory segment. 949 * @throws UnsupportedOperationException if this segment cannot be mapped onto a {@link ByteBuffer} instance, 950 * e.g. if it is a heap segment backed by an array other than {@code byte[]}), or if its size is greater 951 * than {@link Integer#MAX_VALUE}. 952 */ 953 ByteBuffer asByteBuffer(); 954 955 /** 956 * Copy the contents of this memory segment into a new byte array. 957 * @param elementLayout the source element layout. If the byte order associated with the layout is 958 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 959 * @return a new byte array whose contents are copied from this memory segment. 960 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 961 * {@linkplain Scope#isAlive() alive}. 962 * @throws WrongThreadException if this method is called from a thread {@code T}, 963 * such that {@code isAccessibleBy(T) == false}. 964 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code byte[]} instance, 965 * e.g. its size is greater than {@link Integer#MAX_VALUE}. 966 */ 967 byte[] toArray(ValueLayout.OfByte elementLayout); 968 969 /** 970 * Copy the contents of this memory segment into a new short array. 971 * @param elementLayout the source element layout. If the byte order associated with the layout is 972 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 973 * @return a new short array whose contents are copied from this memory segment. 974 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 975 * {@linkplain Scope#isAlive() alive}. 976 * @throws WrongThreadException if this method is called from a thread {@code T}, 977 * such that {@code isAccessibleBy(T) == false}. 978 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code short[]} instance, 979 * e.g. because {@code byteSize() % 2 != 0}, or {@code byteSize() / 2 > Integer.MAX_VALUE} 980 */ 981 short[] toArray(ValueLayout.OfShort elementLayout); 982 983 /** 984 * Copy the contents of this memory segment into a new char array. 985 * @param elementLayout the source element layout. If the byte order associated with the layout is 986 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 987 * @return a new char array whose contents are copied from this memory segment. 988 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 989 * {@linkplain Scope#isAlive() alive}. 990 * @throws WrongThreadException if this method is called from a thread {@code T}, 991 * such that {@code isAccessibleBy(T) == false}. 992 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code char[]} instance, 993 * e.g. because {@code byteSize() % 2 != 0}, or {@code byteSize() / 2 > Integer.MAX_VALUE}. 994 */ 995 char[] toArray(ValueLayout.OfChar elementLayout); 996 997 /** 998 * Copy the contents of this memory segment into a new int array. 999 * @param elementLayout the source element layout. If the byte order associated with the layout is 1000 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 1001 * @return a new int array whose contents are copied from this memory segment. 1002 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1003 * {@linkplain Scope#isAlive() alive}. 1004 * @throws WrongThreadException if this method is called from a thread {@code T}, 1005 * such that {@code isAccessibleBy(T) == false}. 1006 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code int[]} instance, 1007 * e.g. because {@code byteSize() % 4 != 0}, or {@code byteSize() / 4 > Integer.MAX_VALUE}. 1008 */ 1009 int[] toArray(ValueLayout.OfInt elementLayout); 1010 1011 /** 1012 * Copy the contents of this memory segment into a new float array. 1013 * @param elementLayout the source element layout. If the byte order associated with the layout is 1014 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 1015 * @return a new float array whose contents are copied from this memory segment. 1016 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1017 * {@linkplain Scope#isAlive() alive}. 1018 * @throws WrongThreadException if this method is called from a thread {@code T}, 1019 * such that {@code isAccessibleBy(T) == false}. 1020 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code float[]} instance, 1021 * e.g. because {@code byteSize() % 4 != 0}, or {@code byteSize() / 4 > Integer.MAX_VALUE}. 1022 */ 1023 float[] toArray(ValueLayout.OfFloat elementLayout); 1024 1025 /** 1026 * Copy the contents of this memory segment into a new long array. 1027 * @param elementLayout the source element layout. If the byte order associated with the layout is 1028 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 1029 * @return a new long array whose contents are copied from this memory segment. 1030 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1031 * {@linkplain Scope#isAlive() alive}. 1032 * @throws WrongThreadException if this method is called from a thread {@code T}, 1033 * such that {@code isAccessibleBy(T) == false}. 1034 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code long[]} instance, 1035 * e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer.MAX_VALUE}. 1036 */ 1037 long[] toArray(ValueLayout.OfLong elementLayout); 1038 1039 /** 1040 * Copy the contents of this memory segment into a new double array. 1041 * @param elementLayout the source element layout. If the byte order associated with the layout is 1042 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 1043 * @return a new double array whose contents are copied from this memory segment. 1044 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1045 * {@linkplain Scope#isAlive() alive}. 1046 * @throws WrongThreadException if this method is called from a thread {@code T}, 1047 * such that {@code isAccessibleBy(T) == false}. 1048 * @throws IllegalStateException if this segment's contents cannot be copied into a {@code double[]} instance, 1049 * e.g. because {@code byteSize() % 8 != 0}, or {@code byteSize() / 8 > Integer.MAX_VALUE}. 1050 */ 1051 double[] toArray(ValueLayout.OfDouble elementLayout); 1052 1053 /** 1054 * Reads a null-terminated string from this segment at the given offset, using the 1055 * {@linkplain StandardCharsets#UTF_8 UTF-8} charset. 1056 * <p> 1057 * Calling this method is equivalent to the following code: 1058 * {@snippet lang = java: 1059 * getString(offset, StandardCharsets.UTF_8); 1060 *} 1061 * 1062 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1063 * @return a Java string constructed from the bytes read from the given starting address up to (but not including) 1064 * the first {@code '\0'} terminator character (assuming one is found). 1065 * @throws IllegalArgumentException if the size of the string is greater than the largest string supported by the platform. 1066 * @throws IndexOutOfBoundsException if {@code offset < 0}. 1067 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - (B + 1)}, where {@code B} is the size, 1068 * in bytes, of the string encoded using UTF-8 charset {@code str.getBytes(StandardCharsets.UTF_8).length}). 1069 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1070 * {@linkplain Scope#isAlive() alive}. 1071 * @throws WrongThreadException if this method is called from a thread {@code T}, 1072 * such that {@code isAccessibleBy(T) == false}. 1073 */ 1074 default String getString(long offset) { 1075 return getString(offset, sun.nio.cs.UTF_8.INSTANCE); 1076 } 1077 1078 /** 1079 * Reads a null-terminated string from this segment at the given offset, using the provided charset. 1080 * <p> 1081 * This method always replaces malformed-input and unmappable-character 1082 * sequences with this charset's default replacement string. The {@link 1083 * java.nio.charset.CharsetDecoder} class should be used when more control 1084 * over the decoding process is required. 1085 * 1086 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1087 * @param charset the charset used to {@linkplain Charset#newDecoder() decode} the string bytes. 1088 * @return a Java string constructed from the bytes read from the given starting address up to (but not including) 1089 * the first {@code '\0'} terminator character (assuming one is found). 1090 * @throws IllegalArgumentException if the size of the string is greater than the largest string supported by the platform. 1091 * @throws IndexOutOfBoundsException if {@code offset < 0}. 1092 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - (B + N)}, where: 1093 * <ul> 1094 * <li>{@code B} is the size, in bytes, of the string encoded using the provided charset 1095 * (e.g. {@code str.getBytes(charset).length});</li> 1096 * <li>{@code N} is the size (in bytes) of the terminator char according to the provided charset. For instance, 1097 * this is 1 for {@link StandardCharsets#US_ASCII} and 2 for {@link StandardCharsets#UTF_16}.</li> 1098 * </ul> 1099 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1100 * {@linkplain Scope#isAlive() alive}. 1101 * @throws WrongThreadException if this method is called from a thread {@code T}, 1102 * such that {@code isAccessibleBy(T) == false}. 1103 * @throws UnsupportedOperationException if {@code charset} is not a {@linkplain StandardCharsets standard charset}. 1104 */ 1105 default String getString(long offset, Charset charset) { 1106 Objects.requireNonNull(charset); 1107 return StringSupport.read(this, offset, charset); 1108 } 1109 1110 /** 1111 * Writes the given string into this segment at the given offset, converting it to a null-terminated byte sequence 1112 * using the {@linkplain StandardCharsets#UTF_8 UTF-8} charset. 1113 * <p> 1114 * Calling this method is equivalent to the following code: 1115 * {@snippet lang = java: 1116 * setString(offset, str, StandardCharsets.UTF_8); 1117 *} 1118 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1119 * the final address of this write operation can be expressed as {@code address() + offset}. 1120 * @param str the Java string to be written into this segment. 1121 * @throws IndexOutOfBoundsException if {@code offset < 0}. 1122 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - (B + 1)}, where {@code B} is the size, 1123 * in bytes, of the string encoded using UTF-8 charset {@code str.getBytes(StandardCharsets.UTF_8).length}). 1124 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1125 * {@linkplain Scope#isAlive() alive}. 1126 * @throws WrongThreadException if this method is called from a thread {@code T}, 1127 * such that {@code isAccessibleBy(T) == false}. 1128 */ 1129 default void setString(long offset, String str) { 1130 Objects.requireNonNull(str); 1131 setString(offset, str, sun.nio.cs.UTF_8.INSTANCE); 1132 } 1133 1134 /** 1135 * Writes the given string into this segment at the given offset, converting it to a null-terminated byte sequence 1136 * using the provided charset. 1137 * <p> 1138 * This method always replaces malformed-input and unmappable-character 1139 * sequences with this charset's default replacement string. The {@link 1140 * java.nio.charset.CharsetDecoder} class should be used when more control 1141 * over the decoding process is required. 1142 * <p> 1143 * If the given string contains any {@code '\0'} characters, they will be 1144 * copied as well. This means that, depending on the method used to read 1145 * the string, such as {@link MemorySegment#getString(long)}, the string 1146 * will appear truncated when read again. 1147 * 1148 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1149 * the final address of this write operation can be expressed as {@code address() + offset}. 1150 * @param str the Java string to be written into this segment. 1151 * @param charset the charset used to {@linkplain Charset#newEncoder() encode} the string bytes. 1152 * @throws IndexOutOfBoundsException if {@code offset < 0}. 1153 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - (B + N)}, where: 1154 * <ul> 1155 * <li>{@code B} is the size, in bytes, of the string encoded using the provided charset 1156 * (e.g. {@code str.getBytes(charset).length});</li> 1157 * <li>{@code N} is the size (in bytes) of the terminator char according to the provided charset. For instance, 1158 * this is 1 for {@link StandardCharsets#US_ASCII} and 2 for {@link StandardCharsets#UTF_16}.</li> 1159 * </ul> 1160 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1161 * {@linkplain Scope#isAlive() alive}. 1162 * @throws WrongThreadException if this method is called from a thread {@code T}, 1163 * such that {@code isAccessibleBy(T) == false}. 1164 * @throws UnsupportedOperationException if {@code charset} is not a {@linkplain StandardCharsets standard charset}. 1165 */ 1166 default void setString(long offset, String str, Charset charset) { 1167 Objects.requireNonNull(charset); 1168 Objects.requireNonNull(str); 1169 StringSupport.write(this, offset, charset, str); 1170 } 1171 1172 /** 1173 * Creates a memory segment that is backed by the same region of memory that backs the given {@link Buffer} instance. 1174 * The segment starts relative to the buffer's position (inclusive) and ends relative to the buffer's limit (exclusive). 1175 * <p> 1176 * If the buffer is {@linkplain Buffer#isReadOnly() read-only}, the resulting segment is also 1177 * {@linkplain ByteBuffer#isReadOnly() read-only}. Moreover, if the buffer is a {@linkplain Buffer#isDirect() direct buffer}, 1178 * the returned segment is a native segment; otherwise the returned memory segment is a heap segment. 1179 * <p> 1180 * If the provided buffer has been obtained by calling {@link #asByteBuffer()} on a memory segment whose 1181 * {@linkplain Scope scope} is {@code S}, the returned segment will be associated with the 1182 * same scope {@code S}. Otherwise, the scope of the returned segment is a fresh scope that is always alive. 1183 * <p> 1184 * The scope associated with the returned segment keeps the provided buffer reachable. As such, if 1185 * the provided buffer is a direct buffer, its backing memory region will not be deallocated as long as the 1186 * returned segment (or any of its slices) are kept reachable. 1187 * 1188 * @param buffer the buffer instance to be turned into a new memory segment. 1189 * @return a memory segment, derived from the given buffer instance. 1190 * @throws IllegalArgumentException if the provided {@code buffer} is a heap buffer but is not backed by an array. 1191 * For example, buffers directly or indirectly obtained via 1192 * ({@link CharBuffer#wrap(CharSequence)} or {@link CharBuffer#wrap(char[], int, int)} 1193 * are not backed by an array. 1194 */ 1195 static MemorySegment ofBuffer(Buffer buffer) { 1196 return AbstractMemorySegmentImpl.ofBuffer(buffer); 1197 } 1198 1199 /** 1200 * Creates a heap segment backed by the on-heap region of memory that holds the given byte array. 1201 * The scope of the returned segment is a fresh scope that is always alive, and keeps the given array reachable. 1202 * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. 1203 * 1204 * @param byteArray the primitive array backing the heap memory segment. 1205 * @return a heap memory segment backed by a byte array. 1206 */ 1207 static MemorySegment ofArray(byte[] byteArray) { 1208 return HeapMemorySegmentImpl.OfByte.fromArray(byteArray); 1209 } 1210 1211 /** 1212 * Creates a heap segment backed by the on-heap region of memory that holds the given char array. 1213 * The scope of the returned segment is a fresh scope that is always alive, and keeps the given array reachable. 1214 * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. 1215 * 1216 * @param charArray the primitive array backing the heap segment. 1217 * @return a heap memory segment backed by a char array. 1218 */ 1219 static MemorySegment ofArray(char[] charArray) { 1220 return HeapMemorySegmentImpl.OfChar.fromArray(charArray); 1221 } 1222 1223 /** 1224 * Creates a heap segment backed by the on-heap region of memory that holds the given short array. 1225 * The scope of the returned segment is a fresh scope that is always alive, and keeps the given array reachable. 1226 * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. 1227 * 1228 * @param shortArray the primitive array backing the heap segment. 1229 * @return a heap memory segment backed by a short array. 1230 */ 1231 static MemorySegment ofArray(short[] shortArray) { 1232 return HeapMemorySegmentImpl.OfShort.fromArray(shortArray); 1233 } 1234 1235 /** 1236 * Creates a heap segment backed by the on-heap region of memory that holds the given int array. 1237 * The scope of the returned segment is a fresh scope that is always alive, and keeps the given array reachable. 1238 * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. 1239 * 1240 * @param intArray the primitive array backing the heap segment. 1241 * @return a heap memory segment backed by an int array. 1242 */ 1243 static MemorySegment ofArray(int[] intArray) { 1244 return HeapMemorySegmentImpl.OfInt.fromArray(intArray); 1245 } 1246 1247 /** 1248 * Creates a heap segment backed by the on-heap region of memory that holds the given float array. 1249 * The scope of the returned segment is a fresh scope that is always alive, and keeps the given array reachable. 1250 * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. 1251 * 1252 * @param floatArray the primitive array backing the heap segment. 1253 * @return a heap memory segment backed by a float array. 1254 */ 1255 static MemorySegment ofArray(float[] floatArray) { 1256 return HeapMemorySegmentImpl.OfFloat.fromArray(floatArray); 1257 } 1258 1259 /** 1260 * Creates a heap segment backed by the on-heap region of memory that holds the given long array. 1261 * The scope of the returned segment is a fresh scope that is always alive, and keeps the given array reachable. 1262 * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. 1263 * 1264 * @param longArray the primitive array backing the heap segment. 1265 * @return a heap memory segment backed by a long array. 1266 */ 1267 static MemorySegment ofArray(long[] longArray) { 1268 return HeapMemorySegmentImpl.OfLong.fromArray(longArray); 1269 } 1270 1271 /** 1272 * Creates a heap segment backed by the on-heap region of memory that holds the given double array. 1273 * The scope of the returned segment is a fresh scope that is always alive, and keeps the given array reachable. 1274 * The returned segment is always accessible, from any thread. Its {@link #address()} is set to zero. 1275 * 1276 * @param doubleArray the primitive array backing the heap segment. 1277 * @return a heap memory segment backed by a double array. 1278 */ 1279 static MemorySegment ofArray(double[] doubleArray) { 1280 return HeapMemorySegmentImpl.OfDouble.fromArray(doubleArray); 1281 } 1282 1283 /** 1284 * A zero-length native segment modelling the {@code NULL} address. 1285 */ 1286 MemorySegment NULL = new NativeMemorySegmentImpl(); 1287 1288 /** 1289 * Creates a zero-length native segment from the given {@linkplain #address() address value}. 1290 * The returned segment is associated with a scope that is always alive, and is accessible from any thread. 1291 * <p> 1292 * On 32-bit platforms, the given address value will be normalized such that the 1293 * highest-order ("leftmost") 32 bits of the {@link MemorySegment#address() address} 1294 * of the returned memory segment are set to zero. 1295 * 1296 * @param address the address of the returned native segment. 1297 * @return a zero-length native segment with the given address. 1298 */ 1299 static MemorySegment ofAddress(long address) { 1300 return NativeMemorySegmentImpl.makeNativeSegmentUnchecked(address, 0); 1301 } 1302 1303 /** 1304 * Performs a bulk copy from source segment to destination segment. More specifically, the bytes at offset 1305 * {@code srcOffset} through {@code srcOffset + bytes - 1} in the source segment are copied into the destination 1306 * segment at offset {@code dstOffset} through {@code dstOffset + bytes - 1}. 1307 * <p> 1308 * If the source segment overlaps with the destination segment, then the copying is performed as if the bytes at 1309 * offset {@code srcOffset} through {@code srcOffset + bytes - 1} in the source segment were first copied into a 1310 * temporary segment with size {@code bytes}, and then the contents of the temporary segment were copied into 1311 * the destination segment at offset {@code dstOffset} through {@code dstOffset + bytes - 1}. 1312 * <p> 1313 * The result of a bulk copy is unspecified if, in the uncommon case, the source segment and the destination segment 1314 * do not overlap, but refer to overlapping regions of the same backing storage using different addresses. 1315 * For example, this may occur if the same file is {@linkplain FileChannel#map mapped} to two segments. 1316 * <p> 1317 * Calling this method is equivalent to the following code: 1318 * {@snippet lang=java : 1319 * MemorySegment.copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes); 1320 * } 1321 * @param srcSegment the source segment. 1322 * @param srcOffset the starting offset, in bytes, of the source segment. 1323 * @param dstSegment the destination segment. 1324 * @param dstOffset the starting offset, in bytes, of the destination segment. 1325 * @param bytes the number of bytes to be copied. 1326 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not 1327 * {@linkplain Scope#isAlive() alive}. 1328 * @throws WrongThreadException if this method is called from a thread {@code T}, 1329 * such that {@code srcSegment.isAccessibleBy(T) == false}. 1330 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not 1331 * {@linkplain Scope#isAlive() alive}. 1332 * @throws WrongThreadException if this method is called from a thread {@code T}, 1333 * such that {@code dstSegment.isAccessibleBy(T) == false}. 1334 * @throws IndexOutOfBoundsException if {@code srcOffset > srcSegment.byteSize() - bytes}. 1335 * @throws IndexOutOfBoundsException if {@code dstOffset > dstSegment.byteSize() - bytes}. 1336 * @throws IndexOutOfBoundsException if either {@code srcOffset}, {@code dstOffset} 1337 * or {@code bytes} are {@code < 0}. 1338 * @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}. 1339 */ 1340 @ForceInline 1341 static void copy(MemorySegment srcSegment, long srcOffset, 1342 MemorySegment dstSegment, long dstOffset, long bytes) { 1343 copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes); 1344 } 1345 1346 /** 1347 * Performs a bulk copy from source segment to destination segment. More specifically, if {@code S} is the byte size 1348 * of the element layouts, the bytes at offset {@code srcOffset} through {@code srcOffset + (elementCount * S) - 1} 1349 * in the source segment are copied into the destination segment at offset {@code dstOffset} through {@code dstOffset + (elementCount * S) - 1}. 1350 * <p> 1351 * The copy occurs in an element-wise fashion: the bytes in the source segment are interpreted as a sequence of elements 1352 * whose layout is {@code srcElementLayout}, whereas the bytes in the destination segment are interpreted as a sequence of 1353 * elements whose layout is {@code dstElementLayout}. Both element layouts must have same size {@code S}. 1354 * If the byte order of the two element layouts differ, the bytes corresponding to each element to be copied 1355 * are swapped accordingly during the copy operation. 1356 * <p> 1357 * If the source segment overlaps with the destination segment, then the copying is performed as if the bytes at 1358 * offset {@code srcOffset} through {@code srcOffset + (elementCount * S) - 1} in the source segment were first copied into a 1359 * temporary segment with size {@code bytes}, and then the contents of the temporary segment were copied into 1360 * the destination segment at offset {@code dstOffset} through {@code dstOffset + (elementCount * S) - 1}. 1361 * <p> 1362 * The result of a bulk copy is unspecified if, in the uncommon case, the source segment and the destination segment 1363 * do not overlap, but refer to overlapping regions of the same backing storage using different addresses. 1364 * For example, this may occur if the same file is {@linkplain FileChannel#map mapped} to two segments. 1365 * @param srcSegment the source segment. 1366 * @param srcElementLayout the element layout associated with the source segment. 1367 * @param srcOffset the starting offset, in bytes, of the source segment. 1368 * @param dstSegment the destination segment. 1369 * @param dstElementLayout the element layout associated with the destination segment. 1370 * @param dstOffset the starting offset, in bytes, of the destination segment. 1371 * @param elementCount the number of elements to be copied. 1372 * @throws IllegalArgumentException if the element layouts have different sizes, if the source (resp. destination) segment/offset are 1373 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the source 1374 * (resp. destination) element layout. 1375 * @throws IllegalArgumentException if {@code srcElementLayout.byteAlignment() > srcElementLayout.byteSize()}. 1376 * @throws IllegalArgumentException if {@code dstElementLayout.byteAlignment() > dstElementLayout.byteSize()}. 1377 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not 1378 * {@linkplain Scope#isAlive() alive}. 1379 * @throws WrongThreadException if this method is called from a thread {@code T}, 1380 * such that {@code srcSegment.isAccessibleBy(T) == false}. 1381 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not 1382 * {@linkplain Scope#isAlive() alive}. 1383 * @throws WrongThreadException if this method is called from a thread {@code T}, 1384 * such that {@code dstSegment.isAccessibleBy(T) == false}. 1385 * @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}. 1386 * @throws IndexOutOfBoundsException if {@code elementCount * srcLayout.byteSize()} overflows. 1387 * @throws IndexOutOfBoundsException if {@code elementCount * dtsLayout.byteSize()} overflows. 1388 * @throws IndexOutOfBoundsException if {@code srcOffset > srcSegment.byteSize() - (elementCount * srcLayout.byteSize())}. 1389 * @throws IndexOutOfBoundsException if {@code dstOffset > dstSegment.byteSize() - (elementCount * dstLayout.byteSize())}. 1390 * @throws IndexOutOfBoundsException if either {@code srcOffset}, {@code dstOffset} or {@code elementCount} are {@code < 0}. 1391 */ 1392 @ForceInline 1393 static void copy(MemorySegment srcSegment, ValueLayout srcElementLayout, long srcOffset, 1394 MemorySegment dstSegment, ValueLayout dstElementLayout, long dstOffset, 1395 long elementCount) { 1396 Objects.requireNonNull(srcSegment); 1397 Objects.requireNonNull(srcElementLayout); 1398 Objects.requireNonNull(dstSegment); 1399 Objects.requireNonNull(dstElementLayout); 1400 AbstractMemorySegmentImpl.copy(srcSegment, srcElementLayout, srcOffset, dstSegment, dstElementLayout, dstOffset, elementCount); 1401 } 1402 1403 /** 1404 * Reads a byte from this segment at the given offset, with the given layout. 1405 * 1406 * @param layout the layout of the region of memory to be read. 1407 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1408 * @return a byte value read from this segment. 1409 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1410 * {@linkplain Scope#isAlive() alive}. 1411 * @throws WrongThreadException if this method is called from a thread {@code T}, 1412 * such that {@code isAccessibleBy(T) == false}. 1413 * @throws IllegalArgumentException if the access operation is 1414 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1415 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1416 */ 1417 @ForceInline 1418 default byte get(ValueLayout.OfByte layout, long offset) { 1419 return (byte) layout.varHandle().get(this, offset); 1420 } 1421 1422 /** 1423 * Writes a byte into this segment at the given offset, with the given layout. 1424 * 1425 * @param layout the layout of the region of memory to be written. 1426 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1427 * @param value the byte value to be written. 1428 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1429 * {@linkplain Scope#isAlive() alive}. 1430 * @throws WrongThreadException if this method is called from a thread {@code T}, 1431 * such that {@code isAccessibleBy(T) == false}. 1432 * @throws IllegalArgumentException if the access operation is 1433 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1434 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1435 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 1436 */ 1437 @ForceInline 1438 default void set(ValueLayout.OfByte layout, long offset, byte value) { 1439 layout.varHandle().set(this, offset, value); 1440 } 1441 1442 /** 1443 * Reads a boolean from this segment at the given offset, with the given layout. 1444 * 1445 * @param layout the layout of the region of memory to be read. 1446 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1447 * @return a boolean value read from this segment. 1448 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1449 * {@linkplain Scope#isAlive() alive}. 1450 * @throws WrongThreadException if this method is called from a thread {@code T}, 1451 * such that {@code isAccessibleBy(T) == false}. 1452 * @throws IllegalArgumentException if the access operation is 1453 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1454 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1455 */ 1456 @ForceInline 1457 default boolean get(ValueLayout.OfBoolean layout, long offset) { 1458 return (boolean) layout.varHandle().get(this, offset); 1459 } 1460 1461 /** 1462 * Writes a boolean into this segment at the given offset, with the given layout. 1463 * 1464 * @param layout the layout of the region of memory to be written. 1465 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1466 * @param value the boolean value to be written. 1467 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1468 * {@linkplain Scope#isAlive() alive}. 1469 * @throws WrongThreadException if this method is called from a thread {@code T}, 1470 * such that {@code isAccessibleBy(T) == false}. 1471 * @throws IllegalArgumentException if the access operation is 1472 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1473 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1474 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 1475 */ 1476 @ForceInline 1477 default void set(ValueLayout.OfBoolean layout, long offset, boolean value) { 1478 layout.varHandle().set(this, offset, value); 1479 } 1480 1481 /** 1482 * Reads a char from this segment at the given offset, with the given layout. 1483 * 1484 * @param layout the layout of the region of memory to be read. 1485 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1486 * @return a char value read from this segment. 1487 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1488 * {@linkplain Scope#isAlive() alive}. 1489 * @throws WrongThreadException if this method is called from a thread {@code T}, 1490 * such that {@code isAccessibleBy(T) == false}. 1491 * @throws IllegalArgumentException if the access operation is 1492 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1493 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1494 */ 1495 @ForceInline 1496 default char get(ValueLayout.OfChar layout, long offset) { 1497 return (char) layout.varHandle().get(this, offset); 1498 } 1499 1500 /** 1501 * Writes a char into this segment at the given offset, with the given layout. 1502 * 1503 * @param layout the layout of the region of memory to be written. 1504 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1505 * @param value the char value to be written. 1506 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1507 * {@linkplain Scope#isAlive() alive}. 1508 * @throws WrongThreadException if this method is called from a thread {@code T}, 1509 * such that {@code isAccessibleBy(T) == false}. 1510 * @throws IllegalArgumentException if the access operation is 1511 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1512 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1513 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 1514 */ 1515 @ForceInline 1516 default void set(ValueLayout.OfChar layout, long offset, char value) { 1517 layout.varHandle().set(this, offset, value); 1518 } 1519 1520 /** 1521 * Reads a short from this segment at the given offset, with the given layout. 1522 * 1523 * @param layout the layout of the region of memory to be read. 1524 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1525 * @return a short value read from this segment. 1526 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1527 * {@linkplain Scope#isAlive() alive}. 1528 * @throws WrongThreadException if this method is called from a thread {@code T}, 1529 * such that {@code isAccessibleBy(T) == false}. 1530 * @throws IllegalArgumentException if the access operation is 1531 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1532 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1533 */ 1534 @ForceInline 1535 default short get(ValueLayout.OfShort layout, long offset) { 1536 return (short) layout.varHandle().get(this, offset); 1537 } 1538 1539 /** 1540 * Writes a short into this segment at the given offset, with the given layout. 1541 * 1542 * @param layout the layout of the region of memory to be written. 1543 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1544 * @param value the short value to be written. 1545 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1546 * {@linkplain Scope#isAlive() alive}. 1547 * @throws WrongThreadException if this method is called from a thread {@code T}, 1548 * such that {@code isAccessibleBy(T) == false}. 1549 * @throws IllegalArgumentException if the access operation is 1550 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1551 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1552 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 1553 */ 1554 @ForceInline 1555 default void set(ValueLayout.OfShort layout, long offset, short value) { 1556 layout.varHandle().set(this, offset, value); 1557 } 1558 1559 /** 1560 * Reads an int from this segment at the given offset, with the given layout. 1561 * 1562 * @param layout the layout of the region of memory to be read. 1563 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1564 * @return an int value read from this segment. 1565 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1566 * {@linkplain Scope#isAlive() alive}. 1567 * @throws WrongThreadException if this method is called from a thread {@code T}, 1568 * such that {@code isAccessibleBy(T) == false}. 1569 * @throws IllegalArgumentException if the access operation is 1570 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1571 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1572 */ 1573 @ForceInline 1574 default int get(ValueLayout.OfInt layout, long offset) { 1575 return (int) layout.varHandle().get(this, offset); 1576 } 1577 1578 /** 1579 * Writes an int into this segment at the given offset, with the given layout. 1580 * 1581 * @param layout the layout of the region of memory to be written. 1582 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1583 * @param value the int value to be written. 1584 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1585 * {@linkplain Scope#isAlive() alive}. 1586 * @throws WrongThreadException if this method is called from a thread {@code T}, 1587 * such that {@code isAccessibleBy(T) == false}. 1588 * @throws IllegalArgumentException if the access operation is 1589 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1590 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1591 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 1592 */ 1593 @ForceInline 1594 default void set(ValueLayout.OfInt layout, long offset, int value) { 1595 layout.varHandle().set(this, offset, value); 1596 } 1597 1598 /** 1599 * Reads a float from this segment at the given offset, with the given layout. 1600 * 1601 * @param layout the layout of the region of memory to be read. 1602 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1603 * @return a float value read from this segment. 1604 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1605 * {@linkplain Scope#isAlive() alive}. 1606 * @throws WrongThreadException if this method is called from a thread {@code T}, 1607 * such that {@code isAccessibleBy(T) == false}. 1608 * @throws IllegalArgumentException if the access operation is 1609 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1610 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1611 */ 1612 @ForceInline 1613 default float get(ValueLayout.OfFloat layout, long offset) { 1614 return (float)layout.varHandle().get(this, offset); 1615 } 1616 1617 /** 1618 * Writes a float into this segment at the given offset, with the given layout. 1619 * 1620 * @param layout the layout of the region of memory to be written. 1621 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1622 * @param value the float value to be written. 1623 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1624 * {@linkplain Scope#isAlive() alive}. 1625 * @throws WrongThreadException if this method is called from a thread {@code T}, 1626 * such that {@code isAccessibleBy(T) == false}. 1627 * @throws IllegalArgumentException if the access operation is 1628 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1629 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1630 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 1631 */ 1632 @ForceInline 1633 default void set(ValueLayout.OfFloat layout, long offset, float value) { 1634 layout.varHandle().set(this, offset, value); 1635 } 1636 1637 /** 1638 * Reads a long from this segment at the given offset, with the given layout. 1639 * 1640 * @param layout the layout of the region of memory to be read. 1641 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1642 * @return a long value read from this segment. 1643 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1644 * {@linkplain Scope#isAlive() alive}. 1645 * @throws WrongThreadException if this method is called from a thread {@code T}, 1646 * such that {@code isAccessibleBy(T) == false}. 1647 * @throws IllegalArgumentException if the access operation is 1648 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1649 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1650 */ 1651 @ForceInline 1652 default long get(ValueLayout.OfLong layout, long offset) { 1653 return (long) layout.varHandle().get(this, offset); 1654 } 1655 1656 /** 1657 * Writes a long into this segment at the given offset, with the given layout. 1658 * 1659 * @param layout the layout of the region of memory to be written. 1660 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1661 * @param value the long value to be written. 1662 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1663 * {@linkplain Scope#isAlive() alive}. 1664 * @throws WrongThreadException if this method is called from a thread {@code T}, 1665 * such that {@code isAccessibleBy(T) == false}. 1666 * @throws IllegalArgumentException if the access operation is 1667 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1668 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1669 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 1670 */ 1671 @ForceInline 1672 default void set(ValueLayout.OfLong layout, long offset, long value) { 1673 layout.varHandle().set(this, offset, value); 1674 } 1675 1676 /** 1677 * Reads a double from this segment at the given offset, with the given layout. 1678 * 1679 * @param layout the layout of the region of memory to be read. 1680 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1681 * @return a double value read from this segment. 1682 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1683 * {@linkplain Scope#isAlive() alive}. 1684 * @throws WrongThreadException if this method is called from a thread {@code T}, 1685 * such that {@code isAccessibleBy(T) == false}. 1686 * @throws IllegalArgumentException if the access operation is 1687 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1688 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1689 */ 1690 @ForceInline 1691 default double get(ValueLayout.OfDouble layout, long offset) { 1692 return (double) layout.varHandle().get(this, offset); 1693 } 1694 1695 /** 1696 * Writes a double into this segment at the given offset, with the given layout. 1697 * 1698 * @param layout the layout of the region of memory to be written. 1699 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1700 * @param value the double value to be written. 1701 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1702 * {@linkplain Scope#isAlive() alive}. 1703 * @throws WrongThreadException if this method is called from a thread {@code T}, 1704 * such that {@code isAccessibleBy(T) == false}. 1705 * @throws IllegalArgumentException if the access operation is 1706 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1707 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1708 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 1709 */ 1710 @ForceInline 1711 default void set(ValueLayout.OfDouble layout, long offset, double value) { 1712 layout.varHandle().set(this, offset, value); 1713 } 1714 1715 /** 1716 * Reads an address from this segment at the given offset, with the given layout. The read address is wrapped in 1717 * a native segment, associated with a fresh scope that is always alive. Under normal conditions, 1718 * the size of the returned segment is {@code 0}. However, if the provided address layout has a 1719 * {@linkplain AddressLayout#targetLayout() target layout} {@code T}, then the size of the returned segment 1720 * is set to {@code T.byteSize()}. 1721 * @param layout the layout of the region of memory to be read. 1722 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1723 * @return a native segment wrapping an address read from this segment. 1724 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1725 * {@linkplain Scope#isAlive() alive}. 1726 * @throws WrongThreadException if this method is called from a thread {@code T}, 1727 * such that {@code isAccessibleBy(T) == false}. 1728 * @throws IllegalArgumentException if the access operation is 1729 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1730 * @throws IllegalArgumentException if provided address layout has a {@linkplain AddressLayout#targetLayout() target layout} 1731 * {@code T}, and the address of the returned segment 1732 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in {@code T}. 1733 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1734 */ 1735 @ForceInline 1736 default MemorySegment get(AddressLayout layout, long offset) { 1737 return (MemorySegment) layout.varHandle().get(this, offset); 1738 } 1739 1740 /** 1741 * Writes an address into this segment at the given offset, with the given layout. 1742 * 1743 * @param layout the layout of the region of memory to be written. 1744 * @param offset offset in bytes (relative to this segment address) at which this access operation will occur. 1745 * @param value the address value to be written. 1746 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1747 * {@linkplain Scope#isAlive() alive}. 1748 * @throws WrongThreadException if this method is called from a thread {@code T}, 1749 * such that {@code isAccessibleBy(T) == false}. 1750 * @throws IllegalArgumentException if the access operation is 1751 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1752 * @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}. 1753 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 1754 * @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment. 1755 */ 1756 @ForceInline 1757 default void set(AddressLayout layout, long offset, MemorySegment value) { 1758 layout.varHandle().set(this, offset, value); 1759 } 1760 1761 /** 1762 * Reads a byte from this segment at the given index, scaled by the given layout size. 1763 * 1764 * @param layout the layout of the region of memory to be read. 1765 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 1766 * will occur can be expressed as {@code (index * layout.byteSize())}. 1767 * @return a byte value read from this segment. 1768 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1769 * {@linkplain Scope#isAlive() alive}. 1770 * @throws WrongThreadException if this method is called from a thread {@code T}, 1771 * such that {@code isAccessibleBy(T) == false}. 1772 * @throws IllegalArgumentException if the access operation is 1773 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1774 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 1775 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 1776 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 1777 */ 1778 @ForceInline 1779 default byte getAtIndex(ValueLayout.OfByte layout, long index) { 1780 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 1781 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 1782 return (byte) layout.varHandle().get(this, index * layout.byteSize()); 1783 } 1784 1785 /** 1786 * Reads a boolean from this segment at the given index, scaled by the given layout size. 1787 * 1788 * @param layout the layout of the region of memory to be read. 1789 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 1790 * will occur can be expressed as {@code (index * layout.byteSize())}. 1791 * @return a boolean value read from this segment. 1792 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1793 * {@linkplain Scope#isAlive() alive}. 1794 * @throws WrongThreadException if this method is called from a thread {@code T}, 1795 * such that {@code isAccessibleBy(T) == false}. 1796 * @throws IllegalArgumentException if the access operation is 1797 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1798 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 1799 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 1800 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 1801 */ 1802 @ForceInline 1803 default boolean getAtIndex(ValueLayout.OfBoolean layout, long index) { 1804 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 1805 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 1806 return (boolean) layout.varHandle().get(this, index * layout.byteSize()); 1807 } 1808 1809 /** 1810 * Reads a char from this segment at the given index, scaled by the given layout size. 1811 * 1812 * @param layout the layout of the region of memory to be read. 1813 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 1814 * will occur can be expressed as {@code (index * layout.byteSize())}. 1815 * @return a char value read from this segment. 1816 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1817 * {@linkplain Scope#isAlive() alive}. 1818 * @throws WrongThreadException if this method is called from a thread {@code T}, 1819 * such that {@code isAccessibleBy(T) == false}. 1820 * @throws IllegalArgumentException if the access operation is 1821 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1822 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 1823 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 1824 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 1825 */ 1826 @ForceInline 1827 default char getAtIndex(ValueLayout.OfChar layout, long index) { 1828 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 1829 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 1830 return (char) layout.varHandle().get(this, index * layout.byteSize()); 1831 } 1832 1833 /** 1834 * Writes a char into this segment at the given index, scaled by the given layout size. 1835 * 1836 * @param layout the layout of the region of memory to be written. 1837 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 1838 * will occur can be expressed as {@code (index * layout.byteSize())}. 1839 * @param value the char value to be written. 1840 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1841 * {@linkplain Scope#isAlive() alive}. 1842 * @throws WrongThreadException if this method is called from a thread {@code T}, 1843 * such that {@code isAccessibleBy(T) == false}. 1844 * @throws IllegalArgumentException if the access operation is 1845 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1846 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 1847 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 1848 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 1849 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 1850 */ 1851 @ForceInline 1852 default void setAtIndex(ValueLayout.OfChar layout, long index, char value) { 1853 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 1854 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 1855 layout.varHandle().set(this, index * layout.byteSize(), value); 1856 } 1857 1858 /** 1859 * Reads a short from this segment at the given index, scaled by the given layout size. 1860 * 1861 * @param layout the layout of the region of memory to be read. 1862 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 1863 * will occur can be expressed as {@code (index * layout.byteSize())}. 1864 * @return a short value read from this segment. 1865 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1866 * {@linkplain Scope#isAlive() alive}. 1867 * @throws WrongThreadException if this method is called from a thread {@code T}, 1868 * such that {@code isAccessibleBy(T) == false}. 1869 * @throws IllegalArgumentException if the access operation is 1870 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1871 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 1872 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 1873 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 1874 */ 1875 @ForceInline 1876 default short getAtIndex(ValueLayout.OfShort layout, long index) { 1877 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 1878 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 1879 return (short) layout.varHandle().get(this, index * layout.byteSize()); 1880 } 1881 1882 /** 1883 * Writes a byte into this segment at the given index, scaled by the given layout size. 1884 * 1885 * @param layout the layout of the region of memory to be written. 1886 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 1887 * will occur can be expressed as {@code (index * layout.byteSize())}. 1888 * @param value the short value to be written. 1889 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1890 * {@linkplain Scope#isAlive() alive}. 1891 * @throws WrongThreadException if this method is called from a thread {@code T}, 1892 * such that {@code isAccessibleBy(T) == false}. 1893 * @throws IllegalArgumentException if the access operation is 1894 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1895 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 1896 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 1897 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 1898 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 1899 */ 1900 @ForceInline 1901 default void setAtIndex(ValueLayout.OfByte layout, long index, byte value) { 1902 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 1903 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 1904 layout.varHandle().set(this, index * layout.byteSize(), value); 1905 1906 } 1907 1908 /** 1909 * Writes a boolean into this segment at the given index, scaled by the given layout size. 1910 * 1911 * @param layout the layout of the region of memory to be written. 1912 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 1913 * will occur can be expressed as {@code (index * layout.byteSize())}. 1914 * @param value the short value to be written. 1915 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1916 * {@linkplain Scope#isAlive() alive}. 1917 * @throws WrongThreadException if this method is called from a thread {@code T}, 1918 * such that {@code isAccessibleBy(T) == false}. 1919 * @throws IllegalArgumentException if the access operation is 1920 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1921 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 1922 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 1923 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 1924 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 1925 */ 1926 @ForceInline 1927 default void setAtIndex(ValueLayout.OfBoolean layout, long index, boolean value) { 1928 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 1929 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 1930 layout.varHandle().set(this, index * layout.byteSize(), value); 1931 } 1932 1933 /** 1934 * Writes a short into this segment at the given index, scaled by the given layout size. 1935 * 1936 * @param layout the layout of the region of memory to be written. 1937 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 1938 * will occur can be expressed as {@code (index * layout.byteSize())}. 1939 * @param value the short value to be written. 1940 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1941 * {@linkplain Scope#isAlive() alive}. 1942 * @throws WrongThreadException if this method is called from a thread {@code T}, 1943 * such that {@code isAccessibleBy(T) == false}. 1944 * @throws IllegalArgumentException if the access operation is 1945 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1946 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 1947 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 1948 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 1949 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 1950 */ 1951 @ForceInline 1952 default void setAtIndex(ValueLayout.OfShort layout, long index, short value) { 1953 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 1954 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 1955 layout.varHandle().set(this, index * layout.byteSize(), value); 1956 } 1957 1958 /** 1959 * Reads an int from this segment at the given index, scaled by the given layout size. 1960 * 1961 * @param layout the layout of the region of memory to be read. 1962 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 1963 * will occur can be expressed as {@code (index * layout.byteSize())}. 1964 * @return an int value read from this segment. 1965 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1966 * {@linkplain Scope#isAlive() alive}. 1967 * @throws WrongThreadException if this method is called from a thread {@code T}, 1968 * such that {@code isAccessibleBy(T) == false}. 1969 * @throws IllegalArgumentException if the access operation is 1970 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1971 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 1972 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 1973 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 1974 */ 1975 @ForceInline 1976 default int getAtIndex(ValueLayout.OfInt layout, long index) { 1977 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 1978 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 1979 return (int) layout.varHandle().get(this, index * layout.byteSize()); 1980 } 1981 1982 /** 1983 * Writes an int into this segment at the given index, scaled by the given layout size. 1984 * 1985 * @param layout the layout of the region of memory to be written. 1986 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 1987 * will occur can be expressed as {@code (index * layout.byteSize())}. 1988 * @param value the int value to be written. 1989 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 1990 * {@linkplain Scope#isAlive() alive}. 1991 * @throws WrongThreadException if this method is called from a thread {@code T}, 1992 * such that {@code isAccessibleBy(T) == false}. 1993 * @throws IllegalArgumentException if the access operation is 1994 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 1995 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 1996 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 1997 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 1998 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 1999 */ 2000 @ForceInline 2001 default void setAtIndex(ValueLayout.OfInt layout, long index, int value) { 2002 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 2003 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 2004 layout.varHandle().set(this, index * layout.byteSize(), value); 2005 } 2006 2007 /** 2008 * Reads a float from this segment at the given index, scaled by the given layout size. 2009 * 2010 * @param layout the layout of the region of memory to be read. 2011 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 2012 * will occur can be expressed as {@code (index * layout.byteSize())}. 2013 * @return a float value read from this segment. 2014 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 2015 * {@linkplain Scope#isAlive() alive}. 2016 * @throws WrongThreadException if this method is called from a thread {@code T}, 2017 * such that {@code isAccessibleBy(T) == false}. 2018 * @throws IllegalArgumentException if the access operation is 2019 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 2020 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 2021 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 2022 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 2023 */ 2024 @ForceInline 2025 default float getAtIndex(ValueLayout.OfFloat layout, long index) { 2026 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 2027 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 2028 return (float) layout.varHandle().get(this, index * layout.byteSize()); 2029 } 2030 2031 /** 2032 * Writes a float into this segment at the given index, scaled by the given layout size. 2033 * 2034 * @param layout the layout of the region of memory to be written. 2035 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 2036 * will occur can be expressed as {@code (index * layout.byteSize())}. 2037 * @param value the float value to be written. 2038 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 2039 * {@linkplain Scope#isAlive() alive}. 2040 * @throws WrongThreadException if this method is called from a thread {@code T}, 2041 * such that {@code isAccessibleBy(T) == false}. 2042 * @throws IllegalArgumentException if the access operation is 2043 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 2044 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 2045 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 2046 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 2047 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 2048 */ 2049 @ForceInline 2050 default void setAtIndex(ValueLayout.OfFloat layout, long index, float value) { 2051 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 2052 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 2053 layout.varHandle().set(this, index * layout.byteSize(), value); 2054 } 2055 2056 /** 2057 * Reads a long from this segment at the given index, scaled by the given layout size. 2058 * 2059 * @param layout the layout of the region of memory to be read. 2060 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 2061 * will occur can be expressed as {@code (index * layout.byteSize())}. 2062 * @return a long value read from this segment. 2063 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 2064 * {@linkplain Scope#isAlive() alive}. 2065 * @throws WrongThreadException if this method is called from a thread {@code T}, 2066 * such that {@code isAccessibleBy(T) == false}. 2067 * @throws IllegalArgumentException if the access operation is 2068 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 2069 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 2070 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 2071 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 2072 */ 2073 @ForceInline 2074 default long getAtIndex(ValueLayout.OfLong layout, long index) { 2075 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 2076 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 2077 return (long) layout.varHandle().get(this, index * layout.byteSize()); 2078 } 2079 2080 /** 2081 * Writes a long into this segment at the given index, scaled by the given layout size. 2082 * 2083 * @param layout the layout of the region of memory to be written. 2084 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 2085 * will occur can be expressed as {@code (index * layout.byteSize())}. 2086 * @param value the long value to be written. 2087 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 2088 * {@linkplain Scope#isAlive() alive}. 2089 * @throws WrongThreadException if this method is called from a thread {@code T}, 2090 * such that {@code isAccessibleBy(T) == false}. 2091 * @throws IllegalArgumentException if the access operation is 2092 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 2093 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 2094 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 2095 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 2096 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 2097 */ 2098 @ForceInline 2099 default void setAtIndex(ValueLayout.OfLong layout, long index, long value) { 2100 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 2101 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 2102 layout.varHandle().set(this, index * layout.byteSize(), value); 2103 } 2104 2105 /** 2106 * Reads a double from this segment at the given index, scaled by the given layout size. 2107 * 2108 * @param layout the layout of the region of memory to be read. 2109 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 2110 * will occur can be expressed as {@code (index * layout.byteSize())}. 2111 * @return a double value read from this segment. 2112 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 2113 * {@linkplain Scope#isAlive() alive}. 2114 * @throws WrongThreadException if this method is called from a thread {@code T}, 2115 * such that {@code isAccessibleBy(T) == false}. 2116 * @throws IllegalArgumentException if the access operation is 2117 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 2118 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 2119 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 2120 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 2121 */ 2122 @ForceInline 2123 default double getAtIndex(ValueLayout.OfDouble layout, long index) { 2124 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 2125 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 2126 return (double) layout.varHandle().get(this, index * layout.byteSize()); 2127 } 2128 2129 /** 2130 * Writes a double into this segment at the given index, scaled by the given layout size. 2131 * 2132 * @param layout the layout of the region of memory to be written. 2133 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 2134 * will occur can be expressed as {@code (index * layout.byteSize())}. 2135 * @param value the double value to be written. 2136 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 2137 * {@linkplain Scope#isAlive() alive}. 2138 * @throws WrongThreadException if this method is called from a thread {@code T}, 2139 * such that {@code isAccessibleBy(T) == false}. 2140 * @throws IllegalArgumentException if the access operation is 2141 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 2142 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 2143 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 2144 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 2145 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 2146 */ 2147 @ForceInline 2148 default void setAtIndex(ValueLayout.OfDouble layout, long index, double value) { 2149 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 2150 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 2151 layout.varHandle().set(this, index * layout.byteSize(), value); 2152 } 2153 2154 /** 2155 * Reads an address from this segment at the given at the given index, scaled by the given layout size. The read address is wrapped in 2156 * a native segment, associated with a fresh scope that is always alive. Under normal conditions, 2157 * the size of the returned segment is {@code 0}. However, if the provided address layout has a 2158 * {@linkplain AddressLayout#targetLayout() target layout} {@code T}, then the size of the returned segment 2159 * is set to {@code T.byteSize()}. 2160 * @param layout the layout of the region of memory to be read. 2161 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 2162 * will occur can be expressed as {@code (index * layout.byteSize())}. 2163 * @return a native segment wrapping an address read from this segment. 2164 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 2165 * {@linkplain Scope#isAlive() alive}. 2166 * @throws WrongThreadException if this method is called from a thread {@code T}, 2167 * such that {@code isAccessibleBy(T) == false}. 2168 * @throws IllegalArgumentException if the access operation is 2169 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 2170 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 2171 * @throws IllegalArgumentException if provided address layout has a {@linkplain AddressLayout#targetLayout() target layout} 2172 * {@code T}, and the address of the returned segment 2173 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in {@code T}. 2174 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 2175 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 2176 */ 2177 @ForceInline 2178 default MemorySegment getAtIndex(AddressLayout layout, long index) { 2179 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 2180 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 2181 return (MemorySegment) layout.varHandle().get(this, index * layout.byteSize()); 2182 } 2183 2184 /** 2185 * Writes an address into this segment at the given index, scaled by the given layout size. 2186 * 2187 * @param layout the layout of the region of memory to be written. 2188 * @param index a logical index. The offset in bytes (relative to this segment address) at which the access operation 2189 * will occur can be expressed as {@code (index * layout.byteSize())}. 2190 * @param value the address value to be written. 2191 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with this segment is not 2192 * {@linkplain Scope#isAlive() alive}. 2193 * @throws WrongThreadException if this method is called from a thread {@code T}, 2194 * such that {@code isAccessibleBy(T) == false}. 2195 * @throws IllegalArgumentException if the access operation is 2196 * <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout. 2197 * @throws IllegalArgumentException if {@code layout.byteAlignment() > layout.byteSize()}. 2198 * @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows. 2199 * @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}. 2200 * @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}. 2201 * @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment. 2202 */ 2203 @ForceInline 2204 default void setAtIndex(AddressLayout layout, long index, MemorySegment value) { 2205 Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); 2206 // note: we know size is a small value (as it comes from ValueLayout::byteSize()) 2207 layout.varHandle().set(this, index * layout.byteSize(), value); 2208 } 2209 2210 /** 2211 * Compares the specified object with this memory segment for equality. Returns {@code true} if and only if the specified 2212 * object is also a memory segment, and if the two segments refer to the same location, in some region of memory. 2213 * More specifically, for two segments {@code s1} and {@code s2} to be considered equals, all the following must be true: 2214 * <ul> 2215 * <li>{@code s1.heapBase().equals(s2.heapBase())}, that is, the two segments must be of the same kind; 2216 * either both are {@linkplain #isNative() native segments}, backed by off-heap memory, or both are backed by 2217 * the same on-heap {@linkplain #heapBase() Java object}; 2218 * <li>{@code s1.address() == s2.address()}, that is, the address of the two segments should be the same. 2219 * This means that the two segments either refer to the same location in some off-heap region, or they refer 2220 * to the same offset inside their associated {@linkplain #heapBase() Java object}.</li> 2221 * </ul> 2222 * @apiNote This method does not perform a structural comparison of the contents of the two memory segments. Clients can 2223 * compare memory segments structurally by using the {@link #mismatch(MemorySegment)} method instead. Note that this 2224 * method does <em>not</em> compare the temporal and spatial bounds of two segments. As such it is suitable 2225 * to check whether two segments have the same address. 2226 * 2227 * @param that the object to be compared for equality with this memory segment. 2228 * @return {@code true} if the specified object is equal to this memory segment. 2229 * @see #mismatch(MemorySegment) 2230 */ 2231 @Override 2232 boolean equals(Object that); 2233 2234 /** 2235 * {@return the hash code value for this memory segment} 2236 */ 2237 @Override 2238 int hashCode(); 2239 2240 2241 /** 2242 * Copies a number of elements from a source memory segment to a destination array. The elements, whose size and alignment 2243 * constraints are specified by the given layout, are read from the source segment, starting at the given offset 2244 * (expressed in bytes), and are copied into the destination array, at the given index. 2245 * Supported array types are {@code byte[]}, {@code char[]}, {@code short[]}, {@code int[]}, {@code float[]}, {@code long[]} and {@code double[]}. 2246 * @param srcSegment the source segment. 2247 * @param srcLayout the source element layout. If the byte order associated with the layout is 2248 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 2249 * @param srcOffset the starting offset, in bytes, of the source segment. 2250 * @param dstArray the destination array. 2251 * @param dstIndex the starting index of the destination array. 2252 * @param elementCount the number of array elements to be copied. 2253 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not 2254 * {@linkplain Scope#isAlive() alive}. 2255 * @throws WrongThreadException if this method is called from a thread {@code T}, 2256 * such that {@code srcSegment.isAccessibleBy(T) == false}. 2257 * @throws IllegalArgumentException if {@code dstArray} is not an array, or if it is an array but whose type is not supported. 2258 * @throws IllegalArgumentException if the destination array component type does not match {@code srcLayout.carrier()}. 2259 * @throws IllegalArgumentException if {@code offset} is <a href="MemorySegment.html#segment-alignment">incompatible 2260 * with the alignment constraint</a> in the source element layout. 2261 * @throws IllegalArgumentException if {@code srcLayout.byteAlignment() > srcLayout.byteSize()}. 2262 * @throws IndexOutOfBoundsException if {@code elementCount * srcLayout.byteSize()} overflows. 2263 * @throws IndexOutOfBoundsException if {@code srcOffset > srcSegment.byteSize() - (elementCount * srcLayout.byteSize())}. 2264 * @throws IndexOutOfBoundsException if {@code dstIndex > dstArray.length - elementCount}. 2265 * @throws IndexOutOfBoundsException if either {@code srcOffset}, {@code dstIndex} or {@code elementCount} are {@code < 0}. 2266 */ 2267 @ForceInline 2268 static void copy( 2269 MemorySegment srcSegment, ValueLayout srcLayout, long srcOffset, 2270 Object dstArray, int dstIndex, int elementCount) { 2271 Objects.requireNonNull(srcSegment); 2272 Objects.requireNonNull(dstArray); 2273 Objects.requireNonNull(srcLayout); 2274 2275 AbstractMemorySegmentImpl.copy(srcSegment, srcLayout, srcOffset, 2276 dstArray, dstIndex, 2277 elementCount); 2278 } 2279 2280 /** 2281 * Copies a number of elements from a source array to a destination memory segment. The elements, whose size and alignment 2282 * constraints are specified by the given layout, are read from the source array, starting at the given index, 2283 * and are copied into the destination segment, at the given offset (expressed in bytes). 2284 * Supported array types are {@code byte[]}, {@code char[]}, {@code short[]}, {@code int[]}, {@code float[]}, {@code long[]} and {@code double[]}. 2285 * @param srcArray the source array. 2286 * @param srcIndex the starting index of the source array. 2287 * @param dstSegment the destination segment. 2288 * @param dstLayout the destination element layout. If the byte order associated with the layout is 2289 * different from the {@linkplain ByteOrder#nativeOrder native order}, a byte swap operation will be performed on each array element. 2290 * @param dstOffset the starting offset, in bytes, of the destination segment. 2291 * @param elementCount the number of array elements to be copied. 2292 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not 2293 * {@linkplain Scope#isAlive() alive}. 2294 * @throws WrongThreadException if this method is called from a thread {@code T}, 2295 * such that {@code dstSegment.isAccessibleBy(T) == false}. 2296 * @throws IllegalArgumentException if {@code srcArray} is not an array, or if it is an array but whose type is not supported. 2297 * @throws IllegalArgumentException if the source array component type does not match {@code srcLayout.carrier()}. 2298 * @throws IllegalArgumentException if {@code offset} is <a href="MemorySegment.html#segment-alignment">incompatible 2299 * with the alignment constraint</a> in the source element layout. 2300 * @throws IllegalArgumentException if {@code dstLayout.byteAlignment() > dstLayout.byteSize()}. 2301 * @throws UnsupportedOperationException if {@code dstSegment} is {@linkplain #isReadOnly() read-only}. 2302 * @throws IndexOutOfBoundsException if {@code elementCount * dstLayout.byteSize()} overflows. 2303 * @throws IndexOutOfBoundsException if {@code dstOffset > dstSegment.byteSize() - (elementCount * dstLayout.byteSize())}. 2304 * @throws IndexOutOfBoundsException if {@code srcIndex > srcArray.length - elementCount}. 2305 * @throws IndexOutOfBoundsException if either {@code srcIndex}, {@code dstOffset} or {@code elementCount} are {@code < 0}. 2306 */ 2307 @ForceInline 2308 static void copy( 2309 Object srcArray, int srcIndex, 2310 MemorySegment dstSegment, ValueLayout dstLayout, long dstOffset, int elementCount) { 2311 Objects.requireNonNull(srcArray); 2312 Objects.requireNonNull(dstSegment); 2313 Objects.requireNonNull(dstLayout); 2314 2315 AbstractMemorySegmentImpl.copy(srcArray, srcIndex, 2316 dstSegment, dstLayout, dstOffset, 2317 elementCount); 2318 } 2319 2320 /** 2321 * Finds and returns the relative offset, in bytes, of the first mismatch between the source and the destination 2322 * segments. More specifically, the bytes at offset {@code srcFromOffset} through {@code srcToOffset - 1} in the 2323 * source segment are compared against the bytes at offset {@code dstFromOffset} through {@code dstToOffset - 1} 2324 * in the destination segment. 2325 * <p> 2326 * If the two segments, over the specified ranges, share a common prefix then the returned offset is the length 2327 * of the common prefix, and it follows that there is a mismatch between the two segments at that relative offset 2328 * within the respective segments. If one segment is a proper prefix of the other, over the specified ranges, 2329 * then the returned offset is the smallest range, and it follows that the relative offset is only 2330 * valid for the segment with the larger range. Otherwise, there is no mismatch and {@code -1} is returned. 2331 * 2332 * @param srcSegment the source segment. 2333 * @param srcFromOffset the offset (inclusive) of the first byte in the source segment to be tested. 2334 * @param srcToOffset the offset (exclusive) of the last byte in the source segment to be tested. 2335 * @param dstSegment the destination segment. 2336 * @param dstFromOffset the offset (inclusive) of the first byte in the destination segment to be tested. 2337 * @param dstToOffset the offset (exclusive) of the last byte in the destination segment to be tested. 2338 * @return the relative offset, in bytes, of the first mismatch between the source and destination segments, 2339 * otherwise -1 if no mismatch. 2340 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code srcSegment} is not 2341 * {@linkplain Scope#isAlive() alive}. 2342 * @throws WrongThreadException if this method is called from a thread {@code T}, 2343 * such that {@code srcSegment.isAccessibleBy(T) == false}. 2344 * @throws IllegalStateException if the {@linkplain #scope() scope} associated with {@code dstSegment} is not 2345 * {@linkplain Scope#isAlive() alive}. 2346 * @throws WrongThreadException if this method is called from a thread {@code T}, 2347 * such that {@code dstSegment.isAccessibleBy(T) == false}. 2348 * @throws IndexOutOfBoundsException if {@code srcFromOffset < 0}, {@code srcToOffset < srcFromOffset} or 2349 * {@code srcToOffset > srcSegment.byteSize()} 2350 * @throws IndexOutOfBoundsException if {@code dstFromOffset < 0}, {@code dstToOffset < dstFromOffset} or 2351 * {@code dstToOffset > dstSegment.byteSize()} 2352 * 2353 * @see MemorySegment#mismatch(MemorySegment) 2354 * @see Arrays#mismatch(Object[], int, int, Object[], int, int) 2355 */ 2356 static long mismatch(MemorySegment srcSegment, long srcFromOffset, long srcToOffset, 2357 MemorySegment dstSegment, long dstFromOffset, long dstToOffset) { 2358 return AbstractMemorySegmentImpl.mismatch(srcSegment, srcFromOffset, srcToOffset, 2359 dstSegment, dstFromOffset, dstToOffset); 2360 } 2361 2362 /** 2363 * A scope models the <em>lifetime</em> of all the memory segments associated with it. That is, a memory segment 2364 * cannot be accessed if its associated scope is not {@linkplain #isAlive() alive}. A new scope is typically 2365 * obtained indirectly, by creating a new {@linkplain Arena arena}. 2366 * <p> 2367 * Scope instances can be compared for equality. That is, two scopes 2368 * are considered {@linkplain #equals(Object)} if they denote the same lifetime. 2369 */ 2370 sealed interface Scope permits MemorySessionImpl { 2371 /** 2372 * {@return {@code true}, if the regions of memory backing the memory segments associated with this scope are 2373 * still valid} 2374 */ 2375 boolean isAlive(); 2376 2377 /** 2378 * {@return {@code true}, if the provided object is also a scope, which models the same lifetime as that 2379 * modelled by this scope}. In that case, it is always the case that 2380 * {@code this.isAlive() == ((Scope)that).isAlive()}. 2381 * @param that the object to be tested. 2382 */ 2383 @Override 2384 boolean equals(Object that); 2385 2386 /** 2387 * Returns the hash code of this scope object. 2388 * @implSpec Implementations of this method obey the general contract of {@link Object#hashCode}. 2389 * @return the hash code of this scope object. 2390 * @see #equals(Object) 2391 */ 2392 @Override 2393 int hashCode(); 2394 } 2395 }