Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyAsLoadsStores.java
64474 views
1
/*
2
* Copyright (c) 2015, 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
* @bug 6912521
27
* @summary small array copy as loads/stores
28
* @library /
29
*
30
* @run main/othervm -ea -XX:-BackgroundCompilation -XX:-UseOnStackReplacement
31
* -XX:CompileCommand=dontinline,compiler.arraycopy.TestArrayCopyAsLoadsStores::m*
32
* -XX:TypeProfileLevel=200
33
* compiler.arraycopy.TestArrayCopyAsLoadsStores
34
* @run main/othervm -ea -XX:-BackgroundCompilation -XX:-UseOnStackReplacement
35
* -XX:CompileCommand=dontinline,compiler.arraycopy.TestArrayCopyAsLoadsStores::m*
36
* -XX:TypeProfileLevel=200
37
* -XX:+IgnoreUnrecognizedVMOptions -XX:+StressArrayCopyMacroNode
38
* compiler.arraycopy.TestArrayCopyAsLoadsStores
39
*/
40
41
/*
42
* @test
43
* @bug 8282590
44
* @library /
45
*
46
* @run main/othervm -ea -XX:-BackgroundCompilation -XX:-UseOnStackReplacement
47
* -XX:CompileCommand=dontinline,compiler.arraycopy.TestArrayCopyAsLoadsStores::m*
48
* -XX:TypeProfileLevel=200
49
* -XX:+IgnoreUnrecognizedVMOptions -XX:+StressArrayCopyMacroNode
50
* -XX:-TieredCompilation -XX:+StressReflectiveCode -XX:-ReduceInitialCardMarks
51
* compiler.arraycopy.TestArrayCopyAsLoadsStores
52
*/
53
54
package compiler.arraycopy;
55
56
import java.util.Arrays;
57
58
public class TestArrayCopyAsLoadsStores extends TestArrayCopyUtils {
59
60
// array clone should be compiled as loads/stores
61
@Args(src=ArraySrc.SMALL)
62
static A[] m1() throws CloneNotSupportedException {
63
return (A[])small_a_src.clone();
64
}
65
66
@Args(src=ArraySrc.SMALL)
67
static int[] m2() throws CloneNotSupportedException {
68
return (int[])small_int_src.clone();
69
}
70
71
// new array allocation should be optimized out
72
@Args(src=ArraySrc.SMALL)
73
static int m3() throws CloneNotSupportedException {
74
int[] array_clone = (int[])small_int_src.clone();
75
return array_clone[0] + array_clone[1] + array_clone[2] +
76
array_clone[3] + array_clone[4];
77
}
78
79
// should not be compiled as loads/stores
80
@Args(src=ArraySrc.LARGE)
81
static int[] m4() throws CloneNotSupportedException {
82
return (int[])large_int_src.clone();
83
}
84
85
// check that array of length 0 is handled correctly
86
@Args(src=ArraySrc.ZERO)
87
static int[] m5() throws CloneNotSupportedException {
88
return (int[])zero_int_src.clone();
89
}
90
91
// array copy should be compiled as loads/stores
92
@Args(src=ArraySrc.SMALL, dst=ArrayDst.NEW)
93
static void m6(int[] src, int[] dest) {
94
System.arraycopy(src, 0, dest, 0, 5);
95
}
96
97
// array copy should not be compiled as loads/stores
98
@Args(src=ArraySrc.LARGE, dst=ArrayDst.NEW)
99
static void m7(int[] src, int[] dest) {
100
System.arraycopy(src, 0, dest, 0, 10);
101
}
102
103
// array copy should be compiled as loads/stores
104
@Args(src=ArraySrc.SMALL)
105
static A[] m8(A[] src) {
106
src[0] = src[0]; // force null check
107
A[] dest = new A[5];
108
System.arraycopy(src, 0, dest, 0, 5);
109
return dest;
110
}
111
112
// array copy should not be compiled as loads/stores: we would
113
// need to emit GC barriers
114
@Args(src=ArraySrc.SMALL, dst=ArrayDst.NEW)
115
static void m9(A[] src, A[] dest) {
116
System.arraycopy(src, 0, dest, 0, 5);
117
}
118
119
// overlapping array regions: copy backward
120
@Args(src=ArraySrc.SMALL, dst=ArrayDst.SRC)
121
static void m10(int[] src, int[] dest) {
122
System.arraycopy(src, 0, dest, 1, 4);
123
}
124
125
static boolean m10_check(int[] src, int[] dest) {
126
boolean failure = false;
127
for (int i = 0; i < 5; i++) {
128
int j = Math.max(i - 1, 0);
129
if (dest[i] != src[j]) {
130
System.out.println("Test m10 failed for " + i + " src[" + j +"]=" + src[j] + ", dest[" + i + "]=" + dest[i]);
131
failure = true;
132
}
133
}
134
return failure;
135
}
136
137
// overlapping array regions: copy forward
138
@Args(src=ArraySrc.SMALL, dst=ArrayDst.SRC)
139
static void m11(int[] src, int[] dest) {
140
System.arraycopy(src, 1, dest, 0, 4);
141
}
142
143
static boolean m11_check(int[] src, int[] dest) {
144
boolean failure = false;
145
for (int i = 0; i < 5; i++) {
146
int j = Math.min(i + 1, 4);
147
if (dest[i] != src[j]) {
148
System.out.println("Test m11 failed for " + i + " src[" + j +"]=" + src[j] + ", dest[" + i + "]=" + dest[i]);
149
failure = true;
150
}
151
}
152
return failure;
153
}
154
155
// overlapping array region with unknown src/dest offsets: compiled code must include both forward and backward copies
156
@Args(src=ArraySrc.SMALL, dst=ArrayDst.SRC, extra_args={0,1})
157
static void m12(int[] src, int[] dest, int srcPos, int destPos) {
158
System.arraycopy(src, srcPos, dest, destPos, 4);
159
}
160
161
static boolean m12_check(int[] src, int[] dest) {
162
boolean failure = false;
163
for (int i = 0; i < 5; i++) {
164
int j = Math.max(i - 1, 0);
165
if (dest[i] != src[j]) {
166
System.out.println("Test m10 failed for " + i + " src[" + j +"]=" + src[j] + ", dest[" + i + "]=" + dest[i]);
167
failure = true;
168
}
169
}
170
return failure;
171
}
172
173
// Array allocation and copy should optimize out
174
@Args(src=ArraySrc.SMALL)
175
static int m13(int[] src) {
176
int[] dest = new int[5];
177
System.arraycopy(src, 0, dest, 0, 5);
178
return dest[0] + dest[1] + dest[2] + dest[3] + dest[4];
179
}
180
181
// Check that copy of length 0 is handled correctly
182
@Args(src=ArraySrc.ZERO, dst=ArrayDst.NEW)
183
static void m14(int[] src, int[] dest) {
184
System.arraycopy(src, 0, dest, 0, 0);
185
}
186
187
// copyOf should compile to loads/stores
188
@Args(src=ArraySrc.SMALL)
189
static A[] m15() {
190
return Arrays.copyOf(small_a_src, 5, A[].class);
191
}
192
193
static Object[] helper16(int i) {
194
Object[] arr = null;
195
if ((i%2) == 0) {
196
arr = small_a_src;
197
} else {
198
arr = small_object_src;
199
}
200
return arr;
201
}
202
203
// CopyOf may need subtype check
204
@Args(src=ArraySrc.SMALL, dst=ArrayDst.NONE, extra_args={0})
205
static A[] m16(A[] unused_src, int i) {
206
Object[] arr = helper16(i);
207
return Arrays.copyOf(arr, 5, A[].class);
208
}
209
210
static Object[] helper17_1(int i) {
211
Object[] arr = null;
212
if ((i%2) == 0) {
213
arr = small_a_src;
214
} else {
215
arr = small_object_src;
216
}
217
return arr;
218
}
219
220
static A[] helper17_2(Object[] arr) {
221
return Arrays.copyOf(arr, 5, A[].class);
222
}
223
224
// CopyOf may leverage type speculation
225
@Args(src=ArraySrc.SMALL, dst=ArrayDst.NONE, extra_args={0})
226
static A[] m17(A[] unused_src, int i) {
227
Object[] arr = helper17_1(i);
228
return helper17_2(arr);
229
}
230
231
static Object[] helper18_1(int i) {
232
Object[] arr = null;
233
if ((i%2) == 0) {
234
arr = small_a_src;
235
} else {
236
arr = small_object_src;
237
}
238
return arr;
239
}
240
241
static Object[] helper18_2(Object[] arr) {
242
return Arrays.copyOf(arr, 5, Object[].class);
243
}
244
245
// CopyOf should not attempt to use type speculation if it's not needed
246
@Args(src=ArraySrc.SMALL, dst=ArrayDst.NONE, extra_args={0})
247
static Object[] m18(A[] unused_src, int i) {
248
Object[] arr = helper18_1(i);
249
return helper18_2(arr);
250
}
251
252
static Object[] helper19(int i) {
253
Object[] arr = null;
254
if ((i%2) == 0) {
255
arr = small_a_src;
256
} else {
257
arr = small_object_src;
258
}
259
return arr;
260
}
261
262
// CopyOf may need subtype check. Test is run to make type check
263
// fail and cause deoptimization. Next compilation should not
264
// compile as loads/stores because the first compilation
265
// deoptimized.
266
@Args(src=ArraySrc.SMALL, dst=ArrayDst.NONE, extra_args={0})
267
static A[] m19(A[] unused_src, int i) {
268
Object[] arr = helper19(i);
269
return Arrays.copyOf(arr, 5, A[].class);
270
}
271
272
// copyOf for large array should not compile to loads/stores
273
@Args(src=ArraySrc.LARGE)
274
static A[] m20() {
275
return Arrays.copyOf(large_a_src, 10, A[].class);
276
}
277
278
// check zero length copyOf is handled correctly
279
@Args(src=ArraySrc.ZERO)
280
static A[] m21() {
281
return Arrays.copyOf(zero_a_src, 0, A[].class);
282
}
283
284
// Run with srcPos=0 for a 1st compile, then with incorrect value
285
// of srcPos to cause deoptimization, then with srcPos=0 for a 2nd
286
// compile. The 2nd compile shouldn't turn arraycopy into
287
// loads/stores because input arguments are no longer known to be
288
// valid.
289
@Args(src=ArraySrc.SMALL, dst=ArrayDst.NEW, extra_args={0})
290
static void m22(int[] src, int[] dest, int srcPos) {
291
System.arraycopy(src, srcPos, dest, 0, 5);
292
}
293
294
// copyOfRange should compile to loads/stores
295
@Args(src=ArraySrc.SMALL)
296
static A[] m23() {
297
return Arrays.copyOfRange(small_a_src, 1, 4, A[].class);
298
}
299
300
static boolean m23_check(A[] src, A[] dest) {
301
boolean failure = false;
302
for (int i = 0; i < 3; i++) {
303
if (src[i+1] != dest[i]) {
304
System.out.println("Test m23 failed for " + i + " src[" + (i+1) +"]=" + dest[i] + ", dest[" + i + "]=" + dest[i]);
305
failure = true;
306
}
307
}
308
return failure;
309
}
310
311
// array copy should be compiled as loads/stores. Invoke then with
312
// incompatible array type to verify we don't allow a forbidden
313
// arraycopy to happen.
314
@Args(src=ArraySrc.SMALL)
315
static A[] m24(Object[] src) {
316
src[0] = src[0]; // force null check
317
A[] dest = new A[5];
318
System.arraycopy(src, 0, dest, 0, 5);
319
return dest;
320
}
321
322
// overlapping array region with unknown src/dest offsets but
323
// length 1: compiled code doesn't need both forward and backward
324
// copies
325
@Args(src=ArraySrc.SMALL, dst=ArrayDst.SRC, extra_args={0,1})
326
static void m25(int[] src, int[] dest, int srcPos, int destPos) {
327
System.arraycopy(src, srcPos, dest, destPos, 1);
328
}
329
330
static boolean m25_check(int[] src, int[] dest) {
331
boolean failure = false;
332
if (dest[1] != src[0]) {
333
System.out.println("Test m10 failed for src[0]=" + src[0] + ", dest[1]=" + dest[1]);
334
return true;
335
}
336
return false;
337
}
338
339
public static void main(String[] args) throws Exception {
340
TestArrayCopyAsLoadsStores test = new TestArrayCopyAsLoadsStores();
341
342
test.doTest("m1");
343
test.doTest("m2");
344
test.doTest("m3");
345
test.doTest("m4");
346
test.doTest("m5");
347
test.doTest("m6");
348
test.doTest("m7");
349
test.doTest("m8");
350
test.doTest("m9");
351
test.doTest("m10");
352
test.doTest("m11");
353
test.doTest("m12");
354
test.doTest("m13");
355
test.doTest("m14");
356
test.doTest("m15");
357
358
// make both branches of the If appear taken
359
for (int i = 0; i < 20000; i++) {
360
helper16(i);
361
}
362
363
test.doTest("m16");
364
365
// load class B so type check in m17 would not be simple comparison
366
B b = new B();
367
// make both branches of the If appear taken
368
for (int i = 0; i < 20000; i++) {
369
helper17_1(i);
370
}
371
372
test.doTest("m17");
373
374
// make both branches of the If appear taken
375
for (int i = 0; i < 20000; i++) {
376
helper18_1(i);
377
}
378
test.doTest("m18");
379
380
// make both branches of the If appear taken
381
for (int i = 0; i < 20000; i++) {
382
helper19(i);
383
}
384
385
// Compile
386
for (int i = 0; i < 20000; i++) {
387
m19(null, 0);
388
}
389
390
// force deopt
391
boolean m19_exception = false;
392
for (int i = 0; i < 10; i++) {
393
try {
394
m19(null, 1);
395
} catch(ArrayStoreException ase) {
396
m19_exception = true;
397
}
398
}
399
400
if (!m19_exception) {
401
System.out.println("Test m19: exception wasn't thrown");
402
test.success = false;
403
}
404
405
test.doTest("m19");
406
407
test.doTest("m20");
408
test.doTest("m21");
409
410
// Compile
411
int[] dst = new int[small_int_src.length];
412
for (int i = 0; i < 20000; i++) {
413
m22(small_int_src, dst, 0);
414
}
415
416
// force deopt
417
for (int i = 0; i < 10; i++) {
418
try {
419
m22(small_int_src, dst, 5);
420
} catch(ArrayIndexOutOfBoundsException aioobe) {}
421
}
422
423
test.doTest("m22");
424
test.doTest("m23");
425
426
test.doTest("m24");
427
boolean m24_exception = false;
428
try {
429
m24(small_object_src);
430
} catch(ArrayStoreException ase) {
431
m24_exception = true;
432
}
433
434
if (!m24_exception) {
435
System.out.println("Test m24: exception wasn't thrown");
436
test.success = false;
437
}
438
439
test.doTest("m25");
440
441
if (!test.success) {
442
throw new RuntimeException("some tests failed");
443
}
444
}
445
}
446
447