8284115: [IR Framework] Compilation is not found due to rare safepoint while dumping PrintIdeal/PrintOptoAssembly
Reviewed-by: kvn, thartmann
This commit is contained in:
parent
b434b1f233
commit
3984253800
@ -25,6 +25,8 @@ 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.
|
||||
@ -32,9 +34,11 @@ import java.io.IOException;
|
||||
abstract class AbstractLine {
|
||||
private final BufferedReader reader;
|
||||
protected String line;
|
||||
private final Pattern compileIdPatternForTestClass;
|
||||
|
||||
public AbstractLine(BufferedReader reader) {
|
||||
public AbstractLine(BufferedReader reader, Pattern compileIdPatternForTestClass) {
|
||||
this.reader = reader;
|
||||
this.compileIdPatternForTestClass = compileIdPatternForTestClass;
|
||||
}
|
||||
|
||||
public String getLine() {
|
||||
@ -48,4 +52,37 @@ abstract class AbstractLine {
|
||||
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='");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.util.List;
|
||||
|
||||
/**
|
||||
* Class representing a PrintIdeal or PrintOptoAssembly output block read from the hotspot_pid* file.
|
||||
*/
|
||||
record Block(String output, List<String> testClassCompilations) {
|
||||
public String getOutput() {
|
||||
return output;
|
||||
}
|
||||
|
||||
public boolean containsTestClassCompilations() {
|
||||
return !testClassCompilations.isEmpty();
|
||||
}
|
||||
|
||||
public List<String> getTestClassCompilations() {
|
||||
return testClassCompilations;
|
||||
}
|
||||
}
|
@ -24,14 +24,15 @@
|
||||
package compiler.lib.ir_framework.driver.irmatching.parser;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Class representing a block line inside a PrintIdeal or PrintOptoAssembly output block read from the hotspot_pid* file.
|
||||
*/
|
||||
class BlockLine extends AbstractLine {
|
||||
|
||||
public BlockLine(BufferedReader reader) {
|
||||
super(reader);
|
||||
public BlockLine(BufferedReader reader, Pattern compileIdPatternForTestClass) {
|
||||
super(reader, compileIdPatternForTestClass);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,27 +25,36 @@ 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 BufferedReader reader;
|
||||
private final BlockLine line;
|
||||
|
||||
public BlockOutputReader(BufferedReader reader) {
|
||||
this.reader = reader;
|
||||
public BlockOutputReader(BufferedReader reader, Pattern compileIdPatternForTestClass) {
|
||||
this.line = new BlockLine(reader, compileIdPatternForTestClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all lines belonging to a PrintIdeal or PrintOptoAssembly output block.
|
||||
*/
|
||||
public String readBlock() throws IOException {
|
||||
BlockLine line = new BlockLine(reader);
|
||||
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 builder.toString();
|
||||
return new Block(builder.toString(), testClassCompilations);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,6 +56,7 @@ class HotSpotPidFileParser {
|
||||
public void setCompilationsMap(Map<String, IRMethod> compilationsMap) {
|
||||
this.compilationsMap = compilationsMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the hotspot_pid*.log file from the test VM. Read the PrintIdeal and PrintOptoAssembly outputs for all
|
||||
* methods of the test class that need to be IR matched (found in compilations map).
|
||||
@ -75,18 +76,28 @@ class HotSpotPidFileParser {
|
||||
Map<Integer, IRMethod> compileIdMap = new HashMap<>();
|
||||
try (var reader = Files.newBufferedReader(Paths.get(hotspotPidFileName))) {
|
||||
Line line = new Line(reader, compileIdPatternForTestClass);
|
||||
BlockOutputReader blockOutputReader = new BlockOutputReader(reader);
|
||||
BlockOutputReader blockOutputReader = new BlockOutputReader(reader, compileIdPatternForTestClass);
|
||||
while (line.readLine()) {
|
||||
if (line.isTestClassCompilation()) {
|
||||
parseTestMethodCompileId(compileIdMap, line.getLine());
|
||||
} else if (isTestMethodBlockStart(line, compileIdMap)) {
|
||||
String blockOutput = blockOutputReader.readBlock();
|
||||
setIRMethodOutput(blockOutput, line, compileIdMap);
|
||||
processMethodBlock(compileIdMap, line, blockOutputReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processMethodBlock(Map<Integer, IRMethod> 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 PrintIdeal/PrintOptoAssembly output.
|
||||
block.getTestClassCompilations().forEach(l -> parseTestMethodCompileId(compileIdMap, l));
|
||||
}
|
||||
setIRMethodOutput(block.getOutput(), line, compileIdMap);
|
||||
}
|
||||
|
||||
private void parseTestMethodCompileId(Map<Integer, IRMethod> compileIdMap, String line) {
|
||||
String methodName = parseMethodName(line);
|
||||
if (isTestAnnotatedMethod(methodName)) {
|
||||
@ -101,6 +112,9 @@ class HotSpotPidFileParser {
|
||||
return matcher.group(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a @Test method?
|
||||
*/
|
||||
private boolean isTestAnnotatedMethod(String testMethodName) {
|
||||
return compilationsMap.containsKey(testMethodName);
|
||||
}
|
||||
@ -109,8 +123,6 @@ class HotSpotPidFileParser {
|
||||
return compilationsMap.get(testMethodName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private int getCompileId(String line) {
|
||||
Matcher matcher = COMPILE_ID_PATTERN.matcher(line);
|
||||
if (!matcher.find()) {
|
||||
@ -119,6 +131,9 @@ class HotSpotPidFileParser {
|
||||
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, IRMethod> compileIdMap) {
|
||||
return line.isBlockStart() && isTestClassMethodBlock(line, compileIdMap);
|
||||
}
|
||||
|
@ -31,44 +31,8 @@ import java.util.regex.Pattern;
|
||||
* Class representing a normal line read from the hotspot_pid* file.
|
||||
*/
|
||||
class Line extends AbstractLine {
|
||||
private final Pattern compileIdPatternForTestClass;
|
||||
|
||||
public Line(BufferedReader reader, Pattern compileIdPatternForTestClass) {
|
||||
super(reader);
|
||||
this.compileIdPatternForTestClass = compileIdPatternForTestClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this line a start of a @Test annotated method? We only care about test class entries. There might be non-class
|
||||
* entries as well if 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.
|
||||
*/
|
||||
private boolean notOSRCompilation() {
|
||||
return !line.contains("compile_kind='");
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-C2 compilations have level set.
|
||||
*/
|
||||
private boolean notC2Compilation() {
|
||||
return !line.contains("level='");
|
||||
super(reader, compileIdPatternForTestClass);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user