blob: f06c250dc7cb375891ce5a7432859dc4731f619b [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) {
125 array[5] = 1;
126 array[4] = 1;
127 }
128
129
David Brazdila06d66a2015-05-28 11:14:54 +0100130 /// CHECK-START: void Main.constantIndexing2(int[]) BCE (before)
131 /// CHECK: BoundsCheck
132 /// CHECK: ArraySet
133 /// CHECK: BoundsCheck
134 /// CHECK: ArraySet
135 /// CHECK: BoundsCheck
136 /// CHECK: ArraySet
137 /// CHECK: BoundsCheck
138 /// CHECK: ArraySet
Mingyao Yange295e6e2015-03-07 06:37:59 -0800139
David Brazdila06d66a2015-05-28 11:14:54 +0100140 /// CHECK-START: void Main.constantIndexing2(int[]) BCE (after)
141 /// CHECK: LessThanOrEqual
142 /// CHECK: Deoptimize
143 /// CHECK-NOT: BoundsCheck
144 /// CHECK: ArraySet
145 /// CHECK-NOT: BoundsCheck
146 /// CHECK: ArraySet
147 /// CHECK-NOT: BoundsCheck
148 /// CHECK: ArraySet
149 /// CHECK-NOT: BoundsCheck
150 /// CHECK: ArraySet
151 /// CHECK: BoundsCheck
152 /// CHECK: ArraySet
Mingyao Yange295e6e2015-03-07 06:37:59 -0800153
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700154 static void constantIndexing2(int[] array) {
155 array[1] = 1;
156 array[2] = 1;
157 array[3] = 1;
Mingyao Yange295e6e2015-03-07 06:37:59 -0800158 array[4] = 1;
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700159 array[-1] = 1;
Mingyao Yange295e6e2015-03-07 06:37:59 -0800160 }
161
162
David Brazdila06d66a2015-05-28 11:14:54 +0100163 /// CHECK-START: int[] Main.constantIndexing3(int[], int[], boolean) BCE (before)
164 /// CHECK: BoundsCheck
165 /// CHECK: ArrayGet
166 /// CHECK: BoundsCheck
167 /// CHECK: ArraySet
168 /// CHECK: BoundsCheck
169 /// CHECK: ArrayGet
170 /// CHECK: BoundsCheck
171 /// CHECK: ArraySet
172 /// CHECK: BoundsCheck
173 /// CHECK: ArrayGet
174 /// CHECK: BoundsCheck
175 /// CHECK: ArraySet
176 /// CHECK: BoundsCheck
177 /// CHECK: ArrayGet
178 /// CHECK: BoundsCheck
179 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700180
David Brazdila06d66a2015-05-28 11:14:54 +0100181 /// CHECK-START: int[] Main.constantIndexing3(int[], int[], boolean) BCE (after)
182 /// CHECK: LessThanOrEqual
183 /// CHECK: Deoptimize
184 /// CHECK-NOT: BoundsCheck
185 /// CHECK: ArrayGet
186 /// CHECK: LessThanOrEqual
187 /// CHECK: Deoptimize
188 /// CHECK-NOT: BoundsCheck
189 /// CHECK: ArraySet
190 /// CHECK-NOT: BoundsCheck
191 /// CHECK: ArrayGet
192 /// CHECK-NOT: BoundsCheck
193 /// CHECK: ArraySet
194 /// CHECK-NOT: BoundsCheck
195 /// CHECK: ArrayGet
196 /// CHECK-NOT: BoundsCheck
197 /// CHECK: ArraySet
198 /// CHECK-NOT: BoundsCheck
199 /// CHECK: ArrayGet
200 /// CHECK-NOT: BoundsCheck
201 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700202
203 static int[] constantIndexing3(int[] array1, int[] array2, boolean copy) {
204 if (!copy) {
205 return array1;
206 }
207 array2[0] = array1[0];
208 array2[1] = array1[1];
209 array2[2] = array1[2];
210 array2[3] = array1[3];
211 return array2;
212 }
213
214
David Brazdila06d66a2015-05-28 11:14:54 +0100215 /// CHECK-START: void Main.constantIndexing4(int[]) BCE (before)
216 /// CHECK: BoundsCheck
217 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700218
David Brazdila06d66a2015-05-28 11:14:54 +0100219 /// CHECK-START: void Main.constantIndexing4(int[]) BCE (after)
220 /// CHECK-NOT: LessThanOrEqual
221 /// CHECK: BoundsCheck
222 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700223
224 // There is only one array access. It's not beneficial
225 // to create a compare with deoptimization instruction.
226 static void constantIndexing4(int[] array) {
227 array[0] = 1;
228 }
229
230
David Brazdila06d66a2015-05-28 11:14:54 +0100231 /// CHECK-START: void Main.constantIndexing5(int[]) BCE (before)
232 /// CHECK: BoundsCheck
233 /// CHECK: ArraySet
234 /// CHECK: BoundsCheck
235 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700236
David Brazdila06d66a2015-05-28 11:14:54 +0100237 /// CHECK-START: void Main.constantIndexing5(int[]) BCE (after)
238 /// CHECK-NOT: Deoptimize
239 /// CHECK: BoundsCheck
240 /// CHECK: ArraySet
241 /// CHECK: BoundsCheck
242 /// CHECK: ArraySet
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700243
244 static void constantIndexing5(int[] array) {
245 // We don't apply the deoptimization for very large constant index
246 // since it's likely to be an anomaly and will throw AIOOBE.
247 array[Integer.MAX_VALUE - 1000] = 1;
248 array[Integer.MAX_VALUE - 999] = 1;
249 array[Integer.MAX_VALUE - 998] = 1;
250 }
251
Andreas Gampe639bdd12015-06-03 11:22:45 -0700252 /// CHECK-START: void Main.constantIndexing6(int[]) BCE (before)
253 /// CHECK: BoundsCheck
254 /// CHECK: ArraySet
255 /// CHECK: BoundsCheck
256 /// CHECK: ArraySet
257
258 /// CHECK-START: void Main.constantIndexing6(int[]) BCE (after)
259 /// CHECK: Deoptimize
260
261 static void constantIndexing6(int[] array) {
262 array[3] = 1;
263 array[4] = 1;
264 }
265
266 // A helper into which the actual throwing function should be inlined.
267 static void constantIndexingForward6(int[] array) {
268 constantIndexing6(array);
269 }
270
David Brazdila06d66a2015-05-28 11:14:54 +0100271 /// CHECK-START: void Main.loopPattern1(int[]) BCE (before)
272 /// CHECK: BoundsCheck
273 /// CHECK: ArraySet
274 /// CHECK: BoundsCheck
275 /// CHECK: ArraySet
276 /// CHECK: BoundsCheck
277 /// CHECK: ArraySet
278 /// CHECK: BoundsCheck
279 /// CHECK: ArraySet
280 /// CHECK: BoundsCheck
281 /// CHECK: ArraySet
282 /// CHECK: BoundsCheck
283 /// CHECK: ArraySet
284 /// CHECK: BoundsCheck
285 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800286
David Brazdila06d66a2015-05-28 11:14:54 +0100287 /// CHECK-START: void Main.loopPattern1(int[]) BCE (after)
288 /// CHECK-NOT: BoundsCheck
289 /// CHECK: ArraySet
290 /// CHECK-NOT: BoundsCheck
291 /// CHECK: ArraySet
292 /// CHECK-NOT: BoundsCheck
293 /// CHECK: ArraySet
294 /// CHECK: BoundsCheck
295 /// CHECK: ArraySet
296 /// CHECK: BoundsCheck
297 /// CHECK: ArraySet
298 /// CHECK: BoundsCheck
299 /// CHECK: ArraySet
300 /// CHECK-NOT: BoundsCheck
301 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800302
303 static void loopPattern1(int[] array) {
304 for (int i = 0; i < array.length; i++) {
305 array[i] = 1; // Bounds check can be eliminated.
306 }
307
308 for (int i = 1; i < array.length; i++) {
309 array[i] = 1; // Bounds check can be eliminated.
310 }
311
312 for (int i = 1; i < array.length - 1; i++) {
313 array[i] = 1; // Bounds check can be eliminated.
314 }
315
316 for (int i = -1; i < array.length; i++) {
317 array[i] = 1; // Bounds check can't be eliminated.
318 }
319
320 for (int i = 0; i <= array.length; i++) {
321 array[i] = 1; // Bounds check can't be eliminated.
322 }
323
324 for (int i = 0; i < array.length; i += 2) {
325 // We don't have any assumption on max array length yet.
326 // Bounds check can't be eliminated due to overflow concern.
327 array[i] = 1;
328 }
329
330 for (int i = 1; i < array.length; i += 2) {
331 // Bounds check can be eliminated since i is odd so the last
332 // i that's less than array.length is at most (Integer.MAX_VALUE - 2).
333 array[i] = 1;
334 }
335 }
336
337
David Brazdila06d66a2015-05-28 11:14:54 +0100338 /// CHECK-START: void Main.loopPattern2(int[]) BCE (before)
339 /// CHECK: BoundsCheck
340 /// CHECK: ArraySet
341 /// CHECK: BoundsCheck
342 /// CHECK: ArraySet
343 /// CHECK: BoundsCheck
344 /// CHECK: ArraySet
345 /// CHECK: BoundsCheck
346 /// CHECK: ArraySet
347 /// CHECK: BoundsCheck
348 /// CHECK: ArraySet
349 /// CHECK: BoundsCheck
350 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800351
David Brazdila06d66a2015-05-28 11:14:54 +0100352 /// CHECK-START: void Main.loopPattern2(int[]) BCE (after)
353 /// CHECK-NOT: BoundsCheck
354 /// CHECK: ArraySet
355 /// CHECK-NOT: BoundsCheck
356 /// CHECK: ArraySet
357 /// CHECK-NOT: BoundsCheck
358 /// CHECK: ArraySet
359 /// CHECK: BoundsCheck
360 /// CHECK: ArraySet
361 /// CHECK: BoundsCheck
362 /// CHECK: ArraySet
363 /// CHECK-NOT: BoundsCheck
364 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800365
366 static void loopPattern2(int[] array) {
367 for (int i = array.length - 1; i >= 0; i--) {
368 array[i] = 1; // Bounds check can be eliminated.
369 }
370
371 for (int i = array.length; i > 0; i--) {
372 array[i - 1] = 1; // Bounds check can be eliminated.
373 }
374
375 for (int i = array.length - 1; i > 0; i--) {
376 array[i] = 1; // Bounds check can be eliminated.
377 }
378
379 for (int i = array.length; i >= 0; i--) {
380 array[i] = 1; // Bounds check can't be eliminated.
381 }
382
383 for (int i = array.length; i >= 0; i--) {
384 array[i - 1] = 1; // Bounds check can't be eliminated.
385 }
386
387 for (int i = array.length; i > 0; i -= 20) {
388 // For i >= 0, (i - 20 - 1) is guaranteed not to underflow.
389 array[i - 1] = 1; // Bounds check can be eliminated.
390 }
391 }
392
393
David Brazdila06d66a2015-05-28 11:14:54 +0100394 /// CHECK-START: void Main.loopPattern3(int[]) BCE (before)
395 /// CHECK: BoundsCheck
396 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800397
David Brazdila06d66a2015-05-28 11:14:54 +0100398 /// CHECK-START: void Main.loopPattern3(int[]) BCE (after)
399 /// CHECK: BoundsCheck
400 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800401
402 static void loopPattern3(int[] array) {
403 java.util.Random random = new java.util.Random();
404 for (int i = 0; ; i++) {
405 if (random.nextInt() % 1000 == 0 && i < array.length) {
406 // Can't eliminate the bound check since not every i++ is
407 // matched with a array length check, so there is some chance that i
408 // overflows and is negative.
409 array[i] = 1;
410 }
411 }
412 }
413
414
David Brazdila06d66a2015-05-28 11:14:54 +0100415 /// CHECK-START: void Main.constantNewArray() BCE (before)
416 /// CHECK: BoundsCheck
417 /// CHECK: ArraySet
418 /// CHECK: BoundsCheck
419 /// CHECK: ArraySet
420 /// CHECK: BoundsCheck
421 /// CHECK: ArraySet
422 /// CHECK: BoundsCheck
423 /// CHECK: ArraySet
424 /// CHECK: BoundsCheck
425 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800426
David Brazdila06d66a2015-05-28 11:14:54 +0100427 /// CHECK-START: void Main.constantNewArray() BCE (after)
428 /// CHECK-NOT: BoundsCheck
429 /// CHECK: ArraySet
430 /// CHECK: BoundsCheck
431 /// CHECK: ArraySet
432 /// CHECK-NOT: BoundsCheck
433 /// CHECK: ArraySet
434 /// CHECK-NOT: BoundsCheck
435 /// CHECK: ArraySet
436 /// CHECK: BoundsCheck
437 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800438
439 static void constantNewArray() {
440 int[] array = new int[10];
441 for (int i = 0; i < 10; i++) {
442 array[i] = 1; // Bounds check can be eliminated.
443 }
444
445 for (int i = 0; i <= 10; i++) {
446 array[i] = 1; // Bounds check can't be eliminated.
447 }
448
449 array[0] = 1; // Bounds check can be eliminated.
450 array[9] = 1; // Bounds check can be eliminated.
451 array[10] = 1; // Bounds check can't be eliminated.
452 }
453
Mingyao Yang4559f002015-02-27 14:43:53 -0800454
455 static byte readData() {
456 return 1;
457 }
458
David Brazdila06d66a2015-05-28 11:14:54 +0100459 /// CHECK-START: void Main.circularBufferProducer() BCE (before)
460 /// CHECK: BoundsCheck
461 /// CHECK: ArraySet
Mingyao Yang4559f002015-02-27 14:43:53 -0800462
David Brazdila06d66a2015-05-28 11:14:54 +0100463 /// CHECK-START: void Main.circularBufferProducer() BCE (after)
464 /// CHECK-NOT: BoundsCheck
465 /// CHECK: ArraySet
Mingyao Yang4559f002015-02-27 14:43:53 -0800466
467 static void circularBufferProducer() {
468 byte[] array = new byte[4096];
469 int i = 0;
470 while (true) {
471 array[i & (array.length - 1)] = readData();
472 i++;
473 }
474 }
475
476
David Brazdila06d66a2015-05-28 11:14:54 +0100477 /// CHECK-START: void Main.pyramid1(int[]) BCE (before)
478 /// CHECK: BoundsCheck
479 /// CHECK: ArraySet
480 /// CHECK: BoundsCheck
481 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800482
David Brazdila06d66a2015-05-28 11:14:54 +0100483 /// CHECK-START: void Main.pyramid1(int[]) BCE (after)
484 /// CHECK-NOT: BoundsCheck
485 /// CHECK: ArraySet
486 /// CHECK-NOT: BoundsCheck
487 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800488
489 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
490 static void pyramid1(int[] array) {
491 for (int i = 0; i < (array.length + 1) / 2; i++) {
492 array[i] = i;
493 array[array.length - 1 - i] = i;
494 }
495 }
496
497
David Brazdila06d66a2015-05-28 11:14:54 +0100498 /// CHECK-START: void Main.pyramid2(int[]) BCE (before)
499 /// CHECK: BoundsCheck
500 /// CHECK: ArraySet
501 /// CHECK: BoundsCheck
502 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800503
David Brazdila06d66a2015-05-28 11:14:54 +0100504 /// CHECK-START: void Main.pyramid2(int[]) BCE (after)
505 /// CHECK-NOT: BoundsCheck
506 /// CHECK: ArraySet
507 /// CHECK-NOT: BoundsCheck
508 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800509
510 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
511 static void pyramid2(int[] array) {
512 for (int i = 0; i < (array.length + 1) >> 1; i++) {
513 array[i] = i;
514 array[array.length - 1 - i] = i;
515 }
516 }
517
518
David Brazdila06d66a2015-05-28 11:14:54 +0100519 /// CHECK-START: void Main.pyramid3(int[]) BCE (before)
520 /// CHECK: BoundsCheck
521 /// CHECK: ArraySet
522 /// CHECK: BoundsCheck
523 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800524
David Brazdila06d66a2015-05-28 11:14:54 +0100525 /// CHECK-START: void Main.pyramid3(int[]) BCE (after)
526 /// CHECK-NOT: BoundsCheck
527 /// CHECK: ArraySet
528 /// CHECK-NOT: BoundsCheck
529 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800530
531 // Set array to something like {0, 1, 2, 3, 2, 1, 0}.
532 static void pyramid3(int[] array) {
533 for (int i = 0; i < (array.length + 1) >>> 1; i++) {
534 array[i] = i;
535 array[array.length - 1 - i] = i;
536 }
537 }
538
539
David Brazdila06d66a2015-05-28 11:14:54 +0100540 /// CHECK-START: boolean Main.isPyramid(int[]) BCE (before)
541 /// CHECK: BoundsCheck
542 /// CHECK: ArrayGet
543 /// CHECK: BoundsCheck
544 /// CHECK: ArrayGet
Mingyao Yang57e04752015-02-09 18:13:26 -0800545
David Brazdila06d66a2015-05-28 11:14:54 +0100546 /// CHECK-START: boolean Main.isPyramid(int[]) BCE (after)
547 /// CHECK-NOT: BoundsCheck
548 /// CHECK: ArrayGet
549 /// CHECK-NOT: BoundsCheck
550 /// CHECK: ArrayGet
Mingyao Yang57e04752015-02-09 18:13:26 -0800551
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800552 static boolean isPyramid(int[] array) {
553 int i = 0;
554 int j = array.length - 1;
555 while (i <= j) {
556 if (array[i] != i) {
557 return false;
558 }
559 if (array[j] != i) {
560 return false;
561 }
562 i++; j--;
563 }
564 return true;
565 }
566
567
David Brazdila06d66a2015-05-28 11:14:54 +0100568 /// CHECK-START: void Main.bubbleSort(int[]) GVN (before)
569 /// CHECK: BoundsCheck
570 /// CHECK: ArrayGet
571 /// CHECK: BoundsCheck
572 /// CHECK: ArrayGet
573 /// CHECK: BoundsCheck
574 /// CHECK: ArrayGet
575 /// CHECK: BoundsCheck
576 /// CHECK: ArrayGet
577 /// CHECK: BoundsCheck
578 /// CHECK: ArraySet
579 /// CHECK: BoundsCheck
580 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800581
David Brazdila06d66a2015-05-28 11:14:54 +0100582 /// CHECK-START: void Main.bubbleSort(int[]) GVN (after)
583 /// CHECK: BoundsCheck
584 /// CHECK: ArrayGet
585 /// CHECK: BoundsCheck
586 /// CHECK: ArrayGet
587 /// CHECK-NOT: ArrayGet
588 /// CHECK-NOT: ArrayGet
589 /// CHECK-NOT: BoundsCheck
590 /// CHECK: ArraySet
591 /// CHECK-NOT: BoundsCheck
592 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800593
David Brazdila06d66a2015-05-28 11:14:54 +0100594 /// CHECK-START: void Main.bubbleSort(int[]) BCE (after)
595 /// CHECK-NOT: BoundsCheck
596 /// CHECK: ArrayGet
597 /// CHECK-NOT: BoundsCheck
598 /// CHECK: ArrayGet
599 /// CHECK-NOT: ArrayGet
600 /// CHECK-NOT: ArrayGet
601 /// CHECK-NOT: BoundsCheck
602 /// CHECK: ArraySet
603 /// CHECK-NOT: BoundsCheck
604 /// CHECK: ArraySet
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800605
606 static void bubbleSort(int[] array) {
607 for (int i = 0; i < array.length - 1; i++) {
608 for (int j = 0; j < array.length - i - 1; j++) {
609 if (array[j] > array[j + 1]) {
610 int temp = array[j + 1];
611 array[j + 1] = array[j];
612 array[j] = temp;
613 }
614 }
615 }
616 }
617
618
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700619 static int foo() {
620 try {
621 // This will cause AIOOBE.
622 constantIndexing2(new int[3]);
623 } catch (ArrayIndexOutOfBoundsException e) {
Andreas Gampe639bdd12015-06-03 11:22:45 -0700624 try {
625 // This will cause AIOOBE.
626 constantIndexingForward6(new int[3]);
627 } catch (ArrayIndexOutOfBoundsException e2) {
628 return 99;
629 }
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700630 }
631 return 0;
632 }
633
634
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700635 int sum;
636
David Brazdila06d66a2015-05-28 11:14:54 +0100637 /// CHECK-START: void Main.foo1(int[], int, int) BCE (before)
638 /// CHECK: BoundsCheck
639 /// CHECK: ArraySet
640 /// CHECK-NOT: BoundsCheck
641 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700642
David Brazdila06d66a2015-05-28 11:14:54 +0100643 /// CHECK-START: void Main.foo1(int[], int, int) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +0100644 /// CHECK: Phi
645 /// CHECK-NOT: BoundsCheck
646 /// CHECK: ArraySet
647 /// CHECK-NOT: BoundsCheck
648 /// CHECK: ArrayGet
Mingyao Yang3584bce2015-05-19 16:01:59 -0700649 // Added blocks for deoptimization.
650 /// CHECK: If
651 /// CHECK: Goto
652 /// CHECK: Deoptimize
653 /// CHECK: Deoptimize
654 /// CHECK: Deoptimize
655 /// CHECK-NOT: Deoptimize
656 /// CHECK: Goto
657 /// CHECK: Phi
658 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700659
660 void foo1(int[] array, int start, int end) {
661 // Three HDeoptimize will be added. One for
662 // start >= 0, one for end <= array.length,
663 // and one for null check on array (to hoist null
664 // check and array.length out of loop).
665 for (int i = start ; i < end; i++) {
666 array[i] = 1;
667 sum += array[i];
668 }
669 }
670
671
David Brazdila06d66a2015-05-28 11:14:54 +0100672 /// CHECK-START: void Main.foo2(int[], int, int) BCE (before)
673 /// CHECK: BoundsCheck
674 /// CHECK: ArraySet
675 /// CHECK-NOT: BoundsCheck
676 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700677
David Brazdila06d66a2015-05-28 11:14:54 +0100678 /// CHECK-START: void Main.foo2(int[], int, int) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +0100679 /// CHECK: Phi
680 /// CHECK-NOT: BoundsCheck
681 /// CHECK: ArraySet
682 /// CHECK-NOT: BoundsCheck
683 /// CHECK: ArrayGet
Mingyao Yang3584bce2015-05-19 16:01:59 -0700684 // Added blocks for deoptimization.
685 /// CHECK: If
686 /// CHECK: Goto
687 /// CHECK: Deoptimize
688 /// CHECK: Deoptimize
689 /// CHECK: Deoptimize
690 /// CHECK-NOT: Deoptimize
691 /// CHECK: Goto
692 /// CHECK: Phi
693 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700694
695 void foo2(int[] array, int start, int end) {
696 // Three HDeoptimize will be added. One for
697 // start >= 0, one for end <= array.length,
698 // and one for null check on array (to hoist null
699 // check and array.length out of loop).
700 for (int i = start ; i <= end; i++) {
701 array[i] = 1;
702 sum += array[i];
703 }
704 }
705
706
David Brazdila06d66a2015-05-28 11:14:54 +0100707 /// CHECK-START: void Main.foo3(int[], int) BCE (before)
708 /// CHECK: BoundsCheck
709 /// CHECK: ArraySet
710 /// CHECK-NOT: BoundsCheck
711 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700712
David Brazdila06d66a2015-05-28 11:14:54 +0100713 /// CHECK-START: void Main.foo3(int[], int) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +0100714 /// CHECK: Phi
715 /// CHECK-NOT: BoundsCheck
716 /// CHECK: ArraySet
717 /// CHECK-NOT: BoundsCheck
718 /// CHECK: ArrayGet
Mingyao Yang3584bce2015-05-19 16:01:59 -0700719 // Added blocks for deoptimization.
720 /// CHECK: If
721 /// CHECK: Goto
722 /// CHECK: Deoptimize
723 /// CHECK: Deoptimize
724 /// CHECK-NOT: Deoptimize
725 /// CHECK: Goto
726 /// CHECK: Phi
727 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700728
729 void foo3(int[] array, int end) {
730 // Two HDeoptimize will be added. One for end < array.length,
731 // and one for null check on array (to hoist null check
732 // and array.length out of loop).
733 for (int i = 3 ; i <= end; i++) {
734 array[i] = 1;
735 sum += array[i];
736 }
737 }
738
Mingyao Yang3584bce2015-05-19 16:01:59 -0700739
David Brazdila06d66a2015-05-28 11:14:54 +0100740 /// CHECK-START: void Main.foo4(int[], int) BCE (before)
741 /// CHECK: BoundsCheck
742 /// CHECK: ArraySet
743 /// CHECK-NOT: BoundsCheck
744 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700745
David Brazdila06d66a2015-05-28 11:14:54 +0100746 /// CHECK-START: void Main.foo4(int[], int) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +0100747 /// CHECK: Phi
748 /// CHECK-NOT: BoundsCheck
749 /// CHECK: ArraySet
750 /// CHECK-NOT: BoundsCheck
751 /// CHECK: ArrayGet
Mingyao Yang3584bce2015-05-19 16:01:59 -0700752 // Added blocks for deoptimization.
753 /// CHECK: If
754 /// CHECK: Goto
755 /// CHECK: Deoptimize
756 /// CHECK: Deoptimize
757 /// CHECK-NOT: Deoptimize
758 /// CHECK: Goto
759 /// CHECK: Phi
760 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700761
762 void foo4(int[] array, int end) {
763 // Two HDeoptimize will be added. One for end <= array.length,
764 // and one for null check on array (to hoist null check
765 // and array.length out of loop).
766 for (int i = end ; i > 0; i--) {
767 array[i - 1] = 1;
768 sum += array[i - 1];
769 }
770 }
771
772
David Brazdila06d66a2015-05-28 11:14:54 +0100773 /// CHECK-START: void Main.foo5(int[], int) BCE (before)
774 /// CHECK: BoundsCheck
775 /// CHECK: ArraySet
776 /// CHECK: BoundsCheck
777 /// CHECK: ArrayGet
778 /// CHECK: BoundsCheck
779 /// CHECK: ArrayGet
780 /// CHECK: BoundsCheck
781 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700782
David Brazdila06d66a2015-05-28 11:14:54 +0100783 /// CHECK-START: void Main.foo5(int[], int) BCE (after)
784 /// CHECK-NOT: BoundsCheck
785 /// CHECK: ArraySet
David Brazdila06d66a2015-05-28 11:14:54 +0100786 /// CHECK: Phi
787 /// CHECK-NOT: BoundsCheck
788 /// CHECK: ArrayGet
789 /// CHECK-NOT: BoundsCheck
790 /// CHECK: ArrayGet
791 /// CHECK-NOT: BoundsCheck
792 /// CHECK: ArrayGet
Mingyao Yang3584bce2015-05-19 16:01:59 -0700793 // Added blocks for deoptimization.
794 /// CHECK: If
795 /// CHECK: Goto
796 /// CHECK: Deoptimize
797 /// CHECK-NOT: Deoptimize
798 /// CHECK: Goto
799 // array.length is defined before the loop header so no phi is needed.
800 /// CHECK-NOT: Phi
801 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700802
803 void foo5(int[] array, int end) {
804 // Bounds check in this loop can be eliminated without deoptimization.
805 for (int i = array.length - 1 ; i >= 0; i--) {
806 array[i] = 1;
807 }
808 // One HDeoptimize will be added.
809 // It's for (end - 2 <= array.length - 2).
810 for (int i = end - 2 ; i > 0; i--) {
811 sum += array[i - 1];
812 sum += array[i];
813 sum += array[i + 1];
814 }
815 }
816
817
David Brazdila06d66a2015-05-28 11:14:54 +0100818 /// CHECK-START: void Main.foo6(int[], int, int) BCE (before)
819 /// CHECK: BoundsCheck
820 /// CHECK: ArrayGet
821 /// CHECK: BoundsCheck
822 /// CHECK: ArrayGet
823 /// CHECK: BoundsCheck
824 /// CHECK: ArrayGet
825 /// CHECK: BoundsCheck
826 /// CHECK: ArrayGet
827 /// CHECK: BoundsCheck
828 /// CHECK: ArrayGet
829 /// CHECK-NOT: BoundsCheck
830 /// CHECK: ArraySet
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700831
David Brazdila06d66a2015-05-28 11:14:54 +0100832 /// CHECK-START: void Main.foo6(int[], int, int) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +0100833 /// CHECK: Phi
834 /// CHECK-NOT: BoundsCheck
835 /// CHECK: ArrayGet
836 /// CHECK-NOT: BoundsCheck
837 /// CHECK: ArrayGet
838 /// CHECK-NOT: BoundsCheck
839 /// CHECK: ArrayGet
840 /// CHECK-NOT: BoundsCheck
841 /// CHECK: ArrayGet
842 /// CHECK-NOT: BoundsCheck
843 /// CHECK: ArrayGet
844 /// CHECK-NOT: BoundsCheck
845 /// CHECK: ArraySet
Mingyao Yang3584bce2015-05-19 16:01:59 -0700846 // Added blocks for deoptimization.
847 /// CHECK: If
848 /// CHECK: Goto
849 /// CHECK: Deoptimize
850 /// CHECK: Deoptimize
851 /// CHECK: Deoptimize
852 /// CHECK-NOT: Deoptimize
853 /// CHECK: Goto
854 /// CHECK: Phi
855 /// CHECK: Goto
856 /// CHECK-NOT: Deoptimize
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700857
858 void foo6(int[] array, int start, int end) {
859 // Three HDeoptimize will be added. One for
860 // start >= 2, one for end <= array.length - 3,
861 // and one for null check on array (to hoist null
862 // check and array.length out of loop).
863 for (int i = end; i >= start; i--) {
864 array[i] = (array[i-2] + array[i-1] + array[i] + array[i+1] + array[i+2]) / 5;
865 }
866 }
867
868
David Brazdila06d66a2015-05-28 11:14:54 +0100869 /// CHECK-START: void Main.foo7(int[], int, int, boolean) BCE (before)
870 /// CHECK: BoundsCheck
871 /// CHECK: ArrayGet
872 /// CHECK: BoundsCheck
873 /// CHECK: ArrayGet
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700874
David Brazdila06d66a2015-05-28 11:14:54 +0100875 /// CHECK-START: void Main.foo7(int[], int, int, boolean) BCE (after)
David Brazdila06d66a2015-05-28 11:14:54 +0100876 /// CHECK: Phi
877 /// CHECK: BoundsCheck
878 /// CHECK: ArrayGet
879 /// CHECK-NOT: BoundsCheck
880 /// CHECK: ArrayGet
Mingyao Yang3584bce2015-05-19 16:01:59 -0700881 // Added blocks for deoptimization.
882 /// CHECK: If
883 /// CHECK: Goto
884 /// CHECK: Deoptimize
885 /// CHECK: Deoptimize
886 /// CHECK: Deoptimize
887 /// CHECK-NOT: Deoptimize
888 /// CHECK: Goto
889 /// CHECK: Phi
890 /// CHECK: Goto
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700891
892 void foo7(int[] array, int start, int end, boolean lowEnd) {
893 // Three HDeoptimize will be added. One for
894 // start >= 0, one for end <= array.length,
895 // and one for null check on array (to hoist null
896 // check and array.length out of loop).
897 for (int i = start ; i < end; i++) {
898 if (lowEnd) {
899 // This array access isn't certain. So we don't
900 // use +1000 offset in decision making for deoptimization
901 // conditions.
902 sum += array[i + 1000];
903 }
904 sum += array[i];
905 }
906 }
907
908
Mingyao Yang3584bce2015-05-19 16:01:59 -0700909 /// CHECK-START: void Main.foo8(int[][], int, int) BCE (before)
910 /// CHECK: BoundsCheck
911 /// CHECK: ArrayGet
912 /// CHECK: BoundsCheck
913 /// CHECK: ArraySet
914
915 /// CHECK-START: void Main.foo8(int[][], int, int) BCE (after)
916 /// CHECK: Phi
917 /// CHECK-NOT: BoundsCheck
918 /// CHECK: ArrayGet
919 /// CHECK: Phi
920 /// CHECK-NOT: BoundsCheck
921 /// CHECK: ArraySet
922 // Added blocks for deoptimization.
923 /// CHECK: If
924 /// CHECK: Goto
925 /// CHECK: Deoptimize
926 /// CHECK: Deoptimize
927 /// CHECK: Deoptimize
928 /// CHECK: Deoptimize
929 /// CHECK: Deoptimize
930 /// CHECK: Deoptimize
931 /// CHECK-NOT: Deoptimize
932 /// CHECK: Goto
933 /// CHECK: Phi
934 /// CHECK: Goto
935
936 void foo8(int[][] matrix, int start, int end) {
937 // Three HDeoptimize will be added for the outer loop.
938 // start >= 0, end <= matrix.length, and null check on matrix.
939 // Three HDeoptimize will be added for the inner loop
940 // start >= 0 (TODO: this may be optimized away),
941 // end <= row.length, and null check on row.
942 for (int i = start; i < end; i++) {
943 int[] row = matrix[i];
944 for (int j = start; j < end; j++) {
945 row[j] = 1;
946 }
947 }
948 }
949
950
951 /// CHECK-START: void Main.foo9(int[]) BCE (before)
952 /// CHECK: NullCheck
953 /// CHECK: BoundsCheck
954 /// CHECK: ArrayGet
955
956 /// CHECK-START: void Main.foo9(int[]) BCE (after)
957 // The loop is guaranteed to be entered. No need to transform the
958 // loop for loop body entry test.
959 /// CHECK: Deoptimize
960 /// CHECK: Deoptimize
961 /// CHECK-NOT: Deoptimize
962 /// CHECK: Phi
963 /// CHECK-NOT: NullCheck
964 /// CHECK-NOT: BoundsCheck
965 /// CHECK: ArrayGet
966
967 void foo9(int[] array) {
968 // Two HDeoptimize will be added. One for
969 // 10 <= array.length, and one for null check on array.
970 for (int i = 0 ; i < 10; i++) {
971 sum += array[i];
972 }
973 }
974
975
David Brazdila06d66a2015-05-28 11:14:54 +0100976 /// CHECK-START: void Main.partialLooping(int[], int, int) BCE (before)
977 /// CHECK: BoundsCheck
978 /// CHECK: ArraySet
Mingyao Yang9d750ef2015-04-26 18:15:30 -0700979
David Brazdila06d66a2015-05-28 11:14:54 +0100980 /// CHECK-START: void Main.partialLooping(int[], int, int) BCE (after)
981 /// CHECK-NOT: Deoptimize
982 /// CHECK: BoundsCheck
983 /// CHECK: ArraySet
Mingyao Yang9d750ef2015-04-26 18:15:30 -0700984
985 void partialLooping(int[] array, int start, int end) {
986 // This loop doesn't cover the full range of [start, end) so
987 // adding deoptimization is too aggressive, since end can be
988 // greater than array.length but the loop is never going to work on
989 // more than 2 elements.
990 for (int i = start; i < end; i++) {
991 if (i == 2) {
992 return;
993 }
994 array[i] = 1;
995 }
996 }
997
998
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700999 static void testUnknownBounds() {
1000 boolean caught = false;
1001 Main main = new Main();
1002 main.foo1(new int[10], 0, 10);
1003 if (main.sum != 10) {
1004 System.out.println("foo1 failed!");
1005 }
1006
1007 caught = false;
1008 main = new Main();
1009 try {
1010 main.foo1(new int[10], 0, 11);
1011 } catch (ArrayIndexOutOfBoundsException e) {
1012 caught = true;
1013 }
1014 if (!caught || main.sum != 10) {
1015 System.out.println("foo1 exception failed!");
1016 }
1017
1018 main = new Main();
1019 main.foo2(new int[10], 0, 9);
1020 if (main.sum != 10) {
1021 System.out.println("foo2 failed!");
1022 }
1023
1024 caught = false;
1025 main = new Main();
1026 try {
1027 main.foo2(new int[10], 0, 10);
1028 } catch (ArrayIndexOutOfBoundsException e) {
1029 caught = true;
1030 }
1031 if (!caught || main.sum != 10) {
1032 System.out.println("foo2 exception failed!");
1033 }
1034
1035 main = new Main();
1036 main.foo3(new int[10], 9);
1037 if (main.sum != 7) {
1038 System.out.println("foo3 failed!");
1039 }
1040
1041 caught = false;
1042 main = new Main();
1043 try {
1044 main.foo3(new int[10], 10);
1045 } catch (ArrayIndexOutOfBoundsException e) {
1046 caught = true;
1047 }
1048 if (!caught || main.sum != 7) {
1049 System.out.println("foo3 exception failed!");
1050 }
1051
1052 main = new Main();
1053 main.foo4(new int[10], 10);
1054 if (main.sum != 10) {
1055 System.out.println("foo4 failed!");
1056 }
1057
1058 caught = false;
1059 main = new Main();
1060 try {
1061 main.foo4(new int[10], 11);
1062 } catch (ArrayIndexOutOfBoundsException e) {
1063 caught = true;
1064 }
1065 if (!caught || main.sum != 0) {
1066 System.out.println("foo4 exception failed!");
1067 }
1068
1069 main = new Main();
1070 main.foo5(new int[10], 10);
1071 if (main.sum != 24) {
1072 System.out.println("foo5 failed!");
1073 }
1074
1075 caught = false;
1076 main = new Main();
1077 try {
1078 main.foo5(new int[10], 11);
1079 } catch (ArrayIndexOutOfBoundsException e) {
1080 caught = true;
1081 }
1082 if (!caught || main.sum != 2) {
1083 System.out.println("foo5 exception failed!");
1084 }
1085
1086 main = new Main();
1087 main.foo6(new int[10], 2, 7);
1088
Mingyao Yang9d750ef2015-04-26 18:15:30 -07001089 main = new Main();
Mingyao Yang3584bce2015-05-19 16:01:59 -07001090 int[] array9 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
1091 main.foo9(array9);
1092 if (main.sum != 45) {
1093 System.out.println("foo9 failed!");
1094 }
1095
1096 main = new Main();
Mingyao Yang9d750ef2015-04-26 18:15:30 -07001097 int[] array = new int[4];
1098 main.partialLooping(new int[3], 0, 4);
1099 if ((array[0] != 1) && (array[1] != 1) &&
1100 (array[2] != 0) && (array[3] != 0)) {
1101 System.out.println("partialLooping failed!");
1102 }
1103
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001104 caught = false;
1105 main = new Main();
1106 try {
1107 main.foo6(new int[10], 2, 8);
1108 } catch (ArrayIndexOutOfBoundsException e) {
1109 caught = true;
1110 }
1111 if (!caught) {
1112 System.out.println("foo6 exception failed!");
1113 }
1114
1115 caught = false;
1116 main = new Main();
1117 try {
1118 main.foo6(new int[10], 1, 7);
1119 } catch (ArrayIndexOutOfBoundsException e) {
1120 caught = true;
1121 }
1122 if (!caught) {
1123 System.out.println("foo6 exception failed!");
1124 }
1125
1126 }
1127
Mingyao Yang718493c2015-07-22 15:56:34 -07001128 public void testExceptionMessage() {
1129 short[] B1 = new short[5];
1130 int[] B2 = new int[5];
1131 Exception err = null;
1132 try {
1133 testExceptionMessage1(B1, B2, null, -1, 6);
1134 } catch (Exception e) {
1135 err = e;
1136 }
1137 System.out.println(err);
1138 }
1139
1140 void testExceptionMessage1(short[] a1, int[] a2, long a3[], int start, int finish) {
1141 int j = finish + 77;
1142 // Bug: 22665511
1143 // A deoptimization will be triggered here right before the loop. Need to make
1144 // sure the value of j is preserved for the interpreter.
1145 for (int i = start; i <= finish; i++) {
1146 a2[j - 1] = a1[i + 1];
1147 }
1148 }
1149
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001150 // Make sure this method is compiled with optimizing.
David Brazdila06d66a2015-05-28 11:14:54 +01001151 /// CHECK-START: void Main.main(java.lang.String[]) register (after)
1152 /// CHECK: ParallelMove
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001153
Mingyao Yang0304e182015-01-30 16:41:29 -08001154 public static void main(String[] args) {
1155 sieve(20);
Mingyao Yang8c8bad82015-02-09 18:13:26 -08001156
1157 int[] array = {5, 2, 3, 7, 0, 1, 6, 4};
1158 bubbleSort(array);
1159 for (int i = 0; i < 8; i++) {
1160 if (array[i] != i) {
1161 System.out.println("bubble sort failed!");
1162 }
1163 }
1164
1165 array = new int[7];
1166 pyramid1(array);
1167 if (!isPyramid(array)) {
1168 System.out.println("pyramid1 failed!");
1169 }
1170
1171 array = new int[8];
1172 pyramid2(array);
1173 if (!isPyramid(array)) {
1174 System.out.println("pyramid2 failed!");
1175 }
1176
1177 java.util.Arrays.fill(array, -1);
1178 pyramid3(array);
1179 if (!isPyramid(array)) {
1180 System.out.println("pyramid3 failed!");
1181 }
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001182
1183 // Make sure this value is kept after deoptimization.
1184 int i = 1;
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001185 if (foo() + i != 100) {
1186 System.out.println("foo failed!");
1187 };
1188
1189 testUnknownBounds();
Mingyao Yang718493c2015-07-22 15:56:34 -07001190 new Main().testExceptionMessage();
Mingyao Yang0304e182015-01-30 16:41:29 -08001191 }
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001192
Mingyao Yang0304e182015-01-30 16:41:29 -08001193}