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