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 public class Main { 18 19 /// CHECK-START: int Main.sieve(int) BCE (before) 20 /// CHECK: BoundsCheck 21 /// CHECK: ArraySet 22 /// CHECK: BoundsCheck 23 /// CHECK: ArrayGet 24 /// CHECK: BoundsCheck 25 /// CHECK: ArraySet 26 27 /// CHECK-START: int Main.sieve(int) BCE (after) 28 /// CHECK-NOT: BoundsCheck 29 /// CHECK: ArraySet 30 /// CHECK-NOT: BoundsCheck 31 /// CHECK: ArrayGet 32 /// CHECK: BoundsCheck 33 /// CHECK: ArraySet 34 sieve(int size)35 static int sieve(int size) { 36 int primeCount = 0; 37 boolean[] flags = new boolean[size + 1]; 38 for (int i = 1; i < size; i++) flags[i] = true; // Can eliminate. 39 for (int i = 2; i < size; i++) { 40 if (flags[i]) { // Can eliminate. 41 primeCount++; 42 for (int k = i + 1; k <= size; k += i) 43 flags[k - 1] = false; // Can't eliminate yet due to (k+i) may overflow. 44 } 45 } 46 return primeCount; 47 } 48 49 50 /// CHECK-START: void Main.narrow(int[], int) BCE (before) 51 /// CHECK: BoundsCheck 52 /// CHECK: ArraySet 53 /// CHECK: BoundsCheck 54 /// CHECK: ArraySet 55 /// CHECK: BoundsCheck 56 /// CHECK: ArraySet 57 58 /// CHECK-START: void Main.narrow(int[], int) BCE (after) 59 /// CHECK-NOT: BoundsCheck 60 /// CHECK: ArraySet 61 /// CHECK-NOT: BoundsCheck 62 /// CHECK: ArraySet 63 /// CHECK: BoundsCheck 64 /// CHECK: ArraySet 65 /// CHECK-NOT: BoundsCheck 66 /// CHECK: ArraySet 67 /// CHECK: BoundsCheck 68 /// CHECK: ArraySet 69 narrow(int[] array, int offset)70 static void narrow(int[] array, int offset) { 71 if (offset < 0) { 72 return; 73 } 74 if (offset < array.length) { 75 // offset is in range [0, array.length-1]. 76 // Bounds check can be eliminated. 77 array[offset] = 1; 78 79 int biased_offset1 = offset + 1; 80 // biased_offset1 is in range [1, array.length]. 81 if (biased_offset1 < array.length) { 82 // biased_offset1 is in range [1, array.length-1]. 83 // Bounds check can be eliminated. 84 array[biased_offset1] = 1; 85 } 86 87 int biased_offset2 = offset + 0x70000000; 88 // biased_offset2 is in range [0x70000000, array.length-1+0x70000000]. 89 // It may overflow and be negative. 90 if (biased_offset2 < array.length) { 91 // Even with this test, biased_offset2 can be negative so we can't 92 // eliminate this bounds check. 93 array[biased_offset2] = 1; 94 } 95 96 // offset_sub1 won't underflow since offset is no less than 0. 97 int offset_sub1 = offset - Integer.MAX_VALUE; 98 if (offset_sub1 >= 0) { 99 array[offset_sub1] = 1; // Bounds check can be eliminated. 100 } 101 102 // offset_sub2 can underflow. 103 int offset_sub2 = offset_sub1 - Integer.MAX_VALUE; 104 if (offset_sub2 >= 0) { 105 array[offset_sub2] = 1; // Bounds check can't be eliminated. 106 } 107 } 108 } 109 110 111 /// CHECK-START: void Main.constantIndexing1(int[]) BCE (before) 112 /// CHECK: BoundsCheck 113 /// CHECK: ArraySet 114 /// CHECK: BoundsCheck 115 /// CHECK: ArraySet 116 117 /// CHECK-START: void Main.constantIndexing1(int[]) BCE (after) 118 /// CHECK-NOT: Deoptimize 119 /// CHECK: BoundsCheck 120 /// CHECK: ArraySet 121 /// CHECK-NOT: BoundsCheck 122 /// CHECK: ArraySet 123 constantIndexing1(int[] array)124 static void constantIndexing1(int[] array) { 125 // Decreasing order: bc for 5 but not for 4. 126 array[5] = 11; 127 array[4] = 11; 128 } 129 130 131 /// CHECK-START: void Main.$opt$noinline$constantIndexing2(int[]) BCE (before) 132 /// CHECK: BoundsCheck 133 /// CHECK: ArraySet 134 /// CHECK: BoundsCheck 135 /// CHECK: ArraySet 136 /// CHECK: BoundsCheck 137 /// CHECK: ArraySet 138 /// CHECK: BoundsCheck 139 /// CHECK: ArraySet 140 141 /// CHECK-START: void Main.$opt$noinline$constantIndexing2(int[]) BCE (after) 142 /// CHECK: Deoptimize 143 /// CHECK-NOT: BoundsCheck 144 /// CHECK: ArraySet 145 /// CHECK-NOT: BoundsCheck 146 /// CHECK: ArraySet 147 /// CHECK-NOT: BoundsCheck 148 /// CHECK: ArraySet 149 /// CHECK-NOT: BoundsCheck 150 /// CHECK: ArraySet 151 $opt$noinline$constantIndexing2(int[] array)152 static void $opt$noinline$constantIndexing2(int[] array) { 153 array[1] = 1; 154 array[2] = 1; 155 array[3] = 1; 156 array[4] = 1; 157 if (array[1] != 1) { 158 throw new Error(""); 159 } 160 } 161 162 /// CHECK-START: void Main.constantIndexing2b(int[]) BCE (before) 163 /// CHECK: BoundsCheck 164 /// CHECK: ArraySet 165 /// CHECK: BoundsCheck 166 /// CHECK: ArraySet 167 /// CHECK: BoundsCheck 168 /// CHECK: ArraySet 169 /// CHECK: BoundsCheck 170 /// CHECK: ArraySet 171 /// CHECK: BoundsCheck 172 /// CHECK: ArraySet 173 174 /// CHECK-START: void Main.constantIndexing2b(int[]) BCE (after) 175 /// CHECK-NOT: Deoptimize 176 /// CHECK: BoundsCheck 177 /// CHECK: ArraySet 178 /// CHECK: BoundsCheck 179 /// CHECK: ArraySet 180 /// CHECK: BoundsCheck 181 /// CHECK: ArraySet 182 /// CHECK: BoundsCheck 183 /// CHECK: ArraySet 184 /// CHECK: BoundsCheck 185 /// CHECK: ArraySet 186 constantIndexing2b(int[] array)187 static void constantIndexing2b(int[] array) { 188 array[0] = 6; 189 array[1] = 6; 190 array[2] = 6; 191 array[3] = 6; 192 array[-1] = 1; // prevents the whole opt on [-1:4] 193 } 194 195 /// CHECK-START: void Main.constantIndexing2c(int[]) BCE (before) 196 /// CHECK: BoundsCheck 197 /// CHECK: ArraySet 198 /// CHECK: BoundsCheck 199 /// CHECK: ArraySet 200 /// CHECK: BoundsCheck 201 /// CHECK: ArraySet 202 /// CHECK: BoundsCheck 203 /// CHECK: ArraySet 204 205 /// CHECK-START: void Main.constantIndexing2c(int[]) BCE (after) 206 /// CHECK: Deoptimize 207 /// CHECK-NOT: BoundsCheck 208 /// CHECK: ArraySet 209 /// CHECK-NOT: BoundsCheck 210 /// CHECK: ArraySet 211 /// CHECK-NOT: BoundsCheck 212 /// CHECK: ArraySet 213 /// CHECK-NOT: BoundsCheck 214 /// CHECK: ArraySet 215 constantIndexing2c(int[] array)216 static void constantIndexing2c(int[] array) { 217 array[0] = 7; 218 array[1] = 7; 219 array[2] = 7; 220 array[3] = 7; 221 } 222 223 /// CHECK-START: int[] Main.constantIndexing3(int[], int[], boolean) BCE (before) 224 /// CHECK: BoundsCheck 225 /// CHECK: ArrayGet 226 /// CHECK: BoundsCheck 227 /// CHECK: ArraySet 228 /// CHECK: BoundsCheck 229 /// CHECK: ArrayGet 230 /// CHECK: BoundsCheck 231 /// CHECK: ArraySet 232 /// CHECK: BoundsCheck 233 /// CHECK: ArrayGet 234 /// CHECK: BoundsCheck 235 /// CHECK: ArraySet 236 /// CHECK: BoundsCheck 237 /// CHECK: ArrayGet 238 /// CHECK: BoundsCheck 239 /// CHECK: ArraySet 240 241 /// CHECK-START: int[] Main.constantIndexing3(int[], int[], boolean) BCE (after) 242 /// CHECK: Deoptimize 243 /// CHECK-NOT: BoundsCheck 244 /// CHECK: ArrayGet 245 /// CHECK: Deoptimize 246 /// CHECK-NOT: BoundsCheck 247 /// CHECK: ArraySet 248 /// CHECK-NOT: BoundsCheck 249 /// CHECK: ArrayGet 250 /// CHECK-NOT: BoundsCheck 251 /// CHECK: ArraySet 252 /// CHECK-NOT: BoundsCheck 253 /// CHECK: ArrayGet 254 /// CHECK-NOT: BoundsCheck 255 /// CHECK: ArraySet 256 /// CHECK-NOT: BoundsCheck 257 /// CHECK: ArrayGet 258 /// CHECK-NOT: BoundsCheck 259 /// CHECK: ArraySet 260 constantIndexing3(int[] array1, int[] array2, boolean copy)261 static int[] constantIndexing3(int[] array1, int[] array2, boolean copy) { 262 if (!copy) { 263 return array1; 264 } 265 array2[0] = array1[0]; 266 array2[1] = array1[1]; 267 array2[2] = array1[2]; 268 array2[3] = array1[3]; 269 return array2; 270 } 271 272 273 /// CHECK-START: void Main.constantIndexing4(int[]) BCE (before) 274 /// CHECK: BoundsCheck 275 /// CHECK: ArraySet 276 277 /// CHECK-START: void Main.constantIndexing4(int[]) BCE (after) 278 /// CHECK-NOT: Deoptimize 279 /// CHECK: BoundsCheck 280 /// CHECK: ArraySet 281 282 // There is only one array access. It's not beneficial 283 // to create a compare with deoptimization instruction. constantIndexing4(int[] array)284 static void constantIndexing4(int[] array) { 285 array[0] = -1; 286 } 287 288 289 /// CHECK-START: void Main.constantIndexing5(int[]) BCE (before) 290 /// CHECK: BoundsCheck 291 /// CHECK: ArraySet 292 /// CHECK: BoundsCheck 293 /// CHECK: ArraySet 294 295 /// CHECK-START: void Main.constantIndexing5(int[]) BCE (after) 296 /// CHECK-NOT: Deoptimize 297 /// CHECK: BoundsCheck 298 /// CHECK: ArraySet 299 /// CHECK: BoundsCheck 300 /// CHECK: ArraySet 301 constantIndexing5(int[] array)302 static void constantIndexing5(int[] array) { 303 // We don't apply the deoptimization for very large constant index 304 // since it's likely to be an anomaly and will throw AIOOBE. 305 array[Integer.MAX_VALUE - 1000] = 1; 306 array[Integer.MAX_VALUE - 999] = 1; 307 array[Integer.MAX_VALUE - 998] = 1; 308 } 309 310 /// CHECK-START: void Main.constantIndexing6(int[]) BCE (before) 311 /// CHECK: BoundsCheck 312 /// CHECK: ArraySet 313 /// CHECK: BoundsCheck 314 /// CHECK: ArraySet 315 316 /// CHECK-START: void Main.constantIndexing6(int[]) BCE (after) 317 /// CHECK: Deoptimize 318 /// CHECK-NOT: BoundsCheck 319 /// CHECK: ArraySet 320 /// CHECK-NOT: BoundsCheck 321 /// CHECK: ArraySet 322 constantIndexing6(int[] array)323 static void constantIndexing6(int[] array) { 324 array[3] = 111; 325 array[4] = 111; 326 } 327 328 /// CHECK-START: void Main.constantIndexing7(int[], int) BCE (before) 329 /// CHECK: BoundsCheck 330 /// CHECK: ArraySet 331 /// CHECK: BoundsCheck 332 /// CHECK: ArraySet 333 /// CHECK: BoundsCheck 334 /// CHECK: ArraySet 335 /// CHECK: BoundsCheck 336 /// CHECK: ArraySet 337 338 /// CHECK-START: void Main.constantIndexing7(int[], int) BCE (after) 339 /// CHECK: Deoptimize 340 /// CHECK: Deoptimize 341 /// CHECK-NOT: BoundsCheck 342 /// CHECK: ArraySet 343 /// CHECK-NOT: BoundsCheck 344 /// CHECK: ArraySet 345 /// CHECK-NOT: BoundsCheck 346 /// CHECK: ArraySet 347 /// CHECK-NOT: BoundsCheck 348 /// CHECK: ArraySet 349 constantIndexing7(int[] array, int base)350 static void constantIndexing7(int[] array, int base) { 351 // With constant offsets to symbolic base. 352 array[base] = 10; 353 array[base + 1] = 20; 354 array[base + 2] = 30; 355 array[base + 3] = 40; 356 } 357 358 /// CHECK-START: void Main.constantIndexing8(int[], int) BCE (before) 359 /// CHECK: BoundsCheck 360 /// CHECK: ArraySet 361 /// CHECK: BoundsCheck 362 /// CHECK: ArraySet 363 /// CHECK: BoundsCheck 364 /// CHECK: ArraySet 365 /// CHECK: BoundsCheck 366 /// CHECK: ArraySet 367 368 /// CHECK-START: void Main.constantIndexing8(int[], int) BCE (after) 369 /// CHECK: Deoptimize 370 /// CHECK: Deoptimize 371 /// CHECK-NOT: BoundsCheck 372 /// CHECK: ArraySet 373 /// CHECK-NOT: BoundsCheck 374 /// CHECK: ArraySet 375 /// CHECK-NOT: BoundsCheck 376 /// CHECK: ArraySet 377 /// CHECK-NOT: BoundsCheck 378 /// CHECK: ArraySet 379 constantIndexing8(int[] array, int base)380 static void constantIndexing8(int[] array, int base) { 381 // With constant offsets "both ways" to symbolic base. 382 array[base - 1] = 100; 383 array[base] = 200; 384 array[base + 1] = 300; 385 array[base + 2] = 400; 386 } 387 388 /// CHECK-START: void Main.constantIndexing9(int[], int) BCE (before) 389 /// CHECK: BoundsCheck 390 /// CHECK: ArraySet 391 /// CHECK: BoundsCheck 392 /// CHECK: ArraySet 393 /// CHECK: BoundsCheck 394 /// CHECK: ArraySet 395 /// CHECK: BoundsCheck 396 /// CHECK: ArraySet 397 398 /// CHECK-START: void Main.constantIndexing9(int[], int) BCE (after) 399 /// CHECK: Deoptimize 400 /// CHECK: Deoptimize 401 /// CHECK-NOT: BoundsCheck 402 /// CHECK: ArraySet 403 /// CHECK-NOT: BoundsCheck 404 /// CHECK: ArraySet 405 /// CHECK-NOT: BoundsCheck 406 /// CHECK: ArraySet 407 /// CHECK-NOT: BoundsCheck 408 /// CHECK: ArraySet 409 /// CHECK-NOT: BoundsCheck 410 constantIndexing9(int[] array, int base)411 static void constantIndexing9(int[] array, int base) { 412 // Final range is base..base+3 so conditional 413 // references may be included in the end. 414 array[base] = 0; 415 if (base != 12345) 416 array[base + 2] = 2; 417 array[base + 3] = 3; 418 if (base != 67890) 419 array[base + 1] = 1; 420 } 421 422 /// CHECK-START: void Main.constantIndexing10(int[], int) BCE (before) 423 /// CHECK: BoundsCheck 424 /// CHECK: ArraySet 425 /// CHECK: BoundsCheck 426 /// CHECK: ArraySet 427 /// CHECK: BoundsCheck 428 /// CHECK: ArraySet 429 /// CHECK: BoundsCheck 430 /// CHECK: ArraySet 431 432 /// CHECK-START: void Main.constantIndexing10(int[], int) BCE (after) 433 /// CHECK: Deoptimize 434 /// CHECK: Deoptimize 435 /// CHECK-NOT: BoundsCheck 436 /// CHECK: ArraySet 437 /// CHECK-NOT: BoundsCheck 438 /// CHECK: ArraySet 439 /// CHECK-NOT: BoundsCheck 440 /// CHECK: ArraySet 441 /// CHECK-NOT: BoundsCheck 442 /// CHECK: ArraySet 443 constantIndexing10(int[] array, int base)444 static void constantIndexing10(int[] array, int base) { 445 // Offset hidden in incremented base. 446 array[base] = 1; 447 array[++base] = 2; 448 array[++base] = 3; 449 array[++base] = 4; 450 } 451 runAllConstantIndices()452 static void runAllConstantIndices() { 453 int[] a1 = { 0 }; 454 int[] a6 = { 0, 0, 0, 0, 0, 0 }; 455 456 boolean caught = false; 457 try { 458 constantIndexing1(a1); 459 } catch (ArrayIndexOutOfBoundsException e) { 460 caught = true; 461 } 462 if (!caught) { 463 System.out.println("constant indices 1 failed!"); 464 } 465 466 constantIndexing1(a6); 467 if (a6[4] != 11 || a6[5] != 11) { 468 System.out.println("constant indices 1 failed!"); 469 } 470 471 $opt$noinline$constantIndexing2(a6); 472 if (a6[0] != 0 || a6[1] != 1 || a6[2] != 1 || 473 a6[3] != 1 || a6[4] != 1 || a6[5] != 11) { 474 System.out.println("constant indices 2 failed!"); 475 } 476 477 caught = false; 478 try { 479 constantIndexing2b(a6); 480 } catch (ArrayIndexOutOfBoundsException e) { 481 caught = true; 482 } 483 if (!caught || a6[0] != 6 || a6[1] != 6 || a6[2] != 6 || 484 a6[3] != 6 || a6[4] != 1 || a6[5] != 11) { 485 System.out.println("constant indices 2b failed!"); 486 } 487 488 caught = false; 489 try { 490 constantIndexing2c(a1); 491 } catch (ArrayIndexOutOfBoundsException e) { 492 caught = true; 493 } 494 if (!caught || a1[0] != 7) { 495 System.out.println("constant indices 2c failed!"); 496 } 497 498 constantIndexing2c(a6); 499 if (a6[0] != 7 || a6[1] != 7 || a6[2] != 7 || 500 a6[3] != 7 || a6[4] != 1 || a6[5] != 11) { 501 System.out.println("constant indices 2c failed!"); 502 } 503 504 int[] b4 = new int[4]; 505 constantIndexing3(a6, b4, true); 506 if (b4[0] != 7 || b4[1] != 7 || b4[2] != 7 || b4[3] != 7) { 507 System.out.println("constant indices 3 failed!"); 508 } 509 510 constantIndexing4(a1); 511 if (a1[0] != -1) { 512 System.out.println("constant indices 4 failed!"); 513 } 514 515 caught = false; 516 try { 517 constantIndexing5(a6); 518 } catch (ArrayIndexOutOfBoundsException e) { 519 caught = true; 520 } 521 if (!caught) { 522 System.out.println("constant indices 5 failed!"); 523 } 524 525 constantIndexing6(a6); 526 if (a6[0] != 7 || a6[1] != 7 || a6[2] != 7 || 527 a6[3] != 111 || a6[4] != 111 || a6[5] != 11) { 528 System.out.println("constant indices 6 failed!"); 529 } 530 531 constantIndexing7(a6, 1); 532 if (a6[0] != 7 || a6[1] != 10 || a6[2] != 20 || 533 a6[3] != 30 || a6[4] != 40 || a6[5] != 11) { 534 System.out.println("constant indices 7 failed!"); 535 } 536 537 caught = false; 538 try { 539 constantIndexing7(a6, 5); 540 } catch (ArrayIndexOutOfBoundsException e) { 541 caught = true; 542 } 543 if (!caught || a6[0] != 7 || a6[1] != 10 || a6[2] != 20 || 544 a6[3] != 30 || a6[4] != 40 || a6[5] != 10) { 545 System.out.println("constant indices 7 failed!"); 546 } 547 548 constantIndexing8(a6, 1); 549 if (a6[0] != 100 || a6[1] != 200 || a6[2] != 300 || 550 a6[3] != 400 || a6[4] != 40 || a6[5] != 10) { 551 System.out.println("constant indices 8 failed!"); 552 } 553 554 caught = false; 555 try { 556 constantIndexing8(a6, 0); 557 } catch (ArrayIndexOutOfBoundsException e) { 558 caught = true; 559 } 560 if (!caught || a6[0] != 100) { 561 System.out.println("constant indices 8 failed!"); 562 } 563 564 constantIndexing9(a6, 0); 565 if (a6[0] != 0 || a6[1] != 1 || a6[2] != 2 || 566 a6[3] != 3 || a6[4] != 40 || a6[5] != 10) { 567 System.out.println("constant indices 9 failed!"); 568 } 569 570 constantIndexing10(a6, 0); 571 if (a6[0] != 1 || a6[1] != 2 || a6[2] != 3 || 572 a6[3] != 4 || a6[4] != 40 || a6[5] != 10) { 573 System.out.println("constant indices 10 failed!"); 574 } 575 } 576 577 // A helper into which the actual throwing function should be inlined. constantIndexingForward6(int[] array)578 static void constantIndexingForward6(int[] array) { 579 assertIsManaged(); 580 constantIndexing6(array); 581 } 582 583 /// CHECK-START: void Main.loopPattern1(int[]) BCE (before) 584 /// CHECK: BoundsCheck 585 /// CHECK: ArraySet 586 /// CHECK: BoundsCheck 587 /// CHECK: ArraySet 588 /// CHECK: BoundsCheck 589 /// CHECK: ArraySet 590 /// CHECK: BoundsCheck 591 /// CHECK: ArraySet 592 /// CHECK: BoundsCheck 593 /// CHECK: ArraySet 594 /// CHECK: BoundsCheck 595 /// CHECK: ArraySet 596 /// CHECK: BoundsCheck 597 /// CHECK: ArraySet 598 599 /// CHECK-START: void Main.loopPattern1(int[]) BCE (after) 600 /// CHECK-NOT: BoundsCheck 601 /// CHECK: ArraySet 602 /// CHECK-NOT: BoundsCheck 603 /// CHECK: ArraySet 604 /// CHECK-NOT: BoundsCheck 605 /// CHECK: ArraySet 606 /// CHECK: BoundsCheck 607 /// CHECK: ArraySet 608 /// CHECK: BoundsCheck 609 /// CHECK: ArraySet 610 /// CHECK: BoundsCheck 611 /// CHECK: ArraySet 612 /// CHECK-NOT: BoundsCheck 613 /// CHECK: ArraySet 614 loopPattern1(int[] array)615 static void loopPattern1(int[] array) { 616 for (int i = 0; i < array.length; i++) { 617 array[i] = 1; // Bounds check can be eliminated. 618 } 619 620 for (int i = 1; i < array.length; i++) { 621 array[i] = 1; // Bounds check can be eliminated. 622 } 623 624 for (int i = 1; i < array.length - 1; i++) { 625 array[i] = 1; // Bounds check can be eliminated. 626 } 627 628 for (int i = -1; i < array.length; i++) { 629 array[i] = 1; // Bounds check can't be eliminated. 630 } 631 632 for (int i = 0; i <= array.length; i++) { 633 array[i] = 1; // Bounds check can't be eliminated. 634 } 635 636 for (int i = 0; i < array.length; i += 2) { 637 // We don't have any assumption on max array length yet. 638 // Bounds check can't be eliminated due to overflow concern. 639 array[i] = 1; 640 } 641 642 for (int i = 1; i < array.length; i += 2) { 643 // Bounds check can be eliminated since i is odd so the last 644 // i that's less than array.length is at most (Integer.MAX_VALUE - 2). 645 array[i] = 1; 646 } 647 } 648 649 650 /// CHECK-START: void Main.loopPattern2(int[]) BCE (before) 651 /// CHECK: BoundsCheck 652 /// CHECK: ArraySet 653 /// CHECK: BoundsCheck 654 /// CHECK: ArraySet 655 /// CHECK: BoundsCheck 656 /// CHECK: ArraySet 657 /// CHECK: BoundsCheck 658 /// CHECK: ArraySet 659 /// CHECK: BoundsCheck 660 /// CHECK: ArraySet 661 /// CHECK: BoundsCheck 662 /// CHECK: ArraySet 663 664 /// CHECK-START: void Main.loopPattern2(int[]) BCE (after) 665 /// CHECK-NOT: BoundsCheck 666 /// CHECK: ArraySet 667 /// CHECK-NOT: BoundsCheck 668 /// CHECK: ArraySet 669 /// CHECK-NOT: BoundsCheck 670 /// CHECK: ArraySet 671 /// CHECK: BoundsCheck 672 /// CHECK: ArraySet 673 /// CHECK: BoundsCheck 674 /// CHECK: ArraySet 675 /// CHECK-NOT: BoundsCheck 676 /// CHECK: ArraySet 677 loopPattern2(int[] array)678 static void loopPattern2(int[] array) { 679 for (int i = array.length - 1; i >= 0; i--) { 680 array[i] = 1; // Bounds check can be eliminated. 681 } 682 683 for (int i = array.length; i > 0; i--) { 684 array[i - 1] = 1; // Bounds check can be eliminated. 685 } 686 687 for (int i = array.length - 1; i > 0; i--) { 688 array[i] = 1; // Bounds check can be eliminated. 689 } 690 691 for (int i = array.length; i >= 0; i--) { 692 array[i] = 1; // Bounds check can't be eliminated. 693 } 694 695 for (int i = array.length; i >= 0; i--) { 696 array[i - 1] = 1; // Bounds check can't be eliminated. 697 } 698 699 for (int i = array.length; i > 0; i -= 20) { 700 // For i >= 0, (i - 20 - 1) is guaranteed not to underflow. 701 array[i - 1] = 1; // Bounds check can be eliminated. 702 } 703 } 704 705 706 /// CHECK-START: void Main.loopPattern3(int[]) BCE (before) 707 /// CHECK: BoundsCheck 708 /// CHECK: ArraySet 709 710 /// CHECK-START: void Main.loopPattern3(int[]) BCE (after) 711 /// CHECK: BoundsCheck 712 /// CHECK: ArraySet 713 loopPattern3(int[] array)714 static void loopPattern3(int[] array) { 715 java.util.Random random = new java.util.Random(); 716 for (int i = 0; ; i++) { 717 if (random.nextInt() % 1000 == 0 && i < array.length) { 718 // Can't eliminate the bound check since not every i++ is 719 // matched with a array length check, so there is some chance that i 720 // overflows and is negative. 721 array[i] = 1; 722 } 723 } 724 } 725 726 727 /// CHECK-START: void Main.constantNewArray() BCE (before) 728 /// CHECK: BoundsCheck 729 /// CHECK: ArraySet 730 /// CHECK: BoundsCheck 731 /// CHECK: ArraySet 732 /// CHECK: BoundsCheck 733 /// CHECK: ArraySet 734 /// CHECK: BoundsCheck 735 /// CHECK: ArraySet 736 /// CHECK: BoundsCheck 737 /// CHECK: ArraySet 738 739 /// CHECK-START: void Main.constantNewArray() BCE (after) 740 /// CHECK-NOT: BoundsCheck 741 /// CHECK: ArraySet 742 /// CHECK: BoundsCheck 743 /// CHECK: ArraySet 744 /// CHECK-NOT: BoundsCheck 745 /// CHECK: ArraySet 746 /// CHECK-NOT: BoundsCheck 747 /// CHECK: ArraySet 748 /// CHECK: BoundsCheck 749 /// CHECK: ArraySet 750 constantNewArray()751 static void constantNewArray() { 752 int[] array = new int[10]; 753 for (int i = 0; i < 10; i++) { 754 array[i] = 1; // Bounds check can be eliminated. 755 } 756 757 for (int i = 0; i <= 10; i++) { 758 array[i] = 1; // Bounds check can't be eliminated. 759 } 760 761 array[0] = 1; // Bounds check can be eliminated. 762 array[9] = 1; // Bounds check can be eliminated. 763 array[10] = 1; // Bounds check can't be eliminated. 764 } 765 766 readData()767 static byte readData() { 768 return 1; 769 } 770 771 /// CHECK-START: void Main.circularBufferProducer() BCE (before) 772 /// CHECK: BoundsCheck 773 /// CHECK: ArraySet 774 775 /// CHECK-START: void Main.circularBufferProducer() BCE (after) 776 /// CHECK-NOT: BoundsCheck 777 /// CHECK: ArraySet 778 circularBufferProducer()779 static void circularBufferProducer() { 780 byte[] array = new byte[4096]; 781 int i = 0; 782 while (true) { 783 array[i & (array.length - 1)] = readData(); 784 i++; 785 } 786 } 787 788 789 /// CHECK-START: void Main.pyramid1(int[]) BCE (before) 790 /// CHECK: BoundsCheck 791 /// CHECK: ArraySet 792 /// CHECK: BoundsCheck 793 /// CHECK: ArraySet 794 795 /// CHECK-START: void Main.pyramid1(int[]) BCE (after) 796 /// CHECK-NOT: BoundsCheck 797 /// CHECK: ArraySet 798 /// CHECK-NOT: BoundsCheck 799 /// CHECK: ArraySet 800 801 // Set array to something like {0, 1, 2, 3, 2, 1, 0}. pyramid1(int[] array)802 static void pyramid1(int[] array) { 803 for (int i = 0; i < (array.length + 1) / 2; i++) { 804 array[i] = i; 805 array[array.length - 1 - i] = i; 806 } 807 } 808 809 810 /// CHECK-START: void Main.pyramid2(int[]) BCE (before) 811 /// CHECK: BoundsCheck 812 /// CHECK: ArraySet 813 /// CHECK: BoundsCheck 814 /// CHECK: ArraySet 815 816 /// CHECK-START: void Main.pyramid2(int[]) BCE (after) 817 /// CHECK-NOT: BoundsCheck 818 /// CHECK: ArraySet 819 /// CHECK-NOT: BoundsCheck 820 /// CHECK: ArraySet 821 822 // Set array to something like {0, 1, 2, 3, 2, 1, 0}. pyramid2(int[] array)823 static void pyramid2(int[] array) { 824 for (int i = 0; i < (array.length + 1) >> 1; i++) { 825 array[i] = i; 826 array[array.length - 1 - i] = i; 827 } 828 } 829 830 831 /// CHECK-START: void Main.pyramid3(int[]) BCE (before) 832 /// CHECK: BoundsCheck 833 /// CHECK: ArraySet 834 /// CHECK: BoundsCheck 835 /// CHECK: ArraySet 836 837 /// CHECK-START: void Main.pyramid3(int[]) BCE (after) 838 /// CHECK-NOT: BoundsCheck 839 /// CHECK: ArraySet 840 /// CHECK-NOT: BoundsCheck 841 /// CHECK: ArraySet 842 843 // Set array to something like {0, 1, 2, 3, 2, 1, 0}. pyramid3(int[] array)844 static void pyramid3(int[] array) { 845 for (int i = 0; i < (array.length + 1) >>> 1; i++) { 846 array[i] = i; 847 array[array.length - 1 - i] = i; 848 } 849 } 850 851 852 /// CHECK-START: boolean Main.isPyramid(int[]) BCE (before) 853 /// CHECK: BoundsCheck 854 /// CHECK: ArrayGet 855 /// CHECK: BoundsCheck 856 /// CHECK: ArrayGet 857 858 /// CHECK-START: boolean Main.isPyramid(int[]) BCE (after) 859 /// CHECK-NOT: BoundsCheck 860 /// CHECK: ArrayGet 861 /// CHECK-NOT: BoundsCheck 862 /// CHECK: ArrayGet 863 isPyramid(int[] array)864 static boolean isPyramid(int[] array) { 865 int i = 0; 866 int j = array.length - 1; 867 while (i <= j) { 868 if (array[i] != i) { 869 return false; 870 } 871 if (array[j] != i) { 872 return false; 873 } 874 i++; j--; 875 } 876 return true; 877 } 878 879 /// CHECK-START: void Main.modArrayIndex1(int[]) BCE (before) 880 /// CHECK-DAG: BoundsCheck 881 /// CHECK-DAG: ArraySet 882 /// CHECK-DAG: BoundsCheck 883 /// CHECK-DAG: ArraySet 884 885 /// CHECK-START: void Main.modArrayIndex1(int[]) BCE (after) 886 /// CHECK-NOT: Deoptimize 887 /// CHECK-DAG: BoundsCheck 888 /// CHECK-DAG: ArraySet 889 /// CHECK-NOT: BoundsCheck 890 /// CHECK-DAG: ArraySet modArrayIndex1(int[] array)891 public static void modArrayIndex1(int[] array) { 892 for(int i = 0; i < 100; i++) { 893 // Cannot statically eliminate, for example, when array.length == 5. 894 // Currently dynamic BCE isn't applied for this case. 895 array[i % 10] = i; 896 // Can be eliminated by BCE. 897 array[i % array.length] = i; 898 } 899 } 900 901 /// CHECK-START: void Main.modArrayIndex2(int[], int) BCE (before) 902 /// CHECK-DAG: BoundsCheck 903 /// CHECK-DAG: ArraySet 904 /// CHECK-DAG: BoundsCheck 905 /// CHECK-DAG: ArraySet 906 907 /// CHECK-START: void Main.modArrayIndex2(int[], int) BCE (after) 908 /// CHECK-NOT: Deoptimize 909 /// CHECK-DAG: BoundsCheck 910 /// CHECK-DAG: ArraySet 911 /// CHECK-DAG: BoundsCheck 912 /// CHECK-DAG: ArraySet modArrayIndex2(int array[], int index)913 public static void modArrayIndex2(int array[], int index) { 914 for(int i = 0; i < 100; i++) { 915 // Both bounds checks cannot be statically eliminated, because index can be < 0. 916 // Currently dynamic BCE isn't applied for this case. 917 array[(index+i) % 10] = i; 918 array[(index+i) % array.length] = i; 919 } 920 } 921 922 static final int[] staticArray = new int[10]; 923 924 /// CHECK-START: void Main.modArrayIndex3() BCE (before) 925 /// CHECK-DAG: BoundsCheck 926 /// CHECK-DAG: ArraySet 927 /// CHECK-DAG: BoundsCheck 928 /// CHECK-DAG: ArraySet 929 930 /// CHECK-START: void Main.modArrayIndex3() BCE (after) 931 /// CHECK-NOT: Deoptimize 932 /// CHECK-DAG: BoundsCheck 933 /// CHECK-DAG: ArraySet 934 /// CHECK-NOT: BoundsCheck 935 /// CHECK-DAG: ArraySet modArrayIndex3()936 public static void modArrayIndex3() { 937 for(int i = 0; i < 100; i++) { 938 // Currently dynamic BCE isn't applied for this case. 939 staticArray[i % 10] = i; 940 // Can be eliminated by BCE. 941 staticArray[i % staticArray.length] = i; 942 } 943 } 944 945 /// CHECK-START: void Main.modArrayIndex4() BCE (before) 946 /// CHECK-DAG: BoundsCheck 947 /// CHECK-DAG: ArraySet 948 /// CHECK-DAG: BoundsCheck 949 /// CHECK-DAG: ArraySet 950 951 /// CHECK-START: void Main.modArrayIndex4() BCE (after) 952 /// CHECK-NOT: BoundsCheck 953 /// CHECK-DAG: ArraySet 954 /// CHECK-NOT: BoundsCheck 955 /// CHECK-DAG: ArraySet modArrayIndex4()956 public static void modArrayIndex4() { 957 int[] array = new int[20]; 958 for(int i = 0; i < 100; i++) { 959 // The local array length is statically know. Both can be eliminated by BCE. 960 array[i % 10] = i; 961 array[i % array.length] = i; 962 } 963 } 964 965 /// CHECK-START: void Main.modArrayIndex5(int[], int) BCE (before) 966 /// CHECK-DAG: BoundsCheck 967 /// CHECK-DAG: ArraySet 968 // 969 /// CHECK-START: void Main.modArrayIndex5(int[], int) BCE (after) 970 /// CHECK-NOT: BoundsCheck 971 /// CHECK-DAG: ArraySet modArrayIndex5(int[] x, int i)972 public static void modArrayIndex5(int[] x, int i) { 973 while (true) { 974 int xi = i % x.length; 975 if (xi < 0) 976 break; 977 if (i >= x.length) 978 break; 979 x[xi] = i; 980 i++; 981 } 982 } 983 984 /// CHECK-START: void Main.bubbleSort(int[]) GVN (before) 985 /// CHECK: BoundsCheck 986 /// CHECK: ArrayGet 987 /// CHECK: BoundsCheck 988 /// CHECK: ArrayGet 989 /// CHECK: BoundsCheck 990 /// CHECK: ArrayGet 991 /// CHECK: BoundsCheck 992 /// CHECK: ArrayGet 993 /// CHECK: BoundsCheck 994 /// CHECK: ArraySet 995 /// CHECK: BoundsCheck 996 /// CHECK: ArraySet 997 998 /// CHECK-START: void Main.bubbleSort(int[]) GVN (after) 999 /// CHECK: BoundsCheck 1000 /// CHECK: ArrayGet 1001 /// CHECK: BoundsCheck 1002 /// CHECK: ArrayGet 1003 /// CHECK-NOT: ArrayGet 1004 /// CHECK-NOT: ArrayGet 1005 /// CHECK-NOT: BoundsCheck 1006 /// CHECK: ArraySet 1007 /// CHECK-NOT: BoundsCheck 1008 /// CHECK: ArraySet 1009 1010 /// CHECK-START: void Main.bubbleSort(int[]) BCE (after) 1011 /// CHECK-NOT: BoundsCheck 1012 /// CHECK: ArrayGet 1013 /// CHECK-NOT: BoundsCheck 1014 /// CHECK: ArrayGet 1015 /// CHECK-NOT: ArrayGet 1016 /// CHECK-NOT: ArrayGet 1017 /// CHECK-NOT: BoundsCheck 1018 /// CHECK: ArraySet 1019 /// CHECK-NOT: BoundsCheck 1020 /// CHECK: ArraySet 1021 bubbleSort(int[] array)1022 static void bubbleSort(int[] array) { 1023 for (int i = 0; i < array.length - 1; i++) { 1024 for (int j = 0; j < array.length - i - 1; j++) { 1025 if (array[j] > array[j + 1]) { 1026 int temp = array[j + 1]; 1027 array[j + 1] = array[j]; 1028 array[j] = temp; 1029 } 1030 } 1031 } 1032 } 1033 1034 /// CHECK-START: void Main.nonzeroLength(int[]) BCE (before) 1035 /// CHECK-DAG: BoundsCheck 1036 // 1037 /// CHECK-START: void Main.nonzeroLength(int[]) BCE (after) 1038 /// CHECK-NOT: BoundsCheck 1039 /// CHECK-NOT: Deoptimize nonzeroLength(int[] a)1040 public static void nonzeroLength(int[] a) { 1041 if (a.length != 0) { 1042 a[0] = 112; 1043 } 1044 } 1045 1046 /// CHECK-START: void Main.knownLength(int[]) BCE (before) 1047 /// CHECK-DAG: BoundsCheck 1048 /// CHECK-DAG: BoundsCheck 1049 // 1050 /// CHECK-START: void Main.knownLength(int[]) BCE (after) 1051 /// CHECK-NOT: BoundsCheck 1052 /// CHECK-NOT: Deoptimize knownLength(int[] a)1053 public static void knownLength(int[] a) { 1054 if (a.length == 2) { 1055 a[0] = -1; 1056 a[1] = -2; 1057 } 1058 } 1059 1060 /// CHECK-START: void Main.lengthAlias1(int[], int) BCE (before) 1061 /// CHECK-DAG: <<Arr:l\d+>> ParameterValue loop:none 1062 /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none 1063 /// CHECK-DAG: <<Nul:l\d+>> NullCheck [<<Arr>>] loop:none 1064 /// CHECK-DAG: <<Len:i\d+>> ArrayLength [<<Nul>>] loop:none 1065 /// CHECK-DAG: NotEqual [<<Par>>,<<Len>>] loop:none 1066 /// CHECK-DAG: <<Idx:i\d+>> Phi loop:<<Loop:B\d+>> 1067 /// CHECK-DAG: BoundsCheck [<<Idx>>,<<Len>>] loop:<<Loop>> 1068 // 1069 /// CHECK-START: void Main.lengthAlias1(int[], int) BCE (after) 1070 /// CHECK-NOT: BoundsCheck 1071 /// CHECK-NOT: Deoptimize lengthAlias1(int[] a, int len)1072 public static void lengthAlias1(int[] a, int len) { 1073 if (len == a.length) { 1074 for (int i = 0; i < len; i++) { 1075 a[i] = 1; 1076 } 1077 } 1078 } 1079 1080 /// CHECK-START: void Main.lengthAlias2(int[], int) BCE (before) 1081 /// CHECK-DAG: <<Arr:l\d+>> ParameterValue loop:none 1082 /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none 1083 /// CHECK-DAG: <<Nul:l\d+>> NullCheck [<<Arr>>] loop:none 1084 /// CHECK-DAG: <<Len:i\d+>> ArrayLength [<<Nul>>] loop:none 1085 /// CHECK-DAG: Equal [<<Par>>,<<Len>>] loop:none 1086 /// CHECK-DAG: <<Idx:i\d+>> Phi loop:<<Loop:B\d+>> 1087 /// CHECK-DAG: BoundsCheck [<<Idx>>,<<Len>>] loop:<<Loop>> 1088 // 1089 /// CHECK-START: void Main.lengthAlias2(int[], int) BCE (after) 1090 /// CHECK-NOT: BoundsCheck 1091 /// CHECK-NOT: Deoptimize lengthAlias2(int[] a, int len)1092 public static void lengthAlias2(int[] a, int len) { 1093 if (len != a.length) { 1094 return; 1095 } 1096 for (int i = 0; i < len; i++) { 1097 a[i] = 2; 1098 } 1099 } 1100 1101 /// CHECK-START: void Main.lengthAlias3(int[], int) BCE (before) 1102 /// CHECK-DAG: <<Arr:l\d+>> ParameterValue loop:none 1103 /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none 1104 /// CHECK-DAG: <<Nul:l\d+>> NullCheck [<<Arr>>] loop:none 1105 /// CHECK-DAG: <<Len:i\d+>> ArrayLength [<<Nul>>] loop:none 1106 /// CHECK-DAG: NotEqual [<<Par>>,<<Len>>] loop:none 1107 /// CHECK-DAG: <<Idx:i\d+>> Phi loop:<<Loop:B\d+>> 1108 /// CHECK-DAG: BoundsCheck [<<Idx>>,<<Len>>] loop:<<Loop>> 1109 // 1110 /// CHECK-START: void Main.lengthAlias3(int[], int) BCE (after) 1111 /// CHECK-NOT: BoundsCheck 1112 /// CHECK-NOT: Deoptimize lengthAlias3(int[] a, int len)1113 public static void lengthAlias3(int[] a, int len) { 1114 if (a.length == len) { 1115 for (int i = 0; i < len; i++) { 1116 a[i] = 3; 1117 } 1118 } 1119 } 1120 1121 /// CHECK-START: void Main.lengthAlias4(int[]) BCE (before) 1122 /// CHECK-DAG: <<Arr:l\d+>> ParameterValue loop:none 1123 /// CHECK-DAG: <<Val:i\d+>> IntConstant 8 loop:none 1124 /// CHECK-DAG: <<Nul:l\d+>> NullCheck [<<Arr>>] loop:none 1125 /// CHECK-DAG: <<Len:i\d+>> ArrayLength [<<Nul>>] loop:none 1126 /// CHECK-DAG: Equal [<<Len>>,<<Val>>] loop:none 1127 /// CHECK-DAG: <<Idx:i\d+>> Phi loop:<<Loop:B\d+>> 1128 /// CHECK-DAG: BoundsCheck [<<Idx>>,<<Len>>] loop:<<Loop>> 1129 // 1130 /// CHECK-START: void Main.lengthAlias4(int[]) BCE (after) 1131 /// CHECK-NOT: BoundsCheck 1132 /// CHECK-NOT: Deoptimize lengthAlias4(int[] a)1133 public static void lengthAlias4(int[] a) { 1134 if (8 != a.length) { 1135 return; 1136 } 1137 for (int i = 0; i < 8; i++) { 1138 a[i] = 4; 1139 } 1140 } 1141 1142 static int[][] mA; 1143 1144 /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (before) 1145 // Array references mA[i] and ..[j] both in inner loop. 1146 /// CHECK-DAG: <<Get1:l\d+>> ArrayGet [<<Array1:l\d+>>,<<Bounds1:i\d+>>] loop:<<InnerLoop:B\d+>> 1147 /// CHECK-DAG: <<Array1>> NullCheck [<<Field1:l\d+>>] loop:<<InnerLoop>> 1148 /// CHECK-DAG: <<Len1:i\d+>> ArrayLength [<<Array1>>] loop:<<InnerLoop>> 1149 /// CHECK-DAG: <<Bounds1>> BoundsCheck [<<Index1:i\d+>>,<<Len1>>] loop:<<InnerLoop>> 1150 /// CHECK-DAG: <<Get2:i\d+>> ArrayGet [<<Array2:l\d+>>,<<Bounds2:i\d+>>] loop:<<InnerLoop>> 1151 /// CHECK-DAG: <<Array2>> NullCheck [<<Get1>>] loop:<<InnerLoop>> 1152 /// CHECK-DAG: <<Len2:i\d+>> ArrayLength [<<Array2>>] loop:<<InnerLoop>> 1153 /// CHECK-DAG: <<Bounds2>> BoundsCheck [<<Index2:i\d+>>,<<Len2>>] loop:<<InnerLoop>> 1154 /// CHECK-DAG: Abs [<<Get2>>] loop:<<InnerLoop>> 1155 /// CHECK-DAG: <<Index2>> Phi loop:<<InnerLoop>> 1156 /// CHECK-DAG: <<Index1>> Phi loop:<<OuterLoop:B\d+>> 1157 /// CHECK-DAG: <<Field1>> StaticFieldGet loop:none 1158 /// CHECK-EVAL: "<<InnerLoop>>" != "<<OuterLoop>>" 1159 // 1160 /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (after) 1161 // Array reference mA[i] hoisted to same level as deopt. 1162 /// CHECK-DAG: Deoptimize loop:<<OuterLoop:B\d+>> 1163 /// CHECK-DAG: ArrayLength loop:<<OuterLoop>> 1164 /// CHECK-DAG: <<Get1:l\d+>> ArrayGet [<<Array1:l\d+>>,<<Index1:i\d+>>] loop:<<OuterLoop>> 1165 // Array reference ..[j] still in inner loop, with a direct index. 1166 /// CHECK-DAG: <<Get2:i\d+>> ArrayGet [<<Array2:l\d+>>,<<Index2:i\d+>>] loop:<<InnerLoop:B\d+>> 1167 /// CHECK-DAG: Abs [<<Get2>>] loop:<<InnerLoop>> 1168 /// CHECK-DAG: <<Index2>> Phi loop:<<InnerLoop>> 1169 /// CHECK-DAG: <<Index1>> Phi loop:<<OuterLoop>> 1170 // Synthetic phi. 1171 /// CHECK-DAG: <<Array2>> Phi loop:<<OuterLoop>> 1172 /// CHECK-DAG: <<Array1>> StaticFieldGet loop:none 1173 /// CHECK-EVAL: "<<InnerLoop>>" != "<<OuterLoop>>" 1174 // 1175 /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (after) 1176 /// CHECK-NOT: NullCheck 1177 /// CHECK-NOT: BoundsCheck dynamicBCEAndIntrinsic(int n)1178 static void dynamicBCEAndIntrinsic(int n) { 1179 for (int i = 0; i < n; i++) { 1180 for (int j = 0; j < n; j++) { 1181 // Since intrinsic call cannot modify fields or arrays, 1182 // dynamic BCE and hoisting can be applied to the inner loop. 1183 mA[i][j] = Math.abs(mA[i][j]); 1184 } 1185 } 1186 } 1187 foo()1188 static int foo() { 1189 try { 1190 assertIsManaged(); 1191 // This will cause AIOOBE. 1192 $opt$noinline$constantIndexing2(new int[3]); 1193 } catch (ArrayIndexOutOfBoundsException e) { 1194 assertIsManaged(); // This is to ensure that single-frame deoptimization works. 1195 // Will need to be updated if $opt$noinline$constantIndexing2 is inlined. 1196 try { 1197 // This will cause AIOOBE. 1198 constantIndexingForward6(new int[3]); 1199 } catch (ArrayIndexOutOfBoundsException e2) { 1200 // Having deopted, we expect to be running interpreted at this point. 1201 // Does not apply to debuggable, however, since we do not inline. 1202 return 99; 1203 } 1204 } 1205 return 0; 1206 } 1207 1208 1209 int sum; 1210 1211 /// CHECK-START: void Main.foo1(int[], int, int, boolean) BCE (before) 1212 /// CHECK: BoundsCheck 1213 /// CHECK: ArraySet 1214 /// CHECK-NOT: BoundsCheck 1215 /// CHECK: ArrayGet 1216 1217 /// CHECK-START: void Main.foo1(int[], int, int, boolean) BCE (after) 1218 /// CHECK: Phi 1219 /// CHECK-NOT: BoundsCheck 1220 /// CHECK: ArraySet 1221 /// CHECK-NOT: BoundsCheck 1222 /// CHECK: ArrayGet 1223 // Added blocks at end for deoptimization. 1224 /// CHECK: Exit 1225 /// CHECK: If 1226 /// CHECK: Deoptimize 1227 /// CHECK: Deoptimize 1228 /// CHECK: Deoptimize 1229 /// CHECK-NOT: Deoptimize 1230 /// CHECK: Goto 1231 /// CHECK: Goto 1232 /// CHECK: Goto 1233 foo1(int[] array, int start, int end, boolean expectInterpreter)1234 void foo1(int[] array, int start, int end, boolean expectInterpreter) { 1235 if (end < 0) 1236 throw new Error(""); 1237 // Three HDeoptimize will be added. Two for the index 1238 // and one for null check on array (to hoist null 1239 // check and array.length out of loop). 1240 for (int i = start ; i < end; i++) { 1241 if (expectInterpreter) { 1242 assertIsInterpreted(); 1243 } else { 1244 assertIsManaged(); 1245 } 1246 array[i] = 1; 1247 sum += array[i]; 1248 } 1249 } 1250 1251 1252 /// CHECK-START: void Main.foo2(int[], int, int, boolean) BCE (before) 1253 /// CHECK: BoundsCheck 1254 /// CHECK: ArraySet 1255 /// CHECK-NOT: BoundsCheck 1256 /// CHECK: ArrayGet 1257 /// CHECK-START: void Main.foo2(int[], int, int, boolean) BCE (after) 1258 /// CHECK: Phi 1259 /// CHECK-NOT: BoundsCheck 1260 /// CHECK: ArraySet 1261 /// CHECK-NOT: BoundsCheck 1262 /// CHECK: ArrayGet 1263 // Added blocks at end for deoptimization. 1264 /// CHECK: Exit 1265 /// CHECK: If 1266 /// CHECK: Deoptimize 1267 /// CHECK: Deoptimize 1268 /// CHECK: Deoptimize 1269 /// CHECK-NOT: Deoptimize 1270 /// CHECK: Goto 1271 /// CHECK: Goto 1272 /// CHECK: Goto 1273 foo2(int[] array, int start, int end, boolean expectInterpreter)1274 void foo2(int[] array, int start, int end, boolean expectInterpreter) { 1275 if (end < 0) 1276 throw new Error(""); 1277 // Three HDeoptimize will be added. Two for the index 1278 // and one for null check on array (to hoist null 1279 // check and array.length out of loop). 1280 for (int i = start ; i <= end; i++) { 1281 if (expectInterpreter) { 1282 assertIsInterpreted(); 1283 } else { 1284 assertIsManaged(); 1285 } 1286 array[i] = 1; 1287 sum += array[i]; 1288 } 1289 } 1290 1291 1292 /// CHECK-START: void Main.foo3(int[], int, boolean) BCE (before) 1293 /// CHECK: BoundsCheck 1294 /// CHECK: ArraySet 1295 /// CHECK-NOT: BoundsCheck 1296 /// CHECK: ArrayGet 1297 /// CHECK-START: void Main.foo3(int[], int, boolean) BCE (after) 1298 /// CHECK: Phi 1299 /// CHECK-NOT: BoundsCheck 1300 /// CHECK: ArraySet 1301 /// CHECK-NOT: BoundsCheck 1302 /// CHECK: ArrayGet 1303 // Added blocks at end for deoptimization. 1304 /// CHECK: Exit 1305 /// CHECK: If 1306 /// CHECK: Deoptimize 1307 /// CHECK: Deoptimize 1308 /// CHECK: Deoptimize 1309 /// CHECK-NOT: Deoptimize 1310 /// CHECK: Goto 1311 /// CHECK: Goto 1312 /// CHECK: Goto 1313 foo3(int[] array, int end, boolean expectInterpreter)1314 void foo3(int[] array, int end, boolean expectInterpreter) { 1315 if (end < 0) 1316 throw new Error(""); 1317 // Three HDeoptimize will be added. Two for the index 1318 // and one for null check on array (to hoist null check 1319 // and array.length out of loop). 1320 for (int i = 3 ; i <= end; i++) { 1321 if (expectInterpreter) { 1322 assertIsInterpreted(); 1323 } else { 1324 assertIsManaged(); 1325 } 1326 array[i] = 1; 1327 sum += array[i]; 1328 } 1329 } 1330 1331 1332 /// CHECK-START: void Main.foo4(int[], int, boolean) BCE (before) 1333 /// CHECK: BoundsCheck 1334 /// CHECK: ArraySet 1335 /// CHECK-NOT: BoundsCheck 1336 /// CHECK: ArrayGet 1337 1338 /// CHECK-START: void Main.foo4(int[], int, boolean) BCE (after) 1339 /// CHECK: Phi 1340 /// CHECK-NOT: BoundsCheck 1341 /// CHECK: ArraySet 1342 /// CHECK-NOT: BoundsCheck 1343 /// CHECK: ArrayGet 1344 // Added blocks at end for deoptimization. 1345 /// CHECK: Exit 1346 /// CHECK: If 1347 /// CHECK: Deoptimize 1348 /// CHECK: Deoptimize 1349 /// CHECK: Deoptimize 1350 /// CHECK-NOT: Deoptimize 1351 /// CHECK: Goto 1352 /// CHECK: Goto 1353 /// CHECK: Goto 1354 foo4(int[] array, int end, boolean expectInterpreter)1355 void foo4(int[] array, int end, boolean expectInterpreter) { 1356 if (end < 0) 1357 throw new Error(""); 1358 // Three HDeoptimize will be added. Two for the index 1359 // and one for null check on array (to hoist null check 1360 // and array.length out of loop). 1361 for (int i = end ; i > 0; i--) { 1362 if (expectInterpreter) { 1363 assertIsInterpreted(); 1364 } else { 1365 assertIsManaged(); 1366 } 1367 array[i - 1] = 1; 1368 sum += array[i - 1]; 1369 } 1370 } 1371 1372 1373 /// CHECK-START: void Main.foo5(int[], int, boolean) BCE (before) 1374 /// CHECK: BoundsCheck 1375 /// CHECK: ArraySet 1376 /// CHECK: BoundsCheck 1377 /// CHECK: ArrayGet 1378 /// CHECK: BoundsCheck 1379 /// CHECK: ArrayGet 1380 /// CHECK: BoundsCheck 1381 /// CHECK: ArrayGet 1382 1383 /// CHECK-START: void Main.foo5(int[], int, boolean) BCE (after) 1384 /// CHECK-NOT: BoundsCheck 1385 /// CHECK: ArraySet 1386 /// CHECK: Phi 1387 /// CHECK-NOT: BoundsCheck 1388 /// CHECK: ArrayGet 1389 /// CHECK-NOT: BoundsCheck 1390 /// CHECK: ArrayGet 1391 /// CHECK-NOT: BoundsCheck 1392 /// CHECK: ArrayGet 1393 // Added blocks at end for deoptimization. 1394 /// CHECK: Exit 1395 /// CHECK: If 1396 /// CHECK: Deoptimize 1397 /// CHECK: Deoptimize 1398 /// CHECK: Deoptimize 1399 /// CHECK-NOT: Deoptimize 1400 /// CHECK: Goto 1401 /// CHECK: Goto 1402 /// CHECK: Goto 1403 foo5(int[] array, int end, boolean expectInterpreter)1404 void foo5(int[] array, int end, boolean expectInterpreter) { 1405 if (end < 0) 1406 throw new Error(""); 1407 // Bounds check in this loop can be eliminated without deoptimization. 1408 for (int i = array.length - 1 ; i >= 0; i--) { 1409 array[i] = 1; 1410 } 1411 // Three HDeoptimize will be added for the bounds. 1412 // The null check is not necessary. 1413 for (int i = end - 2 ; i > 0; i--) { 1414 if (expectInterpreter) { 1415 assertIsInterpreted(); 1416 } else { 1417 assertIsManaged(); 1418 } 1419 sum += array[i - 1]; 1420 sum += array[i]; 1421 sum += array[i + 1]; 1422 } 1423 } 1424 1425 1426 /// CHECK-START: void Main.foo6(int[], int, int, boolean) BCE (before) 1427 /// CHECK: BoundsCheck 1428 /// CHECK: ArrayGet 1429 /// CHECK: BoundsCheck 1430 /// CHECK: ArrayGet 1431 /// CHECK: BoundsCheck 1432 /// CHECK: ArrayGet 1433 /// CHECK: BoundsCheck 1434 /// CHECK: ArrayGet 1435 /// CHECK: BoundsCheck 1436 /// CHECK: ArrayGet 1437 /// CHECK-NOT: BoundsCheck 1438 /// CHECK: ArraySet 1439 /// CHECK-START: void Main.foo6(int[], int, int, boolean) BCE (after) 1440 /// CHECK: Phi 1441 /// CHECK-NOT: BoundsCheck 1442 /// CHECK: ArrayGet 1443 /// CHECK-NOT: BoundsCheck 1444 /// CHECK: ArrayGet 1445 /// CHECK-NOT: BoundsCheck 1446 /// CHECK: ArrayGet 1447 /// CHECK-NOT: BoundsCheck 1448 /// CHECK: ArrayGet 1449 /// CHECK-NOT: BoundsCheck 1450 /// CHECK: ArrayGet 1451 /// CHECK-NOT: BoundsCheck 1452 /// CHECK: ArraySet 1453 // Added blocks at end for deoptimization. 1454 /// CHECK: Exit 1455 /// CHECK: If 1456 /// CHECK: Deoptimize 1457 /// CHECK: Deoptimize 1458 /// CHECK: Deoptimize 1459 /// CHECK: Deoptimize 1460 /// CHECK-NOT: Deoptimize 1461 /// CHECK: Goto 1462 /// CHECK: Goto 1463 /// CHECK: Goto 1464 foo6(int[] array, int start, int end, boolean expectInterpreter)1465 void foo6(int[] array, int start, int end, boolean expectInterpreter) { 1466 if (end < 0) 1467 throw new Error(""); 1468 for (int i = end; i >= start; i--) { 1469 if (expectInterpreter) { 1470 assertIsInterpreted(); 1471 } else { 1472 assertIsManaged(); 1473 } 1474 array[i] = (array[i-2] + array[i-1] + array[i] + array[i+1] + array[i+2]) / 5; 1475 } 1476 } 1477 1478 1479 /// CHECK-START: void Main.foo7(int[], int, int, boolean) BCE (before) 1480 /// CHECK: BoundsCheck 1481 /// CHECK: ArrayGet 1482 /// CHECK: BoundsCheck 1483 /// CHECK: ArrayGet 1484 1485 /// CHECK-START: void Main.foo7(int[], int, int, boolean) BCE (after) 1486 /// CHECK: Phi 1487 /// CHECK: BoundsCheck 1488 /// CHECK: ArrayGet 1489 /// CHECK-NOT: BoundsCheck 1490 /// CHECK: ArrayGet 1491 // Added blocks at end for deoptimization. 1492 /// CHECK: Exit 1493 /// CHECK: If 1494 /// CHECK: Deoptimize 1495 /// CHECK: Deoptimize 1496 /// CHECK: Deoptimize 1497 /// CHECK-NOT: Deoptimize 1498 /// CHECK: Goto 1499 /// CHECK: Goto 1500 /// CHECK: Goto 1501 foo7(int[] array, int start, int end, boolean lowEnd)1502 void foo7(int[] array, int start, int end, boolean lowEnd) { 1503 // Three HDeoptimize will be added. One for the index 1504 // and one for null check on array (to hoist null 1505 // check and array.length out of loop). 1506 for (int i = start ; i < end; i++) { 1507 if (lowEnd) { 1508 // This array access isn't certain. So we don't 1509 // use +1000 offset in decision making for deoptimization 1510 // conditions. 1511 sum += array[i + 1000]; 1512 } 1513 sum += array[i]; 1514 } 1515 } 1516 1517 1518 /// CHECK-START: void Main.foo8(int[][], int, int) BCE (before) 1519 /// CHECK: BoundsCheck 1520 /// CHECK: ArrayGet 1521 /// CHECK: BoundsCheck 1522 /// CHECK: ArraySet 1523 1524 /// CHECK-START: void Main.foo8(int[][], int, int) BCE (after) 1525 /// CHECK: Phi 1526 /// CHECK-NOT: BoundsCheck 1527 /// CHECK: ArrayGet 1528 /// CHECK: Phi 1529 /// CHECK-NOT: BoundsCheck 1530 /// CHECK: ArraySet 1531 // Added blocks at end for deoptimization. 1532 /// CHECK: Exit 1533 /// CHECK: If 1534 /// CHECK: Deoptimize 1535 /// CHECK: Deoptimize 1536 /// CHECK: Deoptimize 1537 /// CHECK: Goto 1538 /// CHECK: Goto 1539 /// CHECK: Goto 1540 /// CHECK: If 1541 /// CHECK: Deoptimize 1542 /// CHECK: Deoptimize 1543 /// CHECK: Deoptimize 1544 /// CHECK-NOT: Deoptimize 1545 /// CHECK: Goto 1546 /// CHECK: Goto 1547 /// CHECK: Goto 1548 foo8(int[][] matrix, int start, int end)1549 void foo8(int[][] matrix, int start, int end) { 1550 // Three HDeoptimize will be added for the outer loop, 1551 // two for the index, and null check on matrix. Same 1552 // for the inner loop. 1553 for (int i = start; i < end; i++) { 1554 int[] row = matrix[i]; 1555 for (int j = start; j < end; j++) { 1556 row[j] = 1; 1557 } 1558 } 1559 } 1560 1561 1562 /// CHECK-START: void Main.foo9(int[], boolean) BCE (before) 1563 /// CHECK: NullCheck 1564 /// CHECK: BoundsCheck 1565 /// CHECK: ArrayGet 1566 1567 /// CHECK-START: void Main.foo9(int[], boolean) BCE (after) 1568 // The loop is guaranteed to be entered. No need to transform the 1569 // loop for loop body entry test. 1570 /// CHECK: Deoptimize 1571 /// CHECK: Deoptimize 1572 /// CHECK: Deoptimize 1573 /// CHECK-NOT: Deoptimize 1574 /// CHECK: Phi 1575 /// CHECK-NOT: NullCheck 1576 /// CHECK-NOT: BoundsCheck 1577 /// CHECK: ArrayGet 1578 1579 /// CHECK-START: void Main.foo9(int[], boolean) instruction_simplifier$after_bce (after) 1580 // Simplification removes the redundant check 1581 /// CHECK: Deoptimize 1582 /// CHECK: Deoptimize 1583 /// CHECK-NOT: Deoptimize 1584 foo9(int[] array, boolean expectInterpreter)1585 void foo9(int[] array, boolean expectInterpreter) { 1586 // Three HDeoptimize will be added. Two for the index and one for null check on array. Then 1587 // simplification removes one redundant HDeoptimize. 1588 for (int i = 0 ; i < 10; i++) { 1589 if (expectInterpreter) { 1590 assertIsInterpreted(); 1591 } else { 1592 assertIsManaged(); 1593 } 1594 sum += array[i]; 1595 } 1596 } 1597 1598 1599 /// CHECK-START: void Main.partialLooping(int[], int, int) BCE (before) 1600 /// CHECK: BoundsCheck 1601 /// CHECK: ArraySet 1602 1603 /// CHECK-START: void Main.partialLooping(int[], int, int) BCE (after) 1604 /// CHECK-NOT: Deoptimize 1605 /// CHECK: BoundsCheck 1606 /// CHECK: ArraySet 1607 partialLooping(int[] array, int start, int end)1608 void partialLooping(int[] array, int start, int end) { 1609 // This loop doesn't cover the full range of [start, end) so 1610 // adding deoptimization is too aggressive, since end can be 1611 // greater than array.length but the loop is never going to work on 1612 // more than 2 elements. 1613 for (int i = start; i < end; i++) { 1614 if (i == 2) { 1615 return; 1616 } 1617 array[i] = 1; 1618 } 1619 } 1620 1621 testUnknownBounds()1622 static void testUnknownBounds() { 1623 boolean caught = false; 1624 1625 runAllConstantIndices(); 1626 1627 Main main = new Main(); 1628 main.foo1(new int[10], 0, 10, false); 1629 if (main.sum != 10) { 1630 System.out.println("foo1 failed!"); 1631 } 1632 1633 caught = false; 1634 main = new Main(); 1635 try { 1636 main.foo1(new int[10], 0, 11, true); 1637 } catch (ArrayIndexOutOfBoundsException e) { 1638 caught = true; 1639 } 1640 if (!caught || main.sum != 10) { 1641 System.out.println("foo1 exception failed!"); 1642 } 1643 1644 main = new Main(); 1645 main.foo2(new int[10], 0, 9, false); 1646 if (main.sum != 10) { 1647 System.out.println("foo2 failed!"); 1648 } 1649 1650 caught = false; 1651 main = new Main(); 1652 try { 1653 main.foo2(new int[10], 0, 10, true); 1654 } catch (ArrayIndexOutOfBoundsException e) { 1655 caught = true; 1656 } 1657 if (!caught || main.sum != 10) { 1658 System.out.println("foo2 exception failed!"); 1659 } 1660 1661 main = new Main(); 1662 main.foo3(new int[10], 9, false); 1663 if (main.sum != 7) { 1664 System.out.println("foo3 failed!"); 1665 } 1666 1667 caught = false; 1668 main = new Main(); 1669 try { 1670 main.foo3(new int[10], 10, true); 1671 } catch (ArrayIndexOutOfBoundsException e) { 1672 caught = true; 1673 } 1674 if (!caught || main.sum != 7) { 1675 System.out.println("foo3 exception failed!"); 1676 } 1677 1678 main = new Main(); 1679 main.foo4(new int[10], 10, false); 1680 if (main.sum != 10) { 1681 System.out.println("foo4 failed!"); 1682 } 1683 1684 caught = false; 1685 main = new Main(); 1686 try { 1687 main.foo4(new int[10], 11, true); 1688 } catch (ArrayIndexOutOfBoundsException e) { 1689 caught = true; 1690 } 1691 if (!caught || main.sum != 0) { 1692 System.out.println("foo4 exception failed!"); 1693 } 1694 1695 main = new Main(); 1696 main.foo5(new int[10], 10, false); 1697 if (main.sum != 24) { 1698 System.out.println("foo5 failed!"); 1699 } 1700 1701 caught = false; 1702 main = new Main(); 1703 try { 1704 main.foo5(new int[10], 11, true); 1705 } catch (ArrayIndexOutOfBoundsException e) { 1706 caught = true; 1707 } 1708 if (!caught || main.sum != 2) { 1709 System.out.println("foo5 exception failed!"); 1710 } 1711 1712 main = new Main(); 1713 main.foo6(new int[10], 2, 7, false); 1714 1715 main = new Main(); 1716 int[] array9 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 1717 main.foo9(array9, false); 1718 if (main.sum != 45) { 1719 System.out.println("foo9 failed!"); 1720 } 1721 1722 main = new Main(); 1723 int[] array = new int[4]; 1724 main.partialLooping(new int[3], 0, 4); 1725 if ((array[0] != 1) && (array[1] != 1) && 1726 (array[2] != 0) && (array[3] != 0)) { 1727 System.out.println("partialLooping failed!"); 1728 } 1729 1730 caught = false; 1731 main = new Main(); 1732 try { 1733 main.foo6(new int[10], 2, 8, true); 1734 } catch (ArrayIndexOutOfBoundsException e) { 1735 caught = true; 1736 } 1737 if (!caught) { 1738 System.out.println("foo6 exception failed!"); 1739 } 1740 1741 caught = false; 1742 main = new Main(); 1743 try { 1744 main.foo6(new int[10], 1, 7, true); 1745 } catch (ArrayIndexOutOfBoundsException e) { 1746 caught = true; 1747 } 1748 if (!caught) { 1749 System.out.println("foo6 exception failed!"); 1750 } 1751 1752 } 1753 testExceptionMessage()1754 public void testExceptionMessage() { 1755 short[] B1 = new short[5]; 1756 int[] B2 = new int[5]; 1757 Exception err = null; 1758 try { 1759 testExceptionMessage1(B1, B2, null, -1, 6); 1760 } catch (Exception e) { 1761 err = e; 1762 } 1763 System.out.println(err); 1764 } 1765 testExceptionMessage1(short[] a1, int[] a2, long a3[], int start, int finish)1766 void testExceptionMessage1(short[] a1, int[] a2, long a3[], int start, int finish) { 1767 int j = finish + 77; 1768 // Bug: 22665511 1769 // A deoptimization will be triggered here right before the loop. Need to make 1770 // sure the value of j is preserved for the interpreter. 1771 for (int i = start; i <= finish; i++) { 1772 a2[j - 1] = a1[i + 1]; 1773 } 1774 } 1775 1776 // Make sure this method is compiled with optimizing. 1777 /// CHECK-START: void Main.main(java.lang.String[]) register (after) 1778 /// CHECK: ParallelMove 1779 main(String[] args)1780 public static void main(String[] args) { 1781 System.loadLibrary(args[0]); 1782 1783 if (!compiledWithOptimizing() || 1784 !hasOatFile() || 1785 runtimeIsSoftFail() || 1786 isInterpreted()) { 1787 disableStackFrameAsserts(); 1788 } 1789 1790 sieve(20); 1791 1792 int[] x1 = new int[10]; 1793 int[] x2 = new int[10]; 1794 int[] x3 = new int[10]; 1795 modArrayIndex5(x1, -1); 1796 modArrayIndex5(x2, 0); 1797 modArrayIndex5(x3, 5); 1798 for (int i = 0; i < 10; i++) { 1799 int e1 = 0; 1800 int e2 = i; 1801 int e3 = i < 5 ? 0 : i; 1802 if (x1[i] != e1 || x2[i] != e2 || x3[i] != e3) { 1803 System.out.println("modarray failed!"); 1804 } 1805 } 1806 1807 int[] array = {5, 2, 3, 7, 0, 1, 6, 4}; 1808 bubbleSort(array); 1809 for (int i = 0; i < 8; i++) { 1810 if (array[i] != i) { 1811 System.out.println("bubble sort failed!"); 1812 } 1813 } 1814 1815 nonzeroLength(array); 1816 if (array[0] != 112) { 1817 System.out.println("nonzero length failed!"); 1818 } 1819 1820 knownLength(array); 1821 if (array[0] != 112 || array[1] != 1) { 1822 System.out.println("nonzero length failed!"); 1823 } 1824 array = new int[2]; 1825 knownLength(array); 1826 if (array[0] != -1 || array[1] != -2) { 1827 System.out.println("nonzero length failed!"); 1828 } 1829 1830 array = new int[8]; 1831 lengthAlias1(array, 8); 1832 for (int i = 0; i < 8; i++) { 1833 if (array[i] != 1) { 1834 System.out.println("alias1 failed!"); 1835 } 1836 } 1837 lengthAlias2(array, 8); 1838 for (int i = 0; i < 8; i++) { 1839 if (array[i] != 2) { 1840 System.out.println("alias2 failed!"); 1841 } 1842 } 1843 lengthAlias3(array, 8); 1844 for (int i = 0; i < 8; i++) { 1845 if (array[i] != 3) { 1846 System.out.println("alias3 failed!"); 1847 } 1848 } 1849 lengthAlias4(array); 1850 for (int i = 0; i < 8; i++) { 1851 if (array[i] != 4) { 1852 System.out.println("alias4 failed!"); 1853 } 1854 } 1855 1856 array = new int[10]; 1857 lengthAlias1(array, /*mismatched value*/ 8); 1858 lengthAlias2(array, /*mismatched value*/ 8); 1859 lengthAlias3(array, /*mismatched value*/ 8); 1860 lengthAlias4(array); // implicit mismatch 1861 for (int i = 0; i < 10; i++) { 1862 if (array[i] != 0) { 1863 System.out.println("mismatch failed!"); 1864 } 1865 } 1866 1867 // Zero length array does not break. 1868 array = new int[0]; 1869 nonzeroLength(array); 1870 knownLength(array); 1871 lengthAlias1(array, 0); 1872 lengthAlias2(array, 0); 1873 lengthAlias3(array, 0); 1874 1875 mA = new int[4][4]; 1876 for (int i = 0; i < 4; i++) { 1877 for (int j = 0; j < 4; j++) { 1878 mA[i][j] = -1; 1879 } 1880 } 1881 dynamicBCEAndIntrinsic(4); 1882 for (int i = 0; i < 4; i++) { 1883 for (int j = 0; j < 4; j++) { 1884 if (mA[i][i] != 1) { 1885 System.out.println("dynamic bce failed!"); 1886 } 1887 } 1888 } 1889 1890 array = new int[7]; 1891 pyramid1(array); 1892 if (!isPyramid(array)) { 1893 System.out.println("pyramid1 failed!"); 1894 } 1895 1896 array = new int[8]; 1897 pyramid2(array); 1898 if (!isPyramid(array)) { 1899 System.out.println("pyramid2 failed!"); 1900 } 1901 1902 java.util.Arrays.fill(array, -1); 1903 pyramid3(array); 1904 if (!isPyramid(array)) { 1905 System.out.println("pyramid3 failed!"); 1906 } 1907 1908 // Make sure this value is kept after deoptimization. 1909 int i = 1; 1910 if (foo() + i != 100) { 1911 System.out.println("foo failed!"); 1912 }; 1913 1914 testUnknownBounds(); 1915 new Main().testExceptionMessage(); 1916 } 1917 1918 public static native boolean compiledWithOptimizing(); 1919 public static native void disableStackFrameAsserts(); 1920 public static native void assertIsManaged(); 1921 public static native void assertIsInterpreted(); 1922 public static native boolean hasOatFile(); 1923 public static native boolean runtimeIsSoftFail(); 1924 public static native boolean isInterpreted(); 1925 } 1926