1 /* 2 * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @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) { 46 ValueLayout layout = elemLayout.withName("elem"); 47 testAccessInternal(viewFactory, layout, layout.varHandle(), 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) { 88 throw new AssertionError(); //not ok, memory should be immutable 89 } 90 } catch (UnsupportedOperationException ex) { 91 if (!isRO) { 92 throw new AssertionError(); //we should not have failed! 93 } 94 return; 95 } 96 try { 97 checker.check(handle, segment.asSlice(layout.byteSize())); 98 throw new AssertionError(); //not ok, out of bounds 99 } catch (IndexOutOfBoundsException ex) { 100 //ok, should fail (out of bounds) 101 } 102 outer_segment = segment; //leak! 103 } 104 try { 105 checker.check(handle, outer_segment); 106 throw new AssertionError(); //not ok, session is closed 107 } catch (IllegalStateException ex) { 108 //ok, should fail (session is closed) 109 } 110 } 111 112 private void testArrayAccessInternal(Function<MemorySegment, MemorySegment> viewFactory, SequenceLayout seq, VarHandle handle, ArrayChecker checker) { 113 MemorySegment outer_segment; 114 try (Arena arena = Arena.ofConfined()) { 115 MemorySegment segment = viewFactory.apply(arena.allocate(seq)); 116 boolean isRO = segment.isReadOnly(); 117 try { 118 for (int i = 0; i < seq.elementCount(); i++) { 119 checker.check(handle, segment, i); 120 } 121 if (isRO) { 122 throw new AssertionError(); //not ok, memory should be immutable 123 } 124 } catch (UnsupportedOperationException ex) { 125 if (!isRO) { 126 throw new AssertionError(); //we should not have failed! 127 } 128 return; 129 } 130 try { 131 checker.check(handle, segment, seq.elementCount()); 132 throw new AssertionError(); //not ok, out of bounds 133 } catch (IndexOutOfBoundsException ex) { 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 174 private void testMatrixAccessInternal(Function<MemorySegment, MemorySegment> viewFactory, SequenceLayout seq, VarHandle handle, MatrixChecker checker) { 175 MemorySegment outer_segment; 176 try (Arena arena = Arena.ofConfined()) { 177 MemorySegment segment = viewFactory.apply(arena.allocate(seq)); 178 boolean isRO = segment.isReadOnly(); 179 try { 180 for (int i = 0; i < seq.elementCount(); i++) { 181 for (int j = 0; j < ((SequenceLayout) seq.elementLayout()).elementCount(); j++) { 182 checker.check(handle, segment, i, j); 183 } 184 } 185 if (isRO) { 186 throw new AssertionError(); //not ok, memory should be immutable 187 } 188 } catch (UnsupportedOperationException ex) { 189 if (!isRO) { 190 throw new AssertionError(); //we should not have failed! 191 } 192 return; 193 } 194 try { 195 checker.check(handle, segment, seq.elementCount(), 196 ((SequenceLayout)seq.elementLayout()).elementCount()); 197 throw new AssertionError(); //not ok, out of bounds 198 } catch (IndexOutOfBoundsException ex) { 199 //ok, should fail (out of bounds) 200 } 201 outer_segment = segment; //leak! 202 } 203 try { 204 checker.check(handle, outer_segment, 0, 0); 205 throw new AssertionError(); //not ok, session is closed 206 } catch (IllegalStateException ex) { 207 //ok, should fail (session is closed) 208 } 209 } 210 211 static Function<MemorySegment, MemorySegment> ID = Function.identity(); 212 static Function<MemorySegment, MemorySegment> IMMUTABLE = MemorySegment::asReadOnly; 213 214 @DataProvider(name = "elements") 215 public Object[][] createData() { 216 return new Object[][] { 217 //BE, RW 218 { ID, ValueLayout.JAVA_BYTE, Checker.BYTE }, 219 { ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), Checker.SHORT }, 220 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), Checker.CHAR }, 221 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), Checker.INT }, 222 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), Checker.LONG }, 223 { ID, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), Checker.FLOAT }, 224 { ID, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), Checker.DOUBLE }, 225 //BE, RO 226 { IMMUTABLE, ValueLayout.JAVA_BYTE, Checker.BYTE }, 227 { IMMUTABLE, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.BIG_ENDIAN), Checker.SHORT }, 228 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), Checker.CHAR }, 229 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), Checker.INT }, 230 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), Checker.LONG }, 231 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), Checker.FLOAT }, 232 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), Checker.DOUBLE }, 233 //LE, RW 234 { ID, ValueLayout.JAVA_BYTE, Checker.BYTE }, 235 { ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), Checker.SHORT }, 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 }, 308 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.FLOAT }, 309 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), ArrayChecker.DOUBLE }, 310 //LE, RW 311 { ID, ValueLayout.JAVA_BYTE, ArrayChecker.BYTE }, 312 { ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), ArrayChecker.SHORT }, 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 }, 385 { IMMUTABLE, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.CHAR }, 386 { IMMUTABLE, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.INT }, 387 { IMMUTABLE, ValueLayout.JAVA_LONG.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.LONG }, 388 { IMMUTABLE, ValueLayout.ADDRESS.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.ADDR }, 389 { IMMUTABLE, ValueLayout.JAVA_FLOAT.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.FLOAT }, 390 { IMMUTABLE, ValueLayout.JAVA_DOUBLE.withOrder(ByteOrder.BIG_ENDIAN), MatrixChecker.DOUBLE }, 391 //LE, RW 392 { ID, ValueLayout.JAVA_BYTE, MatrixChecker.BYTE }, 393 { ID, ValueLayout.JAVA_BOOLEAN, MatrixChecker.BOOLEAN }, 394 { ID, ValueLayout.JAVA_SHORT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.SHORT }, 395 { ID, ValueLayout.JAVA_CHAR.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.CHAR }, 396 { ID, ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.INT }, 397 { ID, ValueLayout.JAVA_LONG.withOrder(ByteOrder.LITTLE_ENDIAN), MatrixChecker.LONG }, 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 }