< prev index next >

test/jdk/java/foreign/TestMemoryAccess.java

Print this page

 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 jdk.incubator.foreign.GroupLayout;
 33 import jdk.incubator.foreign.MemoryLayouts;
 34 import jdk.incubator.foreign.MemoryLayout;
 35 import jdk.incubator.foreign.MemoryLayout.PathElement;
 36 import jdk.incubator.foreign.MemorySegment;
 37 import jdk.incubator.foreign.ResourceScope;
 38 import jdk.incubator.foreign.SequenceLayout;
 39 import jdk.incubator.foreign.ValueLayout;
 40 
 41 import java.lang.invoke.VarHandle;

 42 import java.util.function.Function;
 43 
 44 import org.testng.annotations.*;
 45 import static org.testng.Assert.*;
 46 
 47 public class TestMemoryAccess {
 48 
 49     @Test(dataProvider = "elements")
 50     public void testAccess(Function<MemorySegment, MemorySegment> viewFactory, ValueLayout elemLayout, Class<?> carrier, Checker checker) {
 51         ValueLayout layout = elemLayout.withName("elem");
 52         testAccessInternal(viewFactory, layout, layout.varHandle(carrier), checker);
 53     }
 54 
 55     @Test(dataProvider = "elements")
 56     public void testPaddedAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, Checker checker) {
 57         GroupLayout layout = MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.bitSize()), elemLayout.withName("elem"));
 58         testAccessInternal(viewFactory, layout, layout.varHandle(carrier, PathElement.groupElement("elem")), checker);
 59     }
 60 
 61     @Test(dataProvider = "elements")
 62     public void testPaddedAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, Checker checker) {
 63         SequenceLayout layout = MemoryLayout.sequenceLayout(2, elemLayout);
 64         testAccessInternal(viewFactory, layout, layout.varHandle(carrier, PathElement.sequenceElement(1)), checker);
 65     }
 66 
 67     @Test(dataProvider = "arrayElements")
 68     public void testArrayAccess(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, ArrayChecker checker) {
 69         SequenceLayout seq = MemoryLayout.sequenceLayout(10, elemLayout.withName("elem"));
 70         testArrayAccessInternal(viewFactory, seq, seq.varHandle(carrier, PathElement.sequenceElement()), checker);
 71     }
 72 
 73     @Test(dataProvider = "arrayElements")
 74     public void testPaddedArrayAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, ArrayChecker checker) {
 75         SequenceLayout seq = MemoryLayout.sequenceLayout(10, MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.bitSize()), elemLayout.withName("elem")));
 76         testArrayAccessInternal(viewFactory, seq, seq.varHandle(carrier, MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("elem")), checker);
 77     }
 78 
 79     @Test(dataProvider = "arrayElements")
 80     public void testPaddedArrayAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, ArrayChecker checker) {
 81         SequenceLayout seq = MemoryLayout.sequenceLayout(10, MemoryLayout.sequenceLayout(2, elemLayout));
 82         testArrayAccessInternal(viewFactory, seq, seq.varHandle(carrier, PathElement.sequenceElement(), MemoryLayout.PathElement.sequenceElement(1)), checker);
 83     }
 84 
 85     private void testAccessInternal(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout layout, VarHandle handle, Checker checker) {
 86         MemorySegment outer_segment;
 87         try (ResourceScope scope = ResourceScope.newConfinedScope()) {
 88             MemorySegment segment = viewFactory.apply(MemorySegment.allocateNative(layout, scope));
 89             boolean isRO = segment.isReadOnly();
 90             try {
 91                 checker.check(handle, segment);
 92                 if (isRO) {
 93                     throw new AssertionError(); //not ok, memory should be immutable
 94                 }
 95             } catch (UnsupportedOperationException ex) {
 96                 if (!isRO) {
 97                     throw new AssertionError(); //we should not have failed!
 98                 }
 99                 return;
100             }
101             try {
102                 checker.check(handle, segment.asSlice(layout.byteSize()));

132                 }
133                 return;
134             }
135             try {
136                 checker.check(handle, segment, seq.elementCount().getAsLong());
137                 throw new AssertionError(); //not ok, out of bounds
138             } catch (IndexOutOfBoundsException ex) {
139                 //ok, should fail (out of bounds)
140             }
141             outer_segment = segment; //leak!
142         }
143         try {
144             checker.check(handle, outer_segment, 0);
145             throw new AssertionError(); //not ok, scope is closed
146         } catch (IllegalStateException ex) {
147             //ok, should fail (scope is closed)
148         }
149     }
150 
151     @Test(dataProvider = "matrixElements")
152     public void testMatrixAccess(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, MatrixChecker checker) {
153         SequenceLayout seq = MemoryLayout.sequenceLayout(20,
154                 MemoryLayout.sequenceLayout(10, elemLayout.withName("elem")));
155         testMatrixAccessInternal(viewFactory, seq, seq.varHandle(carrier,
156                 PathElement.sequenceElement(), PathElement.sequenceElement()), checker);
157     }
158 
159     @Test(dataProvider = "matrixElements")
160     public void testPaddedMatrixAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, MatrixChecker checker) {
161         SequenceLayout seq = MemoryLayout.sequenceLayout(20,
162                 MemoryLayout.sequenceLayout(10, MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.bitSize()), elemLayout.withName("elem"))));
163         testMatrixAccessInternal(viewFactory, seq,
164                 seq.varHandle(carrier,
165                         PathElement.sequenceElement(), PathElement.sequenceElement(), PathElement.groupElement("elem")),
166                 checker);
167     }
168 
169     @Test(dataProvider = "matrixElements")
170     public void testPaddedMatrixAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, MatrixChecker checker) {
171         SequenceLayout seq = MemoryLayout.sequenceLayout(20,
172                 MemoryLayout.sequenceLayout(10, MemoryLayout.sequenceLayout(2, elemLayout)));
173         testMatrixAccessInternal(viewFactory, seq,
174                 seq.varHandle(carrier,
175                         PathElement.sequenceElement(), PathElement.sequenceElement(), PathElement.sequenceElement(1)),
176                 checker);
177     }
178 
179     @Test(dataProvider = "badCarriers",
180           expectedExceptions = IllegalArgumentException.class)
181     public void testBadCarriers(Class<?> carrier) {
182         ValueLayout l = MemoryLayouts.BITS_32_LE.withName("elem");
183         l.varHandle(carrier);
184     }
185 
186     private void testMatrixAccessInternal(Function<MemorySegment, MemorySegment> viewFactory, SequenceLayout seq, VarHandle handle, MatrixChecker checker) {
187         MemorySegment outer_segment;
188         try (ResourceScope scope = ResourceScope.newConfinedScope()) {
189             MemorySegment segment = viewFactory.apply(MemorySegment.allocateNative(seq, scope));
190             boolean isRO = segment.isReadOnly();
191             try {
192                 for (int i = 0; i < seq.elementCount().getAsLong(); i++) {
193                     for (int j = 0; j < ((SequenceLayout) seq.elementLayout()).elementCount().getAsLong(); j++) {
194                         checker.check(handle, segment, i, j);
195                     }
196                 }
197                 if (isRO) {
198                     throw new AssertionError(); //not ok, memory should be immutable
199                 }
200             } catch (UnsupportedOperationException ex) {
201                 if (!isRO) {
202                     throw new AssertionError(); //we should not have failed!
203                 }
204                 return;
205             }

210             } catch (IndexOutOfBoundsException ex) {
211                 //ok, should fail (out of bounds)
212             }
213             outer_segment = segment; //leak!
214         }
215         try {
216             checker.check(handle, outer_segment, 0, 0);
217             throw new AssertionError(); //not ok, scope is closed
218         } catch (IllegalStateException ex) {
219             //ok, should fail (scope is closed)
220         }
221     }
222 
223     static Function<MemorySegment, MemorySegment> ID = Function.identity();
224     static Function<MemorySegment, MemorySegment> IMMUTABLE = MemorySegment::asReadOnly;
225 
226     @DataProvider(name = "elements")
227     public Object[][] createData() {
228         return new Object[][] {
229                 //BE, RW
230                 { ID, MemoryLayouts.BITS_8_BE, byte.class, Checker.BYTE },
231                 { ID, MemoryLayouts.BITS_16_BE, short.class, Checker.SHORT },
232                 { ID, MemoryLayouts.BITS_16_BE, char.class, Checker.CHAR },
233                 { ID, MemoryLayouts.BITS_32_BE, int.class, Checker.INT },
234                 { ID, MemoryLayouts.BITS_64_BE, long.class, Checker.LONG },
235                 { ID, MemoryLayouts.BITS_32_BE, float.class, Checker.FLOAT },
236                 { ID, MemoryLayouts.BITS_64_BE, double.class, Checker.DOUBLE },
237                 //BE, RO
238                 { IMMUTABLE, MemoryLayouts.BITS_8_BE, byte.class, Checker.BYTE },
239                 { IMMUTABLE, MemoryLayouts.BITS_16_BE, short.class, Checker.SHORT },
240                 { IMMUTABLE, MemoryLayouts.BITS_16_BE, char.class, Checker.CHAR },
241                 { IMMUTABLE, MemoryLayouts.BITS_32_BE, int.class, Checker.INT },
242                 { IMMUTABLE, MemoryLayouts.BITS_64_BE, long.class, Checker.LONG },
243                 { IMMUTABLE, MemoryLayouts.BITS_32_BE, float.class, Checker.FLOAT },
244                 { IMMUTABLE, MemoryLayouts.BITS_64_BE, double.class, Checker.DOUBLE },
245                 //LE, RW
246                 { ID, MemoryLayouts.BITS_8_LE, byte.class, Checker.BYTE },
247                 { ID, MemoryLayouts.BITS_16_LE, short.class, Checker.SHORT },
248                 { ID, MemoryLayouts.BITS_16_LE, char.class, Checker.CHAR },
249                 { ID, MemoryLayouts.BITS_32_LE, int.class, Checker.INT },
250                 { ID, MemoryLayouts.BITS_64_LE, long.class, Checker.LONG },
251                 { ID, MemoryLayouts.BITS_32_LE, float.class, Checker.FLOAT },
252                 { ID, MemoryLayouts.BITS_64_LE, double.class, Checker.DOUBLE },
253                 //LE, RO
254                 { IMMUTABLE, MemoryLayouts.BITS_8_LE, byte.class, Checker.BYTE },
255                 { IMMUTABLE, MemoryLayouts.BITS_16_LE, short.class, Checker.SHORT },
256                 { IMMUTABLE, MemoryLayouts.BITS_16_LE, char.class, Checker.CHAR },
257                 { IMMUTABLE, MemoryLayouts.BITS_32_LE, int.class, Checker.INT },
258                 { IMMUTABLE, MemoryLayouts.BITS_64_LE, long.class, Checker.LONG },
259                 { IMMUTABLE, MemoryLayouts.BITS_32_LE, float.class, Checker.FLOAT },
260                 { IMMUTABLE, MemoryLayouts.BITS_64_LE, double.class, Checker.DOUBLE },
261         };
262     }
263 
264     interface Checker {
265         void check(VarHandle handle, MemorySegment segment);
266 
267         Checker BYTE = (handle, segment) -> {
268             handle.set(segment, (byte)42);
269             assertEquals(42, (byte)handle.get(segment));
270         };
271 
272         Checker SHORT = (handle, segment) -> {
273             handle.set(segment, (short)42);
274             assertEquals(42, (short)handle.get(segment));
275         };
276 
277         Checker CHAR = (handle, segment) -> {
278             handle.set(segment, (char)42);
279             assertEquals(42, (char)handle.get(segment));
280         };

287         Checker LONG = (handle, segment) -> {
288             handle.set(segment, (long)42);
289             assertEquals(42, (long)handle.get(segment));
290         };
291 
292         Checker FLOAT = (handle, segment) -> {
293             handle.set(segment, (float)42);
294             assertEquals((float)42, (float)handle.get(segment));
295         };
296 
297         Checker DOUBLE = (handle, segment) -> {
298             handle.set(segment, (double)42);
299             assertEquals((double)42, (double)handle.get(segment));
300         };
301     }
302 
303     @DataProvider(name = "arrayElements")
304     public Object[][] createArrayData() {
305         return new Object[][] {
306                 //BE, RW
307                 { ID, MemoryLayouts.BITS_8_BE, byte.class, ArrayChecker.BYTE },
308                 { ID, MemoryLayouts.BITS_16_BE, short.class, ArrayChecker.SHORT },
309                 { ID, MemoryLayouts.BITS_16_BE, char.class, ArrayChecker.CHAR },
310                 { ID, MemoryLayouts.BITS_32_BE, int.class, ArrayChecker.INT },
311                 { ID, MemoryLayouts.BITS_64_BE, long.class, ArrayChecker.LONG },
312                 { ID, MemoryLayouts.BITS_32_BE, float.class, ArrayChecker.FLOAT },
313                 { ID, MemoryLayouts.BITS_64_BE, double.class, ArrayChecker.DOUBLE },
314                 //BE, RO
315                 { IMMUTABLE, MemoryLayouts.BITS_8_BE, byte.class, ArrayChecker.BYTE },
316                 { IMMUTABLE, MemoryLayouts.BITS_16_BE, short.class, ArrayChecker.SHORT },
317                 { IMMUTABLE, MemoryLayouts.BITS_16_BE, char.class, ArrayChecker.CHAR },
318                 { IMMUTABLE, MemoryLayouts.BITS_32_BE, int.class, ArrayChecker.INT },
319                 { IMMUTABLE, MemoryLayouts.BITS_64_BE, long.class, ArrayChecker.LONG },
320                 { IMMUTABLE, MemoryLayouts.BITS_32_BE, float.class, ArrayChecker.FLOAT },
321                 { IMMUTABLE, MemoryLayouts.BITS_64_BE, double.class, ArrayChecker.DOUBLE },
322                 //LE, RW
323                 { ID, MemoryLayouts.BITS_8_LE, byte.class, ArrayChecker.BYTE },
324                 { ID, MemoryLayouts.BITS_16_LE, short.class, ArrayChecker.SHORT },
325                 { ID, MemoryLayouts.BITS_16_LE, char.class, ArrayChecker.CHAR },
326                 { ID, MemoryLayouts.BITS_32_LE, int.class, ArrayChecker.INT },
327                 { ID, MemoryLayouts.BITS_64_LE, long.class, ArrayChecker.LONG },
328                 { ID, MemoryLayouts.BITS_32_LE, float.class, ArrayChecker.FLOAT },
329                 { ID, MemoryLayouts.BITS_64_LE, double.class, ArrayChecker.DOUBLE },
330                 //LE, RO
331                 { IMMUTABLE, MemoryLayouts.BITS_8_LE, byte.class, ArrayChecker.BYTE },
332                 { IMMUTABLE, MemoryLayouts.BITS_16_LE, short.class, ArrayChecker.SHORT },
333                 { IMMUTABLE, MemoryLayouts.BITS_16_LE, char.class, ArrayChecker.CHAR },
334                 { IMMUTABLE, MemoryLayouts.BITS_32_LE, int.class, ArrayChecker.INT },
335                 { IMMUTABLE, MemoryLayouts.BITS_64_LE, long.class, ArrayChecker.LONG },
336                 { IMMUTABLE, MemoryLayouts.BITS_32_LE, float.class, ArrayChecker.FLOAT },
337                 { IMMUTABLE, MemoryLayouts.BITS_64_LE, double.class, ArrayChecker.DOUBLE },
338         };
339     }
340 
341     interface ArrayChecker {
342         void check(VarHandle handle, MemorySegment segment, long index);
343 
344         ArrayChecker BYTE = (handle, segment, i) -> {
345             handle.set(segment, i, (byte)i);
346             assertEquals(i, (byte)handle.get(segment, i));
347         };
348 
349         ArrayChecker SHORT = (handle, segment, i) -> {
350             handle.set(segment, i, (short)i);
351             assertEquals(i, (short)handle.get(segment, i));
352         };
353 
354         ArrayChecker CHAR = (handle, segment, i) -> {
355             handle.set(segment, i, (char)i);
356             assertEquals(i, (char)handle.get(segment, i));
357         };

364         ArrayChecker LONG = (handle, segment, i) -> {
365             handle.set(segment, i, (long)i);
366             assertEquals(i, (long)handle.get(segment, i));
367         };
368 
369         ArrayChecker FLOAT = (handle, segment, i) -> {
370             handle.set(segment, i, (float)i);
371             assertEquals((float)i, (float)handle.get(segment, i));
372         };
373 
374         ArrayChecker DOUBLE = (handle, segment, i) -> {
375             handle.set(segment, i, (double)i);
376             assertEquals((double)i, (double)handle.get(segment, i));
377         };
378     }
379 
380     @DataProvider(name = "matrixElements")
381     public Object[][] createMatrixData() {
382         return new Object[][] {
383                 //BE, RW
384                 { ID, MemoryLayouts.BITS_8_BE, byte.class, MatrixChecker.BYTE },
385                 { ID, MemoryLayouts.BITS_16_BE, short.class, MatrixChecker.SHORT },
386                 { ID, MemoryLayouts.BITS_16_BE, char.class, MatrixChecker.CHAR },
387                 { ID, MemoryLayouts.BITS_32_BE, int.class, MatrixChecker.INT },
388                 { ID, MemoryLayouts.BITS_64_BE, long.class, MatrixChecker.LONG },
389                 { ID, MemoryLayouts.BITS_32_BE, float.class, MatrixChecker.FLOAT },
390                 { ID, MemoryLayouts.BITS_64_BE, double.class, MatrixChecker.DOUBLE },


391                 //BE, RO
392                 { IMMUTABLE, MemoryLayouts.BITS_8_BE, byte.class, MatrixChecker.BYTE },
393                 { IMMUTABLE, MemoryLayouts.BITS_16_BE, short.class, MatrixChecker.SHORT },
394                 { IMMUTABLE, MemoryLayouts.BITS_16_BE, char.class, MatrixChecker.CHAR },
395                 { IMMUTABLE, MemoryLayouts.BITS_32_BE, int.class, MatrixChecker.INT },
396                 { IMMUTABLE, MemoryLayouts.BITS_64_BE, long.class, MatrixChecker.LONG },
397                 { IMMUTABLE, MemoryLayouts.BITS_32_BE, float.class, MatrixChecker.FLOAT },
398                 { IMMUTABLE, MemoryLayouts.BITS_64_BE, double.class, MatrixChecker.DOUBLE },


399                 //LE, RW
400                 { ID, MemoryLayouts.BITS_8_LE, byte.class, MatrixChecker.BYTE },
401                 { ID, MemoryLayouts.BITS_16_LE, short.class, MatrixChecker.SHORT },
402                 { ID, MemoryLayouts.BITS_16_LE, char.class, MatrixChecker.CHAR },
403                 { ID, MemoryLayouts.BITS_32_LE, int.class, MatrixChecker.INT },
404                 { ID, MemoryLayouts.BITS_64_LE, long.class, MatrixChecker.LONG },
405                 { ID, MemoryLayouts.BITS_32_LE, float.class, MatrixChecker.FLOAT },
406                 { ID, MemoryLayouts.BITS_64_LE, double.class, MatrixChecker.DOUBLE },


407                 //LE, RO
408                 { IMMUTABLE, MemoryLayouts.BITS_8_LE, byte.class, MatrixChecker.BYTE },
409                 { IMMUTABLE, MemoryLayouts.BITS_16_LE, short.class, MatrixChecker.SHORT },
410                 { IMMUTABLE, MemoryLayouts.BITS_16_LE, char.class, MatrixChecker.CHAR },
411                 { IMMUTABLE, MemoryLayouts.BITS_32_LE, int.class, MatrixChecker.INT },
412                 { IMMUTABLE, MemoryLayouts.BITS_64_LE, long.class, MatrixChecker.LONG },
413                 { IMMUTABLE, MemoryLayouts.BITS_32_LE, float.class, MatrixChecker.FLOAT },
414                 { IMMUTABLE, MemoryLayouts.BITS_64_LE, double.class, MatrixChecker.DOUBLE },


415         };
416     }
417 
418     interface MatrixChecker {
419         void check(VarHandle handle, MemorySegment segment, long row, long col);
420 
421         MatrixChecker BYTE = (handle, segment, r, c) -> {
422             handle.set(segment, r, c, (byte)(r + c));
423             assertEquals(r + c, (byte)handle.get(segment, r, c));
424         };
425 





426         MatrixChecker SHORT = (handle, segment, r, c) -> {
427             handle.set(segment, r, c, (short)(r + c));
428             assertEquals(r + c, (short)handle.get(segment, r, c));
429         };
430 
431         MatrixChecker CHAR = (handle, segment, r, c) -> {
432             handle.set(segment, r, c, (char)(r + c));
433             assertEquals(r + c, (char)handle.get(segment, r, c));
434         };
435 
436         MatrixChecker INT = (handle, segment, r, c) -> {
437             handle.set(segment, r, c, (int)(r + c));
438             assertEquals(r + c, (int)handle.get(segment, r, c));
439         };
440 
441         MatrixChecker LONG = (handle, segment, r, c) -> {
442             handle.set(segment, r, c, r + c);
443             assertEquals(r + c, (long)handle.get(segment, r, c));
444         };
445 





446         MatrixChecker FLOAT = (handle, segment, r, c) -> {
447             handle.set(segment, r, c, (float)(r + c));
448             assertEquals((float)(r + c), (float)handle.get(segment, r, c));
449         };
450 
451         MatrixChecker DOUBLE = (handle, segment, r, c) -> {
452             handle.set(segment, r, c, (double)(r + c));
453             assertEquals((double)(r + c), (double)handle.get(segment, r, c));
454         };
455     }
456 
457     @DataProvider(name = "badCarriers")
458     public Object[][] createBadCarriers() {
459         return new Object[][] {
460                 { void.class },
461                 { boolean.class },
462                 { Object.class },
463                 { int[].class }
464         };
465     }
466 }

 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 jdk.incubator.foreign.GroupLayout;
 33 import jdk.incubator.foreign.MemoryAddress;
 34 import jdk.incubator.foreign.MemoryLayout;
 35 import jdk.incubator.foreign.MemoryLayout.PathElement;
 36 import jdk.incubator.foreign.MemorySegment;
 37 import jdk.incubator.foreign.ResourceScope;
 38 import jdk.incubator.foreign.SequenceLayout;
 39 import jdk.incubator.foreign.ValueLayout;
 40 
 41 import java.lang.invoke.VarHandle;
 42 import java.nio.ByteOrder;
 43 import java.util.function.Function;
 44 
 45 import org.testng.annotations.*;
 46 import static org.testng.Assert.*;
 47 
 48 public class TestMemoryAccess {
 49 
 50     @Test(dataProvider = "elements")
 51     public void testAccess(Function<MemorySegment, MemorySegment> viewFactory, ValueLayout elemLayout, Checker checker) {
 52         ValueLayout layout = elemLayout.withName("elem");
 53         testAccessInternal(viewFactory, layout, layout.varHandle(), checker);
 54     }
 55 
 56     @Test(dataProvider = "elements")
 57     public void testPaddedAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Checker checker) {
 58         GroupLayout layout = MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.bitSize()), elemLayout.withName("elem"));
 59         testAccessInternal(viewFactory, layout, layout.varHandle(PathElement.groupElement("elem")), checker);
 60     }
 61 
 62     @Test(dataProvider = "elements")
 63     public void testPaddedAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Checker checker) {
 64         SequenceLayout layout = MemoryLayout.sequenceLayout(2, elemLayout);
 65         testAccessInternal(viewFactory, layout, layout.varHandle(PathElement.sequenceElement(1)), checker);
 66     }
 67 
 68     @Test(dataProvider = "arrayElements")
 69     public void testArrayAccess(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, ArrayChecker checker) {
 70         SequenceLayout seq = MemoryLayout.sequenceLayout(10, elemLayout.withName("elem"));
 71         testArrayAccessInternal(viewFactory, seq, seq.varHandle(PathElement.sequenceElement()), checker);
 72     }
 73 
 74     @Test(dataProvider = "arrayElements")
 75     public void testPaddedArrayAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, ArrayChecker checker) {
 76         SequenceLayout seq = MemoryLayout.sequenceLayout(10, MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.bitSize()), elemLayout.withName("elem")));
 77         testArrayAccessInternal(viewFactory, seq, seq.varHandle(MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("elem")), checker);
 78     }
 79 
 80     @Test(dataProvider = "arrayElements")
 81     public void testPaddedArrayAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, ArrayChecker checker) {
 82         SequenceLayout seq = MemoryLayout.sequenceLayout(10, MemoryLayout.sequenceLayout(2, elemLayout));
 83         testArrayAccessInternal(viewFactory, seq, seq.varHandle(PathElement.sequenceElement(), MemoryLayout.PathElement.sequenceElement(1)), checker);
 84     }
 85 
 86     private void testAccessInternal(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout layout, VarHandle handle, Checker checker) {
 87         MemorySegment outer_segment;
 88         try (ResourceScope scope = ResourceScope.newConfinedScope()) {
 89             MemorySegment segment = viewFactory.apply(MemorySegment.allocateNative(layout, scope));
 90             boolean isRO = segment.isReadOnly();
 91             try {
 92                 checker.check(handle, segment);
 93                 if (isRO) {
 94                     throw new AssertionError(); //not ok, memory should be immutable
 95                 }
 96             } catch (UnsupportedOperationException ex) {
 97                 if (!isRO) {
 98                     throw new AssertionError(); //we should not have failed!
 99                 }
100                 return;
101             }
102             try {
103                 checker.check(handle, segment.asSlice(layout.byteSize()));

133                 }
134                 return;
135             }
136             try {
137                 checker.check(handle, segment, seq.elementCount().getAsLong());
138                 throw new AssertionError(); //not ok, out of bounds
139             } catch (IndexOutOfBoundsException ex) {
140                 //ok, should fail (out of bounds)
141             }
142             outer_segment = segment; //leak!
143         }
144         try {
145             checker.check(handle, outer_segment, 0);
146             throw new AssertionError(); //not ok, scope is closed
147         } catch (IllegalStateException ex) {
148             //ok, should fail (scope is closed)
149         }
150     }
151 
152     @Test(dataProvider = "matrixElements")
153     public void testMatrixAccess(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, MatrixChecker checker) {
154         SequenceLayout seq = MemoryLayout.sequenceLayout(20,
155                 MemoryLayout.sequenceLayout(10, elemLayout.withName("elem")));
156         testMatrixAccessInternal(viewFactory, seq, seq.varHandle(
157                 PathElement.sequenceElement(), PathElement.sequenceElement()), checker);
158     }
159 
160     @Test(dataProvider = "matrixElements")
161     public void testPaddedMatrixAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, MatrixChecker checker) {
162         SequenceLayout seq = MemoryLayout.sequenceLayout(20,
163                 MemoryLayout.sequenceLayout(10, MemoryLayout.structLayout(MemoryLayout.paddingLayout(elemLayout.bitSize()), elemLayout.withName("elem"))));
164         testMatrixAccessInternal(viewFactory, seq,
165                 seq.varHandle(
166                         PathElement.sequenceElement(), PathElement.sequenceElement(), PathElement.groupElement("elem")),
167                 checker);
168     }
169 
170     @Test(dataProvider = "matrixElements")
171     public void testPaddedMatrixAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, MatrixChecker checker) {
172         SequenceLayout seq = MemoryLayout.sequenceLayout(20,
173                 MemoryLayout.sequenceLayout(10, MemoryLayout.sequenceLayout(2, elemLayout)));
174         testMatrixAccessInternal(viewFactory, seq,
175                 seq.varHandle(
176                         PathElement.sequenceElement(), PathElement.sequenceElement(), PathElement.sequenceElement(1)),
177                 checker);
178     }
179 







