From 455707c3dca6d388fa2cfd869b68dfe928a476fd Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 27 Apr 2026 12:47:06 +0000 Subject: [PATCH] 8378257: [IR Framework] Add identity for socket connection and prepare for parsing C2 dumps Reviewed-by: dfenacci, thartmann, mhaessig --- .../network/testvm/TestVmMessageParser.java | 49 +++++++++++++++++++ .../network/testvm/TestVmMessageReader.java | 21 ++++---- .../testvm/java/JavaMessageParser.java | 5 +- .../shared/TestFrameworkSocket.java | 36 ++++++++++++-- .../test/network/TestVmSocket.java | 3 ++ 5 files changed, 98 insertions(+), 16 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/TestVmMessageParser.java diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/TestVmMessageParser.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/TestVmMessageParser.java new file mode 100644 index 00000000000..fa68b638a9f --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/TestVmMessageParser.java @@ -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. + * + *

+ * 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 { + /** + * 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(); +} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/TestVmMessageReader.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/TestVmMessageReader.java index a203fd367f7..992f95660a3 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/TestVmMessageReader.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/TestVmMessageReader.java @@ -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 { +public class TestVmMessageReader implements Callable { private final Socket socket; - private final BufferedReader reader; - private final JavaMessageParser messageParser; + private final BufferedReader reader; // identity already consumed + private final TestVmMessageParser messageParser; - public TestVmMessageReader(Socket socket, BufferedReader reader) { + public TestVmMessageReader(Socket socket, BufferedReader reader, TestVmMessageParser 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 { } } } + diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/JavaMessageParser.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/JavaMessageParser.java index d419a06c8de..5b0c624720a 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/JavaMessageParser.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/JavaMessageParser.java @@ -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 { private static final Pattern TAG_PATTERN = Pattern.compile("^(\\[[^]]+])\\s*(.*)$"); private final List 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), diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFrameworkSocket.java b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFrameworkSocket.java index 44063a4bd43..05359d0d789 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFrameworkSocket.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFrameworkSocket.java @@ -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 diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/test/network/TestVmSocket.java b/test/hotspot/jtreg/compiler/lib/ir_framework/test/network/TestVmSocket.java index 37e59b9dcae..afb65b43338 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/test/network/TestVmSocket.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/test/network/TestVmSocket.java @@ -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.