1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import java.lang.reflect.Method; 18 19 class Circle { Circle(double radius)20 Circle(double radius) { 21 this.radius = radius; 22 } getRadius()23 public double getRadius() { 24 return radius; 25 } getArea()26 public double getArea() { 27 return radius * radius * Math.PI; 28 } 29 private double radius; 30 } 31 32 class TestClass { 33 static { 34 sTestClassObj = new TestClass(-1, -2); 35 } TestClass()36 TestClass() { 37 } TestClass(int i, int j)38 TestClass(int i, int j) { 39 this.i = i; 40 this.j = j; 41 } 42 int i; 43 int j; 44 volatile int k; 45 TestClass next; 46 String str; 47 static int si; 48 static TestClass sTestClassObj; 49 } 50 51 class SubTestClass extends TestClass { 52 int k; 53 } 54 55 class TestClass2 { 56 int i; 57 int j; 58 } 59 60 class TestClass3 { 61 float floatField = 8.0f; 62 boolean test1 = true; 63 } 64 65 class Finalizable { 66 static boolean sVisited = false; 67 static final int VALUE1 = 0xbeef; 68 static final int VALUE2 = 0xcafe; 69 int i; 70 finalize()71 protected void finalize() { 72 if (i != VALUE1) { 73 System.out.println("Where is the beef?"); 74 } 75 sVisited = true; 76 } 77 } 78 79 interface Filter { isValid(int i)80 public boolean isValid(int i); 81 } 82 83 public class Main { 84 85 /// CHECK-START: double Main.calcCircleArea(double) load_store_elimination (before) 86 /// CHECK: NewInstance 87 /// CHECK: InstanceFieldSet 88 /// CHECK: InstanceFieldGet 89 90 /// CHECK-START: double Main.calcCircleArea(double) load_store_elimination (after) 91 /// CHECK-NOT: NewInstance 92 /// CHECK-NOT: InstanceFieldSet 93 /// CHECK-NOT: InstanceFieldGet 94 calcCircleArea(double radius)95 static double calcCircleArea(double radius) { 96 return new Circle(radius).getArea(); 97 } 98 99 /// CHECK-START: int Main.test1(TestClass, TestClass) load_store_elimination (before) 100 /// CHECK: InstanceFieldSet 101 /// CHECK: InstanceFieldSet 102 /// CHECK: InstanceFieldGet 103 /// CHECK: InstanceFieldGet 104 105 /// CHECK-START: int Main.test1(TestClass, TestClass) load_store_elimination (after) 106 /// CHECK: InstanceFieldSet 107 /// CHECK: InstanceFieldSet 108 /// CHECK-NOT: NullCheck 109 /// CHECK-NOT: InstanceFieldGet 110 111 // Different fields shouldn't alias. test1(TestClass obj1, TestClass obj2)112 static int test1(TestClass obj1, TestClass obj2) { 113 obj1.i = 1; 114 obj2.j = 2; 115 return obj1.i + obj2.j; 116 } 117 118 /// CHECK-START: int Main.test2(TestClass) load_store_elimination (before) 119 /// CHECK: InstanceFieldSet 120 /// CHECK: InstanceFieldSet 121 /// CHECK: InstanceFieldGet 122 123 /// CHECK-START: int Main.test2(TestClass) load_store_elimination (after) 124 /// CHECK: InstanceFieldSet 125 /// CHECK-NOT: NullCheck 126 /// CHECK-NOT: InstanceFieldSet 127 /// CHECK-NOT: InstanceFieldGet 128 129 // Redundant store of the same value. test2(TestClass obj)130 static int test2(TestClass obj) { 131 obj.j = 1; 132 obj.j = 1; 133 return obj.j; 134 } 135 136 /// CHECK-START: int Main.test3(TestClass) load_store_elimination (before) 137 /// CHECK: StaticFieldGet 138 /// CHECK: NewInstance 139 /// CHECK: InstanceFieldSet 140 /// CHECK: InstanceFieldSet 141 /// CHECK: InstanceFieldSet 142 /// CHECK: InstanceFieldSet 143 /// CHECK: InstanceFieldGet 144 /// CHECK: InstanceFieldGet 145 /// CHECK: InstanceFieldGet 146 /// CHECK: InstanceFieldGet 147 148 /// CHECK-START: int Main.test3(TestClass) load_store_elimination (after) 149 /// CHECK: StaticFieldGet 150 /// CHECK: NewInstance 151 /// CHECK: InstanceFieldSet 152 /// CHECK: InstanceFieldSet 153 /// CHECK: InstanceFieldSet 154 /// CHECK: InstanceFieldSet 155 /// CHECK-NOT: InstanceFieldGet 156 /// CHECK-NOT: StaticFieldGet 157 158 // A new allocation (even non-singleton) shouldn't alias with pre-existing values. test3(TestClass obj)159 static int test3(TestClass obj) { 160 TestClass obj1 = TestClass.sTestClassObj; 161 TestClass obj2 = new TestClass(); // Cannot alias with obj or obj1 which pre-exist. 162 obj.next = obj2; // Make obj2 a non-singleton. 163 // All stores below need to stay since obj/obj1/obj2 are not singletons. 164 obj.i = 1; 165 obj1.j = 2; 166 // Following stores won't kill values of obj.i and obj1.j. 167 obj2.i = 3; 168 obj2.j = 4; 169 return obj.i + obj1.j + obj2.i + obj2.j; 170 } 171 172 /// CHECK-START: int Main.test6(TestClass, TestClass, boolean) load_store_elimination (before) 173 /// CHECK: InstanceFieldSet 174 /// CHECK: InstanceFieldSet 175 /// CHECK: InstanceFieldSet 176 /// CHECK: InstanceFieldGet 177 /// CHECK: InstanceFieldGet 178 179 /// CHECK-START: int Main.test6(TestClass, TestClass, boolean) load_store_elimination (after) 180 /// CHECK: InstanceFieldSet 181 /// CHECK: InstanceFieldSet 182 /// CHECK: InstanceFieldSet 183 /// CHECK: InstanceFieldGet 184 /// CHECK-NOT: NullCheck 185 /// CHECK-NOT: InstanceFieldGet 186 187 // Setting the same value doesn't clear the value for aliased locations. test6(TestClass obj1, TestClass obj2, boolean b)188 static int test6(TestClass obj1, TestClass obj2, boolean b) { 189 obj1.i = 1; 190 obj1.j = 2; 191 if (b) { 192 obj2.j = 2; 193 } 194 return obj1.j + obj2.j; 195 } 196 197 /// CHECK-START: int Main.test7(TestClass) load_store_elimination (before) 198 /// CHECK: InstanceFieldSet 199 /// CHECK: InstanceFieldGet 200 201 /// CHECK-START: int Main.test7(TestClass) load_store_elimination (after) 202 /// CHECK: InstanceFieldSet 203 /// CHECK: InstanceFieldGet 204 205 // Invocation should kill values in non-singleton heap locations. test7(TestClass obj)206 static int test7(TestClass obj) { 207 obj.i = 1; 208 System.out.print(""); 209 return obj.i; 210 } 211 212 /// CHECK-START: int Main.test8() load_store_elimination (before) 213 /// CHECK: NewInstance 214 /// CHECK: InstanceFieldSet 215 /// CHECK: InvokeVirtual 216 /// CHECK: InstanceFieldGet 217 218 /// CHECK-START: int Main.test8() load_store_elimination (after) 219 /// CHECK-NOT: NewInstance 220 /// CHECK-NOT: InstanceFieldSet 221 /// CHECK: InvokeVirtual 222 /// CHECK-NOT: NullCheck 223 /// CHECK-NOT: InstanceFieldGet 224 225 // Invocation should not kill values in singleton heap locations. test8()226 static int test8() { 227 TestClass obj = new TestClass(); 228 obj.i = 1; 229 System.out.print(""); 230 return obj.i; 231 } 232 233 /// CHECK-START: int Main.test9(TestClass) load_store_elimination (before) 234 /// CHECK: NewInstance 235 /// CHECK: InstanceFieldSet 236 /// CHECK: InstanceFieldSet 237 /// CHECK: InstanceFieldGet 238 239 /// CHECK-START: int Main.test9(TestClass) load_store_elimination (after) 240 /// CHECK: NewInstance 241 /// CHECK: InstanceFieldSet 242 /// CHECK: InstanceFieldSet 243 /// CHECK: InstanceFieldGet 244 245 // Invocation should kill values in non-singleton heap locations. test9(TestClass obj)246 static int test9(TestClass obj) { 247 TestClass obj2 = new TestClass(); 248 obj2.i = 1; 249 obj.next = obj2; 250 System.out.print(""); 251 return obj2.i; 252 } 253 254 /// CHECK-START: int Main.test11(TestClass) load_store_elimination (before) 255 /// CHECK: InstanceFieldSet 256 /// CHECK: InstanceFieldGet 257 258 /// CHECK-START: int Main.test11(TestClass) load_store_elimination (after) 259 /// CHECK: InstanceFieldSet 260 /// CHECK-NOT: NullCheck 261 /// CHECK-NOT: InstanceFieldGet 262 263 // Loop without heap writes. 264 // obj.i is actually hoisted to the loop pre-header by licm already. test11(TestClass obj)265 static int test11(TestClass obj) { 266 obj.i = 1; 267 int sum = 0; 268 for (int i = 0; i < 10; i++) { 269 sum += obj.i; 270 } 271 return sum; 272 } 273 274 /// CHECK-START: int Main.test12(TestClass, TestClass) load_store_elimination (before) 275 /// CHECK: InstanceFieldSet 276 /// CHECK: InstanceFieldGet 277 /// CHECK: InstanceFieldSet 278 279 /// CHECK-START: int Main.test12(TestClass, TestClass) load_store_elimination (after) 280 /// CHECK: InstanceFieldSet 281 /// CHECK: InstanceFieldGet 282 /// CHECK: InstanceFieldSet 283 284 // Loop with heap writes. test12(TestClass obj1, TestClass obj2)285 static int test12(TestClass obj1, TestClass obj2) { 286 obj1.i = 1; 287 int sum = 0; 288 for (int i = 0; i < 10; i++) { 289 sum += obj1.i; 290 obj2.i = sum; 291 } 292 return sum; 293 } 294 295 /// CHECK-START: int Main.test13(TestClass, TestClass2) load_store_elimination (before) 296 /// CHECK: InstanceFieldSet 297 /// CHECK: InstanceFieldSet 298 /// CHECK: InstanceFieldGet 299 /// CHECK: InstanceFieldGet 300 301 /// CHECK-START: int Main.test13(TestClass, TestClass2) load_store_elimination (after) 302 /// CHECK: InstanceFieldSet 303 /// CHECK: InstanceFieldSet 304 /// CHECK-NOT: NullCheck 305 /// CHECK-NOT: InstanceFieldGet 306 307 // Different classes shouldn't alias. test13(TestClass obj1, TestClass2 obj2)308 static int test13(TestClass obj1, TestClass2 obj2) { 309 obj1.i = 1; 310 obj2.i = 2; 311 return obj1.i + obj2.i; 312 } 313 314 /// CHECK-START: int Main.test14(TestClass, SubTestClass) load_store_elimination (before) 315 /// CHECK: InstanceFieldSet 316 /// CHECK: InstanceFieldSet 317 /// CHECK: InstanceFieldGet 318 319 /// CHECK-START: int Main.test14(TestClass, SubTestClass) load_store_elimination (after) 320 /// CHECK: InstanceFieldSet 321 /// CHECK: InstanceFieldSet 322 /// CHECK: InstanceFieldGet 323 324 // Subclass may alias with super class. test14(TestClass obj1, SubTestClass obj2)325 static int test14(TestClass obj1, SubTestClass obj2) { 326 obj1.i = 1; 327 obj2.i = 2; 328 return obj1.i; 329 } 330 331 /// CHECK-START: int Main.test15() load_store_elimination (before) 332 /// CHECK: StaticFieldSet 333 /// CHECK: StaticFieldSet 334 /// CHECK: StaticFieldGet 335 336 /// CHECK-START: int Main.test15() load_store_elimination (after) 337 /// CHECK: <<Const2:i\d+>> IntConstant 2 338 /// CHECK: StaticFieldSet 339 /// CHECK-NOT: StaticFieldGet 340 /// CHECK: Return [<<Const2>>] 341 342 // Static field access from subclass's name. test15()343 static int test15() { 344 TestClass.si = 1; 345 SubTestClass.si = 2; 346 return TestClass.si; 347 } 348 349 /// CHECK-START: int Main.test16() load_store_elimination (before) 350 /// CHECK: NewInstance 351 /// CHECK: InstanceFieldSet 352 /// CHECK: InstanceFieldSet 353 /// CHECK: InstanceFieldGet 354 /// CHECK: InstanceFieldGet 355 356 /// CHECK-START: int Main.test16() load_store_elimination (after) 357 /// CHECK-NOT: NewInstance 358 /// CHECK-NOT: InstanceFieldSet 359 /// CHECK-NOT: InstanceFieldGet 360 361 // Test inlined constructor. test16()362 static int test16() { 363 TestClass obj = new TestClass(1, 2); 364 return obj.i + obj.j; 365 } 366 367 /// CHECK-START: int Main.test17() load_store_elimination (before) 368 /// CHECK: NewInstance 369 /// CHECK: InstanceFieldSet 370 /// CHECK: InstanceFieldGet 371 372 /// CHECK-START: int Main.test17() load_store_elimination (after) 373 /// CHECK: <<Const0:i\d+>> IntConstant 0 374 /// CHECK-NOT: NewInstance 375 /// CHECK-NOT: InstanceFieldSet 376 /// CHECK-NOT: InstanceFieldGet 377 /// CHECK: Return [<<Const0>>] 378 379 // Test getting default value. test17()380 static int test17() { 381 TestClass obj = new TestClass(); 382 obj.j = 1; 383 return obj.i; 384 } 385 386 /// CHECK-START: int Main.test18(TestClass) load_store_elimination (before) 387 /// CHECK: InstanceFieldSet 388 /// CHECK: InstanceFieldGet 389 390 /// CHECK-START: int Main.test18(TestClass) load_store_elimination (after) 391 /// CHECK: InstanceFieldSet 392 /// CHECK: InstanceFieldGet 393 394 // Volatile field load/store shouldn't be eliminated. test18(TestClass obj)395 static int test18(TestClass obj) { 396 obj.k = 1; 397 return obj.k; 398 } 399 400 /// CHECK-START: float Main.test19(float[], float[]) load_store_elimination (before) 401 /// CHECK: {{f\d+}} ArrayGet 402 /// CHECK: {{f\d+}} ArrayGet 403 404 /// CHECK-START: float Main.test19(float[], float[]) load_store_elimination (after) 405 /// CHECK: {{f\d+}} ArrayGet 406 /// CHECK-NOT: {{f\d+}} ArrayGet 407 408 // I/F, J/D aliasing should not happen any more and LSE should eliminate the load. test19(float[] fa1, float[] fa2)409 static float test19(float[] fa1, float[] fa2) { 410 fa1[0] = fa2[0]; 411 return fa1[0]; 412 } 413 414 /// CHECK-START: TestClass Main.test20() load_store_elimination (before) 415 /// CHECK: NewInstance 416 /// CHECK: InstanceFieldSet 417 418 /// CHECK-START: TestClass Main.test20() load_store_elimination (after) 419 /// CHECK: NewInstance 420 /// CHECK-NOT: InstanceFieldSet 421 422 // Storing default heap value is redundant if the heap location has the 423 // default heap value. test20()424 static TestClass test20() { 425 TestClass obj = new TestClass(); 426 obj.i = 0; 427 return obj; 428 } 429 430 /// CHECK-START: void Main.test21(TestClass) load_store_elimination (before) 431 /// CHECK: NewInstance 432 /// CHECK: InstanceFieldSet 433 /// CHECK: InstanceFieldSet 434 /// CHECK: InstanceFieldSet 435 /// CHECK: InstanceFieldGet 436 /// CHECK: InstanceFieldGet 437 438 /// CHECK-START: void Main.test21(TestClass) load_store_elimination (after) 439 /// CHECK: NewInstance 440 /// CHECK: InstanceFieldSet 441 /// CHECK: InstanceFieldSet 442 /// CHECK: InstanceFieldSet 443 /// CHECK: InstanceFieldGet 444 /// CHECK: InstanceFieldGet 445 446 // Loop side effects can kill heap values, stores need to be kept in that case. test21(TestClass obj0)447 static void test21(TestClass obj0) { 448 TestClass obj = new TestClass(); 449 obj0.str = "abc"; 450 obj.str = "abc"; 451 for (int i = 0; i < 2; i++) { 452 // Generate some loop side effect that writes into obj. 453 obj.str = "def"; 454 } 455 System.out.print(obj0.str.substring(0, 0) + obj.str.substring(0, 0)); 456 } 457 458 /// CHECK-START: int Main.test22() load_store_elimination (before) 459 /// CHECK: NewInstance 460 /// CHECK: InstanceFieldSet 461 /// CHECK: NewInstance 462 /// CHECK: InstanceFieldSet 463 /// CHECK: InstanceFieldGet 464 /// CHECK: NewInstance 465 /// CHECK: InstanceFieldSet 466 /// CHECK: InstanceFieldGet 467 /// CHECK: InstanceFieldGet 468 469 /// CHECK-START: int Main.test22() load_store_elimination (after) 470 /// CHECK-NOT: NewInstance 471 /// CHECK-NOT: InstanceFieldSet 472 /// CHECK-NOT: NewInstance 473 /// CHECK-NOT: InstanceFieldSet 474 /// CHECK-NOT: InstanceFieldGet 475 /// CHECK-NOT: NewInstance 476 /// CHECK-NOT: InstanceFieldSet 477 /// CHECK-NOT: InstanceFieldGet 478 /// CHECK-NOT: InstanceFieldGet 479 480 // For a singleton, loop side effects can kill its field values only if: 481 // (1) it dominiates the loop header, and 482 // (2) its fields are stored into inside a loop. test22()483 static int test22() { 484 int sum = 0; 485 TestClass obj1 = new TestClass(); 486 obj1.i = 2; // This store can be eliminated since obj1 is never stored into inside a loop. 487 for (int i = 0; i < 2; i++) { 488 TestClass obj2 = new TestClass(); 489 obj2.i = 3; // This store can be eliminated since the singleton is inside the loop. 490 sum += obj2.i; 491 } 492 TestClass obj3 = new TestClass(); 493 obj3.i = 5; // This store can be eliminated since the singleton is created after the loop. 494 sum += obj1.i + obj3.i; 495 return sum; 496 } 497 498 /// CHECK-START: void Main.testFinalizable() load_store_elimination (before) 499 /// CHECK: NewInstance 500 /// CHECK: InstanceFieldSet 501 /// CHECK: InstanceFieldSet 502 503 /// CHECK-START: void Main.testFinalizable() load_store_elimination (after) 504 /// CHECK: NewInstance 505 /// CHECK: InstanceFieldSet 506 /// CHECK-NOT: InstanceFieldSet 507 508 // Allocations of finalizable objects cannot be eliminated. testFinalizable()509 static void testFinalizable() { 510 Finalizable finalizable = new Finalizable(); 511 finalizable.i = Finalizable.VALUE2; 512 finalizable.i = Finalizable.VALUE1; 513 } 514 getWeakReference()515 static java.lang.ref.WeakReference<Object> getWeakReference() { 516 return new java.lang.ref.WeakReference<>(new Object()); 517 } 518 testFinalizableByForcingGc()519 static void testFinalizableByForcingGc() { 520 testFinalizable(); 521 java.lang.ref.WeakReference<Object> reference = getWeakReference(); 522 523 Runtime runtime = Runtime.getRuntime(); 524 for (int i = 0; i < 20; ++i) { 525 runtime.gc(); 526 System.runFinalization(); 527 try { 528 Thread.sleep(1); 529 } catch (InterruptedException e) { 530 throw new AssertionError(e); 531 } 532 533 // Check to see if the weak reference has been garbage collected. 534 if (reference.get() == null) { 535 // A little bit more sleep time to make sure. 536 try { 537 Thread.sleep(100); 538 } catch (InterruptedException e) { 539 throw new AssertionError(e); 540 } 541 if (!Finalizable.sVisited) { 542 System.out.println("finalize() not called."); 543 } 544 return; 545 } 546 } 547 System.out.println("testFinalizableByForcingGc() failed to force gc."); 548 } 549 550 /// CHECK-START: int Main.$noinline$testHSelect(boolean) load_store_elimination (before) 551 /// CHECK: InstanceFieldSet 552 /// CHECK: Select 553 554 /// CHECK-START: int Main.$noinline$testHSelect(boolean) load_store_elimination (after) 555 /// CHECK: InstanceFieldSet 556 /// CHECK: Select 557 558 // Test that HSelect creates alias. $noinline$testHSelect(boolean b)559 static int $noinline$testHSelect(boolean b) { 560 if (sFlag) { 561 throw new Error(); 562 } 563 TestClass obj = new TestClass(); 564 TestClass obj2 = null; 565 obj.i = 0xdead; 566 if (b) { 567 obj2 = obj; 568 } 569 return obj2.i; 570 } 571 sumWithFilter(int[] array, Filter f)572 static int sumWithFilter(int[] array, Filter f) { 573 int sum = 0; 574 for (int i = 0; i < array.length; i++) { 575 if (f.isValid(array[i])) { 576 sum += array[i]; 577 } 578 } 579 return sum; 580 } 581 582 /// CHECK-START: int Main.sumWithinRange(int[], int, int) load_store_elimination (before) 583 /// CHECK: NewInstance 584 /// CHECK: InstanceFieldSet 585 /// CHECK: InstanceFieldSet 586 /// CHECK: InstanceFieldGet 587 /// CHECK: InstanceFieldGet 588 589 /// CHECK-START: int Main.sumWithinRange(int[], int, int) load_store_elimination (after) 590 /// CHECK-NOT: NewInstance 591 /// CHECK-NOT: InstanceFieldSet 592 /// CHECK-NOT: InstanceFieldGet 593 594 // A lambda-style allocation can be eliminated after inlining. sumWithinRange(int[] array, final int low, final int high)595 static int sumWithinRange(int[] array, final int low, final int high) { 596 Filter filter = new Filter() { 597 public boolean isValid(int i) { 598 return (i >= low) && (i <= high); 599 } 600 }; 601 return sumWithFilter(array, filter); 602 } 603 604 private static int mI = 0; 605 private static float mF = 0f; 606 607 /// CHECK-START: float Main.testAllocationEliminationWithLoops() load_store_elimination (before) 608 /// CHECK: NewInstance 609 /// CHECK: NewInstance 610 /// CHECK: NewInstance 611 612 /// CHECK-START: float Main.testAllocationEliminationWithLoops() load_store_elimination (after) 613 /// CHECK-NOT: NewInstance 614 testAllocationEliminationWithLoops()615 private static float testAllocationEliminationWithLoops() { 616 for (int i0 = 0; i0 < 5; i0++) { 617 for (int i1 = 0; i1 < 5; i1++) { 618 for (int i2 = 0; i2 < 5; i2++) { 619 int lI0 = ((int) new Integer(((int) new Integer(mI)))); 620 if (((boolean) new Boolean(false))) { 621 for (int i3 = 576 - 1; i3 >= 0; i3--) { 622 mF -= 976981405.0f; 623 } 624 } 625 } 626 } 627 } 628 return 1.0f; 629 } 630 631 /// CHECK-START: TestClass2 Main.testStoreStore() load_store_elimination (before) 632 /// CHECK: NewInstance 633 /// CHECK: InstanceFieldSet 634 /// CHECK: InstanceFieldSet 635 /// CHECK: InstanceFieldSet 636 /// CHECK: InstanceFieldSet 637 638 /// CHECK-START: TestClass2 Main.testStoreStore() load_store_elimination (after) 639 /// CHECK: NewInstance 640 /// CHECK: InstanceFieldSet 641 /// CHECK: InstanceFieldSet 642 /// CHECK-NOT: InstanceFieldSet 643 testStoreStore()644 private static TestClass2 testStoreStore() { 645 TestClass2 obj = new TestClass2(); 646 obj.i = 41; 647 obj.j = 42; 648 obj.i = 41; 649 obj.j = 43; 650 return obj; 651 } 652 653 /// CHECK-START: void Main.testStoreStore2(TestClass2) load_store_elimination (before) 654 /// CHECK: InstanceFieldSet 655 /// CHECK: InstanceFieldSet 656 /// CHECK: InstanceFieldSet 657 /// CHECK: InstanceFieldSet 658 659 /// CHECK-START: void Main.testStoreStore2(TestClass2) load_store_elimination (after) 660 /// CHECK: InstanceFieldSet 661 /// CHECK: InstanceFieldSet 662 /// CHECK-NOT: InstanceFieldSet 663 testStoreStore2(TestClass2 obj)664 private static void testStoreStore2(TestClass2 obj) { 665 obj.i = 41; 666 obj.j = 42; 667 obj.i = 43; 668 obj.j = 44; 669 } 670 671 /// CHECK-START: void Main.testStoreStore3(TestClass2, boolean) load_store_elimination (before) 672 /// CHECK: InstanceFieldSet 673 /// CHECK: InstanceFieldSet 674 /// CHECK: InstanceFieldSet 675 /// CHECK: InstanceFieldSet 676 677 /// CHECK-START: void Main.testStoreStore3(TestClass2, boolean) load_store_elimination (after) 678 /// CHECK: InstanceFieldSet 679 /// CHECK: InstanceFieldSet 680 /// CHECK: InstanceFieldSet 681 /// CHECK-NOT: InstanceFieldSet 682 testStoreStore3(TestClass2 obj, boolean flag)683 private static void testStoreStore3(TestClass2 obj, boolean flag) { 684 obj.i = 41; 685 obj.j = 42; // redundant since it's overwritten in both branches below. 686 if (flag) { 687 obj.j = 43; 688 } else { 689 obj.j = 44; 690 } 691 } 692 693 /// CHECK-START: void Main.testStoreStore4() load_store_elimination (before) 694 /// CHECK: StaticFieldSet 695 /// CHECK: StaticFieldSet 696 697 /// CHECK-START: void Main.testStoreStore4() load_store_elimination (after) 698 /// CHECK: StaticFieldSet 699 /// CHECK-NOT: StaticFieldSet 700 testStoreStore4()701 private static void testStoreStore4() { 702 TestClass.si = 61; 703 TestClass.si = 62; 704 } 705 706 /// CHECK-START: int Main.testStoreStore5(TestClass2, TestClass2) load_store_elimination (before) 707 /// CHECK: InstanceFieldSet 708 /// CHECK: InstanceFieldGet 709 /// CHECK: InstanceFieldSet 710 711 /// CHECK-START: int Main.testStoreStore5(TestClass2, TestClass2) load_store_elimination (after) 712 /// CHECK: InstanceFieldSet 713 /// CHECK: InstanceFieldGet 714 /// CHECK: InstanceFieldSet 715 testStoreStore5(TestClass2 obj1, TestClass2 obj2)716 private static int testStoreStore5(TestClass2 obj1, TestClass2 obj2) { 717 obj1.i = 71; // This store is needed since obj2.i may load from it. 718 int i = obj2.i; 719 obj1.i = 72; 720 return i; 721 } 722 723 /// CHECK-START: int Main.testStoreStore6(TestClass2, TestClass2) load_store_elimination (before) 724 /// CHECK: InstanceFieldSet 725 /// CHECK: InstanceFieldGet 726 /// CHECK: InstanceFieldSet 727 728 /// CHECK-START: int Main.testStoreStore6(TestClass2, TestClass2) load_store_elimination (after) 729 /// CHECK-NOT: InstanceFieldSet 730 /// CHECK: InstanceFieldGet 731 /// CHECK: InstanceFieldSet 732 testStoreStore6(TestClass2 obj1, TestClass2 obj2)733 private static int testStoreStore6(TestClass2 obj1, TestClass2 obj2) { 734 obj1.i = 81; // This store is not needed since obj2.j cannot load from it. 735 int j = obj2.j; 736 obj1.i = 82; 737 return j; 738 } 739 740 /// CHECK-START: int Main.testNoSideEffects(int[]) load_store_elimination (before) 741 /// CHECK: ArraySet 742 /// CHECK: ArraySet 743 /// CHECK: ArraySet 744 /// CHECK: ArrayGet 745 746 /// CHECK-START: int Main.testNoSideEffects(int[]) load_store_elimination (after) 747 /// CHECK: ArraySet 748 /// CHECK: ArraySet 749 /// CHECK-NOT: ArraySet 750 /// CHECK-NOT: ArrayGet 751 testNoSideEffects(int[] array)752 private static int testNoSideEffects(int[] array) { 753 array[0] = 101; 754 array[1] = 102; 755 int bitCount = Integer.bitCount(0x3456); 756 array[1] = 103; 757 return array[0] + bitCount; 758 } 759 760 /// CHECK-START: void Main.testThrow(TestClass2, java.lang.Exception) load_store_elimination (before) 761 /// CHECK: InstanceFieldSet 762 /// CHECK: Throw 763 764 /// CHECK-START: void Main.testThrow(TestClass2, java.lang.Exception) load_store_elimination (after) 765 /// CHECK: InstanceFieldSet 766 /// CHECK: Throw 767 768 // Make sure throw keeps the store. testThrow(TestClass2 obj, Exception e)769 private static void testThrow(TestClass2 obj, Exception e) throws Exception { 770 obj.i = 55; 771 throw e; 772 } 773 774 /// CHECK-START: int Main.testStoreStoreWithDeoptimize(int[]) load_store_elimination (before) 775 /// CHECK: NewInstance 776 /// CHECK: InstanceFieldSet 777 /// CHECK: InstanceFieldSet 778 /// CHECK: InstanceFieldSet 779 /// CHECK: InstanceFieldSet 780 /// CHECK: Deoptimize 781 /// CHECK: ArraySet 782 /// CHECK: ArraySet 783 /// CHECK: ArraySet 784 /// CHECK: ArraySet 785 /// CHECK: ArrayGet 786 /// CHECK: ArrayGet 787 /// CHECK: ArrayGet 788 /// CHECK: ArrayGet 789 790 /// CHECK-START: int Main.testStoreStoreWithDeoptimize(int[]) load_store_elimination (after) 791 /// CHECK: NewInstance 792 /// CHECK: InstanceFieldSet 793 /// CHECK: InstanceFieldSet 794 /// CHECK-NOT: InstanceFieldSet 795 /// CHECK: Deoptimize 796 /// CHECK: ArraySet 797 /// CHECK: ArraySet 798 /// CHECK: ArraySet 799 /// CHECK: ArraySet 800 /// CHECK-NOT: ArrayGet 801 testStoreStoreWithDeoptimize(int[] arr)802 private static int testStoreStoreWithDeoptimize(int[] arr) { 803 TestClass2 obj = new TestClass2(); 804 obj.i = 41; 805 obj.j = 42; 806 obj.i = 41; 807 obj.j = 43; 808 arr[0] = 1; // One HDeoptimize here. 809 arr[1] = 1; 810 arr[2] = 1; 811 arr[3] = 1; 812 return arr[0] + arr[1] + arr[2] + arr[3]; 813 } 814 815 /// CHECK-START: double Main.getCircleArea(double, boolean) load_store_elimination (before) 816 /// CHECK: NewInstance 817 818 /// CHECK-START: double Main.getCircleArea(double, boolean) load_store_elimination (after) 819 /// CHECK-NOT: NewInstance 820 getCircleArea(double radius, boolean b)821 private static double getCircleArea(double radius, boolean b) { 822 double area = 0d; 823 if (b) { 824 area = new Circle(radius).getArea(); 825 } 826 return area; 827 } 828 829 /// CHECK-START: double Main.testDeoptimize(int[], double[], double) load_store_elimination (before) 830 /// CHECK: Deoptimize 831 /// CHECK: NewInstance 832 /// CHECK: Deoptimize 833 /// CHECK: NewInstance 834 835 /// CHECK-START: double Main.testDeoptimize(int[], double[], double) load_store_elimination (after) 836 /// CHECK: Deoptimize 837 /// CHECK: NewInstance 838 /// CHECK: Deoptimize 839 /// CHECK-NOT: NewInstance 840 testDeoptimize(int[] iarr, double[] darr, double radius)841 private static double testDeoptimize(int[] iarr, double[] darr, double radius) { 842 iarr[0] = 1; // One HDeoptimize here. Not triggered. 843 iarr[1] = 1; 844 Circle circle1 = new Circle(radius); 845 iarr[2] = 1; 846 darr[0] = circle1.getRadius(); // One HDeoptimize here, which holds circle1 live. Triggered. 847 darr[1] = circle1.getRadius(); 848 darr[2] = circle1.getRadius(); 849 darr[3] = circle1.getRadius(); 850 return new Circle(Math.PI).getArea(); 851 } 852 853 /// CHECK-START: int Main.testAllocationEliminationOfArray1() load_store_elimination (before) 854 /// CHECK: NewArray 855 /// CHECK: ArraySet 856 /// CHECK: ArraySet 857 /// CHECK: ArrayGet 858 /// CHECK: ArrayGet 859 /// CHECK: ArrayGet 860 /// CHECK: ArrayGet 861 862 /// CHECK-START: int Main.testAllocationEliminationOfArray1() load_store_elimination (after) 863 /// CHECK-NOT: NewArray 864 /// CHECK-NOT: ArraySet 865 /// CHECK-NOT: ArrayGet testAllocationEliminationOfArray1()866 private static int testAllocationEliminationOfArray1() { 867 int[] array = new int[4]; 868 array[2] = 4; 869 array[3] = 7; 870 return array[0] + array[1] + array[2] + array[3]; 871 } 872 873 /// CHECK-START: int Main.testAllocationEliminationOfArray2() load_store_elimination (before) 874 /// CHECK: NewArray 875 /// CHECK: ArraySet 876 /// CHECK: ArraySet 877 /// CHECK: ArrayGet 878 879 /// CHECK-START: int Main.testAllocationEliminationOfArray2() load_store_elimination (after) 880 /// CHECK: NewArray 881 /// CHECK: ArraySet 882 /// CHECK: ArraySet 883 /// CHECK: ArrayGet testAllocationEliminationOfArray2()884 private static int testAllocationEliminationOfArray2() { 885 // Cannot eliminate array allocation since array is accessed with non-constant 886 // index (only 3 elements to prevent vectorization of the reduction). 887 int[] array = new int[3]; 888 array[1] = 4; 889 array[2] = 7; 890 int sum = 0; 891 for (int e : array) { 892 sum += e; 893 } 894 return sum; 895 } 896 897 /// CHECK-START: int Main.testAllocationEliminationOfArray3(int) load_store_elimination (before) 898 /// CHECK: NewArray 899 /// CHECK: ArraySet 900 /// CHECK: ArrayGet 901 902 /// CHECK-START: int Main.testAllocationEliminationOfArray3(int) load_store_elimination (after) 903 /// CHECK-NOT: NewArray 904 /// CHECK-NOT: ArraySet 905 /// CHECK-NOT: ArrayGet testAllocationEliminationOfArray3(int i)906 private static int testAllocationEliminationOfArray3(int i) { 907 int[] array = new int[4]; 908 array[i] = 4; 909 return array[i]; 910 } 911 912 /// CHECK-START: int Main.testAllocationEliminationOfArray4(int) load_store_elimination (before) 913 /// CHECK: NewArray 914 /// CHECK: ArraySet 915 /// CHECK: ArraySet 916 /// CHECK: ArrayGet 917 /// CHECK: ArrayGet 918 919 /// CHECK-START: int Main.testAllocationEliminationOfArray4(int) load_store_elimination (after) 920 /// CHECK: NewArray 921 /// CHECK: ArraySet 922 /// CHECK: ArraySet 923 /// CHECK: ArrayGet 924 /// CHECK-NOT: ArrayGet testAllocationEliminationOfArray4(int i)925 private static int testAllocationEliminationOfArray4(int i) { 926 // Cannot eliminate array allocation due to index aliasing between 1 and i. 927 int[] array = new int[4]; 928 array[1] = 2; 929 array[i] = 4; 930 return array[1] + array[i]; 931 } 932 933 /// CHECK-START: int Main.testAllocationEliminationOfArray5(int) load_store_elimination (before) 934 /// CHECK: NewArray 935 /// CHECK: ArraySet 936 /// CHECK: ArrayGet 937 938 /// CHECK-START: int Main.testAllocationEliminationOfArray5(int) load_store_elimination (after) 939 /// CHECK: NewArray 940 /// CHECK-NOT: ArraySet 941 /// CHECK-NOT: ArrayGet testAllocationEliminationOfArray5(int i)942 private static int testAllocationEliminationOfArray5(int i) { 943 // Cannot eliminate array allocation due to unknown i that may 944 // cause NegativeArraySizeException. 945 int[] array = new int[i]; 946 array[1] = 12; 947 return array[1]; 948 } 949 950 /// CHECK-START: int Main.testExitMerge(boolean) load_store_elimination (before) 951 /// CHECK: NewInstance 952 /// CHECK: InstanceFieldSet 953 /// CHECK: InstanceFieldGet 954 /// CHECK: Return 955 /// CHECK: InstanceFieldSet 956 /// CHECK: Throw 957 958 /// CHECK-START: int Main.testExitMerge(boolean) load_store_elimination (after) 959 /// CHECK-NOT: NewInstance 960 /// CHECK-NOT: InstanceFieldSet 961 /// CHECK-NOT: InstanceFieldGet 962 /// CHECK: Return 963 /// CHECK-NOT: InstanceFieldSet 964 /// CHECK: Throw testExitMerge(boolean cond)965 private static int testExitMerge(boolean cond) { 966 TestClass obj = new TestClass(); 967 if (cond) { 968 obj.i = 1; 969 return obj.i + 1; 970 } else { 971 obj.i = 2; 972 throw new Error(); 973 } 974 } 975 976 /// CHECK-START: int Main.testExitMerge2(boolean) load_store_elimination (before) 977 /// CHECK: NewInstance 978 /// CHECK: InstanceFieldSet 979 /// CHECK: InstanceFieldGet 980 /// CHECK: InstanceFieldSet 981 /// CHECK: InstanceFieldGet 982 983 /// CHECK-START: int Main.testExitMerge2(boolean) load_store_elimination (after) 984 /// CHECK-NOT: NewInstance 985 /// CHECK-NOT: InstanceFieldSet 986 /// CHECK-NOT: InstanceFieldGet testExitMerge2(boolean cond)987 private static int testExitMerge2(boolean cond) { 988 TestClass obj = new TestClass(); 989 int res; 990 if (cond) { 991 obj.i = 1; 992 res = obj.i + 1; 993 } else { 994 obj.i = 2; 995 res = obj.j + 2; 996 } 997 return res; 998 } 999 1000 /// CHECK-START: void Main.testStoreSameValue() load_store_elimination (before) 1001 /// CHECK: NewArray 1002 /// CHECK: ArrayGet 1003 /// CHECK: ArraySet 1004 1005 /// CHECK-START: void Main.testStoreSameValue() load_store_elimination (after) 1006 /// CHECK: NewArray 1007 /// CHECK-NOT: ArrayGet 1008 /// CHECK-NOT: ArraySet testStoreSameValue()1009 private static void testStoreSameValue() { 1010 Object[] array = new Object[2]; 1011 sArray = array; 1012 Object obj = array[0]; 1013 array[1] = obj; // store the same value as the defaut value. 1014 } 1015 1016 static Object[] sArray; 1017 1018 /// CHECK-START: int Main.testLocalArrayMerge1(boolean) load_store_elimination (before) 1019 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 1020 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 1021 /// CHECK-DAG: <<A:l\d+>> NewArray 1022 /// CHECK-DAG: ArraySet [<<A>>,<<Const0>>,<<Const0>>] 1023 /// CHECK-DAG: ArraySet [<<A>>,<<Const0>>,<<Const1>>] 1024 /// CHECK-DAG: ArraySet [<<A>>,<<Const0>>,<<Const1>>] 1025 /// CHECK-DAG: <<Get:i\d+>> ArrayGet [<<A>>,<<Const0>>] 1026 /// CHECK-DAG: Return [<<Get>>] 1027 // 1028 /// CHECK-START: int Main.testLocalArrayMerge1(boolean) load_store_elimination (after) 1029 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 1030 /// CHECK-DAG: Return [<<Const1>>] 1031 // 1032 /// CHECK-START: int Main.testLocalArrayMerge1(boolean) load_store_elimination (after) 1033 /// CHECK-NOT: NewArray 1034 /// CHECK-NOT: ArraySet 1035 /// CHECK-NOT: ArrayGet testLocalArrayMerge1(boolean x)1036 private static int testLocalArrayMerge1(boolean x) { 1037 // The explicit store can be removed right away 1038 // since it is equivalent to the default. 1039 int[] a = { 0 }; 1040 // The diamond pattern stores/load can be replaced 1041 // by the direct value. 1042 if (x) { 1043 a[0] = 1; 1044 } else { 1045 a[0] = 1; 1046 } 1047 return a[0]; 1048 } 1049 1050 /// CHECK-START: int Main.testLocalArrayMerge2(boolean) load_store_elimination (before) 1051 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 1052 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 1053 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 1054 /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3 1055 /// CHECK-DAG: <<A:l\d+>> NewArray 1056 /// CHECK-DAG: ArraySet [<<A>>,<<Const0>>,<<Const1>>] 1057 /// CHECK-DAG: ArraySet [<<A>>,<<Const0>>,<<Const2>>] 1058 /// CHECK-DAG: ArraySet [<<A>>,<<Const0>>,<<Const3>>] 1059 /// CHECK-DAG: <<Get:i\d+>> ArrayGet [<<A>>,<<Const0>>] 1060 /// CHECK-DAG: Return [<<Get>>] 1061 // 1062 /// CHECK-START: int Main.testLocalArrayMerge2(boolean) load_store_elimination (after) 1063 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 1064 /// CHECK-DAG: <<A:l\d+>> NewArray 1065 /// CHECK-DAG: <<Get:i\d+>> ArrayGet [<<A>>,<<Const0>>] 1066 /// CHECK-DAG: Return [<<Get>>] 1067 // 1068 /// CHECK-START: int Main.testLocalArrayMerge2(boolean) load_store_elimination (after) 1069 /// CHECK-DAG: ArraySet 1070 /// CHECK-DAG: ArraySet 1071 /// CHECK-NOT: ArraySet testLocalArrayMerge2(boolean x)1072 private static int testLocalArrayMerge2(boolean x) { 1073 // The explicit store can be removed eventually even 1074 // though it is not equivalent to the default. 1075 int[] a = { 1 }; 1076 // The diamond pattern stores/load remain. 1077 if (x) { 1078 a[0] = 2; 1079 } else { 1080 a[0] = 3; 1081 } 1082 return a[0]; 1083 } 1084 1085 /// CHECK-START: int Main.testLocalArrayMerge3(boolean) load_store_elimination (after) 1086 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 1087 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 1088 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 1089 /// CHECK-DAG: <<A:l\d+>> NewArray 1090 /// CHECK-DAG: ArraySet [<<A>>,<<Const0>>,<<Const1>>] 1091 /// CHECK-DAG: ArraySet [<<A>>,<<Const0>>,<<Const2>>] 1092 /// CHECK-DAG: <<Get:i\d+>> ArrayGet [<<A>>,<<Const0>>] 1093 /// CHECK-DAG: Return [<<Get>>] testLocalArrayMerge3(boolean x)1094 private static int testLocalArrayMerge3(boolean x) { 1095 // All stores/load remain. 1096 int[] a = { 1 }; 1097 if (x) { 1098 a[0] = 2; 1099 } 1100 return a[0]; 1101 } 1102 1103 /// CHECK-START: int Main.testLocalArrayMerge4(boolean) load_store_elimination (before) 1104 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 1105 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 1106 /// CHECK-DAG: <<A:l\d+>> NewArray 1107 /// CHECK-DAG: ArraySet [<<A>>,<<Const0>>,<<Const0>>] 1108 /// CHECK-DAG: ArraySet [<<A>>,<<Const0>>,<<Const1>>] 1109 /// CHECK-DAG: ArraySet [<<A>>,<<Const0>>,<<Const1>>] 1110 /// CHECK-DAG: <<Get1:b\d+>> ArrayGet [<<A>>,<<Const0>>] 1111 /// CHECK-DAG: <<Get2:a\d+>> ArrayGet [<<A>>,<<Const0>>] 1112 /// CHECK-DAG: <<Add:i\d+>> Add [<<Get1>>,<<Get2>>] 1113 /// CHECK-DAG: Return [<<Add>>] 1114 // 1115 /// CHECK-START: int Main.testLocalArrayMerge4(boolean) load_store_elimination (after) 1116 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 1117 /// CHECK-DAG: <<Cnv1:b\d+>> TypeConversion [<<Const1>>] 1118 /// CHECK-DAG: <<Cnv2:a\d+>> TypeConversion [<<Const1>>] 1119 /// CHECK-DAG: <<Add:i\d+>> Add [<<Cnv1>>,<<Cnv2>>] 1120 /// CHECK-DAG: Return [<<Add>>] 1121 // 1122 /// CHECK-START: int Main.testLocalArrayMerge4(boolean) load_store_elimination (after) 1123 /// CHECK-NOT: NewArray 1124 /// CHECK-NOT: ArraySet 1125 /// CHECK-NOT: ArrayGet testLocalArrayMerge4(boolean x)1126 private static int testLocalArrayMerge4(boolean x) { 1127 byte[] a = { 0 }; 1128 if (x) { 1129 a[0] = 1; 1130 } else { 1131 a[0] = 1; 1132 } 1133 // Differently typed (signed vs unsigned), 1134 // but same reference. 1135 return a[0] + (a[0] & 0xff); 1136 } 1137 assertIntEquals(int result, int expected)1138 static void assertIntEquals(int result, int expected) { 1139 if (expected != result) { 1140 throw new Error("Expected: " + expected + ", found: " + result); 1141 } 1142 } 1143 assertFloatEquals(float result, float expected)1144 static void assertFloatEquals(float result, float expected) { 1145 if (expected != result) { 1146 throw new Error("Expected: " + expected + ", found: " + result); 1147 } 1148 } 1149 assertDoubleEquals(double result, double expected)1150 static void assertDoubleEquals(double result, double expected) { 1151 if (expected != result) { 1152 throw new Error("Expected: " + expected + ", found: " + result); 1153 } 1154 } 1155 main(String[] args)1156 public static void main(String[] args) throws Exception { 1157 1158 Class main2 = Class.forName("Main2"); 1159 Method test4 = main2.getMethod("test4", TestClass.class, boolean.class); 1160 Method test5 = main2.getMethod("test5", TestClass.class, boolean.class); 1161 Method test10 = main2.getMethod("test10", TestClass.class); 1162 Method test23 = main2.getMethod("test23", boolean.class); 1163 Method test24 = main2.getMethod("test24"); 1164 1165 assertDoubleEquals(Math.PI * Math.PI * Math.PI, calcCircleArea(Math.PI)); 1166 assertIntEquals(test1(new TestClass(), new TestClass()), 3); 1167 assertIntEquals(test2(new TestClass()), 1); 1168 TestClass obj1 = new TestClass(); 1169 TestClass obj2 = new TestClass(); 1170 obj1.next = obj2; 1171 assertIntEquals(test3(obj1), 10); 1172 assertIntEquals((int)test4.invoke(null, new TestClass(), true), 1); 1173 assertIntEquals((int)test4.invoke(null, new TestClass(), false), 1); 1174 assertIntEquals((int)test5.invoke(null, new TestClass(), true), 1); 1175 assertIntEquals((int)test5.invoke(null, new TestClass(), false), 2); 1176 assertIntEquals(test6(new TestClass(), new TestClass(), true), 4); 1177 assertIntEquals(test6(new TestClass(), new TestClass(), false), 2); 1178 assertIntEquals(test7(new TestClass()), 1); 1179 assertIntEquals(test8(), 1); 1180 obj1 = new TestClass(); 1181 obj2 = new TestClass(); 1182 obj1.next = obj2; 1183 assertIntEquals(test9(new TestClass()), 1); 1184 assertIntEquals((int)test10.invoke(null, new TestClass(3, 4)), 3); 1185 assertIntEquals(TestClass.si, 3); 1186 assertIntEquals(test11(new TestClass()), 10); 1187 assertIntEquals(test12(new TestClass(), new TestClass()), 10); 1188 assertIntEquals(test13(new TestClass(), new TestClass2()), 3); 1189 SubTestClass obj3 = new SubTestClass(); 1190 assertIntEquals(test14(obj3, obj3), 2); 1191 assertIntEquals(test15(), 2); 1192 assertIntEquals(test16(), 3); 1193 assertIntEquals(test17(), 0); 1194 assertIntEquals(test18(new TestClass()), 1); 1195 float[] fa1 = { 0.8f }; 1196 float[] fa2 = { 1.8f }; 1197 assertFloatEquals(test19(fa1, fa2), 1.8f); 1198 assertFloatEquals(test20().i, 0); 1199 test21(new TestClass()); 1200 assertIntEquals(test22(), 13); 1201 assertIntEquals((int)test23.invoke(null, true), 4); 1202 assertIntEquals((int)test23.invoke(null, false), 5); 1203 assertFloatEquals((float)test24.invoke(null), 8.0f); 1204 testFinalizableByForcingGc(); 1205 assertIntEquals($noinline$testHSelect(true), 0xdead); 1206 int[] array = {2, 5, 9, -1, -3, 10, 8, 4}; 1207 assertIntEquals(sumWithinRange(array, 1, 5), 11); 1208 assertFloatEquals(testAllocationEliminationWithLoops(), 1.0f); 1209 assertFloatEquals(mF, 0f); 1210 assertDoubleEquals(Math.PI * Math.PI * Math.PI, getCircleArea(Math.PI, true)); 1211 assertDoubleEquals(0d, getCircleArea(Math.PI, false)); 1212 1213 int[] iarray = {0, 0, 0}; 1214 double[] darray = {0d, 0d, 0d}; 1215 try { 1216 assertDoubleEquals(Math.PI * Math.PI * Math.PI, testDeoptimize(iarray, darray, Math.PI)); 1217 } catch (Exception e) { 1218 System.out.println(e); 1219 } 1220 assertIntEquals(iarray[0], 1); 1221 assertIntEquals(iarray[1], 1); 1222 assertIntEquals(iarray[2], 1); 1223 assertDoubleEquals(darray[0], Math.PI); 1224 assertDoubleEquals(darray[1], Math.PI); 1225 assertDoubleEquals(darray[2], Math.PI); 1226 1227 assertIntEquals(testAllocationEliminationOfArray1(), 11); 1228 assertIntEquals(testAllocationEliminationOfArray2(), 11); 1229 assertIntEquals(testAllocationEliminationOfArray3(2), 4); 1230 assertIntEquals(testAllocationEliminationOfArray4(2), 6); 1231 assertIntEquals(testAllocationEliminationOfArray5(2), 12); 1232 try { 1233 testAllocationEliminationOfArray5(-2); 1234 } catch (NegativeArraySizeException e) { 1235 System.out.println("Got NegativeArraySizeException."); 1236 } 1237 1238 assertIntEquals(testStoreStore().i, 41); 1239 assertIntEquals(testStoreStore().j, 43); 1240 1241 assertIntEquals(testExitMerge(true), 2); 1242 assertIntEquals(testExitMerge2(true), 2); 1243 assertIntEquals(testExitMerge2(false), 2); 1244 1245 TestClass2 testclass2 = new TestClass2(); 1246 testStoreStore2(testclass2); 1247 assertIntEquals(testclass2.i, 43); 1248 assertIntEquals(testclass2.j, 44); 1249 1250 testStoreStore3(testclass2, true); 1251 assertIntEquals(testclass2.i, 41); 1252 assertIntEquals(testclass2.j, 43); 1253 testStoreStore3(testclass2, false); 1254 assertIntEquals(testclass2.i, 41); 1255 assertIntEquals(testclass2.j, 44); 1256 1257 testStoreStore4(); 1258 assertIntEquals(TestClass.si, 62); 1259 1260 int ret = testStoreStore5(testclass2, testclass2); 1261 assertIntEquals(testclass2.i, 72); 1262 assertIntEquals(ret, 71); 1263 1264 testclass2.j = 88; 1265 ret = testStoreStore6(testclass2, testclass2); 1266 assertIntEquals(testclass2.i, 82); 1267 assertIntEquals(ret, 88); 1268 1269 ret = testNoSideEffects(iarray); 1270 assertIntEquals(iarray[0], 101); 1271 assertIntEquals(iarray[1], 103); 1272 assertIntEquals(ret, 108); 1273 1274 try { 1275 testThrow(testclass2, new Exception()); 1276 } catch (Exception e) {} 1277 assertIntEquals(testclass2.i, 55); 1278 1279 assertIntEquals(testStoreStoreWithDeoptimize(new int[4]), 4); 1280 1281 assertIntEquals(testLocalArrayMerge1(true), 1); 1282 assertIntEquals(testLocalArrayMerge1(false), 1); 1283 assertIntEquals(testLocalArrayMerge2(true), 2); 1284 assertIntEquals(testLocalArrayMerge2(false), 3); 1285 assertIntEquals(testLocalArrayMerge3(true), 2); 1286 assertIntEquals(testLocalArrayMerge3(false), 1); 1287 assertIntEquals(testLocalArrayMerge4(true), 2); 1288 assertIntEquals(testLocalArrayMerge4(false), 2); 1289 } 1290 1291 static boolean sFlag; 1292 } 1293