180     private void testMatrixAccessInternal(Function<MemorySegment, MemorySegment> viewFactory, SequenceLayout seq, VarHandle handle, MatrixChecker checker) {
181         MemorySegment outer_segment;
182         try (ResourceScope scope = ResourceScope.newConfinedScope()) {
183             MemorySegment segment = viewFactory.apply(MemorySegment.allocateNative(seq, scope));
184             boolean isRO = segment.isReadOnly();
185             try {
186                 for (int i = 0; i < seq.elementCount().getAsLong(); i++) {
187                     for (int j = 0; j < ((SequenceLayout) seq.elementLayout()).elementCount().getAsLong(); j++) {
188                         checker.check(handle, segment, i, j);
189                     }
190                 }
191                 if (isRO) {
192                     throw new AssertionError(); //not ok, memory should be immutable
193                 }
194             } catch (UnsupportedOperationException ex) {
195                 if (!isRO) {
196                     throw new AssertionError(); //we should not have failed!
197                 }
198                 return;
199             }

204             } catch (IndexOutOfBoundsException ex) {
205                 //ok, should fail (out of bounds)
206             }
207             outer_segment = segment; //leak!
208         }
209         try {
210             checker.check(handle, outer_segment, 0, 0);
211             throw new AssertionError(); //not ok, scope is closed
212         } catch (IllegalStateException ex) {
213             //ok, should fail (scope is closed)
214         }
215     }
216 
217     static Function<MemorySegment, MemorySegment> ID = Function.identity();
218     static Function<MemorySegment, MemorySegment> IMMUTABLE = MemorySegment::asReadOnly;
219 
220     @DataProvider(name = "elements")
221     public Object[][] createData() {
222         return new Object[][] {
223                 //BE, RW
224                 { ID, ValueLayout.JAVA_BYTE, Checker.BYTE },
225                 { ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), Checker.SHORT },
226                 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), Checker.CHAR },
227                 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), Checker.INT },
228                 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), Checker.LONG },
229                 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), Checker.FLOAT },
230                 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), Checker.DOUBLE },
231                 //BE, RO
232                 { IMMUTABLE, ValueLayout.JAVA_BYTE, Checker.BYTE },
233                 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), Checker.SHORT },
234                 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), Checker.CHAR },
235                 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), Checker.INT },
236                 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), Checker.LONG },
237                 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), Checker.FLOAT },
238                 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), Checker.DOUBLE },
239                 //LE, RW
240                 { ID, ValueLayout.JAVA_BYTE, Checker.BYTE },
241                 { ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.SHORT },
242                 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.CHAR },
243                 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.INT },
244                 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.LONG },
245                 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.FLOAT },
246                 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.DOUBLE },
247                 //LE, RO
248                 { IMMUTABLE, ValueLayout.JAVA_BYTE, Checker.BYTE },
249                 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.SHORT },
250                 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.CHAR },
251                 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.INT },
252                 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.LONG },
253                 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.FLOAT },
254                 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.DOUBLE },
255         };
256     }
257 
258     interface Checker {
259         void check(VarHandle handle, MemorySegment segment);
260 
261         Checker BYTE = (handle, segment) -> {
262             handle.set(segment, (byte)42);
263             assertEquals(42, (byte)handle.get(segment));
264         };
265 
266         Checker SHORT = (handle, segment) -> {
267             handle.set(segment, (short)42);
268             assertEquals(42, (short)handle.get(segment));
269         };
270 
271         Checker CHAR = (handle, segment) -> {
272             handle.set(segment, (char)42);
273             assertEquals(42, (char)handle.get(segment));
274         };

281         Checker LONG = (handle, segment) -> {
282             handle.set(segment, (long)42);
283             assertEquals(42, (long)handle.get(segment));
284         };
285 
286         Checker FLOAT = (handle, segment) -> {
287             handle.set(segment, (float)42);
288             assertEquals((float)42, (float)handle.get(segment));
289         };
290 
291         Checker DOUBLE = (handle, segment) -> {
292             handle.set(segment, (double)42);
293             assertEquals((double)42, (double)handle.get(segment));
294         };
295     }
296 
297     @DataProvider(name = "arrayElements")
298     public Object[][] createArrayData() {
299         return new Object[][] {
300                 //BE, RW
301                 { ID, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE },
302                 { ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.SHORT },
303                 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.CHAR },
304                 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.INT },
305                 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.LONG },
306                 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.FLOAT },
307                 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.DOUBLE },
308                 //BE, RO
309                 { IMMUTABLE, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE },
310                 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.SHORT },
311                 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.CHAR },
312                 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.INT },
313                 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.LONG },
314                 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.FLOAT },
315                 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.DOUBLE },
316                 //LE, RW
317                 { ID, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE },
318                 { ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.SHORT },
319                 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.CHAR },
320                 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.INT },
321                 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.LONG },
322                 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.FLOAT },
323                 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.DOUBLE },
324                 //LE, RO
325                 { IMMUTABLE, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE },
326                 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.SHORT },
327                 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.CHAR },
328                 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.INT },
329                 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.LONG },
330                 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.FLOAT },
331                 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.DOUBLE },
332         };
333     }
334 
335     interface ArrayChecker {
336         void check(VarHandle handle, MemorySegment segment, long index);
337 
338         ArrayChecker BYTE = (handle, segment, i) -> {
339             handle.set(segment, i, (byte)i);
340             assertEquals(i, (byte)handle.get(segment, i));
341         };
342 
343         ArrayChecker SHORT = (handle, segment, i) -> {
344             handle.set(segment, i, (short)i);
345             assertEquals(i, (short)handle.get(segment, i));
346         };
347 
348         ArrayChecker CHAR = (handle, segment, i) -> {
349             handle.set(segment, i, (char)i);
350             assertEquals(i, (char)handle.get(segment, i));
351         };

358         ArrayChecker LONG = (handle, segment, i) -> {
359             handle.set(segment, i, (long)i);
360             assertEquals(i, (long)handle.get(segment, i));
361         };
362 
363         ArrayChecker FLOAT = (handle, segment, i) -> {
364             handle.set(segment, i, (float)i);
365             assertEquals((float)i, (float)handle.get(segment, i));
366         };
367 
368         ArrayChecker DOUBLE = (handle, segment, i) -> {
369             handle.set(segment, i, (double)i);
370             assertEquals((double)i, (double)handle.get(segment, i));
371         };
372     }
373 
374     @DataProvider(name = "matrixElements")
375     public Object[][] createMatrixData() {
376         return new Object[][] {
377                 //BE, RW
378                 { ID, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE },
379                 { ID, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN },
380                 { ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.SHORT },
381                 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.CHAR },
382                 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.INT },
383                 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.LONG },
384                 { ID, ValueLayout.ADDRESS.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.ADDR },
385                 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.FLOAT },
386                 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.DOUBLE },
387                 //BE, RO
388                 { IMMUTABLE, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE },
389                 { IMMUTABLE, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN },
390                 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.SHORT },
391                 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.CHAR },
392                 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.INT },
393                 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.LONG },
394                 { IMMUTABLE, ValueLayout.ADDRESS.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.ADDR },
395                 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.FLOAT },
396                 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.DOUBLE },
397                 //LE, RW
398                 { ID, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE },
399                 { ID, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN },
400                 { ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.SHORT },
401                 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.CHAR },
402                 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.INT },
403                 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.LONG },
404                 { ID, ValueLayout.ADDRESS.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.ADDR },
405                 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.FLOAT },
406                 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.DOUBLE },
407                 //LE, RO
408                 { IMMUTABLE, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE },
409                 { IMMUTABLE, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN },
410                 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.SHORT },
411                 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.CHAR },
412                 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.INT },
413                 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.LONG },
414                 { IMMUTABLE, ValueLayout.ADDRESS.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.ADDR },
415                 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.FLOAT },
416                 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.DOUBLE },
417         };
418     }
419 
420     interface MatrixChecker {
421         void check(VarHandle handle, MemorySegment segment, long row, long col);
422 
423         MatrixChecker BYTE = (handle, segment, r, c) -> {
424             handle.set(segment, r, c, (byte)(r + c));
425             assertEquals(r + c, (byte)handle.get(segment, r, c));
426         };
427 
428         MatrixChecker BOOLEAN = (handle, segment, r, c) -> {
429             handle.set(segment, r, c, (r + c) != 0);
430             assertEquals((r + c) != 0, (boolean)handle.get(segment, r, c));
431         };
432 
433         MatrixChecker SHORT = (handle, segment, r, c) -> {
434             handle.set(segment, r, c, (short)(r + c));
435             assertEquals(r + c, (short)handle.get(segment, r, c));
436         };
437 
438         MatrixChecker CHAR = (handle, segment, r, c) -> {
439             handle.set(segment, r, c, (char)(r + c));
440             assertEquals(r + c, (char)handle.get(segment, r, c));
441         };
442 
443         MatrixChecker INT = (handle, segment, r, c) -> {
444             handle.set(segment, r, c, (int)(r + c));
445             assertEquals(r + c, (int)handle.get(segment, r, c));
446         };
447 
448         MatrixChecker LONG = (handle, segment, r, c) -> {
449             handle.set(segment, r, c, r + c);
450             assertEquals(r + c, (long)handle.get(segment, r, c));
451         };
452 
453         MatrixChecker ADDR = (handle, segment, r, c) -> {
454             handle.set(segment, r, c, MemoryAddress.ofLong(r + c));
455             assertEquals(MemoryAddress.ofLong(r + c), (MemoryAddress)handle.get(segment, r, c));
456         };
457 
458         MatrixChecker FLOAT = (handle, segment, r, c) -> {
459             handle.set(segment, r, c, (float)(r + c));
460             assertEquals((float)(r + c), (float)handle.get(segment, r, c));
461         };
462 
463         MatrixChecker DOUBLE = (handle, segment, r, c) -> {
464             handle.set(segment, r, c, (double)(r + c));
465             assertEquals((double)(r + c), (double)handle.get(segment, r, c));
466         };
467     }










468 }
< prev index next >