blob: 31bb94cb8c8237ce84644c119f392a0011d00077 [file] [log] [blame]
Mingyao Yang0304e182015-01-30 16:41:29 -08001/*
Roland Levillain6a92a032015-07-23 12:15:01 +01002 * 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 */
Mingyao Yang0304e182015-01-30 16:41:29 -080016
17public class Main {
18
David Brazdila06d66a2015-05-28 11:14:54 +010019 /// 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
Mingyao Yang0304e182015-01-30 16:41:29 -080026
David Brazdila06d66a2015-05-28 11:14:54 +010027 /// 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
Mingyao Yang0304e182015-01-30 16:41:29 -080034
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
Mingyao Yang8c8bad82015-02-09 18:13:26 -080049
David Brazdila06d66a2015-05-28 11:14:54 +010050 /// 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
Mingyao Yang0304e182015-01-30 16:41:29 -080057
David Brazdila06d66a2015-05-28 11:14:54 +010058 /// 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
Mingyao Yang0304e182015-01-30 16:41:29 -080069
Mingyao Yang8c8bad82015-02-09 18:13:26 -080070 static void narrow(int[] array, int offset) {
Mingyao Yang0304e182015-01-30 16:41:29 -080071 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 }
Mingyao Yang8c8bad82015-02-09 18:13:26 -080095
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 }
Mingyao Yang0304e182015-01-30 16:41:29 -0800107 }
108 }
109
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800110
David Brazdila06d66a2015-05-28 11:14:54 +0100111 /// CHECK-START: void Main.constantIndexing1(int[]) BCE (before)
112 /// CHECK: BoundsCheck
113 /// CHECK: ArraySet
114 /// CHECK: BoundsCheck
115 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700116
David Brazdila06d66a2015-05-28 11:14:54 +0100117 /// 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
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700123
124 static void constantIndexing1(int[] array) {
Aart Bik1d239822016-02-09 14:26:34 -0800125 // Decreasing order: bc for 5 but not for 4.
126 array[5] = 11;
127 array[4] = 11;
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700128 }
129
130
Nicolas Geoffray5949fa02015-12-18 10:57:10 +0000131 /// CHECK-START: void Main.$opt$noinline$constantIndexing2(int[]) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +0100132 /// CHECK: BoundsCheck
133 /// CHECK: ArraySet
134 /// CHECK: BoundsCheck
135 /// CHECK: ArraySet
136 /// CHECK: BoundsCheck
137 /// CHECK: ArraySet
138 /// CHECK: BoundsCheck
139 /// CHECK: ArraySet
Aart Bik1d239822016-02-09 14:26:34 -0800140 /// CHECK: BoundsCheck
141 /// CHECK: ArraySet
Mingyao Yange295e6e2015-03-07 06:37:59 -0800142
Nicolas Geoffray5949fa02015-12-18 10:57:10 +0000143 /// CHECK-START: void Main.$opt$noinline$constantIndexing2(int[]) BCE (after)
Aart Bik1d239822016-02-09 14:26:34 -0800144 /// CHECK-NOT: Deoptimize
145 /// CHECK: BoundsCheck
David Brazdila06d66a2015-05-28 11:14:54 +0100146 /// CHECK: ArraySet
Aart Bik1d239822016-02-09 14:26:34 -0800147 /// CHECK: BoundsCheck
David Brazdila06d66a2015-05-28 11:14:54 +0100148 /// CHECK: ArraySet
Aart Bik1d239822016-02-09 14:26:34 -0800149 /// CHECK: BoundsCheck
David Brazdila06d66a2015-05-28 11:14:54 +0100150 /// CHECK: ArraySet
Aart Bik1d239822016-02-09 14:26:34 -0800151 /// CHECK: BoundsCheck
David Brazdila06d66a2015-05-28 11:14:54 +0100152 /// CHECK: ArraySet
153 /// CHECK: BoundsCheck
154 /// CHECK: ArraySet
Mingyao Yange295e6e2015-03-07 06:37:59 -0800155
Nicolas Geoffray5949fa02015-12-18 10:57:10 +0000156 static void $opt$noinline$constantIndexing2(int[] array) {
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700157 array[1] = 1;
158 array[2] = 1;
159 array[3] = 1;
Mingyao Yange295e6e2015-03-07 06:37:59 -0800160 array[4] = 1;
Aart Bik1d239822016-02-09 14:26:34 -0800161 array[-1] = 1; // prevents the whole opt on [-1:4]
Nicolas Geoffray5949fa02015-12-18 10:57:10 +0000162 if (array[1] == 1) {
163 throw new Error("");
164 }
Mingyao Yange295e6e2015-03-07 06:37:59 -0800165 }
166
Aart Bik1d239822016-02-09 14:26:34 -0800167 /// CHECK-START: void Main.constantIndexing2b(int[]) BCE (before)
168 /// CHECK: BoundsCheck
169 /// CHECK: ArraySet
170 /// CHECK: BoundsCheck
171 /// CHECK: ArraySet
172 /// CHECK: BoundsCheck
173 /// CHECK: ArraySet
174 /// CHECK: BoundsCheck
175 /// CHECK: ArraySet
176
177 /// CHECK-START: void Main.constantIndexing2b(int[]) BCE (after)
178 /// CHECK: Deoptimize
179 /// CHECK-NOT: BoundsCheck
180 /// CHECK: ArraySet
181 /// CHECK-NOT: BoundsCheck
182 /// CHECK: ArraySet
183 /// CHECK-NOT: BoundsCheck
184 /// CHECK: ArraySet
185 /// CHECK-NOT: BoundsCheck
186 /// CHECK: ArraySet
187
188 static void constantIndexing2b(int[] array) {
189 array[0] = 7;
190 array[1] = 7;
191 array[2] = 7;
192 array[3] = 7;
193 }
Mingyao Yange295e6e2015-03-07 06:37:59 -0800194
David Brazdila06d66a2015-05-28 11:14:54 +0100195 /// CHECK-START: int[] Main.constantIndexing3(int[], int[], boolean) BCE (before)
196 /// CHECK: BoundsCheck
197 /// CHECK: ArrayGet
198 /// CHECK: BoundsCheck
199 /// CHECK: ArraySet
200 /// CHECK: BoundsCheck
201 /// CHECK: ArrayGet
202 /// CHECK: BoundsCheck
203 /// CHECK: ArraySet
204 /// CHECK: BoundsCheck
205 /// CHECK: ArrayGet
206 /// CHECK: BoundsCheck
207 /// CHECK: ArraySet
208 /// CHECK: BoundsCheck
209 /// CHECK: ArrayGet
210 /// CHECK: BoundsCheck
211 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700212
David Brazdila06d66a2015-05-28 11:14:54 +0100213 /// CHECK-START: int[] Main.constantIndexing3(int[], int[], boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +0100214 /// CHECK: Deoptimize
215 /// CHECK-NOT: BoundsCheck
216 /// CHECK: ArrayGet
David Brazdila06d66a2015-05-28 11:14:54 +0100217 /// CHECK: Deoptimize
218 /// CHECK-NOT: BoundsCheck
219 /// CHECK: ArraySet
220 /// CHECK-NOT: BoundsCheck
221 /// CHECK: ArrayGet
222 /// CHECK-NOT: BoundsCheck
223 /// CHECK: ArraySet
224 /// CHECK-NOT: BoundsCheck
225 /// CHECK: ArrayGet
226 /// CHECK-NOT: BoundsCheck
227 /// CHECK: ArraySet
228 /// CHECK-NOT: BoundsCheck
229 /// CHECK: ArrayGet
230 /// CHECK-NOT: BoundsCheck
231 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700232
233 static int[] constantIndexing3(int[] array1, int[] array2, boolean copy) {
234 if (!copy) {
235 return array1;
236 }
237 array2[0] = array1[0];
238 array2[1] = array1[1];
239 array2[2] = array1[2];
240 array2[3] = array1[3];
241 return array2;
242 }
243
244
David Brazdila06d66a2015-05-28 11:14:54 +0100245 /// CHECK-START: void Main.constantIndexing4(int[]) BCE (before)
246 /// CHECK: BoundsCheck
247 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700248
David Brazdila06d66a2015-05-28 11:14:54 +0100249 /// CHECK-START: void Main.constantIndexing4(int[]) BCE (after)
Aart Bik1d239822016-02-09 14:26:34 -0800250 /// CHECK-NOT: Deoptimize
David Brazdila06d66a2015-05-28 11:14:54 +0100251 /// CHECK: BoundsCheck
252 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700253
254 // There is only one array access. It's not beneficial
255 // to create a compare with deoptimization instruction.
256 static void constantIndexing4(int[] array) {
Aart Bik1d239822016-02-09 14:26:34 -0800257 array[0] = -1;
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700258 }
259
260
David Brazdila06d66a2015-05-28 11:14:54 +0100261 /// CHECK-START: void Main.constantIndexing5(int[]) BCE (before)
262 /// CHECK: BoundsCheck
263 /// CHECK: ArraySet
264 /// CHECK: BoundsCheck
265 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700266
David Brazdila06d66a2015-05-28 11:14:54 +0100267 /// CHECK-START: void Main.constantIndexing5(int[]) BCE (after)
268 /// CHECK-NOT: Deoptimize
269 /// CHECK: BoundsCheck
270 /// CHECK: ArraySet
271 /// CHECK: BoundsCheck
272 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700273
274 static void constantIndexing5(int[] array) {
275 // We don't apply the deoptimization for very large constant index
276 // since it's likely to be an anomaly and will throw AIOOBE.
277 array[Integer.MAX_VALUE - 1000] = 1;
278 array[Integer.MAX_VALUE - 999] = 1;
279 array[Integer.MAX_VALUE - 998] = 1;
280 }
281
Andreas Gampe639bdd12015-06-03 11:22:45 -0700282 /// CHECK-START: void Main.constantIndexing6(int[]) BCE (before)
283 /// CHECK: BoundsCheck
284 /// CHECK: ArraySet
285 /// CHECK: BoundsCheck
286 /// CHECK: ArraySet
287
288 /// CHECK-START: void Main.constantIndexing6(int[]) BCE (after)
289 /// CHECK: Deoptimize
Aart Bik1d239822016-02-09 14:26:34 -0800290 /// CHECK-NOT: BoundsCheck
291 /// CHECK: ArraySet
292 /// CHECK-NOT: BoundsCheck
293 /// CHECK: ArraySet
Andreas Gampe639bdd12015-06-03 11:22:45 -0700294
295 static void constantIndexing6(int[] array) {
Aart Bik1d239822016-02-09 14:26:34 -0800296 array[3] = 111;
297 array[4] = 111;
298 }
299
300 /// CHECK-START: void Main.constantIndexing7(int[], int) BCE (before)
301 /// CHECK: BoundsCheck
302 /// CHECK: ArraySet
303 /// CHECK: BoundsCheck
304 /// CHECK: ArraySet
305 /// CHECK: BoundsCheck
306 /// CHECK: ArraySet
307 /// CHECK: BoundsCheck
308 /// CHECK: ArraySet
309
310 /// CHECK-START: void Main.constantIndexing7(int[], int) BCE (after)
311 /// CHECK: Deoptimize
312 /// CHECK: Deoptimize
313 /// CHECK-NOT: BoundsCheck
314 /// CHECK: ArraySet
315 /// CHECK-NOT: BoundsCheck
316 /// CHECK: ArraySet
317 /// CHECK-NOT: BoundsCheck
318 /// CHECK: ArraySet
319 /// CHECK-NOT: BoundsCheck
320 /// CHECK: ArraySet
321
322 static void constantIndexing7(int[] array, int base) {
323 // With constant offsets to symbolic base.
324 array[base] = 10;
325 array[base + 1] = 20;
326 array[base + 2] = 30;
327 array[base + 3] = 40;
328 }
329
330 /// CHECK-START: void Main.constantIndexing8(int[], int) BCE (before)
331 /// CHECK: BoundsCheck
332 /// CHECK: ArraySet
333 /// CHECK: BoundsCheck
334 /// CHECK: ArraySet
335 /// CHECK: BoundsCheck
336 /// CHECK: ArraySet
337 /// CHECK: BoundsCheck
338 /// CHECK: ArraySet
339
340 /// CHECK-START: void Main.constantIndexing8(int[], int) BCE (after)
341 /// CHECK: Deoptimize
342 /// CHECK: Deoptimize
343 /// CHECK-NOT: BoundsCheck
344 /// CHECK: ArraySet
345 /// CHECK-NOT: BoundsCheck
346 /// CHECK: ArraySet
347 /// CHECK-NOT: BoundsCheck
348 /// CHECK: ArraySet
349 /// CHECK-NOT: BoundsCheck
350 /// CHECK: ArraySet
351
352 static void constantIndexing8(int[] array, int base) {
353 // With constant offsets "both ways" to symbolic base.
354 array[base - 1] = 100;
355 array[base] = 200;
356 array[base + 1] = 300;
357 array[base + 2] = 400;
358 }
359
360 /// CHECK-START: void Main.constantIndexing9(int[], int) BCE (before)
361 /// CHECK: BoundsCheck
362 /// CHECK: ArraySet
363 /// CHECK: BoundsCheck
364 /// CHECK: ArraySet
365 /// CHECK: BoundsCheck
366 /// CHECK: ArraySet
367 /// CHECK: BoundsCheck
368 /// CHECK: ArraySet
369
370 /// CHECK-START: void Main.constantIndexing9(int[], int) BCE (after)
371 /// CHECK: Deoptimize
372 /// CHECK: Deoptimize
373 /// CHECK-NOT: BoundsCheck
374 /// CHECK: ArraySet
375 /// CHECK-NOT: BoundsCheck
376 /// CHECK: ArraySet
377 /// CHECK-NOT: BoundsCheck
378 /// CHECK: ArraySet
379 /// CHECK-NOT: BoundsCheck
380 /// CHECK: ArraySet
381 /// CHECK-NOT: BoundsCheck
382
383 static void constantIndexing9(int[] array, int base) {
384 // Final range is base..base+3 so conditional
385 // references may be included in the end.
386 array[base] = 0;
387 if (base != 12345)
388 array[base + 2] = 2;
389 array[base + 3] = 3;
390 if (base != 67890)
391 array[base + 1] = 1;
392 }
393
394 static void runAllConstantIndices() {
395 int[] a1 = { 0 };
396 int[] a6 = { 0, 0, 0, 0, 0, 0 };
397
398 boolean caught = false;
399 try {
400 constantIndexing1(a1);
401 } catch (ArrayIndexOutOfBoundsException e) {
402 caught = true;
403 }
404 if (!caught) {
405 System.out.println("constant indices 1 failed!");
406 }
407
408 constantIndexing1(a6);
409 if (a6[4] != 11 || a6[5] != 11) {
410 System.out.println("constant indices 1 failed!");
411 }
412
413 caught = false;
414 try {
415 $opt$noinline$constantIndexing2(a6);
416 } catch (ArrayIndexOutOfBoundsException e) {
417 caught = true;
418 }
419 if (!caught || a6[0] != 0 || a6[1] != 1 || a6[2] != 1 ||
420 a6[3] != 1 || a6[4] != 1 || a6[5] != 11) {
421 System.out.println("constant indices 2 failed!");
422 }
423
424 caught = false;
425 try {
426 constantIndexing2b(a1);
427 } catch (ArrayIndexOutOfBoundsException e) {
428 caught = true;
429 }
430 if (!caught || a1[0] != 7) {
431 System.out.println("constant indices 2b failed!");
432 }
433
434 constantIndexing2b(a6);
435 if (a6[0] != 7 || a6[1] != 7 || a6[2] != 7 ||
436 a6[3] != 7 || a6[4] != 1 || a6[5] != 11) {
437 System.out.println("constant indices 2b failed!");
438 }
439
440 int[] b4 = new int[4];
441 constantIndexing3(a6, b4, true);
442 if (b4[0] != 7 || b4[1] != 7 || b4[2] != 7 || b4[3] != 7) {
443 System.out.println("constant indices 3 failed!");
444 }
445
446 constantIndexing4(a1);
447 if (a1[0] != -1) {
448 System.out.println("constant indices 4 failed!");
449 }
450
451 caught = false;
452 try {
453 constantIndexing5(a6);
454 } catch (ArrayIndexOutOfBoundsException e) {
455 caught = true;
456 }
457 if (!caught) {
458 System.out.println("constant indices 5 failed!");
459 }
460
461 constantIndexing6(a6);
462 if (a6[0] != 7 || a6[1] != 7 || a6[2] != 7 ||
463 a6[3] != 111 || a6[4] != 111 || a6[5] != 11) {
464 System.out.println("constant indices 6 failed!");
465 }
466
467 constantIndexing7(a6, 1);
468 if (a6[0] != 7 || a6[1] != 10 || a6[2] != 20 ||
469 a6[3] != 30 || a6[4] != 40 || a6[5] != 11) {
470 System.out.println("constant indices 7 failed!");
471 }
472
473 caught = false;
474 try {
475 constantIndexing7(a6, 5);
476 } catch (ArrayIndexOutOfBoundsException e) {
477 caught = true;
478 }
479 if (!caught || a6[0] != 7 || a6[1] != 10 || a6[2] != 20 ||
480 a6[3] != 30 || a6[4] != 40 || a6[5] != 10) {
481 System.out.println("constant indices 7 failed!");
482 }
483
484 constantIndexing8(a6, 1);
485 if (a6[0] != 100 || a6[1] != 200 || a6[2] != 300 ||
486 a6[3] != 400 || a6[4] != 40 || a6[5] != 10) {
487 System.out.println("constant indices 8 failed!");
488 }
489
490 caught = false;
491 try {
492 constantIndexing8(a6, 0);
493 } catch (ArrayIndexOutOfBoundsException e) {
494 caught = true;
495 }
496 if (!caught || a6[0] != 100) {
497 System.out.println("constant indices 8 failed!");
498 }
499
500 constantIndexing9(a6, 0);
501 if (a6[0] != 0 || a6[1] != 1 || a6[2] != 2 ||
502 a6[3] != 3 || a6[4] != 40 || a6[5] != 10) {
503 System.out.println("constant indices 9 failed!");
504 }
Andreas Gampe639bdd12015-06-03 11:22:45 -0700505 }
506
507 // A helper into which the actual throwing function should be inlined.
508 static void constantIndexingForward6(int[] array) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700509 assertIsManaged();
Andreas Gampe639bdd12015-06-03 11:22:45 -0700510 constantIndexing6(array);
511 }
512
David Brazdila06d66a2015-05-28 11:14:54 +0100513 /// CHECK-START: void Main.loopPattern1(int[]) BCE (before)
514 /// CHECK: BoundsCheck
515 /// CHECK: ArraySet
516 /// CHECK: BoundsCheck
517 /// CHECK: ArraySet
518 /// CHECK: BoundsCheck
519 /// CHECK: ArraySet
520 /// CHECK: BoundsCheck
521 /// CHECK: ArraySet
522 /// CHECK: BoundsCheck
523 /// CHECK: ArraySet
524 /// CHECK: BoundsCheck
525 /// CHECK: ArraySet
526 /// CHECK: BoundsCheck
527 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800528
David Brazdila06d66a2015-05-28 11:14:54 +0100529 /// CHECK-START: void Main.loopPattern1(int[]) BCE (after)
530 /// CHECK-NOT: BoundsCheck
531 /// CHECK: ArraySet
532 /// CHECK-NOT: BoundsCheck
533 /// CHECK: ArraySet
534 /// CHECK-NOT: BoundsCheck
535 /// CHECK: ArraySet
536 /// CHECK: BoundsCheck
537 /// CHECK: ArraySet
538 /// CHECK: BoundsCheck
539 /// CHECK: ArraySet
540 /// CHECK: BoundsCheck
541 /// CHECK: ArraySet
542 /// CHECK-NOT: BoundsCheck
543 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800544
545 static void loopPattern1(int[] array) {
546 for (int i = 0; i < array.length; i++) {
547 array[i] = 1; // Bounds check can be eliminated.
548 }
549
550 for (int i = 1; i < array.length; i++) {
551 array[i] = 1; // Bounds check can be eliminated.
552 }
553
554 for (int i = 1; i < array.length - 1; i++) {
555 array[i] = 1; // Bounds check can be eliminated.
556 }
557
558 for (int i = -1; i < array.length; i++) {
559 array[i] = 1; // Bounds check can't be eliminated.
560 }
561
562 for (int i = 0; i <= array.length; i++) {
563 array[i] = 1; // Bounds check can't be eliminated.
564 }
565
566 for (int i = 0; i < array.length; i += 2) {
567 // We don't have any assumption on max array length yet.
568 // Bounds check can't be eliminated due to overflow concern.
569 array[i] = 1;
570 }
571
572 for (int i = 1; i < array.length; i += 2) {
573 // Bounds check can be eliminated since i is odd so the last
574 // i that's less than array.length is at most (Integer.MAX_VALUE - 2).
575 array[i] = 1;
576 }
577 }
578
579
David Brazdila06d66a2015-05-28 11:14:54 +0100580 /// CHECK-START: void Main.loopPattern2(int[]) BCE (before)
581 /// CHECK: BoundsCheck
582 /// CHECK: ArraySet
583 /// CHECK: BoundsCheck
584 /// CHECK: ArraySet
585 /// CHECK: BoundsCheck
586 /// CHECK: ArraySet
587 /// CHECK: BoundsCheck
588 /// CHECK: ArraySet
589 /// CHECK: BoundsCheck
590 /// CHECK: ArraySet
591 /// CHECK: BoundsCheck
592 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800593
David Brazdila06d66a2015-05-28 11:14:54 +0100594 /// CHECK-START: void Main.loopPattern2(int[]) BCE (after)
595 /// CHECK-NOT: BoundsCheck
596 /// CHECK: ArraySet
597 /// CHECK-NOT: BoundsCheck
598 /// CHECK: ArraySet
599 /// CHECK-NOT: BoundsCheck
600 /// CHECK: ArraySet
601 /// CHECK: BoundsCheck
602 /// CHECK: ArraySet
603 /// CHECK: BoundsCheck
604 /// CHECK: ArraySet
605 /// CHECK-NOT: BoundsCheck
606 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800607
608 static void loopPattern2(int[] array) {
609 for (int i = array.length - 1; i >= 0; i--) {
610 array[i] = 1; // Bounds check can be eliminated.
611 }
612
613 for (int i = array.length; i > 0; i--) {
614 array[i - 1] = 1; // Bounds check can be eliminated.
615 }
616
617 for (int i = array.length - 1; i > 0; i--) {
618 array[i] = 1; // Bounds check can be eliminated.
619 }
620
621 for (int i = array.length; i >= 0; i--) {
622 array[i] = 1; // Bounds check can't be eliminated.
623 }
624
625 for (int i = array.length; i >= 0; i--) {
626 array[i - 1] = 1; // Bounds check can't be eliminated.
627 }
628
629 for (int i = array.length; i > 0; i -= 20) {
630 // For i >= 0, (i - 20 - 1) is guaranteed not to underflow.
631 array[i - 1] = 1; // Bounds check can be eliminated.
632 }
633 }
634
635
David Brazdila06d66a2015-05-28 11:14:54 +0100636 /// CHECK-START: void Main.loopPattern3(int[]) BCE (before)
637 /// CHECK: BoundsCheck
638 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800639
David Brazdila06d66a2015-05-28 11:14:54 +0100640 /// CHECK-START: void Main.loopPattern3(int[]) BCE (after)
641 /// CHECK: BoundsCheck
642 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800643
644 static void loopPattern3(int[] array) {
645 java.util.Random random = new java.util.Random();
646 for (int i = 0; ; i++) {
647 if (random.nextInt() % 1000 == 0 && i < array.length) {
648 // Can't eliminate the bound check since not every i++ is
649 // matched with a array length check, so there is some chance that i
650 // overflows and is negative.
651 array[i] = 1;
652 }
653 }
654 }
655
656
David Brazdila06d66a2015-05-28 11:14:54 +0100657 /// CHECK-START: void Main.constantNewArray() BCE (before)
658 /// CHECK: BoundsCheck
659 /// CHECK: ArraySet
660 /// CHECK: BoundsCheck
661 /// CHECK: ArraySet
662 /// CHECK: BoundsCheck
663 /// CHECK: ArraySet
664 /// CHECK: BoundsCheck
665 /// CHECK: ArraySet
666 /// CHECK: BoundsCheck
667 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800668
David Brazdila06d66a2015-05-28 11:14:54 +0100669 /// CHECK-START: void Main.constantNewArray() BCE (after)
670 /// CHECK-NOT: BoundsCheck
671 /// CHECK: ArraySet
672 /// CHECK: BoundsCheck
673 /// CHECK: ArraySet
674 /// CHECK-NOT: BoundsCheck
675 /// CHECK: ArraySet
676 /// CHECK-NOT: BoundsCheck
677 /// CHECK: ArraySet
678 /// CHECK: BoundsCheck
679 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800680
681 static void constantNewArray() {
682 int[] array = new int[10];
683 for (int i = 0; i < 10; i++) {
684 array[i] = 1; // Bounds check can be eliminated.
685 }
686
687 for (int i = 0; i <= 10; i++) {
688 array[i] = 1; // Bounds check can't be eliminated.
689 }
690
691 array[0] = 1; // Bounds check can be eliminated.
692 array[9] = 1; // Bounds check can be eliminated.
693 array[10] = 1; // Bounds check can't be eliminated.
694 }
695
Mingyao Yang4559f002015-02-27 14:43:53 -0800696
697 static byte readData() {
698 return 1;
699 }
700
David Brazdila06d66a2015-05-28 11:14:54 +0100701 /// CHECK-START: void Main.circularBufferProducer() BCE (before)
702 /// CHECK: BoundsCheck
703 /// CHECK: ArraySet
Mingyao Yang4559f002015-02-27 14:43:53 -0800704
David Brazdila06d66a2015-05-28 11:14:54 +0100705 /// CHECK-START: void Main.circularBufferProducer() BCE (after)
706 /// CHECK-NOT: BoundsCheck
707 /// CHECK: ArraySet
Mingyao Yang4559f002015-02-27 14:43:53 -0800708
709 static void circularBufferProducer() {
710 byte[] array = new byte[4096];
711 int i = 0;
712 while (true) {
713 array[i & (array.length - 1)] = readData();
714 i++;
715 }
716 }
717
718
David Brazdila06d66a2015-05-28 11:14:54 +0100719 /// CHECK-START: void Main.pyramid1(int[]) BCE (before)
720 /// CHECK: BoundsCheck
721 /// CHECK: ArraySet
722 /// CHECK: BoundsCheck
723 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800724
David Brazdila06d66a2015-05-28 11:14:54 +0100725 /// CHECK-START: void Main.pyramid1(int[]) BCE (after)
726 /// CHECK-NOT: BoundsCheck
727 /// CHECK: ArraySet
728 /// CHECK-NOT: BoundsCheck
729 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800730
731 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
732 static void pyramid1(int[] array) {
733 for (int i = 0; i < (array.length + 1) / 2; i++) {
734 array[i] = i;
735 array[array.length - 1 - i] = i;
736 }
737 }
738
739
David Brazdila06d66a2015-05-28 11:14:54 +0100740 /// CHECK-START: void Main.pyramid2(int[]) BCE (before)
741 /// CHECK: BoundsCheck
742 /// CHECK: ArraySet
743 /// CHECK: BoundsCheck
744 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800745
David Brazdila06d66a2015-05-28 11:14:54 +0100746 /// CHECK-START: void Main.pyramid2(int[]) BCE (after)
747 /// CHECK-NOT: BoundsCheck
748 /// CHECK: ArraySet
749 /// CHECK-NOT: BoundsCheck
750 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800751
752 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
753 static void pyramid2(int[] array) {
754 for (int i = 0; i < (array.length + 1) >> 1; i++) {
755 array[i] = i;
756 array[array.length - 1 - i] = i;
757 }
758 }
759
760
David Brazdila06d66a2015-05-28 11:14:54 +0100761 /// CHECK-START: void Main.pyramid3(int[]) BCE (before)
762 /// CHECK: BoundsCheck
763 /// CHECK: ArraySet
764 /// CHECK: BoundsCheck
765 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800766
David Brazdila06d66a2015-05-28 11:14:54 +0100767 /// CHECK-START: void Main.pyramid3(int[]) BCE (after)
768 /// CHECK-NOT: BoundsCheck
769 /// CHECK: ArraySet
770 /// CHECK-NOT: BoundsCheck
771 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800772
773 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
774 static void pyramid3(int[] array) {
775 for (int i = 0; i < (array.length + 1) >>> 1; i++) {
776 array[i] = i;
777 array[array.length - 1 - i] = i;
778 }
779 }
780
781
David Brazdila06d66a2015-05-28 11:14:54 +0100782 /// CHECK-START: boolean Main.isPyramid(int[]) BCE (before)
783 /// CHECK: BoundsCheck
784 /// CHECK: ArrayGet
785 /// CHECK: BoundsCheck
786 /// CHECK: ArrayGet
Mingyao Yang57e04752015-02-09 18:13:26 -0800787
David Brazdila06d66a2015-05-28 11:14:54 +0100788 /// CHECK-START: boolean Main.isPyramid(int[]) BCE (after)
789 /// CHECK-NOT: BoundsCheck
790 /// CHECK: ArrayGet
791 /// CHECK-NOT: BoundsCheck
792 /// CHECK: ArrayGet
Mingyao Yang57e04752015-02-09 18:13:26 -0800793
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800794 static boolean isPyramid(int[] array) {
795 int i = 0;
796 int j = array.length - 1;
797 while (i <= j) {
798 if (array[i] != i) {
799 return false;
800 }
801 if (array[j] != i) {
802 return false;
803 }
804 i++; j--;
805 }
806 return true;
807 }
808
809
David Brazdila06d66a2015-05-28 11:14:54 +0100810 /// CHECK-START: void Main.bubbleSort(int[]) GVN (before)
811 /// CHECK: BoundsCheck
812 /// CHECK: ArrayGet
813 /// CHECK: BoundsCheck
814 /// CHECK: ArrayGet
815 /// CHECK: BoundsCheck
816 /// CHECK: ArrayGet
817 /// CHECK: BoundsCheck
818 /// CHECK: ArrayGet
819 /// CHECK: BoundsCheck
820 /// CHECK: ArraySet
821 /// CHECK: BoundsCheck
822 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800823
David Brazdila06d66a2015-05-28 11:14:54 +0100824 /// CHECK-START: void Main.bubbleSort(int[]) GVN (after)
825 /// CHECK: BoundsCheck
826 /// CHECK: ArrayGet
827 /// CHECK: BoundsCheck
828 /// CHECK: ArrayGet
829 /// CHECK-NOT: ArrayGet
830 /// CHECK-NOT: ArrayGet
831 /// CHECK-NOT: BoundsCheck
832 /// CHECK: ArraySet
833 /// CHECK-NOT: BoundsCheck
834 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800835
David Brazdila06d66a2015-05-28 11:14:54 +0100836 /// CHECK-START: void Main.bubbleSort(int[]) BCE (after)
837 /// CHECK-NOT: BoundsCheck
838 /// CHECK: ArrayGet
839 /// CHECK-NOT: BoundsCheck
840 /// CHECK: ArrayGet
841 /// CHECK-NOT: ArrayGet
842 /// CHECK-NOT: ArrayGet
843 /// CHECK-NOT: BoundsCheck
844 /// CHECK: ArraySet
845 /// CHECK-NOT: BoundsCheck
846 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800847
848 static void bubbleSort(int[] array) {
849 for (int i = 0; i < array.length - 1; i++) {
850 for (int j = 0; j < array.length - i - 1; j++) {
851 if (array[j] > array[j + 1]) {
852 int temp = array[j + 1];
853 array[j + 1] = array[j];
854 array[j] = temp;
855 }
856 }
857 }
858 }
859
Aart Bik5d75afe2015-12-14 11:57:01 -0800860 static int[][] mA;
861
862 /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800863 // Array references mA[i] and ..[j] both in inner loop.
864 /// CHECK-DAG: <<Get1:l\d+>> ArrayGet [<<Array1:l\d+>>,<<Bounds1:i\d+>>] loop:<<InnerLoop:B\d+>>
865 /// CHECK-DAG: <<Array1>> NullCheck [<<Field1:l\d+>>] loop:<<InnerLoop>>
866 /// CHECK-DAG: <<Len1:i\d+>> ArrayLength [<<Array1>>] loop:<<InnerLoop>>
867 /// CHECK-DAG: <<Bounds1>> BoundsCheck [<<Index1:i\d+>>,<<Len1>>] loop:<<InnerLoop>>
868 /// CHECK-DAG: <<Get2:i\d+>> ArrayGet [<<Array2:l\d+>>,<<Bounds2:i\d+>>] loop:<<InnerLoop>>
869 /// CHECK-DAG: <<Array2>> NullCheck [<<Get1>>] loop:<<InnerLoop>>
870 /// CHECK-DAG: <<Len2:i\d+>> ArrayLength [<<Array2>>] loop:<<InnerLoop>>
871 /// CHECK-DAG: <<Bounds2>> BoundsCheck [<<Index2:i\d+>>,<<Len2>>] loop:<<InnerLoop>>
Vladimir Marko17fb8932016-02-02 14:53:47 +0000872 // Note: The ArtMethod* (typed as int or long) is optional after sharpening.
873 /// CHECK-DAG: InvokeStaticOrDirect [<<Get2>>{{(,[ij]\d+)?}}] loop:<<InnerLoop>>
Aart Bik09e8d5f2016-01-22 16:49:55 -0800874 /// CHECK-DAG: <<Index2>> Phi loop:<<InnerLoop>>
875 /// CHECK-DAG: <<Index1>> Phi loop:<<OuterLoop:B\d+>>
876 /// CHECK-DAG: <<Field1>> StaticFieldGet loop:none
877 /// CHECK-EVAL: "<<InnerLoop>>" != "<<OuterLoop>>"
878 //
879 /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (after)
880 // Array reference mA[i] hoisted to same level as deopt.
881 /// CHECK-DAG: Deoptimize loop:<<OuterLoop:B\d+>>
882 /// CHECK-DAG: ArrayLength loop:<<OuterLoop>>
883 /// CHECK-DAG: <<Get1:l\d+>> ArrayGet [<<Array1:l\d+>>,<<Index1:i\d+>>] loop:<<OuterLoop>>
884 // Array reference ..[j] still in inner loop, with a direct index.
885 /// CHECK-DAG: <<Get2:i\d+>> ArrayGet [<<Array2:l\d+>>,<<Index2:i\d+>>] loop:<<InnerLoop:B\d+>>
Vladimir Marko17fb8932016-02-02 14:53:47 +0000886 // Note: The ArtMethod* (typed as int or long) is optional after sharpening.
887 /// CHECK-DAG: InvokeStaticOrDirect [<<Get2>>{{(,[ij]\d+)?}}] loop:<<InnerLoop>>
Aart Bik09e8d5f2016-01-22 16:49:55 -0800888 /// CHECK-DAG: <<Index2>> Phi loop:<<InnerLoop>>
889 /// CHECK-DAG: <<Index1>> Phi loop:<<OuterLoop>>
890 // Synthetic phi.
891 /// CHECK-DAG: <<Array2>> Phi loop:<<OuterLoop>>
892 /// CHECK-DAG: <<Array1>> StaticFieldGet loop:none
893 /// CHECK-EVAL: "<<InnerLoop>>" != "<<OuterLoop>>"
894 //
Aart Bik5d75afe2015-12-14 11:57:01 -0800895 /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (after)
896 /// CHECK-NOT: NullCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800897 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800898 static void dynamicBCEAndIntrinsic(int n) {
899 for (int i = 0; i < n; i++) {
900 for (int j = 0; j < n; j++) {
901 // Since intrinsic call cannot modify fields or arrays,
902 // dynamic BCE and hoisting can be applied to the inner loop.
903 mA[i][j] = Math.abs(mA[i][j]);
904 }
905 }
906 }
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800907
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700908 static int foo() {
909 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700910 assertIsManaged();
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700911 // This will cause AIOOBE.
Nicolas Geoffray5949fa02015-12-18 10:57:10 +0000912 $opt$noinline$constantIndexing2(new int[3]);
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700913 } catch (ArrayIndexOutOfBoundsException e) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700914 assertIsManaged(); // This is to ensure that single-frame deoptimization works.
Nicolas Geoffray5949fa02015-12-18 10:57:10 +0000915 // Will need to be updated if $opt$noinline$constantIndexing2 is inlined.
Andreas Gampe639bdd12015-06-03 11:22:45 -0700916 try {
917 // This will cause AIOOBE.
918 constantIndexingForward6(new int[3]);
919 } catch (ArrayIndexOutOfBoundsException e2) {
David Brazdil95177982015-10-30 12:56:58 -0500920 // Having deopted, we expect to be running interpreted at this point.
921 // Does not apply to debuggable, however, since we do not inline.
Andreas Gampe639bdd12015-06-03 11:22:45 -0700922 return 99;
923 }
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700924 }
925 return 0;
926 }
927
928
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700929 int sum;
930
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700931 /// CHECK-START: void Main.foo1(int[], int, int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +0100932 /// CHECK: BoundsCheck
933 /// CHECK: ArraySet
934 /// CHECK-NOT: BoundsCheck
935 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700936
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700937 /// CHECK-START: void Main.foo1(int[], int, int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +0100938 /// CHECK: Phi
939 /// CHECK-NOT: BoundsCheck
940 /// CHECK: ArraySet
941 /// CHECK-NOT: BoundsCheck
942 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -0800943 // Added blocks at end for deoptimization.
944 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -0700945 /// CHECK: If
Mingyao Yang3584bce2015-05-19 16:01:59 -0700946 /// CHECK: Deoptimize
947 /// CHECK: Deoptimize
948 /// CHECK: Deoptimize
949 /// CHECK-NOT: Deoptimize
950 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -0800951 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -0700952 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700953
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700954 void foo1(int[] array, int start, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -0800955 // Three HDeoptimize will be added. Two for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700956 // and one for null check on array (to hoist null
957 // check and array.length out of loop).
958 for (int i = start ; i < end; i++) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700959 if (expectInterpreter) {
960 assertIsInterpreted();
961 } else {
962 assertIsManaged();
963 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700964 array[i] = 1;
965 sum += array[i];
966 }
967 }
968
969
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700970 /// CHECK-START: void Main.foo2(int[], int, int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +0100971 /// CHECK: BoundsCheck
972 /// CHECK: ArraySet
973 /// CHECK-NOT: BoundsCheck
974 /// CHECK: ArrayGet
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700975 /// CHECK-START: void Main.foo2(int[], int, int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +0100976 /// CHECK: Phi
977 /// CHECK-NOT: BoundsCheck
978 /// CHECK: ArraySet
979 /// CHECK-NOT: BoundsCheck
980 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -0800981 // Added blocks at end for deoptimization.
982 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -0700983 /// CHECK: If
Mingyao Yang3584bce2015-05-19 16:01:59 -0700984 /// CHECK: Deoptimize
985 /// CHECK: Deoptimize
986 /// CHECK: Deoptimize
987 /// CHECK-NOT: Deoptimize
988 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -0800989 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -0700990 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700991
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700992 void foo2(int[] array, int start, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -0800993 // Three HDeoptimize will be added. Two for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700994 // and one for null check on array (to hoist null
995 // check and array.length out of loop).
996 for (int i = start ; i <= end; i++) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700997 if (expectInterpreter) {
998 assertIsInterpreted();
999 } else {
1000 assertIsManaged();
1001 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001002 array[i] = 1;
1003 sum += array[i];
1004 }
1005 }
1006
1007
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001008 /// CHECK-START: void Main.foo3(int[], int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001009 /// CHECK: BoundsCheck
1010 /// CHECK: ArraySet
1011 /// CHECK-NOT: BoundsCheck
1012 /// CHECK: ArrayGet
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001013 /// CHECK-START: void Main.foo3(int[], int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001014 /// CHECK: Phi
1015 /// CHECK-NOT: BoundsCheck
1016 /// CHECK: ArraySet
1017 /// CHECK-NOT: BoundsCheck
1018 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001019 // Added blocks at end for deoptimization.
1020 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001021 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001022 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001023 /// CHECK: Deoptimize
1024 /// CHECK: Deoptimize
1025 /// CHECK-NOT: Deoptimize
1026 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001027 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001028 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001029
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001030 void foo3(int[] array, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001031 // Three HDeoptimize will be added. Two for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001032 // and one for null check on array (to hoist null check
1033 // and array.length out of loop).
1034 for (int i = 3 ; i <= end; i++) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001035 if (expectInterpreter) {
1036 assertIsInterpreted();
1037 } else {
1038 assertIsManaged();
1039 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001040 array[i] = 1;
1041 sum += array[i];
1042 }
1043 }
1044
Mingyao Yang3584bce2015-05-19 16:01:59 -07001045
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001046 /// CHECK-START: void Main.foo4(int[], int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001047 /// CHECK: BoundsCheck
1048 /// CHECK: ArraySet
1049 /// CHECK-NOT: BoundsCheck
1050 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001051
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001052 /// CHECK-START: void Main.foo4(int[], int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001053 /// CHECK: Phi
1054 /// CHECK-NOT: BoundsCheck
1055 /// CHECK: ArraySet
1056 /// CHECK-NOT: BoundsCheck
1057 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001058 // Added blocks at end for deoptimization.
1059 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001060 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001061 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001062 /// CHECK: Deoptimize
1063 /// CHECK: Deoptimize
1064 /// CHECK-NOT: Deoptimize
1065 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001066 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001067 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001068
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001069 void foo4(int[] array, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001070 // Three HDeoptimize will be added. Two for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001071 // and one for null check on array (to hoist null check
1072 // and array.length out of loop).
1073 for (int i = end ; i > 0; i--) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001074 if (expectInterpreter) {
1075 assertIsInterpreted();
1076 } else {
1077 assertIsManaged();
1078 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001079 array[i - 1] = 1;
1080 sum += array[i - 1];
1081 }
1082 }
1083
1084
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001085 /// CHECK-START: void Main.foo5(int[], int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001086 /// CHECK: BoundsCheck
1087 /// CHECK: ArraySet
1088 /// CHECK: BoundsCheck
1089 /// CHECK: ArrayGet
1090 /// CHECK: BoundsCheck
1091 /// CHECK: ArrayGet
1092 /// CHECK: BoundsCheck
1093 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001094
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001095 /// CHECK-START: void Main.foo5(int[], int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001096 /// CHECK-NOT: BoundsCheck
1097 /// CHECK: ArraySet
David Brazdila06d66a2015-05-28 11:14:54 +01001098 /// CHECK: Phi
1099 /// CHECK-NOT: BoundsCheck
1100 /// CHECK: ArrayGet
1101 /// CHECK-NOT: BoundsCheck
1102 /// CHECK: ArrayGet
1103 /// CHECK-NOT: BoundsCheck
1104 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001105 // Added blocks at end for deoptimization.
1106 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001107 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001108 /// CHECK: Deoptimize
1109 /// CHECK: Deoptimize
1110 /// CHECK: Deoptimize
1111 /// CHECK: Deoptimize
1112 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001113 /// CHECK: Deoptimize
1114 /// CHECK-NOT: Deoptimize
1115 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001116 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001117 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001118
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001119 void foo5(int[] array, int end, boolean expectInterpreter) {
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001120 // Bounds check in this loop can be eliminated without deoptimization.
1121 for (int i = array.length - 1 ; i >= 0; i--) {
1122 array[i] = 1;
1123 }
Aart Bik4a342772015-11-30 10:17:46 -08001124 // Several HDeoptimize will be added. Two for each index.
1125 // The null check is not necessary.
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001126 for (int i = end - 2 ; i > 0; i--) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001127 if (expectInterpreter) {
1128 assertIsInterpreted();
1129 } else {
1130 assertIsManaged();
1131 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001132 sum += array[i - 1];
1133 sum += array[i];
1134 sum += array[i + 1];
1135 }
1136 }
1137
1138
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001139 /// CHECK-START: void Main.foo6(int[], int, int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001140 /// CHECK: BoundsCheck
1141 /// CHECK: ArrayGet
1142 /// CHECK: BoundsCheck
1143 /// CHECK: ArrayGet
1144 /// CHECK: BoundsCheck
1145 /// CHECK: ArrayGet
1146 /// CHECK: BoundsCheck
1147 /// CHECK: ArrayGet
1148 /// CHECK: BoundsCheck
1149 /// CHECK: ArrayGet
1150 /// CHECK-NOT: BoundsCheck
1151 /// CHECK: ArraySet
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001152 /// CHECK-START: void Main.foo6(int[], int, int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001153 /// CHECK: Phi
1154 /// CHECK-NOT: BoundsCheck
1155 /// CHECK: ArrayGet
1156 /// CHECK-NOT: BoundsCheck
1157 /// CHECK: ArrayGet
1158 /// CHECK-NOT: BoundsCheck
1159 /// CHECK: ArrayGet
1160 /// CHECK-NOT: BoundsCheck
1161 /// CHECK: ArrayGet
1162 /// CHECK-NOT: BoundsCheck
1163 /// CHECK: ArrayGet
1164 /// CHECK-NOT: BoundsCheck
1165 /// CHECK: ArraySet
Aart Bik4a342772015-11-30 10:17:46 -08001166 // Added blocks at end for deoptimization.
1167 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001168 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001169 /// CHECK: Deoptimize
1170 /// CHECK: Deoptimize
1171 /// CHECK: Deoptimize
1172 /// CHECK: Deoptimize
1173 /// CHECK: Deoptimize
1174 /// CHECK: Deoptimize
1175 /// CHECK: Deoptimize
1176 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001177 /// CHECK: Deoptimize
1178 /// CHECK: Deoptimize
1179 /// CHECK: Deoptimize
1180 /// CHECK-NOT: Deoptimize
1181 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001182 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001183 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001184
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001185 void foo6(int[] array, int start, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001186 // Several HDeoptimize will be added.
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001187 for (int i = end; i >= start; i--) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001188 if (expectInterpreter) {
1189 assertIsInterpreted();
1190 } else {
1191 assertIsManaged();
1192 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001193 array[i] = (array[i-2] + array[i-1] + array[i] + array[i+1] + array[i+2]) / 5;
1194 }
1195 }
1196
1197
David Brazdila06d66a2015-05-28 11:14:54 +01001198 /// CHECK-START: void Main.foo7(int[], int, int, boolean) BCE (before)
1199 /// CHECK: BoundsCheck
1200 /// CHECK: ArrayGet
1201 /// CHECK: BoundsCheck
1202 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001203
David Brazdila06d66a2015-05-28 11:14:54 +01001204 /// CHECK-START: void Main.foo7(int[], int, int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001205 /// CHECK: Phi
1206 /// CHECK: BoundsCheck
1207 /// CHECK: ArrayGet
1208 /// CHECK-NOT: BoundsCheck
1209 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001210 // Added blocks at end for deoptimization.
1211 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001212 /// CHECK: If
Mingyao Yang3584bce2015-05-19 16:01:59 -07001213 /// CHECK: Deoptimize
1214 /// CHECK: Deoptimize
1215 /// CHECK: Deoptimize
1216 /// CHECK-NOT: Deoptimize
1217 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001218 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001219 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001220
1221 void foo7(int[] array, int start, int end, boolean lowEnd) {
Aart Bik4a342772015-11-30 10:17:46 -08001222 // Three HDeoptimize will be added. One for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001223 // and one for null check on array (to hoist null
1224 // check and array.length out of loop).
1225 for (int i = start ; i < end; i++) {
1226 if (lowEnd) {
1227 // This array access isn't certain. So we don't
1228 // use +1000 offset in decision making for deoptimization
1229 // conditions.
1230 sum += array[i + 1000];
1231 }
1232 sum += array[i];
1233 }
1234 }
1235
1236
Mingyao Yang3584bce2015-05-19 16:01:59 -07001237 /// CHECK-START: void Main.foo8(int[][], int, int) BCE (before)
1238 /// CHECK: BoundsCheck
1239 /// CHECK: ArrayGet
1240 /// CHECK: BoundsCheck
1241 /// CHECK: ArraySet
1242
1243 /// CHECK-START: void Main.foo8(int[][], int, int) BCE (after)
1244 /// CHECK: Phi
1245 /// CHECK-NOT: BoundsCheck
1246 /// CHECK: ArrayGet
1247 /// CHECK: Phi
1248 /// CHECK-NOT: BoundsCheck
1249 /// CHECK: ArraySet
Aart Bik4a342772015-11-30 10:17:46 -08001250 // Added blocks at end for deoptimization.
1251 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001252 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001253 /// CHECK: Deoptimize
1254 /// CHECK: Deoptimize
1255 /// CHECK: Deoptimize
Aart Bikd59c7062015-11-21 05:21:52 +00001256 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001257 /// CHECK: Goto
1258 /// CHECK: Goto
1259 /// CHECK: If
Mingyao Yang3584bce2015-05-19 16:01:59 -07001260 /// CHECK: Deoptimize
1261 /// CHECK: Deoptimize
1262 /// CHECK: Deoptimize
1263 /// CHECK-NOT: Deoptimize
1264 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001265 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001266 /// CHECK: Goto
1267
1268 void foo8(int[][] matrix, int start, int end) {
Aart Bik4a342772015-11-30 10:17:46 -08001269 // Three HDeoptimize will be added for the outer loop,
1270 // two for the index, and null check on matrix. Same
1271 // for the inner loop.
Mingyao Yang3584bce2015-05-19 16:01:59 -07001272 for (int i = start; i < end; i++) {
1273 int[] row = matrix[i];
1274 for (int j = start; j < end; j++) {
1275 row[j] = 1;
1276 }
1277 }
1278 }
1279
1280
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001281 /// CHECK-START: void Main.foo9(int[], boolean) BCE (before)
Mingyao Yang3584bce2015-05-19 16:01:59 -07001282 /// CHECK: NullCheck
1283 /// CHECK: BoundsCheck
1284 /// CHECK: ArrayGet
1285
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001286 /// CHECK-START: void Main.foo9(int[], boolean) BCE (after)
Mingyao Yang3584bce2015-05-19 16:01:59 -07001287 // The loop is guaranteed to be entered. No need to transform the
1288 // loop for loop body entry test.
1289 /// CHECK: Deoptimize
1290 /// CHECK: Deoptimize
Aart Bik4a342772015-11-30 10:17:46 -08001291 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001292 /// CHECK-NOT: Deoptimize
1293 /// CHECK: Phi
1294 /// CHECK-NOT: NullCheck
1295 /// CHECK-NOT: BoundsCheck
1296 /// CHECK: ArrayGet
1297
Aart Bik4a342772015-11-30 10:17:46 -08001298 /// CHECK-START: void Main.foo9(int[], boolean) instruction_simplifier_after_bce (after)
1299 // Simplification removes the redundant check
1300 /// CHECK: Deoptimize
1301 /// CHECK: Deoptimize
1302 /// CHECK-NOT: Deoptimize
1303
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001304 void foo9(int[] array, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001305 // Two HDeoptimize will be added. Two for the index
1306 // and one for null check on array.
Mingyao Yang3584bce2015-05-19 16:01:59 -07001307 for (int i = 0 ; i < 10; i++) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001308 if (expectInterpreter) {
1309 assertIsInterpreted();
1310 } else {
1311 assertIsManaged();
1312 }
Mingyao Yang3584bce2015-05-19 16:01:59 -07001313 sum += array[i];
1314 }
1315 }
1316
1317
David Brazdila06d66a2015-05-28 11:14:54 +01001318 /// CHECK-START: void Main.partialLooping(int[], int, int) BCE (before)
1319 /// CHECK: BoundsCheck
1320 /// CHECK: ArraySet
Mingyao Yang9d750ef2015-04-26 18:15:30 -07001321
David Brazdila06d66a2015-05-28 11:14:54 +01001322 /// CHECK-START: void Main.partialLooping(int[], int, int) BCE (after)
1323 /// CHECK-NOT: Deoptimize
1324 /// CHECK: BoundsCheck
1325 /// CHECK: ArraySet
Mingyao Yang9d750ef2015-04-26 18:15:30 -07001326
1327 void partialLooping(int[] array, int start, int end) {
1328 // This loop doesn't cover the full range of [start, end) so
1329 // adding deoptimization is too aggressive, since end can be
1330 // greater than array.length but the loop is never going to work on
1331 // more than 2 elements.
1332 for (int i = start; i < end; i++) {
1333 if (i == 2) {
1334 return;
1335 }
1336 array[i] = 1;
1337 }
1338 }
1339
1340
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001341 static void testUnknownBounds() {
1342 boolean caught = false;
Aart Bik1d239822016-02-09 14:26:34 -08001343
1344 runAllConstantIndices();
1345
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001346 Main main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001347 main.foo1(new int[10], 0, 10, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001348 if (main.sum != 10) {
1349 System.out.println("foo1 failed!");
1350 }
1351
1352 caught = false;
1353 main = new Main();
1354 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001355 main.foo1(new int[10], 0, 11, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001356 } catch (ArrayIndexOutOfBoundsException e) {
1357 caught = true;
1358 }
1359 if (!caught || main.sum != 10) {
1360 System.out.println("foo1 exception failed!");
1361 }
1362
1363 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001364 main.foo2(new int[10], 0, 9, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001365 if (main.sum != 10) {
1366 System.out.println("foo2 failed!");
1367 }
1368
1369 caught = false;
1370 main = new Main();
1371 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001372 main.foo2(new int[10], 0, 10, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001373 } catch (ArrayIndexOutOfBoundsException e) {
1374 caught = true;
1375 }
1376 if (!caught || main.sum != 10) {
1377 System.out.println("foo2 exception failed!");
1378 }
1379
1380 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001381 main.foo3(new int[10], 9, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001382 if (main.sum != 7) {
1383 System.out.println("foo3 failed!");
1384 }
1385
1386 caught = false;
1387 main = new Main();
1388 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001389 main.foo3(new int[10], 10, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001390 } catch (ArrayIndexOutOfBoundsException e) {
1391 caught = true;
1392 }
1393 if (!caught || main.sum != 7) {
1394 System.out.println("foo3 exception failed!");
1395 }
1396
1397 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001398 main.foo4(new int[10], 10, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001399 if (main.sum != 10) {
1400 System.out.println("foo4 failed!");
1401 }
1402
1403 caught = false;
1404 main = new Main();
1405 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001406 main.foo4(new int[10], 11, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001407 } catch (ArrayIndexOutOfBoundsException e) {
1408 caught = true;
1409 }
1410 if (!caught || main.sum != 0) {
1411 System.out.println("foo4 exception failed!");
1412 }
1413
1414 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001415 main.foo5(new int[10], 10, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001416 if (main.sum != 24) {
1417 System.out.println("foo5 failed!");
1418 }
1419
1420 caught = false;
1421 main = new Main();
1422 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001423 main.foo5(new int[10], 11, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001424 } catch (ArrayIndexOutOfBoundsException e) {
1425 caught = true;
1426 }
1427 if (!caught || main.sum != 2) {
1428 System.out.println("foo5 exception failed!");
1429 }
1430
1431 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001432 main.foo6(new int[10], 2, 7, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001433
Mingyao Yang9d750ef2015-04-26 18:15:30 -07001434 main = new Main();
Mingyao Yang3584bce2015-05-19 16:01:59 -07001435 int[] array9 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001436 main.foo9(array9, false);
Mingyao Yang3584bce2015-05-19 16:01:59 -07001437 if (main.sum != 45) {
1438 System.out.println("foo9 failed!");
1439 }
1440
1441 main = new Main();
Mingyao Yang9d750ef2015-04-26 18:15:30 -07001442 int[] array = new int[4];
1443 main.partialLooping(new int[3], 0, 4);
1444 if ((array[0] != 1) && (array[1] != 1) &&
1445 (array[2] != 0) && (array[3] != 0)) {
1446 System.out.println("partialLooping failed!");
1447 }
1448
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001449 caught = false;
1450 main = new Main();
1451 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001452 main.foo6(new int[10], 2, 8, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001453 } catch (ArrayIndexOutOfBoundsException e) {
1454 caught = true;
1455 }
1456 if (!caught) {
1457 System.out.println("foo6 exception failed!");
1458 }
1459
1460 caught = false;
1461 main = new Main();
1462 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001463 main.foo6(new int[10], 1, 7, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001464 } catch (ArrayIndexOutOfBoundsException e) {
1465 caught = true;
1466 }
1467 if (!caught) {
1468 System.out.println("foo6 exception failed!");
1469 }
1470
1471 }
1472
Mingyao Yang718493c2015-07-22 15:56:34 -07001473 public void testExceptionMessage() {
1474 short[] B1 = new short[5];
1475 int[] B2 = new int[5];
1476 Exception err = null;
1477 try {
1478 testExceptionMessage1(B1, B2, null, -1, 6);
1479 } catch (Exception e) {
1480 err = e;
1481 }
1482 System.out.println(err);
1483 }
1484
1485 void testExceptionMessage1(short[] a1, int[] a2, long a3[], int start, int finish) {
1486 int j = finish + 77;
1487 // Bug: 22665511
1488 // A deoptimization will be triggered here right before the loop. Need to make
1489 // sure the value of j is preserved for the interpreter.
1490 for (int i = start; i <= finish; i++) {
1491 a2[j - 1] = a1[i + 1];
1492 }
1493 }
1494
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001495 // Make sure this method is compiled with optimizing.
David Brazdila06d66a2015-05-28 11:14:54 +01001496 /// CHECK-START: void Main.main(java.lang.String[]) register (after)
1497 /// CHECK: ParallelMove
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001498
Mingyao Yang0304e182015-01-30 16:41:29 -08001499 public static void main(String[] args) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001500 System.loadLibrary(args[0]);
1501
1502 if (!compiledWithOptimizing() ||
1503 !hasOatFile() ||
1504 runtimeIsSoftFail() ||
1505 isInterpreted()) {
1506 disableStackFrameAsserts();
1507 }
1508
Mingyao Yang0304e182015-01-30 16:41:29 -08001509 sieve(20);
Mingyao Yang8c8bad82015-02-09 18:13:26 -08001510
1511 int[] array = {5, 2, 3, 7, 0, 1, 6, 4};
1512 bubbleSort(array);
1513 for (int i = 0; i < 8; i++) {
1514 if (array[i] != i) {
1515 System.out.println("bubble sort failed!");
1516 }
1517 }
1518
Aart Bik5d75afe2015-12-14 11:57:01 -08001519 mA = new int[4][4];
1520 for (int i = 0; i < 4; i++) {
1521 for (int j = 0; j < 4; j++) {
1522 mA[i][j] = -1;
1523 }
1524 }
1525 dynamicBCEAndIntrinsic(4);
1526 for (int i = 0; i < 4; i++) {
1527 for (int j = 0; j < 4; j++) {
1528 if (mA[i][i] != 1) {
1529 System.out.println("dynamic bce failed!");
1530 }
1531 }
1532 }
1533
Mingyao Yang8c8bad82015-02-09 18:13:26 -08001534 array = new int[7];
1535 pyramid1(array);
1536 if (!isPyramid(array)) {
1537 System.out.println("pyramid1 failed!");
1538 }
1539
1540 array = new int[8];
1541 pyramid2(array);
1542 if (!isPyramid(array)) {
1543 System.out.println("pyramid2 failed!");
1544 }
1545
1546 java.util.Arrays.fill(array, -1);
1547 pyramid3(array);
1548 if (!isPyramid(array)) {
1549 System.out.println("pyramid3 failed!");
1550 }
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001551
1552 // Make sure this value is kept after deoptimization.
1553 int i = 1;
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001554 if (foo() + i != 100) {
1555 System.out.println("foo failed!");
1556 };
1557
1558 testUnknownBounds();
Mingyao Yang718493c2015-07-22 15:56:34 -07001559 new Main().testExceptionMessage();
Mingyao Yang0304e182015-01-30 16:41:29 -08001560 }
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001561
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001562 public static native boolean compiledWithOptimizing();
1563 public static native void disableStackFrameAsserts();
1564 public static native void assertIsManaged();
1565 public static native void assertIsInterpreted();
1566 public static native boolean hasOatFile();
1567 public static native boolean runtimeIsSoftFail();
1568 public static native boolean isInterpreted();
Mingyao Yang0304e182015-01-30 16:41:29 -08001569}