1 /* 2 * Copyright (c) 2020, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 /* 26 * @test 27 * @enablePreview 28 * @modules java.base/jdk.internal.foreign 29 * @run testng/othervm TestSegmentAllocators 30 */ 31 32 import java.lang.foreign.*; 33 34 import jdk.internal.foreign.MappedMemorySegmentImpl; 35 import jdk.internal.foreign.NativeMemorySegmentImpl; 36 import org.testng.annotations.*; 37 38 import java.lang.foreign.Arena; 39 import java.lang.invoke.VarHandle; 40 import java.nio.ByteBuffer; 41 import java.nio.ByteOrder; 42 import java.nio.CharBuffer; 43 import java.nio.DoubleBuffer; 44 import java.nio.FloatBuffer; 45 import java.nio.IntBuffer; 46 import java.nio.LongBuffer; 47 import java.nio.ShortBuffer; 48 import java.util.ArrayList; 49 import java.util.List; 50 import java.util.concurrent.atomic.AtomicInteger; 51 import java.util.function.BiFunction; 52 import java.util.function.Function; 53 54 import static org.testng.Assert.*; 55 56 public class TestSegmentAllocators { 57 58 final static int ELEMS = 128; 59 60 @Test(dataProvider = "scalarAllocations") 61 @SuppressWarnings("unchecked") 62 public <Z, L extends ValueLayout> void testAllocation(Z value, AllocationFactory allocationFactory, L layout, AllocationFunction<Z, L> allocationFunction, Function<MemoryLayout, VarHandle> handleFactory) { 63 layout = (L)layout.withByteAlignment(layout.byteSize()); 64 L[] layouts = (L[])new ValueLayout[] { 65 layout, 66 layout.withByteAlignment(layout.byteAlignment() * 2), 67 layout.withByteAlignment(layout.byteAlignment() * 4), 68 layout.withByteAlignment(layout.byteAlignment() * 8) 69 }; 70 for (L alignedLayout : layouts) { 71 List<MemorySegment> addressList = new ArrayList<>(); 72 int elems = ELEMS / ((int)alignedLayout.byteAlignment() / (int)layout.byteAlignment()); 73 Arena[] arenas = { 74 Arena.ofConfined(), 75 Arena.ofShared() 76 }; 77 for (Arena arena : arenas) { 78 try (arena) { 79 SegmentAllocator allocator = allocationFactory.allocator(alignedLayout.byteSize() * ELEMS, arena); 80 for (int i = 0; i < elems; i++) { 81 MemorySegment address = allocationFunction.allocate(allocator, alignedLayout, value); 82 assertEquals(address.byteSize(), alignedLayout.byteSize()); 83 addressList.add(address); 84 VarHandle handle = handleFactory.apply(alignedLayout); 85 assertEquals(value, handle.get(address)); 86 } 87 boolean isBound = allocationFactory.isBound(); 88 try { 89 allocationFunction.allocate(allocator, alignedLayout, value); 90 assertFalse(isBound); 91 } catch (IndexOutOfBoundsException ex) { 92 //failure is expected if bound 93 assertTrue(isBound); 94 } 95 } 96 // addresses should be invalid now 97 for (MemorySegment address : addressList) { 98 assertFalse(address.scope().isAlive()); 99 } 100 } 101 } 102 } 103 104 static final int SIZE_256M = 1024 * 1024 * 256; 105 106 @Test 107 public void testBigAllocationInUnboundedSession() { 108 try (Arena arena = Arena.ofConfined()) { 109 for (int i = 8 ; i < SIZE_256M ; i *= 8) { 110 SegmentAllocator allocator = SegmentAllocator.slicingAllocator(arena.allocate(i * 2 + 1)); 111 MemorySegment address = allocator.allocate(i, i); 112 //check size 113 assertEquals(address.byteSize(), i); 114 //check alignment 115 assertEquals(address.address() % i, 0); 116 } 117 } 118 } 119 120 @Test 121 public void testTooBigForBoundedArena() { 122 try (Arena arena = Arena.ofConfined()) { 123 SegmentAllocator allocator = SegmentAllocator.slicingAllocator(arena.allocate(10)); 124 assertThrows(IndexOutOfBoundsException.class, () -> allocator.allocate(12)); 125 allocator.allocate(5); 126 } 127 } 128 129 @Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class) 130 public void testBadAllocationSize(SegmentAllocator allocator) { 131 allocator.allocate(-1); 132 } 133 134 @Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class) 135 public void testBadAllocationAlignZero(SegmentAllocator allocator) { 136 allocator.allocate(1, 0); 137 } 138 139 @Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class) 140 public void testBadAllocationAlignNeg(SegmentAllocator allocator) { 141 allocator.allocate(1, -1); 142 } 143 144 @Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class) 145 public void testBadAllocationAlignNotPowerTwo(SegmentAllocator allocator) { 146 allocator.allocate(1, 3); 147 } 148 149 @Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class) 150 public void testBadAllocationArrayNegSize(SegmentAllocator allocator) { 151 allocator.allocateArray(ValueLayout.JAVA_BYTE, -1); 152 } 153 154 @Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class) 155 public void testBadAllocationArrayOverflow(SegmentAllocator allocator) { 156 allocator.allocateArray(ValueLayout.JAVA_LONG, Long.MAX_VALUE); 157 } 158 159 @Test(expectedExceptions = OutOfMemoryError.class) 160 public void testBadArenaNullReturn() { 161 try (Arena arena = Arena.ofConfined()) { 162 arena.allocate(Long.MAX_VALUE, 2); 163 } 164 } 165 166 @Test 167 public void testArrayAllocateDelegation() { 168 AtomicInteger calls = new AtomicInteger(); 169 SegmentAllocator allocator = new SegmentAllocator() { 170 @Override 171 public MemorySegment allocate(long bytesSize, long byteAlignment) { 172 return null; 173 } 174 175 @Override 176 public MemorySegment allocateArray(MemoryLayout elementLayout, long count) { 177 calls.incrementAndGet(); 178 return null; 179 }; 180 }; 181 allocator.allocateArray(ValueLayout.JAVA_BYTE); 182 allocator.allocateArray(ValueLayout.JAVA_SHORT); 183 allocator.allocateArray(ValueLayout.JAVA_CHAR); 184 allocator.allocateArray(ValueLayout.JAVA_INT); 185 allocator.allocateArray(ValueLayout.JAVA_FLOAT); 186 allocator.allocateArray(ValueLayout.JAVA_LONG); 187 allocator.allocateArray(ValueLayout.JAVA_DOUBLE); 188 assertEquals(calls.get(), 7); 189 } 190 191 @Test 192 public void testStringAllocateDelegation() { 193 AtomicInteger calls = new AtomicInteger(); 194 SegmentAllocator allocator = new SegmentAllocator() { 195 @Override 196 197 public MemorySegment allocate(long byteSize, long byteAlignment) { 198 return Arena.ofAuto().allocate(byteSize, byteAlignment); 199 } 200 201 @Override 202 public MemorySegment allocate(long size) { 203 calls.incrementAndGet(); 204 return allocate(size, 1); 205 }; 206 }; 207 allocator.allocateUtf8String("Hello"); 208 assertEquals(calls.get(), 1); 209 } 210 211 212 @Test(dataProvider = "arrayAllocations") 213 public <Z> void testArray(AllocationFactory allocationFactory, ValueLayout layout, AllocationFunction<Object, ValueLayout> allocationFunction, ToArrayHelper<Z> arrayHelper) { 214 Z arr = arrayHelper.array(); 215 Arena[] arenas = { 216 Arena.ofConfined(), 217 Arena.ofShared() 218 }; 219 for (Arena arena : arenas) { 220 try (arena) { 221 SegmentAllocator allocator = allocationFactory.allocator(100, arena); 222 MemorySegment address = allocationFunction.allocate(allocator, layout, arr); 223 Z found = arrayHelper.toArray(address, layout); 224 assertEquals(found, arr); 225 } 226 } 227 } 228 229 @Test(dataProvider = "arrayAllocations") 230 public <Z> void testPredicatesAndCommands(AllocationFactory allocationFactory, ValueLayout layout, AllocationFunction<Object, ValueLayout> allocationFunction, ToArrayHelper<Z> arrayHelper) { 231 Z arr = arrayHelper.array(); 232 Arena[] arenas = { 233 Arena.ofConfined(), 234 Arena.ofShared() 235 }; 236 for (Arena arena : arenas) { 237 try (arena) { 238 SegmentAllocator allocator = allocationFactory.allocator(100, arena); 239 MemorySegment segment = allocationFunction.allocate(allocator, layout, arr); 240 assertThrows(UnsupportedOperationException.class, segment::load); 241 assertThrows(UnsupportedOperationException.class, segment::unload); 242 assertThrows(UnsupportedOperationException.class, segment::isLoaded); 243 assertThrows(UnsupportedOperationException.class, segment::force); 244 assertFalse(segment.isMapped()); 245 assertEquals(segment.isNative(), segment instanceof NativeMemorySegmentImpl); 246 } 247 } 248 } 249 250 @DataProvider(name = "scalarAllocations") 251 static Object[][] scalarAllocations() { 252 List<Object[]> scalarAllocations = new ArrayList<>(); 253 for (AllocationFactory factory : AllocationFactory.values()) { 254 scalarAllocations.add(new Object[] { (byte)42, factory, ValueLayout.JAVA_BYTE, 255 (AllocationFunction.OfByte) SegmentAllocator::allocate, 256 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 257 scalarAllocations.add(new Object[] { (short)42, factory, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), 258 (AllocationFunction.OfShort) SegmentAllocator::allocate, 259 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 260 scalarAllocations.add(new Object[] { (char)42, factory, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), 261 (AllocationFunction.OfChar) SegmentAllocator::allocate, 262 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 263 scalarAllocations.add(new Object[] { 42, factory, 264 ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), 265 (AllocationFunction.OfInt) SegmentAllocator::allocate, 266 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 267 scalarAllocations.add(new Object[] { 42f, factory, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), 268 (AllocationFunction.OfFloat) SegmentAllocator::allocate, 269 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 270 scalarAllocations.add(new Object[] { 42L, factory, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), 271 (AllocationFunction.OfLong) SegmentAllocator::allocate, 272 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 273 scalarAllocations.add(new Object[] { 42d, factory, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), 274 (AllocationFunction.OfDouble) SegmentAllocator::allocate, 275 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 276 scalarAllocations.add(new Object[] { MemorySegment.ofAddress(42), factory, ValueLayout.ADDRESS.withOrder(ByteOrder.BIG_ENDIAN), 277 (AllocationFunction.OfAddress) SegmentAllocator::allocate, 278 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 279 280 scalarAllocations.add(new Object[] { (short)42, factory, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), 281 (AllocationFunction.OfShort) SegmentAllocator::allocate, 282 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 283 scalarAllocations.add(new Object[] { (char)42, factory, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), 284 (AllocationFunction.OfChar) SegmentAllocator::allocate, 285 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 286 scalarAllocations.add(new Object[] { 42, factory, 287 ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), 288 (AllocationFunction.OfInt) SegmentAllocator::allocate, 289 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 290 scalarAllocations.add(new Object[] { 42f, factory, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), 291 (AllocationFunction.OfFloat) SegmentAllocator::allocate, 292 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 293 scalarAllocations.add(new Object[] { 42L, factory, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), 294 (AllocationFunction.OfLong) SegmentAllocator::allocate, 295 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 296 scalarAllocations.add(new Object[] { 42d, factory, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), 297 (AllocationFunction.OfDouble) SegmentAllocator::allocate, 298 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 299 scalarAllocations.add(new Object[] { MemorySegment.ofAddress(42), factory, ValueLayout.ADDRESS.withOrder(ByteOrder.BIG_ENDIAN), 300 (AllocationFunction.OfAddress) SegmentAllocator::allocate, 301 (Function<MemoryLayout, VarHandle>)l -> l.varHandle() }); 302 } 303 return scalarAllocations.toArray(Object[][]::new); 304 } 305 306 @DataProvider(name = "arrayAllocations") 307 static Object[][] arrayAllocations() { 308 List<Object[]> arrayAllocations = new ArrayList<>(); 309 for (AllocationFactory factory : AllocationFactory.values()) { 310 arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_BYTE, 311 (AllocationFunction.OfByteArray) SegmentAllocator::allocateArray, 312 ToArrayHelper.toByteArray }); 313 arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), 314 (AllocationFunction.OfCharArray) SegmentAllocator::allocateArray, 315 ToArrayHelper.toCharArray }); 316 arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), 317 (AllocationFunction.OfShortArray) SegmentAllocator::allocateArray, 318 ToArrayHelper.toShortArray }); 319 arrayAllocations.add(new Object[] { factory, 320 ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), 321 (AllocationFunction.OfIntArray) SegmentAllocator::allocateArray, 322 ToArrayHelper.toIntArray }); 323 arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), 324 (AllocationFunction.OfFloatArray) SegmentAllocator::allocateArray, 325 ToArrayHelper.toFloatArray }); 326 arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), 327 (AllocationFunction.OfLongArray) SegmentAllocator::allocateArray, 328 ToArrayHelper.toLongArray }); 329 arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), 330 (AllocationFunction.OfDoubleArray) SegmentAllocator::allocateArray, 331 ToArrayHelper.toDoubleArray }); 332 333 arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), 334 (AllocationFunction.OfCharArray) SegmentAllocator::allocateArray, 335 ToArrayHelper.toCharArray }); 336 arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), 337 (AllocationFunction.OfShortArray) SegmentAllocator::allocateArray, 338 ToArrayHelper.toShortArray }); 339 arrayAllocations.add(new Object[] { factory, 340 ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), 341 (AllocationFunction.OfIntArray) SegmentAllocator::allocateArray, 342 ToArrayHelper.toIntArray }); 343 arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), 344 (AllocationFunction.OfFloatArray) SegmentAllocator::allocateArray, 345 ToArrayHelper.toFloatArray }); 346 arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), 347 (AllocationFunction.OfLongArray) SegmentAllocator::allocateArray, 348 ToArrayHelper.toLongArray }); 349 arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), 350 (AllocationFunction.OfDoubleArray) SegmentAllocator::allocateArray, 351 ToArrayHelper.toDoubleArray }); 352 }; 353 return arrayAllocations.toArray(Object[][]::new); 354 } 355 356 interface AllocationFunction<X, L extends ValueLayout> { 357 MemorySegment allocate(SegmentAllocator allocator, L layout, X value); 358 359 interface OfByte extends AllocationFunction<Byte, ValueLayout.OfByte> { } 360 interface OfBoolean extends AllocationFunction<Boolean, ValueLayout.OfBoolean> { } 361 interface OfChar extends AllocationFunction<Character, ValueLayout.OfChar> { } 362 interface OfShort extends AllocationFunction<Short, ValueLayout.OfShort> { } 363 interface OfInt extends AllocationFunction<Integer, ValueLayout.OfInt> { } 364 interface OfFloat extends AllocationFunction<Float, ValueLayout.OfFloat> { } 365 interface OfLong extends AllocationFunction<Long, ValueLayout.OfLong> { } 366 interface OfDouble extends AllocationFunction<Double, ValueLayout.OfDouble> { } 367 interface OfAddress extends AllocationFunction<MemorySegment, AddressLayout> { } 368 369 interface OfByteArray extends AllocationFunction<byte[], ValueLayout.OfByte> { } 370 interface OfCharArray extends AllocationFunction<char[], ValueLayout.OfChar> { } 371 interface OfShortArray extends AllocationFunction<short[], ValueLayout.OfShort> { } 372 interface OfIntArray extends AllocationFunction<int[], ValueLayout.OfInt> { } 373 interface OfFloatArray extends AllocationFunction<float[], ValueLayout.OfFloat> { } 374 interface OfLongArray extends AllocationFunction<long[], ValueLayout.OfLong> { } 375 interface OfDoubleArray extends AllocationFunction<double[], ValueLayout.OfDouble> { } 376 } 377 378 enum AllocationFactory { 379 SLICING(true, (size, arena) -> { 380 return SegmentAllocator.slicingAllocator(arena.allocate(size, 1)); 381 }); 382 383 private final boolean isBound; 384 private final BiFunction<Long, Arena, SegmentAllocator> factory; 385 386 AllocationFactory(boolean isBound, BiFunction<Long, Arena, SegmentAllocator> factory) { 387 this.isBound = isBound; 388 this.factory = factory; 389 } 390 391 SegmentAllocator allocator(long size, Arena arena) { 392 return factory.apply(size, arena); 393 } 394 395 public boolean isBound() { 396 return isBound; 397 } 398 } 399 400 interface ToArrayHelper<T> { 401 T array(); 402 T toArray(MemorySegment segment, ValueLayout layout); 403 404 ToArrayHelper<byte[]> toByteArray = new ToArrayHelper<>() { 405 @Override 406 public byte[] array() { 407 return new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 408 } 409 410 @Override 411 public byte[] toArray(MemorySegment segment, ValueLayout layout) { 412 ByteBuffer buffer = segment.asByteBuffer().order(layout.order()); 413 byte[] found = new byte[buffer.limit()]; 414 buffer.get(found); 415 return found; 416 } 417 }; 418 419 ToArrayHelper<char[]> toCharArray = new ToArrayHelper<>() { 420 @Override 421 public char[] array() { 422 return new char[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 423 } 424 425 @Override 426 public char[] toArray(MemorySegment segment, ValueLayout layout) { 427 CharBuffer buffer = segment.asByteBuffer().order(layout.order()).asCharBuffer(); 428 char[] found = new char[buffer.limit()]; 429 buffer.get(found); 430 return found; 431 } 432 }; 433 434 ToArrayHelper<short[]> toShortArray = new ToArrayHelper<>() { 435 @Override 436 public short[] array() { 437 return new short[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 438 } 439 440 @Override 441 public short[] toArray(MemorySegment segment, ValueLayout layout) { 442 ShortBuffer buffer = segment.asByteBuffer().order(layout.order()).asShortBuffer(); 443 short[] found = new short[buffer.limit()]; 444 buffer.get(found); 445 return found; 446 } 447 }; 448 449 ToArrayHelper<int[]> toIntArray = new ToArrayHelper<>() { 450 @Override 451 public int[] array() { 452 return new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 453 } 454 455 @Override 456 public int[] toArray(MemorySegment segment, ValueLayout layout) { 457 IntBuffer buffer = segment.asByteBuffer().order(layout.order()).asIntBuffer(); 458 int[] found = new int[buffer.limit()]; 459 buffer.get(found); 460 return found; 461 } 462 }; 463 464 ToArrayHelper<float[]> toFloatArray = new ToArrayHelper<>() { 465 @Override 466 public float[] array() { 467 return new float[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 468 } 469 470 @Override 471 public float[] toArray(MemorySegment segment, ValueLayout layout) { 472 FloatBuffer buffer = segment.asByteBuffer().order(layout.order()).asFloatBuffer(); 473 float[] found = new float[buffer.limit()]; 474 buffer.get(found); 475 return found; 476 } 477 }; 478 479 ToArrayHelper<long[]> toLongArray = new ToArrayHelper<>() { 480 @Override 481 public long[] array() { 482 return new long[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 483 } 484 485 @Override 486 public long[] toArray(MemorySegment segment, ValueLayout layout) { 487 LongBuffer buffer = segment.asByteBuffer().order(layout.order()).asLongBuffer(); 488 long[] found = new long[buffer.limit()]; 489 buffer.get(found); 490 return found; 491 } 492 }; 493 494 ToArrayHelper<double[]> toDoubleArray = new ToArrayHelper<>() { 495 @Override 496 public double[] array() { 497 return new double[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 498 } 499 500 @Override 501 public double[] toArray(MemorySegment segment, ValueLayout layout) { 502 DoubleBuffer buffer = segment.asByteBuffer().order(layout.order()).asDoubleBuffer(); 503 double[] found = new double[buffer.limit()]; 504 buffer.get(found); 505 return found; 506 } 507 }; 508 } 509 510 @DataProvider(name = "allocators") 511 static Object[][] allocators() { 512 return new Object[][] { 513 { SegmentAllocator.prefixAllocator(Arena.global().allocate(10, 1)) }, 514 }; 515 } 516 }