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 * @test
26 * @enablePreview
27 * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false -Xverify:all TestMemoryAccess
28 * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true -Xverify:all TestMemoryAccess
29 * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false -Xverify:all TestMemoryAccess
30 * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true -Xverify:all TestMemoryAccess
31 */
32
33 import java.lang.foreign.*;
34 import java.lang.foreign.MemoryLayout.PathElement;
35
36 import java.lang.invoke.VarHandle;
37 import java.nio.ByteOrder;
38 import java.util.function.Function;
39
40 import org.testng.annotations.*;
41 import static org.testng.Assert.*;
42
43 public class TestMemoryAccess {
44
45 @Test(dataProvider = "elements")
46 public void testAccess(Function<MemorySegment, MemorySegment> viewFactory, ValueLayout elemLayout, Checker checker) {
49 }
50
51 @Test(dataProvider = "elements")
52 public void testPaddedAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Checker checker) {
53 GroupLayout layout = MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.byteSize()), elemLayout.withName("elem"));
54 testAccessInternal(viewFactory, layout, layout.varHandle(PathElement.groupElement("elem")), checker);
55 }
56
57 @Test(dataProvider = "elements")
58 public void testPaddedAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Checker checker) {
59 SequenceLayout layout = MemoryLayout.sequenceLayout(2, elemLayout);
60 testAccessInternal(viewFactory, layout, layout.varHandle(PathElement.sequenceElement(1)), checker);
61 }
62
63 @Test(dataProvider = "arrayElements")
64 public void testArrayAccess(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, ArrayChecker checker) {
65 SequenceLayout seq = MemoryLayout.sequenceLayout(10, elemLayout.withName("elem"));
66 testArrayAccessInternal(viewFactory, seq, seq.varHandle(PathElement.sequenceElement()), checker);
67 }
68
69 @Test(dataProvider = "arrayElements")
70 public void testArrayAccessAlt(Function<MemorySegment, MemorySegment> viewFactory, ValueLayout elemLayout, ArrayChecker checker) {
71 SequenceLayout seq = MemoryLayout.sequenceLayout(10, elemLayout.withName("elem"));
72 testArrayAccessInternal(viewFactory, seq, elemLayout.arrayElementVarHandle(), checker);
73 }
74
75 @Test(dataProvider = "arrayElements")
76 public void testPaddedArrayAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, ArrayChecker checker) {
77 SequenceLayout seq = MemoryLayout.sequenceLayout(10, MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.byteSize()), elemLayout.withName("elem")));
78 testArrayAccessInternal(viewFactory, seq, seq.varHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("elem")), checker);
79 }
80
81 @Test(dataProvider = "arrayElements")
82 public void testPaddedArrayAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, ArrayChecker checker) {
83 SequenceLayout seq = MemoryLayout.sequenceLayout(10, MemoryLayout.sequenceLayout(2, elemLayout));
84 testArrayAccessInternal(viewFactory, seq, seq.varHandle(PathElement.sequenceElement(), MemoryLayout.PathElement.sequenceElement(1)), checker);
85 }
86
87 private void testAccessInternal(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout layout, VarHandle handle, Checker checker) {
88 MemorySegment outer_segment;
89 try (Arena arena = Arena.ofConfined()) {
90 MemorySegment segment = viewFactory.apply(arena.allocate(layout));
91 boolean isRO = segment.isReadOnly();
92 try {
93 checker.check(handle, segment);
94 if (isRO) {
141 //ok, should fail (out of bounds)
142 }
143 outer_segment = segment; //leak!
144 }
145 try {
146 checker.check(handle, outer_segment, 0);
147 throw new AssertionError(); //not ok, session is closed
148 } catch (IllegalStateException ex) {
149 //ok, should fail (session is closed)
150 }
151 }
152
153 @Test(dataProvider = "matrixElements")
154 public void testMatrixAccess(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, MatrixChecker checker) {
155 SequenceLayout seq = MemoryLayout.sequenceLayout(20,
156 MemoryLayout.sequenceLayout(10, elemLayout.withName("elem")));
157 testMatrixAccessInternal(viewFactory, seq, seq.varHandle(
158 PathElement.sequenceElement(), PathElement.sequenceElement()), checker);
159 }
160
161 @Test(dataProvider = "matrixElements")
162 public void testMatrixAccessAlt(Function<MemorySegment, MemorySegment> viewFactory, ValueLayout elemLayout, MatrixChecker checker) {
163 SequenceLayout seq = MemoryLayout.sequenceLayout(20,
164 MemoryLayout.sequenceLayout(10, elemLayout.withName("elem")));
165 testMatrixAccessInternal(viewFactory, seq, elemLayout.arrayElementVarHandle(10), checker);
166 }
167
168 @Test(dataProvider = "matrixElements")
169 public void testPaddedMatrixAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, MatrixChecker checker) {
170 SequenceLayout seq = MemoryLayout.sequenceLayout(20,
171 MemoryLayout.sequenceLayout(10, MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.byteSize()), elemLayout.withName("elem"))));
172 testMatrixAccessInternal(viewFactory, seq,
173 seq.varHandle(
174 PathElement.sequenceElement(), PathElement.sequenceElement(), PathElement.groupElement("elem")),
175 checker);
176 }
177
178 @Test(dataProvider = "matrixElements")
179 public void testPaddedMatrixAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, MatrixChecker checker) {
180 SequenceLayout seq = MemoryLayout.sequenceLayout(20,
181 MemoryLayout.sequenceLayout(10, MemoryLayout.sequenceLayout(2, elemLayout)));
182 testMatrixAccessInternal(viewFactory, seq,
183 seq.varHandle(
184 PathElement.sequenceElement(), PathElement.sequenceElement(), PathElement.sequenceElement(1)),
185 checker);
186 }
187
250 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.CHAR },
251 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.INT },
252 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.LONG },
253 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.FLOAT },
254 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.DOUBLE },
255 //LE, RO
256 { IMMUTABLE, ValueLayout.JAVA_BYTE, Checker.BYTE },
257 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.SHORT },
258 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.CHAR },
259 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.INT },
260 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.LONG },
261 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.FLOAT },
262 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.DOUBLE },
263 };
264 }
265
266 interface Checker {
267 void check(VarHandle handle, MemorySegment segment);
268
269 Checker BYTE = (handle, segment) -> {
270 handle.set(segment, (byte)42);
271 assertEquals(42, (byte)handle.get(segment));
272 };
273
274 Checker SHORT = (handle, segment) -> {
275 handle.set(segment, (short)42);
276 assertEquals(42, (short)handle.get(segment));
277 };
278
279 Checker CHAR = (handle, segment) -> {
280 handle.set(segment, (char)42);
281 assertEquals(42, (char)handle.get(segment));
282 };
283
284 Checker INT = (handle, segment) -> {
285 handle.set(segment, 42);
286 assertEquals(42, (int)handle.get(segment));
287 };
288
289 Checker LONG = (handle, segment) -> {
290 handle.set(segment, (long)42);
291 assertEquals(42, (long)handle.get(segment));
292 };
293
294 Checker FLOAT = (handle, segment) -> {
295 handle.set(segment, (float)42);
296 assertEquals((float)42, (float)handle.get(segment));
297 };
298
299 Checker DOUBLE = (handle, segment) -> {
300 handle.set(segment, (double)42);
301 assertEquals((double)42, (double)handle.get(segment));
302 };
303 }
304
305 @DataProvider(name = "arrayElements")
306 public Object[][] createArrayData() {
307 return new Object[][] {
308 //BE, RW
309 { ID, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE },
310 { ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.SHORT },
311 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.CHAR },
312 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.INT },
313 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.LONG },
314 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.FLOAT },
315 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.DOUBLE },
316 //BE, RO
317 { IMMUTABLE, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE },
318 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.SHORT },
319 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.CHAR },
320 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.INT },
321 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.LONG },
327 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.CHAR },
328 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.INT },
329 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.LONG },
330 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.FLOAT },
331 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.DOUBLE },
332 //LE, RO
333 { IMMUTABLE, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE },
334 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.SHORT },
335 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.CHAR },
336 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.INT },
337 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.LONG },
338 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.FLOAT },
339 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.DOUBLE },
340 };
341 }
342
343 interface ArrayChecker {
344 void check(VarHandle handle, MemorySegment segment, long index);
345
346 ArrayChecker BYTE = (handle, segment, i) -> {
347 handle.set(segment, i, (byte)i);
348 assertEquals(i, (byte)handle.get(segment, i));
349 };
350
351 ArrayChecker SHORT = (handle, segment, i) -> {
352 handle.set(segment, i, (short)i);
353 assertEquals(i, (short)handle.get(segment, i));
354 };
355
356 ArrayChecker CHAR = (handle, segment, i) -> {
357 handle.set(segment, i, (char)i);
358 assertEquals(i, (char)handle.get(segment, i));
359 };
360
361 ArrayChecker INT = (handle, segment, i) -> {
362 handle.set(segment, i, (int)i);
363 assertEquals(i, (int)handle.get(segment, i));
364 };
365
366 ArrayChecker LONG = (handle, segment, i) -> {
367 handle.set(segment, i, (long)i);
368 assertEquals(i, (long)handle.get(segment, i));
369 };
370
371 ArrayChecker FLOAT = (handle, segment, i) -> {
372 handle.set(segment, i, (float)i);
373 assertEquals((float)i, (float)handle.get(segment, i));
374 };
375
376 ArrayChecker DOUBLE = (handle, segment, i) -> {
377 handle.set(segment, i, (double)i);
378 assertEquals((double)i, (double)handle.get(segment, i));
379 };
380 }
381
382 @DataProvider(name = "matrixElements")
383 public Object[][] createMatrixData() {
384 return new Object[][] {
385 //BE, RW
386 { ID, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE },
387 { ID, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN },
388 { ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.SHORT },
389 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.CHAR },
390 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.INT },
391 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.LONG },
392 { ID, ValueLayout.ADDRESS.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.ADDR },
393 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.FLOAT },
394 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.DOUBLE },
395 //BE, RO
396 { IMMUTABLE, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE },
397 { IMMUTABLE, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN },
398 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.SHORT },
412 { ID, ValueLayout.ADDRESS.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.ADDR },
413 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.FLOAT },
414 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.DOUBLE },
415 //LE, RO
416 { IMMUTABLE, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE },
417 { IMMUTABLE, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN },
418 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.SHORT },
419 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.CHAR },
420 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.INT },
421 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.LONG },
422 { IMMUTABLE, ValueLayout.ADDRESS.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.ADDR },
423 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.FLOAT },
424 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.DOUBLE },
425 };
426 }
427
428 interface MatrixChecker {
429 void check(VarHandle handle, MemorySegment segment, long row, long col);
430
431 MatrixChecker BYTE = (handle, segment, r, c) -> {
432 handle.set(segment, r, c, (byte)(r + c));
433 assertEquals(r + c, (byte)handle.get(segment, r, c));
434 };
435
436 MatrixChecker BOOLEAN = (handle, segment, r, c) -> {
437 handle.set(segment, r, c, (r + c) != 0);
438 assertEquals((r + c) != 0, (boolean)handle.get(segment, r, c));
439 };
440
441 MatrixChecker SHORT = (handle, segment, r, c) -> {
442 handle.set(segment, r, c, (short)(r + c));
443 assertEquals(r + c, (short)handle.get(segment, r, c));
444 };
445
446 MatrixChecker CHAR = (handle, segment, r, c) -> {
447 handle.set(segment, r, c, (char)(r + c));
448 assertEquals(r + c, (char)handle.get(segment, r, c));
449 };
450
451 MatrixChecker INT = (handle, segment, r, c) -> {
452 handle.set(segment, r, c, (int)(r + c));
453 assertEquals(r + c, (int)handle.get(segment, r, c));
454 };
455
456 MatrixChecker LONG = (handle, segment, r, c) -> {
457 handle.set(segment, r, c, r + c);
458 assertEquals(r + c, (long)handle.get(segment, r, c));
459 };
460
461 MatrixChecker ADDR = (handle, segment, r, c) -> {
462 handle.set(segment, r, c, MemorySegment.ofAddress(r + c));
463 assertEquals(MemorySegment.ofAddress(r + c), (MemorySegment) handle.get(segment, r, c));
464 };
465
466 MatrixChecker FLOAT = (handle, segment, r, c) -> {
467 handle.set(segment, r, c, (float)(r + c));
468 assertEquals((float)(r + c), (float)handle.get(segment, r, c));
469 };
470
471 MatrixChecker DOUBLE = (handle, segment, r, c) -> {
472 handle.set(segment, r, c, (double)(r + c));
473 assertEquals((double)(r + c), (double)handle.get(segment, r, c));
474 };
475 }
476 }
|
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 * @test
26 * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false -Xverify:all TestMemoryAccess
27 * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=true -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true -Xverify:all TestMemoryAccess
28 * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=false -Xverify:all TestMemoryAccess
29 * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true -Xverify:all TestMemoryAccess
30 */
31
32 import java.lang.foreign.*;
33 import java.lang.foreign.MemoryLayout.PathElement;
34
35 import java.lang.invoke.VarHandle;
36 import java.nio.ByteOrder;
37 import java.util.function.Function;
38
39 import org.testng.annotations.*;
40 import static org.testng.Assert.*;
41
42 public class TestMemoryAccess {
43
44 @Test(dataProvider = "elements")
45 public void testAccess(Function<MemorySegment, MemorySegment> viewFactory, ValueLayout elemLayout, Checker checker) {
48 }
49
50 @Test(dataProvider = "elements")
51 public void testPaddedAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Checker checker) {
52 GroupLayout layout = MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.byteSize()), elemLayout.withName("elem"));
53 testAccessInternal(viewFactory, layout, layout.varHandle(PathElement.groupElement("elem")), checker);
54 }
55
56 @Test(dataProvider = "elements")
57 public void testPaddedAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Checker checker) {
58 SequenceLayout layout = MemoryLayout.sequenceLayout(2, elemLayout);
59 testAccessInternal(viewFactory, layout, layout.varHandle(PathElement.sequenceElement(1)), checker);
60 }
61
62 @Test(dataProvider = "arrayElements")
63 public void testArrayAccess(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, ArrayChecker checker) {
64 SequenceLayout seq = MemoryLayout.sequenceLayout(10, elemLayout.withName("elem"));
65 testArrayAccessInternal(viewFactory, seq, seq.varHandle(PathElement.sequenceElement()), checker);
66 }
67
68 @Test(dataProvider = "arrayElements")
69 public void testPaddedArrayAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, ArrayChecker checker) {
70 SequenceLayout seq = MemoryLayout.sequenceLayout(10, MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.byteSize()), elemLayout.withName("elem")));
71 testArrayAccessInternal(viewFactory, seq, seq.varHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("elem")), checker);
72 }
73
74 @Test(dataProvider = "arrayElements")
75 public void testPaddedArrayAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, ArrayChecker checker) {
76 SequenceLayout seq = MemoryLayout.sequenceLayout(10, MemoryLayout.sequenceLayout(2, elemLayout));
77 testArrayAccessInternal(viewFactory, seq, seq.varHandle(PathElement.sequenceElement(), MemoryLayout.PathElement.sequenceElement(1)), checker);
78 }
79
80 private void testAccessInternal(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout layout, VarHandle handle, Checker checker) {
81 MemorySegment outer_segment;
82 try (Arena arena = Arena.ofConfined()) {
83 MemorySegment segment = viewFactory.apply(arena.allocate(layout));
84 boolean isRO = segment.isReadOnly();
85 try {
86 checker.check(handle, segment);
87 if (isRO) {
134 //ok, should fail (out of bounds)
135 }
136 outer_segment = segment; //leak!
137 }
138 try {
139 checker.check(handle, outer_segment, 0);
140 throw new AssertionError(); //not ok, session is closed
141 } catch (IllegalStateException ex) {
142 //ok, should fail (session is closed)
143 }
144 }
145
146 @Test(dataProvider = "matrixElements")
147 public void testMatrixAccess(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, MatrixChecker checker) {
148 SequenceLayout seq = MemoryLayout.sequenceLayout(20,
149 MemoryLayout.sequenceLayout(10, elemLayout.withName("elem")));
150 testMatrixAccessInternal(viewFactory, seq, seq.varHandle(
151 PathElement.sequenceElement(), PathElement.sequenceElement()), checker);
152 }
153
154 @Test(dataProvider = "matrixElements")
155 public void testPaddedMatrixAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, MatrixChecker checker) {
156 SequenceLayout seq = MemoryLayout.sequenceLayout(20,
157 MemoryLayout.sequenceLayout(10, MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.byteSize()), elemLayout.withName("elem"))));
158 testMatrixAccessInternal(viewFactory, seq,
159 seq.varHandle(
160 PathElement.sequenceElement(), PathElement.sequenceElement(), PathElement.groupElement("elem")),
161 checker);
162 }
163
164 @Test(dataProvider = "matrixElements")
165 public void testPaddedMatrixAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, MatrixChecker checker) {
166 SequenceLayout seq = MemoryLayout.sequenceLayout(20,
167 MemoryLayout.sequenceLayout(10, MemoryLayout.sequenceLayout(2, elemLayout)));
168 testMatrixAccessInternal(viewFactory, seq,
169 seq.varHandle(
170 PathElement.sequenceElement(), PathElement.sequenceElement(), PathElement.sequenceElement(1)),
171 checker);
172 }
173
236 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.CHAR },
237 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.INT },
238 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.LONG },
239 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.FLOAT },
240 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.DOUBLE },
241 //LE, RO
242 { IMMUTABLE, ValueLayout.JAVA_BYTE, Checker.BYTE },
243 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.SHORT },
244 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.CHAR },
245 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.INT },
246 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.LONG },
247 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.FLOAT },
248 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.DOUBLE },
249 };
250 }
251
252 interface Checker {
253 void check(VarHandle handle, MemorySegment segment);
254
255 Checker BYTE = (handle, segment) -> {
256 handle.set(segment, 0L, (byte)42);
257 assertEquals(42, (byte)handle.get(segment, 0L));
258 };
259
260 Checker SHORT = (handle, segment) -> {
261 handle.set(segment, 0L, (short)42);
262 assertEquals(42, (short)handle.get(segment, 0L));
263 };
264
265 Checker CHAR = (handle, segment) -> {
266 handle.set(segment, 0L, (char)42);
267 assertEquals(42, (char)handle.get(segment, 0L));
268 };
269
270 Checker INT = (handle, segment) -> {
271 handle.set(segment, 0L, 42);
272 assertEquals(42, (int)handle.get(segment, 0L));
273 };
274
275 Checker LONG = (handle, segment) -> {
276 handle.set(segment, 0L, (long)42);
277 assertEquals(42, (long)handle.get(segment, 0L));
278 };
279
280 Checker FLOAT = (handle, segment) -> {
281 handle.set(segment, 0L, (float)42);
282 assertEquals((float)42, (float)handle.get(segment, 0L));
283 };
284
285 Checker DOUBLE = (handle, segment) -> {
286 handle.set(segment, 0L, (double)42);
287 assertEquals((double)42, (double)handle.get(segment, 0L));
288 };
289 }
290
291 @DataProvider(name = "arrayElements")
292 public Object[][] createArrayData() {
293 return new Object[][] {
294 //BE, RW
295 { ID, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE },
296 { ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.SHORT },
297 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.CHAR },
298 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.INT },
299 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.LONG },
300 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.FLOAT },
301 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.DOUBLE },
302 //BE, RO
303 { IMMUTABLE, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE },
304 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.SHORT },
305 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.CHAR },
306 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.INT },
307 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.LONG },
313 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.CHAR },
314 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.INT },
315 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.LONG },
316 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.FLOAT },
317 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.DOUBLE },
318 //LE, RO
319 { IMMUTABLE, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE },
320 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.SHORT },
321 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.CHAR },
322 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.INT },
323 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.LONG },
324 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.FLOAT },
325 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.DOUBLE },
326 };
327 }
328
329 interface ArrayChecker {
330 void check(VarHandle handle, MemorySegment segment, long index);
331
332 ArrayChecker BYTE = (handle, segment, i) -> {
333 handle.set(segment, 0L, i, (byte)i);
334 assertEquals(i, (byte)handle.get(segment, 0L, i));
335 };
336
337 ArrayChecker SHORT = (handle, segment, i) -> {
338 handle.set(segment, 0L, i, (short)i);
339 assertEquals(i, (short)handle.get(segment, 0L, i));
340 };
341
342 ArrayChecker CHAR = (handle, segment, i) -> {
343 handle.set(segment, 0L, i, (char)i);
344 assertEquals(i, (char)handle.get(segment, 0L, i));
345 };
346
347 ArrayChecker INT = (handle, segment, i) -> {
348 handle.set(segment, 0L, i, (int)i);
349 assertEquals(i, (int)handle.get(segment, 0L, i));
350 };
351
352 ArrayChecker LONG = (handle, segment, i) -> {
353 handle.set(segment, 0L, i, (long)i);
354 assertEquals(i, (long)handle.get(segment, 0L, i));
355 };
356
357 ArrayChecker FLOAT = (handle, segment, i) -> {
358 handle.set(segment, 0L, i, (float)i);
359 assertEquals((float)i, (float)handle.get(segment, 0L, i));
360 };
361
362 ArrayChecker DOUBLE = (handle, segment, i) -> {
363 handle.set(segment, 0L, i, (double)i);
364 assertEquals((double)i, (double)handle.get(segment, 0L, i));
365 };
366 }
367
368 @DataProvider(name = "matrixElements")
369 public Object[][] createMatrixData() {
370 return new Object[][] {
371 //BE, RW
372 { ID, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE },
373 { ID, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN },
374 { ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.SHORT },
375 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.CHAR },
376 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.INT },
377 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.LONG },
378 { ID, ValueLayout.ADDRESS.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.ADDR },
379 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.FLOAT },
380 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.DOUBLE },
381 //BE, RO
382 { IMMUTABLE, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE },
383 { IMMUTABLE, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN },
384 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.SHORT },
398 { ID, ValueLayout.ADDRESS.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.ADDR },
399 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.FLOAT },
400 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.DOUBLE },
401 //LE, RO
402 { IMMUTABLE, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE },
403 { IMMUTABLE, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN },
404 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.SHORT },
405 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.CHAR },
406 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.INT },
407 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.LONG },
408 { IMMUTABLE, ValueLayout.ADDRESS.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.ADDR },
409 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.FLOAT },
410 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.DOUBLE },
411 };
412 }
413
414 interface MatrixChecker {
415 void check(VarHandle handle, MemorySegment segment, long row, long col);
416
417 MatrixChecker BYTE = (handle, segment, r, c) -> {
418 handle.set(segment, 0L, r, c, (byte)(r + c));
419 assertEquals(r + c, (byte)handle.get(segment, 0L, r, c));
420 };
421
422 MatrixChecker BOOLEAN = (handle, segment, r, c) -> {
423 handle.set(segment, 0L, r, c, (r + c) != 0);
424 assertEquals((r + c) != 0, (boolean)handle.get(segment, 0L, r, c));
425 };
426
427 MatrixChecker SHORT = (handle, segment, r, c) -> {
428 handle.set(segment, 0L, r, c, (short)(r + c));
429 assertEquals(r + c, (short)handle.get(segment, 0L, r, c));
430 };
431
432 MatrixChecker CHAR = (handle, segment, r, c) -> {
433 handle.set(segment, 0L, r, c, (char)(r + c));
434 assertEquals(r + c, (char)handle.get(segment, 0L, r, c));
435 };
436
437 MatrixChecker INT = (handle, segment, r, c) -> {
438 handle.set(segment, 0L, r, c, (int)(r + c));
439 assertEquals(r + c, (int)handle.get(segment, 0L, r, c));
440 };
441
442 MatrixChecker LONG = (handle, segment, r, c) -> {
443 handle.set(segment, 0L, r, c, r + c);
444 assertEquals(r + c, (long)handle.get(segment, 0L, r, c));
445 };
446
447 MatrixChecker ADDR = (handle, segment, r, c) -> {
448 handle.set(segment, 0L, r, c, MemorySegment.ofAddress(r + c));
449 assertEquals(MemorySegment.ofAddress(r + c), (MemorySegment) handle.get(segment, 0L, r, c));
450 };
451
452 MatrixChecker FLOAT = (handle, segment, r, c) -> {
453 handle.set(segment, 0L, r, c, (float)(r + c));
454 assertEquals((float)(r + c), (float)handle.get(segment, 0L, r, c));
455 };
456
457 MatrixChecker DOUBLE = (handle, segment, r, c) -> {
458 handle.set(segment, 0L, r, c, (double)(r + c));
459 assertEquals((double)(r + c), (double)handle.get(segment, 0L, r, c));
460 };
461 }
462 }
|