1 /* 2 * Copyright (c) 2019, 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 import jdk.test.lib.Asserts; 26 27 import java.lang.reflect.*; 28 import java.util.Random; 29 import java.util.Arrays; 30 import java.util.Comparator; 31 32 import jdk.internal.misc.Unsafe; 33 34 /* 35 * @test 36 * @summary Test flattened arrays accesses through JNI 37 * @modules java.base/jdk.internal.misc 38 * @library /testlibrary /test/lib 39 * @requires (os.simpleArch == "x64") 40 * @requires (os.family == "linux" | os.family == "mac") 41 * @compile -XDallowGenericsOverValues -XDallowWithFieldOperator TestJNIArrays.java 42 * @run main/othervm/native/timeout=3000 -XX:ValueArrayElemMaxFlatSize=128 TestJNIArrays 43 */ 44 45 public class TestJNIArrays { 46 47 static final Unsafe U = Unsafe.getUnsafe(); 48 49 public static final int ARRAY_SIZE = 1024; 50 static long seed; 51 static Random random; 52 53 static { 54 seed = System.nanoTime(); 55 System.out.println("Seed = " + seed); 56 random = new Random(seed); 57 } 58 59 static { 60 System.loadLibrary("TestJNIArrays"); 61 } 62 63 static inline class IntInt { 64 int i0; 65 int i1; 66 67 public IntInt(int i0, int i1) { 68 this.i0 = i0; 69 this.i1 = i1; 70 } 71 } 72 73 static class IntIntComparator implements Comparator<IntInt> { 74 public int compare(IntInt a, IntInt b) { 75 if (a.i0 < b.i0) return -1; 76 if (a.i0 > b.i0) return 1; 77 if (a.i1 < b.i1) return -1; 78 if (a.i1 > b.i1) return 1; 79 return 0; 80 } 81 } 82 83 static inline class Containee { 84 float f; 85 short s; 86 87 Containee(float f, short s) { 88 this.f = f; 89 this.s = s; 90 } 91 } 92 93 static inline class Container { 94 double d; 95 Containee c; 96 byte b; 97 98 Container(double d, Containee c, byte b) { 99 this.d = d ; 100 this.c = c; 101 this.b = b; 102 } 103 104 Container setc(Containee c) { 105 Container res = __WithField(this.c, c); 106 return res; 107 } 108 109 } 110 111 static inline class LongLongLongLong { 112 long l0, l1, l2, l3; 113 114 public LongLongLongLong(long l0, long l1, long l2, long l3) { 115 this.l0 = l0; 116 this.l1 = l1; 117 this.l2 = l2; 118 this.l3 = l3; 119 } 120 } 121 122 static inline class BigValue { 123 long l0 = 0, l1 = 0, l2 = 0, l3 = 0, l4 = 0, l5 = 0, l6 = 0, l7 = 0, l8 = 0, l9 = 0; 124 long l10 = 0, l11 = 0, l12 = 0, l13 = 0, l14 = 0, l15 = 0, l16 = 0, l17 = 0, l18 = 0, l19 = 0; 125 long l20 = 0, l21 = 0, l22 = 0, l23 = 0, l24 = 0, l25 = 0, l26 = 0, l27 = 0, l28 = 0, l29 = 0; 126 long l30 = 0, l31 = 0, l32 = 0, l33 = 0, l34 = 0, l35 = 0, l36 = 0, l37 = 0, l38 = 0, l39 = 0; 127 } 128 129 static inline class ValueWithOops { 130 String o = null; 131 int i = 0; 132 } 133 134 public static void main(String[] args) { 135 TestJNIArrays test = new TestJNIArrays(); 136 test.checkGetFlattenedArrayElementSize(); 137 test.checkGetFlattenedArrayElementClass(); 138 test.checkGetFieldOffsetInFlattenedLayout(); 139 test.checkGetFlattenedArrayElements(); 140 test.checkBehaviors(); 141 // test.mesureInitializationTime(1024 * 1024 * 10 , 1000); 142 // test.mesureInitializationTime2(1024 * 1024 * 10 , 1000); 143 // test.mesureUpdateTime2(1024 * 1024 * 10, 1000); 144 // test.mesureSortingTime(1024 * 1024, 100); // reduced number of iterations because Java sorting is slow (because of generics?) 145 test.mesureInitializationTime3(1024 * 1024 * 2 , 1000); 146 } 147 148 void checkGetFlattenedArrayElementSize() { 149 Throwable exception = null; 150 try { 151 Object o = new Object(); 152 GetFlattenedArrayElementSizeWrapper(o); 153 } catch(Throwable t) { 154 exception = t; 155 } 156 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 157 Asserts.assertEquals(exception.getClass(), IllegalArgumentException.class , "Wrong exception type"); 158 exception = null; 159 try { 160 int[] array = new int[16]; 161 Object o = array; 162 GetFlattenedArrayElementSizeWrapper(o); 163 } catch(Throwable t) { 164 exception = t; 165 } 166 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 167 Asserts.assertEquals(exception.getClass(), IllegalArgumentException.class , "Wrong exception type"); 168 exception = null; 169 try { 170 GetFlattenedArrayElementSizeWrapper(new String[16]); 171 } catch(Throwable t) { 172 exception = t; 173 } 174 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 175 Asserts.assertEquals(exception.getClass(), IllegalArgumentException.class , "Wrong exception type"); 176 exception = null; 177 try { 178 // Array of BigValue should not be flattened because BigValue is *big* 179 GetFlattenedArrayElementSizeWrapper(new BigValue[16]); 180 } catch(Throwable t) { 181 exception = t; 182 } 183 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 184 Asserts.assertTrue(exception instanceof IllegalArgumentException , "Exception should be a IAE"); 185 exception = null; 186 int size = -1; 187 try { 188 size = GetFlattenedArrayElementSizeWrapper(new IntInt[16]); 189 } catch(Throwable t) { 190 exception = t; 191 } 192 Asserts.assertNull(exception, "No exception should have been thrown"); 193 Asserts.assertEquals(size, 8, "Wrong size"); 194 } 195 196 void checkGetFlattenedArrayElementClass() { 197 Throwable exception = null; 198 try { 199 Object o = new Object(); 200 GetFlattenedArrayElementClassWrapper(o); 201 } catch(Throwable t) { 202 exception = t; 203 } 204 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 205 Asserts.assertEquals(exception.getClass(), IllegalArgumentException.class , "Wrong exception type"); 206 exception = null; 207 try { 208 int[] array = new int[16]; 209 Object o = array; 210 GetFlattenedArrayElementClassWrapper(o); 211 } catch(Throwable t) { 212 exception = t; 213 } 214 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 215 Asserts.assertEquals(exception.getClass(), IllegalArgumentException.class , "Wrong exception type"); 216 exception = null; 217 try { 218 GetFlattenedArrayElementClassWrapper(new String[16]); 219 } catch(Throwable t) { 220 exception = t; 221 } 222 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 223 Asserts.assertEquals(exception.getClass(), IllegalArgumentException.class , "Wrong exception type"); 224 exception = null; 225 try { 226 // Array of BigValue should not be flattened because BigValue is *big* 227 GetFlattenedArrayElementClassWrapper(new BigValue[16]); 228 } catch(Throwable t) { 229 exception = t; 230 } 231 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 232 Asserts.assertTrue(exception instanceof IllegalArgumentException , "Exception should be a IAE"); 233 exception = null; 234 Class c = null; 235 try { 236 c = GetFlattenedArrayElementClassWrapper(new IntInt[16]); 237 } catch(Throwable t) { 238 exception = t; 239 } 240 Asserts.assertNull(exception, "No exception should have been thrown"); 241 Asserts.assertEquals(c, IntInt.class, "Wrong class"); 242 } 243 244 void checkGetFieldOffsetInFlattenedLayout() { 245 Throwable exception = null; 246 try { 247 Object o = new Object(); 248 GetFieldOffsetInFlattenedLayoutWrapper(o.getClass(), "foo", "I", true); 249 } catch(Throwable t) { 250 exception = t; 251 } 252 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 253 Asserts.assertEquals(exception.getClass(), IllegalArgumentException.class , "Wrong exception type"); 254 exception = null; 255 try { 256 int[] array = new int[16]; 257 GetFieldOffsetInFlattenedLayoutWrapper(array.getClass(), "foo", "I", true); 258 } catch(Throwable t) { 259 exception = t; 260 } 261 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 262 Asserts.assertEquals(exception.getClass(), IllegalArgumentException.class , "Wrong exception type"); 263 exception = null; 264 try { 265 String[] array = new String[16]; 266 GetFieldOffsetInFlattenedLayoutWrapper(array.getClass(), "foo", "I", true); 267 } catch(Throwable t) { 268 exception = t; 269 } 270 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 271 Asserts.assertEquals(exception.getClass(), IllegalArgumentException.class , "Wrong exception type"); 272 exception = null; 273 Containee ce = new Containee(3.4f, (short)5); 274 Container c = new Container(123.876, ce, (byte)7); 275 Class<?> cclass = c.getClass(); 276 Container[] containerArray = new Container[32]; 277 int elementSize = GetFlattenedArrayElementSizeWrapper(containerArray); 278 int offset = -1; 279 try { 280 offset = GetFieldOffsetInFlattenedLayoutWrapper(cclass, "d", "D", false); 281 } catch(Throwable t) { 282 exception = t; 283 } 284 Asserts.assertNull(exception, "No exception should have been thrown"); 285 Field f = null; 286 try { 287 f = cclass.getDeclaredField("d"); 288 } catch(NoSuchFieldException e) { 289 e.printStackTrace(); 290 return; 291 } 292 Asserts.assertEquals(U.valueHeaderSize(cclass) + offset, U.objectFieldOffset(cclass, f.getName()), 293 "Incorrect offset"); 294 Asserts.assertLessThan(offset, elementSize, "Invalid offset"); 295 exception = null; 296 try { 297 // Field c should be flattened, so last argument is true, no exception expected 298 GetFieldOffsetInFlattenedLayoutWrapper(cclass, "c", "QTestJNIArrays$Containee;", true); 299 } catch(Throwable t) { 300 exception = t; 301 } 302 Asserts.assertNull(exception, "No exception should have been thrown"); 303 Asserts.assertLessThan(offset, elementSize, "Invalid offset"); 304 exception = null; 305 try { 306 // Field c should be flattened, with last argument being false, exception expected from the wrapper 307 GetFieldOffsetInFlattenedLayoutWrapper(cclass, "c", "QTestJNIArrays$Containee;", false); 308 } catch(Throwable t) { 309 exception = t; 310 } 311 Asserts.assertNotNull(exception, "Wrapper should have thrown a RuntimeException"); 312 Asserts.assertEquals(exception.getClass(), RuntimeException.class , "Wrong exception type"); 313 } 314 315 void checkGetFlattenedArrayElements() { 316 Throwable exception = null; 317 Object o = new Object(); 318 try { 319 GetFlattenedArrayElementsWrapper(o); 320 } catch(Throwable t) { 321 exception = t; 322 } 323 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 324 Asserts.assertEquals(exception.getClass(), IllegalArgumentException.class , "Wrong exception type"); 325 exception = null; 326 int[] a1 = new int[16]; 327 o = a1; 328 try { 329 GetFlattenedArrayElementsWrapper(o); 330 } catch(Throwable t) { 331 exception = t; 332 } 333 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 334 Asserts.assertEquals(exception.getClass(), IllegalArgumentException.class , "Wrong exception type"); 335 exception = null; 336 try { 337 GetFlattenedArrayElementsWrapper(new String[16]); 338 } catch(Throwable t) { 339 exception = t; 340 } 341 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 342 Asserts.assertEquals(exception.getClass(), IllegalArgumentException.class , "Wrong exception type"); 343 exception = null; 344 try { 345 // Array of BigValue should not be flattened because BigValue is *big* 346 GetFlattenedArrayElementsWrapper(new BigValue[16]); 347 } catch(Throwable t) { 348 exception = t; 349 } 350 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 351 Asserts.assertTrue(exception instanceof IllegalArgumentException , "Exception should be a IAE"); 352 exception = null; 353 try { 354 // Direct native access to flattened arrays is not allowed if elements contain oops 355 GetFlattenedArrayElementsWrapper(new ValueWithOops[16]); 356 } catch(Throwable t) { 357 exception = t; 358 } 359 Asserts.assertNotNull(exception, "An IAE should have been thrown"); 360 Asserts.assertTrue(exception instanceof IllegalArgumentException , "Exception should be a IAE"); 361 exception = null; 362 long addr = 0; 363 IntInt[] a2 = new IntInt[16]; 364 try { 365 addr = GetFlattenedArrayElementsWrapper(a2); 366 } catch(Throwable t) { 367 exception = t; 368 } 369 Asserts.assertNull(exception, "No exception should have been thrown"); 370 if (exception == null) { 371 ReleaseFlattenedArrayElementsWrapper(a2, addr, 0); 372 } 373 } 374 375 void checkBehaviors() { 376 System.out.println("Check 1"); 377 IntInt[] array = new IntInt[ARRAY_SIZE]; 378 int value = getIntFieldAtIndex(array, 1, "i0", "I"); 379 Asserts.assertEquals(value, 0, "Initial value must be zero"); 380 printArrayInformation(array); 381 int i0_value = 42; 382 int i1_value = -314; 383 initializeIntIntArrayBuffer(array, i0_value, i1_value); 384 System.gc(); 385 for (int i = 0; i < array.length; i++) { 386 Asserts.assertEquals(array[i].i0, i0_value, "Bad value of i0 at index " + i); 387 Asserts.assertEquals(array[i].i1, i1_value, "Bad value of i1 at index " + i); 388 } 389 System.out.println("Check 2"); 390 array = new IntInt[ARRAY_SIZE]; 391 i0_value = -194; 392 i1_value = 91; 393 initializeIntIntArrayFields(array, i0_value, i1_value); 394 System.gc(); 395 for (int i = 0; i < array.length; i++) { 396 Asserts.assertEquals(array[i].i0, i0_value, "Bad value of i0 at index " + i); 397 Asserts.assertEquals(array[i].i1, i1_value, "Bad value of i1 at index " + i); 398 } 399 System.out.println("Check 3"); 400 array = new IntInt[ARRAY_SIZE]; 401 initializeIntIntArrayJava(array, i0_value, i1_value); 402 System.gc(); 403 for (int i = 0; i < array.length; i++) { 404 Asserts.assertEquals(array[i].i0, i0_value, "Bad value of i0 at index " + i); 405 Asserts.assertEquals(array[i].i1, i1_value, "Bad value of i1 at index " + i); 406 } 407 System.out.println("Check 4"); 408 random = new Random(seed); 409 array = new IntInt[ARRAY_SIZE]; 410 for (int i = 0; i < ARRAY_SIZE; i++) { 411 array[i] = new IntInt(random.nextInt(), random.nextInt()); 412 } 413 sortIntIntArray(array); 414 System.gc(); 415 for (int i = 0; i < array.length - 1; i++) { 416 Asserts.assertLessThanOrEqual(array[i].i0, array[i+1].i0, "Incorrect i0 fields ordering at index " + i); 417 if (array[i].i0 == array[i+1].i0) { 418 Asserts.assertLessThanOrEqual(array[i].i1, array[i+1].i1, "Incorrect i1 fields ordering at index " + i); 419 } 420 } 421 System.out.println("Check 5"); 422 random = new Random(seed); 423 array = new IntInt[ARRAY_SIZE]; 424 for (int i = 0; i < ARRAY_SIZE; i++) { 425 array[i] = new IntInt(random.nextInt(), random.nextInt()); 426 } 427 Arrays.sort(array, new IntIntComparator()); 428 System.gc(); 429 for (int i = 0; i < array.length - 1; i++) { 430 Asserts.assertLessThanOrEqual(array[i].i0, array[i+1].i0, "Incorrect i0 fields ordering at index " + i); 431 if (array[i].i0 == array[i+1].i0) { 432 Asserts.assertLessThanOrEqual(array[i].i1, array[i+1].i1, "Incorrect i1 fields ordering at index " + i); 433 } 434 } 435 System.out.println("Check 6"); 436 Container[] array2 = new Container[ARRAY_SIZE]; 437 double d = 1.23456789; 438 float f = -987.654321f; 439 short s = -512; 440 byte b = 127; 441 Containee c = new Containee(f,s); 442 Container c2 = new Container(d, c, b); 443 initializeContainerArray(array2, d, f, s, b); 444 System.gc(); 445 for (int i = 0; i < array2.length; i++) { 446 Asserts.assertEquals(array2[i], c2, "Incorrect value at index " + i); 447 Asserts.assertEquals(array2[i].d, d, "Incorrect d value at index " + i); 448 Asserts.assertEquals(array2[i].c.f, f, "Incorrect f value at index " + i); 449 Asserts.assertEquals(array2[i].c.s, s, "Incorrect s value at index " + i); 450 Asserts.assertEquals(array2[i].b, b, "Incorrect b value at inde " +i); 451 } 452 System.out.println("Check 7"); 453 f = 19.2837465f; 454 s = 231; 455 updateContainerArray(array2, f, s); 456 System.gc(); 457 for (int i = 0; i < array2.length; i++) { 458 Asserts.assertEquals(array2[i].d, d, "Incorrect d value at index " + i); 459 Asserts.assertEquals(array2[i].c.f, f, "Incorrect f value at index " + i); 460 Asserts.assertEquals(array2[i].c.s, s, "Incorrect s value at index " + i); 461 Asserts.assertEquals(array2[i].b, b, "Incorrect b value at inde " +i); 462 } 463 System.out.println("Check 8"); 464 long l0 = 52467923; 465 long l1= -7854022; 466 long l2 = 230947485; 467 long l3 = -752497024; 468 LongLongLongLong[] array3 = new LongLongLongLong[ARRAY_SIZE/8]; 469 initializeLongLongLongLongArray(array3, l0, l1, l2, l3); 470 System.gc(); 471 for (int i = 0; i < array3.length; i++) { 472 Asserts.assertEquals(array3[i].l0, l0, "Bad value of l0 at index " + i); 473 Asserts.assertEquals(array3[i].l1, l1, "Bad value of l1 at index " + i); 474 Asserts.assertEquals(array3[i].l2, l2, "Bad value of l2 at index " + i); 475 Asserts.assertEquals(array3[i].l3, l3, "Bad value of l3 at index " + i); 476 } 477 } 478 479 void initializeIntIntArrayJava(IntInt[] array, int i0, int i1) { 480 IntInt ii = new IntInt(i0, i1); 481 for (int i = 0; i < array.length; i++) { 482 array[i] = ii; 483 } 484 } 485 486 void initializeContainerArrayJava(Container[] array, double d, float f, short s, byte b) { 487 Containee c = new Containee(f,s); 488 Container c2 = new Container(d, c, b); 489 for (int i = 0; i < array.length; i++) { 490 array[i] = c2; 491 } 492 } 493 494 void updateContainerArrayJava(Container[] array, float f, short s) { 495 Containee c = new Containee(f, s); 496 for (int i = 0; i < array.length; i++) { 497 array[i] = array[i].setc(c);; 498 } 499 } 500 501 void initializeLongLongLongLongArrayJava(LongLongLongLong[] array, long l0, long l1, long l2, long l3) { 502 LongLongLongLong llll = new LongLongLongLong(l0, l1, l2, l3); 503 for (int i = 0; i < array.length; i++) { 504 array[i] = llll; 505 } 506 } 507 508 void mesureInitializationTime(int array_size, int iterations) { 509 System.out.println("\nInitialization time for IntInt[]:"); 510 long[] start = new long[iterations]; 511 long[] end = new long[iterations]; 512 513 514 System.out.println("\nJava:"); 515 // Warmup 516 for (int i = 0; i < 10; i++) { 517 IntInt[] array = new IntInt[array_size]; 518 initializeIntIntArrayJava(array, 42, -314); 519 } 520 // Measure 521 for (int i = 0; i < iterations; i++) { 522 IntInt[] array = new IntInt[array_size]; 523 start[i] = System.nanoTime(); 524 initializeIntIntArrayJava(array, 42, -314); 525 end[i] = System.nanoTime(); 526 } 527 // Results 528 computeStatistics(start, end); 529 530 System.out.println("\nNative(memcpy):"); 531 // Warmup 532 for (int i = 0; i < 10; i++) { 533 IntInt[] array = new IntInt[array_size]; 534 initializeIntIntArrayBuffer(array, 42, -314); 535 } 536 // Measure 537 for (int i = 0; i < iterations; i++) { 538 IntInt[] array = new IntInt[array_size]; 539 start[i] = System.nanoTime(); 540 initializeIntIntArrayBuffer(array, 42, -314); 541 end[i] = System.nanoTime(); 542 } 543 // Results 544 computeStatistics(start, end); 545 546 547 System.out.println("\nNative(fields):"); 548 // Warmup 549 for (int i = 0; i < 10; i++) { 550 IntInt[] array = new IntInt[array_size]; 551 initializeIntIntArrayFields(array, 42, -314); 552 } 553 // Measure 554 for (int i = 0; i < iterations; i++) { 555 IntInt[] array = new IntInt[array_size]; 556 start[i] = System.nanoTime(); 557 initializeIntIntArrayFields(array, 42, -314); 558 end[i] = System.nanoTime(); 559 } 560 // Results 561 computeStatistics(start, end); 562 } 563 564 void mesureInitializationTime2(int array_size, int iterations) { 565 System.out.println("\nInitialization time for Container[]:"); 566 long[] start = new long[iterations]; 567 long[] end = new long[iterations]; 568 569 double d = 0.369852147; 570 float f = -321.654987f; 571 short s = -3579; 572 byte b = 42; 573 574 System.out.println("\nJava:"); 575 // Warmup 576 for (int i = 0; i < 10; i++) { 577 Container[] array = new Container[array_size]; 578 initializeContainerArrayJava(array, d, f, s, b); 579 } 580 // Measure 581 for (int i = 0; i < iterations; i++) { 582 Container[] array = new Container[array_size]; 583 start[i] = System.nanoTime(); 584 initializeContainerArrayJava(array, d, f, s, b); 585 end[i] = System.nanoTime(); 586 } 587 // Results 588 computeStatistics(start, end); 589 590 System.out.println("\nNative:"); 591 // Warmup 592 for (int i = 0; i < 10; i++) { 593 Container[] array = new Container[array_size]; 594 initializeContainerArray(array, d, f, s, b); 595 } 596 // Measure 597 for (int i = 0; i < iterations; i++) { 598 Container[] array = new Container[array_size]; 599 start[i] = System.nanoTime(); 600 initializeContainerArray(array, d, f, s, b); 601 end[i] = System.nanoTime(); 602 } 603 // Results 604 computeStatistics(start, end); 605 } 606 607 void mesureUpdateTime2(int array_size, int iterations) { 608 System.out.println("\nUpdating Container[]:"); 609 long[] start = new long[iterations]; 610 long[] end = new long[iterations]; 611 612 double d = 0.369852147; 613 float f = -321.654987f; 614 short s = -3579; 615 byte b = 42; 616 617 Containee c = new Containee(f,s); 618 Container c2 = new Container(d, c, b); 619 620 System.out.println("\nJava:"); 621 // Warmup 622 for (int i = 0; i < 10; i++) { 623 Container[] array = new Container[array_size]; 624 for (int j = 0; j < array.length; j++) { 625 array[j] = c2; 626 } 627 updateContainerArrayJava(array, f, s); 628 } 629 // Measure 630 for (int i = 0; i < iterations; i++) { 631 Container[] array = new Container[array_size]; 632 for (int j = 0; j < array.length; j++) { 633 array[i] = c2; 634 } 635 start[i] = System.nanoTime(); 636 updateContainerArrayJava(array, f, s); 637 end[i] = System.nanoTime(); 638 } 639 // Results 640 computeStatistics(start, end); 641 642 System.out.println("\nNative:"); 643 // Warmup 644 for (int i = 0; i < 10; i++) { 645 Container[] array = new Container[array_size]; 646 for (int j = 0; j < array.length; j++) { 647 array[i] = c2; 648 } 649 updateContainerArray(array, f, s); 650 } 651 // Measure 652 for (int i = 0; i < iterations; i++) { 653 Container[] array = new Container[array_size]; 654 for (int j = 0; j < array.length; j++) { 655 array[i] = c2; 656 } 657 start[i] = System.nanoTime(); 658 updateContainerArray(array, f, s); 659 end[i] = System.nanoTime(); 660 } 661 // Results 662 computeStatistics(start, end); 663 } 664 665 void mesureSortingTime(int array_size, int iterations) { 666 System.out.println("\nSorting time:"); 667 long[] start = new long[iterations]; 668 long[] end = new long[iterations]; 669 670 random = new Random(seed); 671 System.out.println("\nJava:"); 672 IntIntComparator comparator = new IntIntComparator(); 673 // Warmup 674 for (int i = 0; i < 10; i++) { 675 IntInt[] array = new IntInt[array_size]; 676 array = new IntInt[array_size]; 677 for (int j = 0; j < array_size; j++) { 678 array[j] = new IntInt(random.nextInt(), random.nextInt()); 679 } 680 Arrays.sort(array, comparator); 681 } 682 // Measure 683 for (int i = 0; i < iterations; i++) { 684 IntInt[] array = new IntInt[array_size]; 685 for (int j = 0; j < array_size; j++) { 686 array[j] = new IntInt(random.nextInt(), random.nextInt()); 687 } 688 start[i] = System.nanoTime(); 689 Arrays.sort(array, comparator); 690 end[i] = System.nanoTime(); 691 } 692 // Results 693 computeStatistics(start, end); 694 695 random = new Random(seed); 696 System.out.println("\nNative:"); 697 // Warmup 698 for (int i = 0; i < 10; i++) { 699 IntInt[] array = new IntInt[array_size]; 700 array = new IntInt[array_size]; 701 for (int j = 0; j < array_size; j++) { 702 array[j] = new IntInt(random.nextInt(), random.nextInt()); 703 } 704 sortIntIntArray(array); 705 } 706 // Measure 707 for (int i = 0; i < iterations; i++) { 708 IntInt[] array = new IntInt[array_size]; 709 for (int j = 0; j < array_size; j++) { 710 array[j] = new IntInt(random.nextInt(), random.nextInt()); 711 } 712 start[i] = System.nanoTime(); 713 sortIntIntArray(array); 714 end[i] = System.nanoTime(); 715 } 716 // Results 717 computeStatistics(start, end); 718 } 719 720 721 void mesureInitializationTime3(int array_size, int iterations) { 722 System.out.println("\nInitialization time for LongLongLongLong[]:"); 723 long[] start = new long[iterations]; 724 long[] end = new long[iterations]; 725 726 long l0 = 123456; 727 long l1 = -987654; 728 long l2 = 192837; 729 long l3 = -56473829; 730 731 System.out.println("\nJava:"); 732 // Warmup 733 for (int i = 0; i < 10; i++) { 734 LongLongLongLong[] array = new LongLongLongLong[array_size]; 735 initializeLongLongLongLongArrayJava(array, l0, l1, l2, l3); 736 } 737 // Measure 738 for (int i = 0; i < iterations; i++) { 739 LongLongLongLong[] array = new LongLongLongLong[array_size]; 740 start[i] = System.nanoTime(); 741 initializeLongLongLongLongArrayJava(array, l0, l1, l2, l3); 742 end[i] = System.nanoTime(); 743 } 744 // Results 745 computeStatistics(start, end); 746 747 System.out.println("\nNative:"); 748 // Warmup 749 for (int i = 0; i < 10; i++) { 750 LongLongLongLong[] array = new LongLongLongLong[array_size]; 751 initializeLongLongLongLongArray(array, l0, l1, l2, l3); 752 } 753 // Measure 754 for (int i = 0; i < iterations; i++) { 755 LongLongLongLong[] array = new LongLongLongLong[array_size]; 756 start[i] = System.nanoTime(); 757 initializeLongLongLongLongArray(array, l0, l1, l2, l3); 758 end[i] = System.nanoTime(); 759 } 760 // Results 761 computeStatistics(start, end); 762 } 763 764 void computeStatistics(long[] start, long[] end) { 765 int iterations = start.length; 766 long[] duration = new long[iterations]; 767 long sum = 0; 768 long min = end[0] - start[0]; 769 long max = min; 770 double var = 0.0; 771 for (int i = 0 ; i < iterations; i++) { 772 duration[i] = end[i] - start[i]; 773 if (duration[i] < min) min = duration[i]; 774 if (duration[i] > max) max = duration[i]; 775 sum += duration[i]; 776 double d = (double) duration[i]; 777 var += Math.pow(d, 2); 778 } 779 double avg = (sum/iterations) / 1000; 780 double std = (Math.sqrt(var/iterations - Math.pow(sum/iterations, 2))) / 1000; 781 System.out.println(String.format("Avg: %8.2f us", avg)); 782 System.out.println(String.format("Std: %8.2f us", std)); 783 System.out.println(String.format("Min: %8d us", (min/1000))); 784 System.out.println(String.format("Max: %8d us", (max/1000))); 785 } 786 787 native int GetFlattenedArrayElementSizeWrapper(Object array); 788 native Class GetFlattenedArrayElementClassWrapper(Object array); 789 native long GetFlattenedArrayElementsWrapper(Object array); 790 native void ReleaseFlattenedArrayElementsWrapper(Object array, long addr,int mode); 791 native int GetFieldOffsetInFlattenedLayoutWrapper(Class klass, String name, String signature, boolean flattened); 792 793 native int getIntFieldAtIndex(Object[] array, int index, String fieldName, String FieldSignature); 794 native void printArrayInformation(Object[] array); 795 796 native void initializeIntIntArrayBuffer(Object[] array, int i0, int i1); 797 native void initializeIntIntArrayFields(Object[] array, int i0, int i1); 798 native void sortIntIntArray(Object[] array); 799 800 native void initializeContainerArray(Object[] array, double d, float f, short s, byte b); 801 native void updateContainerArray(Object[] array, float f, short s); 802 803 native void initializeLongLongLongLongArray(Object[] array, long l0, long l1, long l2, long l3); 804 }