< prev index next >

test/jdk/java/foreign/TestSegmentAllocators.java

Print this page

  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.*;

 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 

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     }

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> { }

  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  * @modules java.base/jdk.internal.foreign
 28  * @run testng/othervm TestSegmentAllocators
 29  */
 30 
 31 import java.lang.foreign.*;
 32 

 33 import jdk.internal.foreign.NativeMemorySegmentImpl;
 34 import org.testng.annotations.*;
 35 
 36 import java.lang.foreign.Arena;
 37 import java.lang.invoke.VarHandle;
 38 import java.nio.ByteBuffer;
 39 import java.nio.ByteOrder;
 40 import java.nio.CharBuffer;
 41 import java.nio.DoubleBuffer;
 42 import java.nio.FloatBuffer;
 43 import java.nio.IntBuffer;
 44 import java.nio.LongBuffer;
 45 import java.nio.ShortBuffer;
 46 import java.util.ArrayList;
 47 import java.util.List;
 48 import java.util.concurrent.atomic.AtomicInteger;
 49 import java.util.function.BiFunction;
 50 import java.util.function.Function;
 51 
 52 import static org.testng.Assert.*;

 63                 layout,
 64                 layout.withByteAlignment(layout.byteAlignment() * 2),
 65                 layout.withByteAlignment(layout.byteAlignment() * 4),
 66                 layout.withByteAlignment(layout.byteAlignment() * 8)
 67         };
 68         for (L alignedLayout : layouts) {
 69             List<MemorySegment> addressList = new ArrayList<>();
 70             int elems = ELEMS / ((int)alignedLayout.byteAlignment() / (int)layout.byteAlignment());
 71             Arena[] arenas = {
 72                     Arena.ofConfined(),
 73                     Arena.ofShared()
 74             };
 75             for (Arena arena : arenas) {
 76                 try (arena) {
 77                     SegmentAllocator allocator = allocationFactory.allocator(alignedLayout.byteSize() * ELEMS, arena);
 78                     for (int i = 0; i < elems; i++) {
 79                         MemorySegment address = allocationFunction.allocate(allocator, alignedLayout, value);
 80                         assertEquals(address.byteSize(), alignedLayout.byteSize());
 81                         addressList.add(address);
 82                         VarHandle handle = handleFactory.apply(alignedLayout);
 83                         assertEquals(value, handle.get(address, 0L));
 84                     }
 85                     boolean isBound = allocationFactory.isBound();
 86                     try {
 87                         allocationFunction.allocate(allocator, alignedLayout, value);
 88                         assertFalse(isBound);
 89                     } catch (IndexOutOfBoundsException ex) {
 90                         //failure is expected if bound
 91                         assertTrue(isBound);
 92                     }
 93                 }
 94                 // addresses should be invalid now
 95                 for (MemorySegment address : addressList) {
 96                     assertFalse(address.scope().isAlive());
 97                 }
 98             }
 99         }
100     }
101 
102     static final int SIZE_256M = 1024 * 1024 * 256;
103 

