Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/jit/Arrays/ArrayBounds/ArrayBounds.java
40948 views
1
/*
2
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/*
25
* @test
26
*
27
* @summary converted from VM Testbase jit/Arrays/ArrayBounds.
28
* VM Testbase keywords: [jit, quick]
29
*
30
* @library /vmTestbase
31
* /test/lib
32
* @run main/othervm jit.Arrays.ArrayBounds.ArrayBounds
33
*/
34
35
package jit.Arrays.ArrayBounds;
36
37
/*
38
SCCS ID : @(#)ArrayBounds.java 1.2 02/07/16
39
*/
40
/* The intent of this Java program is to expose Virtual Machines that
41
make illegal array bounds check removal optimizations. */
42
43
/* There are a variety of potential semantic problems with array bounds
44
checking.
45
46
One source of potential bounds-check problems is a compiler that
47
"hoist"s bounds checks outside of loops. This may either either
48
because an array access is loop invariant, or because the compiler
49
is clever enough to determine a loop-invariant "sufficient
50
condition" that guarantees the safety of the safety of one or more
51
accesses within the loop.
52
53
While this is a good approach, it has a variety of possible
54
pitfalls:
55
56
1) If a hoisted test fails, you can't just raise a bounds-check
57
exception when the test fails; the loop may have had global
58
side effects before the exception was supposed to have been
59
raised. [prematureExceptionTest]
60
61
2) A hoisted test may itself generate an exception (such as a
62
null pointer exception). Again, this must not be reflected
63
prematurely if the loop has global side effects that should be
64
observed.
65
66
3) An implementation might fail to be conservative enough about
67
the possible side effects of a method call within the loop.
68
For example, when an array being accessed within a loop is
69
accessed as a static or instance variable, then any call must
70
be assumed to possibly modify the array variable itself (in
71
the absence of pretty clever proof techniques!) So no hoisted
72
predicate mentioning the array length (as most will) can be
73
loop-invariant.
74
75
4) In some implementations, the code generated for a bounds-check
76
implicitly does a null check as well. For example, it may
77
access an array length field in the object header. On systems
78
where the 0-th page is protected, this might ensure an OS
79
signal for a null array pointer. But if a bounds check is
80
elided, the generated code might only access the null pointer
81
at a large offset, beyond the protected page, and fail to
82
produce a null pointer exception.
83
84
5) Multi-dimensional arrays are annoying for bounds-check removal.
85
If a loop over "i" accesses "a[i][j]" (where "j" is invariant in
86
the loop, then "a[i]" is not loop-invariant; it changes every
87
iteration. Even if a two-dimensional array were "rectangular"
88
when a loop begins, nothing guarantees that another thread
89
won't update some "a[k]" during the loop. If the compiler
90
hoisted some bounds check comparing "j" to the presumed length
91
of all the "a[k]", and a shorter array were written to some
92
"a[k]" during the loop, then we might miss a necessary array
93
bounds exception.
94
*/
95
96
import nsk.share.TestFailure;
97
98
99
public class ArrayBounds {
100
private static int global;
101
102
private static int[] aplIota(int n) {
103
int[] a = new int[n];
104
for (int j = 0; j < n; j++) a[j] = j;
105
return a;
106
}
107
108
private static int prematureExceptionWork(int[] a, int n) {
109
global = 0;
110
int sum = 0;
111
try {
112
for (int i = 0; i < n; i++) {
113
global++; sum += a[i];
114
}
115
} catch (ArrayIndexOutOfBoundsException t) {}
116
return sum;
117
}
118
private static void prematureException() {
119
int[] a = aplIota(10);
120
int sum = prematureExceptionWork(a, 11);
121
if (global != 11 || sum != 45) {
122
throw new TestFailure("Premature exception test failed.");
123
}
124
}
125
126
private static class Foo {
127
int[] a;
128
}
129
130
private static int exceptionInHoistedPredWork(Foo f, int n) {
131
global = 0;
132
int sum = 0;
133
try {
134
for (int i = 0; i < n; i++) {
135
global++; sum += f.a[i];
136
}
137
} catch (NullPointerException t) {}
138
return sum;
139
}
140
private static void exceptionInHoistedPred() {
141
int sum = exceptionInHoistedPredWork(null, 10);
142
if (global != 1 || sum != 0) {
143
throw new TestFailure("Premature exception test failed.");
144
}
145
}
146
147
private static void changeLength(Foo f, int n) {
148
int[] a = aplIota(n);
149
f.a = a;
150
}
151
private static int arraySideEffectWork(Foo f, int n) {
152
int sum = 0;
153
try {
154
for (int i = 0; i < n; i++) {
155
sum += f.a[i];
156
if (i == 0) changeLength(f, 5);
157
}
158
} catch (ArrayIndexOutOfBoundsException t) {}
159
return sum;
160
}
161
private static void arraySideEffect() {
162
int[] a = aplIota(10);
163
Foo f = new Foo(); f.a = a;
164
int sum = arraySideEffectWork(f, 10);
165
if (sum != 10) {
166
throw new TestFailure("Array side effect test failed (" + sum + ")");
167
}
168
}
169
170
private static boolean nullArrayWork(int[] a, int n) {
171
int sum = 0;
172
global = 0;
173
boolean x = false;
174
try {
175
for (int i = 0; i < n; i++) {
176
global++; sum += a[i];
177
}
178
} catch (NullPointerException t) {
179
x = true;
180
}
181
return x;
182
}
183
private static void nullArray() {
184
/* 30000 should be larger than most pages sizes! */
185
if (!nullArrayWork(null, 30000) || global != 1) {
186
throw new TestFailure("nullArray test failed.");
187
}
188
}
189
190
private static int[][] aa = new int[10][20];
191
static {
192
for (int i = 0; i < 10; i++) aa[i] = aplIota(20);
193
}
194
private static class ArrayMutator extends Thread {
195
int[][] aa; int newN;
196
ArrayMutator(int[][] aa, int newN) {
197
super();
198
this.aa = aa; this.newN = newN;
199
}
200
public void run() {
201
aa[1] = aplIota(newN);
202
}
203
}
204
205
private static int array2DWork(int[][] aa, int m, int n) {
206
int sum = 0;
207
global = 0;
208
try {
209
for (int i = 0; i < m; i++) {
210
for (int j = 0; j < n; j++) {
211
global++; sum += aa[i][j];
212
if (i == 0 && j == 0) {
213
Thread t = new ArrayMutator(aa, n/2);
214
try {
215
t.start();
216
t.join();
217
} catch (InterruptedException x) {}
218
}
219
}
220
}
221
} catch (ArrayIndexOutOfBoundsException t) {}
222
return sum;
223
}
224
private static void array2D() {
225
int sum = array2DWork(aa, aa.length, aa[0].length);
226
if (sum != 19*20/2 + 9*10/2 || global != 20 + 10 + 1) {
227
throw new TestFailure("array2D test failed (sum = " + sum +
228
"; global = " + global + ")");
229
}
230
}
231
232
public static void main(String[] args) {
233
exceptionInHoistedPred();
234
prematureException();
235
arraySideEffect();
236
nullArray();
237
array2D();
238
}
239
}
240
241