mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-29 08:05:14 +00:00
8378257: [IR Framework] Add identity for socket connection and prepare for parsing C2 dumps
Reviewed-by: dfenacci, thartmann, mhaessig
This commit is contained in:
parent
102302ba87
commit
455707c3dc
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2026, 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.network.testvm;
|
||||
|
||||
import compiler.lib.ir_framework.driver.network.testvm.java.JavaMessage;
|
||||
import compiler.lib.ir_framework.shared.TestFrameworkSocket;
|
||||
|
||||
/**
|
||||
* We currently have only one type of Test VM message sent to the {@link TestFrameworkSocket}:
|
||||
* - {@link JavaMessage}: A message sent from Java code.
|
||||
*
|
||||
* <p>
|
||||
* Later, we will add C2 messages as well as second type with JDK-8375270.
|
||||
* Both kinds of messages are parsed differently by classes implementing this interface.
|
||||
*/
|
||||
public interface TestVmMessageParser<Output> {
|
||||
/**
|
||||
* Parse a single line of a received Test VM message.
|
||||
*
|
||||
* @param line A single message line forwarded by {@link TestVmMessageReader}.
|
||||
*/
|
||||
void parseLine(String line);
|
||||
|
||||
/**
|
||||
* Once parsing is done, this method returns the final output.
|
||||
*/
|
||||
Output output();
|
||||
}
|
||||
@ -23,8 +23,6 @@
|
||||
|
||||
package compiler.lib.ir_framework.driver.network.testvm;
|
||||
|
||||
import compiler.lib.ir_framework.driver.network.testvm.java.JavaMessageParser;
|
||||
import compiler.lib.ir_framework.driver.network.testvm.java.JavaMessages;
|
||||
import compiler.lib.ir_framework.shared.TestFrameworkException;
|
||||
import compiler.lib.ir_framework.shared.TestFrameworkSocket;
|
||||
|
||||
@ -35,23 +33,23 @@ import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* Dedicated reader for Test VM messages received by the {@link TestFrameworkSocket}. The reader is used as a task
|
||||
* wrapped in a {@link Future}. The received messages are parsed with the {@link JavaMessageParser}. Once the Test VM
|
||||
* is terminated, client connection is closed and the parsed messages can be fetched with {@link Future#get()} which
|
||||
* calls {@link #call()}.
|
||||
* wrapped in a {@link Future}. The received messages are parsed with the provided {@link TestVmMessageParser}. Once the
|
||||
* Test VM is terminated, client connection is closed and the parsed messages can be fetched with {@link Future#get()}
|
||||
* which calls {@link #call()}.
|
||||
*/
|
||||
public class TestVmMessageReader implements Callable<JavaMessages> {
|
||||
public class TestVmMessageReader<Output> implements Callable<Output> {
|
||||
private final Socket socket;
|
||||
private final BufferedReader reader;
|
||||
private final JavaMessageParser messageParser;
|
||||
private final BufferedReader reader; // identity already consumed
|
||||
private final TestVmMessageParser<Output> messageParser;
|
||||
|
||||
public TestVmMessageReader(Socket socket, BufferedReader reader) {
|
||||
public TestVmMessageReader(Socket socket, BufferedReader reader, TestVmMessageParser<Output> messageParser) {
|
||||
this.socket = socket;
|
||||
this.reader = reader;
|
||||
this.messageParser = new JavaMessageParser();
|
||||
this.messageParser = messageParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaMessages call() {
|
||||
public Output call() {
|
||||
try (socket; reader) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
@ -63,3 +61,4 @@ public class TestVmMessageReader implements Callable<JavaMessages> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
package compiler.lib.ir_framework.driver.network.testvm.java;
|
||||
|
||||
import compiler.lib.ir_framework.TestFramework;
|
||||
import compiler.lib.ir_framework.driver.network.testvm.TestVmMessageParser;
|
||||
import compiler.lib.ir_framework.driver.network.testvm.java.multiline.ApplicableIRRulesStrategy;
|
||||
import compiler.lib.ir_framework.driver.network.testvm.java.multiline.MultiLineParser;
|
||||
import compiler.lib.ir_framework.driver.network.testvm.java.multiline.VMInfoStrategy;
|
||||
@ -40,7 +41,7 @@ import static compiler.lib.ir_framework.test.network.MessageTag.*;
|
||||
* Dedicated parser for {@link JavaMessages} received from the Test VM. Depending on the parsed {@link MessageTag}, the
|
||||
* message is parsed differently.
|
||||
*/
|
||||
public class JavaMessageParser {
|
||||
public class JavaMessageParser implements TestVmMessageParser<JavaMessages> {
|
||||
private static final Pattern TAG_PATTERN = Pattern.compile("^(\\[[^]]+])\\s*(.*)$");
|
||||
|
||||
private final List<String> stdoutMessages;
|
||||
@ -60,6 +61,7 @@ public class JavaMessageParser {
|
||||
this.currentMultiLineParser = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseLine(String line) {
|
||||
line = line.trim();
|
||||
Matcher tagLineMatcher = TAG_PATTERN.matcher(line);
|
||||
@ -118,6 +120,7 @@ public class JavaMessageParser {
|
||||
currentMultiLineParser = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaMessages output() {
|
||||
return new JavaMessages(new StdoutMessages(stdoutMessages),
|
||||
new ExecutedTests(executedTests),
|
||||
|
||||
@ -26,7 +26,9 @@ package compiler.lib.ir_framework.shared;
|
||||
import compiler.lib.ir_framework.TestFramework;
|
||||
import compiler.lib.ir_framework.driver.network.*;
|
||||
import compiler.lib.ir_framework.driver.network.testvm.TestVmMessageReader;
|
||||
import compiler.lib.ir_framework.driver.network.testvm.java.JavaMessageParser;
|
||||
import compiler.lib.ir_framework.driver.network.testvm.java.JavaMessages;
|
||||
import compiler.lib.ir_framework.test.network.TestVmSocket;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@ -116,20 +118,46 @@ public class TestFrameworkSocket implements AutoCloseable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept new client connection and then submit a task accordingly to manage incoming message on that connection/socket.
|
||||
* Accept new client connection by first reading the identity of the connection (either coming from Java or C2)
|
||||
* and then submitting a task accordingly to manage incoming messages on that connection/socket.
|
||||
*/
|
||||
private void acceptNewClientConnection() throws IOException {
|
||||
Socket client = serverSocket.accept();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
|
||||
submitTask(client, reader);
|
||||
try {
|
||||
String identity = readIdentity(client, reader).trim();
|
||||
submitTask(identity, client, reader);
|
||||
} catch (Exception e) {
|
||||
client.close();
|
||||
reader.close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private String readIdentity(Socket client, BufferedReader reader) throws IOException {
|
||||
String identity;
|
||||
try {
|
||||
client.setSoTimeout(10000);
|
||||
identity = reader.readLine();
|
||||
TestFramework.check(identity != null, "end of stream has been reached without reading the identity");
|
||||
} catch (SocketTimeoutException e) {
|
||||
throw new TestFrameworkException("Did not receive initial identity message after 10s", e);
|
||||
} finally {
|
||||
client.setSoTimeout(0);
|
||||
}
|
||||
return identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit dedicated tasks which are wrapped into {@link Future} objects. The tasks will read all messages sent
|
||||
* over that connection.
|
||||
*/
|
||||
private void submitTask(Socket client, BufferedReader reader) {
|
||||
javaFuture = clientExecutor.submit(new TestVmMessageReader(client, reader));
|
||||
private void submitTask(String identity, Socket client, BufferedReader reader) {
|
||||
if (identity.equals(TestVmSocket.IDENTITY)) {
|
||||
javaFuture = clientExecutor.submit(new TestVmMessageReader<>(client, reader, new JavaMessageParser()));
|
||||
} else {
|
||||
throw new TestFrameworkException("Unrecognized identity: " + identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -33,6 +33,8 @@ import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
|
||||
public class TestVmSocket {
|
||||
public static final String IDENTITY = "#TestVM-Java#";
|
||||
|
||||
private static final boolean REPRODUCE = Boolean.getBoolean("Reproduce");
|
||||
private static final String SERVER_PORT_PROPERTY = "ir.framework.server.port";
|
||||
private static final int SERVER_PORT = Integer.getInteger(SERVER_PORT_PROPERTY, -1);
|
||||
@ -88,6 +90,7 @@ public class TestVmSocket {
|
||||
// Keep the client socket open until the test VM terminates (calls closeClientSocket before exiting main()).
|
||||
socket = new Socket(InetAddress.getLoopbackAddress(), SERVER_PORT);
|
||||
writer = new PrintWriter(socket.getOutputStream(), true);
|
||||
writer.println(IDENTITY);
|
||||
} catch (Exception e) {
|
||||
// When the test VM is directly run, we should ignore all messages that would normally be sent to the
|
||||
// driver VM.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user