129         allocator.allocate(-1);
130     }
131 
132     @Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class)
133     public void testBadAllocationAlignZero(SegmentAllocator allocator) {
134         allocator.allocate(1, 0);
135     }
136 
137     @Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class)
138     public void testBadAllocationAlignNeg(SegmentAllocator allocator) {
139         allocator.allocate(1, -1);
140     }
141 
142     @Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class)
143     public void testBadAllocationAlignNotPowerTwo(SegmentAllocator allocator) {
144         allocator.allocate(1, 3);
145     }
146 
147     @Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class)
148     public void testBadAllocationArrayNegSize(SegmentAllocator allocator) {
149         allocator.allocate(ValueLayout.JAVA_BYTE, -1);
150     }
151 
152     @Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class)
153     public void testBadAllocationArrayOverflow(SegmentAllocator allocator) {
154         allocator.allocate(ValueLayout.JAVA_LONG,  Long.MAX_VALUE);
155     }
156 
157     @Test(expectedExceptions = OutOfMemoryError.class)
158     public void testBadArenaNullReturn() {
159         try (Arena arena = Arena.ofConfined()) {
160             arena.allocate(Long.MAX_VALUE, 2);
161         }
162     }
163 
164     @Test
165     public void testArrayAllocateDelegation() {
166         AtomicInteger calls = new AtomicInteger();
167         SegmentAllocator allocator = new SegmentAllocator() {
168             @Override
169             public MemorySegment allocate(long bytesSize, long byteAlignment) {
170                 return MemorySegment.NULL;
171             }
172 
173             @Override
174             public MemorySegment allocateFrom(ValueLayout elementLayout, MemorySegment source, ValueLayout sourceElementLayout, long sourceOffset, long elementCount) {
175                 calls.incrementAndGet();
176                 return MemorySegment.NULL;
177             }
178         };
179         allocator.allocateFrom(ValueLayout.JAVA_BYTE);
180         allocator.allocateFrom(ValueLayout.JAVA_SHORT);
181         allocator.allocateFrom(ValueLayout.JAVA_CHAR);
182         allocator.allocateFrom(ValueLayout.JAVA_INT);
183         allocator.allocateFrom(ValueLayout.JAVA_FLOAT);
184         allocator.allocateFrom(ValueLayout.JAVA_LONG);
185         allocator.allocateFrom(ValueLayout.JAVA_DOUBLE);
186         assertEquals(calls.get(), 7);
187     }
188 
189     @Test
190     public void testStringAllocateDelegation() {
191         AtomicInteger calls = new AtomicInteger();
192         SegmentAllocator allocator = new SegmentAllocator() {
193             @Override

194             public MemorySegment allocate(long byteSize, long byteAlignment) {
195                 return Arena.ofAuto().allocate(byteSize, byteAlignment);
196             }
197 
198             @Override
199             public MemorySegment allocate(long size) {
200                 calls.incrementAndGet();
201                 return allocate(size, 1);
202             };
203         };
204         allocator.allocateFrom("Hello");
205         assertEquals(calls.get(), 1);
206     }
207 
208 
209     @Test(dataProvider = "arrayAllocations")
210     public <Z> void testArray(AllocationFactory allocationFactory, ValueLayout layout, AllocationFunction<Object, ValueLayout> allocationFunction, ToArrayHelper<Z> arrayHelper) {
211         Z arr = arrayHelper.array();
212         Arena[] arenas = {
213                 Arena.ofConfined(),
214                 Arena.ofShared()
215         };
216         for (Arena arena : arenas) {
217             try (arena) {
218                 SegmentAllocator allocator = allocationFactory.allocator(100, arena);
219                 MemorySegment address = allocationFunction.allocate(allocator, layout, arr);
220                 Z found = arrayHelper.toArray(address, layout);
221                 assertEquals(found, arr);
222             }
223         }
224     }

