8300273: [IR framework] Handle <!-- safepoint while printing --> message instead of bailing out

Reviewed-by: thartmann, kvn
This commit is contained in:
Christian Hagedorn 2023-02-02 14:39:28 +00:00
parent 5b1584b92c
commit 59b7fb1a91
28 changed files with 1076 additions and 585 deletions

View File

@ -338,6 +338,7 @@ void CompileTask::log_task(xmlStream* log) {
void CompileTask::log_task_queued() { void CompileTask::log_task_queued() {
ttyLocker ttyl; ttyLocker ttyl;
ResourceMark rm; ResourceMark rm;
NoSafepointVerifier nsv;
xtty->begin_elem("task_queued"); xtty->begin_elem("task_queued");
log_task(xtty); log_task(xtty);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,7 +29,7 @@ import compiler.lib.ir_framework.driver.TestVMProcess;
import compiler.lib.ir_framework.driver.irmatching.IRMatcher; import compiler.lib.ir_framework.driver.irmatching.IRMatcher;
import compiler.lib.ir_framework.driver.irmatching.IRViolationException; import compiler.lib.ir_framework.driver.irmatching.IRViolationException;
import compiler.lib.ir_framework.driver.irmatching.Matchable; import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.parser.MethodCompilationParser; import compiler.lib.ir_framework.driver.irmatching.parser.TestClassParser;
import compiler.lib.ir_framework.shared.*; import compiler.lib.ir_framework.shared.*;
import compiler.lib.ir_framework.test.TestVM; import compiler.lib.ir_framework.test.TestVM;
import jdk.test.lib.Platform; import jdk.test.lib.Platform;
@ -747,8 +747,8 @@ public class TestFramework {
TestVMProcess testVMProcess = new TestVMProcess(additionalFlags, testClass, helperClasses, defaultWarmup); TestVMProcess testVMProcess = new TestVMProcess(additionalFlags, testClass, helperClasses, defaultWarmup);
if (shouldVerifyIR) { if (shouldVerifyIR) {
try { try {
MethodCompilationParser methodCompilationParser = new MethodCompilationParser(testClass); TestClassParser testClassParser = new TestClassParser(testClass);
Matchable testClassMatchable = methodCompilationParser.parse(testVMProcess.getHotspotPidFileName(), Matchable testClassMatchable = testClassParser.parse(testVMProcess.getHotspotPidFileName(),
testVMProcess.getIrEncoding()); testVMProcess.getIrEncoding());
IRMatcher matcher = new IRMatcher(testClassMatchable); IRMatcher matcher = new IRMatcher(testClassMatchable);
matcher.match(); matcher.match();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,18 +23,17 @@
package compiler.lib.ir_framework.driver.irmatching; package compiler.lib.ir_framework.driver.irmatching;
import compiler.lib.ir_framework.driver.irmatching.parser.MethodCompilationParser; import compiler.lib.ir_framework.driver.irmatching.parser.TestClassParser;
import compiler.lib.ir_framework.driver.irmatching.report.CompilationOutputBuilder; import compiler.lib.ir_framework.driver.irmatching.report.CompilationOutputBuilder;
import compiler.lib.ir_framework.driver.irmatching.report.FailureMessageBuilder; import compiler.lib.ir_framework.driver.irmatching.report.FailureMessageBuilder;
/** /**
* This class performs IR matching on the prepared {@link TestClass} object parsed by {@link MethodCompilationParser}. * This class performs IR matching on the prepared {@link TestClass} object parsed by {@link TestClassParser}.
* All applicable @IR rules are matched with all their defined compilation phases. If there are any IR matching failures, * All applicable @IR rules are matched with all their defined compilation phases. If there are any IR matching failures,
* an {@link IRViolationException} is reported which provides a formatted failure message and the compilation outputs * an {@link IRViolationException} is reported which provides a formatted failure message and the compilation outputs
* of the failed compilation phases. * of the failed compilation phases.
*/ */
public class IRMatcher { public class IRMatcher {
public static final String SAFEPOINT_WHILE_PRINTING_MESSAGE = "<!-- safepoint while printing -->";
private final Matchable testClass; private final Matchable testClass;
public IRMatcher(Matchable testClass) { public IRMatcher(Matchable testClass) {
@ -42,7 +41,7 @@ public class IRMatcher {
} }
/** /**
* Do an IR matching of all methods with applicable @IR rules prepared with by the {@link MethodCompilationParser}. * Do an IR matching of all methods with applicable @IR rules prepared with by the {@link TestClassParser}.
*/ */
public void match() { public void match() {
MatchResult result = testClass.match(); MatchResult result = testClass.match();
@ -59,19 +58,6 @@ public class IRMatcher {
private void reportFailures(MatchResult result) { private void reportFailures(MatchResult result) {
String failureMsg = new FailureMessageBuilder(result).build(); String failureMsg = new FailureMessageBuilder(result).build();
String compilationOutput = new CompilationOutputBuilder(result).build(); String compilationOutput = new CompilationOutputBuilder(result).build();
throwIfNoSafepointWhilePrinting(failureMsg, compilationOutput); throw new IRViolationException(failureMsg, compilationOutput);
}
/**
* In some very rare cases, the hotspot_pid* file to IR match on contains "<!-- safepoint while printing -->"
* (emitted by ttyLocker::break_tty_for_safepoint) which might be the reason for a matching error.
* Do not throw an exception in this case (i.e. bailout).
*/
private void throwIfNoSafepointWhilePrinting(String failures, String compilations) {
if (!compilations.contains(SAFEPOINT_WHILE_PRINTING_MESSAGE)) {
throw new IRViolationException(failures, compilations);
} else {
System.out.println("Found " + SAFEPOINT_WHILE_PRINTING_MESSAGE + ", bail out of IR matching");
}
} }
} }

View File

@ -1,88 +0,0 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.parser;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Base class of a read line from the hotspot_pid* file.
*/
abstract class AbstractLine {
private final BufferedReader reader;
protected String line;
private final Pattern compileIdPatternForTestClass;
public AbstractLine(BufferedReader reader, Pattern compileIdPatternForTestClass) {
this.reader = reader;
this.compileIdPatternForTestClass = compileIdPatternForTestClass;
}
public String getLine() {
return line;
}
/**
* Read next line and return it. If we've reached the end of the file, return NULL instead.
*/
public boolean readLine() throws IOException {
line = reader.readLine();
return line != null;
}
/**
* Is this line a start of a method in the test class? We only care about test class entries. There might be non-class
* entries as well if the user specified additional compile commands. Ignore these.
*/
public boolean isTestClassCompilation() {
if (isCompilation()) {
Matcher matcher = compileIdPatternForTestClass.matcher(line);
return matcher.find();
}
return false;
}
/**
* Is this header a C2 non-OSR compilation header entry?
*/
public boolean isCompilation() {
return line.startsWith("<task_queued") && notOSRCompilation() && notC2Compilation();
}
/**
* OSR compilations have compile_kind set.
*/
protected boolean notOSRCompilation() {
return !line.contains("compile_kind='");
}
/**
* Non-C2 compilations have level set.
*/
private boolean notC2Compilation() {
return !line.contains("level='");
}
}

View File

@ -1,73 +0,0 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.parser;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
/**
* Class to read all lines of a PrintIdeal or PrintOptoAssembly block.
*/
class BlockOutputReader {
private final BlockLine line;
public BlockOutputReader(BufferedReader reader, Pattern compileIdPatternForTestClass) {
this.line = new BlockLine(reader, compileIdPatternForTestClass);
}
/**
* Read all lines belonging to a PrintIdeal or PrintOptoAssembly output block.
*/
public Block readBlock() throws IOException {
StringBuilder builder = new StringBuilder();
List<String> testClassCompilations = new ArrayList<>();
while (line.readLine() && !line.isBlockEnd()) {
if (line.isTestClassCompilation()) {
// Could have safepointed while writing the block (see IRMatcher.SAFEPOINT_WHILE_PRINTING_MESSAGE)
// and enqueuing the next test class method for compilation during the interruption. Record this
// method to ensure that we read the PrintIdeal/PrintOptoAssembly blocks for that method later.
testClassCompilations.add(line.getLine());
}
builder.append(escapeXML(line.getLine())).append(System.lineSeparator());
}
return new Block(builder.toString(), testClassCompilations);
}
/**
* Need to escape XML special characters.
*/
private static String escapeXML(String line) {
if (line.contains("&")) {
line = line.replace("&lt;", "<");
line = line.replace("&gt;", ">");
line = line.replace("&quot;", "\"");
line = line.replace("&apos;", "'");
line = line.replace("&amp;", "&");
}
return line;
}
}

View File

@ -1,169 +0,0 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.parser;
import compiler.lib.ir_framework.TestFramework;
import compiler.lib.ir_framework.driver.irmatching.TestClass;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchable;
import compiler.lib.ir_framework.shared.TestFormat;
import compiler.lib.ir_framework.shared.TestFrameworkException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Class to parse the ideal compile phases and PrintOptoAssembly outputs of the test class from the hotspot_pid* file
* of all methods collected by {@link IREncodingParser}.
*
* @see IRMethod
* @see IREncodingParser
*/
class HotSpotPidFileParser {
private static final Pattern COMPILE_ID_PATTERN = Pattern.compile("compile_id='(\\d+)'");
private final Pattern compileIdPatternForTestClass;
/**
* "Method name" -> TestMethod map created by {@link IREncodingParser} which contains an entry for each method that
* needs to be IR matched on.
*/
private final Map<String, TestMethod> testMethodMap;
public HotSpotPidFileParser(String testClass, Map<String, TestMethod> testMethodMap) {
this.compileIdPatternForTestClass = Pattern.compile("compile_id='(\\d+)'.*" + Pattern.quote(testClass) + " (\\S+)");
this.testMethodMap = testMethodMap;
}
/**
* Parse the hotspot_pid*.log file from the test VM. Read the ideal compile phase and PrintOptoAssembly outputs for
* all methods defined by the IR encoding.
*/
public TestClass parse(String hotspotPidFileName) {
try {
parseHotSpotFile(hotspotPidFileName);
SortedSet<IRMethodMatchable> irMethods = testMethodMap.values().stream()
.map(TestMethod::createIRMethod)
.collect(Collectors.toCollection(TreeSet::new));
TestFormat.throwIfAnyFailures();
return new TestClass(irMethods);
} catch (IOException e) {
throw new TestFrameworkException("Error while reading " + hotspotPidFileName, e);
} catch (FileCorruptedException e) {
throw new TestFrameworkException("Unexpected format of " + hotspotPidFileName, e);
}
}
private void parseHotSpotFile(String hotspotPidFileName) throws IOException {
Map<Integer, TestMethod> compileIdMap = new HashMap<>();
try (var reader = Files.newBufferedReader(Paths.get(hotspotPidFileName))) {
Line line = new Line(reader, compileIdPatternForTestClass);
BlockOutputReader blockOutputReader = new BlockOutputReader(reader, compileIdPatternForTestClass);
while (line.readLine()) {
if (line.isTestClassCompilation()) {
parseTestMethodCompileId(compileIdMap, line.getLine());
} else if (isTestMethodBlockStart(line, compileIdMap)) {
processMethodBlock(compileIdMap, line, blockOutputReader);
}
}
}
}
private void processMethodBlock(Map<Integer, TestMethod> compileIdMap, Line line, BlockOutputReader blockOutputReader)
throws IOException {
Block block = blockOutputReader.readBlock();
if (block.containsTestClassCompilations()) {
// Register all test method compilations that could have been emitted during a rare safepoint while
// dumping the ideal compile phase/PrintOptoAssembly output.
block.getTestClassCompilations().forEach(l -> parseTestMethodCompileId(compileIdMap, l));
}
setIRMethodOutput(block.getOutput(), line, compileIdMap);
}
private void parseTestMethodCompileId(Map<Integer, TestMethod> compileIdMap, String line) {
String methodName = parseMethodName(line);
if (isTestAnnotatedMethod(methodName)) {
compileIdMap.put(getCompileId(line), getTestMethod(methodName));
}
}
private String parseMethodName(String line) {
Matcher matcher = compileIdPatternForTestClass.matcher(line);
TestFramework.check(matcher.find(), "must find match");
return matcher.group(2);
}
/**
* Is this a @Test method?
*/
private boolean isTestAnnotatedMethod(String testMethodName) {
return testMethodMap.containsKey(testMethodName);
}
private TestMethod getTestMethod(String testMethodName) {
TestMethod testMethod = testMethodMap.get(testMethodName);
testMethod.clearOutput();
testMethod.setCompiled();
return testMethod;
}
private int getCompileId(String line) {
Matcher matcher = COMPILE_ID_PATTERN.matcher(line);
if (!matcher.find()) {
throw new FileCorruptedException("Unexpected format found on this line: " + line);
}
return Integer.parseInt(matcher.group(1));
}
/**
* Is this line the start of a PrintIdeal/PrintOptoAssembly output block of a @Test method?
*/
private boolean isTestMethodBlockStart(Line line, Map<Integer, TestMethod> compileIdMap) {
return line.isBlockStart() && isTestClassMethodBlock(line, compileIdMap);
}
private boolean isTestClassMethodBlock(Line line, Map<Integer, TestMethod> compileIdMap) {
return compileIdMap.containsKey(getCompileId(line.getLine()));
}
private void setIRMethodOutput(String blockOutput, Line blockStartLine, Map<Integer, TestMethod> compileIdMap) {
TestMethod testMethod = compileIdMap.get(getCompileId(blockStartLine.getLine()));
setIRMethodOutput(blockOutput, blockStartLine, testMethod);
}
private void setIRMethodOutput(String blockOutput, Line blockStartLine, TestMethod testMethod) {
if (blockStartLine.isPrintIdealStart()) {
testMethod.setIdealOutput(blockOutput, blockStartLine.getCompilePhase());
} else {
testMethod.setOptoAssemblyOutput(blockOutput);
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,7 @@ package compiler.lib.ir_framework.driver.irmatching.parser;
import compiler.lib.ir_framework.IR; import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.TestFramework; import compiler.lib.ir_framework.TestFramework;
import compiler.lib.ir_framework.driver.irmatching.parser.hotspot.HotSpotPidFileParser;
import compiler.lib.ir_framework.shared.TestFormat; import compiler.lib.ir_framework.shared.TestFormat;
import compiler.lib.ir_framework.shared.TestFrameworkException; import compiler.lib.ir_framework.shared.TestFrameworkException;
import compiler.lib.ir_framework.test.IREncodingPrinter; import compiler.lib.ir_framework.test.IREncodingPrinter;
@ -40,25 +41,25 @@ import java.util.regex.Pattern;
* *
* @see TestMethod * @see TestMethod
*/ */
class IREncodingParser { public class IREncodingParser {
private static final boolean PRINT_IR_ENCODING = Boolean.parseBoolean(System.getProperty("PrintIREncoding", "false")); private static final boolean PRINT_IR_ENCODING = Boolean.parseBoolean(System.getProperty("PrintIREncoding", "false"));
private static final Pattern IR_ENCODING_PATTERN = private static final Pattern IR_ENCODING_PATTERN =
Pattern.compile("(?<=" + IREncodingPrinter.START + "\r?\n).*\\R([\\s\\S]*)(?=" + IREncodingPrinter.END + ")"); Pattern.compile("(?<=" + IREncodingPrinter.START + "\r?\n).*\\R([\\s\\S]*)(?=" + IREncodingPrinter.END + ")");
private final Map<String, TestMethod> testMethodMap; private final Map<String, TestMethod> testMethods;
private final Class<?> testClass; private final Class<?> testClass;
public IREncodingParser(Class<?> testClass) { public IREncodingParser(Class<?> testClass) {
this.testClass = testClass; this.testClass = testClass;
this.testMethodMap = new HashMap<>(); this.testMethods = new HashMap<>();
} }
/** /**
* Parse the IR encoding passed as parameter and return a "test name" -> TestMethod map that contains an entry * Parse the IR encoding passed as parameter and return a "test name" -> TestMethod map that contains an entry
* for each method that needs to be IR matched on. * for each method that needs to be IR matched on.
*/ */
public Map<String, TestMethod> parse(String irEncoding) { public TestMethods parse(String irEncoding) {
if (TestFramework.VERBOSE || PRINT_IR_ENCODING) { if (TestFramework.VERBOSE || PRINT_IR_ENCODING) {
System.out.println("Read IR encoding from test VM:"); System.out.println("Read IR encoding from test VM:");
System.out.println(irEncoding); System.out.println(irEncoding);
@ -66,7 +67,7 @@ class IREncodingParser {
createTestMethodMap(irEncoding, testClass); createTestMethodMap(irEncoding, testClass);
// We could have found format errors in @IR annotations. Report them now with an exception. // We could have found format errors in @IR annotations. Report them now with an exception.
TestFormat.throwIfAnyFailures(); TestFormat.throwIfAnyFailures();
return testMethodMap; return new TestMethods(testMethods);
} }
/** /**
@ -134,7 +135,7 @@ class IREncodingParser {
int[] irRuleIds = irRulesMap.get(m.getName()); int[] irRuleIds = irRulesMap.get(m.getName());
validateIRRuleIds(m, irAnnos, irRuleIds); validateIRRuleIds(m, irAnnos, irRuleIds);
if (hasAnyApplicableIRRules(irRuleIds)) { if (hasAnyApplicableIRRules(irRuleIds)) {
testMethodMap.put(m.getName(), new TestMethod(m, irRuleIds)); testMethods.put(m.getName(), new TestMethod(m, irAnnos, irRuleIds));
} }
} }
} }

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.parser;
import compiler.lib.ir_framework.driver.irmatching.Compilation;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchable;
import compiler.lib.ir_framework.driver.irmatching.irmethod.NotCompiledIRMethod;
import compiler.lib.ir_framework.driver.irmatching.parser.hotspot.HotSpotPidFileParser;
import compiler.lib.ir_framework.driver.irmatching.parser.hotspot.LoggedMethod;
import compiler.lib.ir_framework.driver.irmatching.parser.hotspot.LoggedMethods;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* Class to create {@link IRMethod} instances by combining the elements of {@link TestMethods} and {@link LoggedMethods}.
*/
class IRMethodBuilder {
private final Map<String, LoggedMethod> loggedMethods;
private final TestMethods testMethods;
public IRMethodBuilder(TestMethods testMethods, LoggedMethods loggedMethods) {
this.testMethods = testMethods;
this.loggedMethods = loggedMethods.loggedMethods();
}
/**
* Create IR methods for all test methods identified by {@link IREncodingParser} by combining them with the parsed
* compilation output from {@link HotSpotPidFileParser}.
*/
public SortedSet<IRMethodMatchable> build() {
SortedSet<IRMethodMatchable> irMethods = new TreeSet<>();
testMethods.testMethods().forEach(
(methodName, testMethod) -> irMethods.add(createIRMethod(methodName, testMethod)));
return irMethods;
}
private IRMethodMatchable createIRMethod(String methodName, TestMethod testMethod) {
LoggedMethod loggedMethod = loggedMethods.get(methodName);
if (loggedMethod != null) {
return new IRMethod(testMethod.method(), testMethod.irRuleIds(), testMethod.irAnnos(),
new Compilation(loggedMethod.compilationOutput()));
} else {
return new NotCompiledIRMethod(testMethod.method(), testMethod.irRuleIds().length);
}
}
}

View File

@ -1,71 +0,0 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.parser;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.TestFramework;
import java.io.BufferedReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Class representing a normal line read from the hotspot_pid* file.
*/
class Line extends AbstractLine {
private static final Pattern IDEAL_COMPILE_PHASE_PATTERN = Pattern.compile("<ideal.*compile_phase='(.*)'>");
public Line(BufferedReader reader, Pattern compileIdPatternForTestClass) {
super(reader, compileIdPatternForTestClass);
}
/**
* Is this line a start of a PrintIdeal or PrintOptoAssembly output block?
*/
public boolean isBlockStart() {
return isPrintIdealStart() || isPrintOptoAssemblyStart();
}
/**
* Is this line a start of a PrintIdeal output block?
*/
public boolean isPrintIdealStart() {
// Ignore OSR compilations which have compile_kind set.
return line.startsWith("<ideal") && notOSRCompilation();
}
/**
* Is this line a start of a PrintOptoAssembly output block?
*/
private boolean isPrintOptoAssemblyStart() {
// Ignore OSR compilations which have compile_kind set.
return line.startsWith("<opto_assembly") && notOSRCompilation();
}
public CompilePhase getCompilePhase() {
Matcher m = IDEAL_COMPILE_PHASE_PATTERN.matcher(line);
TestFramework.check(m.find(), "must always find \"compile_phase\" in ideal entry in " + line);
return CompilePhase.forName(m.group(1));
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,9 +25,14 @@ package compiler.lib.ir_framework.driver.irmatching.parser;
import compiler.lib.ir_framework.driver.irmatching.Matchable; import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.NonIRTestClass; import compiler.lib.ir_framework.driver.irmatching.NonIRTestClass;
import compiler.lib.ir_framework.driver.irmatching.TestClass;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod; import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchable;
import compiler.lib.ir_framework.driver.irmatching.parser.hotspot.HotSpotPidFileParser;
import compiler.lib.ir_framework.driver.irmatching.parser.hotspot.LoggedMethods;
import compiler.lib.ir_framework.shared.TestFormat;
import java.util.Map; import java.util.SortedSet;
/** /**
* Class to parse the ideal compile phase and PrintOptoAssembly outputs of the test class and store them into a * Class to parse the ideal compile phase and PrintOptoAssembly outputs of the test class and store them into a
@ -35,10 +40,10 @@ import java.util.Map;
* *
* @see IRMethod * @see IRMethod
*/ */
public class MethodCompilationParser { public class TestClassParser {
private final Class<?> testClass; private final Class<?> testClass;
public MethodCompilationParser(Class<?> testClass) { public TestClassParser(Class<?> testClass) {
this.testClass = testClass; this.testClass = testClass;
} }
@ -48,11 +53,25 @@ public class MethodCompilationParser {
*/ */
public Matchable parse(String hotspotPidFileName, String irEncoding) { public Matchable parse(String hotspotPidFileName, String irEncoding) {
IREncodingParser irEncodingParser = new IREncodingParser(testClass); IREncodingParser irEncodingParser = new IREncodingParser(testClass);
Map<String, TestMethod> testMethodMap = irEncodingParser.parse(irEncoding); TestMethods testMethods = irEncodingParser.parse(irEncoding);
if (!testMethodMap.isEmpty()) { if (testMethods.hasTestMethods()) {
HotSpotPidFileParser hotSpotPidFileParser = new HotSpotPidFileParser(testClass.getName(), testMethodMap); HotSpotPidFileParser hotSpotPidFileParser = new HotSpotPidFileParser(testClass.getName(), testMethods);
return hotSpotPidFileParser.parse(hotspotPidFileName); LoggedMethods loggedMethods = hotSpotPidFileParser.parse(hotspotPidFileName);
return createTestClass(testMethods, loggedMethods);
} }
return new NonIRTestClass(); return new NonIRTestClass();
} }
/**
* Create test class with IR methods for all test methods identified by {@link IREncodingParser} by combining them
* with the parsed compilation output from {@link HotSpotPidFileParser}.
*/
private Matchable createTestClass(TestMethods testMethods, LoggedMethods loggedMethods) {
IRMethodBuilder irMethodBuilder = new IRMethodBuilder(testMethods, loggedMethods);
SortedSet<IRMethodMatchable> irMethods = irMethodBuilder.build();
TestFormat.throwIfAnyFailures();
return new TestClass(irMethods);
} }
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,80 +23,40 @@
package compiler.lib.ir_framework.driver.irmatching.parser; package compiler.lib.ir_framework.driver.irmatching.parser;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR; import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.TestFramework;
import compiler.lib.ir_framework.driver.irmatching.Compilation;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod; import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchable; import compiler.lib.ir_framework.driver.irmatching.parser.hotspot.LoggedMethod;
import compiler.lib.ir_framework.driver.irmatching.irmethod.NotCompiledIRMethod;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;
/** /**
* This class represents a test method that is incrementally updated with new information parsed by {@link IREncodingParser} * This class represents a test method parsed by {@link IREncodingParser}. In combination with the associated
* and {@link HotSpotPidFileParser}. Once the parsers are finished, an {@link IRMethod} object can be fetched from the * {@link LoggedMethod}, a new {@link IRMethod} is created to IR match on later.
* collected data with {@link TestMethod#createIRMethod()}.
* *
* @see IREncodingParser * @see IREncodingParser
* @see HotSpotPidFileParser * @see LoggedMethod
* @see IRMethod * @see IRMethod
*/ */
public class TestMethod { public class TestMethod {
private final Method method; private final Method method;
private final IR[] irAnnos;
private final int[] irRuleIds; private final int[] irRuleIds;
private final Map<CompilePhase, String> compilationOutputMap;
private boolean compiled; // Was this method compiled (i.e. found in hotspot_pid* file?)
public TestMethod(Method m, int[] irRuleIds) { public TestMethod(Method m, IR[] irAnnos, int[] irRuleIds) {
this.method = m; this.method = m;
this.irAnnos = irAnnos;
this.irRuleIds = irRuleIds; this.irRuleIds = irRuleIds;
this.compilationOutputMap = new LinkedHashMap<>(); // Keep order of insertion
this.compiled = false;
} }
public void setCompiled() { public Method method() {
this.compiled = true; return method;
} }
public IRMethodMatchable createIRMethod() { public IR[] irAnnos() {
IR[] irAnnos = method.getAnnotationsByType(IR.class); return irAnnos;
TestFramework.check(irAnnos.length > 0, "must have at least one IR rule");
TestFramework.check(irRuleIds.length > 0, "must have at least one IR rule");
if (compiled) {
return new IRMethod(method, irRuleIds, irAnnos, new Compilation(compilationOutputMap));
} else {
return new NotCompiledIRMethod(method, irRuleIds.length);
}
} }
/** public int[] irRuleIds() {
* Clear the collected ideal and opto assembly output of all phases. This is necessary when having multiple return irRuleIds;
* compilations of the same method. We only want to keep the very last compilation which is the one requested by
* the framework.
*/
public void clearOutput() {
compilationOutputMap.clear();
}
/**
* We might parse multiple C2 compilations of this method. Only keep the very last one by overriding the outputMap.
*/
public void setIdealOutput(String idealOutput, CompilePhase compilePhase) {
String idealOutputWithHeader = "> Phase \"" + compilePhase.getName()+ "\":" + System.lineSeparator()
+ idealOutput;
if (!compilationOutputMap.containsKey(compilePhase) || compilePhase.overrideRepeatedPhase()) {
compilationOutputMap.put(compilePhase, idealOutputWithHeader);
}
}
/**
* We might parse multiple C2 compilations of this method. Only keep the very last one by overriding the outputMap.
*/
public void setOptoAssemblyOutput(String optoAssemblyOutput) {
optoAssemblyOutput = "> Phase \"PrintOptoAssembly\":" + System.lineSeparator() + optoAssemblyOutput;
compilationOutputMap.put(CompilePhase.PRINT_OPTO_ASSEMBLY, optoAssemblyOutput);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,11 +23,38 @@
package compiler.lib.ir_framework.driver.irmatching.parser; package compiler.lib.ir_framework.driver.irmatching.parser;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod;
import compiler.lib.ir_framework.driver.irmatching.parser.hotspot.HotSpotPidFileParser;
import java.util.Map;
/** /**
* Exception thrown when facing an unexpected format during parsing of the hotspot-pid* file * This class stores all test methods that need to be IR matched as identified by {@link IREncodingParser}.
*
* @see IREncodingParser
* @see HotSpotPidFileParser
* @see IRMethod
*/ */
class FileCorruptedException extends RuntimeException { public class TestMethods {
public FileCorruptedException(String s) { /**
super(s); * "Method name" -> TestMethod map created by {@link IREncodingParser} which contains an entry for each method that
* needs to be IR matched on.
*/
private final Map<String, TestMethod> testMethods;
public TestMethods(Map<String, TestMethod> testMethods) {
this.testMethods = testMethods;
}
public Map<String, TestMethod> testMethods() {
return testMethods;
}
public boolean isTestMethod(String method) {
return testMethods.containsKey(method);
}
public boolean hasTestMethods() {
return !testMethods.isEmpty();
} }
} }

View File

@ -0,0 +1,134 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.parser.hotspot;
import compiler.lib.ir_framework.CompilePhase;
/**
* This class represents a single compile phase block of a {@link LoggedMethod}.
*/
class CompilePhaseBlock {
public static final String SAFEPOINT_WHILE_PRINTING_MESSAGE = "<!-- safepoint while printing -->";
/**
* Dummy object for a block that we do not need to parse.
*/
public static final CompilePhaseBlock DONT_CARE = new CompilePhaseBlock(CompilePhase.DEFAULT);
private final CompilePhase compilePhase;
private final StringBuilder builder;
/**
* Stores an incomplete line that was interrupted by a safepoint.
* Needs to be merged with the immediately following line.
*/
private String incompleteLine = "";
public CompilePhaseBlock(CompilePhase compilePhase) {
this.compilePhase = compilePhase;
String blockHeader = "> Phase \"" + compilePhase.getName() + "\":" + System.lineSeparator();
this.builder = new StringBuilder(blockHeader);
}
public CompilePhase compilePhase() {
return compilePhase;
}
/**
* Is this line a start of an ideal or opto assembly output block?
*/
public static boolean isBlockStartLine(String line) {
return (isPrintIdealStart(line) || isPrintOptoAssemblyStart(line)) && notOSRCompilation(line);
}
/**
* Is this line a start of an ideal output block?
*/
public static boolean isPrintIdealStart(String line) {
// Ignore OSR compilations which have compile_kind set.
return line.startsWith("<ideal");
}
/**
* Is this line a start of an opto assembly output block?
*/
public static boolean isPrintOptoAssemblyStart(String line) {
// Ignore OSR compilations which have compile_kind set.
return line.startsWith("<opto_assembly");
}
/**
* OSR compilations have compile_kind set.
*/
private static boolean notOSRCompilation(String content) {
return !content.contains("compile_kind='");
}
/**
* Is this line an end of an ideal or opto assembly output block?
*/
public static boolean isBlockEndLine(String line) {
return line.startsWith("</ideal") || line.startsWith("</opto_assembly");
}
public void addLine(String line) {
line = mergeWithIncompleteLine(line);
if (line.endsWith(SAFEPOINT_WHILE_PRINTING_MESSAGE)) {
line = removeSafepointMessage(line);
incompleteLine = line;
} else {
appendLine(line);
}
}
private String mergeWithIncompleteLine(String line) {
if (!incompleteLine.isEmpty()) {
line = incompleteLine + line;
incompleteLine = "";
}
return line;
}
private static String removeSafepointMessage(String line) {
return line.substring(0, line.lastIndexOf(SAFEPOINT_WHILE_PRINTING_MESSAGE));
}
public String content() {
return builder.toString();
}
private void appendLine(String line) {
builder.append(escapeXML(line)).append(System.lineSeparator());
}
private static String escapeXML(String line) {
if (line.contains("&")) {
line = line.replace("&lt;", "<");
line = line.replace("&gt;", ">");
line = line.replace("&quot;", "\"");
line = line.replace("&apos;", "'");
line = line.replace("&amp;", "&");
}
return line;
}
}

View File

@ -0,0 +1,111 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.parser.hotspot;
import compiler.lib.ir_framework.TestFramework;
import compiler.lib.ir_framework.driver.irmatching.parser.IREncodingParser;
import compiler.lib.ir_framework.driver.irmatching.parser.TestMethods;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This class parses compile queue messages found in the hotspot_pid* files and keeps track of those that need to be
* IR matched (i.e. identified by {@link IREncodingParser}.
*
* @see IREncodingParser
*/
class CompileQueueMessages {
private static final Pattern COMPILE_ID_PATTERN = Pattern.compile("compile_id='(\\d+)'");
private final Pattern compileIdTestMethodPattern;
private final Pattern testMethodPattern;
private final TestMethods testMethods;
Map<Integer, String> compileIdToMethodName = new HashMap<>();
public CompileQueueMessages(String testClassName, TestMethods testMethods) {
this.compileIdTestMethodPattern = Pattern.compile("compile_id='(\\d+)'.*" + Pattern.quote(testClassName) + " (\\S+)");
this.testMethodPattern = Pattern.compile(Pattern.quote(testClassName) + " (\\S+)");
this.testMethods = testMethods;
}
public boolean isTestMethodQueuedLine(String line) {
return isCompilation(line) && isTestMethod(line);
}
/**
* Is this header a C2 non-OSR compilation header entry?
*/
private boolean isCompilation(String line) {
return line.startsWith("<task_queued") && notOSRCompilation(line) && notC2Compilation(line);
}
/**
* OSR compilations have compile_kind set.
*/
private boolean notOSRCompilation(String line) {
return !line.contains("compile_kind='");
}
/**
* Non-C2 compilations have level set.
*/
private boolean notC2Compilation(String line) {
return !line.contains("level='");
}
private boolean isTestMethod(String line) {
Matcher matcher = testMethodPattern.matcher(line);
if (matcher.find()) {
return testMethods.isTestMethod(matcher.group(1));
}
return false;
}
public String parse(String line) {
Matcher matcher = compileIdTestMethodPattern.matcher(line);
TestFramework.check(matcher.find(), "must find match on line: \"" + line + "\"");
int compileId = Integer.parseInt(matcher.group(1)); // parse from line
String methodName = matcher.group(2); // parse from line
compileIdToMethodName.put(compileId, methodName);
return methodName;
}
/**
* Return the method name associated with the compile id contained in this line if the method is IR matched.
* Otherwise, return an empty string.
*/
public String findTestMethodName(String line) {
int compileId = parseCompileId(line);
return compileIdToMethodName.getOrDefault(compileId, "");
}
private static int parseCompileId(String line) {
Matcher matcher = COMPILE_ID_PATTERN.matcher(line);
TestFramework.check(matcher.find(), "must find compile id on line: \"" + line + "\"");
return Integer.parseInt(matcher.group(1));
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.parser.hotspot;
import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethod;
import compiler.lib.ir_framework.driver.irmatching.parser.IREncodingParser;
import compiler.lib.ir_framework.driver.irmatching.parser.TestMethods;
import compiler.lib.ir_framework.shared.TestFrameworkException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
* Class to parse the ideal compile phases and PrintOptoAssembly outputs of the test class from the hotspot_pid* file
* of all methods identified by {@link IREncodingParser}.
*
* @see IRMethod
* @see IREncodingParser
*/
public class HotSpotPidFileParser {
private final State state;
public HotSpotPidFileParser(String testClass, TestMethods testMethods) {
this.state = new State(testClass, testMethods);
}
/**
* Parse the hotspot_pid*.log file from the test VM. Read the ideal compile phase and PrintOptoAssembly outputs for
* all methods defined by the IR encoding.
*/
public LoggedMethods parse(String hotspotPidFileName) {
try (var reader = Files.newBufferedReader(Paths.get(hotspotPidFileName))) {
String line;
while ((line = reader.readLine()) != null) {
state.update(line);
}
return state.loggedMethods();
} catch (IOException e) {
throw new TestFrameworkException("Error while reading " + hotspotPidFileName, e);
}
}
}

View File

@ -0,0 +1,92 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.parser.hotspot;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.TestFramework;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This class represents a currently parsed method in {@link HotSpotPidFileParser}. It stores all the different compile
* phase outputs.
*/
public class LoggedMethod {
/**
* Dummy object for methods that we do not need to parse.
*/
public static final LoggedMethod DONT_CARE = new LoggedMethod();
private static final Pattern IDEAL_COMPILE_PHASE_PATTERN = Pattern.compile("<ideal.*compile_phase='(.*)'>");
private final Map<CompilePhase, String> compilationOutput = new LinkedHashMap<>();
private CompilePhaseBlock compilePhaseBlock;
public LoggedMethod() {
this.compilePhaseBlock = CompilePhaseBlock.DONT_CARE;
}
public Map<CompilePhase, String> compilationOutput() {
return compilationOutput;
}
public boolean hasActiveBlock() {
return compilePhaseBlock != CompilePhaseBlock.DONT_CARE;
}
public void addLine(String line) {
if (hasActiveBlock()) {
compilePhaseBlock.addLine(line);
}
}
public void beginPrintIdealBlock(String line) {
Matcher matcher = IDEAL_COMPILE_PHASE_PATTERN.matcher(line);
TestFramework.check(matcher.find(), "must always find \"compile_phase\" in ideal entry in " + line);
CompilePhase compilePhase = CompilePhase.forName(matcher.group(1));
beginBlock(compilePhase);
}
public void beginPrintOptoAssemblyBlock() {
beginBlock(CompilePhase.PRINT_OPTO_ASSEMBLY);
}
private void beginBlock(CompilePhase compilePhase) {
if (compilationOutput.containsKey(compilePhase) && !compilePhase.overrideRepeatedPhase()) {
// We only want to keep the first compilation output for this phase.
compilePhaseBlock = CompilePhaseBlock.DONT_CARE;
} else {
compilePhaseBlock = new CompilePhaseBlock(compilePhase);
}
}
public void terminateBlock() {
if (hasActiveBlock()) {
compilationOutput.put(compilePhaseBlock.compilePhase(), compilePhaseBlock.content());
compilePhaseBlock = CompilePhaseBlock.DONT_CARE;
}
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.parser.hotspot;
import compiler.lib.ir_framework.TestFramework;
import java.util.HashMap;
import java.util.Map;
/**
* This class keeps track of all {@link LoggedMethod} instances.
*/
public class LoggedMethods {
private final Map<String, LoggedMethod> loggedMethods = new HashMap<>();
public Map<String, LoggedMethod> loggedMethods() {
return loggedMethods;
}
public LoggedMethod loggedMethod(String methodName) {
LoggedMethod loggedMethod = loggedMethods.get(methodName);
TestFramework.check(loggedMethod != null, "must exist");
return loggedMethod;
}
/**
* Always creates a new LoggedMethod to drop the already collected ideal and opto assembly outputs of the same method.
* We only want to keep the very last compilation of a method which is the one requested by the framework.
*/
public void registerMethod(String methodName) {
loggedMethods.put(methodName, new LoggedMethod());
}
}

View File

@ -0,0 +1,95 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.lib.ir_framework.driver.irmatching.parser.hotspot;
import compiler.lib.ir_framework.driver.irmatching.parser.TestMethods;
/**
* This class holds the current state of the parsing of the hotspot_pid* file.
*/
class State {
private final WriterThreads writerThreads;
private WriterThread writerThread;
private final CompileQueueMessages compileQueueMessages;
private final LoggedMethods loggedMethods;
private LoggedMethod loggedMethod = LoggedMethod.DONT_CARE;
public State(String testClassName, TestMethods testMethods) {
this.compileQueueMessages = new CompileQueueMessages(testClassName, testMethods);
this.loggedMethods = new LoggedMethods();
this.writerThreads = new WriterThreads();
}
public LoggedMethods loggedMethods() {
return loggedMethods;
}
public void update(String line) {
if (WriterThread.isWriterThreadLine(line)) {
processWriterThreadLine(line);
} else if (compileQueueMessages.isTestMethodQueuedLine(line)) {
processCompileQueueLine(line);
} else if (CompilePhaseBlock.isBlockStartLine(line)) {
processBlockStartLine(line);
} else if (CompilePhaseBlock.isBlockEndLine(line)) {
processBlockEndLine();
} else {
processNormalLine(line);
}
}
private void processWriterThreadLine(String line) {
if (loggedMethod.hasActiveBlock()) {
// The current compile phase block was interrupted due to a safepoint. Save and restore later.
writerThread.saveLoggedMethod(loggedMethod);
}
writerThread = writerThreads.parse(line);
loggedMethod = writerThread.restoreLoggedMethod();
}
private void processCompileQueueLine(String line) {
String methodName = compileQueueMessages.parse(line);
loggedMethods.registerMethod(methodName);
}
private void processBlockStartLine(String line) {
String methodName = compileQueueMessages.findTestMethodName(line);
if (!methodName.isEmpty()) {
loggedMethod = loggedMethods.loggedMethod(methodName);
if (CompilePhaseBlock.isPrintIdealStart(line)) {
loggedMethod.beginPrintIdealBlock(line);
} else {
loggedMethod.beginPrintOptoAssemblyBlock();
}
}
}
private void processBlockEndLine() {
loggedMethod.terminateBlock();
}
private void processNormalLine(String line) {
loggedMethod.addLine(line);
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -21,23 +21,31 @@
* questions. * questions.
*/ */
package compiler.lib.ir_framework.driver.irmatching.parser; package compiler.lib.ir_framework.driver.irmatching.parser.hotspot;
import java.util.List;
/** /**
* Class representing a PrintIdeal or PrintOptoAssembly output block read from the hotspot_pid* file. * This class represents a writer thread that emits log messages with LogCompilation. It saves and restores a currently
* parsed {@link LoggedMethod} if a {@link CompilePhaseBlock} was interrupted before reaching the block end tag.
*
* @see LoggedMethod
* @see CompilePhaseBlock
*/ */
record Block(String output, List<String> testClassCompilations) { class WriterThread {
public String getOutput() { private LoggedMethod loggedMethod = LoggedMethod.DONT_CARE;
return output;
public static boolean isWriterThreadLine(String line) {
return line.startsWith("<writer");
} }
public boolean containsTestClassCompilations() { public void saveLoggedMethod(LoggedMethod loggedMethod) {
return !testClassCompilations.isEmpty(); this.loggedMethod = loggedMethod;
} }
public List<String> getTestClassCompilations() { public LoggedMethod restoreLoggedMethod() {
return testClassCompilations; LoggedMethod restoredLoggedMethod = loggedMethod;
if (restoredLoggedMethod != LoggedMethod.DONT_CARE) {
loggedMethod = LoggedMethod.DONT_CARE;
}
return restoredLoggedMethod;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -21,24 +21,30 @@
* questions. * questions.
*/ */
package compiler.lib.ir_framework.driver.irmatching.parser; package compiler.lib.ir_framework.driver.irmatching.parser.hotspot;
import java.io.BufferedReader; import compiler.lib.ir_framework.TestFramework;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* Class representing a block line inside a PrintIdeal or PrintOptoAssembly output block read from the hotspot_pid* file. * This class keeps track of all {@link WriterThread} instances.
*/ */
class BlockLine extends AbstractLine { class WriterThreads {
private final Map<Integer, WriterThread> mapIdToThread = new HashMap<>();
public BlockLine(BufferedReader reader, Pattern compileIdPatternForTestClass) { WriterThread parse(String line) {
super(reader, compileIdPatternForTestClass); int writerThreadId = parseWriterThreadId(line);
return mapIdToThread.computeIfAbsent(writerThreadId, c -> new WriterThread());
} }
/** private static int parseWriterThreadId(String line) {
* Is this line an end of a PrintIdeal or PrintOptoAssembly output block? Pattern pattern = Pattern.compile("='(\\d+)'");
*/ Matcher matcher = pattern.matcher(line);
public boolean isBlockEnd() { TestFramework.check(matcher.find(), "should find writer thread id");
return line.startsWith("</"); return Integer.parseInt(matcher.group(1));
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -51,7 +51,7 @@ public class TestCheckedTests {
TestFramework.run(); TestFramework.run();
try { try {
TestFramework.run(BadIRAndRuntimeCheckedTests.class); TestFramework.run(BadIRAndRuntimeCheckedTests.class);
Utils.shouldHaveThrownException(baos.toString()); Asserts.fail("Should have thrown exception");
} catch (TestVMException e) { } catch (TestVMException e) {
System.setOut(oldOut); System.setOut(oldOut);
Asserts.assertTrue(e.getExceptionInfo().contains("Test Failures (2)")); Asserts.assertTrue(e.getExceptionInfo().contains("Test Failures (2)"));
@ -64,7 +64,7 @@ public class TestCheckedTests {
System.setOut(ps); System.setOut(ps);
try { try {
TestFramework.run(BadIRCheckedTests.class); TestFramework.run(BadIRCheckedTests.class);
Utils.shouldHaveThrownException(baos.toString()); Asserts.fail("Should have thrown exception");
} catch (IRViolationException e) { } catch (IRViolationException e) {
System.setOut(oldOut); System.setOut(oldOut);
Asserts.assertTrue(e.getExceptionInfo().contains("Failed IR Rules (3)")); Asserts.assertTrue(e.getExceptionInfo().contains("Failed IR Rules (3)"));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -233,7 +233,7 @@ public class TestIRMatching {
try { try {
runWithArgumentsFail(CompilationOutputOfFails.class); runWithArgumentsFail(CompilationOutputOfFails.class);
Utils.shouldHaveThrownException(baos.toString()); Asserts.fail("Should have thrown exception");
} catch (IRViolationException e) { } catch (IRViolationException e) {
try { try {
StringBuilder failures = new StringBuilder(); StringBuilder failures = new StringBuilder();
@ -365,7 +365,7 @@ public class TestIRMatching {
framework.addFlags(args); framework.addFlags(args);
} }
runFramework(framework); runFramework(framework);
Utils.shouldHaveThrownException(baos.toString()); Asserts.fail("Should have thrown exception");
} catch (IRViolationException e) { } catch (IRViolationException e) {
checkConstraints(e, constraints); checkConstraints(e, constraints);
} catch (Exception e) { } catch (Exception e) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -31,7 +31,7 @@ import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.CheckAttributeType; import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.CheckAttributeType;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.CountsConstraintFailure; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.CountsConstraintFailure;
import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.FailOnConstraintFailure; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.FailOnConstraintFailure;
import compiler.lib.ir_framework.driver.irmatching.parser.MethodCompilationParser; import compiler.lib.ir_framework.driver.irmatching.parser.TestClassParser;
import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren; import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren;
import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor; import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor;
import jdk.test.lib.Asserts; import jdk.test.lib.Asserts;
@ -67,8 +67,8 @@ public class TestPhaseIRMatching {
FlagVMProcess flagVMProcess = new FlagVMProcess(testClass, noAdditionalFlags); FlagVMProcess flagVMProcess = new FlagVMProcess(testClass, noAdditionalFlags);
List<String> testVMFlags = flagVMProcess.getTestVMFlags(); List<String> testVMFlags = flagVMProcess.getTestVMFlags();
TestVMProcess testVMProcess = new TestVMProcess(testVMFlags, testClass, null, -1); TestVMProcess testVMProcess = new TestVMProcess(testVMFlags, testClass, null, -1);
MethodCompilationParser methodCompilationParser = new MethodCompilationParser(testClass); TestClassParser testClassParser = new TestClassParser(testClass);
Matchable testClassMatchable = methodCompilationParser.parse(testVMProcess.getHotspotPidFileName(), Matchable testClassMatchable = testClassParser.parse(testVMProcess.getHotspotPidFileName(),
testVMProcess.getIrEncoding()); testVMProcess.getIrEncoding());
MatchResult result = testClassMatchable.match(); MatchResult result = testClassMatchable.match();
List<Failure> expectedFails = new ExpectedFailsBuilder().build(testClass); List<Failure> expectedFails = new ExpectedFailsBuilder().build(testClass);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -51,7 +51,7 @@ public class TestRunTests {
TestFramework.run(); TestFramework.run();
try { try {
TestFramework.run(BadStandalone.class); TestFramework.run(BadStandalone.class);
Utils.shouldHaveThrownException(baos.toString()); Asserts.fail("Should have thrown exception");
} catch (IRViolationException e) { } catch (IRViolationException e) {
System.setOut(oldOut); System.setOut(oldOut);
String[] matches = { "test(int)", "test2(int)", "Failed IR Rules (2)"}; String[] matches = { "test(int)", "test2(int)", "Failed IR Rules (2)"};

View File

@ -0,0 +1,143 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.testlibrary_tests.ir_framework.tests;
import compiler.lib.ir_framework.CompilePhase;
import compiler.lib.ir_framework.IR;
import compiler.lib.ir_framework.IRNode;
import compiler.lib.ir_framework.Test;
import compiler.lib.ir_framework.driver.irmatching.IRMatcher;
import compiler.lib.ir_framework.driver.irmatching.Matchable;
import compiler.lib.ir_framework.driver.irmatching.parser.TestClassParser;
import jdk.test.lib.Utils;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
/*
* @test
* @bug 8300273
* @requires vm.debug == true & vm.flagless
* @summary Test TestClassParser such that it correctly parses the hotspot_pid* files with safepoint interruption messages
* @library /test/lib /testlibrary_tests /
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run junit/othervm -Xbootclasspath/a:. -DSkipWhiteBoxInstall=true -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting
*/
public class TestSafepointWhilePrinting {
static int iFld;
@org.junit.Test
public void test() throws IOException {
String hotspotPidFileName = "safepoint_while_printing_hotspot_pid.log";
Path hotspotPidFilePath = Paths.get(Utils.TEST_SRC).resolve(hotspotPidFileName);
// Copy file to current workdir
Files.copy(hotspotPidFilePath, Paths.get("").resolve(hotspotPidFileName),
StandardCopyOption.REPLACE_EXISTING);
String irEncoding =
"""
##### IRMatchRulesEncoding - used by TestFramework #####
<method>,{comma separated applied @IR rule ids}
test1,1
test2,1
testSafepointInBlock,1
testQueueInBlock1,1
testQueueInBlock2,1
testDoubleInterruptOuter,1
testDoubleInterruptMiddle,1
testDoubleInterruptInner,1
testCompilePhaseBackToBackFirst,1
testCompilePhaseBackToBackLast,1
----- END -----
""";
TestClassParser testClassParser = new TestClassParser(TestSafepointWhilePrinting.class);
Matchable testClassMatchable = testClassParser.parse(hotspotPidFileName, irEncoding);
IRMatcher matcher = new IRMatcher(testClassMatchable);
matcher.match();
}
@Test
@IR(counts = {IRNode.CMP_UL3, "1"})
public void test1() {
iFld = 34;
}
@Test
@IR(counts = {IRNode.CMP_UL3, "1"})
public void test2() {
iFld = 34;
}
@Test
@IR(counts = {"testSafepointInBlock @ bci:-1", "1"}, phase = CompilePhase.PRINT_IDEAL)
public void testSafepointInBlock() {
iFld = 34;
}
@Test
@IR(counts = {"testQueueInBlock1 @ bci:-1", "1"}, phase = CompilePhase.PRINT_IDEAL)
public void testQueueInBlock1() {
iFld = 34;
}
@Test
@IR(counts = {"testQueueInBlock2 @ bci:-1", "1"}, phase = CompilePhase.PRINT_IDEAL)
public void testQueueInBlock2() {
iFld = 34;
}
@Test
@IR(counts = {"!jvms: TestSafepointWhilePrinting::testDoubleInterruptOuter", "1"}, phase = CompilePhase.PRINT_IDEAL)
public void testDoubleInterruptOuter() {
iFld = 34;
}
@Test
@IR(counts = {"testDoubleInterruptMiddle @ bci:-1", "1", IRNode.CMP_UL3, "1"}, phase = CompilePhase.PRINT_IDEAL)
public void testDoubleInterruptMiddle() {
iFld = 34;
}
@Test
@IR(counts = {IRNode.CON_L, "1"}, phase = CompilePhase.PRINT_IDEAL)
public void testDoubleInterruptInner() {
iFld = 34;
}
@Test
@IR(counts = {"(line 115)", "1", IRNode.CMP_UL3, "1"}, phase = {CompilePhase.AFTER_PARSING, CompilePhase.BEFORE_MATCHING})
public void testCompilePhaseBackToBackFirst() {
iFld = 34;
}
@Test
@IR(counts = {"(line 115)", "1", IRNode.CMP_UL3, "1"}, phase = {CompilePhase.AFTER_PARSING, CompilePhase.BEFORE_MATCHING})
public void testCompilePhaseBackToBackLast() {
iFld = 34;
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -52,20 +52,20 @@ public class TestScenarios {
Scenario s3dup = new Scenario(3, "-XX:TLABRefillWasteFraction=53"); Scenario s3dup = new Scenario(3, "-XX:TLABRefillWasteFraction=53");
try { try {
new TestFramework().addScenarios(sDefault, s1, s2, s3).start(); new TestFramework().addScenarios(sDefault, s1, s2, s3).start();
Utils.shouldHaveThrownException(baos.toString()); Asserts.fail("Should have thrown exception");
} catch (TestRunException e) { } catch (TestRunException e) {
if (!e.getMessage().contains("The following scenarios have failed: #0, #1, #3")) { if (!e.getMessage().contains("The following scenarios have failed: #0, #1, #3")) {
Utils.throwIfNoSafepointPrinting(baos.toString(), e); throw e;
} }
} }
baos.reset(); baos.reset();
try { try {
new TestFramework().addScenarios(s1, s2, s3).start(); new TestFramework().addScenarios(s1, s2, s3).start();
Utils.shouldHaveThrownException(baos.toString()); Asserts.fail("Should have thrown exception");
} catch (TestRunException e) { } catch (TestRunException e) {
if (!e.getMessage().contains("The following scenarios have failed: #1, #3")) { if (!e.getMessage().contains("The following scenarios have failed: #1, #3")) {
Utils.throwIfNoSafepointPrinting(baos.toString(), e); throw e;
} }
} }
System.setOut(oldOut); System.setOut(oldOut);

View File

@ -1,43 +0,0 @@
/*
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package ir_framework.tests;
import compiler.lib.ir_framework.driver.irmatching.IRMatcher;
import jdk.test.lib.Asserts;
public class Utils {
public static void shouldHaveThrownException(String output) {
// Do not throw an exception if we hit a safepoint while printing which could possibly let the IR matching fail.
// This happens very rarely. If there is a problem with the test, then we will catch that on the next test invocation.
if (!output.contains(IRMatcher.SAFEPOINT_WHILE_PRINTING_MESSAGE)) {
Asserts.fail("Should have thrown exception");
}
}
public static void throwIfNoSafepointPrinting(String output, RuntimeException e) {
if (!output.contains(IRMatcher.SAFEPOINT_WHILE_PRINTING_MESSAGE)) {
throw e;
}
}
}

View File

@ -0,0 +1,163 @@
<writer thread='1683653'/>
1682 967 b 3 jdk.test.lib.Asserts::assertEquals (7 bytes)
<nmethod compile_id='967' compiler='c1' level='3' entry='0x00007f29791d6440' size='912' address='0x00007f29791d6290' relocation_offset='352' insts_offset='432' stub_offset='648' scopes_data_offset='768' scopes_pcs_offset='808' dependencies_offset='904' oops_offset='752' metadata_offset='760' method='jdk.test.lib.Asserts assertEquals (Ljava/lang/Object;Ljava/lang/Object;)V' bytes='7' count='256' iicount='256' stamp='1.683'/>
<writer thread='1683665'/>
<task_queued compile_id='1013' method='compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting test2 (J)I' bytes='8' count='1000' iicount='1000' blocking='1' stamp='1.715' comment='whitebox' hot_count='1000'/>
<writer thread='1683661'/>
<task_queued compile_id='1008' method='java.util.Arrays copyOfRange ([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;' bytes='90' count='257' iicount='257' level='3' blocking='1' stamp='1.714' comment='tiered' hot_count='256'/>
<writer thread='1683666'/>
<task_queued compile_id='1018' method='compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting test1 (J)I' bytes='8' count='1000' iicount='1000' blocking='1' stamp='1.715' comment='whitebox' hot_count='1000'/>
<writer thread='1683670'/>
<make_not_entrant thread='1683670' compile_id='995' compiler='c1' level='3' stamp='1.716'/>
1716 995 3 compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting::compareLongWithImm5 (8 bytes) made not entrant
<writer thread='1683652'/>
1716 1018 b 4 compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting::test1 (8 bytes)
<writer thread='1683665'/>
<task_queued compile_id='53' method='compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting testSafepointInBlock (J)I' bytes='8' count='1000' iicount='1000' blocking='1' stamp='1.715' comment='whitebox' hot_count='1000'/>
<writer thread='1683653'/>
1716 1008 b 3 java.util.Arrays::copyOfRange (90 bytes)
<writer thread='1683670'/>
1716 1013 b 4 compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting::test2 (8 bytes)
<writer thread='1683663'/>
<task_queued compile_id='1019' method='compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting notATest (I)I' bytes='7' count='1000' iicount='1000' blocking='1' stamp='1.716' comment='whitebox' hot_count='1000'/>
<writer thread='1683652'/>
<ideal compile_id='1018' compile_phase='print_ideal'>
AFTER: print_ideal
0 Root === 0 26 [[ 0 1 3 24 ]] inner
3 Start === 3 0 [[ 3 5 6 7 8 9 11 ]] #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:compiler/intrinsics/TestSafepointWhilePrinting:NotNull *, 6:long, 7:half}
5 Parm === 3 [[ 26 ]] Control !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
6 Parm === 3 [[ 26 ]] I_O !jvms:<!-- safepoint while printing -->
<writer thread='1683670'/>
<ideal compile_id='1013' compile_phase='print_ideal'>
AFTER: print_ideal
0 Root === 0 26 [[ 0 1 3 24 ]] inner
3 Start === 3 0 [[ 3 5 6 7 8 9 11 ]] #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:compiler/intrinsics/TestSafepointWhilePrinting:NotNull *, 6:long, 7:half}
5 Parm === 3 [[ 26 ]] Control !jvms: TestSafepointWhilePrinting::test2 @ bci:-1 (line 109)
6 Parm === 3 [[ 26 ]] I_O !jvms: TestSafepointWhilePrinting::test2 @ bci:-1 (line 109)
7 Parm === 3 [[ 26 ]] Memory Memory: @BotPTR *+bot, idx=Bot; !jvms: TestSafepointWhilePrinting::test2 @ bci:-1 (line 109)
8 Parm === 3 [[ 26 ]] FramePtr !jvms: TestSafepointWhilePrinting::test2 @ bci:-1 (line 109)
9 Parm === 3 [[ 26 ]] ReturnAdr !jvms: TestSafepointWhilePrinting::test2 @ bci:-1 (line 109)
11 Parm === 3 [[ 25 ]] Parm1: long !jvms: TestSafepointWhilePrinting::test2 @ bci:-1 (line 109)
24 ConL === 0 [[ 25 ]] #long:42
25 CmpUL3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test2 @ bci:4 (line 109)
26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
</ideal>
<writer thread='1683652'/>
TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
7 Parm === 3 [[ 26 ]] Memory Memory: @BotPTR *+bot, idx=Bot; !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
8 Parm === 3 [[ 26 ]] FramePtr !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
9 Parm === 3 [[ 26 ]] ReturnAdr !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
11 Parm === 3 [[ 25 ]] Parm1: long !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
24 ConL === 0 [[ 25 ]] #long:172032
25 CmpUL3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test1 @ bci:4 (line 115)
26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
</ideal>
<writer thread='1875264'/>
<nmethod compile_id='1017' compiler='c2' level='4' entry='0x00007fa74cc08ea0' size='664' address='0x00007fa74cc08d10' relocation_offset='352' insts_offset='400' stub_offset='536' scopes_data_offset='576'
scopes_pcs_offset='592' dependencies_offset='656' oops_offset='560' metadata_offset='568' method='compiler.intrinsics.TestCompareUnsigned compareLongWithImm3 (J)I' bytes='8' count='1000' iicount='1000'
stamp='1.785'/>
<make_not_entrant thread='1875264' compile_id='993' compiler='c1' level='3' stamp='1.785'/>
1784 993 3 compiler.intrinsics.TestCompareUnsigned::compareLongWithImm3 (8 bytes) made not entrant
1784 1013 b 4 compiler.intrinsics.TestCompareUnsigned::compareLongWithImm1 (8 bytes)
<ideal compile_id='53' compile_phase='print_ideal'>
AFTER: print_ideal
0 Root === 0 26 [[ 0 1 3 24 ]] inner
8 Parm === 3 [[ 26 ]] FramePtr !jvms: TestSafepointWhilePrinting::testSafepointInBlock<!-- safepoint while printing -->
@ bci:-1 (line 109)
24 ConL === 0 [[ 25 ]] #long:42
26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
</ideal>
<writer thread='5165446'/>
<task_queued compile_id='54' method='compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting testQueueInBlock1 (J)I' bytes='8' count='1000' iicount='1000' blocking='1' stamp='1.715' comment='whitebox' hot_count='1000'/>
<writer thread='234'/>
<ideal compile_id='54' compile_phase='print_ideal'>
AFTER: print_ideal
0 Root === 0 26 [[ 0 1 3 24 ]] inner
8 Parm === 3 [[ 26 ]] FramePtr !jvms: TestSafepointWhilePrinting::testQueueInBlock1<!-- safepoint while printing -->
<writer thread='235'/>
<task_queued compile_id='55' method='compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting testQueueInBlock2 (J)I' bytes='8' count='1000' iicount='1000' blocking='1' stamp='1.715' comment='whitebox' hot_count='1000'/>
<writer thread='234'/>
@ bci:-1 (line 109)
24 ConL === 0 [[ 25 ]] #long:42
26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
</ideal>
<ideal compile_id='55' compile_phase='print_ideal'>
AFTER: print_ideal
0 Root === 0 26 [[ 0 1 3 24 ]] inner
8 Parm === 3 [[ 26 ]] FramePtr !jvms: TestSafepointWhilePrinting::testQueueInBlock2<!-- safepoint while printing -->
@ bci:-1 (line 109)
24 ConL === 0 [[ 25 ]] #long:42
26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
</ideal>
<writer thread='343523525'/>
<task_queued compile_id='61' method='compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting testDoubleInterruptOuter (J)I' bytes='8' count='1000' iicount='1000' blocking='1' stamp='1.715' comment='whitebox' hot_count='1000'/>
<writer thread='343523525'/>
<task_queued compile_id='62' method='compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting testDoubleInterruptMiddle (J)I' bytes='8' count='1000' iicount='1000' blocking='1' stamp='1.715' comment='whitebox' hot_count='1000'/>
<writer thread='1001'/>
<ideal compile_id='61' compile_phase='print_ideal'>
AFTER: print_ideal
0 Root === 0 26 [[ 0 1 3 24 ]] inner
3 Start === 3 0 [[ 3 5 6 7 8 9 11 ]] #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:compiler/intrinsics/TestSafepointWhilePrinting:NotNull *, 6:long, 7:half}
6 Parm === 3 [[ 26 ]] I_O !jvms:<!-- safepoint while printing -->
<writer thread='1002'/>
<ideal compile_id='62' compile_phase='print_ideal'>
AFTER: print_ideal
0 Root === 0 26 [[ 0 1 3 24 ]] inner
8 Parm === 3 [[ 26 ]] FramePtr !jvms: TestSafepointWhilePrinting::testDoubleInterruptMiddle<!-- safepoint while printing -->
@ bci:-1 (line 109)
25 Cmp<!-- safepoint while printing -->
<writer thread='9999'/>
<task_queued compile_id='63' method='compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting testDoubleInterruptInner (J)I' bytes='8' count='1000' iicount='1000' blocking='1' stamp='1.715' comment='whitebox' hot_count='1000'/>
<writer thread='1003'/>
<ideal compile_id='63' compile_phase='print_ideal'>
24 ConL === 0 [[ 25 ]] #long:42
26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
</ideal>
<writer thread='1002'/>
UL3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test2 @ bci:4 (line 109)
26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
</ideal>
<writer thread='1001'/>
TestSafepointWhilePrinting::testDoubleInterruptOuter @ bci:-1 (line 115)
7 Parm === 3 [[ 26 ]] Memory Memory: @BotPTR *+bot, idx=Bot; !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
8 Parm === 3 [[ 26 ]] FramePtr !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
9 Parm === 3 [[ 26 ]] ReturnAdr !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
11 Parm === 3 [[ 25 ]] Parm1: long !jvms: TestSafepointWhilePrinting::test1 @ bci:-1 (line 115)
24 ConL === 0 [[ 25 ]] #long:172032
25 CmpUL3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test1 @ bci:4 (line 115)
26 Return === 5 6 7 8 9 returns 25 [[ 0 ]]
</ideal>
<writer thread='100000'/>
<task_queued compile_id='72' method='compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting testCompilePhaseBackToBackFirst (J)I' bytes='8' count='1000' iicount='1000' blocking='1' stamp='1.715' comment='whitebox' hot_count='1000'/>
<writer thread='72'/>
<ideal compile_id='72' compile_phase='AFTER_PARSING'>
24 ConL === 0 [[ 25 ]] #long:172032
25 CmpUL<!-- safepoint while printing -->
<writer thread='71'/>
<task_queued compile_id='71' method='compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting testCompilePhaseBackToBackLast (J)I' bytes='8' count='1000' iicount='1000' blocking='1' stamp='1.715' comment='whitebox' hot_count='1000'/>
<ideal compile_id='71' compile_phase='AFTER_PARSING'>
24 ConL === 0 [[ 25 ]] #long:172032
25 CmpUL3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test1 @ bci:4 (line 115)
</ideal>
<ideal compile_id='71' compile_phase='BEFORE_MATCHING'>
24 ConL === 0 [[ 25 ]] #long:172032
25 CmpU<!-- safepoint while printing -->
<writer thread='72'/>
3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test1 @ bci:4 (<!-- safepoint while printing -->
<writer thread='71'/>
L3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test1 @ bci:4 (line <!-- safepoint while printing -->
<writer thread='72'/>
line 115)
</ideal>
<writer thread='9999'/>
<task_queued compile_id='3333' method='compiler.testlibrary_tests.ir_framework.tests.TestSafepointWhilePrinting asdf (J)I' bytes='8' count='1000' iicount='1000' blocking='1' stamp='1.715' comment='whitebox' hot_count='1000'/>
<writer thread='72'/>
<ideal compile_id='72' compile_phase='BEFORE_MATCHING'>
24 ConL === 0 [[ 25 ]] #long:172032
25 CmpU<!-- safepoint while printing -->
<writer thread='71'/>
115)
</ideal>
<writer thread='72'/>
L3 === _ 11 24 [[ 26 ]] !jvms: TestSafepointWhilePrinting::test1 @ bci:4 (line 115)
</ideal>