87 // Number of warmup iterations
88 @Retention(RetentionPolicy.RUNTIME)
89 @interface Warmup {
90 int value();
91 }
92
93 // Do not enqueue the test method for compilation immediately after warmup loops have finished. Instead
94 // let the test method be compiled with on-stack-replacement.
95 @Retention(RetentionPolicy.RUNTIME)
96 @interface OSRCompileOnly {}
97
98 // Skip this test temporarily for C1 testing
99 @Retention(RetentionPolicy.RUNTIME)
100 @interface TempSkipForC1 {
101 String reason() default "";
102 }
103
104 public abstract class ValueTypeTest {
105 protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
106
107 // Currently C1 is disabled by default. To test C1, run "jtreg -vmoptions:-XX:+EnableValhallaC1 -vmoptions:-XX:TieredStopAtLevel=1".
108 // This forces C1 to be use for all methods that are compiled, @Test(compLevel=?) setting.
109 static final boolean TEST_C1 = (Boolean)WHITE_BOX.getVMFlag("EnableValhallaC1");
110
111 // Should we execute tests that assume (ValueType[] <: Object[])?
112 static final boolean ENABLE_VALUE_ARRAY_COVARIANCE = Boolean.getBoolean("ValueArrayCovariance");
113
114 // Random test values
115 public static final int rI = Utils.getRandomInstance().nextInt() % 1000;
116 public static final long rL = Utils.getRandomInstance().nextLong() % 1000;
117
118 // User defined settings
119 protected static final boolean XCOMP = Platform.isComp();
120 private static final boolean PRINT_GRAPH = true;
121 protected static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false"));
122 private static final boolean PRINT_TIMES = Boolean.parseBoolean(System.getProperty("PrintTimes", "false"));
123 private static boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")) && !TEST_C1 && !XCOMP;
124 private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false"));
125 private static final String SCENARIOS = System.getProperty("Scenarios", "");
126 private static final String TESTLIST = System.getProperty("Testlist", "");
127 private static final String EXCLUDELIST = System.getProperty("Exclude", "");
128 private static final int WARMUP = Integer.parseInt(System.getProperty("Warmup", "251"));
129 private static final boolean DUMP_REPLAY = Boolean.parseBoolean(System.getProperty("DumpReplay", "false"));
130 protected static final boolean FLIP_C1_C2 = Boolean.parseBoolean(System.getProperty("FlipC1C2", "false"));
131 protected static final boolean GCAfter = Boolean.parseBoolean(System.getProperty("GCAfter", "false"));
132 private static final int OSRTestTimeOut = Integer.parseInt(System.getProperty("OSRTestTimeOut", "-1"));
133
134 // "jtreg -DXcomp=true" runs all the scenarios with -Xcomp. This is faster than "jtreg -javaoptions:-Xcomp".
135 protected static final boolean RUN_SCENARIOS_WITH_XCOMP = Boolean.parseBoolean(System.getProperty("Xcomp", "false"));
136
137 // Pre-defined settings
138 private static final String[] defaultFlags = {
139 "-XX:-BackgroundCompilation",
140 "-XX:CompileCommand=quiet",
141 "-XX:CompileCommand=compileonly,java.lang.invoke.*::*",
142 "-XX:CompileCommand=compileonly,java.lang.Long::sum",
143 "-XX:CompileCommand=compileonly,java.lang.Object::<init>",
148 private static final String[] verifyFlags = {
149 "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", "-XX:+VerifyBeforeGC", "-XX:+VerifyAfterGC",
150 "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing"};
151
152 protected static final int ValueTypePassFieldsAsArgsOn = 0x1;
153 protected static final int ValueTypePassFieldsAsArgsOff = 0x2;
154 protected static final int ValueTypeArrayFlattenOn = 0x4;
155 protected static final int ValueTypeArrayFlattenOff = 0x8;
156 protected static final int ValueTypeReturnedAsFieldsOn = 0x10;
157 protected static final int ValueTypeReturnedAsFieldsOff = 0x20;
158 protected static final int AlwaysIncrementalInlineOn = 0x40;
159 protected static final int AlwaysIncrementalInlineOff = 0x80;
160 protected static final int G1GCOn = 0x100;
161 protected static final int G1GCOff = 0x200;
162 static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff | ValueTypeReturnedAsFieldsOn;
163 protected static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs");
164 protected static final boolean ValueTypeArrayFlatten = (WHITE_BOX.getIntxVMFlag("ValueArrayElemMaxFlatSize") == -1); // FIXME - fix this if default of ValueArrayElemMaxFlatSize is changed
165 protected static final boolean ValueTypeReturnedAsFields = (Boolean)WHITE_BOX.getVMFlag("ValueTypeReturnedAsFields");
166 protected static final boolean AlwaysIncrementalInline = (Boolean)WHITE_BOX.getVMFlag("AlwaysIncrementalInline");
167 protected static final boolean G1GC = (Boolean)WHITE_BOX.getVMFlag("UseG1GC");
168 protected static final long TieredStopAtLevel = (Long)WHITE_BOX.getVMFlag("TieredStopAtLevel");
169 protected static final boolean VerifyOops = (Boolean)WHITE_BOX.getVMFlag("VerifyOops");
170 protected static final int COMP_LEVEL_ANY = -2;
171 protected static final int COMP_LEVEL_ALL = -2;
172 protected static final int COMP_LEVEL_AOT = -1;
173 protected static final int COMP_LEVEL_NONE = 0;
174 protected static final int COMP_LEVEL_SIMPLE = 1; // C1
175 protected static final int COMP_LEVEL_LIMITED_PROFILE = 2; // C1, invocation & backedge counters
176 protected static final int COMP_LEVEL_FULL_PROFILE = 3; // C1, invocation & backedge counters + mdo
177 protected static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; // C2 or JVMCI
178
179 protected static final Hashtable<String, Method> tests = new Hashtable<String, Method>();
180 protected static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler");
181 protected static final boolean PRINT_IDEAL = WHITE_BOX.getBooleanVMFlag("PrintIdeal");
182
183 // Regular expressions used to match nodes in the PrintIdeal output
184 protected static final String START = "(\\d+\\t(.*";
185 protected static final String MID = ".*)+\\t===.*";
186 protected static final String END = ")|";
187 // Generic allocation
188 protected static final String ALLOC_G = "(.*call,static wrapper for: _new_instance_Java" + END;
189 protected static final String ALLOCA_G = "(.*call,static wrapper for: _new_array_Java" + END;
190 // Value type allocation
191 protected static final String ALLOC = "(.*precise klass compiler/valhalla/valuetypes/MyValue.*\\R(.*(nop|spill).*\\R)*.*_new_instance_Java" + END;
192 protected static final String ALLOCA = "(.*precise klass \\[Lcompiler/valhalla/valuetypes/MyValue.*\\R(.*(nop|spill).*\\R)*.*_new_array_Java" + END;
193 protected static final String LOAD = START + "Load(B|S|I|L|F|D|P|N)" + MID + "@compiler/valhalla/valuetypes/MyValue.*" + END;
194 protected static final String LOADK = START + "LoadK" + MID + END;
195 protected static final String STORE = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@compiler/valhalla/valuetypes/MyValue.*" + END;
196 protected static final String LOOP = START + "Loop" + MID + "" + END;
197 protected static final String COUNTEDLOOP = START + "CountedLoop\\b" + MID + "" + END;
429 cmds = concat(cmds, vmInputArgs);
430 cmds = concat(cmds, defaultFlags);
431
432 // Run tests in own process and verify output
433 cmds = concat(cmds, getClass().getName(), "run");
434 OutputAnalyzer oa = ProcessTools.executeTestJvm(cmds);
435 // If ideal graph printing is enabled/supported, verify output
436 String output = oa.getOutput();
437 oa.shouldHaveExitValue(0);
438 if (VERIFY_IR) {
439 if (output.contains("PrintIdeal enabled")) {
440 parseOutput(output);
441 } else {
442 System.out.println(output);
443 System.out.println("WARNING: IR verification failed! Running with -Xint, -Xcomp or release build?");
444 }
445 }
446 }
447
448 private void parseOutput(String output) throws Exception {
449 Pattern comp_re = Pattern.compile("\\n\\s+\\d+\\s+\\d+\\s+(%| )(s| )(!| )b(n| )\\s+\\S+\\.(?<name>[^.]+::\\S+)\\s+(?<osr>@ \\d+\\s+)?[(]\\d+ bytes[)]\\n");
450 Matcher m = comp_re.matcher(output);
451 Map<String,String> compilations = new LinkedHashMap<>();
452 int prev = 0;
453 String methodName = null;
454 while (m.find()) {
455 if (prev == 0) {
456 // Print header
457 System.out.print(output.substring(0, m.start()+1));
458 } else if (methodName != null) {
459 compilations.put(methodName, output.substring(prev, m.start()+1));
460 }
461 if (m.group("osr") != null) {
462 methodName = null;
463 } else {
464 methodName = m.group("name");
465 }
466 prev = m.end();
467 }
468 if (prev == 0) {
469 // Print header
520 }
521 assert anno != null;
522 String regexFail = anno.failOn();
523 if (!regexFail.isEmpty()) {
524 Pattern pattern = Pattern.compile(regexFail.substring(0, regexFail.length()-1));
525 Matcher matcher = pattern.matcher(graph);
526 boolean found = matcher.find();
527 Asserts.assertFalse(found, "Graph for '" + testName + "' contains forbidden node:\n" + (found ? matcher.group() : ""));
528 }
529 String[] regexMatch = anno.match();
530 int[] matchCount = anno.matchCount();
531 for (int i = 0; i < regexMatch.length; ++i) {
532 Pattern pattern = Pattern.compile(regexMatch[i].substring(0, regexMatch[i].length()-1));
533 Matcher matcher = pattern.matcher(graph);
534 int count = 0;
535 String nodes = "";
536 while (matcher.find()) {
537 count++;
538 nodes += matcher.group() + "\n";
539 }
540 if (matchCount[i] < 0) {
541 Asserts.assertLTE(Math.abs(matchCount[i]), count, "Graph for '" + testName + "' contains different number of match nodes:\n" + nodes);
542 } else {
543 Asserts.assertEQ(matchCount[i], count, "Graph for '" + testName + "' contains different number of match nodes:\n" + nodes);
544 }
545 }
546 tests.remove(testName);
547 System.out.println(testName + " passed");
548 }
549 // Check if all tests were compiled
550 if (tests.size() != 0) {
551 for (String name : tests.keySet()) {
552 System.out.println("Test '" + name + "' not compiled!");
553 }
554 throw new RuntimeException("Not all tests were compiled");
555 }
556 }
557
558 private void setup(Class<?> clazz) {
559 if (XCOMP) {
|
87 // Number of warmup iterations
88 @Retention(RetentionPolicy.RUNTIME)
89 @interface Warmup {
90 int value();
91 }
92
93 // Do not enqueue the test method for compilation immediately after warmup loops have finished. Instead
94 // let the test method be compiled with on-stack-replacement.
95 @Retention(RetentionPolicy.RUNTIME)
96 @interface OSRCompileOnly {}
97
98 // Skip this test temporarily for C1 testing
99 @Retention(RetentionPolicy.RUNTIME)
100 @interface TempSkipForC1 {
101 String reason() default "";
102 }
103
104 public abstract class ValueTypeTest {
105 protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
106
107 protected static final int COMP_LEVEL_ANY = -2;
108 protected static final int COMP_LEVEL_ALL = -2;
109 protected static final int COMP_LEVEL_AOT = -1;
110 protected static final int COMP_LEVEL_NONE = 0;
111 protected static final int COMP_LEVEL_SIMPLE = 1; // C1
112 protected static final int COMP_LEVEL_LIMITED_PROFILE = 2; // C1, invocation & backedge counters
113 protected static final int COMP_LEVEL_FULL_PROFILE = 3; // C1, invocation & backedge counters + mdo
114 protected static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; // C2 or JVMCI
115
116 protected static final boolean TieredCompilation = (Boolean)WHITE_BOX.getVMFlag("TieredCompilation");
117 protected static final long TieredStopAtLevel = (Long)WHITE_BOX.getVMFlag("TieredStopAtLevel");
118 static final boolean TEST_C1 = TieredStopAtLevel < COMP_LEVEL_FULL_OPTIMIZATION;
119
120 // Should we execute tests that assume (ValueType[] <: Object[])?
121 static final boolean ENABLE_VALUE_ARRAY_COVARIANCE = Boolean.getBoolean("ValueArrayCovariance");
122
123 // Random test values
124 public static final int rI = Utils.getRandomInstance().nextInt() % 1000;
125 public static final long rL = Utils.getRandomInstance().nextLong() % 1000;
126
127 // User defined settings
128 protected static final boolean XCOMP = Platform.isComp();
129 private static final boolean PRINT_GRAPH = true;
130 protected static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false"));
131 private static final boolean PRINT_TIMES = Boolean.parseBoolean(System.getProperty("PrintTimes", "false"));
132 private static boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")) && !XCOMP;
133 private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false"));
134 private static final String SCENARIOS = System.getProperty("Scenarios", "");
135 private static final String TESTLIST = System.getProperty("Testlist", "");
136 private static final String EXCLUDELIST = System.getProperty("Exclude", "");
137 private static final int WARMUP = Integer.parseInt(System.getProperty("Warmup", "251"));
138 private static final boolean DUMP_REPLAY = Boolean.parseBoolean(System.getProperty("DumpReplay", "false"));
139 protected static final boolean FLIP_C1_C2 = Boolean.parseBoolean(System.getProperty("FlipC1C2", "false"));
140 protected static final boolean GCAfter = Boolean.parseBoolean(System.getProperty("GCAfter", "false"));
141 private static final int OSRTestTimeOut = Integer.parseInt(System.getProperty("OSRTestTimeOut", "-1"));
142
143 // "jtreg -DXcomp=true" runs all the scenarios with -Xcomp. This is faster than "jtreg -javaoptions:-Xcomp".
144 protected static final boolean RUN_SCENARIOS_WITH_XCOMP = Boolean.parseBoolean(System.getProperty("Xcomp", "false"));
145
146 // Pre-defined settings
147 private static final String[] defaultFlags = {
148 "-XX:-BackgroundCompilation",
149 "-XX:CompileCommand=quiet",
150 "-XX:CompileCommand=compileonly,java.lang.invoke.*::*",
151 "-XX:CompileCommand=compileonly,java.lang.Long::sum",
152 "-XX:CompileCommand=compileonly,java.lang.Object::<init>",
157 private static final String[] verifyFlags = {
158 "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", "-XX:+VerifyBeforeGC", "-XX:+VerifyAfterGC",
159 "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing"};
160
161 protected static final int ValueTypePassFieldsAsArgsOn = 0x1;
162 protected static final int ValueTypePassFieldsAsArgsOff = 0x2;
163 protected static final int ValueTypeArrayFlattenOn = 0x4;
164 protected static final int ValueTypeArrayFlattenOff = 0x8;
165 protected static final int ValueTypeReturnedAsFieldsOn = 0x10;
166 protected static final int ValueTypeReturnedAsFieldsOff = 0x20;
167 protected static final int AlwaysIncrementalInlineOn = 0x40;
168 protected static final int AlwaysIncrementalInlineOff = 0x80;
169 protected static final int G1GCOn = 0x100;
170 protected static final int G1GCOff = 0x200;
171 static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff | ValueTypeReturnedAsFieldsOn;
172 protected static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs");
173 protected static final boolean ValueTypeArrayFlatten = (WHITE_BOX.getIntxVMFlag("ValueArrayElemMaxFlatSize") == -1); // FIXME - fix this if default of ValueArrayElemMaxFlatSize is changed
174 protected static final boolean ValueTypeReturnedAsFields = (Boolean)WHITE_BOX.getVMFlag("ValueTypeReturnedAsFields");
175 protected static final boolean AlwaysIncrementalInline = (Boolean)WHITE_BOX.getVMFlag("AlwaysIncrementalInline");
176 protected static final boolean G1GC = (Boolean)WHITE_BOX.getVMFlag("UseG1GC");
177 protected static final boolean VerifyOops = (Boolean)WHITE_BOX.getVMFlag("VerifyOops");
178
179 protected static final Hashtable<String, Method> tests = new Hashtable<String, Method>();
180 protected static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler");
181 protected static final boolean PRINT_IDEAL = WHITE_BOX.getBooleanVMFlag("PrintIdeal");
182
183 // Regular expressions used to match nodes in the PrintIdeal output
184 protected static final String START = "(\\d+\\t(.*";
185 protected static final String MID = ".*)+\\t===.*";
186 protected static final String END = ")|";
187 // Generic allocation
188 protected static final String ALLOC_G = "(.*call,static wrapper for: _new_instance_Java" + END;
189 protected static final String ALLOCA_G = "(.*call,static wrapper for: _new_array_Java" + END;
190 // Value type allocation
191 protected static final String ALLOC = "(.*precise klass compiler/valhalla/valuetypes/MyValue.*\\R(.*(nop|spill).*\\R)*.*_new_instance_Java" + END;
192 protected static final String ALLOCA = "(.*precise klass \\[Lcompiler/valhalla/valuetypes/MyValue.*\\R(.*(nop|spill).*\\R)*.*_new_array_Java" + END;
193 protected static final String LOAD = START + "Load(B|S|I|L|F|D|P|N)" + MID + "@compiler/valhalla/valuetypes/MyValue.*" + END;
194 protected static final String LOADK = START + "LoadK" + MID + END;
195 protected static final String STORE = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@compiler/valhalla/valuetypes/MyValue.*" + END;
196 protected static final String LOOP = START + "Loop" + MID + "" + END;
197 protected static final String COUNTEDLOOP = START + "CountedLoop\\b" + MID + "" + END;
429 cmds = concat(cmds, vmInputArgs);
430 cmds = concat(cmds, defaultFlags);
431
432 // Run tests in own process and verify output
433 cmds = concat(cmds, getClass().getName(), "run");
434 OutputAnalyzer oa = ProcessTools.executeTestJvm(cmds);
435 // If ideal graph printing is enabled/supported, verify output
436 String output = oa.getOutput();
437 oa.shouldHaveExitValue(0);
438 if (VERIFY_IR) {
439 if (output.contains("PrintIdeal enabled")) {
440 parseOutput(output);
441 } else {
442 System.out.println(output);
443 System.out.println("WARNING: IR verification failed! Running with -Xint, -Xcomp or release build?");
444 }
445 }
446 }
447
448 private void parseOutput(String output) throws Exception {
449 Pattern comp_re = Pattern.compile("\\n\\s+\\d+\\s+\\d+\\s+(%| )(s| )(!| )b(n| )\\s+\\d?\\s+\\S+\\.(?<name>[^.]+::\\S+)\\s+(?<osr>@ \\d+\\s+)?[(]\\d+ bytes[)]");
450 Matcher m = comp_re.matcher(output);
451 Map<String,String> compilations = new LinkedHashMap<>();
452 int prev = 0;
453 String methodName = null;
454 while (m.find()) {
455 if (prev == 0) {
456 // Print header
457 System.out.print(output.substring(0, m.start()+1));
458 } else if (methodName != null) {
459 compilations.put(methodName, output.substring(prev, m.start()+1));
460 }
461 if (m.group("osr") != null) {
462 methodName = null;
463 } else {
464 methodName = m.group("name");
465 }
466 prev = m.end();
467 }
468 if (prev == 0) {
469 // Print header
520 }
521 assert anno != null;
522 String regexFail = anno.failOn();
523 if (!regexFail.isEmpty()) {
524 Pattern pattern = Pattern.compile(regexFail.substring(0, regexFail.length()-1));
525 Matcher matcher = pattern.matcher(graph);
526 boolean found = matcher.find();
527 Asserts.assertFalse(found, "Graph for '" + testName + "' contains forbidden node:\n" + (found ? matcher.group() : ""));
528 }
529 String[] regexMatch = anno.match();
530 int[] matchCount = anno.matchCount();
531 for (int i = 0; i < regexMatch.length; ++i) {
532 Pattern pattern = Pattern.compile(regexMatch[i].substring(0, regexMatch[i].length()-1));
533 Matcher matcher = pattern.matcher(graph);
534 int count = 0;
535 String nodes = "";
536 while (matcher.find()) {
537 count++;
538 nodes += matcher.group() + "\n";
539 }
540
541 if (TieredCompilation) {
542 // FIXME: TestLWorld.test88 fails with "expected 4 to equal 2"
543 continue;
544 }
545
546 if (matchCount[i] < 0) {
547 Asserts.assertLTE(Math.abs(matchCount[i]), count, "Graph for '" + testName + "' contains different number of match nodes:\n" + nodes);
548 } else {
549 Asserts.assertEQ(matchCount[i], count, "Graph for '" + testName + "' contains different number of match nodes:\n" + nodes);
550 }
551 }
552 tests.remove(testName);
553 System.out.println(testName + " passed");
554 }
555 // Check if all tests were compiled
556 if (tests.size() != 0) {
557 for (String name : tests.keySet()) {
558 System.out.println("Test '" + name + "' not compiled!");
559 }
560 throw new RuntimeException("Not all tests were compiled");
561 }
562 }
563
564 private void setup(Class<?> clazz) {
565 if (XCOMP) {
|