8268963: [IR Framework] Some default regexes matching on PrintOptoAssembly in IRNode.java do not work on all platforms
Reviewed-by: kvn, thartmann
This commit is contained in:
parent
b59418f47d
commit
9856ace828
@ -24,12 +24,12 @@
|
||||
package compiler.lib.ir_framework;
|
||||
|
||||
import compiler.lib.ir_framework.driver.IRMatcher;
|
||||
import compiler.lib.ir_framework.shared.TestFormat;
|
||||
import compiler.lib.ir_framework.shared.TestFormatException;
|
||||
import compiler.lib.ir_framework.shared.*;
|
||||
import jdk.test.lib.Platform;
|
||||
import sun.hotspot.WhiteBox;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* This class provides default regex strings that can be used in {@link IR @IR} annotations to specify IR constraints.
|
||||
@ -48,15 +48,20 @@ public class IRNode {
|
||||
private static final String START = "(\\d+(\\s){2}(";
|
||||
private static final String MID = ".*)+(\\s){2}===.*";
|
||||
private static final String END = ")";
|
||||
private static final String COMPOSITE_PREFIX = "#PRE#"; // Prefix for regexes that require an additional user-defined string.
|
||||
private static final String IS_REPLACED = "#IS_REPLACED#"; // Is replaced by an additional user-defined string.
|
||||
private static final String STORE_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END;
|
||||
private static final String LOAD_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END;
|
||||
|
||||
public static final String ALLOC = "(.*precise klass .*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_instance_Java" + END;
|
||||
public static final String ALLOC_OF = "(.*precise klass .*";
|
||||
public static final String ALLOC_ARRAY = "(.*precise klass \\[L.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_array_Java" + END;
|
||||
public static final String ALLOC_ARRAY_OF = "(.*precise klass \\[L.*";
|
||||
public static final String ALLOC = "(.*precise klass .*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_instance_Java" + END;
|
||||
public static final String ALLOC_OF = COMPOSITE_PREFIX + "(.*precise klass .*" + IS_REPLACED + ":.*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_instance_Java" + END;
|
||||
public static final String ALLOC_ARRAY = "(.*precise klass \\[L.*\\R((.*(?i:mov|xor|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_array_Java" + END;
|
||||
public static final String ALLOC_ARRAY_OF = COMPOSITE_PREFIX + "(.*precise klass \\[L.*" + IS_REPLACED + ";:.*\\R((.*(?i:mov|xorl|nop|spill).*|\\s*|.*LGHI.*)\\R)*.*(?i:call,static).*wrapper for: _new_array_Java" + END;
|
||||
|
||||
public static final String CHECKCAST_ARRAY = "(cmp.*precise klass \\[.*;:" + END;
|
||||
public static final String CHECKCAST_ARRAY_OF = "(cmp.*precise klass \\[.*";
|
||||
public static final String CHECKCAST_ARRAYCOPY = "(.*call_leaf_nofp,runtime checkcast_arraycopy.*" + END;
|
||||
public static final String CHECKCAST_ARRAY = "(((?i:cmp|CLFI|CLR).*precise klass \\[.*;:|.*(?i:mov|or).*precise klass \\[.*;:.*\\R.*(cmp|CMP|CLR))" + END;
|
||||
public static final String CHECKCAST_ARRAY_OF = COMPOSITE_PREFIX + "(((?i:cmp|CLFI|CLR).*precise klass \\[.*" + IS_REPLACED + ";:|.*(?i:mov|or).*precise klass \\[.*" + IS_REPLACED + ";:.*\\R.*(cmp|CMP|CLR))" + END;
|
||||
// Does not work on s390 (a rule containing this regex will be skipped on s390).
|
||||
public static final String CHECKCAST_ARRAYCOPY = "(.*((?i:call_leaf_nofp,runtime)|CALL,\\s?runtime leaf nofp|BCTRL.*.leaf call).*checkcast_arraycopy.*" + END;
|
||||
|
||||
public static final String FIELD_ACCESS = "(.*Field: *" + END;
|
||||
|
||||
@ -69,16 +74,16 @@ public class IRNode {
|
||||
public static final String STORE_D = START + "StoreD" + MID + END;
|
||||
public static final String STORE_P = START + "StoreP" + MID + END;
|
||||
public static final String STORE_N = START + "StoreN" + MID + END;
|
||||
public static final String STORE_OF_CLASS = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@\\S*";
|
||||
public static final String STORE_B_OF_CLASS = START + "StoreB" + MID + "@\\S*";
|
||||
public static final String STORE_C_OF_CLASS = START + "StoreC" + MID + "@\\S*";
|
||||
public static final String STORE_I_OF_CLASS = START + "StoreI" + MID + "@\\S*";
|
||||
public static final String STORE_L_OF_CLASS = START + "StoreL" + MID + "@\\S*";
|
||||
public static final String STORE_F_OF_CLASS = START + "StoreF" + MID + "@\\S*";
|
||||
public static final String STORE_D_OF_CLASS = START + "StoreD" + MID + "@\\S*";
|
||||
public static final String STORE_P_OF_CLASS = START + "StoreP" + MID + "@\\S*";
|
||||
public static final String STORE_N_OF_CLASS = START + "StoreN" + MID + "@\\S*";
|
||||
public static final String STORE_OF_FIELD = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@.*name=";
|
||||
public static final String STORE_OF_CLASS = COMPOSITE_PREFIX + START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX;
|
||||
public static final String STORE_B_OF_CLASS = COMPOSITE_PREFIX + START + "StoreB" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX;
|
||||
public static final String STORE_C_OF_CLASS = COMPOSITE_PREFIX + START + "StoreC" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX;
|
||||
public static final String STORE_I_OF_CLASS = COMPOSITE_PREFIX + START + "StoreI" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX;
|
||||
public static final String STORE_L_OF_CLASS = COMPOSITE_PREFIX + START + "StoreL" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX;
|
||||
public static final String STORE_F_OF_CLASS = COMPOSITE_PREFIX + START + "StoreF" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX;
|
||||
public static final String STORE_D_OF_CLASS = COMPOSITE_PREFIX + START + "StoreD" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX;
|
||||
public static final String STORE_P_OF_CLASS = COMPOSITE_PREFIX + START + "StoreP" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX;
|
||||
public static final String STORE_N_OF_CLASS = COMPOSITE_PREFIX + START + "StoreN" + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX;
|
||||
public static final String STORE_OF_FIELD = COMPOSITE_PREFIX + START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@.*name=" + IS_REPLACED + ",.*" + END;
|
||||
|
||||
public static final String LOAD = START + "Load(B|UB|S|US|I|L|F|D|P|N)" + MID + END;
|
||||
public static final String LOAD_B = START + "LoadB" + MID + END;
|
||||
@ -91,22 +96,22 @@ public class IRNode {
|
||||
public static final String LOAD_D = START + "LoadD" + MID + END;
|
||||
public static final String LOAD_P = START + "LoadP" + MID + END;
|
||||
public static final String LOAD_N = START + "LoadN" + MID + END;
|
||||
public static final String LOAD_OF_CLASS = START + "Load(B|UB|S|US|I|L|F|D|P|N)" + MID + "@\\S*";
|
||||
public static final String LOAD_B_OF_CLASS = START + "LoadB" + MID + "@\\S*";
|
||||
public static final String LOAD_UB_OF_CLASS = START + "LoadUB" + MID + "@\\S*";
|
||||
public static final String LOAD_S_OF_CLASS = START + "LoadS" + MID + "@\\S*";
|
||||
public static final String LOAD_US_OF_CLASS = START + "LoadUS" + MID + "@\\S*";
|
||||
public static final String LOAD_I_OF_CLASS = START + "LoadI" + MID + "@\\S*";
|
||||
public static final String LOAD_L_OF_CLASS = START + "LoadL" + MID + "@\\S*";
|
||||
public static final String LOAD_F_OF_CLASS = START + "LoadF" + MID + "@\\S*";
|
||||
public static final String LOAD_D_OF_CLASS = START + "LoadD" + MID + "@\\S*";
|
||||
public static final String LOAD_P_OF_CLASS = START + "LoadP" + MID + "@\\S*";
|
||||
public static final String LOAD_N_OF_CLASS = START + "LoadN" + MID + "@\\S*";
|
||||
public static final String LOAD_OF_FIELD = START + "Load(B|C|S|I|L|F|D|P|N)" + MID + "@.*name=";
|
||||
public static final String LOAD_OF_CLASS = COMPOSITE_PREFIX + START + "Load(B|UB|S|US|I|L|F|D|P|N)" + MID + "@\\S*"+ IS_REPLACED + LOAD_OF_CLASS_POSTFIX;
|
||||
public static final String LOAD_B_OF_CLASS = COMPOSITE_PREFIX + START + "LoadB" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX;
|
||||
public static final String LOAD_UB_OF_CLASS = COMPOSITE_PREFIX + START + "LoadUB" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX;
|
||||
public static final String LOAD_S_OF_CLASS = COMPOSITE_PREFIX + START + "LoadS" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX;
|
||||
public static final String LOAD_US_OF_CLASS = COMPOSITE_PREFIX + START + "LoadUS" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX;
|
||||
public static final String LOAD_I_OF_CLASS = COMPOSITE_PREFIX + START + "LoadI" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX;
|
||||
public static final String LOAD_L_OF_CLASS = COMPOSITE_PREFIX + START + "LoadL" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX;
|
||||
public static final String LOAD_F_OF_CLASS = COMPOSITE_PREFIX + START + "LoadF" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX;
|
||||
public static final String LOAD_D_OF_CLASS = COMPOSITE_PREFIX + START + "LoadD" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX;
|
||||
public static final String LOAD_P_OF_CLASS = COMPOSITE_PREFIX + START + "LoadP" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX;
|
||||
public static final String LOAD_N_OF_CLASS = COMPOSITE_PREFIX + START + "LoadN" + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX;
|
||||
public static final String LOAD_OF_FIELD = COMPOSITE_PREFIX + START + "Load(B|C|S|I|L|F|D|P|N)" + MID + "@.*name=" + IS_REPLACED + ",.*" + END;
|
||||
public static final String LOAD_KLASS = START + "LoadK" + MID + END;
|
||||
|
||||
public static final String LOOP = START + "Loop" + MID + "" + END;
|
||||
public static final String COUNTEDLOOP = START + "CountedLoop\\b" + MID + "" + END;
|
||||
public static final String LOOP = START + "Loop" + MID + END;
|
||||
public static final String COUNTEDLOOP = START + "CountedLoop\\b" + MID + END;
|
||||
public static final String COUNTEDLOOP_MAIN = START + "CountedLoop\\b" + MID + "main" + END;
|
||||
|
||||
public static final String CALL = START + "CallStaticJava" + MID + END;
|
||||
@ -118,20 +123,12 @@ public class IRNode {
|
||||
public static final String NULL_ASSERT_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*null_assert" + END;
|
||||
public static final String RANGE_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*range_check" + END;
|
||||
public static final String UNHANDLED_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*unhandled" + END;
|
||||
// Does not work for VM builds without JVMCI like x86_32 (a rule containing this regex will be skipped without having JVMCI built).
|
||||
public static final String INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*intrinsic_or_type_checked_inlining" + END;
|
||||
|
||||
public static final String SCOPE_OBJECT = "(.*# ScObj.*" + END;
|
||||
public static final String MEMBAR = START + "MemBar" + MID + END;
|
||||
|
||||
|
||||
private static final String ALLOC_OF_POSTFIX = ":.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_instance_Java" + END;
|
||||
private static final String ALLOC_ARRAY_OF_POSTFIX = ";:.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_array_Java" + END;
|
||||
private static final String CHECKCAST_ARRAY_OF_POSTFIX = ";:" + END;
|
||||
private static final String STORE_OF_FIELD_POSTFIX = ",.*" + END;
|
||||
private static final String STORE_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END;
|
||||
private static final String LOAD_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END;
|
||||
private static final String LOAD_OF_FIELD_POSTFIX = ",.*" + END;
|
||||
|
||||
/**
|
||||
* Called by {@link IRMatcher} to merge special composite nodes together with additional user-defined input.
|
||||
*/
|
||||
@ -139,29 +136,72 @@ public class IRNode {
|
||||
List<String> mergedNodes = new ArrayList<>();
|
||||
for (int i = 0; i < nodes.length; i += 2) {
|
||||
String node = nodes[i];
|
||||
switch (node) {
|
||||
case ALLOC_OF -> mergeCompositeNodes(nodes, mergedNodes, i, node, ALLOC_OF_POSTFIX, "ALLOC_OF");
|
||||
case ALLOC_ARRAY_OF -> mergeCompositeNodes(nodes, mergedNodes, i, node, ALLOC_ARRAY_OF_POSTFIX, "ALLOC_ARRAY_OF");
|
||||
case CHECKCAST_ARRAY_OF -> mergeCompositeNodes(nodes, mergedNodes, i, node, CHECKCAST_ARRAY_OF_POSTFIX, "CHECKCAST_ARRAY_OF");
|
||||
case STORE_OF_CLASS, STORE_B_OF_CLASS, STORE_C_OF_CLASS, STORE_D_OF_CLASS, STORE_F_OF_CLASS, STORE_I_OF_CLASS,
|
||||
STORE_L_OF_CLASS, STORE_N_OF_CLASS, STORE_P_OF_CLASS
|
||||
-> mergeCompositeNodes(nodes, mergedNodes, i, node, STORE_OF_CLASS_POSTFIX, "STORE_OF_CLASS");
|
||||
case STORE_OF_FIELD -> mergeCompositeNodes(nodes, mergedNodes, i, node, STORE_OF_FIELD_POSTFIX, "STORE_OF_FIELD");
|
||||
case LOAD_OF_CLASS, LOAD_B_OF_CLASS, LOAD_UB_OF_CLASS, LOAD_D_OF_CLASS, LOAD_F_OF_CLASS, LOAD_I_OF_CLASS, LOAD_L_OF_CLASS,
|
||||
LOAD_N_OF_CLASS, LOAD_P_OF_CLASS, LOAD_S_OF_CLASS, LOAD_US_OF_CLASS
|
||||
-> mergeCompositeNodes(nodes, mergedNodes, i, node, LOAD_OF_CLASS_POSTFIX, "LOAD_OF_CLASS");
|
||||
case LOAD_OF_FIELD -> mergeCompositeNodes(nodes, mergedNodes, i, node, LOAD_OF_FIELD_POSTFIX, "LOAD_OF_FIELD");
|
||||
default -> {
|
||||
i--; // No composite node, do not increment by 2.
|
||||
mergedNodes.add(node);
|
||||
if (node.startsWith(COMPOSITE_PREFIX)) {
|
||||
if (i + 1 == nodes.length) {
|
||||
reportMissingCompositeValue(node, i);
|
||||
}
|
||||
// Replace placeholder with user defined string.
|
||||
node = node.substring(COMPOSITE_PREFIX.length()).replaceAll(IS_REPLACED, nodes[i + 1]);
|
||||
} else {
|
||||
i--; // No composite node, do not increment by 2.
|
||||
}
|
||||
mergedNodes.add(node);
|
||||
}
|
||||
return mergedNodes;
|
||||
}
|
||||
|
||||
private static void mergeCompositeNodes(String[] nodes, List<String> mergedNodes, int i, String node, String postFix, String varName) {
|
||||
TestFormat.check(i + 1 < nodes.length, "Must provide class name at index " + (i + 1) + " right after " + varName);
|
||||
mergedNodes.add(node + Pattern.quote(nodes[i + 1]) + postFix);
|
||||
/**
|
||||
* Is default regex supported on current platform, used VM build, etc.?
|
||||
* Throws a {@link CheckedTestFrameworkException} if the default regex is unsupported.
|
||||
*/
|
||||
public static void checkDefaultRegexSupported(String node) throws CheckedTestFrameworkException {
|
||||
switch (node) {
|
||||
case INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP -> {
|
||||
if (!WhiteBox.getWhiteBox().isJVMCISupportedByGC()) {
|
||||
throw new CheckedTestFrameworkException("INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP is unsupported in builds without JVMCI.");
|
||||
}
|
||||
}
|
||||
case CHECKCAST_ARRAYCOPY -> {
|
||||
if (Platform.isS390x()) {
|
||||
throw new CheckedTestFrameworkException("CHECKCAST_ARRAYCOPY is unsupported on s390.");
|
||||
}
|
||||
}
|
||||
// default: do nothing -> default regex is supported
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapping from string variable value to string variable name for better error reporting.
|
||||
*/
|
||||
private static void reportMissingCompositeValue(String node, int i) {
|
||||
String varName = switch (node) {
|
||||
case ALLOC_OF -> "ALLOC_OF";
|
||||
case ALLOC_ARRAY_OF -> "ALLOC_ARRAY_OF";
|
||||
case CHECKCAST_ARRAY_OF -> "CHECKCAST_ARRAY_OF";
|
||||
case STORE_OF_CLASS -> "STORE_OF_CLASS";
|
||||
case STORE_B_OF_CLASS -> "STORE_B_OF_CLASS";
|
||||
case STORE_C_OF_CLASS -> "STORE_C_OF_CLASS";
|
||||
case STORE_D_OF_CLASS -> "STORE_D_OF_CLASS";
|
||||
case STORE_F_OF_CLASS -> "STORE_F_OF_CLASS";
|
||||
case STORE_I_OF_CLASS -> "STORE_I_OF_CLASS";
|
||||
case STORE_L_OF_CLASS -> "STORE_L_OF_CLASS";
|
||||
case STORE_N_OF_CLASS -> "STORE_N_OF_CLASS";
|
||||
case STORE_P_OF_CLASS -> "STORE_P_OF_CLASS";
|
||||
case STORE_OF_FIELD -> "STORE_OF_FIELD";
|
||||
case LOAD_OF_CLASS -> "LOAD_OF_CLASS";
|
||||
case LOAD_B_OF_CLASS -> "LOAD_B_OF_CLASS";
|
||||
case LOAD_UB_OF_CLASS -> "LOAD_UB_OF_CLASS";
|
||||
case LOAD_D_OF_CLASS -> "LOAD_D_OF_CLASS";
|
||||
case LOAD_F_OF_CLASS -> "LOAD_F_OF_CLASS";
|
||||
case LOAD_I_OF_CLASS -> "LOAD_I_OF_CLASS";
|
||||
case LOAD_L_OF_CLASS -> "LOAD_L_OF_CLASS";
|
||||
case LOAD_N_OF_CLASS -> "LOAD_N_OF_CLASS";
|
||||
case LOAD_P_OF_CLASS -> "LOAD_P_OF_CLASS";
|
||||
case LOAD_S_OF_CLASS -> "LOAD_S_OF_CLASS";
|
||||
case LOAD_US_OF_CLASS -> "LOAD_US_OF_CLASS";
|
||||
case LOAD_OF_FIELD -> "LOAD_OF_FIELD";
|
||||
default -> throw new TestFrameworkException("Missing variable mapping for " + node);
|
||||
};
|
||||
TestFormat.fail("Must provide additional value at index " + (i + 1) + " right after " + varName);
|
||||
}
|
||||
}
|
||||
|
@ -71,8 +71,8 @@ import java.lang.annotation.RetentionPolicy;
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* Examples on how to write base tests can be found in {@link jdk.test.lib.hotspot.ir_framework.examples.BaseTestExample}
|
||||
* and also as part of the internal testing in the package {@link jdk.test.lib.hotspot.ir_framework.tests}.
|
||||
* Examples on how to write base tests can be found in {@link ir_framework.examples.BaseTestExample}
|
||||
* and also as part of the internal testing in the package {@link ir_framework.tests}.
|
||||
*
|
||||
* @see Arguments
|
||||
*/
|
||||
|
@ -69,7 +69,7 @@ public class TestVMProcess {
|
||||
prepareTestVMFlags(additionalFlags, socket, testClass, helperClasses, defaultWarmup);
|
||||
start();
|
||||
}
|
||||
processSocketOutput(socket.getOutput());
|
||||
processSocketOutput(socket);
|
||||
checkTestVMExitCode();
|
||||
}
|
||||
|
||||
@ -163,23 +163,42 @@ public class TestVMProcess {
|
||||
* Process the socket output: All prefixed lines are dumped to the standard output while the remaining lines
|
||||
* represent the IR encoding used for IR matching later.
|
||||
*/
|
||||
private void processSocketOutput(String output) {
|
||||
if (TestFramework.TESTLIST || TestFramework.EXCLUDELIST) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
private void processSocketOutput(TestFrameworkSocket socket) {
|
||||
String output = socket.getOutput();
|
||||
if (socket.hasStdOut()) {
|
||||
StringBuilder testListBuilder = new StringBuilder();
|
||||
StringBuilder messagesBuilder = new StringBuilder();
|
||||
StringBuilder nonStdOutBuilder = new StringBuilder();
|
||||
Scanner scanner = new Scanner(output);
|
||||
System.out.println(System.lineSeparator() + "Run flag defined test list");
|
||||
System.out.println("--------------------------");
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
if (line.startsWith(TestFrameworkSocket.STDOUT_PREFIX)) {
|
||||
line = "> " + line.substring(TestFrameworkSocket.STDOUT_PREFIX.length());
|
||||
System.out.println(line);
|
||||
// Exclude [STDOUT] from message.
|
||||
line = line.substring(TestFrameworkSocket.STDOUT_PREFIX.length());
|
||||
if (line.startsWith(TestFrameworkSocket.TESTLIST_TAG)) {
|
||||
// Exclude [TESTLIST] from message for better formatting.
|
||||
line = "> " + line.substring(TestFrameworkSocket.TESTLIST_TAG.length() + 1);
|
||||
testListBuilder.append(line).append(System.lineSeparator());
|
||||
} else {
|
||||
messagesBuilder.append(line).append(System.lineSeparator());
|
||||
}
|
||||
} else {
|
||||
builder.append(line).append(System.lineSeparator());
|
||||
nonStdOutBuilder.append(line).append(System.lineSeparator());
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
irEncoding = builder.toString();
|
||||
if (!testListBuilder.isEmpty()) {
|
||||
System.out.println("Run flag defined test list");
|
||||
System.out.println("--------------------------");
|
||||
System.out.println(testListBuilder.toString());
|
||||
System.out.println();
|
||||
}
|
||||
if (!messagesBuilder.isEmpty()) {
|
||||
System.out.println("Messages from Test VM");
|
||||
System.out.println("---------------------");
|
||||
System.out.println(messagesBuilder.toString());
|
||||
}
|
||||
irEncoding = nonStdOutBuilder.toString();
|
||||
} else {
|
||||
irEncoding = output;
|
||||
}
|
||||
|
@ -39,6 +39,9 @@ import java.util.concurrent.FutureTask;
|
||||
*/
|
||||
public class TestFrameworkSocket implements AutoCloseable {
|
||||
public static final String STDOUT_PREFIX = "[STDOUT]";
|
||||
public static final String TESTLIST_TAG = "[TESTLIST]";
|
||||
public static final String DEFAULT_REGEX_TAG = "[DEFAULT_REGEX]";
|
||||
|
||||
// Static fields used for test VM only.
|
||||
private static final String SERVER_PORT_PROPERTY = "ir.framework.server.port";
|
||||
private static final int SERVER_PORT = Integer.getInteger(SERVER_PORT_PROPERTY, -1);
|
||||
@ -51,6 +54,7 @@ public class TestFrameworkSocket implements AutoCloseable {
|
||||
private final String serverPortPropertyFlag;
|
||||
private FutureTask<String> socketTask;
|
||||
private final ServerSocket serverSocket;
|
||||
private boolean receivedStdOut = false;
|
||||
|
||||
public TestFrameworkSocket() {
|
||||
try {
|
||||
@ -88,6 +92,9 @@ public class TestFrameworkSocket implements AutoCloseable {
|
||||
String next;
|
||||
while ((next = in.readLine()) != null) {
|
||||
builder.append(next).append(System.lineSeparator());
|
||||
if (next.startsWith(STDOUT_PREFIX)) {
|
||||
receivedStdOut = true;
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
} catch (IOException e) {
|
||||
@ -108,14 +115,14 @@ public class TestFrameworkSocket implements AutoCloseable {
|
||||
/**
|
||||
* Only called by test VM to write to server socket.
|
||||
*/
|
||||
public static void write(String msg, String type) {
|
||||
write(msg, type, false);
|
||||
public static void write(String msg, String tag) {
|
||||
write(msg, tag, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only called by test VM to write to server socket.
|
||||
*/
|
||||
public static void write(String msg, String type, boolean stdout) {
|
||||
public static void write(String msg, String tag, boolean stdout) {
|
||||
if (REPRODUCE) {
|
||||
System.out.println("Debugging Test VM: Skip writing due to -DReproduce");
|
||||
return;
|
||||
@ -129,7 +136,7 @@ public class TestFrameworkSocket implements AutoCloseable {
|
||||
clientWriter = new PrintWriter(clientSocket.getOutputStream(), true);
|
||||
}
|
||||
if (stdout) {
|
||||
msg = STDOUT_PREFIX + msg;
|
||||
msg = STDOUT_PREFIX + tag + " " + msg;
|
||||
}
|
||||
clientWriter.println(msg);
|
||||
} catch (Exception e) {
|
||||
@ -145,7 +152,7 @@ public class TestFrameworkSocket implements AutoCloseable {
|
||||
throw new TestRunException(failMsg, e);
|
||||
}
|
||||
if (TestFramework.VERBOSE) {
|
||||
System.out.println("Written " + type + " to socket:");
|
||||
System.out.println("Written " + tag + " to socket:");
|
||||
System.out.println(msg);
|
||||
}
|
||||
}
|
||||
@ -178,4 +185,11 @@ public class TestFrameworkSocket implements AutoCloseable {
|
||||
throw new TestFrameworkException("Could not read from socket task", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether test VM sent messages to be put on stdout (starting with {@link ::STDOUT_PREFIX}).
|
||||
*/
|
||||
public boolean hasStdOut() {
|
||||
return receivedStdOut;
|
||||
}
|
||||
}
|
||||
|
@ -96,6 +96,9 @@ public class IREncodingPrinter {
|
||||
|
||||
private boolean shouldApplyIrRule(IR irAnno) {
|
||||
checkIRAnnotations(irAnno);
|
||||
if (isDefaultRegexUnsupported(irAnno)) {
|
||||
return false;
|
||||
}
|
||||
if (irAnno.applyIf().length != 0) {
|
||||
return hasAllRequiredFlags(irAnno.applyIf(), "applyIf");
|
||||
}
|
||||
@ -141,7 +144,21 @@ public class IREncodingPrinter {
|
||||
}
|
||||
TestFormat.checkNoThrow(applyRules <= 1,
|
||||
"Can only specify one apply constraint " + failAt());
|
||||
}
|
||||
|
||||
private boolean isDefaultRegexUnsupported(IR irAnno) {
|
||||
try {
|
||||
for (String s : irAnno.failOn()) {
|
||||
IRNode.checkDefaultRegexSupported(s);
|
||||
}
|
||||
for (String s : irAnno.counts()) {
|
||||
IRNode.checkDefaultRegexSupported(s);
|
||||
}
|
||||
} catch (CheckedTestFrameworkException e) {
|
||||
TestFrameworkSocket.write("Skip Rule " + ruleIndex + ": " + e.getMessage(), TestFrameworkSocket.DEFAULT_REGEX_TAG, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasAllRequiredFlags(String[] andRules, String ruleType) {
|
||||
|
@ -796,7 +796,7 @@ public class TestVM {
|
||||
System.out.println("Run " + test.toString());
|
||||
}
|
||||
if (testFilterPresent) {
|
||||
TestFrameworkSocket.write("Run " + test.toString(), "testfilter", true);
|
||||
TestFrameworkSocket.write("Run " + test.toString(), TestFrameworkSocket.TESTLIST_TAG, true);
|
||||
}
|
||||
try {
|
||||
test.run();
|
||||
|
@ -26,6 +26,8 @@ package ir_framework.tests;
|
||||
import compiler.lib.ir_framework.*;
|
||||
import compiler.lib.ir_framework.driver.IRViolationException;
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.test.lib.Platform;
|
||||
import sun.hotspot.WhiteBox;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
@ -41,11 +43,21 @@ import java.util.regex.Pattern;
|
||||
* @summary Test IR matcher with different default IR node regexes. Use -DPrintIREncoding.
|
||||
* Normally, the framework should be called with driver.
|
||||
* @library /test/lib /
|
||||
* @run main/othervm -DPrintIREncoding=true ir_framework.tests.TestIRMatching
|
||||
* @build sun.hotspot.WhiteBox
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox
|
||||
* @run main/othervm/timeout=240 -Xbootclasspath/a:. -DSkipWhiteBoxInstall=true -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
|
||||
* -XX:+WhiteBoxAPI -DPrintIREncoding=true ir_framework.tests.TestIRMatching
|
||||
*/
|
||||
|
||||
public class TestIRMatching {
|
||||
|
||||
private static final List<Exception> exceptions = new ArrayList<>();
|
||||
|
||||
private static void addException(Exception e) {
|
||||
System.out.println(TestFramework.getLastTestVMOutput());
|
||||
exceptions.add(e);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
runFailOnTestsArgs(BadFailOnConstraint.create(AndOr1.class, "test1(int)", 1, "CallStaticJava"), "-XX:TLABRefillWasteFraction=50", "-XX:+UsePerfData", "-XX:+UseTLAB");
|
||||
runFailOnTestsArgs(BadFailOnConstraint.create(AndOr1.class, "test2()", 1, "CallStaticJava"), "-XX:TLABRefillWasteFraction=50", "-XX:-UsePerfData", "-XX:+UseTLAB");
|
||||
@ -55,7 +67,7 @@ public class TestIRMatching {
|
||||
runWithArguments(GoodCount.class, "-XX:TLABRefillWasteFraction=50");
|
||||
runWithArguments(MultipleFailOnGood.class, "-XX:TLABRefillWasteFraction=50");
|
||||
|
||||
String[] allocMatches = { "MyClass", "call,static wrapper for: _new_instance_Java" };
|
||||
String[] allocMatches = { "MyClass", "wrapper for: _new_instance_Java" };
|
||||
runCheck(BadFailOnConstraint.create(MultipleFailOnBad.class, "fail1()", 1, 1, "Store"),
|
||||
BadFailOnConstraint.create(MultipleFailOnBad.class, "fail1()", 1, 3, "Store"),
|
||||
GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail1()", 1, 2, 4),
|
||||
@ -88,7 +100,7 @@ public class TestIRMatching {
|
||||
BadCountsConstraint.create(BadCount.class, "bad3()", 2, 1, "Store")
|
||||
);
|
||||
|
||||
String[] allocArrayMatches = { "MyClass", "call,static wrapper for: _new_array_Java"};
|
||||
String[] allocArrayMatches = { "MyClass", "wrapper for: _new_array_Java"};
|
||||
runCheck(BadFailOnConstraint.create(AllocArray.class, "allocArray()", 1, allocArrayMatches),
|
||||
BadFailOnConstraint.create(AllocArray.class, "allocArray()", 2, allocArrayMatches),
|
||||
GoodFailOnConstraint.create(AllocArray.class, "allocArray()", 3),
|
||||
@ -105,7 +117,7 @@ public class TestIRMatching {
|
||||
BadFailOnConstraint.create(RunTests.class, "bad1(int)", 2, "Load")
|
||||
);
|
||||
|
||||
runCheck(new String[] {"-XX:-UseCompressedClassPointers"},
|
||||
runCheck(new String[] {"-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UseCompressedClassPointers"},
|
||||
BadFailOnConstraint.create(Loads.class, "load()", 1, 1, "Load"),
|
||||
BadFailOnConstraint.create(Loads.class, "load()", 1, 3, "LoadI"),
|
||||
BadCountsConstraint.create(Loads.class, "load()", 1, 1, 0),
|
||||
@ -170,7 +182,9 @@ public class TestIRMatching {
|
||||
BadFailOnConstraint.create(Traps.class, "rangeCheck()", 3, "CallStaticJava", "uncommon_trap", "null_check"),
|
||||
GoodRuleConstraint.create(Traps.class, "rangeCheck()", 4),
|
||||
BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 1, "CallStaticJava", "uncommon_trap"),
|
||||
BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 2, "CallStaticJava", "uncommon_trap", "intrinsic_or_type_checked_inlining"),
|
||||
WhiteBox.getWhiteBox().isJVMCISupportedByGC() ?
|
||||
BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 2, "CallStaticJava", "uncommon_trap", "intrinsic_or_type_checked_inlining")
|
||||
: GoodRuleConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 2),
|
||||
BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 3, "CallStaticJava", "uncommon_trap", "null_check"),
|
||||
GoodRuleConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 4)
|
||||
);
|
||||
@ -184,11 +198,22 @@ public class TestIRMatching {
|
||||
|
||||
runCheck(BadFailOnConstraint.create(ScopeObj.class, "scopeObject()", 1, "ScObj"));
|
||||
runCheck(BadFailOnConstraint.create(Membar.class, "membar()", 1, "MemBar"));
|
||||
runCheck(BadFailOnConstraint.create(CheckCastArray.class, "array()", 1, "cmp", "precise klass"),
|
||||
BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 1,"cmp", "precise klass", "MyClass"),
|
||||
BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 2,"cmp", "precise klass", "ir_framework/tests/MyClass"),
|
||||
|
||||
String cmp;
|
||||
if (Platform.isPPC() || Platform.isX86()) {
|
||||
cmp = "CMP";
|
||||
} else if (Platform.isS390x()){
|
||||
cmp = "CLFI";
|
||||
} else {
|
||||
cmp = "cmp";
|
||||
}
|
||||
runCheck(BadFailOnConstraint.create(CheckCastArray.class, "array()", 1, cmp, "precise klass"),
|
||||
BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 1,cmp, "precise klass", "MyClass"),
|
||||
BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 2,cmp, "precise klass", "ir_framework/tests/MyClass"),
|
||||
GoodFailOnConstraint.create(CheckCastArray.class, "array()", 3),
|
||||
BadFailOnConstraint.create(CheckCastArray.class, "arrayCopy(java.lang.Object[],java.lang.Class)", 1, "checkcast_arraycopy")
|
||||
Platform.isS390x() ? // There is no checkcast_arraycopy stub for C2 on s390
|
||||
GoodFailOnConstraint.create(CheckCastArray.class, "arrayCopy(java.lang.Object[],java.lang.Class)", 1)
|
||||
: BadFailOnConstraint.create(CheckCastArray.class, "arrayCopy(java.lang.Object[],java.lang.Class)", 1, "checkcast_arraycopy")
|
||||
);
|
||||
|
||||
// Redirect stdout to stream and then check if we find required IR encoding read from socket.
|
||||
@ -198,33 +223,54 @@ public class TestIRMatching {
|
||||
System.setOut(ps);
|
||||
|
||||
try {
|
||||
runWithArguments(CompilationOutputOfFails.class);
|
||||
runWithArgumentsFail(CompilationOutputOfFails.class);
|
||||
shouldNotReach();
|
||||
} catch (IRViolationException e) {
|
||||
System.out.flush();
|
||||
String output = baos.toString();
|
||||
baos.reset();
|
||||
Pattern pattern = Pattern.compile(">>> Compilation.*both\\d.*\\RPrintIdeal:(?:(?!PrintOpto|>>> Compilation)[\\S\\s])+PrintOptoAssembly");
|
||||
Matcher matcher = pattern.matcher(output);
|
||||
Asserts.assertEQ(matcher.results().count(), (long)7, "Could not find all both methods: " + output);
|
||||
pattern = Pattern.compile(">>> Compilation.*ideal\\d.*\\RPrintIdeal:(?:(?!>>> Compilation)[\\S\\s])+");
|
||||
matcher = pattern.matcher(output);
|
||||
int count = 0;
|
||||
while (matcher.find()) {
|
||||
String match = matcher.group();
|
||||
Asserts.assertFalse(match.contains("PrintOptoAssembly"), "Cannot contain opto assembly: " + output);
|
||||
count++;
|
||||
try {
|
||||
boolean failed = false;
|
||||
System.out.flush();
|
||||
String output = baos.toString();
|
||||
baos.reset();
|
||||
Pattern pattern = Pattern.compile(">>> Compilation.*both\\d.*\\RPrintIdeal:(?:(?!PrintOpto|>>> Compilation)[\\S\\s])+PrintOptoAssembly");
|
||||
Matcher matcher = pattern.matcher(output);
|
||||
long bothCount = matcher.results().count();
|
||||
if (bothCount != 7L) {
|
||||
exceptions.add(new RuntimeException("Could not find all both() methods, expected 7 but found " + bothCount));
|
||||
failed = true;
|
||||
}
|
||||
pattern = Pattern.compile(">>> Compilation.*ideal\\d.*\\RPrintIdeal:(?:(?!>>> Compilation)[\\S\\s])+");
|
||||
matcher = pattern.matcher(output);
|
||||
int count = 0;
|
||||
while (matcher.find()) {
|
||||
String match = matcher.group();
|
||||
Asserts.assertFalse(match.contains("PrintOptoAssembly"), "Cannot contain opto assembly: " + output);
|
||||
count++;
|
||||
}
|
||||
if (count != 7) {
|
||||
exceptions.add(new RuntimeException("Could not find all ideal() methods, expected 7 but found " + count));
|
||||
failed = true;
|
||||
}
|
||||
pattern = Pattern.compile(">>> Compilation.*opto\\d.*\\RPrintOptoAssembly:(?:(?!>>> Compilation)[\\S\\s])+");
|
||||
matcher = pattern.matcher(output);
|
||||
count = 0;
|
||||
while (matcher.find()) {
|
||||
String match = matcher.group();
|
||||
Asserts.assertFalse(match.contains("PrintIdeal"), "Cannot contain opto assembly: " + output);
|
||||
count++;
|
||||
}
|
||||
if (count != 7) {
|
||||
exceptions.add(new RuntimeException("Could not find all opto() methods, expected 7 but found " + count));
|
||||
failed = true;
|
||||
}
|
||||
if (failed) {
|
||||
System.err.println(TestFramework.getLastTestVMOutput());
|
||||
System.err.println(output);
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
addException(e1);
|
||||
}
|
||||
Asserts.assertEQ(count, 7, "Could not find all ideal methods: " + output);
|
||||
pattern = Pattern.compile(">>> Compilation.*opto\\d.*\\RPrintOptoAssembly:(?:(?!>>> Compilation)[\\S\\s])+");
|
||||
matcher = pattern.matcher(output);
|
||||
count = 0;
|
||||
while (matcher.find()) {
|
||||
String match = matcher.group();
|
||||
Asserts.assertFalse(match.contains("PrintIdeal"), "Cannot contain opto assembly: " + output);
|
||||
count++;
|
||||
}
|
||||
Asserts.assertEQ(count, 7, "Could not find all opto methods");
|
||||
} catch (Exception e) {
|
||||
addException(e);
|
||||
}
|
||||
|
||||
runWithArguments(FlagComparisons.class, "-XX:TLABRefillWasteFraction=50");
|
||||
@ -248,9 +294,27 @@ public class TestIRMatching {
|
||||
findIrIds(output, "testMatchAllIf50", 7, 12, 19, 21);
|
||||
findIrIds(output, "testMatchNoneIf50", 4, 7, 11, 16, 20, 22);
|
||||
System.setOut(old);
|
||||
|
||||
if (!exceptions.isEmpty()) {
|
||||
System.err.println("TestIRMatching failed with one or more exceptions:");
|
||||
for (Exception e : exceptions) {
|
||||
System.err.println(e.getMessage());
|
||||
e.printStackTrace(System.err);
|
||||
System.err.println("---------");
|
||||
}
|
||||
throw new RuntimeException("TestIRMatching failed with one or more exceptions - check stderr and stdout");
|
||||
}
|
||||
}
|
||||
|
||||
private static void runWithArguments(Class<?> clazz, String... args) {
|
||||
try {
|
||||
new TestFramework(clazz).addFlags(args).start();
|
||||
} catch (Exception e) {
|
||||
addException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void runWithArgumentsFail(Class<?> clazz, String... args) {
|
||||
new TestFramework(clazz).addFlags(args).start();
|
||||
}
|
||||
|
||||
@ -260,6 +324,8 @@ public class TestIRMatching {
|
||||
shouldNotReach();
|
||||
} catch (IRViolationException e) {
|
||||
checkConstraints(e, constraints);
|
||||
} catch (Exception e) {
|
||||
addException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,6 +335,8 @@ public class TestIRMatching {
|
||||
shouldNotReach();
|
||||
} catch (IRViolationException e) {
|
||||
checkConstraints(e, constraints);
|
||||
} catch (Exception e) {
|
||||
addException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,7 +349,7 @@ public class TestIRMatching {
|
||||
} catch (Exception e1) {
|
||||
System.out.println(TestFramework.getLastTestVMOutput());
|
||||
System.out.println(message);
|
||||
throw e1;
|
||||
exceptions.add(e1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -291,7 +359,13 @@ public class TestIRMatching {
|
||||
new TestFramework(constraint.getKlass()).addFlags(args).start(); // All constraints have the same class.
|
||||
shouldNotReach();
|
||||
} catch (IRViolationException e) {
|
||||
constraint.checkConstraint(e);
|
||||
try {
|
||||
constraint.checkConstraint(e);
|
||||
} catch (Exception e1) {
|
||||
addException(e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
addException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -393,7 +467,7 @@ class MultipleFailOnGood {
|
||||
class MultipleFailOnBad {
|
||||
private int iFld;
|
||||
private int myInt;
|
||||
private MyClass myClass;
|
||||
private MyClassEmpty myClass;
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.STORE, IRNode.CALL, IRNode.STORE_I, IRNode.LOOP})
|
||||
@ -426,21 +500,21 @@ class MultipleFailOnBad {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.STORE_OF_CLASS, "MyClass", IRNode.ALLOC, IRNode.CALL})
|
||||
@IR(failOn = {IRNode.STORE_OF_CLASS, "MyClassEmpty", IRNode.ALLOC, IRNode.CALL})
|
||||
public void fail6() {
|
||||
myClass = new MyClass();
|
||||
myClass = new MyClassEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "MyClass"})
|
||||
@IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "MyClassEmpty"})
|
||||
public void fail7() {
|
||||
myClass = new MyClass();
|
||||
myClass = new MyClassEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "ir_framework/tests/MyClassSub"})
|
||||
@IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "ir_framework/tests/MyClassEmptySub"})
|
||||
public void fail8() {
|
||||
myClass = new MyClassSub();
|
||||
myClass = new MyClassEmptySub();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -564,6 +638,7 @@ class GoodCount {
|
||||
|
||||
long result;
|
||||
MyClass myClass = new MyClass();
|
||||
MyClassEmpty myClassEmpty = new MyClassEmpty();
|
||||
MyClass myClassSubPoly = new MyClassSub();
|
||||
MyClassSub myClassSub = new MyClassSub();
|
||||
|
||||
@ -647,11 +722,11 @@ class GoodCount {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.STORE_OF_FIELD, "myClass", "1", IRNode.STORE_OF_CLASS, "GoodCount", "1",
|
||||
IRNode.STORE_OF_CLASS, "/GoodCount", "1", IRNode.STORE_OF_CLASS, "MyClass", "0"},
|
||||
failOn = {IRNode.STORE_OF_CLASS, "MyClass"})
|
||||
@IR(counts = {IRNode.STORE_OF_FIELD, "myClassEmpty", "1", IRNode.STORE_OF_CLASS, "GoodCount", "1",
|
||||
IRNode.STORE_OF_CLASS, "/GoodCount", "1", IRNode.STORE_OF_CLASS, "MyClassEmpty", "0"},
|
||||
failOn = {IRNode.STORE_OF_CLASS, "MyClassEmpty"})
|
||||
public void good6() {
|
||||
myClass = new MyClass();
|
||||
myClassEmpty = new MyClassEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -1122,7 +1197,7 @@ class CheckCastArray {
|
||||
public void testArrayCopy() {
|
||||
arrayCopy(mArr, MyClass[].class);
|
||||
arrayCopy(mArr, Object[].class);
|
||||
arrayCopy(mArr, MyClass2[].class);
|
||||
arrayCopy(mArr, MyClassEmpty[].class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1171,7 +1246,7 @@ class CompilationOutputOfFails {
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.COUNTEDLOOP, "0"})
|
||||
@IR(counts = {"call", "1"})
|
||||
@IR(counts = {"call", "0"})
|
||||
public void both6() {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
dontInline();
|
||||
@ -1180,7 +1255,7 @@ class CompilationOutputOfFails {
|
||||
|
||||
@Test
|
||||
@IR(failOn = IRNode.COUNTEDLOOP)
|
||||
@IR(counts = {"call", "1"})
|
||||
@IR(counts = {"call", "0"})
|
||||
public void both7() {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
dontInline();
|
||||
@ -1275,7 +1350,7 @@ class CompilationOutputOfFails {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {"call", "1"})
|
||||
@IR(counts = {"call", "0"})
|
||||
public void opto4() {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
dontInline();
|
||||
@ -1284,7 +1359,7 @@ class CompilationOutputOfFails {
|
||||
|
||||
@Test
|
||||
@IR(failOn = IRNode.STORE) // not fail
|
||||
@IR(counts = {"call", "1"})
|
||||
@IR(counts = {"call", "0"})
|
||||
public void opto5() {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
dontInline();
|
||||
@ -1293,7 +1368,7 @@ class CompilationOutputOfFails {
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.STORE, "0"}) // not fail
|
||||
@IR(counts = {"call", "1"})
|
||||
@IR(counts = {"call", "0"})
|
||||
public void opto6() {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
dontInline();
|
||||
@ -1302,7 +1377,7 @@ class CompilationOutputOfFails {
|
||||
|
||||
@Test
|
||||
@IR(counts = {"call", "10"})
|
||||
@IR(counts = {"call", "1"})
|
||||
@IR(counts = {"call", "0"})
|
||||
public void opto7() {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
dontInline();
|
||||
@ -1328,7 +1403,9 @@ class MyClass {
|
||||
static long lFldStatic;
|
||||
}
|
||||
|
||||
class MyClass2 {}
|
||||
class MyClassEmpty {}
|
||||
|
||||
class MyClassEmptySub extends MyClassEmpty {}
|
||||
|
||||
class MyClassSub extends MyClass {
|
||||
int iFld;
|
||||
@ -1375,7 +1452,7 @@ abstract class Constraint {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Constraint " + getClass().getSimpleName() + ", method: " + methodName + ", rule: " + ruleIdx;
|
||||
return "Constraint " + getClass().getSimpleName() + ", " + errorPrefix();
|
||||
}
|
||||
|
||||
public Class<?> getKlass() {
|
||||
@ -1383,7 +1460,7 @@ abstract class Constraint {
|
||||
}
|
||||
|
||||
protected String errorPrefix() {
|
||||
return "Method " + methodName + ", Rule " + ruleIdx;
|
||||
return "Class " + klass.getSimpleName() + ", Method " + methodName + ", Rule " + ruleIdx;
|
||||
}
|
||||
|
||||
public void checkConstraint(IRViolationException e) {
|
||||
@ -1405,8 +1482,6 @@ abstract class Constraint {
|
||||
}
|
||||
|
||||
abstract protected void checkIRRule(String irRule);
|
||||
|
||||
protected void checkOnMethod(String method) {}
|
||||
}
|
||||
|
||||
// Constraint for rule that does not fail.
|
||||
@ -1538,7 +1613,9 @@ abstract class RegexConstraint extends Constraint {
|
||||
for (int i = 1; i < splitRegex.length; i++) {
|
||||
String regexString = splitRegex[i];
|
||||
if (regexString.startsWith(String.valueOf(regexIndex))) {
|
||||
Asserts.assertTrue(matches.stream().allMatch(regexString::contains),
|
||||
// Do matching on actual match and not on regex string
|
||||
String actualMatch = regexString.split("\\R", 2)[1];
|
||||
Asserts.assertTrue(matches.stream().allMatch(actualMatch::contains),
|
||||
errorPrefix() + " could not find all matches at Regex " + regexIndex);
|
||||
matched = true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user