From db49e8d083118709c01eb00e659bbab8f98e95e2 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 23 Mar 2026 07:11:33 +0000 Subject: [PATCH] 8378243: [IR Framework] Create separate VMInfo and ApplicableIRRules JavaMessage classes Reviewed-by: mchevalier, dfenacci, thartmann --- .../compiler/lib/ir_framework/IRNode.java | 2 +- .../driver/irmatching/irmethod/IRMethod.java | 2 +- .../driver/irmatching/irrule/IRRule.java | 2 +- .../checkattribute/parsing/RawIRNode.java | 6 +- .../irrule/constraint/raw/RawConstraint.java | 4 +- .../constraint/raw/RawCountsConstraint.java | 3 +- .../constraint/raw/RawFailOnConstraint.java | 2 +- .../phase/CompilePhaseIRRuleBuilder.java | 2 +- .../DefaultPhaseRawConstraintParser.java | 6 +- .../parser/ApplicableIRRulesParser.java | 75 ++-------------- .../irmatching/parser/IRMethodBuilder.java | 1 + .../irmatching/parser/TestClassParser.java | 20 +++-- .../irmatching/parser/VMInfoParser.java | 67 -------------- .../driver/network/TestVMData.java | 6 +- .../testvm/java/ApplicableIRRules.java | 81 +++++++++++++++++ .../driver/network/testvm/java/IRRuleIds.java | 4 + .../testvm/java/JavaMessageParser.java | 33 +++---- .../network/testvm/java/JavaMessages.java | 24 ++--- .../testvm/java}/VMInfo.java | 87 ++++++++++--------- .../multiline/ApplicableIRRulesStrategy.java | 78 +++++++++++++++++ .../java/multiline/MultiLineParser.java | 67 ++++++++++++++ .../multiline/MultiLineParsingStrategy.java | 32 +++++++ .../testvm/java/multiline/VMInfoStrategy.java | 57 ++++++++++++ .../test/ApplicableIRRulesPrinter.java | 25 +++--- .../ir_framework/tests/TestIRMatching.java | 15 +++- 25 files changed, 453 insertions(+), 248 deletions(-) delete mode 100644 test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/VMInfoParser.java create mode 100644 test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/ApplicableIRRules.java rename test/hotspot/jtreg/compiler/lib/ir_framework/driver/{irmatching/parser => network/testvm/java}/VMInfo.java (74%) create mode 100644 test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/ApplicableIRRulesStrategy.java create mode 100644 test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/MultiLineParser.java create mode 100644 test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/MultiLineParsingStrategy.java create mode 100644 test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/VMInfoStrategy.java diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index 1c59a03b4b0..ebc95527344 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -24,7 +24,7 @@ package compiler.lib.ir_framework; import compiler.lib.ir_framework.driver.irmatching.mapping.*; -import compiler.lib.ir_framework.driver.irmatching.parser.VMInfo; +import compiler.lib.ir_framework.driver.network.testvm.java.VMInfo; import compiler.lib.ir_framework.shared.CheckedTestFrameworkException; import compiler.lib.ir_framework.shared.TestFormat; import compiler.lib.ir_framework.shared.TestFormatException; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethod.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethod.java index 5fbe90f0e72..137766b0011 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethod.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethod.java @@ -31,8 +31,8 @@ import compiler.lib.ir_framework.driver.irmatching.MatchResult; import compiler.lib.ir_framework.driver.irmatching.Matchable; import compiler.lib.ir_framework.driver.irmatching.MatchableMatcher; import compiler.lib.ir_framework.driver.irmatching.irrule.IRRule; -import compiler.lib.ir_framework.driver.irmatching.parser.VMInfo; import compiler.lib.ir_framework.driver.network.testvm.java.IRRuleIds; +import compiler.lib.ir_framework.driver.network.testvm.java.VMInfo; import compiler.lib.ir_framework.shared.TestFormat; import compiler.lib.ir_framework.shared.TestFormatException; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/IRRule.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/IRRule.java index 749942eabd6..5c48394851b 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/IRRule.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/IRRule.java @@ -31,7 +31,7 @@ import compiler.lib.ir_framework.driver.irmatching.Matchable; import compiler.lib.ir_framework.driver.irmatching.MatchableMatcher; import compiler.lib.ir_framework.driver.irmatching.irrule.phase.CompilePhaseIRRule; import compiler.lib.ir_framework.driver.irmatching.irrule.phase.CompilePhaseIRRuleBuilder; -import compiler.lib.ir_framework.driver.irmatching.parser.VMInfo; +import compiler.lib.ir_framework.driver.network.testvm.java.VMInfo; /** * This class represents a generic {@link IR @IR} rule of an IR method. It contains a list of compile phase specific diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/checkattribute/parsing/RawIRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/checkattribute/parsing/RawIRNode.java index b86ae47e186..d8be8add2a2 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/checkattribute/parsing/RawIRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/checkattribute/parsing/RawIRNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -25,10 +25,10 @@ package compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsin import compiler.lib.ir_framework.CompilePhase; import compiler.lib.ir_framework.IRNode; +import compiler.lib.ir_framework.driver.SuccessOnlyConstraintException; +import compiler.lib.ir_framework.driver.network.testvm.java.VMInfo; import compiler.lib.ir_framework.shared.Comparison; import compiler.lib.ir_framework.shared.TestFormat; -import compiler.lib.ir_framework.driver.irmatching.parser.VMInfo; -import compiler.lib.ir_framework.driver.SuccessOnlyConstraintException; import java.util.regex.Matcher; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/raw/RawConstraint.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/raw/RawConstraint.java index 1c2fba218db..174136c7c28 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/raw/RawConstraint.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/raw/RawConstraint.java @@ -27,12 +27,12 @@ import compiler.lib.ir_framework.CompilePhase; import compiler.lib.ir_framework.IR; import compiler.lib.ir_framework.IRNode; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.Constraint; -import compiler.lib.ir_framework.driver.irmatching.parser.VMInfo; +import compiler.lib.ir_framework.driver.network.testvm.java.VMInfo; /** * Interface to represent a single raw constraint as found in the {@link IR @IR} annotation (i.e. {@link IRNode} * placeholder strings are not replaced by regexes, yet). A raw constraint can be parsed into a {@link Constraint} by - * calling {@link #parse(CompilePhase, String)}. This replaces the IR node placeholder strings by actual regexes and + * calling {@link #parse(CompilePhase, String, VMInfo)}. This replaces the IR node placeholder strings by actual regexes and * merges composite nodes together. * * @see Constraint diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/raw/RawCountsConstraint.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/raw/RawCountsConstraint.java index 9934a830a06..a616f1a0455 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/raw/RawCountsConstraint.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/raw/RawCountsConstraint.java @@ -26,12 +26,11 @@ package compiler.lib.ir_framework.driver.irmatching.irrule.constraint.raw; import compiler.lib.ir_framework.CompilePhase; import compiler.lib.ir_framework.IR; -import compiler.lib.ir_framework.IRNode; import compiler.lib.ir_framework.TestFramework; import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawIRNode; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.Constraint; -import compiler.lib.ir_framework.driver.irmatching.parser.VMInfo; import compiler.lib.ir_framework.driver.SuccessOnlyConstraintException; +import compiler.lib.ir_framework.driver.network.testvm.java.VMInfo; import compiler.lib.ir_framework.shared.Comparison; import compiler.lib.ir_framework.shared.TestFormat; import compiler.lib.ir_framework.shared.TestFormatException; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/raw/RawFailOnConstraint.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/raw/RawFailOnConstraint.java index 4bd334f1f08..6bd3f8f3448 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/raw/RawFailOnConstraint.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/raw/RawFailOnConstraint.java @@ -29,7 +29,7 @@ import compiler.lib.ir_framework.TestFramework; import compiler.lib.ir_framework.driver.SuccessOnlyConstraintException; import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawIRNode; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.Constraint; -import compiler.lib.ir_framework.driver.irmatching.parser.VMInfo; +import compiler.lib.ir_framework.driver.network.testvm.java.VMInfo; import compiler.lib.ir_framework.shared.Comparison; /** diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/phase/CompilePhaseIRRuleBuilder.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/phase/CompilePhaseIRRuleBuilder.java index 5d327135c22..4d46a53c46b 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/phase/CompilePhaseIRRuleBuilder.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/phase/CompilePhaseIRRuleBuilder.java @@ -34,7 +34,7 @@ import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.parsing.RawFailOn; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.Constraint; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.raw.RawConstraint; -import compiler.lib.ir_framework.driver.irmatching.parser.VMInfo; +import compiler.lib.ir_framework.driver.network.testvm.java.VMInfo; import compiler.lib.ir_framework.shared.TestFormat; import java.util.*; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/phase/DefaultPhaseRawConstraintParser.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/phase/DefaultPhaseRawConstraintParser.java index 1f837883978..5f8f597a4fe 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/phase/DefaultPhaseRawConstraintParser.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/phase/DefaultPhaseRawConstraintParser.java @@ -31,7 +31,7 @@ import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.Counts; import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.FailOn; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.Constraint; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.raw.RawConstraint; -import compiler.lib.ir_framework.driver.irmatching.parser.VMInfo; +import compiler.lib.ir_framework.driver.network.testvm.java.VMInfo; import compiler.lib.ir_framework.shared.TestFrameworkException; import java.util.ArrayList; @@ -71,7 +71,7 @@ class DefaultPhaseRawConstraintParser { for (RawConstraint rawConstraint : rawConstraints) { CompilePhase compilePhase = rawConstraint.defaultCompilePhase(); List checkAttribute = - matchableForCompilePhase.computeIfAbsent(compilePhase, k -> new ArrayList<>()); + matchableForCompilePhase.computeIfAbsent(compilePhase, _ -> new ArrayList<>()); checkAttribute.add(rawConstraint.parse(compilePhase, compilation.output(compilePhase), vmInfo)); } return replaceConstraintsWithCheckAttribute(matchableForCompilePhase, checkAttributeType); @@ -113,7 +113,7 @@ class DefaultPhaseRawConstraintParser { private static void addCheckAttribute(Map failOnForCompilePhase, Map> result) { failOnForCompilePhase.forEach((compilePhase, matchable) -> { - List list = result.computeIfAbsent(compilePhase, k -> new ArrayList<>()); + List list = result.computeIfAbsent(compilePhase, _ -> new ArrayList<>()); list.add(matchable); }); } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/ApplicableIRRulesParser.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/ApplicableIRRulesParser.java index d251c574e47..67a04df2b58 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/ApplicableIRRulesParser.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/ApplicableIRRulesParser.java @@ -25,16 +25,12 @@ package compiler.lib.ir_framework.driver.irmatching.parser; import compiler.lib.ir_framework.IR; import compiler.lib.ir_framework.TestFramework; -import compiler.lib.ir_framework.driver.irmatching.parser.hotspot.HotSpotPidFileParser; +import compiler.lib.ir_framework.driver.network.testvm.java.ApplicableIRRules; import compiler.lib.ir_framework.driver.network.testvm.java.IRRuleIds; import compiler.lib.ir_framework.shared.TestFormat; -import compiler.lib.ir_framework.shared.TestFrameworkException; -import compiler.lib.ir_framework.test.ApplicableIRRulesPrinter; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -55,73 +51,19 @@ public class ApplicableIRRulesParser { * Parse the Applicable IR rules passed as parameter and return a "test name" -> TestMethod map that contains an * entry for each method that needs to be IR matched on. */ - public TestMethods parse(String applicableIRRules) { - createTestMethodMap(applicableIRRules, testClass); + public TestMethods parse(ApplicableIRRules applicableIRRules) { + createTestMethodMap(applicableIRRules); // We could have found format errors in @IR annotations. Report them now with an exception. TestFormat.throwIfAnyFailures(); return new TestMethods(testMethods); } - /** - * Sets up a map testname -> TestMethod map. The TestMethod object will later be filled with the ideal and opto - * assembly output in {@link HotSpotPidFileParser}. - */ - private void createTestMethodMap(String applicableIRRules, Class testClass) { - Map irRulesMap = parseApplicableIRRules(applicableIRRules); - createTestMethodsWithApplicableIRRules(testClass, irRulesMap); - } - - /** - * Read the Applicable IR Rules emitted by the Test VM to decide if an @IR rule must be checked for a method. - */ - private Map parseApplicableIRRules(String applicableIRRules) { - Map irRulesMap = new HashMap<>(); - String[] applicableIRRulesLines = getApplicableIRRulesLines(applicableIRRules); - for (String s : applicableIRRulesLines) { - String line = s.trim(); - String[] splitLine = line.split(","); - if (splitLine.length < 2) { - throw new TestFrameworkException("Invalid Applicable IR Rules format. No comma found: " + splitLine[0]); - } - String testName = splitLine[0]; - IRRuleIds irRuleIds = parseIrRulesIds(splitLine); - irRulesMap.put(testName, irRuleIds); - } - return irRulesMap; - } - - /** - * Parse the Applicable IR Rules lines without header, explanation line and footer and return them in an array. - */ - private String[] getApplicableIRRulesLines(String applicableIRRules) { - if (applicableIRRules.isEmpty()) { - // Nothing to IR match. - return new String[0]; - } - return applicableIRRules.split("\\R"); - } - - /** - * Parse rule indexes from a single line of the Applicable IR Rules in the format: - */ - private IRRuleIds parseIrRulesIds(String[] splitLine) { - List irRuleIds = new ArrayList<>(); - for (int i = 1; i < splitLine.length; i++) { - try { - irRuleIds.add(Integer.parseInt(splitLine[i])); - } catch (NumberFormatException e) { - throw new TestFrameworkException("Invalid Applicable IR Rules format. No number found: " + splitLine[i]); - } - } - return new IRRuleIds(irRuleIds); - } - - private void createTestMethodsWithApplicableIRRules(Class testClass, Map irRulesMap) { + private void createTestMethodMap(ApplicableIRRules applicableIRRules) { for (Method m : testClass.getDeclaredMethods()) { IR[] irAnnos = m.getAnnotationsByType(IR.class); if (irAnnos.length > 0) { // Validation of legal @IR attributes and placement of the annotation was already done in Test VM. - IRRuleIds irRuleIds = irRulesMap.get(m.getName()); + IRRuleIds irRuleIds = applicableIRRules.ruleIds(m.getName()); validateIRRuleIds(m, irAnnos, irRuleIds); if (hasAnyApplicableIRRules(irRuleIds)) { testMethods.put(m.getName(), new TestMethod(m, irAnnos, irRuleIds)); @@ -131,10 +73,7 @@ public class ApplicableIRRulesParser { } private void validateIRRuleIds(Method m, IR[] irAnnos, IRRuleIds irRuleIds) { - TestFramework.check(irRuleIds != null, "Should find method name in validIrRulesMap for " + m); - TestFramework.check(!irRuleIds.isEmpty(), "Did not find any rule indices for " + m); - TestFramework.check((irRuleIds.first() >= 1 || irRuleIds.first() == ApplicableIRRulesPrinter.NO_RULES) - && irRuleIds.last() <= irAnnos.length, + TestFramework.check((irRuleIds.isEmpty() || (irRuleIds.first() >= 1 && irRuleIds.last() <= irAnnos.length)), "Invalid IR rule index found in validIrRulesMap for " + m); } @@ -142,6 +81,6 @@ public class ApplicableIRRulesParser { * Does the list of IR rules contain any applicable IR rules for the given conditions? */ private boolean hasAnyApplicableIRRules(IRRuleIds irRuleIds) { - return irRuleIds.first() != ApplicableIRRulesPrinter.NO_RULES; + return !irRuleIds.isEmpty(); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/IRMethodBuilder.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/IRMethodBuilder.java index 46a237576e6..5ce93df434c 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/IRMethodBuilder.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/IRMethodBuilder.java @@ -32,6 +32,7 @@ import compiler.lib.ir_framework.driver.irmatching.irmethod.NotCompilableIRMetho 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 compiler.lib.ir_framework.driver.network.testvm.java.VMInfo; import java.util.Map; import java.util.SortedSet; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/TestClassParser.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/TestClassParser.java index ca36a3e9f72..30a766ddd4e 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/TestClassParser.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/TestClassParser.java @@ -23,6 +23,7 @@ package compiler.lib.ir_framework.driver.irmatching.parser; +import compiler.lib.ir_framework.TestFramework; import compiler.lib.ir_framework.driver.irmatching.Matchable; import compiler.lib.ir_framework.driver.irmatching.NonIRTestClass; import compiler.lib.ir_framework.driver.irmatching.TestClass; @@ -31,6 +32,8 @@ 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.driver.network.TestVMData; +import compiler.lib.ir_framework.driver.network.testvm.java.ApplicableIRRules; +import compiler.lib.ir_framework.driver.network.testvm.java.VMInfo; import compiler.lib.ir_framework.shared.TestFormat; import java.util.SortedSet; @@ -55,19 +58,20 @@ public class TestClassParser { * Return a default/empty TestClass object if there are no applicable @IR rules in any method of the test class. */ public Matchable parse(TestVMData testVmData) { + ApplicableIRRules applicableIrRules = testVmData.applicableIRRules(); + if (applicableIrRules.hasNoMethods()) { + return new NonIRTestClass(); + } ApplicableIRRulesParser applicableIRRulesParser = new ApplicableIRRulesParser(testClass); TestMethods testMethods = applicableIRRulesParser.parse(testVmData.applicableIRRules()); - VMInfo vmInfo = VMInfoParser.parseVMInfo(testVmData.vmInfo()); - if (testMethods.hasTestMethods()) { - HotSpotPidFileParser hotSpotPidFileParser = new HotSpotPidFileParser(testClass.getName(), testMethods); - LoggedMethods loggedMethods = hotSpotPidFileParser.parse(testVmData.hotspotPidFileName()); - return createTestClass(testMethods, loggedMethods, vmInfo); - } - return new NonIRTestClass(); + TestFramework.check(testMethods.hasTestMethods(), "must have at least one"); + HotSpotPidFileParser hotSpotPidFileParser = new HotSpotPidFileParser(testClass.getName(), testMethods); + LoggedMethods loggedMethods = hotSpotPidFileParser.parse(testVmData.hotspotPidFileName()); + return createTestClass(testMethods, loggedMethods, testVmData.vmInfo()); } /** - * Create test class with IR methods for all test methods identified by {@link ApplicableIRRulesParser} by combining them + * Create test class with IR methods for all test methods found in {@link ApplicableIRRules} by combining them * with the parsed compilation output from {@link HotSpotPidFileParser}. */ private Matchable createTestClass(TestMethods testMethods, LoggedMethods loggedMethods, VMInfo vmInfo) { diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/VMInfoParser.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/VMInfoParser.java deleted file mode 100644 index 44013839754..00000000000 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/VMInfoParser.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2023, 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.irmatching.parser; - -import compiler.lib.ir_framework.shared.TestFrameworkException; - -import java.util.HashMap; -import java.util.Map; - -/** - * Class to parse the VMInfo emitted by the Test VM and creating {@link VMInfo} objects for each entry. - * - * @see VMInfo - */ -public class VMInfoParser { - - /** - * Create a new VMInfo object from the vmInfo string. - */ - public static VMInfo parseVMInfo(String vmInfo) { - Map map = new HashMap<>(); - String[] lines = getVMInfoLines(vmInfo); - for (String s : lines) { - String line = s.trim(); - String[] splitLine = line.split(":", 2); - if (splitLine.length != 2) { - throw new TestFrameworkException("Invalid VMInfo key:value encoding. Found: " + splitLine[0]); - } - String key = splitLine[0]; - String value = splitLine[1]; - map.put(key, value); - } - return new VMInfo(map); - } - - /** - * Extract the VMInfo from the applicableIRRules string, strip away the header and return the individual key-value lines. - */ - private static String[] getVMInfoLines(String vmInfo) { - if (vmInfo.isEmpty()) { - // Nothing to IR match. - return new String[0]; - } - return vmInfo.split("\\R"); - } -} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/TestVMData.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/TestVMData.java index 413cf3347d8..59632ef1a48 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/TestVMData.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/TestVMData.java @@ -24,7 +24,9 @@ package compiler.lib.ir_framework.driver.network; import compiler.lib.ir_framework.driver.irmatching.IRMatcher; +import compiler.lib.ir_framework.driver.network.testvm.java.ApplicableIRRules; import compiler.lib.ir_framework.driver.network.testvm.java.JavaMessages; +import compiler.lib.ir_framework.driver.network.testvm.java.VMInfo; import compiler.lib.ir_framework.shared.TestFrameworkSocket; /** @@ -42,11 +44,11 @@ public class TestVMData { this.allowNotCompilable = allowNotCompilable; } - public String applicableIRRules() { + public ApplicableIRRules applicableIRRules() { return javaMessages.applicableIRRules(); } - public String vmInfo() { + public VMInfo vmInfo() { return javaMessages.vmInfo(); } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/ApplicableIRRules.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/ApplicableIRRules.java new file mode 100644 index 00000000000..eb41472057e --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/ApplicableIRRules.java @@ -0,0 +1,81 @@ +/* + * 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.java; + +import compiler.lib.ir_framework.IR; +import compiler.lib.ir_framework.TestFramework; +import compiler.lib.ir_framework.driver.irmatching.IRMatcher; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Class to hold the Applicable IR Rules sent by the Test VM. It specifies which {@link IR @IR} rules the + * {@link IRMatcher} need to check. This can be different depending on the used VM flags or the machine the test is run + * on itself. + */ +public class ApplicableIRRules implements JavaMessage { + private static final boolean PRINT_APPLICABLE_IR_RULES = + Boolean.parseBoolean(System.getProperty("PrintApplicableIRRules", "false")) + || TestFramework.VERBOSE; + + private final Map methods; + + public ApplicableIRRules() { + this.methods = new LinkedHashMap<>(); + } + + public void add(String method, IRRuleIds irRuleIds) { + methods.put(method, irRuleIds); + } + + public IRRuleIds ruleIds(String methodName) { + return methods.computeIfAbsent(methodName, _ -> IRRuleIds.createEmpty()); + } + + public boolean hasNoMethods() { + return methods.isEmpty(); + } + + @Override + public void print() { + if (!PRINT_APPLICABLE_IR_RULES) { + return; + } + + System.out.println(); + System.out.println("Applicable IR Rules"); + System.out.println("-------------------"); + if (methods.isEmpty()) { + System.out.println(""); + return; + } + for (var entry : methods.entrySet()) { + String method = entry.getKey(); + String ruleIds = entry.getValue().stream().map(String::valueOf).collect(Collectors.joining(", ")); + System.out.println("- " + method + ": " + ruleIds); + } + } +} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/IRRuleIds.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/IRRuleIds.java index b8ea1765b4f..f5bc084fbce 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/IRRuleIds.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/IRRuleIds.java @@ -49,6 +49,10 @@ public class IRRuleIds implements Iterable { return ruleIds.getLast(); } + public static IRRuleIds createEmpty() { + return new IRRuleIds(new ArrayList<>()); + } + public boolean isEmpty() { return ruleIds.isEmpty(); } 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 896aef38f1f..d419a06c8de 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,9 @@ package compiler.lib.ir_framework.driver.network.testvm.java; import compiler.lib.ir_framework.TestFramework; +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; import compiler.lib.ir_framework.shared.TestFrameworkException; import compiler.lib.ir_framework.test.network.MessageTag; @@ -43,18 +46,18 @@ public class JavaMessageParser { private final List stdoutMessages; private final List executedTests; private final Map methodTimes; - private final StringBuilder vmInfoBuilder; - private final StringBuilder applicableIrRules; + private final MultiLineParser vmInfoParser; + private final MultiLineParser applicableIRRulesParser; - private StringBuilder currentBuilder; + private MultiLineParser currentMultiLineParser; public JavaMessageParser() { this.stdoutMessages = new ArrayList<>(); this.methodTimes = new HashMap<>(); this.executedTests = new ArrayList<>(); - this.vmInfoBuilder = new StringBuilder(); - this.applicableIrRules = new StringBuilder(); - this.currentBuilder = null; + this.vmInfoParser = new MultiLineParser<>(new VMInfoStrategy()); + this.applicableIRRulesParser = new MultiLineParser<>(new ApplicableIRRulesStrategy()); + this.currentMultiLineParser = null; } public void parseLine(String line) { @@ -74,12 +77,11 @@ public class JavaMessageParser { return; } - // Multi-line message for single tag. - currentBuilder.append(line).append(System.lineSeparator()); + currentMultiLineParser.parseLine(line); } private void assertNoActiveParser() { - TestFramework.check(currentBuilder == null, "Unexpected new tag while parsing block"); + TestFramework.check(currentMultiLineParser == null, "Unexpected new tag while parsing block"); } private void parseTagLine(Matcher tagLineMatcher) { @@ -89,8 +91,8 @@ public class JavaMessageParser { case STDOUT -> stdoutMessages.add(message); case TEST_LIST -> executedTests.add(message); case PRINT_TIMES -> parsePrintTimes(message); - case VM_INFO -> currentBuilder = vmInfoBuilder; - case APPLICABLE_IR_RULES -> currentBuilder = applicableIrRules; + case VM_INFO -> currentMultiLineParser = vmInfoParser; + case APPLICABLE_IR_RULES -> currentMultiLineParser = applicableIRRulesParser; default -> throw new TestFrameworkException("unknown tag"); } } @@ -108,18 +110,19 @@ public class JavaMessageParser { } private void assertActiveParser() { - TestFramework.check(currentBuilder != null, "Received non-tag line outside of any tag block"); + TestFramework.check(currentMultiLineParser != null, "Received non-tag line outside of any tag block"); } private void parseEndTag() { - currentBuilder = null; + currentMultiLineParser.markFinished(); + currentMultiLineParser = null; } public JavaMessages output() { return new JavaMessages(new StdoutMessages(stdoutMessages), new ExecutedTests(executedTests), new MethodTimes(methodTimes), - applicableIrRules.toString(), - vmInfoBuilder.toString()); + applicableIRRulesParser.output(), + vmInfoParser.output()); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/JavaMessages.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/JavaMessages.java index e47ecff4b2a..e817610f441 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/JavaMessages.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/JavaMessages.java @@ -23,22 +23,18 @@ package compiler.lib.ir_framework.driver.network.testvm.java; -import compiler.lib.ir_framework.TestFramework; - /** * Class to collect all Java messages sent from the Test VM to the Driver VM. */ public class JavaMessages { - private static final boolean PRINT_APPLICABLE_IR_RULES = Boolean.parseBoolean(System.getProperty("PrintApplicableIRRules", "false")); - private final StdoutMessages stdoutMessages; private final ExecutedTests executedTests; private final MethodTimes methodTimes; - private final String applicableIrRules; - private final String vmInfo; + private final ApplicableIRRules applicableIrRules; + private final VMInfo vmInfo; JavaMessages(StdoutMessages stdoutMessages, ExecutedTests executedTests, MethodTimes methodTimes, - String applicableIrRules, String vmInfo) { + ApplicableIRRules applicableIrRules, VMInfo vmInfo) { this.stdoutMessages = stdoutMessages; this.executedTests = executedTests; this.methodTimes = methodTimes; @@ -46,21 +42,19 @@ public class JavaMessages { this.vmInfo = vmInfo; } - public String applicableIRRules() { - return applicableIrRules; + public VMInfo vmInfo() { + return vmInfo; } - public String vmInfo() { - return vmInfo; + public ApplicableIRRules applicableIRRules() { + return applicableIrRules; } public void print() { stdoutMessages.print(); methodTimes.print(); executedTests.print(); - if (TestFramework.VERBOSE || PRINT_APPLICABLE_IR_RULES) { - System.out.println("Read Applicable IR Rules from Test VM:"); - System.out.println(applicableIrRules); - } + vmInfo.print(); + applicableIrRules.print(); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/VMInfo.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/VMInfo.java similarity index 74% rename from test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/VMInfo.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/VMInfo.java index 89b6d610496..a948dbc22ef 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/parser/VMInfo.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/VMInfo.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.lib.ir_framework.driver.irmatching.parser; +package compiler.lib.ir_framework.driver.network.testvm.java; import compiler.lib.ir_framework.TestFramework; import compiler.lib.ir_framework.shared.TestFrameworkException; @@ -32,31 +32,27 @@ import java.util.regex.Pattern; /** * This class stores the key value mapping from the VMInfo. - * - * @see ApplicableIRRulesParser */ -public class VMInfo { +public class VMInfo implements JavaMessage { + private static final Pattern CPU_SKYLAKE_PATTERN = + Pattern.compile("family 6 model 85 stepping (\\d+) "); + /** * Stores the key-value mapping. */ private final Map keyValueMap; - private static final Pattern CPU_SKYLAKE_PATTERN = - Pattern.compile("family 6 model 85 stepping (\\d+) "); - - public VMInfo(Map map) { - this.keyValueMap = map; - - TestFramework.check(isKey("cpuFeatures"), "VMInfo does not contain cpuFeatures"); - TestFramework.check(isKey("MaxVectorSize"), "VMInfo does not contain MaxVectorSize"); - TestFramework.check(isKey("MaxVectorSizeIsDefault"), "VMInfo does not contain MaxVectorSizeIsDefault"); - TestFramework.check(isKey("LoopMaxUnroll"), "VMInfo does not contain LoopMaxUnroll"); - TestFramework.check(isKey("UseAVX"), "VMInfo does not contain UseAVX"); - TestFramework.check(isKey("UseAVXIsDefault"), "VMInfo does not contain UseAVXIsDefault"); + public VMInfo(Map keyValueMap) { + this.keyValueMap = keyValueMap; } - public String getStringValue(String key) { - TestFramework.check(isKey(key), "VMInfo does not contain \"" + key + "\""); + public boolean hasCPUFeature(String feature) { + String features = getStringValue("cpuFeatures") + ","; + return features.contains(" " + feature + ","); + } + + private String getStringValue(String key) { + TestFramework.check(keyValueMap.containsKey(key), "VMInfo does not contain \"" + key + "\""); return keyValueMap.get(key); } @@ -68,28 +64,6 @@ public class VMInfo { } } - public boolean hasCPUFeature(String feature) { - String features = getStringValue("cpuFeatures") + ","; - return features.contains(" " + feature + ","); - } - - public boolean isCascadeLake() { - Matcher matcher = CPU_SKYLAKE_PATTERN.matcher(getStringValue("cpuFeatures")); - if (!matcher.find()) { - return false; // skylake pattern not found - } - String stepping = matcher.group(1).trim(); - return Long.parseLong(stepping) >= 5; // this makes it Cascade Lake - } - - public boolean isDefaultCascadeLake() { - // See VM_Version::is_default_intel_cascade_lake - return isCascadeLake() && - getLongValue("MaxVectorSizeIsDefault") == 1 && - getLongValue("UseAVXIsDefault") == 1 && - getLongValue("UseAVX") > 2; - } - /** * Some platforms do not behave as expected, and one cannot trust that the vectors * make use of the full MaxVectorSize. For Cascade Lake, we only use 32 bytes for @@ -101,7 +75,36 @@ public class VMInfo { return !isDefaultCascadeLake(); } - public boolean isKey(String key) { - return keyValueMap.containsKey(key); + private boolean isDefaultCascadeLake() { + // See VM_Version::is_default_intel_cascade_lake + return isCascadeLake() && + getLongValue("MaxVectorSizeIsDefault") == 1 && + getLongValue("UseAVXIsDefault") == 1 && + getLongValue("UseAVX") > 2; + } + + private boolean isCascadeLake() { + Matcher matcher = CPU_SKYLAKE_PATTERN.matcher(getStringValue("cpuFeatures")); + if (!matcher.find()) { + return false; // skylake pattern not found + } + String stepping = matcher.group(1).trim(); + return Long.parseLong(stepping) >= 5; // this makes it Cascade Lake + } + + @Override + public void print() { + if (!TestFramework.VERBOSE) { + return; + } + + System.out.println(); + System.out.println("VM Info"); + System.out.println("--------"); + for (var entry : keyValueMap.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + System.out.println("- Key: " + key + ", Value: " + value); + } } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/ApplicableIRRulesStrategy.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/ApplicableIRRulesStrategy.java new file mode 100644 index 00000000000..3728e489ba7 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/ApplicableIRRulesStrategy.java @@ -0,0 +1,78 @@ +/* + * 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.java.multiline; + +import compiler.lib.ir_framework.driver.network.testvm.java.ApplicableIRRules; +import compiler.lib.ir_framework.driver.network.testvm.java.IRRuleIds; +import compiler.lib.ir_framework.shared.TestFrameworkException; +import compiler.lib.ir_framework.test.ApplicableIRRulesPrinter; + +import java.util.ArrayList; +import java.util.List; + +/** + * Dedicated strategy to parse the multi-line Applicable IR Rules message into a new {@link ApplicableIRRules} object. + */ +public class ApplicableIRRulesStrategy implements MultiLineParsingStrategy { + private final ApplicableIRRules applicableIrRules; + + public ApplicableIRRulesStrategy() { + this.applicableIrRules = new ApplicableIRRules(); + } + + @Override + public void parseLine(String line) { + if (line.equals(ApplicableIRRulesPrinter.NO_RULES)) { + return; + } + + String[] splitLine = line.split(","); + if (splitLine.length < 2) { + throw new TestFrameworkException("Invalid Applicable IR Rules format. No comma found: " + splitLine[0]); + } + String testName = splitLine[0]; + IRRuleIds irRulesIds = parseIrRulesIds(splitLine); + applicableIrRules.add(testName, irRulesIds); + } + + /** + * Parse rule indexes from a single line of the Applicable IR Rules in the format: + */ + private IRRuleIds parseIrRulesIds(String[] splitLine) { + List irRuleIds = new ArrayList<>(); + for (int i = 1; i < splitLine.length; i++) { + try { + irRuleIds.add(Integer.parseInt(splitLine[i])); + } catch (NumberFormatException e) { + throw new TestFrameworkException("Invalid Applicable IR Rules format. No number found: " + splitLine[i]); + } + } + return new IRRuleIds(irRuleIds); + } + + @Override + public ApplicableIRRules output() { + return applicableIrRules; + } +} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/MultiLineParser.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/MultiLineParser.java new file mode 100644 index 00000000000..fbc24eed736 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/MultiLineParser.java @@ -0,0 +1,67 @@ +/* + * 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.java.multiline; + +import compiler.lib.ir_framework.TestFramework; +import compiler.lib.ir_framework.driver.network.testvm.java.JavaMessage; +import compiler.lib.ir_framework.test.network.MessageTag; + +/** + * Generic multi-line parser that takes a {@link MultiLineParsingStrategy} to decide how to parse a single line of + * a multi line {@link JavaMessage}. Once parsing is done, the strategy is queried for the final parsed output. + */ +public class MultiLineParser { + private enum ParserState { + NOTHING_PARSED, PARSING, FINISHED_PARSING + } + + private ParserState parserState; + private final MultiLineParsingStrategy multiLineParsingStrategy; + + public MultiLineParser(MultiLineParsingStrategy multiLineParsingStrategy) { + this.multiLineParsingStrategy = multiLineParsingStrategy; + this.parserState = ParserState.NOTHING_PARSED; + } + + public void parseLine(String line) { + TestFramework.check(parserState != ParserState.FINISHED_PARSING, + "cannot parse another block"); + parserState = ParserState.PARSING; + multiLineParsingStrategy.parseLine(line); + } + + /** + * Once the {@link MessageTag#END_MARKER} was seen, this method is called to mark the end of this multi-line message. + */ + public void markFinished() { + TestFramework.check(parserState == ParserState.PARSING, + "nothing parsed, cannot have empty block"); + parserState = ParserState.FINISHED_PARSING; + } + + public Output output() { + TestFramework.check(parserState != ParserState.PARSING, "either nothing parsed or finished"); + return multiLineParsingStrategy.output(); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/MultiLineParsingStrategy.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/MultiLineParsingStrategy.java new file mode 100644 index 00000000000..0283c520465 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/MultiLineParsingStrategy.java @@ -0,0 +1,32 @@ +/* + * 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.java.multiline; + +/** + * Interface to define a strategy to parse a line in a {@link MultiLineParser}. + */ +public interface MultiLineParsingStrategy { + void parseLine(String line); + Output output(); +} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/VMInfoStrategy.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/VMInfoStrategy.java new file mode 100644 index 00000000000..7d3072394c0 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/network/testvm/java/multiline/VMInfoStrategy.java @@ -0,0 +1,57 @@ +/* + * 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.java.multiline; + +import compiler.lib.ir_framework.driver.network.testvm.java.VMInfo; +import compiler.lib.ir_framework.shared.TestFrameworkException; + +import java.util.HashMap; +import java.util.Map; + +/** + * Dedicated strategy to parse the multi-line VM info message into a new {@link VMInfo} object. + */ +public class VMInfoStrategy implements MultiLineParsingStrategy { + private final Map keyValueMap; + + public VMInfoStrategy() { + this.keyValueMap = new HashMap<>(); + } + + @Override + public void parseLine(String line) { + String[] splitLine = line.split(":", 2); + if (splitLine.length != 2) { + throw new TestFrameworkException("Invalid VmInfo key:value encoding. Found: " + splitLine[0]); + } + String key = splitLine[0]; + String value = splitLine[1]; + keyValueMap.put(key, value); + } + + @Override + public VMInfo output() { + return new VMInfo(keyValueMap); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/test/ApplicableIRRulesPrinter.java b/test/hotspot/jtreg/compiler/lib/ir_framework/test/ApplicableIRRulesPrinter.java index 79f5c7fe18e..a4797a29dc7 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/test/ApplicableIRRulesPrinter.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/test/ApplicableIRRulesPrinter.java @@ -47,7 +47,7 @@ import java.util.function.Function; * termination of the Test VM. IR rule indices start at 1. */ public class ApplicableIRRulesPrinter { - public static final int NO_RULES = -1; + public static final String NO_RULES = ""; private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); private static final List> LONG_GETTERS = Arrays.asList( @@ -155,17 +155,15 @@ public class ApplicableIRRulesPrinter { i++; } } - if (irAnnos.length != 0) { - output.append(m.getName()); - if (validRules.isEmpty()) { - output.append("," + NO_RULES); - } else { - for (i = 0; i < validRules.size(); i++) { - output.append(",").append(validRules.get(i)); - } - } - output.append(System.lineSeparator()); + + if (irAnnos.length == 0 || validRules.isEmpty()) { + return; } + output.append(m.getName()); + for (i = 0; i < validRules.size(); i++) { + output.append(",").append(validRules.get(i)); + } + output.append(System.lineSeparator()); } private void printDisableReason(String method, String reason, String[] apply, int ruleIndex, int ruleMax) { @@ -520,9 +518,10 @@ public class ApplicableIRRulesPrinter { } public void emit() { + if (output.isEmpty()) { + output.append(NO_RULES).append(System.lineSeparator()); + } output.append(MessageTag.END_MARKER); TestVmSocket.sendMultiLine(MessageTag.APPLICABLE_IR_RULES, output.toString()); } } - - diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java index b6881fede75..fc8a92cf9a2 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java @@ -329,7 +329,7 @@ public class TestIRMatching { System.out.flush(); String output = baos.toString(); findIrIds(output, "testMatchAllIf50", 1, 22); - findIrIds(output, "testMatchNoneIf50", -1, -1); + assertNoIds(output, "testMatchNoneIf50"); runWithArguments(FlagComparisons.class, "-XX:TLABRefillWasteFraction=49"); System.out.flush(); @@ -431,12 +431,14 @@ public class TestIRMatching { private static void findIrIds(String output, String method, int... numbers) { StringBuilder builder = new StringBuilder(); - builder.append(method); + builder.append(method).append(": "); for (int i = 0; i < numbers.length; i+=2) { int start = numbers[i]; int endIncluded = numbers[i + 1]; for (int j = start; j <= endIncluded; j++) { - builder.append(","); + if (j != numbers[0]) { + builder.append(", "); + } builder.append(j); } } @@ -445,6 +447,13 @@ public class TestIRMatching { System.lineSeparator())); } } + + private static void assertNoIds(String output, String methodName) { + String applicableIRRules = output.split("Applicable IR Rules")[1]; + if (applicableIRRules.contains(methodName)) { + addException(new RuntimeException("Should not find ids for \"" + methodName + "\"" + System.lineSeparator())); + } + } } class AndOr1 {