Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIntrinsics.java
41153 views
1
/*
2
* Copyright (c) 2015, 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
* @bug 8054307
27
* @summary Tests correctness of string related intrinsics and C2 optimizations.
28
* @library /test/lib
29
*
30
* @run main/timeout=240 compiler.intrinsics.string.TestStringIntrinsics
31
*/
32
33
package compiler.intrinsics.string;
34
35
import jdk.test.lib.format.Format;
36
import jdk.test.lib.format.ArrayCodec;
37
38
import java.lang.annotation.ElementType;
39
import java.lang.annotation.Retention;
40
import java.lang.annotation.RetentionPolicy;
41
import java.lang.annotation.Target;
42
import java.lang.reflect.Method;
43
import java.util.Arrays;
44
45
public class TestStringIntrinsics {
46
47
public enum Operation {
48
ARR_EQUALS_B, ARR_EQUALS_C, EQUALS, COMPARE_TO, INDEX_OF, INDEX_OF_CON_U, INDEX_OF_CON_L,
49
INDEX_OF_CON_UL, CONCAT, CONCAT_C, CONCAT_I, CONCAT_M, INDEX_OF_CHAR
50
}
51
52
@Retention(RetentionPolicy.RUNTIME)
53
@Target(ElementType.METHOD)
54
@interface Test {
55
Operation op();
56
String constString() default "";
57
String[] inStrings() default {};
58
char[] inChars() default {};
59
int[] inInts() default {};
60
String[] outStrings() default {};
61
}
62
63
public static void main(String[] args) throws Exception {
64
new TestStringIntrinsics().run();
65
}
66
67
public void run() throws Exception {
68
// Build latin1 and UTF16 strings
69
StringBuilder latin1Builder = new StringBuilder();
70
for (int i = 0; i <= 255; ++i) {
71
latin1Builder.append((char) i);
72
}
73
String latin1 = latin1Builder.toString();
74
StringBuilder utf16Builder = new StringBuilder();
75
for (int i = 0; i <= 10000; ++i) {
76
utf16Builder.append((char) i);
77
}
78
String utf16 = utf16Builder.toString();
79
80
// Invoke test methods
81
for (Method m : TestStringIntrinsics.class.getMethods()) {
82
if (m.isAnnotationPresent(Test.class)) {
83
System.out.print("Checking " + m.getName() + "... ");
84
Test antn = m.getAnnotation(Test.class);
85
Operation op = antn.op();
86
if (isStringConcatTest(op)) {
87
checkStringConcat(op, m, antn);
88
} else {
89
checkIntrinsics(op, m, latin1, utf16, antn);
90
}
91
System.out.println("Done.");
92
}
93
}
94
}
95
96
private boolean isStringConcatTest(Operation op) {
97
return op == Operation.CONCAT ||
98
op == Operation.CONCAT_C ||
99
op == Operation.CONCAT_I ||
100
op == Operation.CONCAT_M;
101
}
102
103
/**
104
* Checks correctness of the String.equals, String.compareTo and String.indexOf intrinsics.
105
* -XX:SpecialStringEquals
106
* -XX:SpecialStringCompareTo
107
* -XX:SpecialStringIndexOf
108
*/
109
private void checkIntrinsics(Operation op, Method m, String latin1, String utf16, Test antn) throws Exception {
110
for (int i = 0; i < 50_000; ++i) {
111
// Copy and permute latin1 and UTF16 string
112
char[] arrL = latin1.toCharArray();
113
int indexL = i % arrL.length;
114
int mod = (arrL.length - arrL[indexL]);
115
int incL = i % ((mod != 0) ? mod : 1);
116
arrL[indexL] = (char) ((int) arrL[indexL] + incL);
117
String latin1Copy = String.valueOf(arrL);
118
119
char[] arrU = utf16.toCharArray();
120
int indexU = i % arrU.length;
121
mod = (arrU.length - arrU[indexU]);
122
int incU = i % ((mod != 0) ? mod : 1);
123
arrU[indexU] = (char) ((int) arrU[indexU] + incU);
124
String utf16Copy = String.valueOf(arrU);
125
126
switch (op) {
127
case ARR_EQUALS_B:
128
invokeAndCompareArrays(m, (incL == 0), latin1.getBytes("ISO-8859-1"), latin1Copy.getBytes("ISO-8859-1"));
129
invokeAndCompareArrays(m, true, new byte[] {1, 2, 3}, new byte[] {1, 2, 3});
130
invokeAndCompareArrays(m, true, new byte[] {1}, new byte[] {1});
131
invokeAndCompareArrays(m, true, new byte[] {}, new byte[] {});
132
break;
133
case ARR_EQUALS_C:
134
invokeAndCompareArrays(m, (incU == 0), utf16.toCharArray(), arrU);
135
break;
136
case EQUALS:
137
invokeAndCheck(m, (incL == 0), latin1, latin1Copy);
138
invokeAndCheck(m, false, latin1, "");
139
invokeAndCheck(m, false, "", latin1);
140
141
invokeAndCheck(m, (incU == 0), utf16, utf16Copy);
142
invokeAndCheck(m, false, utf16, "");
143
invokeAndCheck(m, false, "", utf16);
144
145
invokeAndCheck(m, false, latin1, utf16);
146
break;
147
case COMPARE_TO:
148
invokeAndCheck(m, -incL, latin1, latin1Copy);
149
invokeAndCheck(m, latin1.length(), latin1, "");
150
151
invokeAndCheck(m, -incU, utf16, utf16Copy);
152
invokeAndCheck(m, utf16.length(), utf16, "");
153
154
// Cross coder
155
char cL = latin1.charAt(indexL);
156
char cU = utf16.charAt(indexU);
157
invokeAndCheck(m, cL - cU, latin1, latin1.replace(cL, cU));
158
invokeAndCheck(m, cU - cL, utf16, utf16.replace(cU, cL));
159
160
// Different lengths
161
invokeAndCheck(m, 1, "ABCD", "ABC");
162
invokeAndCheck(m, -1, "\uff21\uff22\uff23", "\uff21\uff22\uff23\uff24");
163
invokeAndCheck(m, 1, "ABC\uff24", "ABC");
164
invokeAndCheck(m, 3, "ABC\uff24\uff25\uff26", "ABC");
165
invokeAndCheck(m, -1, "ABC","ABC\uff24");
166
invokeAndCheck(m, -3, "ABC","ABC\uff24\uff25\uff26");
167
break;
168
case INDEX_OF:
169
invokeAndCheck(m, indexL, latin1, latin1.substring(indexL), (indexL > 42) ? 42 : 0);
170
invokeAndCheck(m, 0, latin1, "", 0);
171
172
invokeAndCheck(m, indexU, utf16, utf16.substring(indexU), (indexU > 42) ? 42 : 0);
173
invokeAndCheck(m, 0, utf16, "", 0);
174
175
// Cross coder
176
invokeAndCheck(m, -1, latin1.substring(0, indexL), utf16.substring(indexU), (indexL > 42) ? 42 : 0);
177
// Skip latin1 chars in utf16 string
178
int start = 256;
179
int end = indexU > start ? indexU : start;
180
invokeAndCheck(m, end-start, utf16.substring(start, end) + latin1.substring(indexL), latin1.substring(indexL), 0);
181
break;
182
case INDEX_OF_CON_L:
183
invokeAndCheck(m, antn.constString(), latin1);
184
break;
185
case INDEX_OF_CON_U:
186
invokeAndCheck(m, antn.constString(), utf16);
187
break;
188
case INDEX_OF_CON_UL:
189
invokeAndCheck(m, antn.constString(), utf16);
190
break;
191
case INDEX_OF_CHAR:
192
invokeAndCheck(m, 7, "abcdefg\uD800\uDC00", 65536, 0);
193
invokeAndCheck(m, -1, "abcdefg\uD800\uDC01", 65536, 0);
194
invokeAndCheck(m, -1, "abcdefg\uD800", 65536, 0);
195
invokeAndCheck(m, 3, "abc\u0107", 263, 0);
196
invokeAndCheck(m, -1, "abc\u0108", 263, 0);
197
invokeAndCheck(m, 7, "abcdefg\u0107", 263, 0);
198
invokeAndCheck(m, 7, "abcdefg\u0107", 263, -1);
199
invokeAndCheck(m, 0, "\u0107", 263, 0);
200
break;
201
default:
202
throw new RuntimeException("Unexpected operation.");
203
}
204
}
205
}
206
207
/**
208
* Checks correctness of the C2 string concatenation optimization.
209
* -XX:OptimizeStringConcat
210
*/
211
private void checkStringConcat(Operation op, Method m, Test antn) throws Exception {
212
for (int i = 0; i < 50_000; ++i) {
213
String[] result = antn.outStrings();
214
switch(op) {
215
case CONCAT:
216
String[] strs = antn.inStrings();
217
for (int j = 0; j < strs.length; ++j) {
218
invokeAndCheck(m, result[j], strs[j]);
219
}
220
break;
221
case CONCAT_C:
222
char[] ch = antn.inChars();
223
for (int j = 0; j < ch.length; ++j) {
224
invokeAndCheck(m, result[j], ch[j]);
225
}
226
break;
227
case CONCAT_I:
228
int[] k = antn.inInts();
229
for (int j = 0; j < k.length; ++j) {
230
invokeAndCheck(m, result[j], k[j]);
231
}
232
break;
233
case CONCAT_M:
234
strs = antn.inStrings();
235
ch = antn.inChars();
236
k = antn.inInts();
237
for (int j = 0; j < strs.length; ++j) {
238
invokeAndCheck(m, result[j], strs[j], ch[j], k[j]);
239
}
240
break;
241
default:
242
throw new RuntimeException("Unexpected operation.");
243
}
244
}
245
}
246
247
/**
248
* Invokes method 'm' by passing arguments the two 'args' (which are supposed to be arrays)
249
* checks if the returned value. In case of error and arrays being not equal, prints their difference.
250
*/
251
private void invokeAndCompareArrays(Method m, boolean expectedResult, Object arg0, Object arg1) throws Exception {
252
boolean result = (Boolean)m.invoke(null, arg0, arg1);
253
if (expectedResult == result)
254
return;
255
256
String cause = String.format("Result: (%b) of '%s' is not equal to expected (%b)",
257
result, m.getName(), expectedResult);
258
259
if (expectedResult == true) {
260
System.err.println(cause);
261
System.err.println(Format.arrayDiff(arg0, arg1));
262
} else {
263
System.err.println(cause);
264
System.err.printf("First array argument: %n %s%n", ArrayCodec.format(arg0));
265
}
266
267
throw new RuntimeException(cause);
268
}
269
270
/**
271
* Invokes method 'm' by passing arguments 'args' and checks if the
272
* returned value equals 'expectedResult'.
273
*/
274
private void invokeAndCheck(Method m, Object expectedResult, Object... args) throws Exception {
275
Object actualResult = m.invoke(null, args);
276
if (!actualResult.equals(expectedResult)) {
277
var nl = System.lineSeparator();
278
StringBuilder msgBuilder = new StringBuilder();
279
msgBuilder.append("Actual result of '" + m.getName() + "' is not equal to expected value." + nl);
280
msgBuilder.append("Expected: " + Format.asLiteral(expectedResult) + nl);
281
msgBuilder.append("Actual: " + Format.asLiteral(actualResult));
282
283
for (int i = 0; i < args.length; i++) {
284
msgBuilder.append(nl + " Arg" + i + ": " + Format.asLiteral(args[i]));
285
}
286
287
final String message = msgBuilder.toString();
288
System.err.println(message);
289
throw new RuntimeException(message);
290
}
291
}
292
293
/*
294
* Constants
295
*/
296
static final char charU = '\uff21';
297
static final char charL = 'A';
298
static final String emptyString = "";
299
static final String stringL = "abcdefghijklmnop";
300
static final String stringSmallL = "abc";
301
static final String stringU = "\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28";
302
static final String stringSmallU = "\u0f21\u0f22\u0f23";
303
static final int constInt = 123;
304
static final int constIntNeg = -123;
305
306
/*
307
* Arrays.equals
308
*/
309
@Test(op = Operation.ARR_EQUALS_B)
310
public static boolean arrayEqualsB(byte[] a, byte[] b) {
311
return Arrays.equals(a, b);
312
}
313
314
@Test(op = Operation.ARR_EQUALS_C)
315
public static boolean arrayEqualsC(char[] a, char[] b) {
316
return Arrays.equals(a, b);
317
}
318
319
/*
320
* String.equals
321
*/
322
@Test(op = Operation.EQUALS)
323
public static boolean equals(String a, String b) {
324
return a.equals(b);
325
}
326
327
/*
328
* String.compareTo
329
*/
330
@Test(op = Operation.COMPARE_TO)
331
public static int compareTo(String a, String b) {
332
return a.compareTo(b);
333
}
334
335
/*
336
* String.indexOf
337
*/
338
@Test(op = Operation.INDEX_OF)
339
public static int indexOf(String a, String b, int from) {
340
return a.indexOf(b, from);
341
}
342
343
@Test(op = Operation.INDEX_OF_CON_U, constString = stringSmallU)
344
public static String indexOfConstU(String a) {
345
int result = a.indexOf(stringSmallU);
346
return a.substring(result, result + stringSmallU.length());
347
}
348
349
@Test(op = Operation.INDEX_OF_CON_U, constString = stringU)
350
public static String indexOfConstLargeU(String a) {
351
int result = a.indexOf(stringU);
352
return a.substring(result, result + stringU.length());
353
}
354
355
@Test(op = Operation.INDEX_OF_CON_U, constString = emptyString)
356
public static String indexOfConstEmptyU(String a) {
357
int result = a.indexOf(emptyString);
358
return a.substring(result, result + emptyString.length());
359
}
360
361
@Test(op = Operation.INDEX_OF_CON_L, constString = stringSmallL)
362
public static String indexOfConstL(String a) {
363
int result = a.indexOf(stringSmallL);
364
return a.substring(result, result + stringSmallL.length());
365
}
366
367
@Test(op = Operation.INDEX_OF_CON_L, constString = stringL)
368
public static String indexOfConstLargeL(String a) {
369
int result = a.indexOf(stringL);
370
return a.substring(result, result + stringL.length());
371
}
372
373
@Test(op = Operation.INDEX_OF_CON_L, constString = emptyString)
374
public static String indexOfConstEmptyL(String a) {
375
int result = a.indexOf(emptyString);
376
return a.substring(result, result + emptyString.length());
377
}
378
379
@Test(op = Operation.INDEX_OF_CON_UL, constString = stringSmallL)
380
public static String indexOfConstUL(String a) {
381
int result = a.indexOf(stringSmallL);
382
return a.substring(result, result + stringSmallL.length());
383
}
384
385
@Test(op = Operation.INDEX_OF_CON_UL, constString = stringL)
386
public static String indexOfConstLargeUL(String a) {
387
int result = a.indexOf(stringL);
388
return a.substring(result, result + stringL.length());
389
}
390
391
@Test(op = Operation.INDEX_OF_CHAR)
392
public static int indexOfChar(String a, int ch, int from) {
393
return a.indexOf(ch, from);
394
}
395
396
/*
397
* String concatenation optimization
398
*/
399
@Test(op = Operation.CONCAT, inStrings = {"ABC", "\uff21\uff22\uff23"}, outStrings = {"ABC", "\uff21\uff22\uff23"})
400
public static String concatString(String a) {
401
return new StringBuilder().append(a).toString();
402
}
403
404
@Test(op = Operation.CONCAT, inStrings = {""}, outStrings = {""})
405
public static String concatStringEmpty(String a) {
406
return new StringBuilder().toString();
407
}
408
409
@Test(op = Operation.CONCAT, inStrings = {""}, outStrings = {"null"})
410
public static String concatStringNull(String a) {
411
return new StringBuilder().append((String)null).toString();
412
}
413
414
@Test(op = Operation.CONCAT, inStrings = {"ABC", "\uff21\uff22\uff23"}, outStrings = {"abcdefghijklmnopABCabc", "abcdefghijklmnop\uff21\uff22\uff23abc"})
415
public static String concatStringConstL(String a) {
416
return new StringBuilder().append(stringL).append(a).append(stringSmallL).toString();
417
}
418
419
@Test(op = Operation.CONCAT, inStrings = {"ABC", "\uff21\uff22\uff23"}, outStrings = {"\u0f21\u0f22\u0f23ABC\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28", "\u0f21\u0f22\u0f23\uff21\uff22\uff23\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28"})
420
public static String concatStringConstU(String a) {
421
return new StringBuilder().append(stringSmallU).append(a).append(stringU).toString();
422
}
423
424
@Test(op = Operation.CONCAT_C, inChars = {'A', '\uff21'}, outStrings = {"A", "\uff21"})
425
public static String concatChar(char a) {
426
return new StringBuilder().append(a).toString();
427
}
428
429
@Test(op = Operation.CONCAT_C, inChars = {'A', '\uff21'}, outStrings = {"abcdefghijklmnopAabcA\uff21", "abcdefghijklmnop\uff21abcA\uff21"})
430
public static String concatCharConstL(char a) {
431
return new StringBuilder().append(stringL).append(a).append(stringSmallL).append(charL).append(charU).toString();
432
}
433
434
@Test(op = Operation.CONCAT_C, inChars = {'A', '\uff21'}, outStrings = {"\u0f21\u0f22\u0f23A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21A", "\u0f21\u0f22\u0f23\uff21\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21A"})
435
public static String concatCharConstU(char a) {
436
return new StringBuilder().append(stringSmallU).append(a).append(stringU).append(charU).append(charL).toString();
437
}
438
439
@Test(op = Operation.CONCAT_I, inInts = {Integer.MIN_VALUE, -42, 42, Integer.MAX_VALUE}, outStrings = {"-2147483648", "-42", "42", "2147483647"})
440
public static String concatInt(int a) {
441
return new StringBuilder().append(a).toString();
442
}
443
444
@Test(op = Operation.CONCAT_I, inInts = {Integer.MIN_VALUE, -42, 42, Integer.MAX_VALUE}, outStrings = {"abcdefghijklmnop-2147483648abc123-123", "abcdefghijklmnop-42abc123-123", "abcdefghijklmnop42abc123-123", "abcdefghijklmnop2147483647abc123-123"})
445
public static String concatIntConstL(int b) {
446
return new StringBuilder().append(stringL).append(b).append(stringSmallL).append(constInt).append(constIntNeg).toString();
447
}
448
449
@Test(op = Operation.CONCAT_I, inInts = {Integer.MIN_VALUE, -42, 42, Integer.MAX_VALUE}, outStrings = {"\u0f21\u0f22\u0f23-2147483648\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28123-123", "\u0f21\u0f22\u0f23-42\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28123-123", "\u0f21\u0f22\u0f2342\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28123-123", "\u0f21\u0f22\u0f232147483647\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28123-123"})
450
public static String concatIntConstU(int b) {
451
return new StringBuilder().append(stringSmallU).append(b).append(stringU).append(constInt).append(constIntNeg).toString();
452
}
453
454
@Test(op = Operation.CONCAT, inStrings = {""}, outStrings = {"nullabcabcdefghijklmnopA123-123"})
455
public static String concatConstL(String a) {
456
return new StringBuilder().append((String)null).append(stringSmallL).append(stringL).append(charL).append(constInt).append(constIntNeg).toString();
457
}
458
459
@Test(op = Operation.CONCAT, inStrings = {""}, outStrings = {"nullabcabcdefghijklmnop\u0f21\u0f22\u0f23\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28A\uff21123-123"})
460
public static String concatConstU(String a) {
461
return new StringBuilder().append((String)null).append(stringSmallL).append(stringL).append(stringSmallU).append(stringU).append(charL).append(charU).append(constInt).append(constIntNeg).toString();
462
}
463
464
@Test(op = Operation.CONCAT_M,
465
inStrings = {"ABCDEFG", "ABCDEFG", "\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28", "\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28"},
466
inChars = {'A', '\uff21', 'A', '\uff21'},
467
inInts = {Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE},
468
outStrings = {"ABCDEFGA-2147483648nullabcdefghijklmnop123-123A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21ABCDEFGA-2147483648null",
469
"ABCDEFG\uff212147483647nullabcdefghijklmnop123-123A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21ABCDEFG\uff212147483647null",
470
"\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28A-2147483648nullabcdefghijklmnop123-123A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28A-2147483648null",
471
"\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff212147483647nullabcdefghijklmnop123-123A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff212147483647null"})
472
public static String concatMixed(String a, char b, int c) {
473
return new StringBuilder().append(a).append(b).append(c).append((String)null)
474
.append(stringL).append(constInt).append(constIntNeg).append(charL).append(stringU).append(charU)
475
.append(a).append(b).append(c).append((String)null).toString();
476
}
477
}
478
479