1 /* 2 * Copyright (c) 2019, 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 -Xverify:all TestMemoryAccess 27 */ 28 29 import jdk.incubator.foreign.GroupLayout; 30 import jdk.incubator.foreign.MemoryLayouts; 31 import jdk.incubator.foreign.MemoryLayout; 32 import jdk.incubator.foreign.MemoryLayout.PathElement; 33 import jdk.incubator.foreign.MemorySegment; 34 import jdk.incubator.foreign.SequenceLayout; 35 import jdk.incubator.foreign.ValueLayout; 36 import jdk.incubator.foreign.MemoryAddress; 37 import java.lang.invoke.VarHandle; 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, Class<?> carrier, Checker checker) { 47 ValueLayout layout = elemLayout.withName("elem"); 48 testAccessInternal(viewFactory, layout, layout.varHandle(carrier), checker); 49 } 50 51 @Test(dataProvider = "elements") 52 public void testPaddedAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, Checker checker) { 53 GroupLayout layout = MemoryLayout.ofStruct(MemoryLayout.ofPaddingBits(elemLayout.bitSize()), elemLayout.withName("elem")); 54 testAccessInternal(viewFactory, layout, layout.varHandle(carrier, PathElement.groupElement("elem")), checker); 55 } 56 57 @Test(dataProvider = "elements") 58 public void testPaddedAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, Checker checker) { 59 SequenceLayout layout = MemoryLayout.ofSequence(2, elemLayout); 60 testAccessInternal(viewFactory, layout, layout.varHandle(carrier, PathElement.sequenceElement(1)), checker); 61 } 62 63 @Test(dataProvider = "arrayElements") 64 public void testArrayAccess(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, ArrayChecker checker) { 65 SequenceLayout seq = MemoryLayout.ofSequence(10, elemLayout.withName("elem")); 66 testArrayAccessInternal(viewFactory, seq, seq.varHandle(carrier, PathElement.sequenceElement()), checker); 67 } 68 69 @Test(dataProvider = "arrayElements") 70 public void testPaddedArrayAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, ArrayChecker checker) { 71 SequenceLayout seq = MemoryLayout.ofSequence(10, MemoryLayout.ofStruct(MemoryLayout.ofPaddingBits(elemLayout.bitSize()), elemLayout.withName("elem"))); 72 testArrayAccessInternal(viewFactory, seq, seq.varHandle(carrier, MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("elem")), checker); 73 } 74 75 @Test(dataProvider = "arrayElements") 76 public void testPaddedArrayAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, ArrayChecker checker) { 77 SequenceLayout seq = MemoryLayout.ofSequence(10, MemoryLayout.ofSequence(2, elemLayout)); 78 testArrayAccessInternal(viewFactory, seq, seq.varHandle(carrier, PathElement.sequenceElement(), MemoryLayout.PathElement.sequenceElement(1)), checker); 79 } 80 81 private void testAccessInternal(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout layout, VarHandle handle, Checker checker) { 82 MemoryAddress outer_address; 83 try (MemorySegment segment = viewFactory.apply(MemorySegment.allocateNative(layout))) { 84 MemoryAddress addr = segment.baseAddress(); 85 try { 86 checker.check(handle, addr); 87 if (segment.isReadOnly()) { 88 throw new AssertionError(); //not ok, memory should be immutable 89 } 90 } catch (UnsupportedOperationException ex) { 91 if (!segment.isReadOnly()) { 92 throw new AssertionError(); //we should not have failed! 93 } 94 return; 95 } 96 try { 97 checker.check(handle, addr.offset(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_address = addr; //leak! 103 } 104 try { 105 checker.check(handle, outer_address); 106 throw new AssertionError(); //not ok, scope is closed 107 } catch (IllegalStateException ex) { 108 //ok, should fail (scope is closed) 109 } 110 } 111 112 private void testArrayAccessInternal(Function<MemorySegment, MemorySegment> viewFactory, SequenceLayout seq, VarHandle handle, ArrayChecker checker) { 113 MemoryAddress outer_address; 114 try (MemorySegment segment = viewFactory.apply(MemorySegment.allocateNative(seq))) { 115 MemoryAddress addr = segment.baseAddress(); 116 try { 117 for (int i = 0; i < seq.elementCount().getAsLong(); i++) { 118 checker.check(handle, addr, i); 119 } 120 if (segment.isReadOnly()) { 121 throw new AssertionError(); //not ok, memory should be immutable 122 } 123 } catch (UnsupportedOperationException ex) { 124 if (!segment.isReadOnly()) { 125 throw new AssertionError(); //we should not have failed! 126 } 127 return; 128 } 129 try { 130 checker.check(handle, addr, seq.elementCount().getAsLong()); 131 throw new AssertionError(); //not ok, out of bounds 132 } catch (IndexOutOfBoundsException ex) { 133 //ok, should fail (out of bounds) 134 } 135 outer_address = addr; //leak! 136 } 137 try { 138 checker.check(handle, outer_address, 0); 139 throw new AssertionError(); //not ok, scope is closed 140 } catch (IllegalStateException ex) { 141 //ok, should fail (scope is closed) 142 } 143 } 144 145 @Test(dataProvider = "matrixElements") 146 public void testMatrixAccess(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, MatrixChecker checker) { 147 SequenceLayout seq = MemoryLayout.ofSequence(20, 148 MemoryLayout.ofSequence(10, elemLayout.withName("elem"))); 149 testMatrixAccessInternal(viewFactory, seq, seq.varHandle(carrier, 150 PathElement.sequenceElement(), PathElement.sequenceElement()), checker); 151 } 152 153 @Test(dataProvider = "matrixElements") 154 public void testPaddedMatrixAccessByName(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, MatrixChecker checker) { 155 SequenceLayout seq = MemoryLayout.ofSequence(20, 156 MemoryLayout.ofSequence(10, MemoryLayout.ofStruct(MemoryLayout.ofPaddingBits(elemLayout.bitSize()), elemLayout.withName("elem")))); 157 testMatrixAccessInternal(viewFactory, seq, 158 seq.varHandle(carrier, 159 PathElement.sequenceElement(), PathElement.sequenceElement(), PathElement.groupElement("elem")), 160 checker); 161 } 162 163 @Test(dataProvider = "matrixElements") 164 public void testPaddedMatrixAccessByIndexSeq(Function<MemorySegment, MemorySegment> viewFactory, MemoryLayout elemLayout, Class<?> carrier, MatrixChecker checker) { 165 SequenceLayout seq = MemoryLayout.ofSequence(20, 166 MemoryLayout.ofSequence(10, MemoryLayout.ofSequence(2, elemLayout))); 167 testMatrixAccessInternal(viewFactory, seq, 168 seq.varHandle(carrier, 169 PathElement.sequenceElement(), PathElement.sequenceElement(), PathElement.sequenceElement(1)), 170 checker); 171 } 172 173 @Test(dataProvider = "badCarriers", 174 expectedExceptions = IllegalArgumentException.class) 175 public void testBadCarriers(Class<?> carrier) { 176 ValueLayout l = MemoryLayouts.BITS_32_LE.withName("elem"); 177 l.varHandle(carrier); 178 } 179 180 private void testMatrixAccessInternal(Function<MemorySegment, MemorySegment> viewFactory, SequenceLayout seq, VarHandle handle, MatrixChecker checker) { 181 MemoryAddress outer_address; 182 try (MemorySegment segment = viewFactory.apply(MemorySegment.allocateNative(seq))) { 183 MemoryAddress addr = segment.baseAddress(); 184 try { 185 for (int i = 0; i < seq.elementCount().getAsLong(); i++) { 186 for (int j = 0; j < ((SequenceLayout) seq.elementLayout()).elementCount().getAsLong(); j++) { 187 checker.check(handle, addr, i, j); 188 } 189 } 190 if (segment.isReadOnly()) { 191 throw new AssertionError(); //not ok, memory should be immutable 192 } 193 } catch (UnsupportedOperationException ex) { 194 if (!segment.isReadOnly()) { 195 throw new AssertionError(); //we should not have failed! 196 } 197 return; 198 } 199 try { 200 checker.check(handle, addr, seq.elementCount().getAsLong(), 201 ((SequenceLayout)seq.elementLayout()).elementCount().getAsLong()); 202 throw new AssertionError(); //not ok, out of bounds 203 } catch (IndexOutOfBoundsException ex) { 204 //ok, should fail (out of bounds) 205 } 206 outer_address = addr; //leak! 207 } 208 try { 209 checker.check(handle, outer_address, 0, 0); 210 throw new AssertionError(); //not ok, scope is closed 211 } catch (IllegalStateException ex) { 212 //ok, should fail (scope is closed) 213 } 214 } 215 216 static Function<MemorySegment, MemorySegment> ID = Function.identity(); 217 static Function<MemorySegment, MemorySegment> IMMUTABLE = MemorySegment::asReadOnly; 218 219 @DataProvider(name = "elements") 220 public Object[][] createData() { 221 return new Object[][] { 222 //BE, RW 223 { ID, MemoryLayouts.BITS_8_BE, byte.class, Checker.BYTE }, 224 { ID, MemoryLayouts.BITS_16_BE, short.class, Checker.SHORT }, 225 { ID, MemoryLayouts.BITS_16_BE, char.class, Checker.CHAR }, 226 { ID, MemoryLayouts.BITS_32_BE, int.class, Checker.INT }, 227 { ID, MemoryLayouts.BITS_64_BE, long.class, Checker.LONG }, 228 { ID, MemoryLayouts.BITS_32_BE, float.class, Checker.FLOAT }, 229 { ID, MemoryLayouts.BITS_64_BE, double.class, Checker.DOUBLE }, 230 //BE, RO 231 { IMMUTABLE, MemoryLayouts.BITS_8_BE, byte.class, Checker.BYTE }, 232 { IMMUTABLE, MemoryLayouts.BITS_16_BE, short.class, Checker.SHORT }, 233 { IMMUTABLE, MemoryLayouts.BITS_16_BE, char.class, Checker.CHAR }, 234 { IMMUTABLE, MemoryLayouts.BITS_32_BE, int.class, Checker.INT }, 235 { IMMUTABLE, MemoryLayouts.BITS_64_BE, long.class, Checker.LONG }, 236 { IMMUTABLE, MemoryLayouts.BITS_32_BE, float.class, Checker.FLOAT }, 237 { IMMUTABLE, MemoryLayouts.BITS_64_BE, double.class, Checker.DOUBLE }, 238 //LE, RW 239 { ID, MemoryLayouts.BITS_8_LE, byte.class, Checker.BYTE }, 240 { ID, MemoryLayouts.BITS_16_LE, short.class, Checker.SHORT }, 241 { ID, MemoryLayouts.BITS_16_LE, char.class, Checker.CHAR }, 242 { ID, MemoryLayouts.BITS_32_LE, int.class, Checker.INT }, 243 { ID, MemoryLayouts.BITS_64_LE, long.class, Checker.LONG }, 244 { ID, MemoryLayouts.BITS_32_LE, float.class, Checker.FLOAT }, 245 { ID, MemoryLayouts.BITS_64_LE, double.class, Checker.DOUBLE }, 246 //LE, RO 247 { IMMUTABLE, MemoryLayouts.BITS_8_LE, byte.class, Checker.BYTE }, 248 { IMMUTABLE, MemoryLayouts.BITS_16_LE, short.class, Checker.SHORT }, 249 { IMMUTABLE, MemoryLayouts.BITS_16_LE, char.class, Checker.CHAR }, 250 { IMMUTABLE, MemoryLayouts.BITS_32_LE, int.class, Checker.INT }, 251 { IMMUTABLE, MemoryLayouts.BITS_64_LE, long.class, Checker.LONG }, 252 { IMMUTABLE, MemoryLayouts.BITS_32_LE, float.class, Checker.FLOAT }, 253 { IMMUTABLE, MemoryLayouts.BITS_64_LE, double.class, Checker.DOUBLE }, 254 }; 255 } 256 257 interface Checker { 258 void check(VarHandle handle, MemoryAddress addr); 259 260 Checker BYTE = (handle, addr) -> { 261 handle.set(addr, (byte)42); 262 assertEquals(42, (byte)handle.get(addr)); 263 }; 264 265 Checker SHORT = (handle, addr) -> { 266 handle.set(addr, (short)42); 267 assertEquals(42, (short)handle.get(addr)); 268 }; 269 270 Checker CHAR = (handle, addr) -> { 271 handle.set(addr, (char)42); 272 assertEquals(42, (char)handle.get(addr)); 273 }; 274 275 Checker INT = (handle, addr) -> { 276 handle.set(addr, 42); 277 assertEquals(42, (int)handle.get(addr)); 278 }; 279 280 Checker LONG = (handle, addr) -> { 281 handle.set(addr, (long)42); 282 assertEquals(42, (long)handle.get(addr)); 283 }; 284 285 Checker FLOAT = (handle, addr) -> { 286 handle.set(addr, (float)42); 287 assertEquals((float)42, (float)handle.get(addr)); 288 }; 289 290 Checker DOUBLE = (handle, addr) -> { 291 handle.set(addr, (double)42); 292 assertEquals((double)42, (double)handle.get(addr)); 293 }; 294 } 295 296 @DataProvider(name = "arrayElements") 297 public Object[][] createArrayData() { 298 return new Object[][] { 299 //BE, RW 300 { ID, MemoryLayouts.BITS_8_BE, byte.class, ArrayChecker.BYTE }, 301 { ID, MemoryLayouts.BITS_16_BE, short.class, ArrayChecker.SHORT }, 302 { ID, MemoryLayouts.BITS_16_BE, char.class, ArrayChecker.CHAR }, 303 { ID, MemoryLayouts.BITS_32_BE, int.class, ArrayChecker.INT }, 304 { ID, MemoryLayouts.BITS_64_BE, long.class, ArrayChecker.LONG }, 305 { ID, MemoryLayouts.BITS_32_BE, float.class, ArrayChecker.FLOAT }, 306 { ID, MemoryLayouts.BITS_64_BE, double.class, ArrayChecker.DOUBLE }, 307 //BE, RO 308 { IMMUTABLE, MemoryLayouts.BITS_8_BE, byte.class, ArrayChecker.BYTE }, 309 { IMMUTABLE, MemoryLayouts.BITS_16_BE, short.class, ArrayChecker.SHORT }, 310 { IMMUTABLE, MemoryLayouts.BITS_16_BE, char.class, ArrayChecker.CHAR }, 311 { IMMUTABLE, MemoryLayouts.BITS_32_BE, int.class, ArrayChecker.INT }, 312 { IMMUTABLE, MemoryLayouts.BITS_64_BE, long.class, ArrayChecker.LONG }, 313 { IMMUTABLE, MemoryLayouts.BITS_32_BE, float.class, ArrayChecker.FLOAT }, 314 { IMMUTABLE, MemoryLayouts.BITS_64_BE, double.class, ArrayChecker.DOUBLE }, 315 //LE, RW 316 { ID, MemoryLayouts.BITS_8_LE, byte.class, ArrayChecker.BYTE }, 317 { ID, MemoryLayouts.BITS_16_LE, short.class, ArrayChecker.SHORT }, 318 { ID, MemoryLayouts.BITS_16_LE, char.class, ArrayChecker.CHAR }, 319 { ID, MemoryLayouts.BITS_32_LE, int.class, ArrayChecker.INT }, 320 { ID, MemoryLayouts.BITS_64_LE, long.class, ArrayChecker.LONG }, 321 { ID, MemoryLayouts.BITS_32_LE, float.class, ArrayChecker.FLOAT }, 322 { ID, MemoryLayouts.BITS_64_LE, double.class, ArrayChecker.DOUBLE }, 323 //LE, RO 324 { IMMUTABLE, MemoryLayouts.BITS_8_LE, byte.class, ArrayChecker.BYTE }, 325 { IMMUTABLE, MemoryLayouts.BITS_16_LE, short.class, ArrayChecker.SHORT }, 326 { IMMUTABLE, MemoryLayouts.BITS_16_LE, char.class, ArrayChecker.CHAR }, 327 { IMMUTABLE, MemoryLayouts.BITS_32_LE, int.class, ArrayChecker.INT }, 328 { IMMUTABLE, MemoryLayouts.BITS_64_LE, long.class, ArrayChecker.LONG }, 329 { IMMUTABLE, MemoryLayouts.BITS_32_LE, float.class, ArrayChecker.FLOAT }, 330 { IMMUTABLE, MemoryLayouts.BITS_64_LE, double.class, ArrayChecker.DOUBLE }, 331 }; 332 } 333 334 interface ArrayChecker { 335 void check(VarHandle handle, MemoryAddress addr, long index); 336 337 ArrayChecker BYTE = (handle, addr, i) -> { 338 handle.set(addr, i, (byte)i); 339 assertEquals(i, (byte)handle.get(addr, i)); 340 }; 341 342 ArrayChecker SHORT = (handle, addr, i) -> { 343 handle.set(addr, i, (short)i); 344 assertEquals(i, (short)handle.get(addr, i)); 345 }; 346 347 ArrayChecker CHAR = (handle, addr, i) -> { 348 handle.set(addr, i, (char)i); 349 assertEquals(i, (char)handle.get(addr, i)); 350 }; 351 352 ArrayChecker INT = (handle, addr, i) -> { 353 handle.set(addr, i, (int)i); 354 assertEquals(i, (int)handle.get(addr, i)); 355 }; 356 357 ArrayChecker LONG = (handle, addr, i) -> { 358 handle.set(addr, i, (long)i); 359 assertEquals(i, (long)handle.get(addr, i)); 360 }; 361 362 ArrayChecker FLOAT = (handle, addr, i) -> { 363 handle.set(addr, i, (float)i); 364 assertEquals((float)i, (float)handle.get(addr, i)); 365 }; 366 367 ArrayChecker DOUBLE = (handle, addr, i) -> { 368 handle.set(addr, i, (double)i); 369 assertEquals((double)i, (double)handle.get(addr, i)); 370 }; 371 } 372 373 @DataProvider(name = "matrixElements") 374 public Object[][] createMatrixData() { 375 return new Object[][] { 376 //BE, RW 377 { ID, MemoryLayouts.BITS_8_BE, byte.class, MatrixChecker.BYTE }, 378 { ID, MemoryLayouts.BITS_16_BE, short.class, MatrixChecker.SHORT }, 379 { ID, MemoryLayouts.BITS_16_BE, char.class, MatrixChecker.CHAR }, 380 { ID, MemoryLayouts.BITS_32_BE, int.class, MatrixChecker.INT }, 381 { ID, MemoryLayouts.BITS_64_BE, long.class, MatrixChecker.LONG }, 382 { ID, MemoryLayouts.BITS_32_BE, float.class, MatrixChecker.FLOAT }, 383 { ID, MemoryLayouts.BITS_64_BE, double.class, MatrixChecker.DOUBLE }, 384 //BE, RO 385 { IMMUTABLE, MemoryLayouts.BITS_8_BE, byte.class, MatrixChecker.BYTE }, 386 { IMMUTABLE, MemoryLayouts.BITS_16_BE, short.class, MatrixChecker.SHORT }, 387 { IMMUTABLE, MemoryLayouts.BITS_16_BE, char.class, MatrixChecker.CHAR }, 388 { IMMUTABLE, MemoryLayouts.BITS_32_BE, int.class, MatrixChecker.INT }, 389 { IMMUTABLE, MemoryLayouts.BITS_64_BE, long.class, MatrixChecker.LONG }, 390 { IMMUTABLE, MemoryLayouts.BITS_32_BE, float.class, MatrixChecker.FLOAT }, 391 { IMMUTABLE, MemoryLayouts.BITS_64_BE, double.class, MatrixChecker.DOUBLE }, 392 //LE, RW 393 { ID, MemoryLayouts.BITS_8_LE, byte.class, MatrixChecker.BYTE }, 394 { ID, MemoryLayouts.BITS_16_LE, short.class, MatrixChecker.SHORT }, 395 { ID, MemoryLayouts.BITS_16_LE, char.class, MatrixChecker.CHAR }, 396 { ID, MemoryLayouts.BITS_32_LE, int.class, MatrixChecker.INT }, 397 { ID, MemoryLayouts.BITS_64_LE, long.class, MatrixChecker.LONG }, 398 { ID, MemoryLayouts.BITS_32_LE, float.class, MatrixChecker.FLOAT }, 399 { ID, MemoryLayouts.BITS_64_LE, double.class, MatrixChecker.DOUBLE }, 400 //LE, RO 401 { IMMUTABLE, MemoryLayouts.BITS_8_LE, byte.class, MatrixChecker.BYTE }, 402 { IMMUTABLE, MemoryLayouts.BITS_16_LE, short.class, MatrixChecker.SHORT }, 403 { IMMUTABLE, MemoryLayouts.BITS_16_LE, char.class, MatrixChecker.CHAR }, 404 { IMMUTABLE, MemoryLayouts.BITS_32_LE, int.class, MatrixChecker.INT }, 405 { IMMUTABLE, MemoryLayouts.BITS_64_LE, long.class, MatrixChecker.LONG }, 406 { IMMUTABLE, MemoryLayouts.BITS_32_LE, float.class, MatrixChecker.FLOAT }, 407 { IMMUTABLE, MemoryLayouts.BITS_64_LE, double.class, MatrixChecker.DOUBLE }, 408 }; 409 } 410 411 interface MatrixChecker { 412 void check(VarHandle handle, MemoryAddress addr, long row, long col); 413 414 MatrixChecker BYTE = (handle, addr, r, c) -> { 415 handle.set(addr, r, c, (byte)(r + c)); 416 assertEquals(r + c, (byte)handle.get(addr, r, c)); 417 }; 418 419 MatrixChecker SHORT = (handle, addr, r, c) -> { 420 handle.set(addr, r, c, (short)(r + c)); 421 assertEquals(r + c, (short)handle.get(addr, r, c)); 422 }; 423 424 MatrixChecker CHAR = (handle, addr, r, c) -> { 425 handle.set(addr, r, c, (char)(r + c)); 426 assertEquals(r + c, (char)handle.get(addr, r, c)); 427 }; 428 429 MatrixChecker INT = (handle, addr, r, c) -> { 430 handle.set(addr, r, c, (int)(r + c)); 431 assertEquals(r + c, (int)handle.get(addr, r, c)); 432 }; 433 434 MatrixChecker LONG = (handle, addr, r, c) -> { 435 handle.set(addr, r, c, r + c); 436 assertEquals(r + c, (long)handle.get(addr, r, c)); 437 }; 438 439 MatrixChecker FLOAT = (handle, addr, r, c) -> { 440 handle.set(addr, r, c, (float)(r + c)); 441 assertEquals((float)(r + c), (float)handle.get(addr, r, c)); 442 }; 443 444 MatrixChecker DOUBLE = (handle, addr, r, c) -> { 445 handle.set(addr, r, c, (double)(r + c)); 446 assertEquals((double)(r + c), (double)handle.get(addr, r, c)); 447 }; 448 } 449 450 @DataProvider(name = "badCarriers") 451 public Object[][] createBadCarriers() { 452 return new Object[][] { 453 { void.class }, 454 { boolean.class }, 455 { Object.class }, 456 { int[].class } 457 }; 458 } 459 }