232         };
233         for (Arena arena : arenas) {
234             try (arena) {
235                 SegmentAllocator allocator = allocationFactory.allocator(100, arena);
236                 MemorySegment segment = allocationFunction.allocate(allocator, layout, arr);
237                 assertThrows(UnsupportedOperationException.class, segment::load);
238                 assertThrows(UnsupportedOperationException.class, segment::unload);
239                 assertThrows(UnsupportedOperationException.class, segment::isLoaded);
240                 assertThrows(UnsupportedOperationException.class, segment::force);
241                 assertFalse(segment.isMapped());
242                 assertEquals(segment.isNative(), segment instanceof NativeMemorySegmentImpl);
243             }
244         }
245     }
246 
247     @DataProvider(name = "scalarAllocations")
248     static Object[][] scalarAllocations() {
249         List<Object[]> scalarAllocations = new ArrayList<>();
250         for (AllocationFactory factory : AllocationFactory.values()) {
251             scalarAllocations.add(new Object[] { (byte)42, factory, ValueLayout.JAVA_BYTE,
252                     (AllocationFunction.OfByte) SegmentAllocator::allocateFrom,
253                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
254             scalarAllocations.add(new Object[] { (short)42, factory, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN),
255                     (AllocationFunction.OfShort) SegmentAllocator::allocateFrom,
256                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
257             scalarAllocations.add(new Object[] { (char)42, factory, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN),
258                     (AllocationFunction.OfChar) SegmentAllocator::allocateFrom,
259                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
260             scalarAllocations.add(new Object[] { 42, factory,
261                     ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN),
262                     (AllocationFunction.OfInt) SegmentAllocator::allocateFrom,
263                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
264             scalarAllocations.add(new Object[] { 42f, factory, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN),
265                     (AllocationFunction.OfFloat) SegmentAllocator::allocateFrom,
266                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
267             scalarAllocations.add(new Object[] { 42L, factory, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN),
268                     (AllocationFunction.OfLong) SegmentAllocator::allocateFrom,
269                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
270             scalarAllocations.add(new Object[] { 42d, factory, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN),
271                     (AllocationFunction.OfDouble) SegmentAllocator::allocateFrom,
272                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
273             scalarAllocations.add(new Object[] { MemorySegment.ofAddress(42), factory, ValueLayout.ADDRESS.withOrder(ByteOrder.BIG_ENDIAN),
274                     (AllocationFunction.OfAddress) SegmentAllocator::allocateFrom,
275                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
276 
277             scalarAllocations.add(new Object[] { (short)42, factory, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN),
278                     (AllocationFunction.OfShort) SegmentAllocator::allocateFrom,
279                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
280             scalarAllocations.add(new Object[] { (char)42, factory, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN),
281                     (AllocationFunction.OfChar) SegmentAllocator::allocateFrom,
282                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
283             scalarAllocations.add(new Object[] { 42, factory,
284                     ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN),
285                     (AllocationFunction.OfInt) SegmentAllocator::allocateFrom,
286                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
287             scalarAllocations.add(new Object[] { 42f, factory, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN),
288                     (AllocationFunction.OfFloat) SegmentAllocator::allocateFrom,
289                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
290             scalarAllocations.add(new Object[] { 42L, factory, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN),
291                     (AllocationFunction.OfLong) SegmentAllocator::allocateFrom,
292                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
293             scalarAllocations.add(new Object[] { 42d, factory, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN),
294                     (AllocationFunction.OfDouble) SegmentAllocator::allocateFrom,
295                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
296             scalarAllocations.add(new Object[] { MemorySegment.ofAddress(42), factory, ValueLayout.ADDRESS.withOrder(ByteOrder.BIG_ENDIAN),
297                     (AllocationFunction.OfAddress) SegmentAllocator::allocateFrom,
298                     (Function<MemoryLayout, VarHandle>)l -> l.varHandle() });
299         }
300         return scalarAllocations.toArray(Object[][]::new);
301     }
302 
303     @DataProvider(name = "arrayAllocations")
304     static Object[][] arrayAllocations() {
305         List<Object[]> arrayAllocations = new ArrayList<>();
306         for (AllocationFactory factory : AllocationFactory.values()) {
307             arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_BYTE,
308                     (AllocationFunction.OfByteArray) SegmentAllocator::allocateFrom,
309                     ToArrayHelper.toByteArray });
310             arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN),
311                     (AllocationFunction.OfCharArray) SegmentAllocator::allocateFrom,
312                     ToArrayHelper.toCharArray });
313             arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN),
314                     (AllocationFunction.OfShortArray) SegmentAllocator::allocateFrom,
315                     ToArrayHelper.toShortArray });
316             arrayAllocations.add(new Object[] { factory,
317                     ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN),
318                     (AllocationFunction.OfIntArray) SegmentAllocator::allocateFrom,
319                     ToArrayHelper.toIntArray });
320             arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN),
321                     (AllocationFunction.OfFloatArray) SegmentAllocator::allocateFrom,
322                     ToArrayHelper.toFloatArray });
323             arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN),
324                     (AllocationFunction.OfLongArray) SegmentAllocator::allocateFrom,
325                     ToArrayHelper.toLongArray });
326             arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN),
327                     (AllocationFunction.OfDoubleArray) SegmentAllocator::allocateFrom,
328                     ToArrayHelper.toDoubleArray });
329 
330             arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN),
331                     (AllocationFunction.OfCharArray) SegmentAllocator::allocateFrom,
332                     ToArrayHelper.toCharArray });
333             arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN),
334                     (AllocationFunction.OfShortArray) SegmentAllocator::allocateFrom,
335                     ToArrayHelper.toShortArray });
336             arrayAllocations.add(new Object[] { factory,
337                     ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN),
338                     (AllocationFunction.OfIntArray) SegmentAllocator::allocateFrom,
339                     ToArrayHelper.toIntArray });
340             arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN),
341                     (AllocationFunction.OfFloatArray) SegmentAllocator::allocateFrom,
342                     ToArrayHelper.toFloatArray });
343             arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN),
344                     (AllocationFunction.OfLongArray) SegmentAllocator::allocateFrom,
345                     ToArrayHelper.toLongArray });
346             arrayAllocations.add(new Object[] { factory, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN),
347                     (AllocationFunction.OfDoubleArray) SegmentAllocator::allocateFrom,
348                     ToArrayHelper.toDoubleArray });
349         };
350         return arrayAllocations.toArray(Object[][]::new);
351     }
352 
353     interface AllocationFunction<X, L extends ValueLayout> {
354         MemorySegment allocate(SegmentAllocator allocator, L layout, X value);
355 
356         interface OfByte extends AllocationFunction<Byte, ValueLayout.OfByte> { }
357         interface OfBoolean extends AllocationFunction<Boolean, ValueLayout.OfBoolean> { }
358         interface OfChar extends AllocationFunction<Character, ValueLayout.OfChar> { }
359         interface OfShort extends AllocationFunction<Short, ValueLayout.OfShort> { }
360         interface OfInt extends AllocationFunction<Integer, ValueLayout.OfInt> { }
361         interface OfFloat extends AllocationFunction<Float, ValueLayout.OfFloat> { }
362         interface OfLong extends AllocationFunction<Long, ValueLayout.OfLong> { }
363         interface OfDouble extends AllocationFunction<Double, ValueLayout.OfDouble> { }
364         interface OfAddress extends AllocationFunction<MemorySegment, AddressLayout> { }
365 
366         interface OfByteArray extends AllocationFunction<byte[], ValueLayout.OfByte> { }
367         interface OfCharArray extends AllocationFunction<char[], ValueLayout.OfChar> { }
< prev index next >