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