blob: 32bbc5b61d8d66d79809c446254b7ef9420f446e [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
Aart Bikbf3f1cf2016-02-22 16:22:33 -0800394 /// CHECK-START: void Main.constantIndexing10(int[], int) BCE (before)
395 /// CHECK: BoundsCheck
396 /// CHECK: ArraySet
397 /// CHECK: BoundsCheck
398 /// CHECK: ArraySet
399 /// CHECK: BoundsCheck
400 /// CHECK: ArraySet
401 /// CHECK: BoundsCheck
402 /// CHECK: ArraySet
403
404 /// CHECK-START: void Main.constantIndexing10(int[], int) BCE (after)
405 /// CHECK: Deoptimize
406 /// CHECK: Deoptimize
407 /// CHECK-NOT: BoundsCheck
408 /// CHECK: ArraySet
409 /// CHECK-NOT: BoundsCheck
410 /// CHECK: ArraySet
411 /// CHECK-NOT: BoundsCheck
412 /// CHECK: ArraySet
413 /// CHECK-NOT: BoundsCheck
414 /// CHECK: ArraySet
415
416 static void constantIndexing10(int[] array, int base) {
417 // Offset hidden in incremented base.
418 array[base] = 1;
419 array[++base] = 2;
420 array[++base] = 3;
421 array[++base] = 4;
422 }
423
Aart Bik1d239822016-02-09 14:26:34 -0800424 static void runAllConstantIndices() {
425 int[] a1 = { 0 };
426 int[] a6 = { 0, 0, 0, 0, 0, 0 };
427
428 boolean caught = false;
429 try {
430 constantIndexing1(a1);
431 } catch (ArrayIndexOutOfBoundsException e) {
432 caught = true;
433 }
434 if (!caught) {
435 System.out.println("constant indices 1 failed!");
436 }
437
438 constantIndexing1(a6);
439 if (a6[4] != 11 || a6[5] != 11) {
440 System.out.println("constant indices 1 failed!");
441 }
442
443 caught = false;
444 try {
445 $opt$noinline$constantIndexing2(a6);
446 } catch (ArrayIndexOutOfBoundsException e) {
447 caught = true;
448 }
449 if (!caught || a6[0] != 0 || a6[1] != 1 || a6[2] != 1 ||
450 a6[3] != 1 || a6[4] != 1 || a6[5] != 11) {
451 System.out.println("constant indices 2 failed!");
452 }
453
454 caught = false;
455 try {
456 constantIndexing2b(a1);
457 } catch (ArrayIndexOutOfBoundsException e) {
458 caught = true;
459 }
460 if (!caught || a1[0] != 7) {
461 System.out.println("constant indices 2b failed!");
462 }
463
464 constantIndexing2b(a6);
465 if (a6[0] != 7 || a6[1] != 7 || a6[2] != 7 ||
466 a6[3] != 7 || a6[4] != 1 || a6[5] != 11) {
467 System.out.println("constant indices 2b failed!");
468 }
469
470 int[] b4 = new int[4];
471 constantIndexing3(a6, b4, true);
472 if (b4[0] != 7 || b4[1] != 7 || b4[2] != 7 || b4[3] != 7) {
473 System.out.println("constant indices 3 failed!");
474 }
475
476 constantIndexing4(a1);
477 if (a1[0] != -1) {
478 System.out.println("constant indices 4 failed!");
479 }
480
481 caught = false;
482 try {
483 constantIndexing5(a6);
484 } catch (ArrayIndexOutOfBoundsException e) {
485 caught = true;
486 }
487 if (!caught) {
488 System.out.println("constant indices 5 failed!");
489 }
490
491 constantIndexing6(a6);
492 if (a6[0] != 7 || a6[1] != 7 || a6[2] != 7 ||
493 a6[3] != 111 || a6[4] != 111 || a6[5] != 11) {
494 System.out.println("constant indices 6 failed!");
495 }
496
497 constantIndexing7(a6, 1);
498 if (a6[0] != 7 || a6[1] != 10 || a6[2] != 20 ||
499 a6[3] != 30 || a6[4] != 40 || a6[5] != 11) {
500 System.out.println("constant indices 7 failed!");
501 }
502
503 caught = false;
504 try {
505 constantIndexing7(a6, 5);
506 } catch (ArrayIndexOutOfBoundsException e) {
507 caught = true;
508 }
509 if (!caught || a6[0] != 7 || a6[1] != 10 || a6[2] != 20 ||
510 a6[3] != 30 || a6[4] != 40 || a6[5] != 10) {
511 System.out.println("constant indices 7 failed!");
512 }
513
514 constantIndexing8(a6, 1);
515 if (a6[0] != 100 || a6[1] != 200 || a6[2] != 300 ||
516 a6[3] != 400 || a6[4] != 40 || a6[5] != 10) {
517 System.out.println("constant indices 8 failed!");
518 }
519
520 caught = false;
521 try {
522 constantIndexing8(a6, 0);
523 } catch (ArrayIndexOutOfBoundsException e) {
524 caught = true;
525 }
526 if (!caught || a6[0] != 100) {
527 System.out.println("constant indices 8 failed!");
528 }
529
530 constantIndexing9(a6, 0);
531 if (a6[0] != 0 || a6[1] != 1 || a6[2] != 2 ||
532 a6[3] != 3 || a6[4] != 40 || a6[5] != 10) {
533 System.out.println("constant indices 9 failed!");
534 }
Aart Bikbf3f1cf2016-02-22 16:22:33 -0800535
536 constantIndexing10(a6, 0);
537 if (a6[0] != 1 || a6[1] != 2 || a6[2] != 3 ||
538 a6[3] != 4 || a6[4] != 40 || a6[5] != 10) {
539 System.out.println("constant indices 10 failed!");
540 }
Andreas Gampe639bdd12015-06-03 11:22:45 -0700541 }
542
543 // A helper into which the actual throwing function should be inlined.
544 static void constantIndexingForward6(int[] array) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700545 assertIsManaged();
Andreas Gampe639bdd12015-06-03 11:22:45 -0700546 constantIndexing6(array);
547 }
548
David Brazdila06d66a2015-05-28 11:14:54 +0100549 /// CHECK-START: void Main.loopPattern1(int[]) BCE (before)
550 /// CHECK: BoundsCheck
551 /// CHECK: ArraySet
552 /// CHECK: BoundsCheck
553 /// CHECK: ArraySet
554 /// CHECK: BoundsCheck
555 /// CHECK: ArraySet
556 /// CHECK: BoundsCheck
557 /// CHECK: ArraySet
558 /// CHECK: BoundsCheck
559 /// CHECK: ArraySet
560 /// CHECK: BoundsCheck
561 /// CHECK: ArraySet
562 /// CHECK: BoundsCheck
563 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800564
David Brazdila06d66a2015-05-28 11:14:54 +0100565 /// CHECK-START: void Main.loopPattern1(int[]) BCE (after)
566 /// CHECK-NOT: BoundsCheck
567 /// CHECK: ArraySet
568 /// CHECK-NOT: BoundsCheck
569 /// CHECK: ArraySet
570 /// CHECK-NOT: BoundsCheck
571 /// CHECK: ArraySet
572 /// CHECK: BoundsCheck
573 /// CHECK: ArraySet
574 /// CHECK: BoundsCheck
575 /// CHECK: ArraySet
576 /// CHECK: BoundsCheck
577 /// CHECK: ArraySet
578 /// CHECK-NOT: BoundsCheck
579 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800580
581 static void loopPattern1(int[] array) {
582 for (int i = 0; i < array.length; i++) {
583 array[i] = 1; // Bounds check can be eliminated.
584 }
585
586 for (int i = 1; i < array.length; i++) {
587 array[i] = 1; // Bounds check can be eliminated.
588 }
589
590 for (int i = 1; i < array.length - 1; i++) {
591 array[i] = 1; // Bounds check can be eliminated.
592 }
593
594 for (int i = -1; i < array.length; i++) {
595 array[i] = 1; // Bounds check can't be eliminated.
596 }
597
598 for (int i = 0; i <= array.length; i++) {
599 array[i] = 1; // Bounds check can't be eliminated.
600 }
601
602 for (int i = 0; i < array.length; i += 2) {
603 // We don't have any assumption on max array length yet.
604 // Bounds check can't be eliminated due to overflow concern.
605 array[i] = 1;
606 }
607
608 for (int i = 1; i < array.length; i += 2) {
609 // Bounds check can be eliminated since i is odd so the last
610 // i that's less than array.length is at most (Integer.MAX_VALUE - 2).
611 array[i] = 1;
612 }
613 }
614
615
David Brazdila06d66a2015-05-28 11:14:54 +0100616 /// CHECK-START: void Main.loopPattern2(int[]) BCE (before)
617 /// CHECK: BoundsCheck
618 /// CHECK: ArraySet
619 /// CHECK: BoundsCheck
620 /// CHECK: ArraySet
621 /// CHECK: BoundsCheck
622 /// CHECK: ArraySet
623 /// CHECK: BoundsCheck
624 /// CHECK: ArraySet
625 /// CHECK: BoundsCheck
626 /// CHECK: ArraySet
627 /// CHECK: BoundsCheck
628 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800629
David Brazdila06d66a2015-05-28 11:14:54 +0100630 /// CHECK-START: void Main.loopPattern2(int[]) BCE (after)
631 /// CHECK-NOT: BoundsCheck
632 /// CHECK: ArraySet
633 /// CHECK-NOT: BoundsCheck
634 /// CHECK: ArraySet
635 /// CHECK-NOT: BoundsCheck
636 /// CHECK: ArraySet
637 /// CHECK: BoundsCheck
638 /// CHECK: ArraySet
639 /// CHECK: BoundsCheck
640 /// CHECK: ArraySet
641 /// CHECK-NOT: BoundsCheck
642 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800643
644 static void loopPattern2(int[] array) {
645 for (int i = array.length - 1; i >= 0; i--) {
646 array[i] = 1; // Bounds check can be eliminated.
647 }
648
649 for (int i = array.length; i > 0; i--) {
650 array[i - 1] = 1; // Bounds check can be eliminated.
651 }
652
653 for (int i = array.length - 1; i > 0; i--) {
654 array[i] = 1; // Bounds check can be eliminated.
655 }
656
657 for (int i = array.length; i >= 0; i--) {
658 array[i] = 1; // Bounds check can't be eliminated.
659 }
660
661 for (int i = array.length; i >= 0; i--) {
662 array[i - 1] = 1; // Bounds check can't be eliminated.
663 }
664
665 for (int i = array.length; i > 0; i -= 20) {
666 // For i >= 0, (i - 20 - 1) is guaranteed not to underflow.
667 array[i - 1] = 1; // Bounds check can be eliminated.
668 }
669 }
670
671
David Brazdila06d66a2015-05-28 11:14:54 +0100672 /// CHECK-START: void Main.loopPattern3(int[]) BCE (before)
673 /// CHECK: BoundsCheck
674 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800675
David Brazdila06d66a2015-05-28 11:14:54 +0100676 /// CHECK-START: void Main.loopPattern3(int[]) BCE (after)
677 /// CHECK: BoundsCheck
678 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800679
680 static void loopPattern3(int[] array) {
681 java.util.Random random = new java.util.Random();
682 for (int i = 0; ; i++) {
683 if (random.nextInt() % 1000 == 0 && i < array.length) {
684 // Can't eliminate the bound check since not every i++ is
685 // matched with a array length check, so there is some chance that i
686 // overflows and is negative.
687 array[i] = 1;
688 }
689 }
690 }
691
692
David Brazdila06d66a2015-05-28 11:14:54 +0100693 /// CHECK-START: void Main.constantNewArray() BCE (before)
694 /// CHECK: BoundsCheck
695 /// CHECK: ArraySet
696 /// CHECK: BoundsCheck
697 /// CHECK: ArraySet
698 /// CHECK: BoundsCheck
699 /// CHECK: ArraySet
700 /// CHECK: BoundsCheck
701 /// CHECK: ArraySet
702 /// CHECK: BoundsCheck
703 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800704
David Brazdila06d66a2015-05-28 11:14:54 +0100705 /// CHECK-START: void Main.constantNewArray() BCE (after)
706 /// CHECK-NOT: BoundsCheck
707 /// CHECK: ArraySet
708 /// CHECK: BoundsCheck
709 /// CHECK: ArraySet
710 /// CHECK-NOT: BoundsCheck
711 /// CHECK: ArraySet
712 /// CHECK-NOT: BoundsCheck
713 /// CHECK: ArraySet
714 /// CHECK: BoundsCheck
715 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800716
717 static void constantNewArray() {
718 int[] array = new int[10];
719 for (int i = 0; i < 10; i++) {
720 array[i] = 1; // Bounds check can be eliminated.
721 }
722
723 for (int i = 0; i <= 10; i++) {
724 array[i] = 1; // Bounds check can't be eliminated.
725 }
726
727 array[0] = 1; // Bounds check can be eliminated.
728 array[9] = 1; // Bounds check can be eliminated.
729 array[10] = 1; // Bounds check can't be eliminated.
730 }
731
Mingyao Yang4559f002015-02-27 14:43:53 -0800732
733 static byte readData() {
734 return 1;
735 }
736
David Brazdila06d66a2015-05-28 11:14:54 +0100737 /// CHECK-START: void Main.circularBufferProducer() BCE (before)
738 /// CHECK: BoundsCheck
739 /// CHECK: ArraySet
Mingyao Yang4559f002015-02-27 14:43:53 -0800740
David Brazdila06d66a2015-05-28 11:14:54 +0100741 /// CHECK-START: void Main.circularBufferProducer() BCE (after)
742 /// CHECK-NOT: BoundsCheck
743 /// CHECK: ArraySet
Mingyao Yang4559f002015-02-27 14:43:53 -0800744
745 static void circularBufferProducer() {
746 byte[] array = new byte[4096];
747 int i = 0;
748 while (true) {
749 array[i & (array.length - 1)] = readData();
750 i++;
751 }
752 }
753
754
David Brazdila06d66a2015-05-28 11:14:54 +0100755 /// CHECK-START: void Main.pyramid1(int[]) BCE (before)
756 /// CHECK: BoundsCheck
757 /// CHECK: ArraySet
758 /// CHECK: BoundsCheck
759 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800760
David Brazdila06d66a2015-05-28 11:14:54 +0100761 /// CHECK-START: void Main.pyramid1(int[]) BCE (after)
762 /// CHECK-NOT: BoundsCheck
763 /// CHECK: ArraySet
764 /// CHECK-NOT: BoundsCheck
765 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800766
767 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
768 static void pyramid1(int[] array) {
769 for (int i = 0; i < (array.length + 1) / 2; i++) {
770 array[i] = i;
771 array[array.length - 1 - i] = i;
772 }
773 }
774
775
David Brazdila06d66a2015-05-28 11:14:54 +0100776 /// CHECK-START: void Main.pyramid2(int[]) BCE (before)
777 /// CHECK: BoundsCheck
778 /// CHECK: ArraySet
779 /// CHECK: BoundsCheck
780 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800781
David Brazdila06d66a2015-05-28 11:14:54 +0100782 /// CHECK-START: void Main.pyramid2(int[]) BCE (after)
783 /// CHECK-NOT: BoundsCheck
784 /// CHECK: ArraySet
785 /// CHECK-NOT: BoundsCheck
786 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800787
788 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
789 static void pyramid2(int[] array) {
790 for (int i = 0; i < (array.length + 1) >> 1; i++) {
791 array[i] = i;
792 array[array.length - 1 - i] = i;
793 }
794 }
795
796
David Brazdila06d66a2015-05-28 11:14:54 +0100797 /// CHECK-START: void Main.pyramid3(int[]) BCE (before)
798 /// CHECK: BoundsCheck
799 /// CHECK: ArraySet
800 /// CHECK: BoundsCheck
801 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800802
David Brazdila06d66a2015-05-28 11:14:54 +0100803 /// CHECK-START: void Main.pyramid3(int[]) BCE (after)
804 /// CHECK-NOT: BoundsCheck
805 /// CHECK: ArraySet
806 /// CHECK-NOT: BoundsCheck
807 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800808
809 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
810 static void pyramid3(int[] array) {
811 for (int i = 0; i < (array.length + 1) >>> 1; i++) {
812 array[i] = i;
813 array[array.length - 1 - i] = i;
814 }
815 }
816
817
David Brazdila06d66a2015-05-28 11:14:54 +0100818 /// CHECK-START: boolean Main.isPyramid(int[]) BCE (before)
819 /// CHECK: BoundsCheck
820 /// CHECK: ArrayGet
821 /// CHECK: BoundsCheck
822 /// CHECK: ArrayGet
Mingyao Yang57e04752015-02-09 18:13:26 -0800823
David Brazdila06d66a2015-05-28 11:14:54 +0100824 /// CHECK-START: boolean Main.isPyramid(int[]) BCE (after)
825 /// CHECK-NOT: BoundsCheck
826 /// CHECK: ArrayGet
827 /// CHECK-NOT: BoundsCheck
828 /// CHECK: ArrayGet
Mingyao Yang57e04752015-02-09 18:13:26 -0800829
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800830 static boolean isPyramid(int[] array) {
831 int i = 0;
832 int j = array.length - 1;
833 while (i <= j) {
834 if (array[i] != i) {
835 return false;
836 }
837 if (array[j] != i) {
838 return false;
839 }
840 i++; j--;
841 }
842 return true;
843 }
844
845
David Brazdila06d66a2015-05-28 11:14:54 +0100846 /// CHECK-START: void Main.bubbleSort(int[]) GVN (before)
847 /// CHECK: BoundsCheck
848 /// CHECK: ArrayGet
849 /// CHECK: BoundsCheck
850 /// CHECK: ArrayGet
851 /// CHECK: BoundsCheck
852 /// CHECK: ArrayGet
853 /// CHECK: BoundsCheck
854 /// CHECK: ArrayGet
855 /// CHECK: BoundsCheck
856 /// CHECK: ArraySet
857 /// CHECK: BoundsCheck
858 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800859
David Brazdila06d66a2015-05-28 11:14:54 +0100860 /// CHECK-START: void Main.bubbleSort(int[]) GVN (after)
861 /// CHECK: BoundsCheck
862 /// CHECK: ArrayGet
863 /// CHECK: BoundsCheck
864 /// CHECK: ArrayGet
865 /// CHECK-NOT: ArrayGet
866 /// CHECK-NOT: ArrayGet
867 /// CHECK-NOT: BoundsCheck
868 /// CHECK: ArraySet
869 /// CHECK-NOT: BoundsCheck
870 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800871
David Brazdila06d66a2015-05-28 11:14:54 +0100872 /// CHECK-START: void Main.bubbleSort(int[]) BCE (after)
873 /// CHECK-NOT: BoundsCheck
874 /// CHECK: ArrayGet
875 /// CHECK-NOT: BoundsCheck
876 /// CHECK: ArrayGet
877 /// CHECK-NOT: ArrayGet
878 /// CHECK-NOT: ArrayGet
879 /// CHECK-NOT: BoundsCheck
880 /// CHECK: ArraySet
881 /// CHECK-NOT: BoundsCheck
882 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800883
884 static void bubbleSort(int[] array) {
885 for (int i = 0; i < array.length - 1; i++) {
886 for (int j = 0; j < array.length - i - 1; j++) {
887 if (array[j] > array[j + 1]) {
888 int temp = array[j + 1];
889 array[j + 1] = array[j];
890 array[j] = temp;
891 }
892 }
893 }
894 }
895
Aart Bik5d75afe2015-12-14 11:57:01 -0800896 static int[][] mA;
897
898 /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (before)
Aart Bik09e8d5f2016-01-22 16:49:55 -0800899 // Array references mA[i] and ..[j] both in inner loop.
900 /// CHECK-DAG: <<Get1:l\d+>> ArrayGet [<<Array1:l\d+>>,<<Bounds1:i\d+>>] loop:<<InnerLoop:B\d+>>
901 /// CHECK-DAG: <<Array1>> NullCheck [<<Field1:l\d+>>] loop:<<InnerLoop>>
902 /// CHECK-DAG: <<Len1:i\d+>> ArrayLength [<<Array1>>] loop:<<InnerLoop>>
903 /// CHECK-DAG: <<Bounds1>> BoundsCheck [<<Index1:i\d+>>,<<Len1>>] loop:<<InnerLoop>>
904 /// CHECK-DAG: <<Get2:i\d+>> ArrayGet [<<Array2:l\d+>>,<<Bounds2:i\d+>>] loop:<<InnerLoop>>
905 /// CHECK-DAG: <<Array2>> NullCheck [<<Get1>>] loop:<<InnerLoop>>
906 /// CHECK-DAG: <<Len2:i\d+>> ArrayLength [<<Array2>>] loop:<<InnerLoop>>
907 /// CHECK-DAG: <<Bounds2>> BoundsCheck [<<Index2:i\d+>>,<<Len2>>] loop:<<InnerLoop>>
Vladimir Marko17fb8932016-02-02 14:53:47 +0000908 // Note: The ArtMethod* (typed as int or long) is optional after sharpening.
909 /// CHECK-DAG: InvokeStaticOrDirect [<<Get2>>{{(,[ij]\d+)?}}] loop:<<InnerLoop>>
Aart Bik09e8d5f2016-01-22 16:49:55 -0800910 /// CHECK-DAG: <<Index2>> Phi loop:<<InnerLoop>>
911 /// CHECK-DAG: <<Index1>> Phi loop:<<OuterLoop:B\d+>>
912 /// CHECK-DAG: <<Field1>> StaticFieldGet loop:none
913 /// CHECK-EVAL: "<<InnerLoop>>" != "<<OuterLoop>>"
914 //
915 /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (after)
916 // Array reference mA[i] hoisted to same level as deopt.
917 /// CHECK-DAG: Deoptimize loop:<<OuterLoop:B\d+>>
918 /// CHECK-DAG: ArrayLength loop:<<OuterLoop>>
919 /// CHECK-DAG: <<Get1:l\d+>> ArrayGet [<<Array1:l\d+>>,<<Index1:i\d+>>] loop:<<OuterLoop>>
920 // Array reference ..[j] still in inner loop, with a direct index.
921 /// CHECK-DAG: <<Get2:i\d+>> ArrayGet [<<Array2:l\d+>>,<<Index2:i\d+>>] loop:<<InnerLoop:B\d+>>
Vladimir Marko17fb8932016-02-02 14:53:47 +0000922 // Note: The ArtMethod* (typed as int or long) is optional after sharpening.
923 /// CHECK-DAG: InvokeStaticOrDirect [<<Get2>>{{(,[ij]\d+)?}}] loop:<<InnerLoop>>
Aart Bik09e8d5f2016-01-22 16:49:55 -0800924 /// CHECK-DAG: <<Index2>> Phi loop:<<InnerLoop>>
925 /// CHECK-DAG: <<Index1>> Phi loop:<<OuterLoop>>
926 // Synthetic phi.
927 /// CHECK-DAG: <<Array2>> Phi loop:<<OuterLoop>>
928 /// CHECK-DAG: <<Array1>> StaticFieldGet loop:none
929 /// CHECK-EVAL: "<<InnerLoop>>" != "<<OuterLoop>>"
930 //
Aart Bik5d75afe2015-12-14 11:57:01 -0800931 /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (after)
932 /// CHECK-NOT: NullCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800933 /// CHECK-NOT: BoundsCheck
Aart Bik5d75afe2015-12-14 11:57:01 -0800934 static void dynamicBCEAndIntrinsic(int n) {
935 for (int i = 0; i < n; i++) {
936 for (int j = 0; j < n; j++) {
937 // Since intrinsic call cannot modify fields or arrays,
938 // dynamic BCE and hoisting can be applied to the inner loop.
939 mA[i][j] = Math.abs(mA[i][j]);
940 }
941 }
942 }
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800943
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700944 static int foo() {
945 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700946 assertIsManaged();
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700947 // This will cause AIOOBE.
Nicolas Geoffray5949fa02015-12-18 10:57:10 +0000948 $opt$noinline$constantIndexing2(new int[3]);
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700949 } catch (ArrayIndexOutOfBoundsException e) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700950 assertIsManaged(); // This is to ensure that single-frame deoptimization works.
Nicolas Geoffray5949fa02015-12-18 10:57:10 +0000951 // Will need to be updated if $opt$noinline$constantIndexing2 is inlined.
Andreas Gampe639bdd12015-06-03 11:22:45 -0700952 try {
953 // This will cause AIOOBE.
954 constantIndexingForward6(new int[3]);
955 } catch (ArrayIndexOutOfBoundsException e2) {
David Brazdil95177982015-10-30 12:56:58 -0500956 // Having deopted, we expect to be running interpreted at this point.
957 // Does not apply to debuggable, however, since we do not inline.
Andreas Gampe639bdd12015-06-03 11:22:45 -0700958 return 99;
959 }
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700960 }
961 return 0;
962 }
963
964
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700965 int sum;
966
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700967 /// CHECK-START: void Main.foo1(int[], int, int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +0100968 /// CHECK: BoundsCheck
969 /// CHECK: ArraySet
970 /// CHECK-NOT: BoundsCheck
971 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700972
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700973 /// CHECK-START: void Main.foo1(int[], int, int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +0100974 /// CHECK: Phi
975 /// CHECK-NOT: BoundsCheck
976 /// CHECK: ArraySet
977 /// CHECK-NOT: BoundsCheck
978 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -0800979 // Added blocks at end for deoptimization.
980 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -0700981 /// CHECK: If
Mingyao Yang3584bce2015-05-19 16:01:59 -0700982 /// CHECK: Deoptimize
983 /// CHECK: Deoptimize
984 /// CHECK: Deoptimize
985 /// CHECK-NOT: Deoptimize
986 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -0800987 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -0700988 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700989
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700990 void foo1(int[] array, int start, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -0800991 // Three HDeoptimize will be added. Two for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700992 // and one for null check on array (to hoist null
993 // check and array.length out of loop).
994 for (int i = start ; i < end; i++) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -0700995 if (expectInterpreter) {
996 assertIsInterpreted();
997 } else {
998 assertIsManaged();
999 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001000 array[i] = 1;
1001 sum += array[i];
1002 }
1003 }
1004
1005
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001006 /// CHECK-START: void Main.foo2(int[], int, int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001007 /// CHECK: BoundsCheck
1008 /// CHECK: ArraySet
1009 /// CHECK-NOT: BoundsCheck
1010 /// CHECK: ArrayGet
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001011 /// CHECK-START: void Main.foo2(int[], int, int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001012 /// CHECK: Phi
1013 /// CHECK-NOT: BoundsCheck
1014 /// CHECK: ArraySet
1015 /// CHECK-NOT: BoundsCheck
1016 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001017 // Added blocks at end for deoptimization.
1018 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001019 /// CHECK: If
Mingyao Yang3584bce2015-05-19 16:01:59 -07001020 /// CHECK: Deoptimize
1021 /// CHECK: Deoptimize
1022 /// CHECK: Deoptimize
1023 /// CHECK-NOT: Deoptimize
1024 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001025 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001026 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001027
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001028 void foo2(int[] array, int start, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001029 // Three HDeoptimize will be added. Two for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001030 // and one for null check on array (to hoist null
1031 // check and array.length out of loop).
1032 for (int i = start ; i <= end; i++) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001033 if (expectInterpreter) {
1034 assertIsInterpreted();
1035 } else {
1036 assertIsManaged();
1037 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001038 array[i] = 1;
1039 sum += array[i];
1040 }
1041 }
1042
1043
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001044 /// CHECK-START: void Main.foo3(int[], int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001045 /// CHECK: BoundsCheck
1046 /// CHECK: ArraySet
1047 /// CHECK-NOT: BoundsCheck
1048 /// CHECK: ArrayGet
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001049 /// CHECK-START: void Main.foo3(int[], int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001050 /// CHECK: Phi
1051 /// CHECK-NOT: BoundsCheck
1052 /// CHECK: ArraySet
1053 /// CHECK-NOT: BoundsCheck
1054 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001055 // Added blocks at end for deoptimization.
1056 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001057 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001058 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001059 /// CHECK: Deoptimize
1060 /// CHECK: Deoptimize
1061 /// CHECK-NOT: Deoptimize
1062 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001063 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001064 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001065
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001066 void foo3(int[] array, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001067 // Three HDeoptimize will be added. Two for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001068 // and one for null check on array (to hoist null check
1069 // and array.length out of loop).
1070 for (int i = 3 ; i <= end; i++) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001071 if (expectInterpreter) {
1072 assertIsInterpreted();
1073 } else {
1074 assertIsManaged();
1075 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001076 array[i] = 1;
1077 sum += array[i];
1078 }
1079 }
1080
Mingyao Yang3584bce2015-05-19 16:01:59 -07001081
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001082 /// CHECK-START: void Main.foo4(int[], int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001083 /// CHECK: BoundsCheck
1084 /// CHECK: ArraySet
1085 /// CHECK-NOT: BoundsCheck
1086 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001087
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001088 /// CHECK-START: void Main.foo4(int[], int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001089 /// CHECK: Phi
1090 /// CHECK-NOT: BoundsCheck
1091 /// CHECK: ArraySet
1092 /// CHECK-NOT: BoundsCheck
1093 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001094 // Added blocks at end for deoptimization.
1095 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001096 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001097 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001098 /// CHECK: Deoptimize
1099 /// CHECK: Deoptimize
1100 /// CHECK-NOT: Deoptimize
1101 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001102 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001103 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001104
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001105 void foo4(int[] array, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001106 // Three HDeoptimize will be added. Two for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001107 // and one for null check on array (to hoist null check
1108 // and array.length out of loop).
1109 for (int i = end ; i > 0; i--) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001110 if (expectInterpreter) {
1111 assertIsInterpreted();
1112 } else {
1113 assertIsManaged();
1114 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001115 array[i - 1] = 1;
1116 sum += array[i - 1];
1117 }
1118 }
1119
1120
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001121 /// CHECK-START: void Main.foo5(int[], int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001122 /// CHECK: BoundsCheck
1123 /// CHECK: ArraySet
1124 /// CHECK: BoundsCheck
1125 /// CHECK: ArrayGet
1126 /// CHECK: BoundsCheck
1127 /// CHECK: ArrayGet
1128 /// CHECK: BoundsCheck
1129 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001130
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001131 /// CHECK-START: void Main.foo5(int[], int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001132 /// CHECK-NOT: BoundsCheck
1133 /// CHECK: ArraySet
David Brazdila06d66a2015-05-28 11:14:54 +01001134 /// CHECK: Phi
1135 /// CHECK-NOT: BoundsCheck
1136 /// CHECK: ArrayGet
1137 /// CHECK-NOT: BoundsCheck
1138 /// CHECK: ArrayGet
1139 /// CHECK-NOT: BoundsCheck
1140 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001141 // Added blocks at end for deoptimization.
1142 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001143 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001144 /// CHECK: Deoptimize
1145 /// CHECK: Deoptimize
1146 /// CHECK: Deoptimize
1147 /// CHECK: Deoptimize
1148 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001149 /// CHECK: Deoptimize
1150 /// CHECK-NOT: Deoptimize
1151 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001152 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001153 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001154
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001155 void foo5(int[] array, int end, boolean expectInterpreter) {
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001156 // Bounds check in this loop can be eliminated without deoptimization.
1157 for (int i = array.length - 1 ; i >= 0; i--) {
1158 array[i] = 1;
1159 }
Aart Bik4a342772015-11-30 10:17:46 -08001160 // Several HDeoptimize will be added. Two for each index.
1161 // The null check is not necessary.
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001162 for (int i = end - 2 ; i > 0; i--) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001163 if (expectInterpreter) {
1164 assertIsInterpreted();
1165 } else {
1166 assertIsManaged();
1167 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001168 sum += array[i - 1];
1169 sum += array[i];
1170 sum += array[i + 1];
1171 }
1172 }
1173
1174
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001175 /// CHECK-START: void Main.foo6(int[], int, int, boolean) BCE (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001176 /// CHECK: BoundsCheck
1177 /// CHECK: ArrayGet
1178 /// CHECK: BoundsCheck
1179 /// CHECK: ArrayGet
1180 /// CHECK: BoundsCheck
1181 /// CHECK: ArrayGet
1182 /// CHECK: BoundsCheck
1183 /// CHECK: ArrayGet
1184 /// CHECK: BoundsCheck
1185 /// CHECK: ArrayGet
1186 /// CHECK-NOT: BoundsCheck
1187 /// CHECK: ArraySet
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001188 /// CHECK-START: void Main.foo6(int[], int, int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001189 /// CHECK: Phi
1190 /// CHECK-NOT: BoundsCheck
1191 /// CHECK: ArrayGet
1192 /// CHECK-NOT: BoundsCheck
1193 /// CHECK: ArrayGet
1194 /// CHECK-NOT: BoundsCheck
1195 /// CHECK: ArrayGet
1196 /// CHECK-NOT: BoundsCheck
1197 /// CHECK: ArrayGet
1198 /// CHECK-NOT: BoundsCheck
1199 /// CHECK: ArrayGet
1200 /// CHECK-NOT: BoundsCheck
1201 /// CHECK: ArraySet
Aart Bik4a342772015-11-30 10:17:46 -08001202 // Added blocks at end for deoptimization.
1203 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001204 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001205 /// CHECK: Deoptimize
1206 /// CHECK: Deoptimize
1207 /// CHECK: Deoptimize
1208 /// CHECK: Deoptimize
1209 /// CHECK: Deoptimize
1210 /// CHECK: Deoptimize
1211 /// CHECK: Deoptimize
1212 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001213 /// CHECK: Deoptimize
1214 /// CHECK: Deoptimize
1215 /// CHECK: Deoptimize
1216 /// CHECK-NOT: Deoptimize
1217 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001218 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001219 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001220
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001221 void foo6(int[] array, int start, int end, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001222 // Several HDeoptimize will be added.
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001223 for (int i = end; i >= start; i--) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001224 if (expectInterpreter) {
1225 assertIsInterpreted();
1226 } else {
1227 assertIsManaged();
1228 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001229 array[i] = (array[i-2] + array[i-1] + array[i] + array[i+1] + array[i+2]) / 5;
1230 }
1231 }
1232
1233
David Brazdila06d66a2015-05-28 11:14:54 +01001234 /// CHECK-START: void Main.foo7(int[], int, int, boolean) BCE (before)
1235 /// CHECK: BoundsCheck
1236 /// CHECK: ArrayGet
1237 /// CHECK: BoundsCheck
1238 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001239
David Brazdila06d66a2015-05-28 11:14:54 +01001240 /// CHECK-START: void Main.foo7(int[], int, int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001241 /// CHECK: Phi
1242 /// CHECK: BoundsCheck
1243 /// CHECK: ArrayGet
1244 /// CHECK-NOT: BoundsCheck
1245 /// CHECK: ArrayGet
Aart Bik4a342772015-11-30 10:17:46 -08001246 // Added blocks at end for deoptimization.
1247 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001248 /// CHECK: If
Mingyao Yang3584bce2015-05-19 16:01:59 -07001249 /// CHECK: Deoptimize
1250 /// CHECK: Deoptimize
1251 /// CHECK: Deoptimize
1252 /// CHECK-NOT: Deoptimize
1253 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001254 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001255 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001256
1257 void foo7(int[] array, int start, int end, boolean lowEnd) {
Aart Bik4a342772015-11-30 10:17:46 -08001258 // Three HDeoptimize will be added. One for the index
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001259 // and one for null check on array (to hoist null
1260 // check and array.length out of loop).
1261 for (int i = start ; i < end; i++) {
1262 if (lowEnd) {
1263 // This array access isn't certain. So we don't
1264 // use +1000 offset in decision making for deoptimization
1265 // conditions.
1266 sum += array[i + 1000];
1267 }
1268 sum += array[i];
1269 }
1270 }
1271
1272
Mingyao Yang3584bce2015-05-19 16:01:59 -07001273 /// CHECK-START: void Main.foo8(int[][], int, int) BCE (before)
1274 /// CHECK: BoundsCheck
1275 /// CHECK: ArrayGet
1276 /// CHECK: BoundsCheck
1277 /// CHECK: ArraySet
1278
1279 /// CHECK-START: void Main.foo8(int[][], int, int) BCE (after)
1280 /// CHECK: Phi
1281 /// CHECK-NOT: BoundsCheck
1282 /// CHECK: ArrayGet
1283 /// CHECK: Phi
1284 /// CHECK-NOT: BoundsCheck
1285 /// CHECK: ArraySet
Aart Bik4a342772015-11-30 10:17:46 -08001286 // Added blocks at end for deoptimization.
1287 /// CHECK: Exit
Mingyao Yang3584bce2015-05-19 16:01:59 -07001288 /// CHECK: If
Aart Bik4a342772015-11-30 10:17:46 -08001289 /// CHECK: Deoptimize
1290 /// CHECK: Deoptimize
1291 /// CHECK: Deoptimize
Aart Bikd59c7062015-11-21 05:21:52 +00001292 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001293 /// CHECK: Goto
1294 /// CHECK: Goto
1295 /// CHECK: If
Mingyao Yang3584bce2015-05-19 16:01:59 -07001296 /// CHECK: Deoptimize
1297 /// CHECK: Deoptimize
1298 /// CHECK: Deoptimize
1299 /// CHECK-NOT: Deoptimize
1300 /// CHECK: Goto
Aart Bik4a342772015-11-30 10:17:46 -08001301 /// CHECK: Goto
Mingyao Yang3584bce2015-05-19 16:01:59 -07001302 /// CHECK: Goto
1303
1304 void foo8(int[][] matrix, int start, int end) {
Aart Bik4a342772015-11-30 10:17:46 -08001305 // Three HDeoptimize will be added for the outer loop,
1306 // two for the index, and null check on matrix. Same
1307 // for the inner loop.
Mingyao Yang3584bce2015-05-19 16:01:59 -07001308 for (int i = start; i < end; i++) {
1309 int[] row = matrix[i];
1310 for (int j = start; j < end; j++) {
1311 row[j] = 1;
1312 }
1313 }
1314 }
1315
1316
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001317 /// CHECK-START: void Main.foo9(int[], boolean) BCE (before)
Mingyao Yang3584bce2015-05-19 16:01:59 -07001318 /// CHECK: NullCheck
1319 /// CHECK: BoundsCheck
1320 /// CHECK: ArrayGet
1321
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001322 /// CHECK-START: void Main.foo9(int[], boolean) BCE (after)
Mingyao Yang3584bce2015-05-19 16:01:59 -07001323 // The loop is guaranteed to be entered. No need to transform the
1324 // loop for loop body entry test.
1325 /// CHECK: Deoptimize
1326 /// CHECK: Deoptimize
Aart Bik4a342772015-11-30 10:17:46 -08001327 /// CHECK: Deoptimize
Mingyao Yang3584bce2015-05-19 16:01:59 -07001328 /// CHECK-NOT: Deoptimize
1329 /// CHECK: Phi
1330 /// CHECK-NOT: NullCheck
1331 /// CHECK-NOT: BoundsCheck
1332 /// CHECK: ArrayGet
1333
Aart Bik4a342772015-11-30 10:17:46 -08001334 /// CHECK-START: void Main.foo9(int[], boolean) instruction_simplifier_after_bce (after)
1335 // Simplification removes the redundant check
1336 /// CHECK: Deoptimize
1337 /// CHECK: Deoptimize
1338 /// CHECK-NOT: Deoptimize
1339
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001340 void foo9(int[] array, boolean expectInterpreter) {
Aart Bik4a342772015-11-30 10:17:46 -08001341 // Two HDeoptimize will be added. Two for the index
1342 // and one for null check on array.
Mingyao Yang3584bce2015-05-19 16:01:59 -07001343 for (int i = 0 ; i < 10; i++) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001344 if (expectInterpreter) {
1345 assertIsInterpreted();
1346 } else {
1347 assertIsManaged();
1348 }
Mingyao Yang3584bce2015-05-19 16:01:59 -07001349 sum += array[i];
1350 }
1351 }
1352
1353
David Brazdila06d66a2015-05-28 11:14:54 +01001354 /// CHECK-START: void Main.partialLooping(int[], int, int) BCE (before)
1355 /// CHECK: BoundsCheck
1356 /// CHECK: ArraySet
Mingyao Yang9d750ef2015-04-26 18:15:30 -07001357
David Brazdila06d66a2015-05-28 11:14:54 +01001358 /// CHECK-START: void Main.partialLooping(int[], int, int) BCE (after)
1359 /// CHECK-NOT: Deoptimize
1360 /// CHECK: BoundsCheck
1361 /// CHECK: ArraySet
Mingyao Yang9d750ef2015-04-26 18:15:30 -07001362
1363 void partialLooping(int[] array, int start, int end) {
1364 // This loop doesn't cover the full range of [start, end) so
1365 // adding deoptimization is too aggressive, since end can be
1366 // greater than array.length but the loop is never going to work on
1367 // more than 2 elements.
1368 for (int i = start; i < end; i++) {
1369 if (i == 2) {
1370 return;
1371 }
1372 array[i] = 1;
1373 }
1374 }
1375
1376
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001377 static void testUnknownBounds() {
1378 boolean caught = false;
Aart Bik1d239822016-02-09 14:26:34 -08001379
1380 runAllConstantIndices();
1381
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001382 Main main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001383 main.foo1(new int[10], 0, 10, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001384 if (main.sum != 10) {
1385 System.out.println("foo1 failed!");
1386 }
1387
1388 caught = false;
1389 main = new Main();
1390 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001391 main.foo1(new int[10], 0, 11, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001392 } catch (ArrayIndexOutOfBoundsException e) {
1393 caught = true;
1394 }
1395 if (!caught || main.sum != 10) {
1396 System.out.println("foo1 exception failed!");
1397 }
1398
1399 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001400 main.foo2(new int[10], 0, 9, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001401 if (main.sum != 10) {
1402 System.out.println("foo2 failed!");
1403 }
1404
1405 caught = false;
1406 main = new Main();
1407 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001408 main.foo2(new int[10], 0, 10, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001409 } catch (ArrayIndexOutOfBoundsException e) {
1410 caught = true;
1411 }
1412 if (!caught || main.sum != 10) {
1413 System.out.println("foo2 exception failed!");
1414 }
1415
1416 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001417 main.foo3(new int[10], 9, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001418 if (main.sum != 7) {
1419 System.out.println("foo3 failed!");
1420 }
1421
1422 caught = false;
1423 main = new Main();
1424 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001425 main.foo3(new int[10], 10, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001426 } catch (ArrayIndexOutOfBoundsException e) {
1427 caught = true;
1428 }
1429 if (!caught || main.sum != 7) {
1430 System.out.println("foo3 exception failed!");
1431 }
1432
1433 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001434 main.foo4(new int[10], 10, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001435 if (main.sum != 10) {
1436 System.out.println("foo4 failed!");
1437 }
1438
1439 caught = false;
1440 main = new Main();
1441 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001442 main.foo4(new int[10], 11, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001443 } catch (ArrayIndexOutOfBoundsException e) {
1444 caught = true;
1445 }
1446 if (!caught || main.sum != 0) {
1447 System.out.println("foo4 exception failed!");
1448 }
1449
1450 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001451 main.foo5(new int[10], 10, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001452 if (main.sum != 24) {
1453 System.out.println("foo5 failed!");
1454 }
1455
1456 caught = false;
1457 main = new Main();
1458 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001459 main.foo5(new int[10], 11, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001460 } catch (ArrayIndexOutOfBoundsException e) {
1461 caught = true;
1462 }
1463 if (!caught || main.sum != 2) {
1464 System.out.println("foo5 exception failed!");
1465 }
1466
1467 main = new Main();
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001468 main.foo6(new int[10], 2, 7, false);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001469
Mingyao Yang9d750ef2015-04-26 18:15:30 -07001470 main = new Main();
Mingyao Yang3584bce2015-05-19 16:01:59 -07001471 int[] array9 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001472 main.foo9(array9, false);
Mingyao Yang3584bce2015-05-19 16:01:59 -07001473 if (main.sum != 45) {
1474 System.out.println("foo9 failed!");
1475 }
1476
1477 main = new Main();
Mingyao Yang9d750ef2015-04-26 18:15:30 -07001478 int[] array = new int[4];
1479 main.partialLooping(new int[3], 0, 4);
1480 if ((array[0] != 1) && (array[1] != 1) &&
1481 (array[2] != 0) && (array[3] != 0)) {
1482 System.out.println("partialLooping failed!");
1483 }
1484
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001485 caught = false;
1486 main = new Main();
1487 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001488 main.foo6(new int[10], 2, 8, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001489 } catch (ArrayIndexOutOfBoundsException e) {
1490 caught = true;
1491 }
1492 if (!caught) {
1493 System.out.println("foo6 exception failed!");
1494 }
1495
1496 caught = false;
1497 main = new Main();
1498 try {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001499 main.foo6(new int[10], 1, 7, true);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001500 } catch (ArrayIndexOutOfBoundsException e) {
1501 caught = true;
1502 }
1503 if (!caught) {
1504 System.out.println("foo6 exception failed!");
1505 }
1506
1507 }
1508
Mingyao Yang718493c2015-07-22 15:56:34 -07001509 public void testExceptionMessage() {
1510 short[] B1 = new short[5];
1511 int[] B2 = new int[5];
1512 Exception err = null;
1513 try {
1514 testExceptionMessage1(B1, B2, null, -1, 6);
1515 } catch (Exception e) {
1516 err = e;
1517 }
1518 System.out.println(err);
1519 }
1520
1521 void testExceptionMessage1(short[] a1, int[] a2, long a3[], int start, int finish) {
1522 int j = finish + 77;
1523 // Bug: 22665511
1524 // A deoptimization will be triggered here right before the loop. Need to make
1525 // sure the value of j is preserved for the interpreter.
1526 for (int i = start; i <= finish; i++) {
1527 a2[j - 1] = a1[i + 1];
1528 }
1529 }
1530
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001531 // Make sure this method is compiled with optimizing.
David Brazdila06d66a2015-05-28 11:14:54 +01001532 /// CHECK-START: void Main.main(java.lang.String[]) register (after)
1533 /// CHECK: ParallelMove
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001534
Mingyao Yang0304e182015-01-30 16:41:29 -08001535 public static void main(String[] args) {
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001536 System.loadLibrary(args[0]);
1537
1538 if (!compiledWithOptimizing() ||
1539 !hasOatFile() ||
1540 runtimeIsSoftFail() ||
1541 isInterpreted()) {
1542 disableStackFrameAsserts();
1543 }
1544
Mingyao Yang0304e182015-01-30 16:41:29 -08001545 sieve(20);
Mingyao Yang8c8bad82015-02-09 18:13:26 -08001546
1547 int[] array = {5, 2, 3, 7, 0, 1, 6, 4};
1548 bubbleSort(array);
1549 for (int i = 0; i < 8; i++) {
1550 if (array[i] != i) {
1551 System.out.println("bubble sort failed!");
1552 }
1553 }
1554
Aart Bik5d75afe2015-12-14 11:57:01 -08001555 mA = new int[4][4];
1556 for (int i = 0; i < 4; i++) {
1557 for (int j = 0; j < 4; j++) {
1558 mA[i][j] = -1;
1559 }
1560 }
1561 dynamicBCEAndIntrinsic(4);
1562 for (int i = 0; i < 4; i++) {
1563 for (int j = 0; j < 4; j++) {
1564 if (mA[i][i] != 1) {
1565 System.out.println("dynamic bce failed!");
1566 }
1567 }
1568 }
1569
Mingyao Yang8c8bad82015-02-09 18:13:26 -08001570 array = new int[7];
1571 pyramid1(array);
1572 if (!isPyramid(array)) {
1573 System.out.println("pyramid1 failed!");
1574 }
1575
1576 array = new int[8];
1577 pyramid2(array);
1578 if (!isPyramid(array)) {
1579 System.out.println("pyramid2 failed!");
1580 }
1581
1582 java.util.Arrays.fill(array, -1);
1583 pyramid3(array);
1584 if (!isPyramid(array)) {
1585 System.out.println("pyramid3 failed!");
1586 }
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001587
1588 // Make sure this value is kept after deoptimization.
1589 int i = 1;
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001590 if (foo() + i != 100) {
1591 System.out.println("foo failed!");
1592 };
1593
1594 testUnknownBounds();
Mingyao Yang718493c2015-07-22 15:56:34 -07001595 new Main().testExceptionMessage();
Mingyao Yang0304e182015-01-30 16:41:29 -08001596 }
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001597
Andreas Gampe0dfc9bc2015-09-30 17:13:59 -07001598 public static native boolean compiledWithOptimizing();
1599 public static native void disableStackFrameAsserts();
1600 public static native void assertIsManaged();
1601 public static native void assertIsInterpreted();
1602 public static native boolean hasOatFile();
1603 public static native boolean runtimeIsSoftFail();
1604 public static native boolean isInterpreted();
Mingyao Yang0304e182015-01-30 16:41:29 -08001605}