From 14b15081f9c48aafe542dcd2a07af21c0fe58478 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 22 Dec 2020 19:17:24 +0100 Subject: [PATCH 001/131] Initial and last commit of 2020 --- .../compiler/valhalla/framework/Argument.java | 211 ++++ .../valhalla/framework/ArgumentValue.java | 13 + .../valhalla/framework/Arguments.java | 9 + .../compiler/valhalla/framework/Check.java | 10 + .../compiler/valhalla/framework/CheckAt.java | 6 + .../valhalla/framework/CompLevel.java | 37 + .../valhalla/framework/CompileOnly.java | 9 + .../valhalla/framework/DontCompile.java | 9 + .../valhalla/framework/DontInline.java | 9 + .../src/compiler/valhalla/framework/Foo.java | 5 + .../valhalla/framework/ForceCompile.java | 10 + .../valhalla/framework/ForceInline.java | 9 + .../src/compiler/valhalla/framework/IR.java | 20 + .../valhalla/framework/IREncodingPrinter.java | 245 ++++ .../valhalla/framework/IRMatcher.java | 182 +++ .../compiler/valhalla/framework/IRNode.java | 92 ++ .../src/compiler/valhalla/framework/IRs.java | 9 + .../compiler/valhalla/framework/OSROnly.java | 9 + .../src/compiler/valhalla/framework/Run.java | 9 + .../compiler/valhalla/framework/Scenario.java | 54 + .../src/compiler/valhalla/framework/Skip.java | 21 + .../src/compiler/valhalla/framework/Test.java | 18 + .../framework/TestFormatException.java | 13 + .../valhalla/framework/TestFramework.java | 1030 +++++++++++++++++ .../framework/TestFrameworkValhalla.java | 76 ++ .../compiler/valhalla/framework/TestInfo.java | 34 + .../valhalla/framework/TestRunException.java | 11 + .../compiler/valhalla/framework/VMFlag.java | 7 + .../valhalla/framework/VMFlagValhalla.java | 11 + .../compiler/valhalla/framework/Warmup.java | 10 + .../valhalla/framework/tests/TestBasics.java | 688 +++++++++++ .../framework/tests/TestIRMatching.java | 334 ++++++ .../framework/tests/TestPackagePrivate.java | 65 ++ .../framework/tests/TestScenarios.java | 52 + 34 files changed, 3327 insertions(+) create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompileOnly.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSROnly.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Skip.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFrameworkValhalla.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java new file mode 100644 index 00000000000..64248ca21c5 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java @@ -0,0 +1,211 @@ +package compiler.valhalla.framework; + + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.Random; + +class Argument { + private static final Random random = new Random(); + + final private Object argumentValue; + final private boolean isToggleBoolean; + final private boolean isRandomEach; + final private boolean isFixedRandom; + final private Class randomClass; + private boolean previousBoolean; + + private Argument(Object argumentValue, Boolean booleanToggle, boolean isFixedRandom) { + this.argumentValue = argumentValue; + this.isToggleBoolean = booleanToggle != null; + this.previousBoolean = isToggleBoolean && !booleanToggle; + this.isRandomEach = false; + this.randomClass = null; + this.isFixedRandom = isFixedRandom; + } + + private Argument(Object argumentValue, Class randomClass) { + this.argumentValue = argumentValue; + this.isToggleBoolean = false; + this.isRandomEach = true; + this.randomClass = randomClass; + this.isFixedRandom = false; + } + + /** + * Return all arguments for the @Arguments annotation. + * @param m The @Test method + * @return Return array with Argument objects for each specified argument in the @Arguments annotation of m. + * Return null if method has no @Arguments annotation. + */ + public static Argument[] getArguments(Method m) { + Arguments argumentsAnno = m.getAnnotation(Arguments.class); + if (argumentsAnno == null) { + return null; + } + ArgumentValue[] values = argumentsAnno.value(); + Argument[] arguments = new Argument[values.length]; + Class[] declaredParameters = m.getParameterTypes(); + if (values.length != declaredParameters.length) { + throw new TestFormatException("Number of argument values provided in @Arguments does not match the number of actual arguments in " + m); + } + + for (int i = 0; i < values.length; i++) { + ArgumentValue specifiedArg = values[i]; + Class parameter = declaredParameters[i]; + switch (specifiedArg) { + case DEFAULT -> arguments[i] = createDefault(parameter); + case NUMBER_42 -> { + if (isNumber(parameter)) { + arguments[i] = create((byte) 42); + } else { + throw new TestFormatException("Provided invalid NUMBER_42 argument for non-number " + parameter + " for " + m); + } + } + case NUMBER_MINUS_42 -> { + if (isNumber(parameter)) { + arguments[i] = create((byte) -42); + } else { + throw new TestFormatException("Provided invalid NUMBER_MINUS_42 argument for non-number " + parameter + " for " + m); + } + } + case BOOLEAN_TOGGLE_FIRST_FALSE -> { + if (!isBoolean(parameter)) { + throw new TestFormatException("Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + parameter + " for " + m); + } + arguments[i] = createToggleBoolean(false); + } + case BOOLEAN_TOGGLE_FIRST_TRUE -> { + if (!Argument.isBoolean(parameter)) { + throw new TestFormatException("Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + parameter + " for " + m); + } + arguments[i] = createToggleBoolean(true); + } + case TRUE -> { + if (!Argument.isBoolean(parameter)) { + throw new TestFormatException("Provided invalid TRUE argument for non-boolean " + parameter + " for " + m); + } + arguments[i] = create(true); + } + case FALSE -> { + if (!isBoolean(parameter)) { + throw new TestFormatException("Provided invalid FALSE argument for non-boolean " + parameter + " for " + m); + } + arguments[i] = create(false); + } + case RANDOM_ONCE -> { + if (isNotPrimitiveType(parameter)) { + throw new TestFormatException("Provided invalid RANDOM_ONCE argument for non-primitive type " + parameter + " for " + m); + } + arguments[i] = createRandom(parameter); + } + case RANDOM_EACH -> { + if (isNotPrimitiveType(parameter)) { + throw new TestFormatException("Provided invalid RANDOM_ONCE argument for non-primitive type " + parameter + " for " + m); + } + arguments[i] = createRandomEach(parameter); + } + } + } + return arguments; + } + + private static Argument create(Object argumentValue) { + return new Argument(argumentValue, null,false); + } + + private static Argument createDefault(Class c) { + if (Argument.isNumber(c)) { + return Argument.create((byte)0); + } else if (Argument.isChar(c)) { + return Argument.create('\u0000'); + } else if (Argument.isBoolean(c)) { + return Argument.create(false); + } else { + // Object + try { + Constructor constructor = c.getDeclaredConstructor(); + constructor.setAccessible(true); + return Argument.create(constructor.newInstance()); + } catch (Exception e) { + throw new TestFormatException("Cannot create new default instance of " + c, e); + } + } + } + + private static Argument createRandom(Class c) { + return new Argument(getRandom(c), null, true); + } + private static Argument createToggleBoolean(boolean firstBoolean) { + return new Argument(null, firstBoolean, false); + } + + private static Argument createRandomEach(Class c) { + return new Argument(null, c); + } + + public boolean isFixedRandom() { + return isFixedRandom; + } + + public Object getArgument() { + if (isToggleBoolean) { + previousBoolean = !previousBoolean; + return previousBoolean; + } else if (isRandomEach) { + return getRandom(randomClass); + } else { + return argumentValue; + } + } + + private static boolean isNotPrimitiveType(Class c) { + return !isNumber(c) && !isBoolean(c) && !isChar(c); + } + + private static boolean isBoolean(Class c) { + return c.equals(boolean.class); + } + + private static boolean isChar(Class c) { + return c.equals(char.class); + } + private static boolean isNumber(Class c) { + return isIntNumber(c) || isFloatNumber(c); + } + + private static boolean isIntNumber(Class c) { + return c.equals(byte.class) + || c.equals(short.class) + || c.equals(int.class) + || c.equals(long.class); + } + + public static boolean isFloatNumber(Class c) { + return c.equals(float.class) || c.equals(double.class); + } + + private static Object getRandom(Class c) { + if (isBoolean(c)) { + return random.nextBoolean(); + } else if (c.equals(byte.class)) { + return (byte)random.nextInt(256); + } else if (isChar(c)) { + return (char)random.nextInt(65536); + } else if (c.equals(short.class)) { + return (short)random.nextInt(65536); + } else if (c.equals(int.class)) { + return random.nextInt(); + } else if (c.equals(long.class)) { + return random.nextLong(); + } else if (c.equals(float.class)) { + // Get number between 0 and 1000. + return random.nextFloat() * 1000; + } else if (c.equals(double.class)) { + // Get number between 0 and 1000. + return random.nextDouble() * 1000; + } else { + throw new TestFormatException("Cannot generate random value for non-primitive type"); + } + } +} \ No newline at end of file diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java new file mode 100644 index 00000000000..0d3c66ede2d --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java @@ -0,0 +1,13 @@ +package compiler.valhalla.framework; + +public enum ArgumentValue { + DEFAULT, + NUMBER_MINUS_42, + NUMBER_42, + BOOLEAN_TOGGLE_FIRST_FALSE, + BOOLEAN_TOGGLE_FIRST_TRUE, + TRUE, + FALSE, + RANDOM_ONCE, + RANDOM_EACH +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java new file mode 100644 index 00000000000..667ef43cfc3 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java @@ -0,0 +1,9 @@ +package compiler.valhalla.framework; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Arguments { + ArgumentValue[] value(); +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java new file mode 100644 index 00000000000..035d2e5a7eb --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java @@ -0,0 +1,10 @@ +package compiler.valhalla.framework; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Check { + String test() default ""; + CheckAt when() default CheckAt.EACH_INVOCATION; +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java new file mode 100644 index 00000000000..ac962ce4eae --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java @@ -0,0 +1,6 @@ +package compiler.valhalla.framework; + +public enum CheckAt { + EACH_INVOCATION, + C2_COMPILED +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java new file mode 100644 index 00000000000..7b2ce36a01b --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java @@ -0,0 +1,37 @@ +package compiler.valhalla.framework; + +import java.util.HashMap; +import java.util.Map; + +public enum CompLevel { + ANY(-2), + ALL(-2), + AOT(-1), + INTERPRETER(0), // Only execute in interpreter, no compilation + C1_SIMPLE(1), // C1 + C1_LIMITED_PROFILE(2), // C1, invocation & backedge counters + C1_FULL_PROFILE(3), // C1, invocation & backedge counters + mdo + C2_FULL_OPTIMIZATION(4); // C2 or JVMCI + + + private static final Map typesByValue = new HashMap<>(); + private final int value; + + static { + for (CompLevel level : CompLevel.values()) { + typesByValue.put(level.value, level); + } + } + + CompLevel(int level) { + this.value = level; + } + + public int getValue() { + return value; + } + + public static CompLevel forValue(int value) { + return typesByValue.get(value); + } +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompileOnly.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompileOnly.java new file mode 100644 index 00000000000..fb1aee0ede5 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompileOnly.java @@ -0,0 +1,9 @@ +package compiler.valhalla.framework; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +// +@Retention(RetentionPolicy.RUNTIME) +public @interface CompileOnly { +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java new file mode 100644 index 00000000000..9f22f208ece --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java @@ -0,0 +1,9 @@ +package compiler.valhalla.framework; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +// Prevent method compilation +@Retention(RetentionPolicy.RUNTIME) +public @interface DontCompile { +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java new file mode 100644 index 00000000000..8eb16b4e8ec --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java @@ -0,0 +1,9 @@ +package compiler.valhalla.framework; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +// Prevent method inlining during compilation +@Retention(RetentionPolicy.RUNTIME) +public @interface DontInline { +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java new file mode 100644 index 00000000000..13eb58a104a --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java @@ -0,0 +1,5 @@ +package compiler.valhalla.framework; + +public @interface Foo { + +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java new file mode 100644 index 00000000000..b6a0d883833 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java @@ -0,0 +1,10 @@ +package compiler.valhalla.framework; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +// Force method compilation +@Retention(RetentionPolicy.RUNTIME) +public @interface ForceCompile { + CompLevel compLevel() default CompLevel.ANY; +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java new file mode 100644 index 00000000000..9726214230c --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java @@ -0,0 +1,9 @@ +package compiler.valhalla.framework; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +// Force method inlining during compilation +@Retention(RetentionPolicy.RUNTIME) +public @interface ForceInline { +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java new file mode 100644 index 00000000000..f911e013582 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java @@ -0,0 +1,20 @@ +package compiler.valhalla.framework; + +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +@Repeatable(IRs.class) +public @interface IR { + // Regular expression used to match forbidden IR nodes + // in the C2 IR emitted for this test. + String[] failOn() default {}; + + // Regular expressions used to match and count IR nodes. + String[] counts() default {}; + String[] applyIf() default {}; + String[] applyIfNot() default {}; + String[] applyIfAnd() default {}; + String[] applyIfOr() default {}; +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java new file mode 100644 index 00000000000..a07bdf0a395 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java @@ -0,0 +1,245 @@ +package compiler.valhalla.framework; + +import sun.hotspot.WhiteBox; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.function.BiPredicate; +import java.util.function.Function; + +// Only used by TestVM +class IREncodingPrinter { + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private static final List> longGetters = Arrays.asList( + WHITE_BOX::getIntVMFlag, WHITE_BOX::getUintVMFlag, WHITE_BOX::getIntxVMFlag, + WHITE_BOX::getUintxVMFlag, WHITE_BOX::getUint64VMFlag, WHITE_BOX::getSizeTVMFlag); + public static final String START = "##### IRMatchRulesEncoding - used by TestFramework #####"; + public static final String END = "----- END -----"; + public static final int NO_RULE_APPLIED = -1; + private final StringBuilder output = new StringBuilder(); + + public IREncodingPrinter() { + output.append(START).append("\n"); + output.append(",{comma separated applied @IR rule ids}\n"); + } + + /** + * Emits ",{ids}" where {ids} is either: + * - indices of all @IR rules that should be applied, separated by a comma + * - "-1" if no @IR rule should not be applied + */ + public void emitRuleEncoding(Method m) { + int i = 0; + ArrayList validRules = new ArrayList<>(); + IR[] irAnnos = m.getAnnotationsByType(IR.class); + for (IR irAnno : irAnnos) { + if (shouldApplyIrRule(m, irAnno)) { + validRules.add(i); + } + i++; + } + if (irAnnos.length != 0) { + output.append(m.getName()); + if (validRules.isEmpty()) { + output.append("," + NO_RULE_APPLIED); + } else { + for (i = 0; i < validRules.size(); i++) { + output.append(",").append(validRules.get(i)); + } + } + output.append("\n"); + } + } + + public void dump() { + output.append(END); + System.out.println(output.toString()); + } + + private boolean shouldApplyIrRule(Method m, IR irAnnotation) { + checkAnnotation(m, irAnnotation); + if (irAnnotation.applyIf().length != 0) { + return hasAllRequiredFlags(m, irAnnotation.applyIf(), "applyIf"); + } + + if (irAnnotation.applyIfNot().length != 0) { + return hasNoRequiredFlags(m, irAnnotation.applyIfNot(), "applyIfNot"); + } + + if (irAnnotation.applyIfAnd().length != 0) { + return hasAllRequiredFlags(m, irAnnotation.applyIfAnd(), "applyIfAnd"); + } + + if (irAnnotation.applyIfOr().length != 0) { + return !hasNoRequiredFlags(m, irAnnotation.applyIfOr(), "applyIfOr"); + } + // No conditions, always apply. + return true; + } + + private static void checkAnnotation(Method m, IR irAnnotation) { + int applyRules = 0; + if (irAnnotation.applyIfAnd().length != 0) { + applyRules++; + if (irAnnotation.applyIfAnd().length <= 2) { + throw new TestFormatException("Use [applyIf|applyIfNot] or at least 2 conditions for applyIfAnd in @IR at " + m); + } + } + if (irAnnotation.applyIfOr().length != 0) { + applyRules++; + if (irAnnotation.applyIfOr().length <= 2) { + throw new TestFormatException("Use [applyIf|applyIfNot] or at least 2 conditions for applyIfOr in @IR at " + m); + } + } + if (irAnnotation.applyIf().length != 0) { + applyRules++; + if (irAnnotation.applyIf().length > 2) { + throw new TestFormatException("Use [applyIfAnd|applyIfOr] or only 1 condition for applyIf in @IR at " + m); + } + } + if (irAnnotation.applyIfNot().length != 0) { + applyRules++; + if (irAnnotation.applyIfNot().length > 2) { + throw new TestFormatException("Use [applyIfAnd|applyIfOr] or only 1 condition for applyIfNot in @IR at " + m); + } + } + if (applyRules > 1) { + throw new TestFormatException("Can only use one of [applyIf|applyIfNot|applyIfAnd|applyIfOr] in @IR at " + m); + } + } + + private boolean hasAllRequiredFlags(Method m, String[] andRules, String ruleType) { + for (int i = 0; i < andRules.length; i++) { + String flag = andRules[i]; + i++; + if (i == andRules.length) { + throw new TestFormatException("Missing value for flag " + flag + " in " + ruleType + " for @IR at " + m); + } + String value = andRules[i]; + if (!check(m, flag, value)) { + return false; + } + } + return true; + } + + private boolean hasNoRequiredFlags(Method m, String[] orRules, String ruleType) { + for (int i = 0; i < orRules.length; i++) { + String flag = orRules[i]; + i++; + if (i == orRules.length) { + throw new TestFormatException("Missing value for flag " + flag + " in " + ruleType + " for @IR at " + m); + } + String value = orRules[i]; + if (check(m, flag, value)) { + return false; + } + } + return true; + } + + private boolean check(Method m, String flag, String value) { + if (value.length() == 0) { + throw new TestFormatException("Provided empty value for flag " + flag + " at " + m); + } + Object actualFlagValue = longGetters.stream() + .map(f -> f.apply(flag)) + .filter(Objects::nonNull) + .findAny().orElse(null); + if (actualFlagValue != null) { + long actualLongFlagValue = (Long) actualFlagValue; + long longValue; + ParsedComparator parsedComparator; + try { + parsedComparator = parseComparator(value.trim()); + longValue = Long.parseLong(parsedComparator.getStrippedString()); + } catch (NumberFormatException e) { + throw new TestFormatException("Invalid value " + value + " for number based flag " + flag); + } catch (Exception e) { + throw new TestFormatException("Invalid comparator in \"" + value + "\" for number based flag " + flag, e); + } + return parsedComparator.getPredicate().test(actualLongFlagValue, longValue); + } + actualFlagValue = WHITE_BOX.getBooleanVMFlag(flag); + if (actualFlagValue != null) { + boolean actualBooleanFlagValue = (Boolean) actualFlagValue; + boolean booleanValue; + try { + booleanValue = Boolean.parseBoolean(value); + } catch (Exception e) { + throw new TestFormatException("Invalid value " + value + " for boolean flag " + flag); + } + return booleanValue == actualBooleanFlagValue; + } + actualFlagValue = WHITE_BOX.getDoubleVMFlag(flag); + if (actualFlagValue != null) { + double actualDoubleFlagValue = (Double) actualFlagValue; + double doubleValue; + ParsedComparator parsedComparator; + + try { + parsedComparator = parseComparator(value); + doubleValue = Double.parseDouble(parsedComparator.getStrippedString()); + } catch (NumberFormatException e) { + throw new TestFormatException("Invalid value " + value + " for number based flag " + flag); + } catch (Exception e) { + throw new TestFormatException("Invalid comparator in \"" + value + "\" for number based flag " + flag, e); + } + return parsedComparator.getPredicate().test(actualDoubleFlagValue, doubleValue); + } + actualFlagValue = WHITE_BOX.getStringVMFlag(flag); + if (actualFlagValue != null) { + String actualStringFlagValue = (String) actualFlagValue; + return actualStringFlagValue.equals(value); + } + throw new TestFormatException("Could not find flag " + flag); + } + + private > ParsedComparator parseComparator(String value) { + BiPredicate comparison; + try { + switch (value.charAt(0)) { + case '<': + if (value.charAt(1) == '=') { + comparison = (x, y) -> x.compareTo(y) <= 0; + value = value.substring(2).trim(); + } else { + comparison = (x, y) -> x.compareTo(y) < 0; + value = value.substring(1).trim(); + } + break; + case '>': + if (value.charAt(1) == '=') { + comparison = (x, y) -> x.compareTo(y) >= 0; + value = value.substring(2).trim(); + } else { + comparison = (x, y) -> x.compareTo(y) > 0; + value = value.substring(1).trim(); + } + break; + case '!': + if (value.charAt(1) == '=') { + comparison = (x, y) -> x.compareTo(y) != 0; + value = value.substring(2).trim(); + } else { + throw new TestFormatException("Invalid comparator sign used."); + } + break; + case '=': // Allowed syntax, equivalent to not using any symbol. + value = value.substring(1).trim(); + default: + comparison = (x, y) -> x.compareTo(y) == 0; + value = value.trim(); + break; + } + } catch (IndexOutOfBoundsException e) { + throw new TestFormatException("Invalid value format."); + } + return new ParsedComparator<>(value, comparison); + } +} + + diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java new file mode 100644 index 00000000000..da983b3a9f6 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java @@ -0,0 +1,182 @@ +package compiler.valhalla.framework; + +import jdk.test.lib.Asserts; + +import java.lang.reflect.Method; +import java.util.*; +import java.util.regex.MatchResult; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +class IRMatcher { + private final Map irRulesMap; + private final Map compilations; + private final Class testClass; + private final Map> fails; + + public IRMatcher(String output, Class testClass) { + this.irRulesMap = new HashMap<>(); + this.compilations = new LinkedHashMap<>(); + this.fails = new HashMap<>(); + this.testClass = testClass; + parseIREncoding(output); + splitCompilations(output, testClass); + } + + private void parseIREncoding(String output) { + String patternString = "(?<=" + IREncodingPrinter.START + "\\R)[\\s\\S]*(?=" + IREncodingPrinter.END + ")"; + Pattern pattern = Pattern.compile(patternString); + Matcher matcher = pattern.matcher(output); + + while (matcher.find()) { + String[] lines = matcher.group(0).split("\\R"); + // Skip first line containing information about the format only + for (int i = 1; i < lines.length; i++) { + String line = lines[i].trim(); + String[] splitComma = line.split(","); + if (splitComma.length < 2) { + throw new TestFrameworkException("Invalid IR match rule encoding"); + } + String testName = splitComma[0]; + Integer[] irRulesIdx = new Integer[splitComma.length - 1]; + for (int j = 1; j < splitComma.length; j++) { + irRulesIdx[j - 1] = Integer.valueOf(splitComma[j]); + } + irRulesMap.put(testName, irRulesIdx); + } + } + } + + private void splitCompilations(String output, Class testClass) { + Pattern comp_re = Pattern.compile("\\n\\s+\\d+\\s+\\d+\\s+([% ])([s ])([! ])b([n ])\\s+\\d?\\s+\\S+\\.(?[^.]+::\\S+)\\s+(?@ \\d+\\s+)?[(]\\d+ bytes[)]"); + Matcher m = comp_re.matcher(output); + int prev = 0; + String methodName = null; + String keyMatchPrefix = testClass.getSimpleName() + "::"; + while (m.find()) { + if (methodName != null) { + if (methodName.startsWith(keyMatchPrefix)) { + String shortMethodName = methodName.split("::")[1]; + if (irRulesMap.containsKey(methodName.split("::")[1])) { + compilations.put(shortMethodName, output.substring(prev, m.start() + 1)); + } + } + + } + if (m.group("osr") != null) { + methodName = null; + } else { + methodName = m.group("name"); + } + prev = m.end(); + } + if (methodName != null) { + if (methodName.startsWith(keyMatchPrefix)) { + String shortMethodName = methodName.split("::")[1]; + if (irRulesMap.containsKey(methodName.split("::")[1])) { + compilations.put(shortMethodName, output.substring(prev)); + } + } + } + } + + public void applyRules() { + fails.clear(); + for (Method m : testClass.getDeclaredMethods()) { + IR[] irAnnos = m.getAnnotationsByType(IR.class); + if (irAnnos.length > 0) { + if (!m.isAnnotationPresent(Test.class)) { + throw new TestFormatException("Found IR annotation at non-@Test method " + m); + } + Integer[] ids = irRulesMap.get(m.getName()); + if (ids == null) { + throw new TestFrameworkException("Should find method name in validIrRulesMap for " + m); + } + if (ids.length < 1) { + throw new TestFrameworkException("Did not find any rule indices for " + m); + } + if (ids[ids.length - 1] >= irAnnos.length) { + throw new TestFrameworkException("Invalid IR rule index found in validIrRulesMap for " + m); + } + if (ids[0] != IREncodingPrinter.NO_RULE_APPLIED) { + // If -1, than there was no matching IR rule for given conditions. + applyRuleToMethod(m, irAnnos, ids); + } + } + } + if (!fails.isEmpty()) { + StringBuilder builder = new StringBuilder("\n\n"); + builder.append("One or more @IR rules failed:\n"); + builder.append("-----------------------------\n"); + fails.forEach((method, list) -> { + builder.append("- Method \"").append(method).append("\":\n"); + list.forEach(s -> builder.append(" * ").append(s.replace("\n", "\n ").trim()).append("\n")); + builder.append("\n"); + }); + builder.append("\n"); + Asserts.fail(builder.toString()); + } + } + + private void applyRuleToMethod(Method m, IR[] irAnnos, Integer[] ids) { + String testOutput = compilations.get(m.getName()); + if (TestFramework.VERBOSE) { + System.out.println(testOutput); + } + for (Integer id : ids) { + IR irAnno = irAnnos[id]; + applyFailOn(m, testOutput, irAnno, id + 1); + applyCount(m, testOutput, irAnno, id + 1); + } + } + + private void applyFailOn(Method m, String testOutput, IR irAnno, int annoId) { + if (irAnno.failOn().length != 0) { + String failOnRegex = String.join("|", IRNode.mergeCompositeNodes(irAnno.failOn())); + Pattern pattern = Pattern.compile(failOnRegex); + Matcher matcher = pattern.matcher(testOutput); + boolean found = matcher.find(); + if (found) { + addFail(m, irAnno, annoId, matcher, "contains forbidden node"); + } + } + } + + private void applyCount(Method m, String testOutput, IR irAnno, int annoId) { + if (irAnno.counts().length != 0) { + final List nodesWithCount = IRNode.mergeCompositeNodes(irAnno.counts()); + for (int i = 0; i < nodesWithCount.size(); i += 2) { + String node = nodesWithCount.get(i); + if (i + 1 == nodesWithCount.size()) { + throw new TestFormatException("Missing count for IR node \"" + node + "\" at " + m); + } + String countString = nodesWithCount.get(i + 1); + long expectedCount; + try { + expectedCount = Long.parseLong(countString); + } catch (NumberFormatException e) { + throw new TestFormatException("Provided invalid count \"" + countString + "\" for IR node \"" + node + "\" at " + m); + } + Pattern pattern = Pattern.compile(node); + Matcher matcher = pattern.matcher(testOutput); + long actualCount = matcher.results().count(); + if (expectedCount != actualCount) { + String message = "contains " + actualCount + " instead of " + expectedCount + " nodes"; + addFail(m, irAnno, annoId, matcher, message); + } + + } + } + } + + private void addFail(Method m, IR irAnno, int annoId, Matcher matcher, String message) { + matcher.reset(); + StringBuilder builder = new StringBuilder(); + builder.append("@IR rule ").append(annoId).append(": \"").append(irAnno).append("\"\n"); + builder.append("Failure: Graph for '").append(m).append(" ").append(message).append(":\n"); + matcher.results().forEach(r -> builder.append(r.group()).append("\n")); + List failsList = fails.computeIfAbsent(m, k -> new ArrayList<>()); + failsList.add(builder.toString()); + } +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java new file mode 100644 index 00000000000..03e373a4831 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java @@ -0,0 +1,92 @@ +package compiler.valhalla.framework; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + +public class IRNode { + private static final String START = "(\\d+(\\s|\\t)("; + private static final String MID = ".*)+(\\s|\\t)===.*"; + private static final String END = ")"; + + // Generic allocation + public static final String ALLOC_G = "(.*call,static wrapper for: _new_instance_Java" + END; + public static final String ALLOCA_G = "(.*call,static wrapper for: _new_array_Java" + END; + + public static final String ALLOC = "(.*precise klass .*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_instance_Java" + END; + public static final String ALLOC_OF = "(.*precise klass .*"; + private static final String ALLOC_OF_POSTFIX = ":.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_instance_Java" + END; + + public static final String STORE = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + END; + public static final String STORE_OF_CLASS = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@.*"; + private static final String STORE_OF_CLASS_POSTFIX = "(\\+|:).*" + END; + public static final String STORE_OF_FIELD = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@.*name="; + private static final String STORE_OF_FIELD_POSTFIX = ",.*" + END; + + + // Inline type allocation + public static final String ALLOCA = "(.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_array_Java" + END; + public static final String LOAD = START + "Load(B|S|I|L|F|D|P|N)" + MID + "@compiler/valhalla/inlinetypes/MyValue.*" + END; + public static final String LOADK = START + "LoadK" + MID + END; + public static final String LOOP = START + "Loop" + MID + "" + END; + public static final String COUNTEDLOOP = START + "CountedLoop\\b" + MID + "" + END; + public static final String COUNTEDLOOP_MAIN = START + "CountedLoop\\b" + MID + "main" + END; + public static final String TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*(unstable_if|predicate)" + END; + public static final String RETURN = START + "Return" + MID + "returns" + END; + public static final String LINKTOSTATIC = START + "CallStaticJava" + MID + "linkToStatic" + END; + public static final String NPE = START + "CallStaticJava" + MID + "null_check" + END; + public static final String CALL = START + "CallStaticJava" + MID + END; + public static final String STORE_INLINE_FIELDS = START + "CallStaticJava" + MID + "store_inline_type_fields" + END; + public static final String SCOBJ = "(.*# ScObj.*" + END; + public static final String LOAD_UNKNOWN_INLINE = "(.*call_leaf,runtime load_unknown_inline.*" + END; + public static final String STORE_UNKNOWN_INLINE = "(.*call_leaf,runtime store_unknown_inline.*" + END; + public static final String INLINE_ARRAY_NULL_GUARD = "(.*call,static wrapper for: uncommon_trap.*reason='null_check' action='none'.*" + END; + public static final String INTRINSIC_SLOW_PATH = "(.*call,static wrapper for: uncommon_trap.*reason='intrinsic_or_type_checked_inlining'.*" + END; + public static final String CLONE_INTRINSIC_SLOW_PATH = "(.*call,static.*java.lang.Object::clone.*" + END; + public static final String CLASS_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*class_check" + END; + public static final String NULL_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*null_check" + END; + public static final String NULL_ASSERT_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*null_assert" + END; + public static final String RANGE_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*range_check" + END; + public static final String UNHANDLED_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*unhandled" + END; + public static final String PREDICATE_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*predicate" + END; + public static final String MEMBAR = START + "MemBar" + MID + END; + public static final String CHECKCAST_ARRAY = "(cmp.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*" + END; + public static final String CHECKCAST_ARRAYCOPY = "(.*call_leaf_nofp,runtime checkcast_arraycopy.*" + END; + public static final String JLONG_ARRAYCOPY = "(.*call_leaf_nofp,runtime jlong_disjoint_arraycopy.*" + END; + public static final String FIELD_ACCESS = "(.*Field: *" + END; + public static final String SUBSTITUTABILITY_TEST = START + "CallStaticJava" + MID + "java.lang.invoke.ValueBootstrapMethods::isSubstitutable" + END; + + static List mergeCompositeNodes(String[] nodes) { + final List mergedNodes = new ArrayList<>(); + for (int i = 0; i < nodes.length; i++) { + String node = nodes[i]; + switch (node) { + case ALLOC_OF -> { + if (i + 1 == nodes.length) { + throw new TestFormatException("Must provide class name at index " + (i + 1) + " right after ALLOC_OF"); + } + mergedNodes.add(node + Pattern.quote(nodes[i + 1]) + ALLOC_OF_POSTFIX); + i++; + } + case STORE_OF_CLASS -> { + if (i + 1 == nodes.length) { + throw new TestFormatException("Must provide class name at index " + (i + 1) + " right after STORE_OF_CLASS"); + } + mergedNodes.add(node + Pattern.quote(nodes[i + 1]) + STORE_OF_CLASS_POSTFIX); + i++; + } + case STORE_OF_FIELD -> { + if (i + 1 == nodes.length) { + throw new TestFormatException("Must provide field name at index " + (i + 1) + " right after STORE_OF_FIELD"); + } + mergedNodes.add(node + Pattern.quote(nodes[i + 1]) + STORE_OF_FIELD_POSTFIX); + i++; + } + default -> { + mergedNodes.add(node); + } + } + } + return mergedNodes; + } +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java new file mode 100644 index 00000000000..96617913043 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java @@ -0,0 +1,9 @@ +package compiler.valhalla.framework; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +@Retention(RetentionPolicy.RUNTIME) + +public @interface IRs { + IR[] value(); +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSROnly.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSROnly.java new file mode 100644 index 00000000000..39fce2bb6b9 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSROnly.java @@ -0,0 +1,9 @@ +package compiler.valhalla.framework; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +// Do not enqueue the test method for compilation immediately after warmup loops have finished. Instead +// let the test method be compiled with on-stack-replacement. +@Retention(RetentionPolicy.RUNTIME) +public @interface OSROnly {} \ No newline at end of file diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java new file mode 100644 index 00000000000..286d6fbe372 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java @@ -0,0 +1,9 @@ +package compiler.valhalla.framework; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Run { + String test() default ""; +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java new file mode 100644 index 00000000000..c60144e3cb9 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java @@ -0,0 +1,54 @@ +package compiler.valhalla.framework; + +import java.util.ArrayList; + +public class Scenario { + private final ArrayList flags; + private boolean enabled; + private String disableReason; + private String output; + + public Scenario(ArrayList flags) { + this.flags = flags; + this.disableReason = ""; + } + + public boolean isIgnored() { + return enabled; + } + + public void addFlag(String flag) { + flags.add(flag.trim()); + } + + public void disable() { + enabled = false; + disableReason = "Disabled by Test."; + } + + public void disable(String reason) { + enabled = false; + disableReason = reason; + } + + public void enable() { + enabled = true; + disableReason = "Disabled by Test."; + } + + public String getIgnoreReason() { + return disableReason; + } + + public ArrayList getFlags() { + return flags; + } + + public void setOutput(String output) { + this.output = output; + } + + public String getOutput() { + return output; + } +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Skip.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Skip.java new file mode 100644 index 00000000000..5711ba28d16 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Skip.java @@ -0,0 +1,21 @@ +package compiler.valhalla.framework; + +public enum Skip { + C1_SIMPLE(1), // C1 + C1_LIMITED_PROFILE(2), // C1, invocation & backedge counters + C1_FULL_PROFILE(3), // C1, invocation & backedge counters + mdo + C2_FULL_OPTIMIZATION(4), // C2 or JVMCI + ALL(5), // Special artificial level, skip this test completely. + C1(6), // Special artificial level to exlude C1 (Level 1-3) + C2(7); // Special artificial level to exclude C2 (Level 4) + + private final int value; + + Skip(int level) { + this.value = level; + } + + public int getValue() { + return value; + } +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java new file mode 100644 index 00000000000..2353903ffe4 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java @@ -0,0 +1,18 @@ +package compiler.valhalla.framework; + +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Test { + // Regular expression used to match forbidden IR nodes + // in the C2 IR emitted for this test. + String failOn() default ""; + // Regular expressions used to match and count IR nodes. + String[] match() default {}; + int[] matchCount() default {}; + CompLevel compLevel() default CompLevel.ANY; + Skip[] skip() default {}; + int valid() default 0; +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java new file mode 100644 index 00000000000..d5f80b6c6a1 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java @@ -0,0 +1,13 @@ +package compiler.valhalla.framework; + +public class TestFormatException extends RuntimeException { + public TestFormatException(String message) { + super(message); + } + + public TestFormatException(String message, Exception e) { + super(message, e); + } +} + + diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java new file mode 100644 index 00000000000..ab58a8e57ff --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -0,0 +1,1030 @@ +package compiler.valhalla.framework; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.*; +import java.util.function.BiPredicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import jdk.test.lib.Asserts; +import jdk.test.lib.Utils; +import jdk.test.lib.management.InputArguments; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import sun.hotspot.WhiteBox; +import jdk.test.lib.Platform; + + +public class TestFramework { + public static final int DEFAULT_SCENARIOS = 6; + private static final WhiteBox WHITE_BOX; + + static { + try { + WHITE_BOX = WhiteBox.getWhiteBox(); + } catch (UnsatisfiedLinkError e) { + System.err.println("Did you set up the jtreg test properly? Ensure that at least the following settings are set:"); + System.err.println(""" + * @library /testlibrary /test/lib /compiler/whitebox / + * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions + * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI""".indent(1)); + throw e; + } + } + + static final boolean TIERED_COMPILATION = (Boolean)WHITE_BOX.getVMFlag("TieredCompilation"); + static final CompLevel TIERED_COMPILATION_STOP_AT_LEVEL = CompLevel.forValue(((Long)WHITE_BOX.getVMFlag("TieredStopAtLevel")).intValue()); + static final boolean TEST_C1 = TIERED_COMPILATION && TIERED_COMPILATION_STOP_AT_LEVEL.getValue() < Skip.C2_FULL_OPTIMIZATION.getValue(); + + // User defined settings + static final boolean XCOMP = Platform.isComp(); + private static final boolean PRINT_GRAPH = true; +// private static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); + static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "true")); + private static final boolean PRINT_TIMES = Boolean.parseBoolean(System.getProperty("PrintTimes", "false")); + + private static final boolean COMPILE_COMMANDS = Boolean.parseBoolean(System.getProperty("CompileCommands", "true")) && !XCOMP; + private static boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")) + && !XCOMP && !TEST_C1 && COMPILE_COMMANDS && Platform.isDebugBuild() && !Platform.isInt(); + private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false")) && Platform.isDebugBuild(); + private static final String SCENARIOS = System.getProperty("Scenarios", ""); + private static final String TESTLIST = System.getProperty("Testlist", ""); + private static final String EXCLUDELIST = System.getProperty("Exclude", ""); + public static final int WARMUP_ITERATIONS = Integer.parseInt(System.getProperty("Warmup", "251")); + private static final boolean DUMP_REPLAY = Boolean.parseBoolean(System.getProperty("DumpReplay", "false")); + private static final boolean GC_AFTER = Boolean.parseBoolean(System.getProperty("GCAfter", "false")); + static final boolean STRESS_CC = Boolean.parseBoolean(System.getProperty("StressCC", "false")); + private static final boolean SHUFFLE_TESTS = Boolean.parseBoolean(System.getProperty("ShuffleTests", "true")); + private static final boolean PREFER_CL_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); + private static final boolean USE_COMPILE_COMMAND_ANNOTATIONS = Boolean.parseBoolean(System.getProperty("UseCompileCommandAnnotations", "true")); + private static final boolean PRINT_VALID_IR_RULES = Boolean.parseBoolean(System.getProperty("PrintValidIRRules", "false")); + + // "jtreg -DXcomp=true" runs all the scenarios with -Xcomp. This is faster than "jtreg -javaoptions:-Xcomp". + static final boolean RUN_WITH_XCOMP = Boolean.parseBoolean(System.getProperty("Xcomp", "false")); + + private final String[] fixedDefaultFlags; + private final String[] compileCommandFlags; + private final String[] printFlags; + private final String[] verifyFlags; + private static String lastVmOutput; // Only used to test TestFramework + + protected String[] setupDefaultFlags() { + return new String[] {"-XX:-BackgroundCompilation"}; + } + + protected String[] setupCompileCommandFlags() { + return new String[] {"-XX:CompileCommand=quiet"}; + } + + protected String[] setupPrintFlags() { + return new String[] {"-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions"}; + } + + protected String[] setupVerifyFlags() { + return new String[] { + "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", "-XX:+VerifyBeforeGC", + "-XX:+VerifyAfterGC", "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing"}; + } + + static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); + static final boolean PRINT_IDEAL = WHITE_BOX.getBooleanVMFlag("PrintIdeal"); + + static final boolean G1GC = (Boolean)WHITE_BOX.getVMFlag("UseG1GC"); + static final boolean ZGC = (Boolean)WHITE_BOX.getVMFlag("UseZGC"); + static final boolean VerifyOops = (Boolean)WHITE_BOX.getVMFlag("VerifyOops"); + + private final HashMap declaredTests = new HashMap<>(); + private final LinkedHashMap allTests = new LinkedHashMap<>(); // Keep order + private final HashMap testMethodMap = new HashMap<>(); + + // Index into this array is the scenario ID. + protected final List scenarios = new ArrayList<>(); + + private final IREncodingPrinter irMatchRulePrinter; + + // Used to run scenarios + public TestFramework() { + // These flags can be overridden + fixedDefaultFlags = setupDefaultFlags(); + compileCommandFlags = setupCompileCommandFlags(); + printFlags = setupPrintFlags(); + verifyFlags = setupVerifyFlags(); + setupDefaultScenarios(); + if (PRINT_VALID_IR_RULES) { + irMatchRulePrinter = new IREncodingPrinter(); + } else { + irMatchRulePrinter = null; + } + } + + public static void main(String[] args) { + String testClassName = args[0]; + System.out.println("Framework main(), about to run test class " + testClassName); + Class testClass; + try { + testClass = Class.forName(testClassName); + } catch (Exception e) { + throw new TestRunException("Could not find test class " + testClassName, e); + } + + ArrayList> helperClasses = new ArrayList<>(); + for (int i = 1; i < args.length; i++) { + String helperClassName = args[i]; + try { + helperClasses.add(Class.forName(helperClassName)); + } catch (Exception e) { + throw new TestRunException("Could not find helper class " + helperClassName, e); + } + } + TestFramework framework = new TestFramework(); + framework.runTestsOnSameVM(testClass, helperClasses); + } + + public static void run() { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + doRun(walker.getCallerClass(), null, null); + } + + public static void run(Class testClass) { + doRun(testClass, null, null); + } + + public static void run(Class testClass, Class... helperClasses) { + doRun(testClass, Arrays.asList(helperClasses), null); + } + + public static void runWithArguments(String... commandLineArgs) { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + doRun(walker.getCallerClass(), null, Arrays.asList(commandLineArgs)); + } + + public static void runWithArguments(Class testClass, String... commandLineArgs) { + doRun(testClass, null, Arrays.asList(commandLineArgs)); + } + + private static void doRun(Class testClass, List> helperClasses, List commandLineArgs) { + TestFramework framework = new TestFramework(); + framework.startTestVM(null, testClass, helperClasses, commandLineArgs); + } + + public void runTestsOnSameVM() { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + runTestsOnSameVM(walker.getCallerClass()); + } + + private void runTestsOnSameVM(Class testClass, ArrayList> helperClasses) { + for (Class helperClass : helperClasses) { + // Process the helper classes and apply the explicit compile commands + processExplicitCompileCommands(helperClass); + } + runTestsOnSameVM(testClass); + } + + private void runTestsOnSameVM(Class testClass) { + parseTestClass(testClass); + runTests(); + } + + private String startTestVM(ArrayList scenarioFlags, Class testClass, List> helperClasses, + List commandLineArgs) { + ArrayList cmds = new ArrayList<>(Arrays.asList(InputArguments.getVmInputArgs())); + if (RUN_WITH_XCOMP) { + cmds.add( "-Xcomp"); + } + + if (VERIFY_IR && cmds.stream().anyMatch(flag -> flag.startsWith("-XX:CompileThreshold"))) { + // Disable IR verification if non-default CompileThreshold is set + if (VERBOSE) { + System.out.println("Disabled IR verification due to CompileThreshold flag"); + } + VERIFY_IR = false; + } + + if (VERIFY_IR) { + // Add print flags for IR verification + cmds.addAll(Arrays.asList(printFlags)); + addBoolOptionForClass(cmds, testClass, "PrintIdeal"); + addBoolOptionForClass(cmds, testClass, "PrintOptoAssembly"); + // Always trap for exception throwing to not confuse IR verification + cmds.add("-XX:-OmitStackTraceInFastThrow"); + cmds.add("-DPrintValidIRRules=true"); + } else { + cmds.add("-DPrintValidIRRules=false"); + } + + if (VERIFY_VM) { + cmds.addAll(Arrays.asList(verifyFlags)); + } + + cmds.addAll(Arrays.asList(fixedDefaultFlags)); + if (COMPILE_COMMANDS) { + cmds.addAll(Arrays.asList(compileCommandFlags)); + } + + if (scenarioFlags != null) { + cmds.addAll(scenarioFlags); + } + + if (commandLineArgs != null) { + // Ensured to be always set. Useful for testing the framework itself, for example @IR behavior. + cmds.addAll(commandLineArgs); + } + + // TODO: Only for debugging + if (cmds.get(0).startsWith("-agentlib")) { + cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=n,server=y"); + } + cmds.add(getClass().getCanonicalName()); + cmds.add(testClass.getCanonicalName()); + if (helperClasses != null) { + helperClasses.forEach(c -> cmds.add(c.getCanonicalName())); + } + + if (VERBOSE) { + System.out.print("Command Line: "); + cmds.forEach(flag -> System.out.print(flag + " ")); + } + + OutputAnalyzer oa; + try { + // Calls this 'main' of this class to run all specified tests with the flags specified by the scenario. + oa = ProcessTools.executeTestJvm(cmds); + } catch (Exception e) { + throw new TestRunException("Error while executing Test VM", e); + } + String output = oa.getOutput(); + if (VERBOSE) { + System.out.println(" ----- OUTPUT -----"); + System.out.println(output); + } + lastVmOutput = output; + oa.shouldHaveExitValue(0); + + if (VERIFY_IR) { + IRMatcher irMatcher = new IRMatcher(output, testClass); + irMatcher.applyRules(); + } + return output; + } + + public static String getLastVmOutput() { + return lastVmOutput; + } + private void addBoolOptionForClass(ArrayList cmds, Class testClass, String option) { + cmds.add("-XX:CompileCommand=option," + testClass.getCanonicalName() + "::*,bool," + option + ",true"); + } + +// public static void runDefaultScenarios() { +// StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); +// Class testClass = walker.getCallerClass(); +// TestFramework frameWork = new TestFramework(); +// frameWork.setupDefaultScenarios(); +// frameWork.runScenarios(testClass); +// } + + public void runScenarios() { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + runScenarios(walker.getCallerClass()); + } + + private void runScenarios(Class testClass, Class... helperClasses) { + if (!SCENARIOS.isEmpty()) { + setupFlagDefinedScenarios(); + } + + for (int i = 0; i < scenarios.size(); i++) { + Scenario scenario = scenarios.get(i); + if (scenario.isIgnored()) { + System.out.println("Scenario #" + i + " is ignored. Reason:" + scenario.getIgnoreReason()); + } + System.out.println("Run Scenario #" + i + " -------- "); + ArrayList scenarioFlags = new ArrayList<>(scenario.getFlags()); + scenario.setOutput(startTestVM(scenarioFlags, testClass, Arrays.asList(helperClasses), null)); + } + } + + private void setupFlagDefinedScenarios() { + List flagDefinedScenarios = Arrays.stream(SCENARIOS.split("\\s*,\\s*")).map(Integer::getInteger).sorted().collect(Collectors.toList()); + scenarios.forEach(s -> s.disable("Disabled by -Dscenarios")); + int lastIndex = flagDefinedScenarios.get(flagDefinedScenarios.size() - 1); + for (int scenarioId : flagDefinedScenarios) { + if (scenarioId >= scenarios.size()) { + System.out.println("Scenario #" + scenarioId + " does not exist."); + continue; + } + Scenario scenario = scenarios.get(scenarioId); + if (scenario.isIgnored()) { + continue; + } + + scenario.enable(); + } + + // All remaining flag defined scenarios are invalid + } + + public void addScenario(Scenario scenario) { + scenarios.add(scenario); + } + + public void disableDefaultScenario(int scenarioId) { + checkScenarioId(scenarioId); + scenarios.get(scenarioId).disable(); + } + + public void disableDefaultScenario(int scenarioId, String reason) { + checkScenarioId(scenarioId); + scenarios.get(scenarioId).disable(reason); + } + + public void replaceDefaultScenario(Scenario newScenario, int scenarioId) { + checkScenarioId(scenarioId); + scenarios.set(scenarioId, newScenario); + } + + public void replaceDefaultScenarios(Scenario[] newScenarios) { + scenarios.clear(); + scenarios.addAll(Arrays.asList(newScenarios)); + } + + public void addFlagsToDefaultScenario(int scenarioId, String... flags) { + checkScenarioId(scenarioId); + Arrays.stream(flags).forEach(f -> scenarios.get(scenarioId).addFlag(f)); + } + + public String getScenarioOutput(int scenarioId) { + checkScenarioId(scenarioId); + return scenarios.get(scenarioId).getOutput(); + } + + private void checkScenarioId(int scenarioId) { + if (scenarioId < 0 || scenarioId >= scenarios.size()) { + throw new TestFormatException("Invalid default scenario id " + scenarioId + ". Must be in [0, " + (scenarios.size() - 1) + "]."); + } + } + + // Can be overridden, for example by Valhalla + protected void setupDefaultScenarios() { + scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( + "-XX:+IgnoreUnrecognizedVMOptions")))); + scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( + "-XX:CompileCommand=quiet")))); + scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( + "-Xmx256m")))); + scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( + "-DVerifyIR=false")))); + scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( + "-XX:+StressGCM")))); + scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( + "-XX:+StressLCM")))); + } + + private void parseTestClass(Class clazz) { + addReplay(); + processExplicitCompileCommands(clazz); + setupTestMethodMap(clazz); + setupTests(clazz); + setupCheckAndRunMethods(clazz); + + // All remaining tests are simple base tests without check or specific way to run them + declaredTests.forEach((key, value) -> allTests.put(key, new BaseTest(value))); + declaredTests.clear(); + testMethodMap.clear(); + } + + private void addReplay() { + if (DUMP_REPLAY) { + // Generate replay compilation files + String directive = "[{ match: \"*.*\", DumpReplay: true }]"; + if (WHITE_BOX.addCompilerDirective(directive) != 1) { + throw new TestFormatException("Failed to add DUMP_REPLAY directive"); + } + } + } + + private void processExplicitCompileCommands(Class clazz) { + if (USE_COMPILE_COMMAND_ANNOTATIONS) { + Method[] methods = clazz.getDeclaredMethods(); + for (Method m : methods) { + applyIndependentCompilationCommands(m); + } + + // Only force compilation now because above annotations affect inlining + for (Method m : methods) { + applyForceCompileCommand(m); + } + } + } + + private void applyIndependentCompilationCommands(Method m) { + ForceInline forceInlineAnno = getAnnotation(m, ForceInline.class); + DontInline dontInlineAnno = getAnnotation(m, DontInline.class); + ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); + DontCompile dontCompileAnno = getAnnotation(m, DontCompile.class); + Test testAnno = getAnnotation(m, Test.class); + if (testAnno != null && Stream.of(forceCompileAnno, dontCompileAnno, forceInlineAnno, dontInlineAnno).anyMatch(Objects::nonNull)) { + throw new TestFormatException("Not allowed to use explicit compile command annotations (@ForceInline, @DontInline," + + "@ForceCompile or @DontCompile) together with @Test at " + m + ". Use compLevel and skip in @Test for fine tuning."); + } + if (Stream.of(forceCompileAnno, dontCompileAnno, dontInlineAnno).filter(Objects::nonNull).count() > 1) { + if (dontCompileAnno != null && dontInlineAnno != null) { + throw new TestFormatException("@DontInline is implicitely done with @DontCompile annotation at " + m); + } + throw new TestFormatException("Cannot mix @ForceInline, @DontInline and @DontCompile at the same time at " + m); + } + if (forceCompileAnno != null && dontCompileAnno != null) { + throw new TestFormatException("Cannot have @ForceCompile and @DontCompile at the same time at " + m); + } + // First handle inline annotations + if (dontInlineAnno != null) { + WHITE_BOX.testSetDontInlineMethod(m, true); + } else if (forceInlineAnno != null) { + WHITE_BOX.testSetForceInlineMethod(m, true); + } + if (dontCompileAnno != null) { + dontCompileMethod(m); + } + + if (STRESS_CC) { + // Exclude some methods from compilation with C2 to stress test the calling convention + if (Utils.getRandomInstance().nextBoolean()) { + System.out.println("Excluding from C2 compilation: " + m); + WHITE_BOX.makeMethodNotCompilable(m, CompLevel.C2_FULL_OPTIMIZATION.getValue(), false); + } + } + } + + private void dontCompileMethod(Method m) { + WHITE_BOX.makeMethodNotCompilable(m, CompLevel.ANY.getValue(), true); + WHITE_BOX.makeMethodNotCompilable(m, CompLevel.ANY.getValue(), false); + WHITE_BOX.testSetDontInlineMethod(m, true); + } + + private void applyForceCompileCommand(Method m) { + ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); + if (forceCompileAnno != null) { + enqueueMethodForCompilation(m, forceCompileAnno.compLevel()); + } + } + + // Can be called from tests for non-@Test methods + public static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { + if (getAnnotation(m, Test.class) != null) { + throw new TestFormatException("Cannot call enqueueMethodForCompilation() for @Test annotated method " + m); + } + TestFrameworkUtils.enqueueMethodForCompilation(m ,compLevel); + } + + private void setupTestMethodMap(Class clazz) { + Arrays.stream(clazz.getDeclaredMethods()).forEach(m -> { + Test testAnno = getAnnotation(m, Test.class); + if (testAnno != null) { + if (testMethodMap.containsKey(m.getName())) { + throw new TestFormatException("Cannot overload two @Test methods " + m + " and " + testMethodMap.get(m.getName())); + } + testMethodMap.put(m.getName(), m); + } else { + if (m.isAnnotationPresent(IR.class)) { + throw new TestFormatException("Found @IR annotation on non-@Test method " + m); + } + } + }); + } + + private void setupTests(Class clazz) { + for (Method m : testMethodMap.values()) { + Argument[] arguments = Argument.getArguments(m); + addTest(clazz, m, arguments); + } + if (PRINT_VALID_IR_RULES) { + irMatchRulePrinter.dump(); + } + } + + private void addTest(Class clazz, Method m, Argument[] arguments) { + Test testAnno = getAnnotation(m, Test.class); + if (testAnno == null) { + throw new TestFormatException(m + " must be a method with a @Test annotation"); + } + + Check checkAnno = getAnnotation(m, Check.class); + Run runAnno = getAnnotation(m, Run.class); + if (checkAnno != null || runAnno != null) { + throw new TestFormatException(m.getName() + " has invalid @compiler.valhalla.new_inlinetypes.Check or @compiler.valhalla.new_inlinetypes.Run annotation while @compiler.valhalla.new_inlinetypes.Test annotation is present."); + } + + Warmup warmup = getAnnotation(m, Warmup.class); + int warmupIterations = WARMUP_ITERATIONS; + if (warmup != null) { + warmupIterations = warmup.value(); + } + + boolean osrOnly = getAnnotation(m, OSROnly.class) != null; + + if (PRINT_VALID_IR_RULES) { + irMatchRulePrinter.emitRuleEncoding(m); + } + // Don't inline test methods + WHITE_BOX.testSetDontInlineMethod(m, true); + DeclaredTest test = new DeclaredTest(m, testAnno, arguments, clazz, warmupIterations, osrOnly); + declaredTests.put(m, test); + } + + private void setupCheckAndRunMethods(Class clazz) { + for (Method m : clazz.getDeclaredMethods()) { + Check checkAnno = getAnnotation(m, Check.class); + Run runAnno = getAnnotation(m, Run.class); + + if (checkAnno != null) { + addCheckedTest(m, checkAnno, runAnno); + } else if (runAnno != null) { + addCustomRunTest(m, runAnno); + } + } + } + + private void addCheckedTest(Method m, Check checkAnno, Run runAnno) { + if (runAnno != null) { + throw new TestFormatException(m.getName() + " has invalid @compiler.valhalla.new_inlinetypes.Run annotation while @compiler.valhalla.new_inlinetypes.Check annotation is present."); + } + Method testMethod = testMethodMap.get(checkAnno.test()); + if (testMethod == null) { + throw new TestFormatException("Did not find associated test method " + checkAnno.test() + " for @compiler.valhalla.new_inlinetypes.Check at " + m.getName()); + } + if (allTests.containsKey(testMethod)) { + BaseTest baseTest = allTests.get(testMethod); + throw new TestFormatException("Method " + m.getName() + " and " + baseTest.getAssociatedTestName() + + " cannot both reference test method " + testMethod.getName()); + } + DeclaredTest test = declaredTests.remove(testMethod); + if (test == null) { + throw new TestFormatException("Missing @compiler.valhalla.new_inlinetypes.Test annotation for associated test method " + checkAnno.test() + " for @compiler.valhalla.new_inlinetypes.Check at " + m.getName()); + } + applyCompileCommands(m); + // Don't inline check methods + WHITE_BOX.testSetDontInlineMethod(m, true); + CheckedTest checkedTest = new CheckedTest(test, m, checkAnno); + allTests.put(testMethod, checkedTest); + } + + private void applyCompileCommands(Method m) { + ForceInline forceInlineAnno = getAnnotation(m, ForceInline.class); + DontInline dontInlineAnno = getAnnotation(m, DontInline.class); + ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); + DontCompile dontCompileAnno = getAnnotation(m, DontCompile.class); + if (Stream.of(forceCompileAnno, dontCompileAnno, forceCompileAnno, dontInlineAnno).anyMatch(Objects::nonNull)) { + applyIndependentCompilationCommands(m); + applyForceCompileCommand(m); + } else { + // Implicitely @DontCompile if nothing specified + dontCompileMethod(m); + } + } + + private void addCustomRunTest(Method m, Run runAnno) { + Method testMethod = testMethodMap.get(runAnno.test()); + if (testMethod == null) { + throw new TestFormatException("Did not find associated test method " + runAnno.test() + " for @Run at " + m.getName()); + } + DeclaredTest test = declaredTests.remove(testMethod); + if (test == null) { + throw new TestFormatException("Missing @Test annotation for associated test method " + runAnno.test() + " for @Run at " + m.getName()); + } + if (test.hasArguments()) { + throw new TestFormatException("Invalid @Arguments annotation for associated test method " + runAnno.test() + " for @Run at " + m.getName()); + } + if (m.getParameterCount() != 1 || !m.getParameterTypes()[0].equals(TestInfo.class)) { + throw new TestFormatException("@Run method " + m.getName() + " must specify exactly one TestInfo parameter"); + } + applyCompileCommands(m); + // Don't inline run methods + WHITE_BOX.testSetDontInlineMethod(m, true); + CustomRunTest customRunTest = new CustomRunTest(test, m, runAnno); + allTests.put(m, customRunTest); + } + + public static T getAnnotation(Method m, Class c) { + T[] annos = m.getAnnotationsByType(c); + if (annos.length > 1) { + throw new TestFormatException(m + " has duplicated annotations"); + } + return Arrays.stream(annos).findFirst().orElse(null); + } + + public void runTests() { + TreeMap durations = (PRINT_TIMES || VERBOSE) ? new TreeMap<>() : null; + long startTime = System.nanoTime(); + Collection testCollection = allTests.values(); + if (SHUFFLE_TESTS) { + // Execute tests in random order (execution sequence affects profiling) + ArrayList shuffledList = new ArrayList<>(allTests.values()); + Collections.shuffle(shuffledList); + testCollection = shuffledList; + } + for (BaseTest test : testCollection) { + test.run(); + if (PRINT_TIMES || VERBOSE) { + long endTime = System.nanoTime(); + long duration = (endTime - startTime); + durations.put(duration, test.getAssociatedTestName()); + if (VERBOSE) { + System.out.println("Done " + test.getAssociatedTestName() + ": " + duration + " ns = " + (duration / 1000000) + " ms"); + } + } + if (GC_AFTER) { + System.out.println("doing GC"); + System.gc(); + } + } + + // Print execution times + if (PRINT_TIMES) { + System.out.println("\n\nTest execution times:"); + for (Map.Entry entry : durations.entrySet()) { + System.out.format("%-10s%15d ns\n", entry.getValue() + ":", entry.getKey()); + } + } + } + + enum TriState { + Maybe, + Yes, + No + } + + public static boolean isC2Compiled(Method m) { + return compiledByC2(m) == TriState.Yes; + } + + public static void assertDeoptimizedByC2(Method m) { + if (compiledByC2(m) == TriState.Yes) { + throw new TestRunException("Expected to have deoptimized"); + } + } + + public static void assertCompiledByC2(Method m) { + if (compiledByC2(m) == TriState.No) { + throw new TestRunException("Expected to be compiled"); + } + } + + private static TriState compiledByC2(Method m) { + if (!USE_COMPILER || XCOMP || TEST_C1 || + (STRESS_CC && !WHITE_BOX.isMethodCompilable(m, CompLevel.C2_FULL_OPTIMIZATION.getValue(), false))) { + return TriState.Maybe; + } + if (WHITE_BOX.isMethodCompiled(m, false) && + WHITE_BOX.getMethodCompilationLevel(m, false) >= CompLevel.C2_FULL_OPTIMIZATION.getValue()) { + return TriState.Yes; + } + return TriState.No; + } +} + +// Errors in the framework +class TestFrameworkException extends RuntimeException { + public TestFrameworkException(String message) { + super(message); + } + public TestFrameworkException(String message, Exception e) { + super(message, e); + } +} + +class ParsedComparator> { + private final String strippedString; + private final BiPredicate predicate; + + public ParsedComparator(String strippedString, BiPredicate predicate) { + this.strippedString = strippedString; + this.predicate = predicate; + } + + public String getStrippedString() { + return strippedString; + } + + public BiPredicate getPredicate() { + return predicate; + } +} + +class DeclaredTest { + private final Method testMethod; + public Method getTestMethod() { + return testMethod; + } + + private final Argument[] arguments; + private final Object invocationTarget; + private final int warmupIterations; + private final CompLevel requestedCompLevel; + private final boolean osrOnly; + + public DeclaredTest(Method testMethod, Test testAnnotation, Argument[] arguments, Class c, int warmupIterations, boolean osrOnly) { + // Make sure we can also call non-public or public methods in package private classes + testMethod.setAccessible(true); + this.testMethod = testMethod; + this.requestedCompLevel = testAnnotation.compLevel(); + this.arguments = arguments; + this.warmupIterations = warmupIterations; + this.osrOnly = osrOnly; + if (Modifier.isStatic(testMethod.getModifiers())) { + invocationTarget = null; + } else { + try { + Constructor constructor = c.getDeclaredConstructor(); + constructor.setAccessible(true); + invocationTarget = constructor.newInstance(); + } catch (Exception e) { + throw new TestRunException("Could not create instance of " + c + + ". Make sure there is a constructor without arguments.", e); + } + } + } + + public CompLevel getRequestedCompLevel() { + return requestedCompLevel; + } + + public int getWarmupIterations() { + return warmupIterations; + } + + public boolean isOSROnly() { + return osrOnly; + } + + public boolean hasArguments() { + return arguments != null; + } + + public void printFixedRandomArguments() { + if (hasArguments()) { + boolean hasRandomArgs = false; + StringBuilder builder = new StringBuilder("Random Arguments: "); + for (int i = 0; i < arguments.length; i++) { + Argument argument = arguments[i]; + if (argument.isFixedRandom()) { + hasRandomArgs = true; + builder.append("arg ").append(i).append(": ").append(argument.getArgument()).append(", "); + } + } + if (hasRandomArgs) { + // Drop the last comma and space. + builder.setLength(builder.length() - 2); + System.out.println(builder.toString()); + } + } + } + + public Object invokeWithSpecifiedArguments() { + try { + if (hasArguments()) { + Object[] args = Arrays.stream(arguments).map(Argument::getArgument).toArray(); + return testMethod.invoke(invocationTarget, args); + } else { + return testMethod.invoke(invocationTarget); + } + } catch (Exception e) { + throw new TestRunException("There was an error while invoking @Test method " + testMethod, e); + } + } + + public Object invoke(Object obj, Object... args) { + try { + return testMethod.invoke(obj, args); + } catch (Exception e) { + throw new TestRunException("There was an error while invoking @Test method " + testMethod, e); + } + } + + public Object getInvocationTarget() { + return invocationTarget; + } + + public void checkCompilationLevel() { + int level = WhiteBox.getWhiteBox().getMethodCompilationLevel(testMethod); + Asserts.assertEQ(level, TestFrameworkUtils.compLevelToInt(requestedCompLevel), "Unexpected compilation level for " + testMethod); + } +} + +class BaseTest { + protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private static final int OSR_TEST_TIMEOUT = Integer.parseInt(System.getProperty("OSRTestTimeOut", "5000")); + + protected final DeclaredTest test; + protected final TestInfo testInfo; + + public BaseTest(DeclaredTest test) { + this.test = test; + this.testInfo = new TestInfo(); + } + public String getAssociatedTestName() { + return test.getTestMethod().getName(); + } + + /** + * Run the associated test + */ + public void run() { +// ByteArrayOutputStream systemOutStream = new ByteArrayOutputStream(); +// PrintStream ps = new PrintStream(systemOutStream); +// PrintStream old = System.out; +// System.setOut(ps); + + test.printFixedRandomArguments(); + for (int i = 0; i < test.getWarmupIterations(); i++) { + runMethod(); + } + testInfo.setWarmUpFinished(); + + if (test.isOSROnly()) { + compileOSRAndRun(); + } else { + compileNormallyAndRun(); + } +// System.setOut(old); +// System.out.print(systemOutStream.toString()); + } + + protected void runMethod() { + verify(testInfo, test.invokeWithSpecifiedArguments()); + } + + protected void compileOSRAndRun() { + final boolean maybeCodeBufferOverflow = (TestFramework.TEST_C1 && TestFramework.VerifyOops); + final long started = System.currentTimeMillis(); + boolean stateCleared = false; + while (true) { + long elapsed = System.currentTimeMillis() - started; + Method testMethod = test.getTestMethod(); + int level = WHITE_BOX.getMethodCompilationLevel(testMethod); + if (maybeCodeBufferOverflow && elapsed > 5000 + && (!WHITE_BOX.isMethodCompiled(testMethod, false) || level != test.getRequestedCompLevel().getValue())) { + System.out.println("Temporarily disabling VerifyOops"); + try { + WHITE_BOX.setBooleanVMFlag("VerifyOops", false); + if (!stateCleared) { + WHITE_BOX.clearMethodState(testMethod); + stateCleared = true; + } + runMethod(); + } finally { + WHITE_BOX.setBooleanVMFlag("VerifyOops", true); + System.out.println("Re-enabled VerifyOops"); + } + } else { + runMethod(); + } + + boolean b = WHITE_BOX.isMethodCompiled(testMethod, false); + if (TestFramework.VERBOSE) { + System.out.println("Is " + testMethod + " compiled? " + b); + } + if (b || TestFramework.XCOMP || TestFramework.STRESS_CC || !TestFramework.USE_COMPILER) { + // Don't control compilation if -Xcomp is enabled, or if compiler is disabled + break; + } + Asserts.assertTrue(OSR_TEST_TIMEOUT < 0 || elapsed < OSR_TEST_TIMEOUT, test + " not compiled after " + OSR_TEST_TIMEOUT + " ms"); + } + } + + private void compileNormallyAndRun() { + final boolean maybeCodeBufferOverflow = (TestFramework.TEST_C1 && TestFramework.VerifyOops); + final Method testMethod = test.getTestMethod(); + TestFrameworkUtils.enqueueMethodForCompilation(test); + if (maybeCodeBufferOverflow && !WHITE_BOX.isMethodCompiled(testMethod, false)) { + // Let's disable VerifyOops temporarily and retry. + WHITE_BOX.setBooleanVMFlag("VerifyOops", false); + WHITE_BOX.clearMethodState(testMethod); + TestFrameworkUtils.enqueueMethodForCompilation(test); + WHITE_BOX.setBooleanVMFlag("VerifyOops", true); + } + if (!TestFramework.STRESS_CC && TestFramework.USE_COMPILER) { + for (int i = 0; !WHITE_BOX.isMethodCompiled(testMethod, false) && i < 10 ; i++) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + throw new TestFormatException("Error while waiting for compilation to be completed of " + testMethod); + } + } + Asserts.assertTrue(WHITE_BOX.isMethodCompiled(testMethod, false), testMethod + " not compiled after waiting 1s"); + test.checkCompilationLevel(); + } + runMethod(); + } + + /** + * Verify the result + */ + public void verify(TestInfo testInfo, Object result) { /* no verification in BaseTests */ } +} + +class CheckedTest extends BaseTest { + Method checkMethod; + Check checkSpecification; + + public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecification) { + super(test); + // Make sure we can also call non-public or public methods in package private classes + checkMethod.setAccessible(true); + this.checkMethod = checkMethod; + this.checkSpecification = checkSpecification; + } + + @Override + public void verify(TestInfo testInfo, Object result) { + boolean shouldVerify = false; + switch (checkSpecification.when()) { + case EACH_INVOCATION -> shouldVerify = true; + case C2_COMPILED -> shouldVerify = !testInfo.isWarmUp(); + } + if (shouldVerify) { + try { + checkMethod.invoke(test.getInvocationTarget(), testInfo, result); + } catch (Exception e) { + throw new TestRunException("There was an error while invoking @Check method " + checkMethod, e); + } + } + } +} + +class CustomRunTest extends BaseTest { + Method runMethod; + Run runSpecification; + + public CustomRunTest(DeclaredTest test, Method runMethod, Run runSpecification) { + super(test); + // Make sure we can also call non-public or public methods in package private classes + runMethod.setAccessible(true); + this.runMethod = runMethod; + this.runSpecification = runSpecification; + } + + /** + * Do not directly run the test but rather the run method that is responsible for invoking the actual test. + */ + @Override + protected void runMethod() { + try { + runMethod.invoke(test.getInvocationTarget(), testInfo); + } catch (Exception e) { + throw new TestRunException("There was an error while invoking @Run method " + runMethod, e); + } + } +} + + +class TestFrameworkUtils { + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private static final boolean FLIP_C1_C2 = Boolean.parseBoolean(System.getProperty("FlipC1C2", "false")); + + public static void enqueueMethodForCompilation(DeclaredTest test) { + enqueueMethodForCompilation(test.getTestMethod(), test.getRequestedCompLevel()); + } + + // Used for non-@Tests, can also be called from other places in tests. + public static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { + compLevel = restrictCompLevel(compLevel); + if (TestFramework.VERBOSE) { + System.out.println("enqueueMethodForCompilation " + m + ", level = " + compLevel); + } + WHITE_BOX.enqueueMethodForCompilation(m, compLevel.getValue()); + } + + public static int compLevelToInt(CompLevel compLevel) { + return TestFrameworkUtils.restrictCompLevel(compLevel).getValue(); + } + + // Get the appropriate level as permitted by the test scenario and VM options. + private static CompLevel restrictCompLevel(CompLevel compLevel) { + switch (compLevel) { + case ANY -> compLevel = CompLevel.C2_FULL_OPTIMIZATION; + case C1_SIMPLE, C1_LIMITED_PROFILE, C1_FULL_PROFILE -> { + if (FLIP_C1_C2) { + // Effectively treat all (compLevel = C1_*) as (compLevel = C2) + compLevel = CompLevel.C2_FULL_OPTIMIZATION; + } + } + case C2_FULL_OPTIMIZATION -> { + if (FLIP_C1_C2) { + // Effectively treat all (compLevel = C2) as (compLevel = C1_SIMPLE) + compLevel = CompLevel.C1_SIMPLE; + } + } + } + + if (!TestFramework.TEST_C1 && compLevel.getValue() < CompLevel.C2_FULL_OPTIMIZATION.getValue()) { + compLevel = CompLevel.C2_FULL_OPTIMIZATION; + } + if (TestFramework.TIERED_COMPILATION && compLevel.getValue() > TestFramework.TIERED_COMPILATION_STOP_AT_LEVEL.getValue()) { + compLevel = TestFramework.TIERED_COMPILATION_STOP_AT_LEVEL; + } + return compLevel; + } +} \ No newline at end of file diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFrameworkValhalla.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFrameworkValhalla.java new file mode 100644 index 00000000000..4d9ce555e7b --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFrameworkValhalla.java @@ -0,0 +1,76 @@ +package compiler.valhalla.framework; + +import jdk.test.lib.Platform; +import jdk.test.lib.management.InputArguments; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import sun.hotspot.WhiteBox; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + +public class TestFrameworkValhalla extends TestFramework { + + @Override + protected void setupDefaultScenarios() { + scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( + "-XX:-UseACmpProfile", + "-XX:+AlwaysIncrementalInline", + "-XX:FlatArrayElementMaxOops=5", + "-XX:FlatArrayElementMaxSize=-1", + "-XX:-UseArrayLoadStoreProfile", + "-XX:InlineFieldMaxFlatSize=-1", + "-XX:+InlineTypePassFieldsAsArgs", + "-XX:+InlineTypeReturnedAsFields")))); + scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( + "-XX:-UseACmpProfile", + "-XX:-UseCompressedOops", + "-XX:FlatArrayElementMaxOops=5", + "-XX:FlatArrayElementMaxSize=-1", + "-XX:-UseArrayLoadStoreProfile", + "-XX:InlineFieldMaxFlatSize=-1", + "-XX:-InlineTypePassFieldsAsArgs", + "-XX:-InlineTypeReturnedAsFields")))); + scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( + "-XX:-UseACmpProfile", + "-XX:-UseCompressedOops", + "-XX:FlatArrayElementMaxOops=0", + "-XX:FlatArrayElementMaxSize=0", + "-XX:-UseArrayLoadStoreProfile", + "-XX:InlineFieldMaxFlatSize=-1", + "-XX:+InlineTypePassFieldsAsArgs", + "-XX:+InlineTypeReturnedAsFields", + "-XX:+StressInlineTypeReturnedAsFields")))); + scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( + "-DVerifyIR=false", + "-XX:+AlwaysIncrementalInline", + "-XX:FlatArrayElementMaxOops=0", + "-XX:FlatArrayElementMaxSize=0", + "-XX:InlineFieldMaxFlatSize=0", + "-XX:+InlineTypePassFieldsAsArgs", + "-XX:+InlineTypeReturnedAsFields")))); + scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( + "-DVerifyIR=false", + "-XX:FlatArrayElementMaxOops=-1", + "-XX:FlatArrayElementMaxSize=-1", + "-XX:InlineFieldMaxFlatSize=0", + "-XX:+InlineTypePassFieldsAsArgs", + "-XX:-InlineTypeReturnedAsFields", + "-XX:-ReduceInitialCardMarks")))); + scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( + "-XX:-UseACmpProfile", + "-XX:+AlwaysIncrementalInline", + "-XX:FlatArrayElementMaxOops=5", + "-XX:FlatArrayElementMaxSize=-1", + "-XX:-UseArrayLoadStoreProfile", + "-XX:InlineFieldMaxFlatSize=-1", + "-XX:-InlineTypePassFieldsAsArgs", + "-XX:-InlineTypeReturnedAsFields")))); + } +} \ No newline at end of file diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java new file mode 100644 index 00000000000..4b72346fc70 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java @@ -0,0 +1,34 @@ +package compiler.valhalla.framework; + +import java.util.Random; + +public class TestInfo { + private boolean toggleBool = false; + private boolean onWarmUp = true; + private static final Random random = new Random(); + + public boolean toggleBoolean() { + toggleBool = !toggleBool; + return toggleBool; + } + + public static int getRandomInt() { + return random.nextInt() % 1000; + } + + public static long getRandomLong() { + return random.nextLong() % 1000; + } + + public static double getRandomDouble() { + return random.nextDouble() % 1000; + } + + public boolean isWarmUp() { + return onWarmUp; + } + + public void setWarmUpFinished() { + onWarmUp = false; + } +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java new file mode 100644 index 00000000000..eebe4d8428e --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java @@ -0,0 +1,11 @@ +package compiler.valhalla.framework; + +public class TestRunException extends RuntimeException { + public TestRunException(String message) { + super(message); + } + + public TestRunException(String message, Exception e) { + super(message, e); + } +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java new file mode 100644 index 00000000000..302d05a7b3a --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java @@ -0,0 +1,7 @@ +package compiler.valhalla.framework; + +public class VMFlag { + public static final String G1GC = "UseG1GC"; + public static final String ZGC = "UseZGC"; + public static final String AVX = "UseAVX"; +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java new file mode 100644 index 00000000000..da830c2c7c1 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java @@ -0,0 +1,11 @@ +package compiler.valhalla.framework; + +public class VMFlagValhalla { + public static final String InlineTypePassFieldsAsArgsOn = "InlineTypePassFieldsAsArgsOn"; + public static final String InlineTypePassFieldsAsArgsOff = "InlineTypePassFieldsAsArgsOff"; + public static final String InlineTypeArrayFlattenOn = "InlineTypeArrayFlattenOn"; + public static final String InlineTypeArrayFlattenOff = "InlineTypeArrayFlattenOff"; + public static final String InlineTypeReturnedAsFieldsOn = "InlineTypeReturnedAsFieldsOn"; + public static final String InlineTypeReturnedAsFieldsOff = "InlineTypeReturnedAsFieldsOff"; + +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java new file mode 100644 index 00000000000..05e61ab3a0a --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java @@ -0,0 +1,10 @@ +package compiler.valhalla.framework; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +// Number of warmup iterations +@Retention(RetentionPolicy.RUNTIME) +public @interface Warmup { + int value(); +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java new file mode 100644 index 00000000000..02b9253731a --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -0,0 +1,688 @@ +package compiler.valhalla.framework.tests; + +import compiler.valhalla.framework.*; + +import java.util.Arrays; +import java.util.stream.Stream; + +public class TestBasics { + public static void main(String[] args) { + TestFramework framework = new TestFramework(); + // Run on same VM to make this test easier as we are not interested in any output processing. + framework.runTestsOnSameVM(); + + if (wasExecuted) { + throw new RuntimeException("Executed non @Test method"); + } + for (int i = 0; i < testExecuted.length; i++) { + int value = testExecuted[i]; + if (value != TestFramework.WARMUP_ITERATIONS + 1) { + // Warmups + 1 C2 compiled invocation + throw new RuntimeException("Test " + i + " was executed " + value + " times stead of " + + TestFramework.WARMUP_ITERATIONS + 1 + " times." ); + } + } + } + +// @Test +// @Arguments({ArgumentValue.DEFAULT, ArgumentValue.FALSE, ArgumentValue.NUMBER_42, ArgumentValue.RANDOM_ALL, ArgumentValue.RANDOM_ONCE, ArgumentValue.BOOLEAN_TOGGLE}) +// public int test(int arg1, boolean arg2, double arg3, double arg4, int arg5, boolean arg6) { +// return 0; +// } +// +// // Useful for quick checking, nothing fancy going on. This method is optional. +// @Check(test="test", when=CheckAt.C2_COMPILED) +// // Must match method 'test' when removing '_check'. Could also think about matching in annotation, e.g. @Check(test="test2"). +// public void test_check(int result /* must match return argument of 'test', possible to check? */) { +// // This method runs in interpreter, DontCompile. +// // Check that there is a method 'test' with @Test, no method 'test_check' or when present no @Run at it (bad style though, better use check in annotation?), +// // 'test' has non-void return (if void, what do you need the check for then?) +// // If 'test' has arguments but no @Arguments annotation, framework takes default arguments (bad style though). +// // Framework executes 'test' with warmup (specified or default). +// // This method is then called from framework once after 'test' compiled or once when 'test' is called the first time by framework and after 'test' is compiled +//// Asserts.assertEQ(result, 0); +// } +// +// @Test +// public void test2(int arg1, boolean arg2, int arg3, int arg4) { +// } +// +// // Optional method. +// // Useful when more complex/changing arguments are required. Framework calls this method in interpreter and let it handle how to call the method +// // 'test'. Framework could verify that this method has at least one call to 'test2'? +// @Run(test="test2") +// // Must match method 'test2' when removing '_run'. Could also think about matching in annotation, e.g. @Run(test="test2"). +// public void test2_run(TestInfo info) { +// // This method runs in interpreter, DontCompile +// // Check that there is a method 'test2' with @Test. +// // Check that no @Arguments present in 'test2' (not useful when specifying here how to call the method) +// // Called each time by framework, specifies how to run test +// if (info.isWarmUp()) { +// test2(34, info.toggleBoolean(), info.getRandomInt(), 0); +// } else { +// test2(12, true, info.getRandomInt(), -555); +// } +// } + + static boolean wasExecuted = false; + static int[] testExecuted = new int[61]; + boolean lastToggleBoolean = true; + long[] nonFloatingRandomNumbers = new long[10]; + double[] floatingRandomNumbers = new double[10]; + Boolean[] randomBooleans = new Boolean[64]; + + private void clearNonFloatingRandomNumbers() { + nonFloatingRandomNumbers = new long[10]; + } + + private void clearFloatingRandomNumbers() { + floatingRandomNumbers = new double[10]; + } + + private void clearRandomBooleans() { + randomBooleans = new Boolean[64]; + } + + @Test + public void test() { + testExecuted[0]++; + } + + // Not a test + public void noTest() { + wasExecuted = true; + } + + // Not a test + public void test2() { + wasExecuted = true; + } + + // Can overload when not a @Test + public static void test2(int i) { + wasExecuted = true; + } + + @Test + public static void staticTest() { + testExecuted[1]++; + } + + @Test + public final void finalTest() { + testExecuted[2]++; + } + + @Test + public int returnValueTest() { + testExecuted[3]++; + return 4; + } + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void byteDefaultArgument(byte x) { + testExecuted[4]++; + if (x != 0) { + throw new RuntimeException("Must be 0"); + } + } + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void shortDefaultArgument(short x) { + testExecuted[5]++; + if (x != 0) { + throw new RuntimeException("Must be 0"); + } + } + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void intDefaultArgument(int x) { + testExecuted[6]++; + if (x != 0) { + throw new RuntimeException("Must be 0"); + } + } + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void longDefaultArgument(long x) { + testExecuted[7]++; + if (x != 0L) { + throw new RuntimeException("Must be 0"); + } + } + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void floatDefaultArgument(float x) { + testExecuted[8]++; + if (x != 0.0f) { + throw new RuntimeException("Must be 0.0"); + } + } + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void doubleDefaultArgument(double x) { + testExecuted[9]++; + if (x != 0.0f) { + throw new RuntimeException("Must be 0.0"); + } + } + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void charDefaultArgument(char x) { + testExecuted[10]++; + if (x != '\u0000') { + throw new RuntimeException("Must be \u0000"); + } + } + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void booleanDefaultArgument(boolean x) { + testExecuted[11]++; + if (x) { + throw new RuntimeException("Must be false"); + } + } + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void stringObjectDefaultArgument(String x) { + testExecuted[12]++; + if (x == null || x.length() != 0) { + throw new RuntimeException("Default string object must be non-null and having a length of zero"); + } + } + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void defaultObjectDefaultArgument(DefaultObject x) { + testExecuted[13]++; + if (x == null || x.i != 4) { + throw new RuntimeException("Default object must not be null and its i field must be 4"); + } + } + + @Test + @Arguments(ArgumentValue.NUMBER_42) + public void byte42(byte x) { + testExecuted[14]++; + if (x != 42) { + throw new RuntimeException("Must be 42"); + } + } + + @Test + @Arguments(ArgumentValue.NUMBER_42) + public void short42(short x) { + testExecuted[15]++; + if (x != 42) { + throw new RuntimeException("Must be 42"); + } + } + + @Test + @Arguments(ArgumentValue.NUMBER_42) + public void int42(int x) { + testExecuted[16]++; + if (x != 42) { + throw new RuntimeException("Must be 42"); + } + } + + @Test + @Arguments(ArgumentValue.NUMBER_42) + public void long42(long x) { + testExecuted[17]++; + if (x != 42) { + throw new RuntimeException("Must be 42"); + } + } + + @Test + @Arguments(ArgumentValue.NUMBER_42) + public void float42(float x) { + testExecuted[18]++; + if (x != 42.0) { + throw new RuntimeException("Must be 42"); + } + } + + @Test + @Arguments(ArgumentValue.NUMBER_42) + public void double42(double x) { + testExecuted[19]++; + if (x != 42.0) { + throw new RuntimeException("Must be 42"); + } + } + + @Test + @Arguments(ArgumentValue.FALSE) + public void booleanFalse(boolean x) { + testExecuted[20]++; + if (x) { + throw new RuntimeException("Must be false"); + } + } + + @Test + @Arguments(ArgumentValue.TRUE) + public void booleanTrue(boolean x) { + testExecuted[21]++; + if (!x) { + throw new RuntimeException("Must be true"); + } + } + + @Test + @Arguments(ArgumentValue.RANDOM_ONCE) + public void randomByte(byte x) { + testExecuted[22]++; + } + + @Test + @Arguments(ArgumentValue.RANDOM_ONCE) + public void randomShort(short x) { + testExecuted[23]++; + } + + @Test + @Arguments(ArgumentValue.RANDOM_ONCE) + public void randomInt(int x) { + testExecuted[24]++; + } + + @Test + @Arguments(ArgumentValue.RANDOM_ONCE) + public void randomLong(long x) { + testExecuted[25]++; + } + + @Test + @Arguments(ArgumentValue.RANDOM_ONCE) + public void randomFloat(float x) { + testExecuted[26]++; + } + + @Test + @Arguments(ArgumentValue.RANDOM_ONCE) + public void randomDouble(double x) { + testExecuted[27]++; + } + + // Not executed + public void randomNotExecutedTest(double x) { + wasExecuted = true; + } + + @Test + @Arguments(ArgumentValue.RANDOM_ONCE) + public void randomBoolean(boolean x) { + testExecuted[28]++; + } + + @Test + @Arguments(ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE) + public void booleanToggleFirstFalse(boolean x) { + if (testExecuted[29] == 0) { + // First invocation + if (x) { + throw new RuntimeException("BOOLEAN_TOGGLE_FIRST_FALSE must be false on first invocation"); + } + } else if (x == lastToggleBoolean) { + throw new RuntimeException("BOOLEAN_TOGGLE_FIRST_FALSE did not toggle"); + } + lastToggleBoolean = x; + testExecuted[29]++; + } + + @Test + @Arguments(ArgumentValue.RANDOM_EACH) + public void randomEachByte(byte x) { + checkNonFloatingRandomNumber(x, testExecuted[30]); + testExecuted[30]++; + } + + @Test + @Arguments(ArgumentValue.RANDOM_EACH) + public void randomEachShort(short x) { + checkNonFloatingRandomNumber(x, testExecuted[31]); + testExecuted[31]++; + } + + @Test + @Arguments(ArgumentValue.RANDOM_EACH) + public void randomEachInt(int x) { + checkNonFloatingRandomNumber(x, testExecuted[32]); + testExecuted[32]++; + } + + @Test + @Arguments(ArgumentValue.RANDOM_EACH) + public void randomEachLong(long x) { + checkNonFloatingRandomNumber(x, testExecuted[33]); + testExecuted[33]++; + } + + @Test + @Arguments(ArgumentValue.RANDOM_EACH) + public void randomEachChar(char x) { + checkNonFloatingRandomNumber(x, testExecuted[34]); + testExecuted[34]++; + } + + @Test + @Arguments(ArgumentValue.RANDOM_EACH) + public void randomEachFloat(float x) { + checkFloatingRandomNumber(x, testExecuted[35]); + testExecuted[35]++; + } + + @Test + @Arguments(ArgumentValue.RANDOM_EACH) + public void randomEachDouble(double x) { + checkFloatingRandomNumber(x, testExecuted[36]); + testExecuted[36]++; + } + + @Test + @Arguments(ArgumentValue.RANDOM_EACH) + public void randomEachBoolean(boolean x) { + checkRandomBoolean(x, testExecuted[37]); + testExecuted[37]++; + } + + private void checkNonFloatingRandomNumber(long x, int invocationCount) { + int mod10 = invocationCount % 10; + if (invocationCount > 0 && mod10 == 0) { + // Not first invocation + // Check the last 10 numbers and ensure that there are at least 2 different ones. + // All numbers are equal? Very unlikely nd we should really consider to play the lottery... + long first = nonFloatingRandomNumbers[0]; + if (Arrays.stream(nonFloatingRandomNumbers).allMatch(n -> n == first)) { + throw new RuntimeException("RANDOM_EACH does not generate random integer numbers"); + } + clearNonFloatingRandomNumbers(); + } + nonFloatingRandomNumbers[mod10] = x; + } + + private void checkFloatingRandomNumber(double x, int invocationCount) { + int mod10 = invocationCount % 10; + if (invocationCount > 0 && mod10 == 0) { + // Not first invocation + // Check the last 10 numbers and ensure that there are at least 2 different ones. + // All numbers are equal? Very unlikely nd we should really consider to play the lottery... + double first = floatingRandomNumbers[0]; + if (Arrays.stream(floatingRandomNumbers).allMatch(n -> n == first)) { + throw new RuntimeException("RANDOM_EACH does not generate random floating point numbers"); + } + clearFloatingRandomNumbers(); + } + floatingRandomNumbers[mod10] = x; + } + + private void checkRandomBoolean(boolean x, int invocationCount) { + int mod64 = invocationCount % 64; + if (invocationCount > 0 && mod64 == 0) { + // Not first invocation + // Check the last 64 booleans and ensure that there are at least one true and one false. + // All booleans are equal? Very unlikely (chance of 2^64) and we should really consider + // to play the lottery... + if (Arrays.stream(randomBooleans).allMatch(b -> b == randomBooleans[0])) { + throw new RuntimeException("RANDOM_EACH does not generate random booleans"); + } + clearRandomBooleans(); + } + randomBooleans[mod64] = x; + } + + + @Test + @Arguments(ArgumentValue.NUMBER_MINUS_42) + public void byteMinus42(byte x) { + testExecuted[38]++; + if (x != -42) { + throw new RuntimeException("Must be -42"); + } + } + + @Test + @Arguments(ArgumentValue.NUMBER_MINUS_42) + public void shortMinus42(short x) { + testExecuted[39]++; + if (x != -42) { + throw new RuntimeException("Must be -42"); + } + } + + @Test + @Arguments(ArgumentValue.NUMBER_MINUS_42) + public void intMinus42(int x) { + testExecuted[40]++; + if (x != -42) { + throw new RuntimeException("Must be -42"); + } + } + + @Test + @Arguments(ArgumentValue.NUMBER_MINUS_42) + public void longMinus42(long x) { + testExecuted[41]++; + if (x != -42) { + throw new RuntimeException("Must be -42"); + } + } + + @Test + @Arguments(ArgumentValue.NUMBER_MINUS_42) + public void floatMinus42(float x) { + testExecuted[42]++; + if (x != -42.0) { + throw new RuntimeException("Must be -42"); + } + } + + @Test + @Arguments(ArgumentValue.NUMBER_MINUS_42) + public void doubleMinus42(double x) { + testExecuted[43]++; + if (x != -42.0) { + throw new RuntimeException("Must be -42"); + } + } + + @Test + @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) + public void twoArgsDefault1(byte x, short y) { + testExecuted[44]++; + if (x != 0 || y != 0) { + throw new RuntimeException("Both must be 0"); + } + } + + @Test + @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) + public void twoArgsDefault2(int x, short y) { + testExecuted[45]++; + if (x != 0 || y != 0) { + throw new RuntimeException("Both must be 0"); + } + } + + @Test + @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) + public void twoArgsDefault3(short x, long y) { + testExecuted[46]++; + if (x != 0 || y != 0) { + throw new RuntimeException("Both must be 0"); + } + } + + @Test + @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) + public void twoArgsDefault4(float x, boolean y) { + testExecuted[47]++; + if (x != 0.0 || y) { + throw new RuntimeException("Must be 0 and false"); + } + } + + @Test + @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) + public void twoArgsDefault5(boolean x, char y) { + testExecuted[48]++; + if (x || y != '\u0000') { + throw new RuntimeException("Must be false and \u0000"); + } + } + + @Test + @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) + public void twoArgsDefault6(char x, byte y) { + testExecuted[49]++; + if (x != '\u0000' || y != 0) { + throw new RuntimeException("Must be\u0000 and 0"); + } + } + + @Test + @Arguments({ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE}) + public void twoArgsRandomOnce(char x, byte y) { + testExecuted[50]++; + } + + @Test + @Arguments({ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, + ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, + ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, + ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE}) + public void checkRandomOnceDifferentArgs(int a, int b, int c, int d, int e, int f, int g, int h) { + if (Stream.of(a, b, c, d, e, f, g, h).allMatch(i -> i == a)) { + throw new RuntimeException("RANDOM_ONCE does not produce random values for different arguments"); + } + testExecuted[51]++; + } + + @Test + @Arguments({ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, + ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, + ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, + ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE}) + public void checkMixedRandoms1(byte a, short b, int c, long d, char e, boolean f, float g, double h) { + testExecuted[52]++; + } + + @Test + @Arguments({ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_EACH, + ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_EACH, + ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_EACH, + ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_EACH}) + public void checkMixedRandoms2(byte a, short b, int c, long d, char e, boolean f, float g, double h) { + testExecuted[53]++; + } + + @Test + @Arguments({ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, + ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_EACH, + ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_EACH, + ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_ONCE}) + public void checkMixedRandoms3(byte a, short b, int c, long d, char e, boolean f, float g, double h) { + testExecuted[54]++; + } + + @Test + @Arguments({ArgumentValue.NUMBER_42, ArgumentValue.NUMBER_42, + ArgumentValue.NUMBER_42, ArgumentValue.NUMBER_42, + ArgumentValue.NUMBER_42, ArgumentValue.NUMBER_42}) + public void check42Mix1(byte a, short b, int c, long d, float e, double f) { + if (a != 42 || b != 42 || c != 42 || d != 42 || e != 42.0 || f != 42.0) { + throw new RuntimeException("Must all be 42"); + } + testExecuted[55]++; + } + + @Test + @Arguments({ArgumentValue.NUMBER_MINUS_42, ArgumentValue.NUMBER_MINUS_42, + ArgumentValue.NUMBER_MINUS_42, ArgumentValue.NUMBER_MINUS_42, + ArgumentValue.NUMBER_MINUS_42, ArgumentValue.NUMBER_MINUS_42}) + public void check42Mix2(byte a, short b, int c, long d, float e, double f) { + if (a != -42 || b != -42 || c != -42 || d != -42 || e != -42.0 || f != -42.0) { + throw new RuntimeException("Must all be -42"); + } + testExecuted[56]++; + } + + @Test + @Arguments({ArgumentValue.NUMBER_MINUS_42, ArgumentValue.NUMBER_42, + ArgumentValue.NUMBER_MINUS_42, ArgumentValue.NUMBER_MINUS_42, + ArgumentValue.NUMBER_42, ArgumentValue.NUMBER_MINUS_42}) + public void check42Mix3(byte a, short b, int c, long d, float e, double f) { + if (a != -42 || b != 42 || c != -42 || d != -42 || e != 42.0 || f != -42.0) { + throw new RuntimeException("Do not match the right 42 version"); + } + testExecuted[57]++; + } + + + @Test + @Arguments(ArgumentValue.BOOLEAN_TOGGLE_FIRST_TRUE) + public void booleanToggleFirstTrue(boolean x) { + if (testExecuted[58] == 0) { + // First invocation + if (!x) { + throw new RuntimeException("BOOLEAN_TOGGLE_FIRST_FALSE must be false on first invocation"); + } + } else if (x == lastToggleBoolean) { + throw new RuntimeException("BOOLEAN_TOGGLE_FIRST_FALSE did not toggle"); + } + lastToggleBoolean = x; + testExecuted[58]++; + } + + @Test + @Arguments({ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE, ArgumentValue.BOOLEAN_TOGGLE_FIRST_TRUE}) + public void checkTwoToggles(boolean b1, boolean b2) { + if (testExecuted[59] == 0) { + // First invocation + if (b1 || !b2) { + throw new RuntimeException("BOOLEAN_TOGGLES have wrong initial value"); + } + } else if (b1 == b2) { + throw new RuntimeException("Boolean values must be different"); + } else if (b1 == lastToggleBoolean) { + throw new RuntimeException("Booleans did not toggle"); + } + lastToggleBoolean = b1; + testExecuted[59]++; + } + + @Test + @Arguments({ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE, ArgumentValue.FALSE, + ArgumentValue.TRUE, ArgumentValue.BOOLEAN_TOGGLE_FIRST_TRUE}) + public void booleanMix(boolean b1, boolean b2, boolean b3, boolean b4) { + if (testExecuted[60] == 0) { + // First invocation + if (b1 || b2 || !b3 || !b4) { + throw new RuntimeException("BOOLEAN_TOGGLES have wrong initial value"); + } + } else if (b1 == b4) { + throw new RuntimeException("Boolean values must be different"); + } else if (b1 == lastToggleBoolean) { + throw new RuntimeException("Booleans did not toggle"); + } + lastToggleBoolean = b1; + testExecuted[60]++; + } +} + +class DefaultObject { + int i = 4; +} \ No newline at end of file diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java new file mode 100644 index 00000000000..7978e38ee3c --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java @@ -0,0 +1,334 @@ +package compiler.valhalla.framework.tests; + +import compiler.valhalla.framework.*; +import jdk.test.lib.Asserts; + +import java.lang.reflect.Array; +import java.util.Arrays; +import java.util.List; + +public class TestIRMatching { + private static final String SHOULD_NOT_REACH_MESSAGE = "should not reach"; + static int[] testExecuted = new int[61]; + + public static void main(String[] args) { + // Run with -DPrintValidIRRules=true to simulate TestVM + runFailOnTests(AndOr1.class, "test1(int)", "CallStaticJava", "-XX:SuspendRetryCount=50", "-XX:+UsePerfData", "-XX:+UseTLAB"); + runFailOnTests(AndOr1.class, "test1(int)", "CallStaticJava", "-XX:SuspendRetryCount=50", "-XX:+UsePerfData", "-XX:+UseTLAB"); + runFailOnTests(AndOr1.class, "test2()", "CallStaticJava", "-XX:SuspendRetryCount=50", "-XX:-UsePerfData", "-XX:+UseTLAB"); + + TestFramework.runWithArguments(AndOr1.class, "-XX:SuspendRetryCount=52", "-XX:+UsePerfData", "-XX:+UseTLAB"); + + TestFramework.runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=50"); + + findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 0, 21); + findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", -1, -1); + TestFramework.runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=49"); + findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 4, 6, 13, 18); + findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); + TestFramework.runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=51"); + findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 7, 12, 19, 21); + findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 4, 7, 11, 16, 20, 22); + + TestFramework.runWithArguments(MultipleFailOnGood.class, "-XX:SuspendRetryCount=50"); + + runFailOnTests(MultipleFailOnBad.class, "fail1()", "Store", "-XX:SuspendRetryCount=50"); + runFailOnTests(MultipleFailOnBad.class, "fail2()", "CallStaticJava", "-XX:SuspendRetryCount=51"); + runFailOnTests(MultipleFailOnBad.class, "fail3()", "Store", "-XX:SuspendRetryCount=52"); + runFailOnTests(MultipleFailOnBad.class, "fail4()", "Store", "-XX:SuspendRetryCount=53"); + runFailOnTests(MultipleFailOnBad.class, "fail5()", "Store", "-XX:SuspendRetryCount=54"); + runFailOnTests(MultipleFailOnBad.class, "fail6()", new String[] {"MyClass", "call,static wrapper for: _new_instance_Java"}, "-XX:SuspendRetryCount=55"); + runFailOnTests(MultipleFailOnBad.class, "fail7()", new String[] {"MyClass", "call,static wrapper for: _new_instance_Java"}, "-XX:SuspendRetryCount=56"); + runFailOnTests(MultipleFailOnBad.class, "fail8()", new String[] {"MyClassSub", "call,static wrapper for: _new_instance_Java"}, "-XX:SuspendRetryCount=57"); + runFailOnTests(MultipleFailOnBad.class, "fail9()", new String[] {"Store", "CallStaticJava"}, "-XX:SuspendRetryCount=58"); + TestFramework.runWithArguments(GoodCount.class, "-XX:SuspendRetryCount=50"); + } + + private static void runFailOnTests(Class c, String methodName, String node, String... args) { + try { + TestFramework.runWithArguments(c, args); + shouldNotReach(); + } catch (RuntimeException e) { + shouldContain(e, c.getSimpleName() + "." + methodName, "forbidden", node); + } + } + + + private static void runFailOnTests(Class c, String methodName, String[] matches, String... args) { + try { + TestFramework.runWithArguments(c, args); + shouldNotReach(); + } catch (RuntimeException e) { + String[] allMatches = Arrays.copyOf(matches, matches.length + 2); + allMatches[matches.length] = c.getSimpleName() + "." + methodName; + allMatches[matches.length + 1] = "forbidden"; + shouldContain(e, allMatches); + } + } + + private static void shouldNotReach() { + Asserts.fail(SHOULD_NOT_REACH_MESSAGE); + } + + private static void shouldContain(RuntimeException e, String... strings) { + String message = e.getMessage(); + if (e.getMessage().equals(SHOULD_NOT_REACH_MESSAGE)) { + throw e; + } + Arrays.stream(strings).forEach(s -> Asserts.assertTrue(message.contains(s), "Did not find \"" + s + "\" in:\n" + message)); + } + + + public static void findIrIds(String output, String method, int... numbers) { + StringBuilder builder = new StringBuilder(); + builder.append(method); + 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(","); + builder.append(j); + } + } + Asserts.assertTrue(output.contains(builder.toString()), "Could not find encoding: \"" + builder.toString() + "\n"); + } +} + +class AndOr1 { + @Test + @Arguments(ArgumentValue.DEFAULT) + @IR(applyIfAnd={"UsePerfData", "true", "SuspendRetryCount", "50", "UseTLAB", "true"}, failOn={IRNode.CALL}) + public void test1(int i) { + dontInline(); + } + + @Test + @IR(applyIfOr={"UsePerfData", "false", "SuspendRetryCount", "51", "UseTLAB", "false"}, failOn={IRNode.CALL}) + public void test2() { + dontInline(); + } + + @DontInline + private void dontInline() { + } +} + +class MultipleFailOnGood { + private int iFld; + private MyClassSub myClassSub = new MyClassSub(); + + @Test + @IR(applyIf={"SuspendRetryCount", "50"}, failOn={IRNode.STORE, IRNode.CALL}) + @IR(failOn={IRNode.STORE, IRNode.CALL}) + @IR(applyIfOr={"SuspendRetryCount", "99", "SuspendRetryCount", "100"}, failOn={IRNode.RETURN, IRNode.CALL}) // Not applied + public void good1() { + forceInline(); + } + + @Test + @IR(failOn={IRNode.STORE, IRNode.CALL}) + @IR(applyIfNot={"SuspendRetryCount", "20"}, failOn={IRNode.ALLOC}) + @IR(applyIfNot={"SuspendRetryCount", "< 100"}, failOn={IRNode.ALLOC_OF, "Test"}) + public void good2() { + forceInline(); + } + + @Test + @IR(failOn={IRNode.STORE_OF_CLASS, "Test", IRNode.CALL}) + @IR(applyIfNot={"SuspendRetryCount", "20"}, failOn={IRNode.ALLOC}) + @IR(applyIfNot={"SuspendRetryCount", "< 100"}, failOn={IRNode.ALLOC_OF, "Test"}) + public void good3() { + forceInline(); + } + + @Test + @IR(failOn={IRNode.CALL, IRNode.STORE_OF_CLASS, "UnknownClass"}) + public void good4() { + iFld = 42; + } + + @Test + @IR(failOn={IRNode.STORE_OF_FIELD, "xFld", IRNode.CALL}) + public void good5() { + iFld = 42; + } + + @Test + @IR(failOn={IRNode.STORE_OF_CLASS, "MyClass"}) // Needs exact match to fail + public void good6() { + myClassSub.iFld = 42; + } + + @Test + @IR(failOn={IRNode.STORE_OF_CLASS, "MyClassSub"}) // Static write is with Class and not MySubClass + public void good7() { + MyClassSub.iFldStatic = 42; + } + + @ForceInline + private void forceInline() { + } +} + +class MultipleFailOnBad { + private int iFld; + private MyClass myClass; + @Test + @IR(applyIf={"SuspendRetryCount", "50"}, failOn={IRNode.STORE, IRNode.CALL}) + public void fail1() { + iFld = 42; + } + + @Test + @IR(applyIf={"SuspendRetryCount", "51"}, failOn={IRNode.STORE, IRNode.CALL}) + public void fail2() { + dontInline(); + } + + @Test + @IR(applyIf={"SuspendRetryCount", "52"}, failOn={IRNode.CALL, IRNode.STORE_OF_CLASS, "MultipleFailOnBad", IRNode.ALLOC}) + public void fail3() { + iFld = 42; + } + + @Test + @IR(applyIf={"SuspendRetryCount", "53"}, failOn={IRNode.STORE_OF_CLASS, "compiler/valhalla/framework/tests/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) + public void fail4() { + iFld = 42; + } + + @Test + @IR(applyIf={"SuspendRetryCount", "54"}, failOn={IRNode.STORE_OF_FIELD, "iFld", IRNode.CALL, IRNode.ALLOC}) + public void fail5() { + iFld = 42; + } + + @Test + @IR(applyIf={"SuspendRetryCount", "55"}, failOn={IRNode.STORE_OF_CLASS, "MyClass", IRNode.ALLOC}) + public void fail6() { + myClass = new MyClass(); + } + + @Test + @IR(applyIf={"SuspendRetryCount", "56"}, failOn={IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "MyClass"}) + public void fail7() { + myClass = new MyClass(); + } + + @Test + @IR(applyIf={"SuspendRetryCount", "57"}, failOn={IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "compiler/valhalla/framework/tests/MyClassSub"}) + public void fail8() { + myClass = new MyClassSub(); + } + + @Test + @IR(applyIf={"SuspendRetryCount", "58"}, failOn={IRNode.STORE, IRNode.CALL}) + public void fail9() { + iFld = 42; + dontInline(); + } + + @DontInline + private void dontInline() { + } +} + +// Called with -XX:SuspendRetryCount=X. +class Comparisons { + // Applies all IR rules if SuspendRetryCount=50 + @Test + @IR(applyIf={"SuspendRetryCount", "50"}) // Index 0 + @IR(applyIf={"SuspendRetryCount", "=50"}) + @IR(applyIf={"SuspendRetryCount", "= 50"}) + @IR(applyIf={"SuspendRetryCount", " = 50"}) + @IR(applyIf={"SuspendRetryCount", "<=50"}) // Index 4 + @IR(applyIf={"SuspendRetryCount", "<= 50"}) + @IR(applyIf={"SuspendRetryCount", " <= 50"}) + @IR(applyIf={"SuspendRetryCount", ">=50"}) // Index 7 + @IR(applyIf={"SuspendRetryCount", ">= 50"}) + @IR(applyIf={"SuspendRetryCount", " >= 50"}) + @IR(applyIf={"SuspendRetryCount", ">49"}) + @IR(applyIf={"SuspendRetryCount", "> 49"}) + @IR(applyIf={"SuspendRetryCount", " > 49"}) + @IR(applyIf={"SuspendRetryCount", "<51"}) // Index 13 + @IR(applyIf={"SuspendRetryCount", "< 51"}) + @IR(applyIf={"SuspendRetryCount", " < 51"}) + @IR(applyIf={"SuspendRetryCount", "!=51"}) + @IR(applyIf={"SuspendRetryCount", "!= 51"}) + @IR(applyIf={"SuspendRetryCount", " != 51"}) + @IR(applyIf={"SuspendRetryCount", "!=49"}) + @IR(applyIf={"SuspendRetryCount", "!= 49"}) + @IR(applyIf={"SuspendRetryCount", " != 49"}) // Index 21 + public void testMatchAllIf50() { + } + + // Applies no IR rules if SuspendRetryCount=50 + @Test + @IR(applyIf={"SuspendRetryCount", "49"}) // Index 0 + @IR(applyIf={"SuspendRetryCount", "=49"}) + @IR(applyIf={"SuspendRetryCount", "= 49"}) + @IR(applyIf={"SuspendRetryCount", " = 49"}) + @IR(applyIf={"SuspendRetryCount", "51"}) // Index 4 + @IR(applyIf={"SuspendRetryCount", "=51"}) + @IR(applyIf={"SuspendRetryCount", "= 51"}) + @IR(applyIf={"SuspendRetryCount", " = 51"}) + @IR(applyIf={"SuspendRetryCount", "<=49"}) // Index 8 + @IR(applyIf={"SuspendRetryCount", "<= 49"}) + @IR(applyIf={"SuspendRetryCount", " <= 49"}) + @IR(applyIf={"SuspendRetryCount", ">=51"}) // Index 11 + @IR(applyIf={"SuspendRetryCount", ">= 51"}) + @IR(applyIf={"SuspendRetryCount", " >= 51"}) + @IR(applyIf={"SuspendRetryCount", ">50"}) + @IR(applyIf={"SuspendRetryCount", "> 50"}) + @IR(applyIf={"SuspendRetryCount", " > 50"}) + @IR(applyIf={"SuspendRetryCount", "<50"}) // Index 17 + @IR(applyIf={"SuspendRetryCount", "< 50"}) + @IR(applyIf={"SuspendRetryCount", " < 50"}) + @IR(applyIf={"SuspendRetryCount", "!=50"}) + @IR(applyIf={"SuspendRetryCount", "!= 50"}) + @IR(applyIf={"SuspendRetryCount", " != 50"}) // Index 22 + public void testMatchNoneIf50() { + } +} + + +class GoodCount { + int iFld; + int iFld2; + MyClass myClass = new MyClass(); + + @Test + @IR(applyIf={"SuspendRetryCount", "50"}, counts={IRNode.STORE, "1"}) + public void good1() { + iFld = 3; + } + + @Test + @IR(counts={IRNode.STORE, "2"}) + public void good2() { + iFld = 3; + iFld2 = 4; + } + + @Test + @IR(counts={IRNode.STORE, "2", IRNode.STORE_OF_CLASS, "GoodCount", "2"}) + public void good3() { + iFld = 3; + iFld2 = 4; + } + + @Test + @IR(counts={IRNode.STORE_OF_FIELD, "iFld", "1", IRNode.STORE, "2", IRNode.STORE_OF_CLASS, "GoodCount", "2"}) + public void good4() { + iFld = 3; + iFld2 = 4; + } +} + +class MyClass { + int iFld; +} +class MyClassSub extends MyClass { + int iFld; + static int iFldStatic; +} \ No newline at end of file diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java new file mode 100644 index 00000000000..78c22b0a011 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java @@ -0,0 +1,65 @@ +package compiler.valhalla.framework.tests; + +import compiler.valhalla.framework.*; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Arrays; +import java.util.stream.Stream; + +public class TestPackagePrivate { + public static void main(String[] args) { + TestFramework.run(PackagePrivate.class); + } +} + +// @Test +// @Arguments({ArgumentValue.DEFAULT, ArgumentValue.FALSE, ArgumentValue.NUMBER_42, ArgumentValue.RANDOM_ALL, ArgumentValue.RANDOM_ONCE, ArgumentValue.BOOLEAN_TOGGLE}) +// public int test(int arg1, boolean arg2, double arg3, double arg4, int arg5, boolean arg6) { +// return 0; +// } +// +// // Useful for quick checking, nothing fancy going on. This method is optional. +// @Check(test="test", when=CheckAt.C2_COMPILED) +// // Must match method 'test' when removing '_check'. Could also think about matching in annotation, e.g. @Check(test="test2"). +// public void test_check(int result /* must match return argument of 'test', possible to check? */) { +// // This method runs in interpreter, DontCompile. +// // Check that there is a method 'test' with @Test, no method 'test_check' or when present no @Run at it (bad style though, better use check in annotation?), +// // 'test' has non-void return (if void, what do you need the check for then?) +// // If 'test' has arguments but no @Arguments annotation, framework takes default arguments (bad style though). +// // Framework executes 'test' with warmup (specified or default). +// // This method is then called from framework once after 'test' compiled or once when 'test' is called the first time by framework and after 'test' is compiled +//// Asserts.assertEQ(result, 0); +// } +// +// @Test +// public void test2(int arg1, boolean arg2, int arg3, int arg4) { +// } +// +// // Optional method. +// // Useful when more complex/changing arguments are required. Framework calls this method in interpreter and let it handle how to call the method +// // 'test'. Framework could verify that this method has at least one call to 'test2'? +// @Run(test="test2") +// // Must match method 'test2' when removing '_run'. Could also think about matching in annotation, e.g. @Run(test="test2"). +// public void test2_run(TestInfo info) { +// // This method runs in interpreter, DontCompile +// // Check that there is a method 'test2' with @Test. +// // Check that no @Arguments present in 'test2' (not useful when specifying here how to call the method) +// // Called each time by framework, specifies how to run test +// if (info.isWarmUp()) { +// test2(34, info.toggleBoolean(), info.getRandomInt(), 0); +// } else { +// test2(12, true, info.getRandomInt(), -555); +// } +// } + + class PackagePrivate { + @Test + public void test() { + } + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void test2(int x) { + } +} \ No newline at end of file diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java new file mode 100644 index 00000000000..cd5232423e6 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java @@ -0,0 +1,52 @@ +package compiler.valhalla.framework.tests; + +import compiler.valhalla.framework.ArgumentValue; +import compiler.valhalla.framework.Arguments; +import compiler.valhalla.framework.Test; +import compiler.valhalla.framework.TestFramework; + +public class TestScenarios { + public static final String[] TEST_KEYS = { "test-key0", "test-key1" }; + + public static void main(String[] args) { + TestFramework framework = new TestFramework(); + framework.runScenarios(); + final int expectedInvocationsPerTest = TestFramework.WARMUP_ITERATIONS + 1; + for (int i = 0; i < TestFramework.DEFAULT_SCENARIOS; i++) { + String output = framework.getScenarioOutput(i); + for (int j = 0; j < TEST_KEYS.length; j++) { + int invocationCount = getMatches(output, TEST_KEYS[j]); + if (invocationCount != expectedInvocationsPerTest) { + // Warmups + 1 C2 compiled invocation * number of default scenarios + throw new RuntimeException("Test " + j + " was executed " + invocationCount + " times stead of " + + expectedInvocationsPerTest + 1 + " times." ); + } + } + } + } + + // How many times do wie find 'toMatch' in 'target'? + private static int getMatches(String target, String toMatch) { + int fromIndex = 0; + int count = 0; + while (true) { + fromIndex = target.indexOf(toMatch, fromIndex); + if (fromIndex == -1) { + break; + } + count++; + fromIndex += toMatch.length(); + } + return count; + } + @Test + public void test() { + System.out.println(TEST_KEYS[0]); + } + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void test2(int i) { + System.out.println(TEST_KEYS[1]); + } +} From b6e4b982f6d3674bad6aa680a1c40e10e4d02f2d Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 15 Jan 2021 13:49:48 +0100 Subject: [PATCH 002/131] Fix @Run and @Check, added more IR rules, refactorings, added more tests --- .../valhalla/framework/IRMatcher.java | 7 +- .../compiler/valhalla/framework/IRNode.java | 74 +++-- .../valhalla/framework/TestFramework.java | 93 ++++-- .../valhalla/framework/tests/TestBasics.java | 145 +++++++- .../framework/tests/TestIRMatching.java | 313 ++++++++++++++---- 5 files changed, 509 insertions(+), 123 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java index da983b3a9f6..69c6b7d0b5a 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java @@ -4,10 +4,8 @@ import java.lang.reflect.Method; import java.util.*; -import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.stream.Stream; class IRMatcher { private final Map irRulesMap; @@ -133,10 +131,11 @@ private void applyRuleToMethod(Method m, IR[] irAnnos, Integer[] ids) { private void applyFailOn(Method m, String testOutput, IR irAnno, int annoId) { if (irAnno.failOn().length != 0) { - String failOnRegex = String.join("|", IRNode.mergeCompositeNodes(irAnno.failOn())); + String failOnRegex = String.join("|", IRNode.mergeNodes(irAnno.failOn())); Pattern pattern = Pattern.compile(failOnRegex); Matcher matcher = pattern.matcher(testOutput); boolean found = matcher.find(); + System.out.println(failOnRegex); if (found) { addFail(m, irAnno, annoId, matcher, "contains forbidden node"); } @@ -145,7 +144,7 @@ private void applyFailOn(Method m, String testOutput, IR irAnno, int annoId) { private void applyCount(Method m, String testOutput, IR irAnno, int annoId) { if (irAnno.counts().length != 0) { - final List nodesWithCount = IRNode.mergeCompositeNodes(irAnno.counts()); + final List nodesWithCount = IRNode.mergeNodes(irAnno.counts()); for (int i = 0; i < nodesWithCount.size(); i += 2) { String node = nodesWithCount.get(i); if (i + 1 == nodesWithCount.size()) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java index 03e373a4831..b8e9a84b282 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java @@ -5,34 +5,39 @@ import java.util.regex.Pattern; public class IRNode { - private static final String START = "(\\d+(\\s|\\t)("; - private static final String MID = ".*)+(\\s|\\t)===.*"; + private static final String START = "(\\d+(\\s){2}("; + private static final String MID = ".*)+(\\s){2}===.*"; private static final String END = ")"; - // Generic allocation - public static final String ALLOC_G = "(.*call,static wrapper for: _new_instance_Java" + END; - public static final String ALLOCA_G = "(.*call,static wrapper for: _new_array_Java" + END; - - public static final String ALLOC = "(.*precise klass .*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_instance_Java" + END; + public static final String ALLOC = "(.*precise klass .*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_instance_Java" + END; public static final String ALLOC_OF = "(.*precise klass .*"; - private static final String ALLOC_OF_POSTFIX = ":.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_instance_Java" + END; + private static final String ALLOC_OF_POSTFIX = ":.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_instance_Java" + END; + + public static final String ALLOC_ARRAY = "(.*precise klass \\[L.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_array_Java" + END; + public static final String ALLOC_ARRAY_OF = "(.*precise klass \\[L.*"; + private static final String ALLOC_ARRAY_OF_POSTFIX = ";:.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_array_Java" + END; - public static final String STORE = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + END; - public static final String STORE_OF_CLASS = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@.*"; + public static final String STORE = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + END; + public static final String STORE_OF_CLASS = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@.*"; private static final String STORE_OF_CLASS_POSTFIX = "(\\+|:).*" + END; - public static final String STORE_OF_FIELD = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@.*name="; + public static final String STORE_OF_FIELD = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@.*name="; private static final String STORE_OF_FIELD_POSTFIX = ",.*" + END; + public static final String LOAD = START + "Load(B|S|I|L|F|D|P|N)" + MID + END; + public static final String LOAD_OF_CLASS = START + "Load(B|C|S|I|L|F|D|P|N)" + MID + "@.*"; + private static final String LOAD_OF_CLASS_POSTFIX = "(\\+|:).*" + END; + public static final String LOAD_OF_FIELD = START + "Load(B|C|S|I|L|F|D|P|N)" + MID + "@.*name="; + private static final String LOAD_OF_FIELD_POSTFIX = ",.*" + END; + public static final String LOOP = START + "Loop" + MID + "" + END; + public static final String COUNTEDLOOP = START + "CountedLoop\\b" + MID + "" + END; + // Inline type allocation public static final String ALLOCA = "(.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_array_Java" + END; - public static final String LOAD = START + "Load(B|S|I|L|F|D|P|N)" + MID + "@compiler/valhalla/inlinetypes/MyValue.*" + END; public static final String LOADK = START + "LoadK" + MID + END; - public static final String LOOP = START + "Loop" + MID + "" + END; - public static final String COUNTEDLOOP = START + "CountedLoop\\b" + MID + "" + END; public static final String COUNTEDLOOP_MAIN = START + "CountedLoop\\b" + MID + "main" + END; public static final String TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*(unstable_if|predicate)" + END; - public static final String RETURN = START + "Return" + MID + "returns" + END; + public static final String RETURN = START + "Return" + MID + END; public static final String LINKTOSTATIC = START + "CallStaticJava" + MID + "linkToStatic" + END; public static final String NPE = START + "CallStaticJava" + MID + "null_check" + END; public static final String CALL = START + "CallStaticJava" + MID + END; @@ -56,37 +61,42 @@ public class IRNode { public static final String FIELD_ACCESS = "(.*Field: *" + END; public static final String SUBSTITUTABILITY_TEST = START + "CallStaticJava" + MID + "java.lang.invoke.ValueBootstrapMethods::isSubstitutable" + END; - static List mergeCompositeNodes(String[] nodes) { + static List mergeNodes(String[] nodes) { final List mergedNodes = new ArrayList<>(); - for (int i = 0; i < nodes.length; i++) { + for (int i = 0; i < nodes.length; i += 2) { String node = nodes[i]; switch (node) { case ALLOC_OF -> { - if (i + 1 == nodes.length) { - throw new TestFormatException("Must provide class name at index " + (i + 1) + " right after ALLOC_OF"); - } - mergedNodes.add(node + Pattern.quote(nodes[i + 1]) + ALLOC_OF_POSTFIX); - i++; + mergeCompositeNodes(nodes, mergedNodes, i, node, ALLOC_OF_POSTFIX, "ALLOC_OF"); + } + case ALLOC_ARRAY_OF -> { + mergeCompositeNodes(nodes, mergedNodes, i, node, ALLOC_ARRAY_OF_POSTFIX, "ALLOC_ARRAY_OF"); } case STORE_OF_CLASS -> { - if (i + 1 == nodes.length) { - throw new TestFormatException("Must provide class name at index " + (i + 1) + " right after STORE_OF_CLASS"); - } - mergedNodes.add(node + Pattern.quote(nodes[i + 1]) + STORE_OF_CLASS_POSTFIX); - i++; + mergeCompositeNodes(nodes, mergedNodes, i, node, STORE_OF_CLASS_POSTFIX, "STORE_OF_CLASS"); } case STORE_OF_FIELD -> { - if (i + 1 == nodes.length) { - throw new TestFormatException("Must provide field name at index " + (i + 1) + " right after STORE_OF_FIELD"); - } - mergedNodes.add(node + Pattern.quote(nodes[i + 1]) + STORE_OF_FIELD_POSTFIX); - i++; + mergeCompositeNodes(nodes, mergedNodes, i, node, STORE_OF_FIELD_POSTFIX, "STORE_OF_FIELD"); + } + case LOAD_OF_CLASS -> { + mergeCompositeNodes(nodes, mergedNodes, i, node, LOAD_OF_CLASS_POSTFIX, "LOAD_OF_CLASS"); + } + case LOAD_OF_FIELD -> { + mergeCompositeNodes(nodes, mergedNodes, i, node, LOAD_OF_FIELD_POSTFIX, "LOAD_OF_FIELD"); } default -> { + i--; // No composite node, do not increment by 2. mergedNodes.add(node); } } } return mergedNodes; } + + private static void mergeCompositeNodes(String[] nodes, List mergedNodes, int i, String node, String postFix, String varName) { + if (i + 1 == nodes.length) { + throw new TestFormatException("Must provide class name at index " + (i + 1) + " right after " + varName); + } + mergedNodes.add(node + Pattern.quote(nodes[i + 1]) + postFix); + } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index ab58a8e57ff..20d0a63d163 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -514,7 +514,11 @@ private void addTest(Class clazz, Method m, Argument[] arguments) { Check checkAnno = getAnnotation(m, Check.class); Run runAnno = getAnnotation(m, Run.class); if (checkAnno != null || runAnno != null) { - throw new TestFormatException(m.getName() + " has invalid @compiler.valhalla.new_inlinetypes.Check or @compiler.valhalla.new_inlinetypes.Run annotation while @compiler.valhalla.new_inlinetypes.Test annotation is present."); + throw new TestFormatException(m + " has invalid @Check or @Run annotation while @Test annotation is present."); + } + + if (Arrays.asList(m.getParameterTypes()).contains(TestInfo.class)) { + throw new TestFormatException("Forbidden use of " + TestInfo.class + " as parameter at @Test method " + m); } Warmup warmup = getAnnotation(m, Warmup.class); @@ -538,7 +542,10 @@ private void setupCheckAndRunMethods(Class clazz) { for (Method m : clazz.getDeclaredMethods()) { Check checkAnno = getAnnotation(m, Check.class); Run runAnno = getAnnotation(m, Run.class); - + Arguments argumentsAnno = getAnnotation(m, Arguments.class); + if ((checkAnno != null || runAnno != null) && argumentsAnno != null) { + throw new TestFormatException("Cannot have @Argument annotation in combination with @Run or @Check at " + m); + } if (checkAnno != null) { addCheckedTest(m, checkAnno, runAnno); } else if (runAnno != null) { @@ -549,25 +556,52 @@ private void setupCheckAndRunMethods(Class clazz) { private void addCheckedTest(Method m, Check checkAnno, Run runAnno) { if (runAnno != null) { - throw new TestFormatException(m.getName() + " has invalid @compiler.valhalla.new_inlinetypes.Run annotation while @compiler.valhalla.new_inlinetypes.Check annotation is present."); + throw new TestFormatException(m + " has invalid @Run annotation while @Check annotation is present."); } Method testMethod = testMethodMap.get(checkAnno.test()); if (testMethod == null) { - throw new TestFormatException("Did not find associated test method " + checkAnno.test() + " for @compiler.valhalla.new_inlinetypes.Check at " + m.getName()); + throw new TestFormatException("Did not find associated test method " + checkAnno.test() + " for @Check at " + m); + } + + boolean firstParameterTestInfo = m.getParameterCount() > 0 && m.getParameterTypes()[0].equals(TestInfo.class); + boolean secondParameterTestInfo = m.getParameterCount() > 1 && m.getParameterTypes()[1].equals(TestInfo.class); + + CheckedTest.Parameter parameter; + Class testReturnType = testMethod.getReturnType(); + switch (m.getParameterCount()) { + case 0 -> { + parameter = CheckedTest.Parameter.NONE; + } + case 1 -> { + if (!firstParameterTestInfo && m.getParameterTypes()[0] != testReturnType) { + throw new TestFormatException("Single-parameter version of @Check method " + m + " must match return type of @Test " + testMethod); + } + parameter = firstParameterTestInfo ? CheckedTest.Parameter.TEST_INFO_ONLY : CheckedTest.Parameter.RETURN_ONLY; + } + case 2 -> { + if (!secondParameterTestInfo || m.getParameterTypes()[0] != testReturnType) { + throw new TestFormatException("Two-parameter version of @Check method " + m + " must provide as first parameter the same" + + " return type as @Test method " + testMethod + " and as second parameter an object of " + TestInfo.class); + } + parameter = CheckedTest.Parameter.BOTH; + } + default -> { + throw new TestFormatException("@Check method " + m + " must provide either a none, single or two-parameter variant."); + } } + if (allTests.containsKey(testMethod)) { BaseTest baseTest = allTests.get(testMethod); - throw new TestFormatException("Method " + m.getName() + " and " + baseTest.getAssociatedTestName() + - " cannot both reference test method " + testMethod.getName()); + throw new TestFormatException("Method " + m + " and " + baseTest.getAssociatedTestName() + " cannot both reference test method " + testMethod); } DeclaredTest test = declaredTests.remove(testMethod); if (test == null) { - throw new TestFormatException("Missing @compiler.valhalla.new_inlinetypes.Test annotation for associated test method " + checkAnno.test() + " for @compiler.valhalla.new_inlinetypes.Check at " + m.getName()); + throw new TestFormatException("Missing @Test annotation for associated test method " + checkAnno.test() + " for @Check at " + m); } applyCompileCommands(m); // Don't inline check methods WHITE_BOX.testSetDontInlineMethod(m, true); - CheckedTest checkedTest = new CheckedTest(test, m, checkAnno); + CheckedTest checkedTest = new CheckedTest(test, m, checkAnno, parameter); allTests.put(testMethod, checkedTest); } @@ -588,17 +622,17 @@ private void applyCompileCommands(Method m) { private void addCustomRunTest(Method m, Run runAnno) { Method testMethod = testMethodMap.get(runAnno.test()); if (testMethod == null) { - throw new TestFormatException("Did not find associated test method " + runAnno.test() + " for @Run at " + m.getName()); + throw new TestFormatException("Did not find associated test method " + runAnno.test() + " for @Run at " + m); } DeclaredTest test = declaredTests.remove(testMethod); if (test == null) { - throw new TestFormatException("Missing @Test annotation for associated test method " + runAnno.test() + " for @Run at " + m.getName()); + throw new TestFormatException("Missing @Test annotation for associated test method " + runAnno.test() + " for @Run at " + m); } if (test.hasArguments()) { - throw new TestFormatException("Invalid @Arguments annotation for associated test method " + runAnno.test() + " for @Run at " + m.getName()); + throw new TestFormatException("Invalid @Arguments annotation for associated test method " + runAnno.test() + " for @Run at " + m); } - if (m.getParameterCount() != 1 || !m.getParameterTypes()[0].equals(TestInfo.class)) { - throw new TestFormatException("@Run method " + m.getName() + " must specify exactly one TestInfo parameter"); + if (m.getParameterCount() > 1 || (m.getParameterCount() == 1 && !m.getParameterTypes()[0].equals(TestInfo.class))) { + throw new TestFormatException("@Run method " + m + " must specify either no TestInfo parameter or exactly one"); } applyCompileCommands(m); // Don't inline run methods @@ -819,10 +853,12 @@ class BaseTest { protected final DeclaredTest test; protected final TestInfo testInfo; + protected final Object invocationTarget; public BaseTest(DeclaredTest test) { this.test = test; this.testInfo = new TestInfo(); + this.invocationTarget = test.getInvocationTarget(); } public String getAssociatedTestName() { return test.getTestMethod().getName(); @@ -926,15 +962,21 @@ public void verify(TestInfo testInfo, Object result) { /* no verification in Bas } class CheckedTest extends BaseTest { - Method checkMethod; - Check checkSpecification; + private final Method checkMethod; + private final Check checkSpecification; + private final Parameter parameter; + + enum Parameter { + NONE, RETURN_ONLY, TEST_INFO_ONLY, BOTH + } - public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecification) { + public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecification, Parameter parameter) { super(test); // Make sure we can also call non-public or public methods in package private classes checkMethod.setAccessible(true); this.checkMethod = checkMethod; this.checkSpecification = checkSpecification; + this.parameter = parameter; } @Override @@ -946,7 +988,12 @@ public void verify(TestInfo testInfo, Object result) { } if (shouldVerify) { try { - checkMethod.invoke(test.getInvocationTarget(), testInfo, result); + switch (parameter) { + case NONE -> checkMethod.invoke(invocationTarget); + case RETURN_ONLY -> checkMethod.invoke(invocationTarget, result); + case TEST_INFO_ONLY -> checkMethod.invoke(invocationTarget, testInfo); + case BOTH -> checkMethod.invoke(invocationTarget, result, testInfo); + } } catch (Exception e) { throw new TestRunException("There was an error while invoking @Check method " + checkMethod, e); } @@ -955,8 +1002,8 @@ public void verify(TestInfo testInfo, Object result) { } class CustomRunTest extends BaseTest { - Method runMethod; - Run runSpecification; + private final Method runMethod; + private final Run runSpecification; public CustomRunTest(DeclaredTest test, Method runMethod, Run runSpecification) { super(test); @@ -972,7 +1019,11 @@ public CustomRunTest(DeclaredTest test, Method runMethod, Run runSpecification) @Override protected void runMethod() { try { - runMethod.invoke(test.getInvocationTarget(), testInfo); + if (runMethod.getParameterCount() == 1) { + runMethod.invoke(invocationTarget, testInfo); + } else { + runMethod.invoke(invocationTarget); + } } catch (Exception e) { throw new TestRunException("There was an error while invoking @Run method " + runMethod, e); } @@ -1027,4 +1078,4 @@ private static CompLevel restrictCompLevel(CompLevel compLevel) { } return compLevel; } -} \ No newline at end of file +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java index 02b9253731a..740715ba13d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -12,7 +12,7 @@ public static void main(String[] args) { framework.runTestsOnSameVM(); if (wasExecuted) { - throw new RuntimeException("Executed non @Test method"); + throw new RuntimeException("Executed non @Test method or a method that was not intended to be run"); } for (int i = 0; i < testExecuted.length; i++) { int value = testExecuted[i]; @@ -22,6 +22,13 @@ public static void main(String[] args) { + TestFramework.WARMUP_ITERATIONS + 1 + " times." ); } } + + for (int i = 0; i < checkExecuted.length; i++) { + int value = checkExecuted[i]; + if (value != 1) { + throw new RuntimeException("Check function should have been executed exactly once"); + } + } } // @Test @@ -65,7 +72,8 @@ public static void main(String[] args) { // } static boolean wasExecuted = false; - static int[] testExecuted = new int[61]; + static int[] testExecuted = new int[75]; + static int[] checkExecuted = new int[4]; boolean lastToggleBoolean = true; long[] nonFloatingRandomNumbers = new long[10]; double[] floatingRandomNumbers = new double[10]; @@ -681,8 +689,139 @@ public void booleanMix(boolean b1, boolean b2, boolean b3, boolean b4) { lastToggleBoolean = b1; testExecuted[60]++; } + + @Test + public void testRun() { + testExecuted[61]++; + } + + @Run(test="testRun") + public void runTestRun(TestInfo info) { + testRun(); + } + + @Test + public void testRunNoTestInfo(int i) { + testExecuted[62]++; + } + + @Run(test="testRunNoTestInfo") + public void runTestRunNoTestInfo() { + testRunNoTestInfo(3); + } + + @Test + public void testNotRun() { + wasExecuted = true; + } + + @Run(test="testNotRun") + public void runTestNotRun() { + // Do not execute the test. Pointless but need to test that as well. + } + + @Test + public int testCheck() { + testExecuted[63]++; + return 1; + } + + @Check(test="testCheck") + public void checkTestCheck() { + testExecuted[64]++; // Executed on each invocation + } + + @Test + public int testCheckReturn() { + testExecuted[65]++; + return 2; + } + + @Check(test="testCheckReturn") + public void checkTestCheckReturn(int returnValue) { + if (returnValue != 2) { + throw new RuntimeException("Must be 2"); + } + testExecuted[66]++; // Executed on each invocation + } + + @Test + public int testCheckTestInfo() { + testExecuted[67]++; + return 3; + } + + @Check(test="testCheckTestInfo") + public void checkTestCheckTestInfo(TestInfo testInfo) { + testExecuted[68]++; // Executed on each invocation + } + + + @Test + public int testCheckBoth() { + testExecuted[69]++; + return 4; + } + + @Check(test="testCheckBoth") + public void checkTestCheckTestInfo(int returnValue, TestInfo testInfo) { + if (returnValue != 4) { + throw new RuntimeException("Must be 4"); + } + testExecuted[70]++; // Executed on each invocation + } + + @Test + public int testCheckOnce() { + testExecuted[71]++; + return 1; + } + + @Check(test="testCheckOnce", when=CheckAt.C2_COMPILED) + public void checkTestCheckOnce() { + checkExecuted[0]++; // Executed once + } + + @Test + public int testCheckReturnOnce() { + testExecuted[72]++; + return 2; + } + + @Check(test="testCheckReturnOnce", when=CheckAt.C2_COMPILED) + public void checkTestCheckReturnOnce(int returnValue) { + if (returnValue != 2) { + throw new RuntimeException("Must be 2"); + } + checkExecuted[1]++; // Executed once + } + + @Test + public int testCheckTestInfoOnce() { + testExecuted[73]++; + return 3; + } + + @Check(test="testCheckTestInfoOnce", when=CheckAt.C2_COMPILED) + public void checkTestCheckTestInfoOnce(TestInfo testInfo) { + checkExecuted[2]++; // Executed once + } + + @Test + public int testCheckBothOnce() { + testExecuted[74]++; + return 4; + } + + @Check(test="testCheckBothOnce", when=CheckAt.C2_COMPILED) + public void checkTestCheckBothOnce(int returnValue, TestInfo testInfo) { + if (returnValue != 4) { + throw new RuntimeException("Must be 4"); + } + checkExecuted[3]++; // Executed once + } } class DefaultObject { int i = 4; -} \ No newline at end of file +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java index 7978e38ee3c..e1b45ccd7b8 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java @@ -3,82 +3,100 @@ import compiler.valhalla.framework.*; import jdk.test.lib.Asserts; -import java.lang.reflect.Array; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.function.Predicate; +import java.util.regex.Pattern; public class TestIRMatching { - private static final String SHOULD_NOT_REACH_MESSAGE = "should not reach"; static int[] testExecuted = new int[61]; public static void main(String[] args) { // Run with -DPrintValidIRRules=true to simulate TestVM - runFailOnTests(AndOr1.class, "test1(int)", "CallStaticJava", "-XX:SuspendRetryCount=50", "-XX:+UsePerfData", "-XX:+UseTLAB"); - runFailOnTests(AndOr1.class, "test1(int)", "CallStaticJava", "-XX:SuspendRetryCount=50", "-XX:+UsePerfData", "-XX:+UseTLAB"); - runFailOnTests(AndOr1.class, "test2()", "CallStaticJava", "-XX:SuspendRetryCount=50", "-XX:-UsePerfData", "-XX:+UseTLAB"); - - TestFramework.runWithArguments(AndOr1.class, "-XX:SuspendRetryCount=52", "-XX:+UsePerfData", "-XX:+UseTLAB"); - - TestFramework.runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=50"); - - findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 0, 21); - findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", -1, -1); - TestFramework.runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=49"); - findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 4, 6, 13, 18); - findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); - TestFramework.runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=51"); - findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 7, 12, 19, 21); - findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 4, 7, 11, 16, 20, 22); - - TestFramework.runWithArguments(MultipleFailOnGood.class, "-XX:SuspendRetryCount=50"); - - runFailOnTests(MultipleFailOnBad.class, "fail1()", "Store", "-XX:SuspendRetryCount=50"); - runFailOnTests(MultipleFailOnBad.class, "fail2()", "CallStaticJava", "-XX:SuspendRetryCount=51"); - runFailOnTests(MultipleFailOnBad.class, "fail3()", "Store", "-XX:SuspendRetryCount=52"); - runFailOnTests(MultipleFailOnBad.class, "fail4()", "Store", "-XX:SuspendRetryCount=53"); - runFailOnTests(MultipleFailOnBad.class, "fail5()", "Store", "-XX:SuspendRetryCount=54"); - runFailOnTests(MultipleFailOnBad.class, "fail6()", new String[] {"MyClass", "call,static wrapper for: _new_instance_Java"}, "-XX:SuspendRetryCount=55"); - runFailOnTests(MultipleFailOnBad.class, "fail7()", new String[] {"MyClass", "call,static wrapper for: _new_instance_Java"}, "-XX:SuspendRetryCount=56"); - runFailOnTests(MultipleFailOnBad.class, "fail8()", new String[] {"MyClassSub", "call,static wrapper for: _new_instance_Java"}, "-XX:SuspendRetryCount=57"); - runFailOnTests(MultipleFailOnBad.class, "fail9()", new String[] {"Store", "CallStaticJava"}, "-XX:SuspendRetryCount=58"); - TestFramework.runWithArguments(GoodCount.class, "-XX:SuspendRetryCount=50"); - } - - private static void runFailOnTests(Class c, String methodName, String node, String... args) { +// runFailOnTests(Constraint.failOnNodes(AndOr1.class, "test1(int)", 1, true,"CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:+UsePerfData", "-XX:+UseTLAB"); +// runFailOnTests(Constraint.failOnNodes(AndOr1.class, "test2()", 1, true,"CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:-UsePerfData", "-XX:+UseTLAB"); +// +// TestFramework.runWithArguments(AndOr1.class, "-XX:SuspendRetryCount=52", "-XX:+UsePerfData", "-XX:+UseTLAB"); +// +// TestFramework.runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=50"); +// findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 0, 21); +// findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", -1, -1); +// +// TestFramework.runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=49"); +// findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 4, 6, 13, 18); +// findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); +// +// TestFramework.runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=51"); +// findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 7, 12, 19, 21); +// findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 4, 7, 11, 16, 20, 22); +// +// TestFramework.runWithArguments(MultipleFailOnGood.class, "-XX:SuspendRetryCount=50"); +// +// runFailOnTests(Constraint.failOnNodes(MultipleFailOnBad.class, "fail1()", 1,true, "Store"), +// Constraint.failOnNodes(MultipleFailOnBad.class, "fail2()", 1,true, "CallStaticJava"), +// Constraint.failOnNodes(MultipleFailOnBad.class, "fail3()", 1,true, "Store"), +// Constraint.failOnNodes(MultipleFailOnBad.class, "fail4()", 1,true, "Store"), +// Constraint.failOnMatches(MultipleFailOnBad.class, "fail5()", 1,true, "Store", "iFld"), +// Constraint.failOnAlloc(MultipleFailOnBad.class, "fail6()", 1,true, "MyClass"), +// Constraint.failOnAlloc(MultipleFailOnBad.class, "fail7()", 1,true, "MyClass"), +// Constraint.failOnAlloc(MultipleFailOnBad.class, "fail8()", 1,true, "MyClass"), +// Constraint.failOnNodes(MultipleFailOnBad.class, "fail9()", 1,true, "Store", "CallStaticJava"), +// Constraint.failOnMatches(MultipleFailOnBad.class, "fail10()", 1,true, "Store", "iFld")); +// +// TestFramework.runWithArguments(GoodCount.class, "-XX:SuspendRetryCount=50"); + + runFailOnTests(Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 1,true, "MyClass"), + Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 2,true, "MyClass"), + Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 3,false, "MyClass"), + Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 4,false, "MyClass"), + Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 5,true, "MyClass"), + Constraint.failOnNodes(VariousIrNodes.class, "loop()", 1, true, "Loop"), + Constraint.failOnNodes(VariousIrNodes.class, "loop()", 2, false, "CountedLoop"), + Constraint.failOnNodes(VariousIrNodes.class, "countedLoop()", 1, false, "Loop"), + Constraint.failOnNodes(VariousIrNodes.class, "countedLoop()", 2, true, "CountedLoop"), + Constraint.failOnNodes(VariousIrNodes.class, "loopAndCountedLoop()", 1, true, "Loop"), + Constraint.failOnNodes(VariousIrNodes.class, "loopAndCountedLoop()", 2, true, "CountedLoop"), + Constraint.failOnNodes(VariousIrNodes.class, "load()", 1, true, "Load"), + Constraint.failOnNodes(VariousIrNodes.class, "load()", 2, true, "VariousIrNodes"), + Constraint.failOnNodes(VariousIrNodes.class, "load()", 3, true, "VariousIrNodes"), + Constraint.failOnMatches(VariousIrNodes.class, "load()", 4, true, "Load", "iFld"), + Constraint.failOnNodes(VariousIrNodes.class, "load()", 5, false, "Load") + ); + + } + + private static void runFailOnTests(Constraint... constraints) { try { - TestFramework.runWithArguments(c, args); + TestFramework.run(constraints[0].getKlass()); // All constraints have the same class. shouldNotReach(); + } catch (ShouldNotReachException e) { + throw e; } catch (RuntimeException e) { - shouldContain(e, c.getSimpleName() + "." + methodName, "forbidden", node); + System.out.println(e.getMessage()); + for (Constraint constraint : constraints) { + constraint.checkConstraint(e); + } } } - - private static void runFailOnTests(Class c, String methodName, String[] matches, String... args) { + // Single constraint + private static void runFailOnTests(Constraint constraint, String... args) { try { - TestFramework.runWithArguments(c, args); + TestFramework.runWithArguments(constraint.getKlass(), args); // All constraints have the same class. shouldNotReach(); + } catch (ShouldNotReachException e) { + throw e; } catch (RuntimeException e) { - String[] allMatches = Arrays.copyOf(matches, matches.length + 2); - allMatches[matches.length] = c.getSimpleName() + "." + methodName; - allMatches[matches.length + 1] = "forbidden"; - shouldContain(e, allMatches); + System.out.println(e.getMessage()); + constraint.checkConstraint(e); } } private static void shouldNotReach() { - Asserts.fail(SHOULD_NOT_REACH_MESSAGE); + throw new ShouldNotReachException("Framework did not fail but it should have!"); } - private static void shouldContain(RuntimeException e, String... strings) { - String message = e.getMessage(); - if (e.getMessage().equals(SHOULD_NOT_REACH_MESSAGE)) { - throw e; - } - Arrays.stream(strings).forEach(s -> Asserts.assertTrue(message.contains(s), "Did not find \"" + s + "\" in:\n" + message)); - } - - public static void findIrIds(String output, String method, int... numbers) { StringBuilder builder = new StringBuilder(); builder.append(method); @@ -172,62 +190,70 @@ private void forceInline() { class MultipleFailOnBad { private int iFld; + private int myInt; private MyClass myClass; @Test - @IR(applyIf={"SuspendRetryCount", "50"}, failOn={IRNode.STORE, IRNode.CALL}) + @IR(failOn={IRNode.STORE, IRNode.CALL}) public void fail1() { iFld = 42; } @Test - @IR(applyIf={"SuspendRetryCount", "51"}, failOn={IRNode.STORE, IRNode.CALL}) + @IR(failOn={IRNode.STORE, IRNode.CALL}) public void fail2() { dontInline(); } @Test - @IR(applyIf={"SuspendRetryCount", "52"}, failOn={IRNode.CALL, IRNode.STORE_OF_CLASS, "MultipleFailOnBad", IRNode.ALLOC}) + @IR(failOn={IRNode.CALL, IRNode.STORE_OF_CLASS, "MultipleFailOnBad", IRNode.ALLOC}) public void fail3() { iFld = 42; } @Test - @IR(applyIf={"SuspendRetryCount", "53"}, failOn={IRNode.STORE_OF_CLASS, "compiler/valhalla/framework/tests/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) + @IR(failOn={IRNode.STORE_OF_CLASS, "compiler/valhalla/framework/tests/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) public void fail4() { iFld = 42; } @Test - @IR(applyIf={"SuspendRetryCount", "54"}, failOn={IRNode.STORE_OF_FIELD, "iFld", IRNode.CALL, IRNode.ALLOC}) + @IR(failOn={IRNode.STORE_OF_FIELD, "iFld", IRNode.CALL, IRNode.ALLOC}) public void fail5() { iFld = 42; } @Test - @IR(applyIf={"SuspendRetryCount", "55"}, failOn={IRNode.STORE_OF_CLASS, "MyClass", IRNode.ALLOC}) + @IR(failOn={IRNode.STORE_OF_CLASS, "MyClass", IRNode.ALLOC}) public void fail6() { myClass = new MyClass(); } @Test - @IR(applyIf={"SuspendRetryCount", "56"}, failOn={IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "MyClass"}) + @IR(failOn={IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "MyClass"}) public void fail7() { myClass = new MyClass(); } @Test - @IR(applyIf={"SuspendRetryCount", "57"}, failOn={IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "compiler/valhalla/framework/tests/MyClassSub"}) + @IR(failOn={IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "compiler/valhalla/framework/tests/MyClassSub"}) public void fail8() { myClass = new MyClassSub(); } @Test - @IR(applyIf={"SuspendRetryCount", "58"}, failOn={IRNode.STORE, IRNode.CALL}) + @IR(failOn={IRNode.STORE, IRNode.CALL}) public void fail9() { iFld = 42; dontInline(); } + @Test + @IR(failOn={IRNode.STORE_OF_FIELD, "iFld", IRNode.CALL, IRNode.ALLOC}) + public void fail10() { + myInt = 34; + iFld = 42; + } + @DontInline private void dontInline() { } @@ -325,10 +351,171 @@ public void good4() { } } +// Test on remaining IR nodes that we have not tested above, yet. +class VariousIrNodes { + MyClass[] myClassArray; + int limit = 1024; + int iFld = 34; + int result = 0; + @Test + @IR(failOn={IRNode.ALLOC_ARRAY}) + @IR(failOn={IRNode.ALLOC_ARRAY_OF, "MyClass"}) + @IR(failOn={IRNode.ALLOC_ARRAY_OF, "MyClasss"}) // Does not fail + @IR(failOn={IRNode.ALLOC_ARRAY_OF, "compiler/valhalla/framework/tests/MySubClass"}) // Does not fail + @IR(failOn={IRNode.ALLOC_ARRAY_OF, "compiler/valhalla/framework/tests/MyClass"}) + public void allocArray() { + myClassArray = new MyClass[2]; + } + + @Test + @IR(failOn={IRNode.LOOP}) + @IR(failOn={IRNode.COUNTEDLOOP}) // Does not fail + public void loop() { + for (int i = 0; i < limit; i++) { + dontInline(); + } + } + + @Test + @IR(failOn={IRNode.LOOP}) // Does not fail + @IR(failOn={IRNode.COUNTEDLOOP}) + public void countedLoop() { + for (int i = 0; i < 2000; i++) { + dontInline(); + } + } + + @Test + @IR(failOn={IRNode.LOOP}) + @IR(failOn={IRNode.COUNTEDLOOP}) + public void loopAndCountedLoop() { + for (int i = 0; i < 2000; i++) { + for (int j = 0; j < limit; j++) { + dontInline(); + } + } + } + + @DontInline + public void dontInline() {} + + @Test + @IR(failOn={IRNode.LOAD}) + @IR(failOn={IRNode.LOAD_OF_CLASS, "compiler/valhalla/framework/tests/VariousIrNodes"}) + @IR(failOn={IRNode.LOAD_OF_CLASS, "VariousIrNodes"}) + @IR(failOn={IRNode.LOAD_OF_FIELD, "iFld"}) + @IR(failOn={IRNode.LOAD_OF_FIELD, "iFld2", IRNode.LOAD_OF_CLASS, "Various"}) // Does not fail + public void load() { + result = iFld; + } + + @Test + @IR(failOn={IRNode.RETURN}) + public void returns() { + dontInline(); + } + +} + class MyClass { int iFld; } class MyClassSub extends MyClass { int iFld; static int iFldStatic; -} \ No newline at end of file +} + +enum FailType { + FAIL_ON +} + +class Constraint { + final private Class klass; + final private int ruleIdx; + final private Pattern irPattern; + final private List matches; + final private Pattern methodPattern; + private final String classAndMethod; + final FailType failType; + final boolean shouldMatch; + + private Constraint(Class klass, String methodName, int ruleIdx, FailType failType, List matches, boolean shouldMatch) { + this.klass = klass; + classAndMethod = klass.getSimpleName() + "." + methodName; + this.ruleIdx = ruleIdx; + this.failType = failType; + this.methodPattern = Pattern.compile(Pattern.quote(classAndMethod)); + if (failType == FailType.FAIL_ON) { + irPattern = Pattern.compile("rule " + ruleIdx + ":.*\\R.*Failure:.*contains forbidden node:"); + } else { + irPattern = null; // TODO + } + this.shouldMatch = shouldMatch; + this.matches = matches; + } + + public Class getKlass() { + return klass; + } + + public static Constraint failOnNodes(Class klass, String methodName, int ruleIdx, boolean shouldMatch, String... nodes) { + return new Constraint(klass, methodName, ruleIdx, FailType.FAIL_ON, new ArrayList<>(Arrays.asList(nodes)), shouldMatch); + } + + public static Constraint failOnAlloc(Class klass, String methodName, int ruleIdx, boolean shouldMatch, String allocKlass) { + List list = new ArrayList<>(); + list.add(allocKlass); + list.add("call,static wrapper for: _new_instance_Java"); + return new Constraint(klass, methodName, ruleIdx, FailType.FAIL_ON, list, shouldMatch); + } + + public static Constraint failOnArrayAlloc(Class klass, String methodName, int ruleIdx, boolean shouldMatch, String allocKlass) { + List list = new ArrayList<>(); + list.add(allocKlass); + list.add("call,static wrapper for: _new_array_Java"); + return new Constraint(klass, methodName, ruleIdx, FailType.FAIL_ON, list, shouldMatch); + } + + public static Constraint failOnMatches(Class klass, String methodName, int ruleIdx, boolean shouldMatch, String... matches) { + return new Constraint(klass, methodName, ruleIdx, FailType.FAIL_ON, new ArrayList<>(Arrays.asList(matches)), shouldMatch); + } + + public void checkConstraint(RuntimeException e) { + String message = e.getMessage(); + String[] splitMethods = message.split("Method"); + for (String method : splitMethods) { + if (methodPattern.matcher(method).find()) { + String[] splitIrRules = method.split("@IR"); + for (String irRule : splitIrRules) { + if (irPattern.matcher(irRule).find()) { + boolean allMatch = matches.stream().allMatch(irRule::contains); + if (shouldMatch) { + Asserts.assertTrue(allMatch, "Constraint for method " + classAndMethod + ", rule " + ruleIdx + " could not be matched:\n" + message); + } else { + Asserts.assertFalse(allMatch, "Constraint for method " + classAndMethod + ", rule " + ruleIdx + " should not have been matched:\n" + message); + } + return; + } + } + Predicate irPredicate = s -> irPattern.matcher(s).find(); + if (shouldMatch) { + Asserts.assertTrue(Arrays.stream(splitIrRules).anyMatch(irPredicate), "Constraint for method " + classAndMethod + ", rule " + + ruleIdx + " could not be matched:\n" + message); + } else { + Asserts.assertTrue(Arrays.stream(splitIrRules).noneMatch(irPredicate), "Constraint for method " + classAndMethod + ", rule " + + ruleIdx + " should not have been matched:\n" + message); + } + return; + } + } + if (shouldMatch) { + Asserts.fail("Constraint for method " + classAndMethod + ", rule " + ruleIdx + " could not be matched:\n" + message); + } + } +} + +class ShouldNotReachException extends RuntimeException { + ShouldNotReachException(String s) { + super(s); + } +} From 24de07c588b4d271717577f1fc76c4ace60d3ca3 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 15 Jan 2021 15:04:47 +0100 Subject: [PATCH 003/131] Refactor usage of TestFrameworkException --- .../compiler/valhalla/framework/Argument.java | 63 ++++----- .../valhalla/framework/IREncodingPrinter.java | 73 ++++------ .../valhalla/framework/IRMatcher.java | 24 +--- .../compiler/valhalla/framework/IRNode.java | 4 +- .../valhalla/framework/TestFormat.java | 26 ++++ .../framework/TestFormatException.java | 13 -- .../valhalla/framework/TestFramework.java | 130 +++++++----------- 7 files changed, 141 insertions(+), 192 deletions(-) create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java delete mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java index 64248ca21c5..68ce869c62d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java @@ -46,9 +46,8 @@ public static Argument[] getArguments(Method m) { ArgumentValue[] values = argumentsAnno.value(); Argument[] arguments = new Argument[values.length]; Class[] declaredParameters = m.getParameterTypes(); - if (values.length != declaredParameters.length) { - throw new TestFormatException("Number of argument values provided in @Arguments does not match the number of actual arguments in " + m); - } + TestFormat.check(values.length == declaredParameters.length, + "Number of argument values provided in @Arguments does not match the number of actual arguments in " + m); for (int i = 0; i < values.length; i++) { ArgumentValue specifiedArg = values[i]; @@ -56,53 +55,43 @@ public static Argument[] getArguments(Method m) { switch (specifiedArg) { case DEFAULT -> arguments[i] = createDefault(parameter); case NUMBER_42 -> { - if (isNumber(parameter)) { - arguments[i] = create((byte) 42); - } else { - throw new TestFormatException("Provided invalid NUMBER_42 argument for non-number " + parameter + " for " + m); - } + TestFormat.check(isNumber(parameter), + "Provided invalid NUMBER_42 argument for non-number " + parameter + " for " + m); + arguments[i] = create((byte) 42); } case NUMBER_MINUS_42 -> { - if (isNumber(parameter)) { - arguments[i] = create((byte) -42); - } else { - throw new TestFormatException("Provided invalid NUMBER_MINUS_42 argument for non-number " + parameter + " for " + m); - } + TestFormat.check(isNumber(parameter), + "Provided invalid NUMBER_MINUS_42 argument for non-number " + parameter + " for " + m); + arguments[i] = create((byte) -42); } case BOOLEAN_TOGGLE_FIRST_FALSE -> { - if (!isBoolean(parameter)) { - throw new TestFormatException("Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + parameter + " for " + m); - } + TestFormat.check(isBoolean(parameter), + "Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + parameter + " for " + m); arguments[i] = createToggleBoolean(false); } case BOOLEAN_TOGGLE_FIRST_TRUE -> { - if (!Argument.isBoolean(parameter)) { - throw new TestFormatException("Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + parameter + " for " + m); - } + TestFormat.check(Argument.isBoolean(parameter), + "Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + parameter + " for " + m); arguments[i] = createToggleBoolean(true); } case TRUE -> { - if (!Argument.isBoolean(parameter)) { - throw new TestFormatException("Provided invalid TRUE argument for non-boolean " + parameter + " for " + m); - } + TestFormat.check(Argument.isBoolean(parameter), + "Provided invalid TRUE argument for non-boolean " + parameter + " for " + m); arguments[i] = create(true); } case FALSE -> { - if (!isBoolean(parameter)) { - throw new TestFormatException("Provided invalid FALSE argument for non-boolean " + parameter + " for " + m); - } + TestFormat.check(Argument.isBoolean(parameter), + "Provided invalid FALSE argument for non-boolean " + parameter + " for " + m); arguments[i] = create(false); } case RANDOM_ONCE -> { - if (isNotPrimitiveType(parameter)) { - throw new TestFormatException("Provided invalid RANDOM_ONCE argument for non-primitive type " + parameter + " for " + m); - } + TestFormat.check(isPrimitiveType(parameter), + "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameter + " for " + m); arguments[i] = createRandom(parameter); } case RANDOM_EACH -> { - if (isNotPrimitiveType(parameter)) { - throw new TestFormatException("Provided invalid RANDOM_ONCE argument for non-primitive type " + parameter + " for " + m); - } + TestFormat.check(isPrimitiveType(parameter), + "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameter + " for " + m); arguments[i] = createRandomEach(parameter); } } @@ -128,7 +117,8 @@ private static Argument createDefault(Class c) { constructor.setAccessible(true); return Argument.create(constructor.newInstance()); } catch (Exception e) { - throw new TestFormatException("Cannot create new default instance of " + c, e); + TestFormat.fail("Cannot create new default instance of " + c, e); + return null; } } } @@ -159,8 +149,8 @@ public Object getArgument() { } } - private static boolean isNotPrimitiveType(Class c) { - return !isNumber(c) && !isBoolean(c) && !isChar(c); + private static boolean isPrimitiveType(Class c) { + return isNumber(c) || isBoolean(c) || isChar(c); } private static boolean isBoolean(Class c) { @@ -205,7 +195,8 @@ private static Object getRandom(Class c) { // Get number between 0 and 1000. return random.nextDouble() * 1000; } else { - throw new TestFormatException("Cannot generate random value for non-primitive type"); + TestFormat.fail("Cannot generate random value for non-primitive type"); + return null; } } -} \ No newline at end of file +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java index a07bdf0a395..f242a504506 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java @@ -84,40 +84,32 @@ private static void checkAnnotation(Method m, IR irAnnotation) { int applyRules = 0; if (irAnnotation.applyIfAnd().length != 0) { applyRules++; - if (irAnnotation.applyIfAnd().length <= 2) { - throw new TestFormatException("Use [applyIf|applyIfNot] or at least 2 conditions for applyIfAnd in @IR at " + m); - } + TestFormat.check(irAnnotation.applyIfAnd().length > 2, + "Use [applyIf|applyIfNot] or at least 2 conditions for applyIfAnd in @IR at " + m); } if (irAnnotation.applyIfOr().length != 0) { applyRules++; - if (irAnnotation.applyIfOr().length <= 2) { - throw new TestFormatException("Use [applyIf|applyIfNot] or at least 2 conditions for applyIfOr in @IR at " + m); - } + TestFormat.check(irAnnotation.applyIfOr().length > 2, + "Use [applyIf|applyIfNot] or at least 2 conditions for applyIfOr in @IR at " + m); } if (irAnnotation.applyIf().length != 0) { applyRules++; - if (irAnnotation.applyIf().length > 2) { - throw new TestFormatException("Use [applyIfAnd|applyIfOr] or only 1 condition for applyIf in @IR at " + m); - } + TestFormat.check(irAnnotation.applyIf().length <= 2, + "Use [applyIfAnd|applyIfOr] or only 1 condition for applyIf in @IR at " + m); } if (irAnnotation.applyIfNot().length != 0) { applyRules++; - if (irAnnotation.applyIfNot().length > 2) { - throw new TestFormatException("Use [applyIfAnd|applyIfOr] or only 1 condition for applyIfNot in @IR at " + m); - } - } - if (applyRules > 1) { - throw new TestFormatException("Can only use one of [applyIf|applyIfNot|applyIfAnd|applyIfOr] in @IR at " + m); + TestFormat.check(irAnnotation.applyIfNot().length <= 2, + "Use [applyIfAnd|applyIfOr] or only 1 condition for applyIfNot in @IR at " + m); } + TestFormat.check(applyRules <= 1, "Can only use one of [applyIf|applyIfNot|applyIfAnd|applyIfOr] in @IR at " + m); } private boolean hasAllRequiredFlags(Method m, String[] andRules, String ruleType) { for (int i = 0; i < andRules.length; i++) { String flag = andRules[i]; i++; - if (i == andRules.length) { - throw new TestFormatException("Missing value for flag " + flag + " in " + ruleType + " for @IR at " + m); - } + TestFormat.check(i < andRules.length, "Missing value for flag " + flag + " in " + ruleType + " for @IR at " + m); String value = andRules[i]; if (!check(m, flag, value)) { return false; @@ -130,9 +122,7 @@ private boolean hasNoRequiredFlags(Method m, String[] orRules, String ruleType) for (int i = 0; i < orRules.length; i++) { String flag = orRules[i]; i++; - if (i == orRules.length) { - throw new TestFormatException("Missing value for flag " + flag + " in " + ruleType + " for @IR at " + m); - } + TestFormat.check(i < orRules.length, "Missing value for flag " + flag + " in " + ruleType + " for @IR at " + m); String value = orRules[i]; if (check(m, flag, value)) { return false; @@ -142,51 +132,48 @@ private boolean hasNoRequiredFlags(Method m, String[] orRules, String ruleType) } private boolean check(Method m, String flag, String value) { - if (value.length() == 0) { - throw new TestFormatException("Provided empty value for flag " + flag + " at " + m); - } + TestFormat.check(!value.isEmpty(), "Provided empty value for flag " + flag + " at " + m); Object actualFlagValue = longGetters.stream() .map(f -> f.apply(flag)) .filter(Objects::nonNull) .findAny().orElse(null); if (actualFlagValue != null) { long actualLongFlagValue = (Long) actualFlagValue; - long longValue; - ParsedComparator parsedComparator; + long longValue = 0; + ParsedComparator parsedComparator = null; try { parsedComparator = parseComparator(value.trim()); longValue = Long.parseLong(parsedComparator.getStrippedString()); } catch (NumberFormatException e) { - throw new TestFormatException("Invalid value " + value + " for number based flag " + flag); + TestFormat.fail("Invalid value " + value + " for number based flag " + flag); } catch (Exception e) { - throw new TestFormatException("Invalid comparator in \"" + value + "\" for number based flag " + flag, e); + TestFormat.fail("Invalid comparator in \"" + value + "\" for number based flag " + flag, e); } return parsedComparator.getPredicate().test(actualLongFlagValue, longValue); } actualFlagValue = WHITE_BOX.getBooleanVMFlag(flag); if (actualFlagValue != null) { boolean actualBooleanFlagValue = (Boolean) actualFlagValue; - boolean booleanValue; + boolean booleanValue = false; try { booleanValue = Boolean.parseBoolean(value); } catch (Exception e) { - throw new TestFormatException("Invalid value " + value + " for boolean flag " + flag); + TestFormat.fail("Invalid value " + value + " for boolean flag " + flag); } return booleanValue == actualBooleanFlagValue; } actualFlagValue = WHITE_BOX.getDoubleVMFlag(flag); if (actualFlagValue != null) { double actualDoubleFlagValue = (Double) actualFlagValue; - double doubleValue; - ParsedComparator parsedComparator; - + double doubleValue = 0; + ParsedComparator parsedComparator = null; try { parsedComparator = parseComparator(value); doubleValue = Double.parseDouble(parsedComparator.getStrippedString()); } catch (NumberFormatException e) { - throw new TestFormatException("Invalid value " + value + " for number based flag " + flag); + TestFormat.fail("Invalid value " + value + " for number based flag " + flag); } catch (Exception e) { - throw new TestFormatException("Invalid comparator in \"" + value + "\" for number based flag " + flag, e); + TestFormat.fail("Invalid comparator in \"" + value + "\" for number based flag " + flag, e); } return parsedComparator.getPredicate().test(actualDoubleFlagValue, doubleValue); } @@ -195,11 +182,12 @@ private boolean check(Method m, String flag, String value) { String actualStringFlagValue = (String) actualFlagValue; return actualStringFlagValue.equals(value); } - throw new TestFormatException("Could not find flag " + flag); + TestFormat.fail("Could not find flag " + flag); + return false; } private > ParsedComparator parseComparator(String value) { - BiPredicate comparison; + BiPredicate comparison = null; try { switch (value.charAt(0)) { case '<': @@ -221,12 +209,9 @@ private > ParsedComparator parseComparator(String val } break; case '!': - if (value.charAt(1) == '=') { - comparison = (x, y) -> x.compareTo(y) != 0; - value = value.substring(2).trim(); - } else { - throw new TestFormatException("Invalid comparator sign used."); - } + TestFormat.check(value.charAt(1) == '=', "Invalid comparator sign used."); + comparison = (x, y) -> x.compareTo(y) != 0; + value = value.substring(2).trim(); break; case '=': // Allowed syntax, equivalent to not using any symbol. value = value.substring(1).trim(); @@ -236,7 +221,7 @@ private > ParsedComparator parseComparator(String val break; } } catch (IndexOutOfBoundsException e) { - throw new TestFormatException("Invalid value format."); + TestFormat.fail("Invalid value format."); } return new ParsedComparator<>(value, comparison); } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java index 69c6b7d0b5a..8a5180ed142 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java @@ -84,19 +84,11 @@ public void applyRules() { for (Method m : testClass.getDeclaredMethods()) { IR[] irAnnos = m.getAnnotationsByType(IR.class); if (irAnnos.length > 0) { - if (!m.isAnnotationPresent(Test.class)) { - throw new TestFormatException("Found IR annotation at non-@Test method " + m); - } + TestFormat.check(m.isAnnotationPresent(Test.class), "Found @IR annotation at non-@Test method " + m); Integer[] ids = irRulesMap.get(m.getName()); - if (ids == null) { - throw new TestFrameworkException("Should find method name in validIrRulesMap for " + m); - } - if (ids.length < 1) { - throw new TestFrameworkException("Did not find any rule indices for " + m); - } - if (ids[ids.length - 1] >= irAnnos.length) { - throw new TestFrameworkException("Invalid IR rule index found in validIrRulesMap for " + m); - } + TestFramework.check(ids != null, "Should find method name in validIrRulesMap for " + m); + TestFramework.check(ids.length > 0, "Did not find any rule indices for " + m); + TestFramework.check(ids[ids.length - 1] < irAnnos.length, "Invalid IR rule index found in validIrRulesMap for " + m); if (ids[0] != IREncodingPrinter.NO_RULE_APPLIED) { // If -1, than there was no matching IR rule for given conditions. applyRuleToMethod(m, irAnnos, ids); @@ -147,15 +139,13 @@ private void applyCount(Method m, String testOutput, IR irAnno, int annoId) { final List nodesWithCount = IRNode.mergeNodes(irAnno.counts()); for (int i = 0; i < nodesWithCount.size(); i += 2) { String node = nodesWithCount.get(i); - if (i + 1 == nodesWithCount.size()) { - throw new TestFormatException("Missing count for IR node \"" + node + "\" at " + m); - } + TestFormat.check(i + 1 < nodesWithCount.size(), "Missing count for IR node \"" + node + "\" at " + m); String countString = nodesWithCount.get(i + 1); - long expectedCount; + long expectedCount = 0; try { expectedCount = Long.parseLong(countString); } catch (NumberFormatException e) { - throw new TestFormatException("Provided invalid count \"" + countString + "\" for IR node \"" + node + "\" at " + m); + TestFormat.fail("Provided invalid count \"" + countString + "\" for IR node \"" + node + "\" at " + m); } Pattern pattern = Pattern.compile(node); Matcher matcher = pattern.matcher(testOutput); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java index b8e9a84b282..913adc3dfdf 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java @@ -94,9 +94,7 @@ static List mergeNodes(String[] nodes) { } private static void mergeCompositeNodes(String[] nodes, List mergedNodes, int i, String node, String postFix, String varName) { - if (i + 1 == nodes.length) { - throw new TestFormatException("Must provide class name at index " + (i + 1) + " right after " + varName); - } + TestFormat.check(i + 1 < nodes.length, "Must provide class name at index " + (i + 1) + " right after " + varName); mergedNodes.add(node + Pattern.quote(nodes[i + 1]) + postFix); } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java new file mode 100644 index 00000000000..d684ae321de --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java @@ -0,0 +1,26 @@ +package compiler.valhalla.framework; + +public class TestFormat { + public static void check(boolean test, String failureMessage) { + if (!test) { + throw new TestFormatException(failureMessage); + } + } + public static void fail(String failureMessage) { + throw new TestFormatException(failureMessage); + } + + public static void fail(String failureMessage, Exception e) { + throw new TestFormatException(failureMessage, e); + } +} + +class TestFormatException extends RuntimeException { + public TestFormatException(String message) { + super(message); + } + + public TestFormatException(String message, Exception e) { + super(message, e); + } +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java deleted file mode 100644 index d5f80b6c6a1..00000000000 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java +++ /dev/null @@ -1,13 +0,0 @@ -package compiler.valhalla.framework; - -public class TestFormatException extends RuntimeException { - public TestFormatException(String message) { - super(message); - } - - public TestFormatException(String message, Exception e) { - super(message, e); - } -} - - diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 20d0a63d163..beb423732e7 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -362,9 +362,8 @@ public String getScenarioOutput(int scenarioId) { } private void checkScenarioId(int scenarioId) { - if (scenarioId < 0 || scenarioId >= scenarios.size()) { - throw new TestFormatException("Invalid default scenario id " + scenarioId + ". Must be in [0, " + (scenarios.size() - 1) + "]."); - } + TestFormat.check(scenarioId >= 0 && scenarioId < scenarios.size(), + "Invalid default scenario id " + scenarioId + ". Must be in [0, " + (scenarios.size() - 1) + "]."); } // Can be overridden, for example by Valhalla @@ -400,9 +399,7 @@ private void addReplay() { if (DUMP_REPLAY) { // Generate replay compilation files String directive = "[{ match: \"*.*\", DumpReplay: true }]"; - if (WHITE_BOX.addCompilerDirective(directive) != 1) { - throw new TestFormatException("Failed to add DUMP_REPLAY directive"); - } + TestFormat.check(WHITE_BOX.addCompilerDirective(directive) == 1, "Failed to add DUMP_REPLAY directive"); } } @@ -426,19 +423,17 @@ private void applyIndependentCompilationCommands(Method m) { ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); DontCompile dontCompileAnno = getAnnotation(m, DontCompile.class); Test testAnno = getAnnotation(m, Test.class); - if (testAnno != null && Stream.of(forceCompileAnno, dontCompileAnno, forceInlineAnno, dontInlineAnno).anyMatch(Objects::nonNull)) { - throw new TestFormatException("Not allowed to use explicit compile command annotations (@ForceInline, @DontInline," + - "@ForceCompile or @DontCompile) together with @Test at " + m + ". Use compLevel and skip in @Test for fine tuning."); - } + TestFormat.check(testAnno == null || Stream.of(forceCompileAnno, dontCompileAnno, forceInlineAnno, dontInlineAnno).noneMatch(Objects::nonNull), + "Not allowed to use explicit compile command annotations (@ForceInline, @DontInline," + + "@ForceCompile or @DontCompile) together with @Test at " + m + ". Use compLevel and skip in @Test for fine tuning."); if (Stream.of(forceCompileAnno, dontCompileAnno, dontInlineAnno).filter(Objects::nonNull).count() > 1) { - if (dontCompileAnno != null && dontInlineAnno != null) { - throw new TestFormatException("@DontInline is implicitely done with @DontCompile annotation at " + m); - } - throw new TestFormatException("Cannot mix @ForceInline, @DontInline and @DontCompile at the same time at " + m); - } - if (forceCompileAnno != null && dontCompileAnno != null) { - throw new TestFormatException("Cannot have @ForceCompile and @DontCompile at the same time at " + m); + // Failure + TestFormat.check(dontCompileAnno == null || dontInlineAnno == null, + "@DontInline is implicitely done with @DontCompile annotation at " + m); + TestFormat.fail("Cannot mix @ForceInline, @DontInline and @DontCompile at the same time at " + m); } + TestFormat.check(forceCompileAnno == null || dontCompileAnno == null, + "Cannot have @ForceCompile and @DontCompile at the same time at " + m); // First handle inline annotations if (dontInlineAnno != null) { WHITE_BOX.testSetDontInlineMethod(m, true); @@ -473,9 +468,8 @@ private void applyForceCompileCommand(Method m) { // Can be called from tests for non-@Test methods public static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { - if (getAnnotation(m, Test.class) != null) { - throw new TestFormatException("Cannot call enqueueMethodForCompilation() for @Test annotated method " + m); - } + TestFormat.check(getAnnotation(m, Test.class) == null, + "Cannot call enqueueMethodForCompilation() for @Test annotated method " + m); TestFrameworkUtils.enqueueMethodForCompilation(m ,compLevel); } @@ -483,14 +477,11 @@ private void setupTestMethodMap(Class clazz) { Arrays.stream(clazz.getDeclaredMethods()).forEach(m -> { Test testAnno = getAnnotation(m, Test.class); if (testAnno != null) { - if (testMethodMap.containsKey(m.getName())) { - throw new TestFormatException("Cannot overload two @Test methods " + m + " and " + testMethodMap.get(m.getName())); - } + TestFormat.check(!testMethodMap.containsKey(m.getName()), + "Cannot overload two @Test methods " + m + " and " + testMethodMap.get(m.getName())); testMethodMap.put(m.getName(), m); } else { - if (m.isAnnotationPresent(IR.class)) { - throw new TestFormatException("Found @IR annotation on non-@Test method " + m); - } + TestFormat.check(!m.isAnnotationPresent(IR.class), "Found @IR annotation on non-@Test method " + m); } }); } @@ -507,19 +498,15 @@ private void setupTests(Class clazz) { private void addTest(Class clazz, Method m, Argument[] arguments) { Test testAnno = getAnnotation(m, Test.class); - if (testAnno == null) { - throw new TestFormatException(m + " must be a method with a @Test annotation"); - } + TestFormat.check(testAnno != null, m + " must be a method with a @Test annotation"); Check checkAnno = getAnnotation(m, Check.class); Run runAnno = getAnnotation(m, Run.class); - if (checkAnno != null || runAnno != null) { - throw new TestFormatException(m + " has invalid @Check or @Run annotation while @Test annotation is present."); - } + TestFormat.check(checkAnno == null && runAnno == null, + m + " has invalid @Check or @Run annotation while @Test annotation is present."); - if (Arrays.asList(m.getParameterTypes()).contains(TestInfo.class)) { - throw new TestFormatException("Forbidden use of " + TestInfo.class + " as parameter at @Test method " + m); - } + TestFormat.check(!Arrays.asList(m.getParameterTypes()).contains(TestInfo.class), + "Forbidden use of " + TestInfo.class + " as parameter at @Test method " + m); Warmup warmup = getAnnotation(m, Warmup.class); int warmupIterations = WARMUP_ITERATIONS; @@ -543,9 +530,8 @@ private void setupCheckAndRunMethods(Class clazz) { Check checkAnno = getAnnotation(m, Check.class); Run runAnno = getAnnotation(m, Run.class); Arguments argumentsAnno = getAnnotation(m, Arguments.class); - if ((checkAnno != null || runAnno != null) && argumentsAnno != null) { - throw new TestFormatException("Cannot have @Argument annotation in combination with @Run or @Check at " + m); - } + TestFormat.check(argumentsAnno == null || (checkAnno == null && runAnno == null), + "Cannot have @Argument annotation in combination with @Run or @Check at " + m); if (checkAnno != null) { addCheckedTest(m, checkAnno, runAnno); } else if (runAnno != null) { @@ -555,49 +541,38 @@ private void setupCheckAndRunMethods(Class clazz) { } private void addCheckedTest(Method m, Check checkAnno, Run runAnno) { - if (runAnno != null) { - throw new TestFormatException(m + " has invalid @Run annotation while @Check annotation is present."); - } + TestFormat.check(runAnno == null, m + " has invalid @Run annotation while @Check annotation is present."); Method testMethod = testMethodMap.get(checkAnno.test()); - if (testMethod == null) { - throw new TestFormatException("Did not find associated test method " + checkAnno.test() + " for @Check at " + m); - } + TestFormat.check(testMethod != null,"Did not find associated test method " + checkAnno.test() + " for @Check at " + m); boolean firstParameterTestInfo = m.getParameterCount() > 0 && m.getParameterTypes()[0].equals(TestInfo.class); boolean secondParameterTestInfo = m.getParameterCount() > 1 && m.getParameterTypes()[1].equals(TestInfo.class); - CheckedTest.Parameter parameter; + CheckedTest.Parameter parameter = null; Class testReturnType = testMethod.getReturnType(); switch (m.getParameterCount()) { - case 0 -> { - parameter = CheckedTest.Parameter.NONE; - } + case 0 -> parameter = CheckedTest.Parameter.NONE; case 1 -> { - if (!firstParameterTestInfo && m.getParameterTypes()[0] != testReturnType) { - throw new TestFormatException("Single-parameter version of @Check method " + m + " must match return type of @Test " + testMethod); - } + TestFormat.check(firstParameterTestInfo || m.getParameterTypes()[0] == testReturnType, + "Single-parameter version of @Check method " + m + " must match return type of @Test " + testMethod); parameter = firstParameterTestInfo ? CheckedTest.Parameter.TEST_INFO_ONLY : CheckedTest.Parameter.RETURN_ONLY; } case 2 -> { - if (!secondParameterTestInfo || m.getParameterTypes()[0] != testReturnType) { - throw new TestFormatException("Two-parameter version of @Check method " + m + " must provide as first parameter the same" + - " return type as @Test method " + testMethod + " and as second parameter an object of " + TestInfo.class); - } + TestFormat.check(m.getParameterTypes()[0] == testReturnType && secondParameterTestInfo, + "Two-parameter version of @Check method " + m + " must provide as first parameter the same" + + " return type as @Test method " + testMethod + " and as second parameter an object of " + TestInfo.class); parameter = CheckedTest.Parameter.BOTH; } - default -> { - throw new TestFormatException("@Check method " + m + " must provide either a none, single or two-parameter variant."); - } + default -> TestFormat.fail("@Check method " + m + " must provide either a none, single or two-parameter variant."); } if (allTests.containsKey(testMethod)) { - BaseTest baseTest = allTests.get(testMethod); - throw new TestFormatException("Method " + m + " and " + baseTest.getAssociatedTestName() + " cannot both reference test method " + testMethod); + TestFormat.fail("Method " + m + " and " + allTests.get(testMethod).getAssociatedTestName() + + " cannot both reference test method " + testMethod); } + DeclaredTest test = declaredTests.remove(testMethod); - if (test == null) { - throw new TestFormatException("Missing @Test annotation for associated test method " + checkAnno.test() + " for @Check at " + m); - } + TestFormat.check(test != null, "Missing @Test annotation for associated test method " + checkAnno.test() + " for @Check at " + m); applyCompileCommands(m); // Don't inline check methods WHITE_BOX.testSetDontInlineMethod(m, true); @@ -621,19 +596,12 @@ private void applyCompileCommands(Method m) { private void addCustomRunTest(Method m, Run runAnno) { Method testMethod = testMethodMap.get(runAnno.test()); - if (testMethod == null) { - throw new TestFormatException("Did not find associated test method " + runAnno.test() + " for @Run at " + m); - } + TestFormat.check(testMethod != null, "Did not find associated test method " + runAnno.test() + " for @Run at " + m); DeclaredTest test = declaredTests.remove(testMethod); - if (test == null) { - throw new TestFormatException("Missing @Test annotation for associated test method " + runAnno.test() + " for @Run at " + m); - } - if (test.hasArguments()) { - throw new TestFormatException("Invalid @Arguments annotation for associated test method " + runAnno.test() + " for @Run at " + m); - } - if (m.getParameterCount() > 1 || (m.getParameterCount() == 1 && !m.getParameterTypes()[0].equals(TestInfo.class))) { - throw new TestFormatException("@Run method " + m + " must specify either no TestInfo parameter or exactly one"); - } + TestFormat.check(test != null, "Missing @Test annotation for associated test method " + runAnno.test() + " for @Run at " + m); + TestFormat.check(!test.hasArguments(), "Invalid @Arguments annotation for associated test method " + runAnno.test() + " for @Run at " + m); + TestFormat.check(m.getParameterCount() == 0 || (m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(TestInfo.class)), + "@Run method " + m + " must specify either no TestInfo parameter or exactly one"); applyCompileCommands(m); // Don't inline run methods WHITE_BOX.testSetDontInlineMethod(m, true); @@ -643,9 +611,7 @@ private void addCustomRunTest(Method m, Run runAnno) { public static T getAnnotation(Method m, Class c) { T[] annos = m.getAnnotationsByType(c); - if (annos.length > 1) { - throw new TestFormatException(m + " has duplicated annotations"); - } + TestFormat.check(annos.length < 2, m + " has duplicated annotations"); return Arrays.stream(annos).findFirst().orElse(null); } @@ -717,6 +683,12 @@ private static TriState compiledByC2(Method m) { } return TriState.No; } + + public static void check(boolean test, String failureMessage) { + if (!test) { + throw new TestFrameworkException("Internal TestFramework exception:\n" + failureMessage); + } + } } // Errors in the framework @@ -946,7 +918,7 @@ private void compileNormallyAndRun() { try { Thread.sleep(100); } catch (InterruptedException e) { - throw new TestFormatException("Error while waiting for compilation to be completed of " + testMethod); + TestFormat.fail("Error while waiting for compilation to be completed of " + testMethod); } } Asserts.assertTrue(WHITE_BOX.isMethodCompiled(testMethod, false), testMethod + " not compiled after waiting 1s"); From 85a1547e871a37d100e9c8a74ec0e3fe6b95c5db Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 18 Jan 2021 12:04:53 +0100 Subject: [PATCH 004/131] Refactoring --- .../compiler/valhalla/framework/Argument.java | 1 - .../valhalla/framework/TestFramework.java | 170 +++++++----------- .../compiler/valhalla/framework/TestInfo.java | 49 ++++- .../framework/tests/TestPackagePrivate.java | 44 +---- 4 files changed, 115 insertions(+), 149 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java index 68ce869c62d..3c059ff57b1 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java @@ -1,6 +1,5 @@ package compiler.valhalla.framework; - import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Random; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index beb423732e7..2f8d7614dff 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -385,7 +385,6 @@ protected void setupDefaultScenarios() { private void parseTestClass(Class clazz) { addReplay(); processExplicitCompileCommands(clazz); - setupTestMethodMap(clazz); setupTests(clazz); setupCheckAndRunMethods(clazz); @@ -399,7 +398,7 @@ private void addReplay() { if (DUMP_REPLAY) { // Generate replay compilation files String directive = "[{ match: \"*.*\", DumpReplay: true }]"; - TestFormat.check(WHITE_BOX.addCompilerDirective(directive) == 1, "Failed to add DUMP_REPLAY directive"); + TestFramework.check(WHITE_BOX.addCompilerDirective(directive) == 1, "Failed to add DUMP_REPLAY directive"); } } @@ -473,30 +472,24 @@ public static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { TestFrameworkUtils.enqueueMethodForCompilation(m ,compLevel); } - private void setupTestMethodMap(Class clazz) { - Arrays.stream(clazz.getDeclaredMethods()).forEach(m -> { + private void setupTests(Class clazz) { + for (Method m : clazz.getDeclaredMethods()) { Test testAnno = getAnnotation(m, Test.class); if (testAnno != null) { TestFormat.check(!testMethodMap.containsKey(m.getName()), "Cannot overload two @Test methods " + m + " and " + testMethodMap.get(m.getName())); + addTest(m, Argument.getArguments(m)); testMethodMap.put(m.getName(), m); } else { TestFormat.check(!m.isAnnotationPresent(IR.class), "Found @IR annotation on non-@Test method " + m); } - }); - } - - private void setupTests(Class clazz) { - for (Method m : testMethodMap.values()) { - Argument[] arguments = Argument.getArguments(m); - addTest(clazz, m, arguments); } if (PRINT_VALID_IR_RULES) { irMatchRulePrinter.dump(); } } - private void addTest(Class clazz, Method m, Argument[] arguments) { + private void addTest(Method m, Argument[] arguments) { Test testAnno = getAnnotation(m, Test.class); TestFormat.check(testAnno != null, m + " must be a method with a @Test annotation"); @@ -521,7 +514,7 @@ private void addTest(Class clazz, Method m, Argument[] arguments) { } // Don't inline test methods WHITE_BOX.testSetDontInlineMethod(m, true); - DeclaredTest test = new DeclaredTest(m, testAnno, arguments, clazz, warmupIterations, osrOnly); + DeclaredTest test = new DeclaredTest(m, testAnno, arguments, warmupIterations, osrOnly); declaredTests.put(m, test); } @@ -567,7 +560,7 @@ private void addCheckedTest(Method m, Check checkAnno, Run runAnno) { } if (allTests.containsKey(testMethod)) { - TestFormat.fail("Method " + m + " and " + allTests.get(testMethod).getAssociatedTestName() + TestFormat.fail("Method " + m + " and " + allTests.get(testMethod).getTestName() + " cannot both reference test method " + testMethod); } @@ -630,9 +623,9 @@ public void runTests() { if (PRINT_TIMES || VERBOSE) { long endTime = System.nanoTime(); long duration = (endTime - startTime); - durations.put(duration, test.getAssociatedTestName()); + durations.put(duration, test.getTestName()); if (VERBOSE) { - System.out.println("Done " + test.getAssociatedTestName() + ": " + duration + " ns = " + (duration / 1000000) + " ms"); + System.out.println("Done " + test.getTestName() + ": " + duration + " ns = " + (duration / 1000000) + " ms"); } } if (GC_AFTER) { @@ -650,40 +643,6 @@ public void runTests() { } } - enum TriState { - Maybe, - Yes, - No - } - - public static boolean isC2Compiled(Method m) { - return compiledByC2(m) == TriState.Yes; - } - - public static void assertDeoptimizedByC2(Method m) { - if (compiledByC2(m) == TriState.Yes) { - throw new TestRunException("Expected to have deoptimized"); - } - } - - public static void assertCompiledByC2(Method m) { - if (compiledByC2(m) == TriState.No) { - throw new TestRunException("Expected to be compiled"); - } - } - - private static TriState compiledByC2(Method m) { - if (!USE_COMPILER || XCOMP || TEST_C1 || - (STRESS_CC && !WHITE_BOX.isMethodCompilable(m, CompLevel.C2_FULL_OPTIMIZATION.getValue(), false))) { - return TriState.Maybe; - } - if (WHITE_BOX.isMethodCompiled(m, false) && - WHITE_BOX.getMethodCompilationLevel(m, false) >= CompLevel.C2_FULL_OPTIMIZATION.getValue()) { - return TriState.Yes; - } - return TriState.No; - } - public static void check(boolean test, String failureMessage) { if (!test) { throw new TestFrameworkException("Internal TestFramework exception:\n" + failureMessage); @@ -726,12 +685,11 @@ public Method getTestMethod() { } private final Argument[] arguments; - private final Object invocationTarget; private final int warmupIterations; private final CompLevel requestedCompLevel; private final boolean osrOnly; - public DeclaredTest(Method testMethod, Test testAnnotation, Argument[] arguments, Class c, int warmupIterations, boolean osrOnly) { + public DeclaredTest(Method testMethod, Test testAnnotation, Argument[] arguments, int warmupIterations, boolean osrOnly) { // Make sure we can also call non-public or public methods in package private classes testMethod.setAccessible(true); this.testMethod = testMethod; @@ -739,18 +697,6 @@ public DeclaredTest(Method testMethod, Test testAnnotation, Argument[] arguments this.arguments = arguments; this.warmupIterations = warmupIterations; this.osrOnly = osrOnly; - if (Modifier.isStatic(testMethod.getModifiers())) { - invocationTarget = null; - } else { - try { - Constructor constructor = c.getDeclaredConstructor(); - constructor.setAccessible(true); - invocationTarget = constructor.newInstance(); - } catch (Exception e) { - throw new TestRunException("Could not create instance of " + c - + ". Make sure there is a constructor without arguments.", e); - } - } } public CompLevel getRequestedCompLevel() { @@ -769,6 +715,10 @@ public boolean hasArguments() { return arguments != null; } + public Object[] getArguments() { + return Arrays.stream(arguments).map(Argument::getArgument).toArray(); + } + public void printFixedRandomArguments() { if (hasArguments()) { boolean hasRandomArgs = false; @@ -788,19 +738,6 @@ public void printFixedRandomArguments() { } } - public Object invokeWithSpecifiedArguments() { - try { - if (hasArguments()) { - Object[] args = Arrays.stream(arguments).map(Argument::getArgument).toArray(); - return testMethod.invoke(invocationTarget, args); - } else { - return testMethod.invoke(invocationTarget); - } - } catch (Exception e) { - throw new TestRunException("There was an error while invoking @Test method " + testMethod, e); - } - } - public Object invoke(Object obj, Object... args) { try { return testMethod.invoke(obj, args); @@ -809,10 +746,6 @@ public Object invoke(Object obj, Object... args) { } } - public Object getInvocationTarget() { - return invocationTarget; - } - public void checkCompilationLevel() { int level = WhiteBox.getWhiteBox().getMethodCompilationLevel(testMethod); Asserts.assertEQ(level, TestFrameworkUtils.compLevelToInt(requestedCompLevel), "Unexpected compilation level for " + testMethod); @@ -824,16 +757,30 @@ class BaseTest { private static final int OSR_TEST_TIMEOUT = Integer.parseInt(System.getProperty("OSRTestTimeOut", "5000")); protected final DeclaredTest test; + protected final Method testMethod; protected final TestInfo testInfo; protected final Object invocationTarget; public BaseTest(DeclaredTest test) { this.test = test; - this.testInfo = new TestInfo(); - this.invocationTarget = test.getInvocationTarget(); + this.testMethod = test.getTestMethod(); + this.testInfo = new TestInfo(testMethod); + Class clazz = testMethod.getDeclaringClass(); + if (Modifier.isStatic(testMethod.getModifiers())) { + this.invocationTarget = null; + } else { + try { + Constructor constructor = clazz.getDeclaredConstructor(); + constructor.setAccessible(true); + this.invocationTarget = constructor.newInstance(); + } catch (Exception e) { + throw new TestRunException("Could not create instance of " + clazz + + ". Make sure there is a constructor without arguments.", e); + } + } } - public String getAssociatedTestName() { - return test.getTestMethod().getName(); + public String getTestName() { + return testMethod.getName(); } /** @@ -861,31 +808,32 @@ public void run() { } protected void runMethod() { - verify(testInfo, test.invokeWithSpecifiedArguments()); + verify(testInfo, invokeTestMethod()); + } + + private Object invokeTestMethod() { + try { + if (test.hasArguments()) { + return testMethod.invoke(invocationTarget, test.getArguments()); + } else { + return testMethod.invoke(invocationTarget); + } + } catch (Exception e) { + throw new TestRunException("There was an error while invoking @Test method " + testMethod, e); + } } - protected void compileOSRAndRun() { + private void compileOSRAndRun() { final boolean maybeCodeBufferOverflow = (TestFramework.TEST_C1 && TestFramework.VerifyOops); final long started = System.currentTimeMillis(); boolean stateCleared = false; while (true) { long elapsed = System.currentTimeMillis() - started; - Method testMethod = test.getTestMethod(); int level = WHITE_BOX.getMethodCompilationLevel(testMethod); if (maybeCodeBufferOverflow && elapsed > 5000 && (!WHITE_BOX.isMethodCompiled(testMethod, false) || level != test.getRequestedCompLevel().getValue())) { - System.out.println("Temporarily disabling VerifyOops"); - try { - WHITE_BOX.setBooleanVMFlag("VerifyOops", false); - if (!stateCleared) { - WHITE_BOX.clearMethodState(testMethod); - stateCleared = true; - } - runMethod(); - } finally { - WHITE_BOX.setBooleanVMFlag("VerifyOops", true); - System.out.println("Re-enabled VerifyOops"); - } + retryDisabledVerifyOops(stateCleared); + stateCleared = true; } else { runMethod(); } @@ -898,7 +846,21 @@ protected void compileOSRAndRun() { // Don't control compilation if -Xcomp is enabled, or if compiler is disabled break; } - Asserts.assertTrue(OSR_TEST_TIMEOUT < 0 || elapsed < OSR_TEST_TIMEOUT, test + " not compiled after " + OSR_TEST_TIMEOUT + " ms"); + Asserts.assertTrue(OSR_TEST_TIMEOUT < 0 || elapsed < OSR_TEST_TIMEOUT, testMethod + " not compiled after " + OSR_TEST_TIMEOUT + " ms"); + } + } + + private void retryDisabledVerifyOops(boolean stateCleared) { + System.out.println("Temporarily disabling VerifyOops"); + try { + WHITE_BOX.setBooleanVMFlag("VerifyOops", false); + if (!stateCleared) { + WHITE_BOX.clearMethodState(testMethod); + } + runMethod(); + } finally { + WHITE_BOX.setBooleanVMFlag("VerifyOops", true); + System.out.println("Re-enabled VerifyOops"); } } @@ -935,7 +897,7 @@ public void verify(TestInfo testInfo, Object result) { /* no verification in Bas class CheckedTest extends BaseTest { private final Method checkMethod; - private final Check checkSpecification; + private final CheckAt checkAt; private final Parameter parameter; enum Parameter { @@ -947,14 +909,14 @@ public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecificati // Make sure we can also call non-public or public methods in package private classes checkMethod.setAccessible(true); this.checkMethod = checkMethod; - this.checkSpecification = checkSpecification; + this.checkAt = checkSpecification.when(); this.parameter = parameter; } @Override public void verify(TestInfo testInfo, Object result) { boolean shouldVerify = false; - switch (checkSpecification.when()) { + switch (checkAt) { case EACH_INVOCATION -> shouldVerify = true; case C2_COMPILED -> shouldVerify = !testInfo.isWarmUp(); } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java index 4b72346fc70..e38faa047f6 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java @@ -1,11 +1,21 @@ package compiler.valhalla.framework; +import sun.hotspot.WhiteBox; + +import java.lang.reflect.Method; import java.util.Random; public class TestInfo { + private static final Random random = new Random(); + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private boolean toggleBool = false; private boolean onWarmUp = true; - private static final Random random = new Random(); + private final Method testMethod; + + public TestInfo(Method testMethod) { + this.testMethod = testMethod; + } public boolean toggleBoolean() { toggleBool = !toggleBool; @@ -28,7 +38,42 @@ public boolean isWarmUp() { return onWarmUp; } - public void setWarmUpFinished() { + void setWarmUpFinished() { onWarmUp = false; } + + + enum TriState { + Maybe, + Yes, + No + } + + public static boolean isC2Compiled(Method m) { + return compiledByC2(m) == TriState.Yes; + } + + public static void assertDeoptimizedByC2(Method m) { + if (compiledByC2(m) == TriState.Yes) { + throw new TestRunException(m + " should have been deoptimized"); + } + } + + public static void assertCompiledByC2(Method m) { + if (compiledByC2(m) == TriState.No) { + throw new TestRunException(m + " should have been compiled"); + } + } + + private static TriState compiledByC2(Method m) { + if (!TestFramework.USE_COMPILER || TestFramework.XCOMP || TestFramework.TEST_C1 || + (TestFramework.STRESS_CC && !WHITE_BOX.isMethodCompilable(m, CompLevel.C2_FULL_OPTIMIZATION.getValue(), false))) { + return TriState.Maybe; + } + if (WHITE_BOX.isMethodCompiled(m, false) && + WHITE_BOX.getMethodCompilationLevel(m, false) >= CompLevel.C2_FULL_OPTIMIZATION.getValue()) { + return TriState.Yes; + } + return TriState.No; + } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java index 78c22b0a011..13c17a17fd6 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java @@ -13,47 +13,7 @@ public static void main(String[] args) { } } -// @Test -// @Arguments({ArgumentValue.DEFAULT, ArgumentValue.FALSE, ArgumentValue.NUMBER_42, ArgumentValue.RANDOM_ALL, ArgumentValue.RANDOM_ONCE, ArgumentValue.BOOLEAN_TOGGLE}) -// public int test(int arg1, boolean arg2, double arg3, double arg4, int arg5, boolean arg6) { -// return 0; -// } -// -// // Useful for quick checking, nothing fancy going on. This method is optional. -// @Check(test="test", when=CheckAt.C2_COMPILED) -// // Must match method 'test' when removing '_check'. Could also think about matching in annotation, e.g. @Check(test="test2"). -// public void test_check(int result /* must match return argument of 'test', possible to check? */) { -// // This method runs in interpreter, DontCompile. -// // Check that there is a method 'test' with @Test, no method 'test_check' or when present no @Run at it (bad style though, better use check in annotation?), -// // 'test' has non-void return (if void, what do you need the check for then?) -// // If 'test' has arguments but no @Arguments annotation, framework takes default arguments (bad style though). -// // Framework executes 'test' with warmup (specified or default). -// // This method is then called from framework once after 'test' compiled or once when 'test' is called the first time by framework and after 'test' is compiled -//// Asserts.assertEQ(result, 0); -// } -// -// @Test -// public void test2(int arg1, boolean arg2, int arg3, int arg4) { -// } -// -// // Optional method. -// // Useful when more complex/changing arguments are required. Framework calls this method in interpreter and let it handle how to call the method -// // 'test'. Framework could verify that this method has at least one call to 'test2'? -// @Run(test="test2") -// // Must match method 'test2' when removing '_run'. Could also think about matching in annotation, e.g. @Run(test="test2"). -// public void test2_run(TestInfo info) { -// // This method runs in interpreter, DontCompile -// // Check that there is a method 'test2' with @Test. -// // Check that no @Arguments present in 'test2' (not useful when specifying here how to call the method) -// // Called each time by framework, specifies how to run test -// if (info.isWarmUp()) { -// test2(34, info.toggleBoolean(), info.getRandomInt(), 0); -// } else { -// test2(12, true, info.getRandomInt(), -555); -// } -// } - - class PackagePrivate { +class PackagePrivate { @Test public void test() { } @@ -62,4 +22,4 @@ public void test() { @Arguments(ArgumentValue.DEFAULT) public void test2(int x) { } -} \ No newline at end of file +} From 2f5449d8ce5ea1b85d53d46f05ce715121104d32 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 18 Jan 2021 14:15:02 +0100 Subject: [PATCH 005/131] Fix helper classes and add test for it --- .../valhalla/framework/CompLevel.java | 2 +- .../valhalla/framework/ForceCompile.java | 2 +- .../valhalla/framework/TestFramework.java | 137 ++++++++++++------ .../compiler/valhalla/framework/TestInfo.java | 35 +---- .../valhalla/framework/tests/TestBasics.java | 8 +- .../tests/TestWithHelperClasses.java | 38 +++++ 6 files changed, 146 insertions(+), 76 deletions(-) create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java index 7b2ce36a01b..e1e2f11f284 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java @@ -11,7 +11,7 @@ public enum CompLevel { C1_SIMPLE(1), // C1 C1_LIMITED_PROFILE(2), // C1, invocation & backedge counters C1_FULL_PROFILE(3), // C1, invocation & backedge counters + mdo - C2_FULL_OPTIMIZATION(4); // C2 or JVMCI + C2(4); // C2 or JVMCI private static final Map typesByValue = new HashMap<>(); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java index b6a0d883833..7376188a795 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java @@ -6,5 +6,5 @@ // Force method compilation @Retention(RetentionPolicy.RUNTIME) public @interface ForceCompile { - CompLevel compLevel() default CompLevel.ANY; + CompLevel value() default CompLevel.ANY; } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 2f8d7614dff..58f37286778 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -66,36 +66,16 @@ public class TestFramework { // "jtreg -DXcomp=true" runs all the scenarios with -Xcomp. This is faster than "jtreg -javaoptions:-Xcomp". static final boolean RUN_WITH_XCOMP = Boolean.parseBoolean(System.getProperty("Xcomp", "false")); + static final boolean TESTING_TEST_FRAMEWORK = Boolean.parseBoolean(System.getProperty("TestingTestFramework", "false")); + private final String[] fixedDefaultFlags; private final String[] compileCommandFlags; private final String[] printFlags; private final String[] verifyFlags; private static String lastVmOutput; // Only used to test TestFramework - protected String[] setupDefaultFlags() { - return new String[] {"-XX:-BackgroundCompilation"}; - } - - protected String[] setupCompileCommandFlags() { - return new String[] {"-XX:CompileCommand=quiet"}; - } - - protected String[] setupPrintFlags() { - return new String[] {"-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions"}; - } - - protected String[] setupVerifyFlags() { - return new String[] { - "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", "-XX:+VerifyBeforeGC", - "-XX:+VerifyAfterGC", "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing"}; - } - static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); - static final boolean PRINT_IDEAL = WHITE_BOX.getBooleanVMFlag("PrintIdeal"); - - static final boolean G1GC = (Boolean)WHITE_BOX.getVMFlag("UseG1GC"); - static final boolean ZGC = (Boolean)WHITE_BOX.getVMFlag("UseZGC"); - static final boolean VerifyOops = (Boolean)WHITE_BOX.getVMFlag("VerifyOops"); + static final boolean VERIFY_OOPS = (Boolean)WHITE_BOX.getVMFlag("VerifyOops"); private final HashMap declaredTests = new HashMap<>(); private final LinkedHashMap allTests = new LinkedHashMap<>(); // Keep order @@ -107,7 +87,7 @@ protected String[] setupVerifyFlags() { private final IREncodingPrinter irMatchRulePrinter; // Used to run scenarios - public TestFramework() { + TestFramework() { // These flags can be overridden fixedDefaultFlags = setupDefaultFlags(); compileCommandFlags = setupCompileCommandFlags(); @@ -121,6 +101,24 @@ public TestFramework() { } } + protected String[] setupDefaultFlags() { + return new String[] {"-XX:-BackgroundCompilation"}; + } + + protected String[] setupCompileCommandFlags() { + return new String[] {"-XX:CompileCommand=quiet"}; + } + + protected String[] setupPrintFlags() { + return new String[] {"-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions"}; + } + + protected String[] setupVerifyFlags() { + return new String[] { + "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", "-XX:+VerifyBeforeGC", + "-XX:+VerifyAfterGC", "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing"}; + } + public static void main(String[] args) { String testClassName = args[0]; System.out.println("Framework main(), about to run test class " + testClassName); @@ -131,6 +129,11 @@ public static void main(String[] args) { throw new TestRunException("Could not find test class " + testClassName, e); } + TestFramework framework = new TestFramework(); + framework.runTestsOnSameVM(testClass, getHelperClasses(args)); + } + + private static ArrayList> getHelperClasses(String[] args) { ArrayList> helperClasses = new ArrayList<>(); for (int i = 1; i < args.length; i++) { String helperClassName = args[i]; @@ -140,10 +143,13 @@ public static void main(String[] args) { throw new TestRunException("Could not find helper class " + helperClassName, e); } } - TestFramework framework = new TestFramework(); - framework.runTestsOnSameVM(testClass, helperClasses); + return helperClasses; } + + /* + * Public interface methods + */ public static void run() { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); doRun(walker.getCallerClass(), null, null); @@ -153,10 +159,14 @@ public static void run(Class testClass) { doRun(testClass, null, null); } - public static void run(Class testClass, Class... helperClasses) { + public static void runWithHelperClasses(Class testClass, Class... helperClasses) { doRun(testClass, Arrays.asList(helperClasses), null); } + public static void run(Class testClass, List> helperClasses) { + doRun(testClass, helperClasses, null); + } + public static void runWithArguments(String... commandLineArgs) { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); doRun(walker.getCallerClass(), null, Arrays.asList(commandLineArgs)); @@ -171,10 +181,9 @@ private static void doRun(Class testClass, List> helperClasses, List framework.startTestVM(null, testClass, helperClasses, commandLineArgs); } - public void runTestsOnSameVM() { - StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - runTestsOnSameVM(walker.getCallerClass()); - } + /* + * End of public interface + */ private void runTestsOnSameVM(Class testClass, ArrayList> helperClasses) { for (Class helperClass : helperClasses) { @@ -189,6 +198,13 @@ private void runTestsOnSameVM(Class testClass) { runTests(); } + // Only called by tests testing the framework itself. Accessed by reflection. Do not expose this to normal users. + private static void runTestsOnSameVM() { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + TestFramework framework = new TestFramework(); + framework.runTestsOnSameVM(walker.getCallerClass()); + } + private String startTestVM(ArrayList scenarioFlags, Class testClass, List> helperClasses, List commandLineArgs) { ArrayList cmds = new ArrayList<>(Arrays.asList(InputArguments.getVmInputArgs())); @@ -262,7 +278,10 @@ private String startTestVM(ArrayList scenarioFlags, Class testClass, System.out.println(output); } lastVmOutput = output; - oa.shouldHaveExitValue(0); + if (!TESTING_TEST_FRAMEWORK) { + // Tests for the framework itself might expect certain exceptions. + oa.shouldHaveExitValue(0); + } if (VERIFY_IR) { IRMatcher irMatcher = new IRMatcher(output, testClass); @@ -447,7 +466,7 @@ private void applyIndependentCompilationCommands(Method m) { // Exclude some methods from compilation with C2 to stress test the calling convention if (Utils.getRandomInstance().nextBoolean()) { System.out.println("Excluding from C2 compilation: " + m); - WHITE_BOX.makeMethodNotCompilable(m, CompLevel.C2_FULL_OPTIMIZATION.getValue(), false); + WHITE_BOX.makeMethodNotCompilable(m, CompLevel.C2.getValue(), false); } } } @@ -461,7 +480,7 @@ private void dontCompileMethod(Method m) { private void applyForceCompileCommand(Method m) { ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); if (forceCompileAnno != null) { - enqueueMethodForCompilation(m, forceCompileAnno.compLevel()); + enqueueMethodForCompilation(m, forceCompileAnno.value()); } } @@ -469,7 +488,7 @@ private void applyForceCompileCommand(Method m) { public static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { TestFormat.check(getAnnotation(m, Test.class) == null, "Cannot call enqueueMethodForCompilation() for @Test annotated method " + m); - TestFrameworkUtils.enqueueMethodForCompilation(m ,compLevel); + TestFrameworkUtils.enqueueMethodForCompilation(m, compLevel); } private void setupTests(Class clazz) { @@ -648,6 +667,40 @@ public static void check(boolean test, String failureMessage) { throw new TestFrameworkException("Internal TestFramework exception:\n" + failureMessage); } } + + enum TriState { + Maybe, + Yes, + No + } + + public static boolean isC2Compiled(Method m) { + return compiledByC2(m) == TriState.Yes; + } + + public static void assertDeoptimizedByC2(Method m) { + if (compiledByC2(m) == TriState.Yes) { + throw new TestRunException(m + " should have been deoptimized"); + } + } + + public static void assertCompiledByC2(Method m) { + if (compiledByC2(m) == TriState.No) { + throw new TestRunException(m + " should have been compiled"); + } + } + + private static TriState compiledByC2(Method m) { + if (!TestFramework.USE_COMPILER || TestFramework.XCOMP || TestFramework.TEST_C1 || + (TestFramework.STRESS_CC && !WHITE_BOX.isMethodCompilable(m, CompLevel.C2.getValue(), false))) { + return TriState.Maybe; + } + if (WHITE_BOX.isMethodCompiled(m, false) && + WHITE_BOX.getMethodCompilationLevel(m, false) >= CompLevel.C2.getValue()) { + return TriState.Yes; + } + return TriState.No; + } } // Errors in the framework @@ -824,7 +877,7 @@ private Object invokeTestMethod() { } private void compileOSRAndRun() { - final boolean maybeCodeBufferOverflow = (TestFramework.TEST_C1 && TestFramework.VerifyOops); + final boolean maybeCodeBufferOverflow = (TestFramework.TEST_C1 && TestFramework.VERIFY_OOPS); final long started = System.currentTimeMillis(); boolean stateCleared = false; while (true) { @@ -865,7 +918,7 @@ private void retryDisabledVerifyOops(boolean stateCleared) { } private void compileNormallyAndRun() { - final boolean maybeCodeBufferOverflow = (TestFramework.TEST_C1 && TestFramework.VerifyOops); + final boolean maybeCodeBufferOverflow = (TestFramework.TEST_C1 && TestFramework.VERIFY_OOPS); final Method testMethod = test.getTestMethod(); TestFrameworkUtils.enqueueMethodForCompilation(test); if (maybeCodeBufferOverflow && !WHITE_BOX.isMethodCompiled(testMethod, false)) { @@ -989,14 +1042,14 @@ public static int compLevelToInt(CompLevel compLevel) { // Get the appropriate level as permitted by the test scenario and VM options. private static CompLevel restrictCompLevel(CompLevel compLevel) { switch (compLevel) { - case ANY -> compLevel = CompLevel.C2_FULL_OPTIMIZATION; + case ANY -> compLevel = CompLevel.C2; case C1_SIMPLE, C1_LIMITED_PROFILE, C1_FULL_PROFILE -> { if (FLIP_C1_C2) { // Effectively treat all (compLevel = C1_*) as (compLevel = C2) - compLevel = CompLevel.C2_FULL_OPTIMIZATION; + compLevel = CompLevel.C2; } } - case C2_FULL_OPTIMIZATION -> { + case C2 -> { if (FLIP_C1_C2) { // Effectively treat all (compLevel = C2) as (compLevel = C1_SIMPLE) compLevel = CompLevel.C1_SIMPLE; @@ -1004,8 +1057,8 @@ private static CompLevel restrictCompLevel(CompLevel compLevel) { } } - if (!TestFramework.TEST_C1 && compLevel.getValue() < CompLevel.C2_FULL_OPTIMIZATION.getValue()) { - compLevel = CompLevel.C2_FULL_OPTIMIZATION; + if (!TestFramework.TEST_C1 && compLevel.getValue() < CompLevel.C2.getValue()) { + compLevel = CompLevel.C2; } if (TestFramework.TIERED_COMPILATION && compLevel.getValue() > TestFramework.TIERED_COMPILATION_STOP_AT_LEVEL.getValue()) { compLevel = TestFramework.TIERED_COMPILATION_STOP_AT_LEVEL; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java index e38faa047f6..07e3fcb02d1 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java @@ -42,38 +42,15 @@ void setWarmUpFinished() { onWarmUp = false; } - - enum TriState { - Maybe, - Yes, - No - } - - public static boolean isC2Compiled(Method m) { - return compiledByC2(m) == TriState.Yes; - } - - public static void assertDeoptimizedByC2(Method m) { - if (compiledByC2(m) == TriState.Yes) { - throw new TestRunException(m + " should have been deoptimized"); - } + public boolean isC2Compiled() { + return TestFramework.isC2Compiled(testMethod); } - public static void assertCompiledByC2(Method m) { - if (compiledByC2(m) == TriState.No) { - throw new TestRunException(m + " should have been compiled"); - } + public void assertDeoptimizedByC2() { + TestFramework.assertDeoptimizedByC2(testMethod); } - private static TriState compiledByC2(Method m) { - if (!TestFramework.USE_COMPILER || TestFramework.XCOMP || TestFramework.TEST_C1 || - (TestFramework.STRESS_CC && !WHITE_BOX.isMethodCompilable(m, CompLevel.C2_FULL_OPTIMIZATION.getValue(), false))) { - return TriState.Maybe; - } - if (WHITE_BOX.isMethodCompiled(m, false) && - WHITE_BOX.getMethodCompilationLevel(m, false) >= CompLevel.C2_FULL_OPTIMIZATION.getValue()) { - return TriState.Yes; - } - return TriState.No; + public void assertCompiledByC2(Method m) { + TestFramework.assertCompiledByC2(testMethod); } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java index 740715ba13d..75881f19c91 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -2,14 +2,16 @@ import compiler.valhalla.framework.*; +import java.lang.reflect.Method; import java.util.Arrays; import java.util.stream.Stream; public class TestBasics { - public static void main(String[] args) { - TestFramework framework = new TestFramework(); + public static void main(String[] args) throws Exception { // Run on same VM to make this test easier as we are not interested in any output processing. - framework.runTestsOnSameVM(); + Method runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM"); + runTestsOnSameVM.setAccessible(true); + runTestsOnSameVM.invoke(null); if (wasExecuted) { throw new RuntimeException("Executed non @Test method or a method that was not intended to be run"); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java new file mode 100644 index 00000000000..187acfa2a80 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java @@ -0,0 +1,38 @@ +package compiler.valhalla.framework.tests; + +import compiler.valhalla.framework.*; +import jdk.test.lib.Asserts; + +public class TestWithHelperClasses { + + public static void main(String[] args) throws NoSuchMethodException { + TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class, Helper2.class); + try { + TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class); + } catch (TestRunException e) { + Asserts.assertTrue(e.getMessage().contains("public static void compiler.valhalla.framework.tests.Helper2.foo() should have been compiled")); + } + } + + @Test + public void test() throws NoSuchMethodException { + TestFramework.assertCompiledByC2(Helper1.class.getMethod("foo")); + TestFramework.assertCompiledByC2(Helper2.class.getMethod("foo")); + } +} + +class Helper1 { + + @ForceCompile(CompLevel.C2) + public static void foo() { + throw new RuntimeException("Should not be executed"); + } +} + +class Helper2 { + + @ForceCompile(CompLevel.C2) + public static void foo() { + throw new RuntimeException("Should not be executed"); + } +} From 12b6629d00a58afd8b0eeef231ad74ece4d06bf1 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 18 Jan 2021 17:52:12 +0100 Subject: [PATCH 006/131] Fixing how scenarios are defined, run, checked and error reported --- .../valhalla/framework/IRMatcher.java | 3 +- .../compiler/valhalla/framework/Scenario.java | 81 +++-- .../valhalla/framework/TestFramework.java | 289 +++++++----------- .../framework/TestFrameworkValhalla.java | 58 +--- .../framework/tests/TestIRMatching.java | 71 +++-- .../framework/tests/TestScenarios.java | 63 ++-- 6 files changed, 223 insertions(+), 342 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java index 8a5180ed142..2b76ebe5251 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java @@ -96,7 +96,7 @@ public void applyRules() { } } if (!fails.isEmpty()) { - StringBuilder builder = new StringBuilder("\n\n"); + StringBuilder builder = new StringBuilder("\n"); builder.append("One or more @IR rules failed:\n"); builder.append("-----------------------------\n"); fails.forEach((method, list) -> { @@ -127,7 +127,6 @@ private void applyFailOn(Method m, String testOutput, IR irAnno, int annoId) { Pattern pattern = Pattern.compile(failOnRegex); Matcher matcher = pattern.matcher(testOutput); boolean found = matcher.find(); - System.out.println(failOnRegex); if (found) { addFail(m, irAnno, annoId, matcher, "contains forbidden node"); } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java index c60144e3cb9..9de6a79edea 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java @@ -1,54 +1,49 @@ package compiler.valhalla.framework; -import java.util.ArrayList; +import java.util.*; public class Scenario { - private final ArrayList flags; - private boolean enabled; - private String disableReason; - private String output; - - public Scenario(ArrayList flags) { - this.flags = flags; - this.disableReason = ""; - } - - public boolean isIgnored() { - return enabled; - } - - public void addFlag(String flag) { - flags.add(flag.trim()); - } - - public void disable() { - enabled = false; - disableReason = "Disabled by Test."; - } - - public void disable(String reason) { - enabled = false; - disableReason = reason; - } - - public void enable() { - enabled = true; - disableReason = "Disabled by Test."; - } - - public String getIgnoreReason() { - return disableReason; - } - - public ArrayList getFlags() { + // "jtreg -DXcomp=true" runs all the scenarios with -Xcomp. This is faster than "jtreg -javaoptions:-Xcomp". + static final String ADDITIONAL_SCENARIO_FLAGS = System.getProperty("ScenarioFlags", ""); + private static final String SCENARIOS = System.getProperty("Scenarios", ""); + private static final List additionalScenarioFlags = new ArrayList<>(); + private static final Set enabledScenarios = new HashSet<>(); + + private final List flags; + private final int index; + boolean enabled; + + static { + if (!SCENARIOS.isEmpty()) { + Arrays.stream(SCENARIOS.split("\\s*,\\s*")).map(Integer::getInteger).forEachOrdered(enabledScenarios::add); + } + + if (!ADDITIONAL_SCENARIO_FLAGS.isEmpty()) { + additionalScenarioFlags.addAll(Arrays.asList(ADDITIONAL_SCENARIO_FLAGS.split("\\s*,\\s*"))); + } + } + + public Scenario(int index, String... flags) { + this.index = index; + if (enabledScenarios.isEmpty() || enabledScenarios.contains(index)) { + this.flags = new ArrayList<>(Arrays.asList(flags)); + this.flags.addAll(additionalScenarioFlags); + this.enabled = true; + } else { + this.flags = new ArrayList<>(); + this.enabled = false; + } + } + + public List getFlags() { return flags; } - public void setOutput(String output) { - this.output = output; + public int getIndex() { + return index; } - public String getOutput() { - return output; + public boolean isEnabled() { + return enabled; } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 58f37286778..d601aa15661 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -51,7 +51,6 @@ public class TestFramework { private static boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")) && !XCOMP && !TEST_C1 && COMPILE_COMMANDS && Platform.isDebugBuild() && !Platform.isInt(); private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false")) && Platform.isDebugBuild(); - private static final String SCENARIOS = System.getProperty("Scenarios", ""); private static final String TESTLIST = System.getProperty("Testlist", ""); private static final String EXCLUDELIST = System.getProperty("Exclude", ""); public static final int WARMUP_ITERATIONS = Integer.parseInt(System.getProperty("Warmup", "251")); @@ -59,12 +58,11 @@ public class TestFramework { private static final boolean GC_AFTER = Boolean.parseBoolean(System.getProperty("GCAfter", "false")); static final boolean STRESS_CC = Boolean.parseBoolean(System.getProperty("StressCC", "false")); private static final boolean SHUFFLE_TESTS = Boolean.parseBoolean(System.getProperty("ShuffleTests", "true")); - private static final boolean PREFER_CL_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); + private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); private static final boolean USE_COMPILE_COMMAND_ANNOTATIONS = Boolean.parseBoolean(System.getProperty("UseCompileCommandAnnotations", "true")); private static final boolean PRINT_VALID_IR_RULES = Boolean.parseBoolean(System.getProperty("PrintValidIRRules", "false")); + private static final boolean ENABLE_DEFAULT_SCENARIO = Boolean.parseBoolean(System.getProperty("EnableDefaultScenario", "true")); - // "jtreg -DXcomp=true" runs all the scenarios with -Xcomp. This is faster than "jtreg -javaoptions:-Xcomp". - static final boolean RUN_WITH_XCOMP = Boolean.parseBoolean(System.getProperty("Xcomp", "false")); static final boolean TESTING_TEST_FRAMEWORK = Boolean.parseBoolean(System.getProperty("TestingTestFramework", "false")); @@ -83,17 +81,15 @@ public class TestFramework { // Index into this array is the scenario ID. protected final List scenarios = new ArrayList<>(); - private final IREncodingPrinter irMatchRulePrinter; - // Used to run scenarios TestFramework() { // These flags can be overridden fixedDefaultFlags = setupDefaultFlags(); compileCommandFlags = setupCompileCommandFlags(); printFlags = setupPrintFlags(); verifyFlags = setupVerifyFlags(); - setupDefaultScenarios(); + if (PRINT_VALID_IR_RULES) { irMatchRulePrinter = new IREncodingPrinter(); } else { @@ -152,39 +148,77 @@ private static ArrayList> getHelperClasses(String[] args) { */ public static void run() { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - doRun(walker.getCallerClass(), null, null); + doRun(walker.getCallerClass(), null); } public static void run(Class testClass) { - doRun(testClass, null, null); + doRun(testClass, null); } public static void runWithHelperClasses(Class testClass, Class... helperClasses) { - doRun(testClass, Arrays.asList(helperClasses), null); - } - - public static void run(Class testClass, List> helperClasses) { - doRun(testClass, helperClasses, null); + doRun(testClass, Arrays.asList(helperClasses)); } - public static void runWithArguments(String... commandLineArgs) { + public static void runWithScenarios(Scenario... scenarios) { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - doRun(walker.getCallerClass(), null, Arrays.asList(commandLineArgs)); + runWithScenarios(walker.getCallerClass(), scenarios); } - public static void runWithArguments(Class testClass, String... commandLineArgs) { - doRun(testClass, null, Arrays.asList(commandLineArgs)); + public static void runWithScenarios(Class testClass, Scenario... scenarios) { + runWithScenarios(testClass, null, scenarios); } - private static void doRun(Class testClass, List> helperClasses, List commandLineArgs) { + public static void runWithScenarios(Class testClass, List> helperClasses, Scenario... scenarios) { TestFramework framework = new TestFramework(); - framework.startTestVM(null, testClass, helperClasses, commandLineArgs); + Map exceptionMap = new HashMap<>(); + // First run without additional scenario flags. + if (ENABLE_DEFAULT_SCENARIO) { + try { + framework.runTestVM(testClass, helperClasses, null); + } catch (Exception e) { + exceptionMap.put("Default Scenario", e); + } + } + + Set scenarioIndecies = new HashSet<>(); + for (Scenario scenario : scenarios) { + int scenarioIndex = scenario.getIndex(); + TestFormat.check(!scenarioIndecies.contains(scenarioIndex), + "Cannot define two scenarios with the same index " + scenarioIndex); + scenarioIndecies.add(scenarioIndex); + try { + framework.runTestVM(testClass, helperClasses, scenario); + } catch (Exception e) { + exceptionMap.put(String.valueOf(scenarioIndex), e); + } + } + if (!exceptionMap.isEmpty()) { + StringBuilder builder = new StringBuilder("The following scenarios have failed: #"); + builder.append(String.join(", #", exceptionMap.keySet())).append("\n\n"); + for (Map.Entry entry: exceptionMap.entrySet()) { + String title = "Stacktrace for Scenario #" + entry.getKey(); + builder.append(title).append("\n").append("=".repeat(title.length())).append("\n"); + builder.append(entry.getValue().getMessage()).append("\n"); + } + throw new TestRunException(builder.toString()); + } + } + + public static void run(Class testClass, List> helperClasses) { + doRun(testClass, helperClasses); } /* * End of public interface */ + + private static void doRun(Class testClass, List> helperClasses) { + TestFramework framework = new TestFramework(); + framework.runTestVM(testClass, helperClasses, null); + } + + private void runTestsOnSameVM(Class testClass, ArrayList> helperClasses) { for (Class helperClass : helperClasses) { // Process the helper classes and apply the explicit compile commands @@ -205,69 +239,17 @@ private static void runTestsOnSameVM() { framework.runTestsOnSameVM(walker.getCallerClass()); } - private String startTestVM(ArrayList scenarioFlags, Class testClass, List> helperClasses, - List commandLineArgs) { - ArrayList cmds = new ArrayList<>(Arrays.asList(InputArguments.getVmInputArgs())); - if (RUN_WITH_XCOMP) { - cmds.add( "-Xcomp"); - } - - if (VERIFY_IR && cmds.stream().anyMatch(flag -> flag.startsWith("-XX:CompileThreshold"))) { - // Disable IR verification if non-default CompileThreshold is set - if (VERBOSE) { - System.out.println("Disabled IR verification due to CompileThreshold flag"); - } - VERIFY_IR = false; - } - - if (VERIFY_IR) { - // Add print flags for IR verification - cmds.addAll(Arrays.asList(printFlags)); - addBoolOptionForClass(cmds, testClass, "PrintIdeal"); - addBoolOptionForClass(cmds, testClass, "PrintOptoAssembly"); - // Always trap for exception throwing to not confuse IR verification - cmds.add("-XX:-OmitStackTraceInFastThrow"); - cmds.add("-DPrintValidIRRules=true"); - } else { - cmds.add("-DPrintValidIRRules=false"); - } - - if (VERIFY_VM) { - cmds.addAll(Arrays.asList(verifyFlags)); - } - - cmds.addAll(Arrays.asList(fixedDefaultFlags)); - if (COMPILE_COMMANDS) { - cmds.addAll(Arrays.asList(compileCommandFlags)); - } - - if (scenarioFlags != null) { - cmds.addAll(scenarioFlags); - } - - if (commandLineArgs != null) { - // Ensured to be always set. Useful for testing the framework itself, for example @IR behavior. - cmds.addAll(commandLineArgs); - } - - // TODO: Only for debugging - if (cmds.get(0).startsWith("-agentlib")) { - cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=n,server=y"); - } - cmds.add(getClass().getCanonicalName()); - cmds.add(testClass.getCanonicalName()); - if (helperClasses != null) { - helperClasses.forEach(c -> cmds.add(c.getCanonicalName())); - } - - if (VERBOSE) { - System.out.print("Command Line: "); - cmds.forEach(flag -> System.out.print(flag + " ")); + private void runTestVM(Class testClass, List> helperClasses, Scenario scenario) { + if (scenario != null && !scenario.isEnabled()) { + System.out.println("Disabled scenario #" + scenario.getIndex() + "! This scenario is not present in set flag -DScenarios and" + + "is therefore not executed."); + return; } + ArrayList cmds = prepareTestVmFlags(testClass, helperClasses, scenario); OutputAnalyzer oa; try { - // Calls this 'main' of this class to run all specified tests with the flags specified by the scenario. + // Calls 'main' of this class to run all specified tests with commands 'cmds'. oa = ProcessTools.executeTestJvm(cmds); } catch (Exception e) { throw new TestRunException("Error while executing Test VM", e); @@ -287,118 +269,81 @@ private String startTestVM(ArrayList scenarioFlags, Class testClass, IRMatcher irMatcher = new IRMatcher(output, testClass); irMatcher.applyRules(); } - return output; } - public static String getLastVmOutput() { - return lastVmOutput; - } - private void addBoolOptionForClass(ArrayList cmds, Class testClass, String option) { - cmds.add("-XX:CompileCommand=option," + testClass.getCanonicalName() + "::*,bool," + option + ",true"); - } - -// public static void runDefaultScenarios() { -// StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); -// Class testClass = walker.getCallerClass(); -// TestFramework frameWork = new TestFramework(); -// frameWork.setupDefaultScenarios(); -// frameWork.runScenarios(testClass); -// } - - public void runScenarios() { - StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - runScenarios(walker.getCallerClass()); - } - - private void runScenarios(Class testClass, Class... helperClasses) { - if (!SCENARIOS.isEmpty()) { - setupFlagDefinedScenarios(); + private ArrayList prepareTestVmFlags(Class testClass, List> helperClasses, Scenario scenario) { + String[] vmInputArguments = InputArguments.getVmInputArgs(); + ArrayList cmds = new ArrayList<>(); + if (!PREFER_COMMAND_LINE_FLAGS) { + cmds.addAll(Arrays.asList(vmInputArguments)); } - for (int i = 0; i < scenarios.size(); i++) { - Scenario scenario = scenarios.get(i); - if (scenario.isIgnored()) { - System.out.println("Scenario #" + i + " is ignored. Reason:" + scenario.getIgnoreReason()); - } - System.out.println("Run Scenario #" + i + " -------- "); - ArrayList scenarioFlags = new ArrayList<>(scenario.getFlags()); - scenario.setOutput(startTestVM(scenarioFlags, testClass, Arrays.asList(helperClasses), null)); + if (scenario != null) { + System.out.println("Running Scenario #" + scenario.getIndex()); + cmds.addAll(scenario.getFlags()); } - } - - private void setupFlagDefinedScenarios() { - List flagDefinedScenarios = Arrays.stream(SCENARIOS.split("\\s*,\\s*")).map(Integer::getInteger).sorted().collect(Collectors.toList()); - scenarios.forEach(s -> s.disable("Disabled by -Dscenarios")); - int lastIndex = flagDefinedScenarios.get(flagDefinedScenarios.size() - 1); - for (int scenarioId : flagDefinedScenarios) { - if (scenarioId >= scenarios.size()) { - System.out.println("Scenario #" + scenarioId + " does not exist."); - continue; - } - Scenario scenario = scenarios.get(scenarioId); - if (scenario.isIgnored()) { - continue; - } + setupIrVerificationFlags(testClass, cmds); - scenario.enable(); + if (VERIFY_VM) { + cmds.addAll(Arrays.asList(verifyFlags)); } - // All remaining flag defined scenarios are invalid - } - - public void addScenario(Scenario scenario) { - scenarios.add(scenario); - } + cmds.addAll(Arrays.asList(fixedDefaultFlags)); + if (COMPILE_COMMANDS) { + cmds.addAll(Arrays.asList(compileCommandFlags)); + } - public void disableDefaultScenario(int scenarioId) { - checkScenarioId(scenarioId); - scenarios.get(scenarioId).disable(); - } + // TODO: Only for debugging + if (cmds.get(0).startsWith("-agentlib")) { + cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=n,server=y"); + } - public void disableDefaultScenario(int scenarioId, String reason) { - checkScenarioId(scenarioId); - scenarios.get(scenarioId).disable(reason); - } + if (PREFER_COMMAND_LINE_FLAGS) { + // Prefer flags set via the command line over the ones set by scenarios. + cmds.addAll(Arrays.asList(vmInputArguments)); + } - public void replaceDefaultScenario(Scenario newScenario, int scenarioId) { - checkScenarioId(scenarioId); - scenarios.set(scenarioId, newScenario); - } + cmds.add(getClass().getCanonicalName()); + cmds.add(testClass.getCanonicalName()); + if (helperClasses != null) { + helperClasses.forEach(c -> cmds.add(c.getCanonicalName())); + } - public void replaceDefaultScenarios(Scenario[] newScenarios) { - scenarios.clear(); - scenarios.addAll(Arrays.asList(newScenarios)); + if (VERBOSE) { + System.out.print("Command Line: "); + cmds.forEach(flag -> System.out.print(flag + " ")); + } + return cmds; } - public void addFlagsToDefaultScenario(int scenarioId, String... flags) { - checkScenarioId(scenarioId); - Arrays.stream(flags).forEach(f -> scenarios.get(scenarioId).addFlag(f)); - } + private void setupIrVerificationFlags(Class testClass, ArrayList cmds) { + if (VERIFY_IR && cmds.stream().anyMatch(flag -> flag.startsWith("-XX:CompileThreshold"))) { + // Disable IR verification if non-default CompileThreshold is set + if (VERBOSE) { + System.out.println("Disabled IR verification due to CompileThreshold flag"); + } + VERIFY_IR = false; + } - public String getScenarioOutput(int scenarioId) { - checkScenarioId(scenarioId); - return scenarios.get(scenarioId).getOutput(); + if (VERIFY_IR) { + // Add print flags for IR verification + cmds.addAll(Arrays.asList(printFlags)); + addBoolOptionForClass(cmds, testClass, "PrintIdeal"); + addBoolOptionForClass(cmds, testClass, "PrintOptoAssembly"); + // Always trap for exception throwing to not confuse IR verification + cmds.add("-XX:-OmitStackTraceInFastThrow"); + cmds.add("-DPrintValidIRRules=true"); + } else { + cmds.add("-DPrintValidIRRules=false"); + } } - private void checkScenarioId(int scenarioId) { - TestFormat.check(scenarioId >= 0 && scenarioId < scenarios.size(), - "Invalid default scenario id " + scenarioId + ". Must be in [0, " + (scenarios.size() - 1) + "]."); + private void addBoolOptionForClass(ArrayList cmds, Class testClass, String option) { + cmds.add("-XX:CompileCommand=option," + testClass.getCanonicalName() + "::*,bool," + option + ",true"); } - // Can be overridden, for example by Valhalla - protected void setupDefaultScenarios() { - scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( - "-XX:+IgnoreUnrecognizedVMOptions")))); - scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( - "-XX:CompileCommand=quiet")))); - scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( - "-Xmx256m")))); - scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( - "-DVerifyIR=false")))); - scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( - "-XX:+StressGCM")))); - scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( - "-XX:+StressLCM")))); + public static String getLastVmOutput() { + return lastVmOutput; } private void parseTestClass(Class clazz) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFrameworkValhalla.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFrameworkValhalla.java index 4d9ce555e7b..767ec829bc6 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFrameworkValhalla.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFrameworkValhalla.java @@ -17,60 +17,4 @@ public class TestFrameworkValhalla extends TestFramework { - @Override - protected void setupDefaultScenarios() { - scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( - "-XX:-UseACmpProfile", - "-XX:+AlwaysIncrementalInline", - "-XX:FlatArrayElementMaxOops=5", - "-XX:FlatArrayElementMaxSize=-1", - "-XX:-UseArrayLoadStoreProfile", - "-XX:InlineFieldMaxFlatSize=-1", - "-XX:+InlineTypePassFieldsAsArgs", - "-XX:+InlineTypeReturnedAsFields")))); - scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( - "-XX:-UseACmpProfile", - "-XX:-UseCompressedOops", - "-XX:FlatArrayElementMaxOops=5", - "-XX:FlatArrayElementMaxSize=-1", - "-XX:-UseArrayLoadStoreProfile", - "-XX:InlineFieldMaxFlatSize=-1", - "-XX:-InlineTypePassFieldsAsArgs", - "-XX:-InlineTypeReturnedAsFields")))); - scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( - "-XX:-UseACmpProfile", - "-XX:-UseCompressedOops", - "-XX:FlatArrayElementMaxOops=0", - "-XX:FlatArrayElementMaxSize=0", - "-XX:-UseArrayLoadStoreProfile", - "-XX:InlineFieldMaxFlatSize=-1", - "-XX:+InlineTypePassFieldsAsArgs", - "-XX:+InlineTypeReturnedAsFields", - "-XX:+StressInlineTypeReturnedAsFields")))); - scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( - "-DVerifyIR=false", - "-XX:+AlwaysIncrementalInline", - "-XX:FlatArrayElementMaxOops=0", - "-XX:FlatArrayElementMaxSize=0", - "-XX:InlineFieldMaxFlatSize=0", - "-XX:+InlineTypePassFieldsAsArgs", - "-XX:+InlineTypeReturnedAsFields")))); - scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( - "-DVerifyIR=false", - "-XX:FlatArrayElementMaxOops=-1", - "-XX:FlatArrayElementMaxSize=-1", - "-XX:InlineFieldMaxFlatSize=0", - "-XX:+InlineTypePassFieldsAsArgs", - "-XX:-InlineTypeReturnedAsFields", - "-XX:-ReduceInitialCardMarks")))); - scenarios.add(new Scenario(new ArrayList<>(Arrays.asList( - "-XX:-UseACmpProfile", - "-XX:+AlwaysIncrementalInline", - "-XX:FlatArrayElementMaxOops=5", - "-XX:FlatArrayElementMaxSize=-1", - "-XX:-UseArrayLoadStoreProfile", - "-XX:InlineFieldMaxFlatSize=-1", - "-XX:-InlineTypePassFieldsAsArgs", - "-XX:-InlineTypeReturnedAsFields")))); - } -} \ No newline at end of file +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java index e1b45ccd7b8..2497d9db077 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java @@ -14,37 +14,37 @@ public class TestIRMatching { public static void main(String[] args) { // Run with -DPrintValidIRRules=true to simulate TestVM -// runFailOnTests(Constraint.failOnNodes(AndOr1.class, "test1(int)", 1, true,"CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:+UsePerfData", "-XX:+UseTLAB"); -// runFailOnTests(Constraint.failOnNodes(AndOr1.class, "test2()", 1, true,"CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:-UsePerfData", "-XX:+UseTLAB"); -// -// TestFramework.runWithArguments(AndOr1.class, "-XX:SuspendRetryCount=52", "-XX:+UsePerfData", "-XX:+UseTLAB"); -// -// TestFramework.runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=50"); -// findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 0, 21); -// findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", -1, -1); -// -// TestFramework.runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=49"); -// findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 4, 6, 13, 18); -// findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); -// -// TestFramework.runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=51"); -// findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 7, 12, 19, 21); -// findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 4, 7, 11, 16, 20, 22); -// -// TestFramework.runWithArguments(MultipleFailOnGood.class, "-XX:SuspendRetryCount=50"); -// -// runFailOnTests(Constraint.failOnNodes(MultipleFailOnBad.class, "fail1()", 1,true, "Store"), -// Constraint.failOnNodes(MultipleFailOnBad.class, "fail2()", 1,true, "CallStaticJava"), -// Constraint.failOnNodes(MultipleFailOnBad.class, "fail3()", 1,true, "Store"), -// Constraint.failOnNodes(MultipleFailOnBad.class, "fail4()", 1,true, "Store"), -// Constraint.failOnMatches(MultipleFailOnBad.class, "fail5()", 1,true, "Store", "iFld"), -// Constraint.failOnAlloc(MultipleFailOnBad.class, "fail6()", 1,true, "MyClass"), -// Constraint.failOnAlloc(MultipleFailOnBad.class, "fail7()", 1,true, "MyClass"), -// Constraint.failOnAlloc(MultipleFailOnBad.class, "fail8()", 1,true, "MyClass"), -// Constraint.failOnNodes(MultipleFailOnBad.class, "fail9()", 1,true, "Store", "CallStaticJava"), -// Constraint.failOnMatches(MultipleFailOnBad.class, "fail10()", 1,true, "Store", "iFld")); -// -// TestFramework.runWithArguments(GoodCount.class, "-XX:SuspendRetryCount=50"); + runFailOnTests(Constraint.failOnNodes(AndOr1.class, "test1(int)", 1, true,"CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:+UsePerfData", "-XX:+UseTLAB"); + runFailOnTests(Constraint.failOnNodes(AndOr1.class, "test2()", 1, true,"CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:-UsePerfData", "-XX:+UseTLAB"); + + runWithArguments(AndOr1.class, "-XX:SuspendRetryCount=52", "-XX:+UsePerfData", "-XX:+UseTLAB"); + + runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=50"); + findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 0, 21); + findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", -1, -1); + + runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=49"); + findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 4, 6, 13, 18); + findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); + + runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=51"); + findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 7, 12, 19, 21); + findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 4, 7, 11, 16, 20, 22); + + runWithArguments(MultipleFailOnGood.class, "-XX:SuspendRetryCount=50"); + + runFailOnTests(Constraint.failOnNodes(MultipleFailOnBad.class, "fail1()", 1,true, "Store"), + Constraint.failOnNodes(MultipleFailOnBad.class, "fail2()", 1,true, "CallStaticJava"), + Constraint.failOnNodes(MultipleFailOnBad.class, "fail3()", 1,true, "Store"), + Constraint.failOnNodes(MultipleFailOnBad.class, "fail4()", 1,true, "Store"), + Constraint.failOnMatches(MultipleFailOnBad.class, "fail5()", 1,true, "Store", "iFld"), + Constraint.failOnAlloc(MultipleFailOnBad.class, "fail6()", 1,true, "MyClass"), + Constraint.failOnAlloc(MultipleFailOnBad.class, "fail7()", 1,true, "MyClass"), + Constraint.failOnAlloc(MultipleFailOnBad.class, "fail8()", 1,true, "MyClass"), + Constraint.failOnNodes(MultipleFailOnBad.class, "fail9()", 1,true, "Store", "CallStaticJava"), + Constraint.failOnMatches(MultipleFailOnBad.class, "fail10()", 1,true, "Store", "iFld")); + + runWithArguments(GoodCount.class, "-XX:SuspendRetryCount=50"); runFailOnTests(Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 1,true, "MyClass"), Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 2,true, "MyClass"), @@ -66,6 +66,10 @@ public static void main(String[] args) { } + private static void runWithArguments(Class clazz, String... args) { + TestFramework.runWithScenarios(clazz, new Scenario(0, args)); + } + private static void runFailOnTests(Constraint... constraints) { try { TestFramework.run(constraints[0].getKlass()); // All constraints have the same class. @@ -83,11 +87,12 @@ private static void runFailOnTests(Constraint... constraints) { // Single constraint private static void runFailOnTests(Constraint constraint, String... args) { try { - TestFramework.runWithArguments(constraint.getKlass(), args); // All constraints have the same class. + Scenario scenario = new Scenario(0, args); + TestFramework.runWithScenarios(constraint.getKlass(), scenario); // All constraints have the same class. shouldNotReach(); } catch (ShouldNotReachException e) { throw e; - } catch (RuntimeException e) { + } catch (TestRunException e) { System.out.println(e.getMessage()); constraint.checkConstraint(e); } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java index cd5232423e6..0d150bfd699 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java @@ -1,52 +1,45 @@ package compiler.valhalla.framework.tests; -import compiler.valhalla.framework.ArgumentValue; -import compiler.valhalla.framework.Arguments; -import compiler.valhalla.framework.Test; -import compiler.valhalla.framework.TestFramework; +import compiler.valhalla.framework.*; +import jdk.test.lib.Asserts; +// Run test with SuspendRetryCount=50 public class TestScenarios { public static final String[] TEST_KEYS = { "test-key0", "test-key1" }; public static void main(String[] args) { - TestFramework framework = new TestFramework(); - framework.runScenarios(); - final int expectedInvocationsPerTest = TestFramework.WARMUP_ITERATIONS + 1; - for (int i = 0; i < TestFramework.DEFAULT_SCENARIOS; i++) { - String output = framework.getScenarioOutput(i); - for (int j = 0; j < TEST_KEYS.length; j++) { - int invocationCount = getMatches(output, TEST_KEYS[j]); - if (invocationCount != expectedInvocationsPerTest) { - // Warmups + 1 C2 compiled invocation * number of default scenarios - throw new RuntimeException("Test " + j + " was executed " + invocationCount + " times stead of " - + expectedInvocationsPerTest + 1 + " times." ); - } - } + Scenario s1 = new Scenario(1, "-XX:SuspendRetryCount=51"); + Scenario s2 = new Scenario(2, "-XX:SuspendRetryCount=52"); + Scenario s3 = new Scenario(3, "-XX:SuspendRetryCount=53"); + Scenario s3dup = new Scenario(3, "-XX:SuspendRetryCount=53"); + try { + TestFramework.runWithScenarios(s1, s2, s3); + } catch (TestRunException e) { + Asserts.assertTrue(e.getMessage().contains("The following scenarios have failed: #1, #3, #Default Scenario")); + } + TestFramework.runWithScenarios(ScenarioTest.class, s1, s2, s3); + try { + TestFramework.runWithScenarios(s1, s3dup, s2, s3); + } catch (RuntimeException e) { + Asserts.assertTrue(e.getMessage().contains("Cannot define two scenarios with the same index 3")); } } - // How many times do wie find 'toMatch' in 'target'? - private static int getMatches(String target, String toMatch) { - int fromIndex = 0; - int count = 0; - while (true) { - fromIndex = target.indexOf(toMatch, fromIndex); - if (fromIndex == -1) { - break; - } - count++; - fromIndex += toMatch.length(); - } - return count; + @Test + @IR(applyIf={"SuspendRetryCount", "50"}, failOn={IRNode.RETURN}) + public void failDefault() { } + @Test - public void test() { - System.out.println(TEST_KEYS[0]); + @IR(applyIf={"SuspendRetryCount", "51"}, failOn={IRNode.RETURN}) + @IR(applyIf={"SuspendRetryCount", "53"}, failOn={IRNode.RETURN}) + public void failS3() { } +} +class ScenarioTest { @Test - @Arguments(ArgumentValue.DEFAULT) - public void test2(int i) { - System.out.println(TEST_KEYS[1]); + @IR(applyIf={"SuspendRetryCount", "54"}, failOn={IRNode.RETURN}) + public void doesNotFail() { } } From 906027722749017d541b00132c24704da21736f4 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 19 Jan 2021 12:27:49 +0100 Subject: [PATCH 007/131] Add @Run mode --- .../src/compiler/valhalla/framework/Run.java | 1 + .../compiler/valhalla/framework/RunMode.java | 6 ++ .../valhalla/framework/TestFormat.java | 10 --- .../framework/TestFormatException.java | 11 +++ .../valhalla/framework/TestFramework.java | 68 +++++++++++-------- .../compiler/valhalla/framework/TestRun.java | 16 +++++ .../valhalla/framework/tests/TestBasics.java | 31 +++++++-- 7 files changed, 101 insertions(+), 42 deletions(-) create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java index 286d6fbe372..6bd472154e7 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java @@ -6,4 +6,5 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Run { String test() default ""; + RunMode mode() default RunMode.NORMAL; } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java new file mode 100644 index 00000000000..22b3068e7f9 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java @@ -0,0 +1,6 @@ +package compiler.valhalla.framework; + +public enum RunMode { + ONCE, + NORMAL +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java index d684ae321de..48b5c2d8042 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java @@ -14,13 +14,3 @@ public static void fail(String failureMessage, Exception e) { throw new TestFormatException(failureMessage, e); } } - -class TestFormatException extends RuntimeException { - public TestFormatException(String message) { - super(message); - } - - public TestFormatException(String message, Exception e) { - super(message, e); - } -} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java new file mode 100644 index 00000000000..a0ece7d124f --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java @@ -0,0 +1,11 @@ +package compiler.valhalla.framework; + +public class TestFormatException extends RuntimeException { + public TestFormatException(String message) { + super(message); + } + + public TestFormatException(String message, Exception e) { + super(message, e); + } +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index d601aa15661..897c9713f54 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -62,7 +62,8 @@ public class TestFramework { private static final boolean USE_COMPILE_COMMAND_ANNOTATIONS = Boolean.parseBoolean(System.getProperty("UseCompileCommandAnnotations", "true")); private static final boolean PRINT_VALID_IR_RULES = Boolean.parseBoolean(System.getProperty("PrintValidIRRules", "false")); private static final boolean ENABLE_DEFAULT_SCENARIO = Boolean.parseBoolean(System.getProperty("EnableDefaultScenario", "true")); - + protected static final long PerMethodTrapLimit = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); + protected static final boolean ProfileInterpreter = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); static final boolean TESTING_TEST_FRAMEWORK = Boolean.parseBoolean(System.getProperty("TestingTestFramework", "false")); @@ -200,7 +201,7 @@ public static void runWithScenarios(Class testClass, List> helperCla builder.append(title).append("\n").append("=".repeat(title.length())).append("\n"); builder.append(entry.getValue().getMessage()).append("\n"); } - throw new TestRunException(builder.toString()); + TestRun.fail(builder.toString()); } } @@ -624,15 +625,11 @@ public static boolean isC2Compiled(Method m) { } public static void assertDeoptimizedByC2(Method m) { - if (compiledByC2(m) == TriState.Yes) { - throw new TestRunException(m + " should have been deoptimized"); - } + TestRun.check(compiledByC2(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized"); } public static void assertCompiledByC2(Method m) { - if (compiledByC2(m) == TriState.No) { - throw new TestRunException(m + " should have been compiled"); - } + TestRun.check(compiledByC2(m) != TriState.No, m + " should have been compiled"); } private static TriState compiledByC2(Method m) { @@ -691,7 +688,7 @@ public DeclaredTest(Method testMethod, Test testAnnotation, Argument[] arguments // Make sure we can also call non-public or public methods in package private classes testMethod.setAccessible(true); this.testMethod = testMethod; - this.requestedCompLevel = testAnnotation.compLevel(); + this.requestedCompLevel = TestFrameworkUtils.restrictCompLevel(testAnnotation.compLevel()); this.arguments = arguments; this.warmupIterations = warmupIterations; this.osrOnly = osrOnly; @@ -743,11 +740,6 @@ public Object invoke(Object obj, Object... args) { throw new TestRunException("There was an error while invoking @Test method " + testMethod, e); } } - - public void checkCompilationLevel() { - int level = WhiteBox.getWhiteBox().getMethodCompilationLevel(testMethod); - Asserts.assertEQ(level, TestFrameworkUtils.compLevelToInt(requestedCompLevel), "Unexpected compilation level for " + testMethod); - } } class BaseTest { @@ -785,11 +777,6 @@ public String getTestName() { * Run the associated test */ public void run() { -// ByteArrayOutputStream systemOutStream = new ByteArrayOutputStream(); -// PrintStream ps = new PrintStream(systemOutStream); -// PrintStream old = System.out; -// System.setOut(ps); - test.printFixedRandomArguments(); for (int i = 0; i < test.getWarmupIterations(); i++) { runMethod(); @@ -801,12 +788,10 @@ public void run() { } else { compileNormallyAndRun(); } -// System.setOut(old); -// System.out.print(systemOutStream.toString()); } protected void runMethod() { - verify(testInfo, invokeTestMethod()); + verify(invokeTestMethod()); } private Object invokeTestMethod() { @@ -882,15 +867,21 @@ private void compileNormallyAndRun() { } } Asserts.assertTrue(WHITE_BOX.isMethodCompiled(testMethod, false), testMethod + " not compiled after waiting 1s"); - test.checkCompilationLevel(); + checkCompilationLevel(); } runMethod(); } + protected void checkCompilationLevel() { + CompLevel level = CompLevel.forValue(WhiteBox.getWhiteBox().getMethodCompilationLevel(testMethod)); + TestRun.check(level == test.getRequestedCompLevel(), + "Compilation level should be " + test.getRequestedCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod); + } + /** * Verify the result */ - public void verify(TestInfo testInfo, Object result) { /* no verification in BaseTests */ } + public void verify(Object result) { /* no verification in BaseTests */ } } class CheckedTest extends BaseTest { @@ -912,7 +903,7 @@ public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecificati } @Override - public void verify(TestInfo testInfo, Object result) { + public void verify(Object result) { boolean shouldVerify = false; switch (checkAt) { case EACH_INVOCATION -> shouldVerify = true; @@ -935,14 +926,22 @@ public void verify(TestInfo testInfo, Object result) { class CustomRunTest extends BaseTest { private final Method runMethod; - private final Run runSpecification; + private final RunMode mode; public CustomRunTest(DeclaredTest test, Method runMethod, Run runSpecification) { super(test); // Make sure we can also call non-public or public methods in package private classes runMethod.setAccessible(true); this.runMethod = runMethod; - this.runSpecification = runSpecification; + this.mode = runSpecification.mode(); + } + + @Override + public void run() { + switch (mode) { + case ONCE -> runMethod(); + case NORMAL -> super.run(); + } } /** @@ -960,6 +959,19 @@ protected void runMethod() { throw new TestRunException("There was an error while invoking @Run method " + runMethod, e); } } + + @Override + protected void checkCompilationLevel() { + CompLevel level = CompLevel.forValue(WhiteBox.getWhiteBox().getMethodCompilationLevel(testMethod)); + if (level != test.getRequestedCompLevel()) { + String message = "Compilation level should be " + test.getRequestedCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod + "."; + switch (mode) { + case ONCE -> message = message + "\nCheck your @Run method (invoked once) " + runMethod + " to ensure that " + testMethod + " will be complied at the requested level."; + case NORMAL -> message = message + "\nCheck your @Run method " + runMethod + " to ensure that " + testMethod + " is called at least once in each iteration."; + } + TestRun.fail(message); + } + } } @@ -985,7 +997,7 @@ public static int compLevelToInt(CompLevel compLevel) { } // Get the appropriate level as permitted by the test scenario and VM options. - private static CompLevel restrictCompLevel(CompLevel compLevel) { + public static CompLevel restrictCompLevel(CompLevel compLevel) { switch (compLevel) { case ANY -> compLevel = CompLevel.C2; case C1_SIMPLE, C1_LIMITED_PROFILE, C1_FULL_PROFILE -> { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java new file mode 100644 index 00000000000..ea2446f0996 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java @@ -0,0 +1,16 @@ +package compiler.valhalla.framework; + +public class TestRun { + public static void check(boolean test, String failureMessage) { + if (!test) { + throw new TestRunException(failureMessage); + } + } + public static void fail(String failureMessage) { + throw new TestRunException(failureMessage); + } + + public static void fail(String failureMessage, Exception e) { + throw new TestRunException(failureMessage, e); + } +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java index 75881f19c91..44c71140f30 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -25,8 +25,7 @@ public static void main(String[] args) throws Exception { } } - for (int i = 0; i < checkExecuted.length; i++) { - int value = checkExecuted[i]; + for (int value : checkExecuted) { if (value != 1) { throw new RuntimeException("Check function should have been executed exactly once"); } @@ -74,8 +73,8 @@ public static void main(String[] args) throws Exception { // } static boolean wasExecuted = false; - static int[] testExecuted = new int[75]; - static int[] checkExecuted = new int[4]; + static int[] testExecuted = new int[76]; + static int[] checkExecuted = new int[5]; boolean lastToggleBoolean = true; long[] nonFloatingRandomNumbers = new long[10]; double[] floatingRandomNumbers = new double[10]; @@ -822,6 +821,30 @@ public void checkTestCheckBothOnce(int returnValue, TestInfo testInfo) { } checkExecuted[3]++; // Executed once } + + @Test + public void testRunOnce() { + checkExecuted[4]++; + } + + @Run(test="testRunOnce", mode=RunMode.ONCE) + public void runTestRunOnce(TestInfo info) { + testRunOnce(); + } + + + @Test(compLevel = CompLevel.C2) + public void testRunOnce2() { + testExecuted[75]++; + } + + @Run(test="testRunOnce2", mode=RunMode.ONCE) + public void runTestRunOnce2(TestInfo info) { + for (int i = 0; i < TestFramework.WARMUP_ITERATIONS + 1; i++) { + testRunOnce2(); + } + } + } class DefaultObject { From 66de13b405ab47804a20abcae6707370afbc06b6 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 20 Jan 2021 16:11:47 +0100 Subject: [PATCH 008/131] Fix compilation level for @Test --- .../compiler/valhalla/framework/CheckAt.java | 3 +- .../valhalla/framework/CompLevel.java | 6 +- .../compiler/valhalla/framework/Scenario.java | 4 + .../src/compiler/valhalla/framework/Skip.java | 21 --- .../src/compiler/valhalla/framework/Test.java | 10 +- .../valhalla/framework/TestFramework.java | 137 ++++++++++-------- .../compiler/valhalla/framework/TestInfo.java | 26 +++- .../valhalla/framework/tests/TestBasics.java | 11 +- .../framework/tests/TestCompLevels.java | 120 +++++++++++++++ 9 files changed, 232 insertions(+), 106 deletions(-) delete mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Skip.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java index ac962ce4eae..50243d983b9 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java @@ -1,6 +1,5 @@ package compiler.valhalla.framework; public enum CheckAt { - EACH_INVOCATION, - C2_COMPILED + EACH_INVOCATION, COMPILED } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java index e1e2f11f284..944b9c17b53 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java @@ -4,11 +4,9 @@ import java.util.Map; public enum CompLevel { + SKIP(-3), // Skip a @Test having this value ANY(-2), - ALL(-2), - AOT(-1), - INTERPRETER(0), // Only execute in interpreter, no compilation - C1_SIMPLE(1), // C1 + C1(1), // C1 C1_LIMITED_PROFILE(2), // C1, invocation & backedge counters C1_FULL_PROFILE(3), // C1, invocation & backedge counters + mdo C2(4); // C2 or JVMCI diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java index 9de6a79edea..217c0a7472b 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java @@ -13,6 +13,10 @@ public class Scenario { private final int index; boolean enabled; + public enum Run { + EXCLUDE_DEFAULT, INCLUDE_DEFAULT + } + static { if (!SCENARIOS.isEmpty()) { Arrays.stream(SCENARIOS.split("\\s*,\\s*")).map(Integer::getInteger).forEachOrdered(enabledScenarios::add); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Skip.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Skip.java deleted file mode 100644 index 5711ba28d16..00000000000 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Skip.java +++ /dev/null @@ -1,21 +0,0 @@ -package compiler.valhalla.framework; - -public enum Skip { - C1_SIMPLE(1), // C1 - C1_LIMITED_PROFILE(2), // C1, invocation & backedge counters - C1_FULL_PROFILE(3), // C1, invocation & backedge counters + mdo - C2_FULL_OPTIMIZATION(4), // C2 or JVMCI - ALL(5), // Special artificial level, skip this test completely. - C1(6), // Special artificial level to exlude C1 (Level 1-3) - C2(7); // Special artificial level to exclude C2 (Level 4) - - private final int value; - - Skip(int level) { - this.value = level; - } - - public int getValue() { - return value; - } -} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java index 2353903ffe4..6c7f703d3ca 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java @@ -6,13 +6,5 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Test { - // Regular expression used to match forbidden IR nodes - // in the C2 IR emitted for this test. - String failOn() default ""; - // Regular expressions used to match and count IR nodes. - String[] match() default {}; - int[] matchCount() default {}; - CompLevel compLevel() default CompLevel.ANY; - Skip[] skip() default {}; - int valid() default 0; + CompLevel compLevel() default CompLevel.C2; } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 897c9713f54..4294b3f2033 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -6,7 +6,6 @@ import java.lang.reflect.Modifier; import java.util.*; import java.util.function.BiPredicate; -import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.test.lib.Asserts; @@ -38,7 +37,7 @@ public class TestFramework { static final boolean TIERED_COMPILATION = (Boolean)WHITE_BOX.getVMFlag("TieredCompilation"); static final CompLevel TIERED_COMPILATION_STOP_AT_LEVEL = CompLevel.forValue(((Long)WHITE_BOX.getVMFlag("TieredStopAtLevel")).intValue()); - static final boolean TEST_C1 = TIERED_COMPILATION && TIERED_COMPILATION_STOP_AT_LEVEL.getValue() < Skip.C2_FULL_OPTIMIZATION.getValue(); + static final boolean TEST_C1 = TIERED_COMPILATION && TIERED_COMPILATION_STOP_AT_LEVEL.getValue() < CompLevel.C2.getValue(); // User defined settings static final boolean XCOMP = Platform.isComp(); @@ -61,9 +60,9 @@ public class TestFramework { private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); private static final boolean USE_COMPILE_COMMAND_ANNOTATIONS = Boolean.parseBoolean(System.getProperty("UseCompileCommandAnnotations", "true")); private static final boolean PRINT_VALID_IR_RULES = Boolean.parseBoolean(System.getProperty("PrintValidIRRules", "false")); - private static final boolean ENABLE_DEFAULT_SCENARIO = Boolean.parseBoolean(System.getProperty("EnableDefaultScenario", "true")); protected static final long PerMethodTrapLimit = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); protected static final boolean ProfileInterpreter = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); + private static final boolean FLIP_C1_C2 = Boolean.parseBoolean(System.getProperty("FlipC1C2", "false")); static final boolean TESTING_TEST_FRAMEWORK = Boolean.parseBoolean(System.getProperty("TestingTestFramework", "false")); @@ -162,18 +161,31 @@ public static void runWithHelperClasses(Class testClass, Class... helperCl public static void runWithScenarios(Scenario... scenarios) { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - runWithScenarios(walker.getCallerClass(), scenarios); + runWithScenarios(Scenario.Run.EXCLUDE_DEFAULT, walker.getCallerClass(), scenarios); + } + + public static void runWithScenarios(Scenario.Run runMode, Scenario... scenarios) { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + runWithScenarios(runMode, walker.getCallerClass(), scenarios); } public static void runWithScenarios(Class testClass, Scenario... scenarios) { - runWithScenarios(testClass, null, scenarios); + runWithScenarios(Scenario.Run.EXCLUDE_DEFAULT, testClass, null, scenarios); + } + + public static void runWithScenarios(Scenario.Run runMode, Class testClass, Scenario... scenarios) { + runWithScenarios(runMode, testClass, null, scenarios); } public static void runWithScenarios(Class testClass, List> helperClasses, Scenario... scenarios) { + runWithScenarios(Scenario.Run.EXCLUDE_DEFAULT, testClass, helperClasses, scenarios); + } + + public static void runWithScenarios(Scenario.Run runMode, Class testClass, List> helperClasses, Scenario... scenarios) { TestFramework framework = new TestFramework(); Map exceptionMap = new HashMap<>(); // First run without additional scenario flags. - if (ENABLE_DEFAULT_SCENARIO) { + if (runMode == Scenario.Run.INCLUDE_DEFAULT) { try { framework.runTestVM(testClass, helperClasses, null); } catch (Exception e) { @@ -311,8 +323,7 @@ private ArrayList prepareTestVmFlags(Class testClass, List> } if (VERBOSE) { - System.out.print("Command Line: "); - cmds.forEach(flag -> System.out.print(flag + " ")); + System.out.println("Command Line: " + String.join(" ", cmds)); } return cmds; } @@ -479,10 +490,46 @@ private void addTest(Method m, Argument[] arguments) { } // Don't inline test methods WHITE_BOX.testSetDontInlineMethod(m, true); - DeclaredTest test = new DeclaredTest(m, testAnno, arguments, warmupIterations, osrOnly); + CompLevel compLevel = testAnno.compLevel(); + if (FLIP_C1_C2) { + compLevel = flipCompLevel(compLevel); + } + compLevel = restrictCompLevel(compLevel); + DeclaredTest test = new DeclaredTest(m, arguments, compLevel, warmupIterations, osrOnly); declaredTests.put(m, test); } + + // Get the appropriate level as permitted by the test scenario and VM options. + private static CompLevel restrictCompLevel(CompLevel compLevel) { + if (!USE_COMPILER) { + return CompLevel.SKIP; + } + if (compLevel == CompLevel.ANY) { + // Use C2 by default. + return CompLevel.C2; + } + if (!TIERED_COMPILATION && compLevel.getValue() < CompLevel.C2.getValue()) { + return CompLevel.SKIP; + } + if (TIERED_COMPILATION && compLevel.getValue() > TIERED_COMPILATION_STOP_AT_LEVEL.getValue()) { + return CompLevel.SKIP; + } + return compLevel; + } + + private static CompLevel flipCompLevel(CompLevel compLevel) { + switch (compLevel) { + case C1, C1_LIMITED_PROFILE, C1_FULL_PROFILE -> { + return CompLevel.C2; + } + case C2 -> { + return CompLevel.C1; + } + } + return compLevel; + } + private void setupCheckAndRunMethods(Class clazz) { for (Method m : clazz.getDeclaredMethods()) { Check checkAnno = getAnnotation(m, Check.class); @@ -621,7 +668,8 @@ enum TriState { } public static boolean isC2Compiled(Method m) { - return compiledByC2(m) == TriState.Yes; + return WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) == CompLevel.C2.getValue(); +// return compiledByC2(m) == TriState.Yes; } public static void assertDeoptimizedByC2(Method m) { @@ -633,10 +681,10 @@ public static void assertCompiledByC2(Method m) { } private static TriState compiledByC2(Method m) { - if (!TestFramework.USE_COMPILER || TestFramework.XCOMP || TestFramework.TEST_C1 || - (TestFramework.STRESS_CC && !WHITE_BOX.isMethodCompilable(m, CompLevel.C2.getValue(), false))) { - return TriState.Maybe; - } +// if (!TestFramework.USE_COMPILER || TestFramework.XCOMP || TestFramework.TEST_C1 || +// (TestFramework.STRESS_CC && !WHITE_BOX.isMethodCompilable(m, CompLevel.C2.getValue(), false))) { +// return TriState.Maybe; +// } if (WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) >= CompLevel.C2.getValue()) { return TriState.Yes; @@ -681,21 +729,21 @@ public Method getTestMethod() { private final Argument[] arguments; private final int warmupIterations; - private final CompLevel requestedCompLevel; + private final CompLevel compLevel; private final boolean osrOnly; - public DeclaredTest(Method testMethod, Test testAnnotation, Argument[] arguments, int warmupIterations, boolean osrOnly) { + public DeclaredTest(Method testMethod, Argument[] arguments, CompLevel compLevel, int warmupIterations, boolean osrOnly) { // Make sure we can also call non-public or public methods in package private classes testMethod.setAccessible(true); this.testMethod = testMethod; - this.requestedCompLevel = TestFrameworkUtils.restrictCompLevel(testAnnotation.compLevel()); + this.compLevel = compLevel; this.arguments = arguments; this.warmupIterations = warmupIterations; this.osrOnly = osrOnly; } - public CompLevel getRequestedCompLevel() { - return requestedCompLevel; + public CompLevel getCompLevel() { + return compLevel; } public int getWarmupIterations() { @@ -777,6 +825,10 @@ public String getTestName() { * Run the associated test */ public void run() { + if (test.getCompLevel() == CompLevel.SKIP) { + // Exclude test if compilation level is SKIP either set through test or by not matching the current VM flags. + return; + } test.printFixedRandomArguments(); for (int i = 0; i < test.getWarmupIterations(); i++) { runMethod(); @@ -814,7 +866,7 @@ private void compileOSRAndRun() { long elapsed = System.currentTimeMillis() - started; int level = WHITE_BOX.getMethodCompilationLevel(testMethod); if (maybeCodeBufferOverflow && elapsed > 5000 - && (!WHITE_BOX.isMethodCompiled(testMethod, false) || level != test.getRequestedCompLevel().getValue())) { + && (!WHITE_BOX.isMethodCompiled(testMethod, false) || level != test.getCompLevel().getValue())) { retryDisabledVerifyOops(stateCleared); stateCleared = true; } else { @@ -874,8 +926,8 @@ private void compileNormallyAndRun() { protected void checkCompilationLevel() { CompLevel level = CompLevel.forValue(WhiteBox.getWhiteBox().getMethodCompilationLevel(testMethod)); - TestRun.check(level == test.getRequestedCompLevel(), - "Compilation level should be " + test.getRequestedCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod); + TestRun.check(level == test.getCompLevel(), + "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod); } /** @@ -907,7 +959,7 @@ public void verify(Object result) { boolean shouldVerify = false; switch (checkAt) { case EACH_INVOCATION -> shouldVerify = true; - case C2_COMPILED -> shouldVerify = !testInfo.isWarmUp(); + case COMPILED -> shouldVerify = !testInfo.isWarmUp(); } if (shouldVerify) { try { @@ -963,8 +1015,8 @@ protected void runMethod() { @Override protected void checkCompilationLevel() { CompLevel level = CompLevel.forValue(WhiteBox.getWhiteBox().getMethodCompilationLevel(testMethod)); - if (level != test.getRequestedCompLevel()) { - String message = "Compilation level should be " + test.getRequestedCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod + "."; + if (level != test.getCompLevel()) { + String message = "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod + "."; switch (mode) { case ONCE -> message = message + "\nCheck your @Run method (invoked once) " + runMethod + " to ensure that " + testMethod + " will be complied at the requested level."; case NORMAL -> message = message + "\nCheck your @Run method " + runMethod + " to ensure that " + testMethod + " is called at least once in each iteration."; @@ -977,49 +1029,16 @@ protected void checkCompilationLevel() { class TestFrameworkUtils { private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); - private static final boolean FLIP_C1_C2 = Boolean.parseBoolean(System.getProperty("FlipC1C2", "false")); public static void enqueueMethodForCompilation(DeclaredTest test) { - enqueueMethodForCompilation(test.getTestMethod(), test.getRequestedCompLevel()); + enqueueMethodForCompilation(test.getTestMethod(), test.getCompLevel()); } // Used for non-@Tests, can also be called from other places in tests. public static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { - compLevel = restrictCompLevel(compLevel); if (TestFramework.VERBOSE) { System.out.println("enqueueMethodForCompilation " + m + ", level = " + compLevel); } WHITE_BOX.enqueueMethodForCompilation(m, compLevel.getValue()); } - - public static int compLevelToInt(CompLevel compLevel) { - return TestFrameworkUtils.restrictCompLevel(compLevel).getValue(); - } - - // Get the appropriate level as permitted by the test scenario and VM options. - public static CompLevel restrictCompLevel(CompLevel compLevel) { - switch (compLevel) { - case ANY -> compLevel = CompLevel.C2; - case C1_SIMPLE, C1_LIMITED_PROFILE, C1_FULL_PROFILE -> { - if (FLIP_C1_C2) { - // Effectively treat all (compLevel = C1_*) as (compLevel = C2) - compLevel = CompLevel.C2; - } - } - case C2 -> { - if (FLIP_C1_C2) { - // Effectively treat all (compLevel = C2) as (compLevel = C1_SIMPLE) - compLevel = CompLevel.C1_SIMPLE; - } - } - } - - if (!TestFramework.TEST_C1 && compLevel.getValue() < CompLevel.C2.getValue()) { - compLevel = CompLevel.C2; - } - if (TestFramework.TIERED_COMPILATION && compLevel.getValue() > TestFramework.TIERED_COMPILATION_STOP_AT_LEVEL.getValue()) { - compLevel = TestFramework.TIERED_COMPILATION_STOP_AT_LEVEL; - } - return compLevel; - } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java index 07e3fcb02d1..3301ced0480 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java @@ -8,6 +8,8 @@ public class TestInfo { private static final Random random = new Random(); private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + protected static final long PerMethodTrapLimit = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); + protected static final boolean ProfileInterpreter = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); private boolean toggleBool = false; private boolean onWarmUp = true; @@ -42,15 +44,29 @@ void setWarmUpFinished() { onWarmUp = false; } - public boolean isC2Compiled() { - return TestFramework.isC2Compiled(testMethod); + public Method getTest() { + return testMethod; } - public void assertDeoptimizedByC2() { - TestFramework.assertDeoptimizedByC2(testMethod); + public boolean isC2Compiled(Method m) { + return WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) == CompLevel.C2.getValue(); +// return compiledByC2(m) == TriState.Yes; + } + + public boolean isCompiledAtLevel(Method m, CompLevel level) { + return WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) == level.getValue(); +// return compiledByC2(m) == TriState.Yes; + } + + public void assertDeoptimizedByC2(Method m) { + TestRun.check(!isC2Compiled(m) || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized"); } public void assertCompiledByC2(Method m) { - TestFramework.assertCompiledByC2(testMethod); + TestRun.check(isC2Compiled(m), m + " should have been compiled"); + } + + public void assertCompiledAtLevel(Method m, CompLevel level) { + TestRun.check(isCompiledAtLevel(m, level), m + " should have been compiled at level " + level.name()); } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java index 44c71140f30..d03379dc85d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -778,7 +778,7 @@ public int testCheckOnce() { return 1; } - @Check(test="testCheckOnce", when=CheckAt.C2_COMPILED) + @Check(test="testCheckOnce", when=CheckAt.COMPILED) public void checkTestCheckOnce() { checkExecuted[0]++; // Executed once } @@ -789,7 +789,7 @@ public int testCheckReturnOnce() { return 2; } - @Check(test="testCheckReturnOnce", when=CheckAt.C2_COMPILED) + @Check(test="testCheckReturnOnce", when=CheckAt.COMPILED) public void checkTestCheckReturnOnce(int returnValue) { if (returnValue != 2) { throw new RuntimeException("Must be 2"); @@ -803,7 +803,7 @@ public int testCheckTestInfoOnce() { return 3; } - @Check(test="testCheckTestInfoOnce", when=CheckAt.C2_COMPILED) + @Check(test="testCheckTestInfoOnce", when=CheckAt.COMPILED) public void checkTestCheckTestInfoOnce(TestInfo testInfo) { checkExecuted[2]++; // Executed once } @@ -814,7 +814,7 @@ public int testCheckBothOnce() { return 4; } - @Check(test="testCheckBothOnce", when=CheckAt.C2_COMPILED) + @Check(test="testCheckBothOnce", when=CheckAt.COMPILED) public void checkTestCheckBothOnce(int returnValue, TestInfo testInfo) { if (returnValue != 4) { throw new RuntimeException("Must be 4"); @@ -833,7 +833,7 @@ public void runTestRunOnce(TestInfo info) { } - @Test(compLevel = CompLevel.C2) + @Test public void testRunOnce2() { testExecuted[75]++; } @@ -844,7 +844,6 @@ public void runTestRunOnce2(TestInfo info) { testRunOnce2(); } } - } class DefaultObject { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java new file mode 100644 index 00000000000..3cc5f568b97 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java @@ -0,0 +1,120 @@ +package compiler.valhalla.framework.tests; + +import compiler.valhalla.framework.*; +import jdk.test.lib.Asserts; + +import java.lang.reflect.Method; + +// Requires C1 and C2 enabled +public class TestCompLevels { + public static final String[] TEST_KEYS = { "test-key0", "test-key1" }; + static int[] testExecuted = new int[4]; + + public static void main(String[] args) throws Exception { + Method runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM"); + runTestsOnSameVM.setAccessible(true); + runTestsOnSameVM.invoke(null); + for (int i = 0; i < testExecuted.length; i++) { + int value = testExecuted[i]; + if (value != TestFramework.WARMUP_ITERATIONS + 1) { + // Warmups + 1 compiled invocation + throw new RuntimeException("Test " + i + " was executed " + value + " times stead of " + + TestFramework.WARMUP_ITERATIONS + 1 + " times." ); + } + } + Scenario s = new Scenario(1, "-XX:-TieredCompilation"); + TestFramework.runWithScenarios(TestNoTiered.class, s); + s = new Scenario(1, "-XX:TieredStopAtLevel=1"); + TestFramework.runWithScenarios(TestStopAtLevel1.class, s); + Asserts.assertTrue(TestFramework.getLastVmOutput().contains("TestStopAtLevel1=34")); + } + + @Test(compLevel = CompLevel.C1) + public void testC1() { + testExecuted[0]++; + } + + @Check(test="testC1", when = CheckAt.COMPILED) + public void checkTestC1(TestInfo info) { + info.assertCompiledAtLevel(info.getTest(), CompLevel.C1); + } + + @Test(compLevel = CompLevel.C1_LIMITED_PROFILE) + public void testC1Limited() { + testExecuted[1]++; + } + + @Check(test="testC1Limited", when = CheckAt.COMPILED) + public void checkTestLimited(TestInfo info) { + info.assertCompiledAtLevel(info.getTest(), CompLevel.C1_LIMITED_PROFILE); + } + + @Test(compLevel = CompLevel.C1_FULL_PROFILE) + public void testC1Full() { + testExecuted[2]++; + } + + @Check(test="testC1Full", when = CheckAt.COMPILED) + public void checkTestC1Full(TestInfo info) { + info.assertCompiledAtLevel(info.getTest(), CompLevel.C1_FULL_PROFILE); + } + + @Test(compLevel = CompLevel.C2) + public void testC2() { + testExecuted[3]++; + } + + @Check(test="testC2", when = CheckAt.COMPILED) + public void checkTestC2(TestInfo info) { + info.assertCompiledAtLevel(info.getTest(), CompLevel.C2); + } +} + +class TestNoTiered { + @Test(compLevel = CompLevel.C1) + public void notExecuted() { + throw new RuntimeException("Should not be executed"); + } + + @Test(compLevel = CompLevel.C1_LIMITED_PROFILE) + public void notExecuted1() { + throw new RuntimeException("Should not be executed"); + } + + @Test(compLevel = CompLevel.C1_FULL_PROFILE) + public void notExecuted2() { + throw new RuntimeException("Should not be executed"); + } + + @Test(compLevel = CompLevel.SKIP) + public void notExecuted3() { + throw new RuntimeException("Should not be executed"); + } +} + +class TestStopAtLevel1 { + @Test(compLevel = CompLevel.C2) + public void notExecuted() { + throw new RuntimeException("Should not be executed"); + } + + @Test(compLevel = CompLevel.C1_LIMITED_PROFILE) + public void notExecuted1() { + throw new RuntimeException("Should not be executed"); + } + + @Test(compLevel = CompLevel.C1_FULL_PROFILE) + public void notExecuted2() { + throw new RuntimeException("Should not be executed"); + } + + @Test(compLevel = CompLevel.C1) + public int executed() { + return 34; + } + + @Check(test="executed", when = CheckAt.COMPILED) + public void checkExecuted(int result) { + System.out.println("TestStopAtLevel1=" + result); + } +} From 9e66467d9f78253539662b8a5cfd95cd63c554f5 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 25 Jan 2021 17:32:51 +0100 Subject: [PATCH 009/131] Finishing counts rule for @IR and adding appropriate tests + fixing some IR rules --- .../valhalla/framework/IREncodingPrinter.java | 44 +-- .../valhalla/framework/IRMatcher.java | 17 +- .../compiler/valhalla/framework/IRNode.java | 8 +- .../valhalla/framework/TestFramework.java | 148 ++++++-- .../valhalla/framework/tests/TestBasics.java | 34 +- .../framework/tests/TestCompLevels.java | 10 +- .../framework/tests/TestIRMatching.java | 320 ++++++++++++------ .../framework/tests/TestScenarios.java | 8 +- 8 files changed, 374 insertions(+), 215 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java index f242a504506..c197fdc8c2d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java @@ -142,7 +142,7 @@ private boolean check(Method m, String flag, String value) { long longValue = 0; ParsedComparator parsedComparator = null; try { - parsedComparator = parseComparator(value.trim()); + parsedComparator = ParsedComparator.parseComparator(value); longValue = Long.parseLong(parsedComparator.getStrippedString()); } catch (NumberFormatException e) { TestFormat.fail("Invalid value " + value + " for number based flag " + flag); @@ -168,7 +168,7 @@ private boolean check(Method m, String flag, String value) { double doubleValue = 0; ParsedComparator parsedComparator = null; try { - parsedComparator = parseComparator(value); + parsedComparator = ParsedComparator.parseComparator(value); doubleValue = Double.parseDouble(parsedComparator.getStrippedString()); } catch (NumberFormatException e) { TestFormat.fail("Invalid value " + value + " for number based flag " + flag); @@ -185,46 +185,6 @@ private boolean check(Method m, String flag, String value) { TestFormat.fail("Could not find flag " + flag); return false; } - - private > ParsedComparator parseComparator(String value) { - BiPredicate comparison = null; - try { - switch (value.charAt(0)) { - case '<': - if (value.charAt(1) == '=') { - comparison = (x, y) -> x.compareTo(y) <= 0; - value = value.substring(2).trim(); - } else { - comparison = (x, y) -> x.compareTo(y) < 0; - value = value.substring(1).trim(); - } - break; - case '>': - if (value.charAt(1) == '=') { - comparison = (x, y) -> x.compareTo(y) >= 0; - value = value.substring(2).trim(); - } else { - comparison = (x, y) -> x.compareTo(y) > 0; - value = value.substring(1).trim(); - } - break; - case '!': - TestFormat.check(value.charAt(1) == '=', "Invalid comparator sign used."); - comparison = (x, y) -> x.compareTo(y) != 0; - value = value.substring(2).trim(); - break; - case '=': // Allowed syntax, equivalent to not using any symbol. - value = value.substring(1).trim(); - default: - comparison = (x, y) -> x.compareTo(y) == 0; - value = value.trim(); - break; - } - } catch (IndexOutOfBoundsException e) { - TestFormat.fail("Invalid value format."); - } - return new ParsedComparator<>(value, comparison); - } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java index 2b76ebe5251..4db7634c174 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java @@ -128,7 +128,7 @@ private void applyFailOn(Method m, String testOutput, IR irAnno, int annoId) { Matcher matcher = pattern.matcher(testOutput); boolean found = matcher.find(); if (found) { - addFail(m, irAnno, annoId, matcher, "contains forbidden node"); + addFail(m, irAnno, annoId, matcher, "contains forbidden node(s)"); } } } @@ -141,19 +141,25 @@ private void applyCount(Method m, String testOutput, IR irAnno, int annoId) { TestFormat.check(i + 1 < nodesWithCount.size(), "Missing count for IR node \"" + node + "\" at " + m); String countString = nodesWithCount.get(i + 1); long expectedCount = 0; + + ParsedComparator parsedComparator = null; try { - expectedCount = Long.parseLong(countString); + parsedComparator = ParsedComparator.parseComparator(countString); + expectedCount = Long.parseLong(parsedComparator.getStrippedString()); } catch (NumberFormatException e) { TestFormat.fail("Provided invalid count \"" + countString + "\" for IR node \"" + node + "\" at " + m); + } catch (Exception e) { + TestFormat.fail("Invalid comparator in \"" + countString + "\" for count of node " + node, e); } + TestFormat.check(expectedCount >= 0,"Provided invalid negative count \"" + countString + "\" for IR node \"" + node + "\" at " + m); + Pattern pattern = Pattern.compile(node); Matcher matcher = pattern.matcher(testOutput); long actualCount = matcher.results().count(); - if (expectedCount != actualCount) { - String message = "contains " + actualCount + " instead of " + expectedCount + " nodes"; + if (!parsedComparator.getPredicate().test(actualCount, expectedCount)) { + String message = "contains wrong number of nodes. Failed constraint: " + actualCount + " (found) " + countString.trim(); addFail(m, irAnno, annoId, matcher, message); } - } } } @@ -162,6 +168,7 @@ private void addFail(Method m, IR irAnno, int annoId, Matcher matcher, String me matcher.reset(); StringBuilder builder = new StringBuilder(); builder.append("@IR rule ").append(annoId).append(": \"").append(irAnno).append("\"\n"); + builder.append("Failing Regex: ").append(matcher.pattern().toString()).append("\n"); builder.append("Failure: Graph for '").append(m).append(" ").append(message).append(":\n"); matcher.results().forEach(r -> builder.append(r.group()).append("\n")); List failsList = fails.computeIfAbsent(m, k -> new ArrayList<>()); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java index 913adc3dfdf..aaee73916fc 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java @@ -18,13 +18,13 @@ public class IRNode { private static final String ALLOC_ARRAY_OF_POSTFIX = ";:.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_array_Java" + END; public static final String STORE = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + END; - public static final String STORE_OF_CLASS = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@.*"; - private static final String STORE_OF_CLASS_POSTFIX = "(\\+|:).*" + END; + public static final String STORE_OF_CLASS = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@\\S*"; + private static final String STORE_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; public static final String STORE_OF_FIELD = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@.*name="; private static final String STORE_OF_FIELD_POSTFIX = ",.*" + END; public static final String LOAD = START + "Load(B|S|I|L|F|D|P|N)" + MID + END; - public static final String LOAD_OF_CLASS = START + "Load(B|C|S|I|L|F|D|P|N)" + MID + "@.*"; - private static final String LOAD_OF_CLASS_POSTFIX = "(\\+|:).*" + END; + public static final String LOAD_OF_CLASS = START + "Load(B|C|S|I|L|F|D|P|N)" + MID + "@\\S*"; + private static final String LOAD_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; public static final String LOAD_OF_FIELD = START + "Load(B|C|S|I|L|F|D|P|N)" + MID + "@.*name="; private static final String LOAD_OF_FIELD_POSTFIX = ",.*" + END; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 4294b3f2033..2bdbdd89cc5 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -78,17 +78,16 @@ public class TestFramework { private final HashMap declaredTests = new HashMap<>(); private final LinkedHashMap allTests = new LinkedHashMap<>(); // Keep order private final HashMap testMethodMap = new HashMap<>(); - - // Index into this array is the scenario ID. - protected final List scenarios = new ArrayList<>(); + private List excludeList = null; + private List includeList = null; private final IREncodingPrinter irMatchRulePrinter; TestFramework() { // These flags can be overridden - fixedDefaultFlags = setupDefaultFlags(); - compileCommandFlags = setupCompileCommandFlags(); - printFlags = setupPrintFlags(); - verifyFlags = setupVerifyFlags(); + fixedDefaultFlags = initDefaultFlags(); + compileCommandFlags = initCompileCommandFlags(); + printFlags = initPrintFlags(); + verifyFlags = initVerifyFlags(); if (PRINT_VALID_IR_RULES) { irMatchRulePrinter = new IREncodingPrinter(); @@ -97,24 +96,51 @@ public class TestFramework { } } - protected String[] setupDefaultFlags() { + // Only used by a TestVM + private TestFramework(Class testClass) { + this(); + includeList = createTestFilterList(TESTLIST, testClass); + excludeList = createTestFilterList(EXCLUDELIST, testClass); + } + + protected String[] initDefaultFlags() { return new String[] {"-XX:-BackgroundCompilation"}; } - protected String[] setupCompileCommandFlags() { + protected String[] initCompileCommandFlags() { return new String[] {"-XX:CompileCommand=quiet"}; } - protected String[] setupPrintFlags() { + protected String[] initPrintFlags() { return new String[] {"-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions"}; } - protected String[] setupVerifyFlags() { + protected String[] initVerifyFlags() { return new String[] { "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", "-XX:+VerifyBeforeGC", "-XX:+VerifyAfterGC", "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing"}; } + private List createTestFilterList(String list, Class testClass) { + List filterList = null; + if (!list.isEmpty()) { + String classPrefix = testClass.getSimpleName() + "."; + filterList = new ArrayList<>(Arrays.asList(list.split(","))); + for (int i = filterList.size() - 1; i >= 0; i--) { + String test = filterList.get(i); + if (test.indexOf(".") > 0) { + if (test.startsWith(classPrefix)) { + test = test.substring(classPrefix.length()); + filterList.set(i, test); + } else { + filterList.remove(i); + } + } + } + } + return filterList; + } + public static void main(String[] args) { String testClassName = args[0]; System.out.println("Framework main(), about to run test class " + testClassName); @@ -125,7 +151,7 @@ public static void main(String[] args) { throw new TestRunException("Could not find test class " + testClassName, e); } - TestFramework framework = new TestFramework(); + TestFramework framework = new TestFramework(testClass); framework.runTestsOnSameVM(testClass, getHelperClasses(args)); } @@ -449,13 +475,18 @@ public static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { } private void setupTests(Class clazz) { + boolean hasIncludeList = includeList != null; + boolean hasExcludeList = excludeList != null; for (Method m : clazz.getDeclaredMethods()) { Test testAnno = getAnnotation(m, Test.class); if (testAnno != null) { - TestFormat.check(!testMethodMap.containsKey(m.getName()), - "Cannot overload two @Test methods " + m + " and " + testMethodMap.get(m.getName())); - addTest(m, Argument.getArguments(m)); - testMethodMap.put(m.getName(), m); + if (hasIncludeList && includeList.contains(m.getName()) && (!hasExcludeList || !excludeList.contains(m.getName()))) { + addTest(m); + } else if (hasExcludeList && !excludeList.contains(m.getName())) { + addTest(m); + } else { + addTest(m); + } } else { TestFormat.check(!m.isAnnotationPresent(IR.class), "Found @IR annotation on non-@Test method " + m); } @@ -465,7 +496,9 @@ private void setupTests(Class clazz) { } } - private void addTest(Method m, Argument[] arguments) { + private void addTest(Method m) { + TestFormat.check(!testMethodMap.containsKey(m.getName()), + "Cannot overload two @Test methods " + m + " and " + testMethodMap.get(m.getName())); Test testAnno = getAnnotation(m, Test.class); TestFormat.check(testAnno != null, m + " must be a method with a @Test annotation"); @@ -495,8 +528,9 @@ private void addTest(Method m, Argument[] arguments) { compLevel = flipCompLevel(compLevel); } compLevel = restrictCompLevel(compLevel); - DeclaredTest test = new DeclaredTest(m, arguments, compLevel, warmupIterations, osrOnly); + DeclaredTest test = new DeclaredTest(m, Argument.getArguments(m), compLevel, warmupIterations, osrOnly); declaredTests.put(m, test); + testMethodMap.put(m.getName(), m); } @@ -703,24 +737,6 @@ public TestFrameworkException(String message, Exception e) { } } -class ParsedComparator> { - private final String strippedString; - private final BiPredicate predicate; - - public ParsedComparator(String strippedString, BiPredicate predicate) { - this.strippedString = strippedString; - this.predicate = predicate; - } - - public String getStrippedString() { - return strippedString; - } - - public BiPredicate getPredicate() { - return predicate; - } -} - class DeclaredTest { private final Method testMethod; public Method getTestMethod() { @@ -1027,6 +1043,66 @@ protected void checkCompilationLevel() { } +class ParsedComparator> { + private final String strippedString; + private final BiPredicate predicate; + + public ParsedComparator(String strippedString, BiPredicate predicate) { + this.strippedString = strippedString; + this.predicate = predicate; + } + + public String getStrippedString() { + return strippedString; + } + + public BiPredicate getPredicate() { + return predicate; + } + + + public static > ParsedComparator parseComparator(String value) { + BiPredicate comparison = null; + value = value.trim(); + try { + switch (value.charAt(0)) { + case '<': + if (value.charAt(1) == '=') { + comparison = (x, y) -> x.compareTo(y) <= 0; + value = value.substring(2).trim(); + } else { + comparison = (x, y) -> x.compareTo(y) < 0; + value = value.substring(1).trim(); + } + break; + case '>': + if (value.charAt(1) == '=') { + comparison = (x, y) -> x.compareTo(y) >= 0; + value = value.substring(2).trim(); + } else { + comparison = (x, y) -> x.compareTo(y) > 0; + value = value.substring(1).trim(); + } + break; + case '!': + TestFormat.check(value.charAt(1) == '=', "Invalid comparator sign used."); + comparison = (x, y) -> x.compareTo(y) != 0; + value = value.substring(2).trim(); + break; + case '=': // Allowed syntax, equivalent to not using any symbol. + value = value.substring(1).trim(); + default: + comparison = (x, y) -> x.compareTo(y) == 0; + value = value.trim(); + break; + } + } catch (IndexOutOfBoundsException e) { + TestFormat.fail("Invalid value format."); + } + return new ParsedComparator<>(value, comparison); + } +} + class TestFrameworkUtils { private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java index d03379dc85d..e3d0934658f 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -39,8 +39,8 @@ public static void main(String[] args) throws Exception { // } // // // Useful for quick checking, nothing fancy going on. This method is optional. -// @Check(test="test", when=CheckAt.C2_COMPILED) -// // Must match method 'test' when removing '_check'. Could also think about matching in annotation, e.g. @Check(test="test2"). +// @Check(test = "test", when=CheckAt.C2_COMPILED) +// // Must match method 'test' when removing '_check'. Could also think about matching in annotation, e.g. @Check(test = "test2"). // public void test_check(int result /* must match return argument of 'test', possible to check? */) { // // This method runs in interpreter, DontCompile. // // Check that there is a method 'test' with @Test, no method 'test_check' or when present no @Run at it (bad style though, better use check in annotation?), @@ -58,8 +58,8 @@ public static void main(String[] args) throws Exception { // // Optional method. // // Useful when more complex/changing arguments are required. Framework calls this method in interpreter and let it handle how to call the method // // 'test'. Framework could verify that this method has at least one call to 'test2'? -// @Run(test="test2") -// // Must match method 'test2' when removing '_run'. Could also think about matching in annotation, e.g. @Run(test="test2"). +// @Run(test = "test2") +// // Must match method 'test2' when removing '_run'. Could also think about matching in annotation, e.g. @Run(test = "test2"). // public void test2_run(TestInfo info) { // // This method runs in interpreter, DontCompile // // Check that there is a method 'test2' with @Test. @@ -696,7 +696,7 @@ public void testRun() { testExecuted[61]++; } - @Run(test="testRun") + @Run(test = "testRun") public void runTestRun(TestInfo info) { testRun(); } @@ -706,7 +706,7 @@ public void testRunNoTestInfo(int i) { testExecuted[62]++; } - @Run(test="testRunNoTestInfo") + @Run(test = "testRunNoTestInfo") public void runTestRunNoTestInfo() { testRunNoTestInfo(3); } @@ -716,7 +716,7 @@ public void testNotRun() { wasExecuted = true; } - @Run(test="testNotRun") + @Run(test = "testNotRun") public void runTestNotRun() { // Do not execute the test. Pointless but need to test that as well. } @@ -727,7 +727,7 @@ public int testCheck() { return 1; } - @Check(test="testCheck") + @Check(test = "testCheck") public void checkTestCheck() { testExecuted[64]++; // Executed on each invocation } @@ -738,7 +738,7 @@ public int testCheckReturn() { return 2; } - @Check(test="testCheckReturn") + @Check(test = "testCheckReturn") public void checkTestCheckReturn(int returnValue) { if (returnValue != 2) { throw new RuntimeException("Must be 2"); @@ -752,7 +752,7 @@ public int testCheckTestInfo() { return 3; } - @Check(test="testCheckTestInfo") + @Check(test = "testCheckTestInfo") public void checkTestCheckTestInfo(TestInfo testInfo) { testExecuted[68]++; // Executed on each invocation } @@ -764,7 +764,7 @@ public int testCheckBoth() { return 4; } - @Check(test="testCheckBoth") + @Check(test = "testCheckBoth") public void checkTestCheckTestInfo(int returnValue, TestInfo testInfo) { if (returnValue != 4) { throw new RuntimeException("Must be 4"); @@ -778,7 +778,7 @@ public int testCheckOnce() { return 1; } - @Check(test="testCheckOnce", when=CheckAt.COMPILED) + @Check(test = "testCheckOnce", when=CheckAt.COMPILED) public void checkTestCheckOnce() { checkExecuted[0]++; // Executed once } @@ -789,7 +789,7 @@ public int testCheckReturnOnce() { return 2; } - @Check(test="testCheckReturnOnce", when=CheckAt.COMPILED) + @Check(test = "testCheckReturnOnce", when=CheckAt.COMPILED) public void checkTestCheckReturnOnce(int returnValue) { if (returnValue != 2) { throw new RuntimeException("Must be 2"); @@ -803,7 +803,7 @@ public int testCheckTestInfoOnce() { return 3; } - @Check(test="testCheckTestInfoOnce", when=CheckAt.COMPILED) + @Check(test = "testCheckTestInfoOnce", when=CheckAt.COMPILED) public void checkTestCheckTestInfoOnce(TestInfo testInfo) { checkExecuted[2]++; // Executed once } @@ -814,7 +814,7 @@ public int testCheckBothOnce() { return 4; } - @Check(test="testCheckBothOnce", when=CheckAt.COMPILED) + @Check(test = "testCheckBothOnce", when=CheckAt.COMPILED) public void checkTestCheckBothOnce(int returnValue, TestInfo testInfo) { if (returnValue != 4) { throw new RuntimeException("Must be 4"); @@ -827,7 +827,7 @@ public void testRunOnce() { checkExecuted[4]++; } - @Run(test="testRunOnce", mode=RunMode.ONCE) + @Run(test = "testRunOnce", mode=RunMode.ONCE) public void runTestRunOnce(TestInfo info) { testRunOnce(); } @@ -838,7 +838,7 @@ public void testRunOnce2() { testExecuted[75]++; } - @Run(test="testRunOnce2", mode=RunMode.ONCE) + @Run(test = "testRunOnce2", mode=RunMode.ONCE) public void runTestRunOnce2(TestInfo info) { for (int i = 0; i < TestFramework.WARMUP_ITERATIONS + 1; i++) { testRunOnce2(); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java index 3cc5f568b97..942b0b89b9a 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java @@ -34,7 +34,7 @@ public void testC1() { testExecuted[0]++; } - @Check(test="testC1", when = CheckAt.COMPILED) + @Check(test = "testC1", when = CheckAt.COMPILED) public void checkTestC1(TestInfo info) { info.assertCompiledAtLevel(info.getTest(), CompLevel.C1); } @@ -44,7 +44,7 @@ public void testC1Limited() { testExecuted[1]++; } - @Check(test="testC1Limited", when = CheckAt.COMPILED) + @Check(test = "testC1Limited", when = CheckAt.COMPILED) public void checkTestLimited(TestInfo info) { info.assertCompiledAtLevel(info.getTest(), CompLevel.C1_LIMITED_PROFILE); } @@ -54,7 +54,7 @@ public void testC1Full() { testExecuted[2]++; } - @Check(test="testC1Full", when = CheckAt.COMPILED) + @Check(test = "testC1Full", when = CheckAt.COMPILED) public void checkTestC1Full(TestInfo info) { info.assertCompiledAtLevel(info.getTest(), CompLevel.C1_FULL_PROFILE); } @@ -64,7 +64,7 @@ public void testC2() { testExecuted[3]++; } - @Check(test="testC2", when = CheckAt.COMPILED) + @Check(test = "testC2", when = CheckAt.COMPILED) public void checkTestC2(TestInfo info) { info.assertCompiledAtLevel(info.getTest(), CompLevel.C2); } @@ -113,7 +113,7 @@ public int executed() { return 34; } - @Check(test="executed", when = CheckAt.COMPILED) + @Check(test = "executed", when = CheckAt.COMPILED) public void checkExecuted(int result) { System.out.println("TestStopAtLevel1=" + result); } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java index 2497d9db077..4706829d557 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java @@ -10,24 +10,22 @@ import java.util.regex.Pattern; public class TestIRMatching { - static int[] testExecuted = new int[61]; public static void main(String[] args) { - // Run with -DPrintValidIRRules=true to simulate TestVM runFailOnTests(Constraint.failOnNodes(AndOr1.class, "test1(int)", 1, true,"CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:+UsePerfData", "-XX:+UseTLAB"); runFailOnTests(Constraint.failOnNodes(AndOr1.class, "test2()", 1, true,"CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:-UsePerfData", "-XX:+UseTLAB"); runWithArguments(AndOr1.class, "-XX:SuspendRetryCount=52", "-XX:+UsePerfData", "-XX:+UseTLAB"); - runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=50"); + runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=50"); findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 0, 21); findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", -1, -1); - runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=49"); + runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=49"); findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 4, 6, 13, 18); findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); - runWithArguments(Comparisons.class, "-XX:SuspendRetryCount=51"); + runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=51"); findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 7, 12, 19, 21); findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 4, 7, 11, 16, 20, 22); @@ -44,8 +42,6 @@ public static void main(String[] args) { Constraint.failOnNodes(MultipleFailOnBad.class, "fail9()", 1,true, "Store", "CallStaticJava"), Constraint.failOnMatches(MultipleFailOnBad.class, "fail10()", 1,true, "Store", "iFld")); - runWithArguments(GoodCount.class, "-XX:SuspendRetryCount=50"); - runFailOnTests(Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 1,true, "MyClass"), Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 2,true, "MyClass"), Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 3,false, "MyClass"), @@ -64,6 +60,14 @@ public static void main(String[] args) { Constraint.failOnNodes(VariousIrNodes.class, "load()", 5, false, "Load") ); + runWithArguments(CountComparisons.class, "-XX:SuspendRetryCount=50"); + runWithArguments(GoodCount.class, "-XX:SuspendRetryCount=50"); + runFailOnTests(Constraint.countsMatches(BadCount.class, "bad1()", 1,true), + Constraint.countsMatches(BadCount.class, "bad1()", 2,false), + Constraint.countsMatches(BadCount.class, "bad2()", 1,false), + Constraint.countsMatches(BadCount.class, "bad2()", 2,true), + Constraint.countsMatches(BadCount.class, "bad3()", 1,true), + Constraint.countsMatches(BadCount.class, "bad3()", 2,true)); } private static void runWithArguments(Class clazz, String... args) { @@ -120,13 +124,13 @@ public static void findIrIds(String output, String method, int... numbers) { class AndOr1 { @Test @Arguments(ArgumentValue.DEFAULT) - @IR(applyIfAnd={"UsePerfData", "true", "SuspendRetryCount", "50", "UseTLAB", "true"}, failOn={IRNode.CALL}) + @IR(applyIfAnd = {"UsePerfData", "true", "SuspendRetryCount", "50", "UseTLAB", "true"}, failOn = {IRNode.CALL}) public void test1(int i) { dontInline(); } @Test - @IR(applyIfOr={"UsePerfData", "false", "SuspendRetryCount", "51", "UseTLAB", "false"}, failOn={IRNode.CALL}) + @IR(applyIfOr = {"UsePerfData", "false", "SuspendRetryCount", "51", "UseTLAB", "false"}, failOn = {IRNode.CALL}) public void test2() { dontInline(); } @@ -141,49 +145,49 @@ class MultipleFailOnGood { private MyClassSub myClassSub = new MyClassSub(); @Test - @IR(applyIf={"SuspendRetryCount", "50"}, failOn={IRNode.STORE, IRNode.CALL}) - @IR(failOn={IRNode.STORE, IRNode.CALL}) - @IR(applyIfOr={"SuspendRetryCount", "99", "SuspendRetryCount", "100"}, failOn={IRNode.RETURN, IRNode.CALL}) // Not applied + @IR(applyIf = {"SuspendRetryCount", "50"}, failOn = {IRNode.STORE, IRNode.CALL}) + @IR(failOn = {IRNode.STORE, IRNode.CALL}) + @IR(applyIfOr = {"SuspendRetryCount", "99", "SuspendRetryCount", "100"}, failOn = {IRNode.RETURN, IRNode.CALL}) // Not applied public void good1() { forceInline(); } @Test - @IR(failOn={IRNode.STORE, IRNode.CALL}) - @IR(applyIfNot={"SuspendRetryCount", "20"}, failOn={IRNode.ALLOC}) - @IR(applyIfNot={"SuspendRetryCount", "< 100"}, failOn={IRNode.ALLOC_OF, "Test"}) + @IR(failOn = {IRNode.STORE, IRNode.CALL}) + @IR(applyIfNot = {"SuspendRetryCount", "20"}, failOn = {IRNode.ALLOC}) + @IR(applyIfNot = {"SuspendRetryCount", "< 100"}, failOn = {IRNode.ALLOC_OF, "Test"}) public void good2() { forceInline(); } @Test - @IR(failOn={IRNode.STORE_OF_CLASS, "Test", IRNode.CALL}) - @IR(applyIfNot={"SuspendRetryCount", "20"}, failOn={IRNode.ALLOC}) - @IR(applyIfNot={"SuspendRetryCount", "< 100"}, failOn={IRNode.ALLOC_OF, "Test"}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "Test", IRNode.CALL}) + @IR(applyIfNot = {"SuspendRetryCount", "20"}, failOn = {IRNode.ALLOC}) + @IR(applyIfNot = {"SuspendRetryCount", "< 100"}, failOn = {IRNode.ALLOC_OF, "Test"}) public void good3() { forceInline(); } @Test - @IR(failOn={IRNode.CALL, IRNode.STORE_OF_CLASS, "UnknownClass"}) + @IR(failOn = {IRNode.CALL, IRNode.STORE_OF_CLASS, "UnknownClass"}) public void good4() { iFld = 42; } @Test - @IR(failOn={IRNode.STORE_OF_FIELD, "xFld", IRNode.CALL}) + @IR(failOn = {IRNode.STORE_OF_FIELD, "xFld", IRNode.CALL}) public void good5() { iFld = 42; } @Test - @IR(failOn={IRNode.STORE_OF_CLASS, "MyClass"}) // Needs exact match to fail + @IR(failOn = {IRNode.STORE_OF_CLASS, "MyClass"}) // Needs exact match to fail public void good6() { myClassSub.iFld = 42; } @Test - @IR(failOn={IRNode.STORE_OF_CLASS, "MyClassSub"}) // Static write is with Class and not MySubClass + @IR(failOn = {IRNode.STORE_OF_CLASS, "MyClassSub"}) // Static write is with Class and not MySubClass public void good7() { MyClassSub.iFldStatic = 42; } @@ -198,62 +202,62 @@ class MultipleFailOnBad { private int myInt; private MyClass myClass; @Test - @IR(failOn={IRNode.STORE, IRNode.CALL}) + @IR(failOn = {IRNode.STORE, IRNode.CALL}) public void fail1() { iFld = 42; } @Test - @IR(failOn={IRNode.STORE, IRNode.CALL}) + @IR(failOn = {IRNode.STORE, IRNode.CALL}) public void fail2() { dontInline(); } @Test - @IR(failOn={IRNode.CALL, IRNode.STORE_OF_CLASS, "MultipleFailOnBad", IRNode.ALLOC}) + @IR(failOn = {IRNode.CALL, IRNode.STORE_OF_CLASS, "MultipleFailOnBad", IRNode.ALLOC}) public void fail3() { iFld = 42; } @Test - @IR(failOn={IRNode.STORE_OF_CLASS, "compiler/valhalla/framework/tests/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "compiler/valhalla/framework/tests/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) public void fail4() { iFld = 42; } @Test - @IR(failOn={IRNode.STORE_OF_FIELD, "iFld", IRNode.CALL, IRNode.ALLOC}) + @IR(failOn = {IRNode.STORE_OF_FIELD, "iFld", IRNode.CALL, IRNode.ALLOC}) public void fail5() { iFld = 42; } @Test - @IR(failOn={IRNode.STORE_OF_CLASS, "MyClass", IRNode.ALLOC}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "MyClass", IRNode.ALLOC}) public void fail6() { myClass = new MyClass(); } @Test - @IR(failOn={IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "MyClass"}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "MyClass"}) public void fail7() { myClass = new MyClass(); } @Test - @IR(failOn={IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "compiler/valhalla/framework/tests/MyClassSub"}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "compiler/valhalla/framework/tests/MyClassSub"}) public void fail8() { myClass = new MyClassSub(); } @Test - @IR(failOn={IRNode.STORE, IRNode.CALL}) + @IR(failOn = {IRNode.STORE, IRNode.CALL}) public void fail9() { iFld = 42; dontInline(); } @Test - @IR(failOn={IRNode.STORE_OF_FIELD, "iFld", IRNode.CALL, IRNode.ALLOC}) + @IR(failOn = {IRNode.STORE_OF_FIELD, "iFld", IRNode.CALL, IRNode.ALLOC}) public void fail10() { myInt = 34; iFld = 42; @@ -265,95 +269,202 @@ private void dontInline() { } // Called with -XX:SuspendRetryCount=X. -class Comparisons { +class FlagComparisons { // Applies all IR rules if SuspendRetryCount=50 @Test - @IR(applyIf={"SuspendRetryCount", "50"}) // Index 0 - @IR(applyIf={"SuspendRetryCount", "=50"}) - @IR(applyIf={"SuspendRetryCount", "= 50"}) - @IR(applyIf={"SuspendRetryCount", " = 50"}) - @IR(applyIf={"SuspendRetryCount", "<=50"}) // Index 4 - @IR(applyIf={"SuspendRetryCount", "<= 50"}) - @IR(applyIf={"SuspendRetryCount", " <= 50"}) - @IR(applyIf={"SuspendRetryCount", ">=50"}) // Index 7 - @IR(applyIf={"SuspendRetryCount", ">= 50"}) - @IR(applyIf={"SuspendRetryCount", " >= 50"}) - @IR(applyIf={"SuspendRetryCount", ">49"}) - @IR(applyIf={"SuspendRetryCount", "> 49"}) - @IR(applyIf={"SuspendRetryCount", " > 49"}) - @IR(applyIf={"SuspendRetryCount", "<51"}) // Index 13 - @IR(applyIf={"SuspendRetryCount", "< 51"}) - @IR(applyIf={"SuspendRetryCount", " < 51"}) - @IR(applyIf={"SuspendRetryCount", "!=51"}) - @IR(applyIf={"SuspendRetryCount", "!= 51"}) - @IR(applyIf={"SuspendRetryCount", " != 51"}) - @IR(applyIf={"SuspendRetryCount", "!=49"}) - @IR(applyIf={"SuspendRetryCount", "!= 49"}) - @IR(applyIf={"SuspendRetryCount", " != 49"}) // Index 21 + @IR(applyIf = {"SuspendRetryCount", "50"}) // Index 0 + @IR(applyIf = {"SuspendRetryCount", "=50"}) + @IR(applyIf = {"SuspendRetryCount", "= 50"}) + @IR(applyIf = {"SuspendRetryCount", " = 50"}) + @IR(applyIf = {"SuspendRetryCount", "<=50"}) // Index 4 + @IR(applyIf = {"SuspendRetryCount", "<= 50"}) + @IR(applyIf = {"SuspendRetryCount", " <= 50"}) + @IR(applyIf = {"SuspendRetryCount", ">=50"}) // Index 7 + @IR(applyIf = {"SuspendRetryCount", ">= 50"}) + @IR(applyIf = {"SuspendRetryCount", " >= 50"}) + @IR(applyIf = {"SuspendRetryCount", ">49"}) + @IR(applyIf = {"SuspendRetryCount", "> 49"}) + @IR(applyIf = {"SuspendRetryCount", " > 49"}) + @IR(applyIf = {"SuspendRetryCount", "<51"}) // Index 13 + @IR(applyIf = {"SuspendRetryCount", "< 51"}) + @IR(applyIf = {"SuspendRetryCount", " < 51"}) + @IR(applyIf = {"SuspendRetryCount", "!=51"}) + @IR(applyIf = {"SuspendRetryCount", "!= 51"}) + @IR(applyIf = {"SuspendRetryCount", " != 51"}) + @IR(applyIf = {"SuspendRetryCount", "!=49"}) + @IR(applyIf = {"SuspendRetryCount", "!= 49"}) + @IR(applyIf = {"SuspendRetryCount", " != 49"}) // Index 21 public void testMatchAllIf50() { } // Applies no IR rules if SuspendRetryCount=50 @Test - @IR(applyIf={"SuspendRetryCount", "49"}) // Index 0 - @IR(applyIf={"SuspendRetryCount", "=49"}) - @IR(applyIf={"SuspendRetryCount", "= 49"}) - @IR(applyIf={"SuspendRetryCount", " = 49"}) - @IR(applyIf={"SuspendRetryCount", "51"}) // Index 4 - @IR(applyIf={"SuspendRetryCount", "=51"}) - @IR(applyIf={"SuspendRetryCount", "= 51"}) - @IR(applyIf={"SuspendRetryCount", " = 51"}) - @IR(applyIf={"SuspendRetryCount", "<=49"}) // Index 8 - @IR(applyIf={"SuspendRetryCount", "<= 49"}) - @IR(applyIf={"SuspendRetryCount", " <= 49"}) - @IR(applyIf={"SuspendRetryCount", ">=51"}) // Index 11 - @IR(applyIf={"SuspendRetryCount", ">= 51"}) - @IR(applyIf={"SuspendRetryCount", " >= 51"}) - @IR(applyIf={"SuspendRetryCount", ">50"}) - @IR(applyIf={"SuspendRetryCount", "> 50"}) - @IR(applyIf={"SuspendRetryCount", " > 50"}) - @IR(applyIf={"SuspendRetryCount", "<50"}) // Index 17 - @IR(applyIf={"SuspendRetryCount", "< 50"}) - @IR(applyIf={"SuspendRetryCount", " < 50"}) - @IR(applyIf={"SuspendRetryCount", "!=50"}) - @IR(applyIf={"SuspendRetryCount", "!= 50"}) - @IR(applyIf={"SuspendRetryCount", " != 50"}) // Index 22 + @IR(applyIf = {"SuspendRetryCount", "49"}) // Index 0 + @IR(applyIf = {"SuspendRetryCount", "=49"}) + @IR(applyIf = {"SuspendRetryCount", "= 49"}) + @IR(applyIf = {"SuspendRetryCount", " = 49"}) + @IR(applyIf = {"SuspendRetryCount", "51"}) // Index 4 + @IR(applyIf = {"SuspendRetryCount", "=51"}) + @IR(applyIf = {"SuspendRetryCount", "= 51"}) + @IR(applyIf = {"SuspendRetryCount", " = 51"}) + @IR(applyIf = {"SuspendRetryCount", "<=49"}) // Index 8 + @IR(applyIf = {"SuspendRetryCount", "<= 49"}) + @IR(applyIf = {"SuspendRetryCount", " <= 49"}) + @IR(applyIf = {"SuspendRetryCount", ">=51"}) // Index 11 + @IR(applyIf = {"SuspendRetryCount", ">= 51"}) + @IR(applyIf = {"SuspendRetryCount", " >= 51"}) + @IR(applyIf = {"SuspendRetryCount", ">50"}) + @IR(applyIf = {"SuspendRetryCount", "> 50"}) + @IR(applyIf = {"SuspendRetryCount", " > 50"}) + @IR(applyIf = {"SuspendRetryCount", "<50"}) // Index 17 + @IR(applyIf = {"SuspendRetryCount", "< 50"}) + @IR(applyIf = {"SuspendRetryCount", " < 50"}) + @IR(applyIf = {"SuspendRetryCount", "!=50"}) + @IR(applyIf = {"SuspendRetryCount", "!= 50"}) + @IR(applyIf = {"SuspendRetryCount", " != 50"}) // Index 22 public void testMatchNoneIf50() { } } +class CountComparisons { + int iFld; + + @Test + @IR(counts = {IRNode.STORE, "= 1", + IRNode.STORE, "=1", + IRNode.STORE, " = 1", + IRNode.STORE, " = 1", + IRNode.STORE, ">= 1", + IRNode.STORE, ">=1", + IRNode.STORE, " >= 1", + IRNode.STORE, " >= 1", + IRNode.STORE, "<= 1", + IRNode.STORE, "<=1", + IRNode.STORE, " <= 1", + IRNode.STORE, " <= 1", + IRNode.STORE, "!= 0", + IRNode.STORE, "!=0", + IRNode.STORE, " != 0", + IRNode.STORE, " != 0", + IRNode.STORE, "> 0", + IRNode.STORE, ">0", + IRNode.STORE, " > 0", + IRNode.STORE, " > 0", + IRNode.STORE, "< 2", + IRNode.STORE, "<2", + IRNode.STORE, " < 2", + IRNode.STORE, " < 2", + }) + public void countComparison() { + iFld = 3; + } +} class GoodCount { int iFld; int iFld2; + long result; MyClass myClass = new MyClass(); + MyClass myClassSubPoly = new MyClassSub(); + MyClassSub myClassSub = new MyClassSub(); + @Test - @IR(applyIf={"SuspendRetryCount", "50"}, counts={IRNode.STORE, "1"}) + @IR(counts = {IRNode.STORE, "1"}) public void good1() { iFld = 3; } @Test - @IR(counts={IRNode.STORE, "2"}) + @IR(counts = {IRNode.STORE, "2"}) public void good2() { iFld = 3; iFld2 = 4; } @Test - @IR(counts={IRNode.STORE, "2", IRNode.STORE_OF_CLASS, "GoodCount", "2"}) + @IR(counts = {IRNode.STORE, "2", IRNode.STORE_OF_CLASS, "GoodCount", "2"}) public void good3() { iFld = 3; iFld2 = 4; } @Test - @IR(counts={IRNode.STORE_OF_FIELD, "iFld", "1", IRNode.STORE, "2", IRNode.STORE_OF_CLASS, "GoodCount", "2"}) + @IR(counts = {IRNode.STORE_OF_FIELD, "iFld", "1", IRNode.STORE, "2", IRNode.STORE_OF_CLASS, "GoodCount", "2"}) public void good4() { iFld = 3; iFld2 = 4; } + + @Test + @IR(counts = {IRNode.STORE_OF_FIELD, "iFld", "2", IRNode.STORE, "2", IRNode.STORE_OF_CLASS, "GoodCount", "1", + IRNode.STORE_OF_CLASS, "compiler/valhalla/framework/tests/MyClass", "1", + IRNode.STORE_OF_CLASS, "framework/tests/GoodCount", "1"}) + public void good5() { + iFld = 3; + myClass.iFld = 4; + } + + @Test + @IR(counts = {IRNode.STORE_OF_FIELD, "myClass", "1", IRNode.STORE_OF_CLASS, "GoodCount", "1", + IRNode.STORE_OF_CLASS, "/GoodCount", "1", IRNode.STORE_OF_CLASS, "MyClass", "0"}, + failOn = {IRNode.STORE_OF_CLASS, "MyClass"}) + public void good6() { + myClass = new MyClass(); + } + + @Test + @IR(counts = {IRNode.STORE_OF_FIELD, "iFld", "3", IRNode.STORE_OF_CLASS, "GoodCount", "0", + IRNode.STORE_OF_CLASS, "MyClass", "2", IRNode.STORE_OF_CLASS, "MyClassSub", "1", + IRNode.STORE, "3"}, + failOn = {IRNode.STORE_OF_CLASS, "GoodCount"}) + public void good7() { + myClass.iFld = 1; + myClassSubPoly.iFld = 2; + myClassSub.iFld = 3; + } + + @Test + @IR(counts = {IRNode.LOAD, "1", IRNode.STORE, "1"}) + public void good8() { + result = iFld; + } + + + @Test + @IR(counts = {IRNode.LOAD, "4", IRNode.STORE, "1", IRNode.LOAD_OF_FIELD, "iFld", "2", IRNode.LOAD_OF_FIELD, "iFld2", "0", + IRNode.LOAD_OF_FIELD, "lFldStatic", "1", IRNode.LOAD_OF_CLASS, "GoodCount", "2", IRNode.LOAD_OF_CLASS, "MyClass", "1", + IRNode.STORE_OF_CLASS, "GoodCount", "1", IRNode.STORE_OF_FIELD, "result", "1", + IRNode.LOAD_OF_FIELD, "myClass", "1"}) + public void good9() { + result = iFld + MyClass.lFldStatic + myClass.iFld; // 1 + 1 + 2 loads (myClass is LoadN of GoodCount and myClass.iFld a LoadI of MyClass) + } +} + +class BadCount { + int iFld; + int result; + @Test + @IR(counts = {IRNode.LOAD, "!= 1"}) + @IR(counts = {IRNode.STORE, "> 0"}) + public void bad1() { + result = iFld; + } + + @Test + @IR(counts = {IRNode.LOAD, "1"}) + @IR(counts = {IRNode.STORE, "< 1"}) + public void bad2() { + result = iFld; + } + + + @Test + @IR(counts = {IRNode.LOAD, "0"}) + @IR(counts = {IRNode.STORE, " <= 0"}) + public void bad3() { + result = iFld; + } } // Test on remaining IR nodes that we have not tested above, yet. @@ -363,18 +474,18 @@ class VariousIrNodes { int iFld = 34; int result = 0; @Test - @IR(failOn={IRNode.ALLOC_ARRAY}) - @IR(failOn={IRNode.ALLOC_ARRAY_OF, "MyClass"}) - @IR(failOn={IRNode.ALLOC_ARRAY_OF, "MyClasss"}) // Does not fail - @IR(failOn={IRNode.ALLOC_ARRAY_OF, "compiler/valhalla/framework/tests/MySubClass"}) // Does not fail - @IR(failOn={IRNode.ALLOC_ARRAY_OF, "compiler/valhalla/framework/tests/MyClass"}) + @IR(failOn = {IRNode.ALLOC_ARRAY}) + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClass"}) + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClasss"}) // Does not fail + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/valhalla/framework/tests/MySubClass"}) // Does not fail + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/valhalla/framework/tests/MyClass"}) public void allocArray() { myClassArray = new MyClass[2]; } @Test - @IR(failOn={IRNode.LOOP}) - @IR(failOn={IRNode.COUNTEDLOOP}) // Does not fail + @IR(failOn = {IRNode.LOOP}) + @IR(failOn = {IRNode.COUNTEDLOOP}) // Does not fail public void loop() { for (int i = 0; i < limit; i++) { dontInline(); @@ -382,8 +493,8 @@ public void loop() { } @Test - @IR(failOn={IRNode.LOOP}) // Does not fail - @IR(failOn={IRNode.COUNTEDLOOP}) + @IR(failOn = {IRNode.LOOP}) // Does not fail + @IR(failOn = {IRNode.COUNTEDLOOP}) public void countedLoop() { for (int i = 0; i < 2000; i++) { dontInline(); @@ -391,8 +502,8 @@ public void countedLoop() { } @Test - @IR(failOn={IRNode.LOOP}) - @IR(failOn={IRNode.COUNTEDLOOP}) + @IR(failOn = {IRNode.LOOP}) + @IR(failOn = {IRNode.COUNTEDLOOP}) public void loopAndCountedLoop() { for (int i = 0; i < 2000; i++) { for (int j = 0; j < limit; j++) { @@ -405,17 +516,17 @@ public void loopAndCountedLoop() { public void dontInline() {} @Test - @IR(failOn={IRNode.LOAD}) - @IR(failOn={IRNode.LOAD_OF_CLASS, "compiler/valhalla/framework/tests/VariousIrNodes"}) - @IR(failOn={IRNode.LOAD_OF_CLASS, "VariousIrNodes"}) - @IR(failOn={IRNode.LOAD_OF_FIELD, "iFld"}) - @IR(failOn={IRNode.LOAD_OF_FIELD, "iFld2", IRNode.LOAD_OF_CLASS, "Various"}) // Does not fail + @IR(failOn = {IRNode.LOAD}) + @IR(failOn = {IRNode.LOAD_OF_CLASS, "compiler/valhalla/framework/tests/VariousIrNodes"}) + @IR(failOn = {IRNode.LOAD_OF_CLASS, "VariousIrNodes"}) + @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld"}) + @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld2", IRNode.LOAD_OF_CLASS, "Various"}) // Does not fail public void load() { result = iFld; } @Test - @IR(failOn={IRNode.RETURN}) + @IR(failOn = {IRNode.RETURN}) public void returns() { dontInline(); } @@ -424,6 +535,7 @@ public void returns() { class MyClass { int iFld; + static long lFldStatic; } class MyClassSub extends MyClass { int iFld; @@ -431,7 +543,7 @@ class MyClassSub extends MyClass { } enum FailType { - FAIL_ON + FAIL_ON, COUNTS } class Constraint { @@ -451,9 +563,9 @@ private Constraint(Class klass, String methodName, int ruleIdx, FailType fail this.failType = failType; this.methodPattern = Pattern.compile(Pattern.quote(classAndMethod)); if (failType == FailType.FAIL_ON) { - irPattern = Pattern.compile("rule " + ruleIdx + ":.*\\R.*Failure:.*contains forbidden node:"); + irPattern = Pattern.compile("rule " + ruleIdx + ":.*\\R.*Failing Regex.*\\R.*Failure:.*contains forbidden node\\(s\\):"); } else { - irPattern = null; // TODO + irPattern = Pattern.compile("rule " + ruleIdx + ":.*\\R.*Failing Regex.*\\R.*Failure:.*contains wrong number of nodes. Failed constraint:.*"); } this.shouldMatch = shouldMatch; this.matches = matches; @@ -485,6 +597,10 @@ public static Constraint failOnMatches(Class klass, String methodName, int ru return new Constraint(klass, methodName, ruleIdx, FailType.FAIL_ON, new ArrayList<>(Arrays.asList(matches)), shouldMatch); } + public static Constraint countsMatches(Class klass, String methodName, int ruleIdx, boolean shouldMatch) { + return new Constraint(klass, methodName, ruleIdx, FailType.COUNTS, new ArrayList<>(), shouldMatch); + } + public void checkConstraint(RuntimeException e) { String message = e.getMessage(); String[] splitMethods = message.split("Method"); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java index 0d150bfd699..6fc20ef519d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java @@ -26,20 +26,20 @@ public static void main(String[] args) { } @Test - @IR(applyIf={"SuspendRetryCount", "50"}, failOn={IRNode.RETURN}) + @IR(applyIf = {"SuspendRetryCount", "50"}, failOn = {IRNode.RETURN}) public void failDefault() { } @Test - @IR(applyIf={"SuspendRetryCount", "51"}, failOn={IRNode.RETURN}) - @IR(applyIf={"SuspendRetryCount", "53"}, failOn={IRNode.RETURN}) + @IR(applyIf = {"SuspendRetryCount", "51"}, failOn = {IRNode.RETURN}) + @IR(applyIf = {"SuspendRetryCount", "53"}, failOn = {IRNode.RETURN}) public void failS3() { } } class ScenarioTest { @Test - @IR(applyIf={"SuspendRetryCount", "54"}, failOn={IRNode.RETURN}) + @IR(applyIf = {"SuspendRetryCount", "54"}, failOn = {IRNode.RETURN}) public void doesNotFail() { } } From 11e7b5480efcd7b7ab1f3e609fd8103d77010fb3 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 25 Jan 2021 18:00:36 +0100 Subject: [PATCH 010/131] Minor cleanups --- .../valhalla/framework/TestFramework.java | 100 ++++++++---------- .../tests/TestWithHelperClasses.java | 2 +- 2 files changed, 48 insertions(+), 54 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 2bdbdd89cc5..57e8a25dfff 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -18,7 +18,6 @@ public class TestFramework { - public static final int DEFAULT_SCENARIOS = 6; private static final WhiteBox WHITE_BOX; static { @@ -35,8 +34,8 @@ public class TestFramework { } } - static final boolean TIERED_COMPILATION = (Boolean)WHITE_BOX.getVMFlag("TieredCompilation"); - static final CompLevel TIERED_COMPILATION_STOP_AT_LEVEL = CompLevel.forValue(((Long)WHITE_BOX.getVMFlag("TieredStopAtLevel")).intValue()); + private static final boolean TIERED_COMPILATION = (Boolean)WHITE_BOX.getVMFlag("TieredCompilation"); + private static final CompLevel TIERED_COMPILATION_STOP_AT_LEVEL = CompLevel.forValue(((Long)WHITE_BOX.getVMFlag("TieredStopAtLevel")).intValue()); static final boolean TEST_C1 = TIERED_COMPILATION && TIERED_COMPILATION_STOP_AT_LEVEL.getValue() < CompLevel.C2.getValue(); // User defined settings @@ -247,6 +246,29 @@ public static void run(Class testClass, List> helperClasses) { doRun(testClass, helperClasses); } + // Can be called from tests for non-@Test methods + public static void compile(Method m, CompLevel compLevel) { + TestFormat.check(getAnnotation(m, Test.class) == null, + "Cannot call enqueueMethodForCompilation() for @Test annotated method " + m); + enqueueMethodForCompilation(m, compLevel); + } + + public static boolean isC2Compiled(Method m) { + return WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) == CompLevel.C2.getValue(); +// return compiledByC2(m) == TriState.Yes; + } + + public static void assertDeoptimizedByC2(Method m) { + TestRun.check(compiledByC2(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized"); + } + + public static void assertCompiledByC2(Method m) { + TestRun.check(compiledByC2(m) != TriState.No, m + " should have been compiled"); + } + + public static String getLastVmOutput() { + return lastVmOutput; + } /* * End of public interface */ @@ -380,10 +402,6 @@ private void addBoolOptionForClass(ArrayList cmds, Class testClass, S cmds.add("-XX:CompileCommand=option," + testClass.getCanonicalName() + "::*,bool," + option + ",true"); } - public static String getLastVmOutput() { - return lastVmOutput; - } - private void parseTestClass(Class clazz) { addReplay(); processExplicitCompileCommands(clazz); @@ -467,11 +485,11 @@ private void applyForceCompileCommand(Method m) { } } - // Can be called from tests for non-@Test methods - public static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { - TestFormat.check(getAnnotation(m, Test.class) == null, - "Cannot call enqueueMethodForCompilation() for @Test annotated method " + m); - TestFrameworkUtils.enqueueMethodForCompilation(m, compLevel); + static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { + if (TestFramework.VERBOSE) { + System.out.println("enqueueMethodForCompilation " + m + ", level = " + compLevel); + } + WHITE_BOX.enqueueMethodForCompilation(m, compLevel.getValue()); } private void setupTests(Class clazz) { @@ -648,13 +666,13 @@ private void addCustomRunTest(Method m, Run runAnno) { allTests.put(m, customRunTest); } - public static T getAnnotation(Method m, Class c) { + private static T getAnnotation(Method m, Class c) { T[] annos = m.getAnnotationsByType(c); TestFormat.check(annos.length < 2, m + " has duplicated annotations"); return Arrays.stream(annos).findFirst().orElse(null); } - public void runTests() { + private void runTests() { TreeMap durations = (PRINT_TIMES || VERBOSE) ? new TreeMap<>() : null; long startTime = System.nanoTime(); Collection testCollection = allTests.values(); @@ -689,7 +707,7 @@ public void runTests() { } } - public static void check(boolean test, String failureMessage) { + static void check(boolean test, String failureMessage) { if (!test) { throw new TestFrameworkException("Internal TestFramework exception:\n" + failureMessage); } @@ -701,26 +719,13 @@ enum TriState { No } - public static boolean isC2Compiled(Method m) { - return WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) == CompLevel.C2.getValue(); -// return compiledByC2(m) == TriState.Yes; - } - - public static void assertDeoptimizedByC2(Method m) { - TestRun.check(compiledByC2(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized"); - } - - public static void assertCompiledByC2(Method m) { - TestRun.check(compiledByC2(m) != TriState.No, m + " should have been compiled"); - } - private static TriState compiledByC2(Method m) { // if (!TestFramework.USE_COMPILER || TestFramework.XCOMP || TestFramework.TEST_C1 || // (TestFramework.STRESS_CC && !WHITE_BOX.isMethodCompilable(m, CompLevel.C2.getValue(), false))) { // return TriState.Maybe; // } - if (WHITE_BOX.isMethodCompiled(m, false) && - WHITE_BOX.getMethodCompilationLevel(m, false) >= CompLevel.C2.getValue()) { + if (WHITE_BOX.isMethodCompiled(m, false) + && WHITE_BOX.getMethodCompilationLevel(m, false) >= CompLevel.C2.getValue()) { return TriState.Yes; } return TriState.No; @@ -739,10 +744,6 @@ public TestFrameworkException(String message, Exception e) { class DeclaredTest { private final Method testMethod; - public Method getTestMethod() { - return testMethod; - } - private final Argument[] arguments; private final int warmupIterations; private final CompLevel compLevel; @@ -758,6 +759,10 @@ public DeclaredTest(Method testMethod, Argument[] arguments, CompLevel compLevel this.osrOnly = osrOnly; } + public Method getTestMethod() { + return testMethod; + } + public CompLevel getCompLevel() { return compLevel; } @@ -807,7 +812,7 @@ public Object invoke(Object obj, Object... args) { } class BaseTest { - protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); private static final int OSR_TEST_TIMEOUT = Integer.parseInt(System.getProperty("OSRTestTimeOut", "5000")); protected final DeclaredTest test; @@ -833,6 +838,7 @@ public BaseTest(DeclaredTest test) { } } } + public String getTestName() { return testMethod.getName(); } @@ -918,12 +924,12 @@ private void retryDisabledVerifyOops(boolean stateCleared) { private void compileNormallyAndRun() { final boolean maybeCodeBufferOverflow = (TestFramework.TEST_C1 && TestFramework.VERIFY_OOPS); final Method testMethod = test.getTestMethod(); - TestFrameworkUtils.enqueueMethodForCompilation(test); + enqueueMethodForCompilation(); if (maybeCodeBufferOverflow && !WHITE_BOX.isMethodCompiled(testMethod, false)) { // Let's disable VerifyOops temporarily and retry. WHITE_BOX.setBooleanVMFlag("VerifyOops", false); WHITE_BOX.clearMethodState(testMethod); - TestFrameworkUtils.enqueueMethodForCompilation(test); + enqueueMethodForCompilation(); WHITE_BOX.setBooleanVMFlag("VerifyOops", true); } if (!TestFramework.STRESS_CC && TestFramework.USE_COMPILER) { @@ -940,6 +946,10 @@ private void compileNormallyAndRun() { runMethod(); } + private void enqueueMethodForCompilation() { + TestFramework.enqueueMethodForCompilation(test.getTestMethod(), test.getCompLevel()); + } + protected void checkCompilationLevel() { CompLevel level = CompLevel.forValue(WhiteBox.getWhiteBox().getMethodCompilationLevel(testMethod)); TestRun.check(level == test.getCompLevel(), @@ -1102,19 +1112,3 @@ public static > ParsedComparator parseComparator(Stri return new ParsedComparator<>(value, comparison); } } - -class TestFrameworkUtils { - private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); - - public static void enqueueMethodForCompilation(DeclaredTest test) { - enqueueMethodForCompilation(test.getTestMethod(), test.getCompLevel()); - } - - // Used for non-@Tests, can also be called from other places in tests. - public static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { - if (TestFramework.VERBOSE) { - System.out.println("enqueueMethodForCompilation " + m + ", level = " + compLevel); - } - WHITE_BOX.enqueueMethodForCompilation(m, compLevel.getValue()); - } -} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java index 187acfa2a80..5e7617344b4 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java @@ -5,7 +5,7 @@ public class TestWithHelperClasses { - public static void main(String[] args) throws NoSuchMethodException { + public static void main(String[] args) { TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class, Helper2.class); try { TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class); From 6f4be30ac50eeee04c69cc62bc655c4a9747603b Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 26 Jan 2021 14:41:49 +0100 Subject: [PATCH 011/131] Switch to bulk reporting for TestFormatExceptions instead of throwing immediately, started adding Bad tests, some refactorings --- .../compiler/valhalla/framework/Argument.java | 83 ++++++----- .../valhalla/framework/IREncodingPrinter.java | 17 ++- .../valhalla/framework/IRMatcher.java | 30 ++-- .../valhalla/framework/TestFormat.java | 24 +++- .../valhalla/framework/TestFramework.java | 126 ++++++++++------- .../framework/tests/TestBadFormat.java | 131 ++++++++++++++++++ .../valhalla/framework/tests/TestBasics.java | 23 ++- .../framework/tests/TestScenarios.java | 11 +- 8 files changed, 326 insertions(+), 119 deletions(-) create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java index 3c059ff57b1..b5c5253a536 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java @@ -2,6 +2,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import java.lang.reflect.Parameter; import java.util.Random; class Argument { @@ -45,54 +46,52 @@ public static Argument[] getArguments(Method m) { ArgumentValue[] values = argumentsAnno.value(); Argument[] arguments = new Argument[values.length]; Class[] declaredParameters = m.getParameterTypes(); + Parameter[] declaredParameterObjects = m.getParameters(); TestFormat.check(values.length == declaredParameters.length, "Number of argument values provided in @Arguments does not match the number of actual arguments in " + m); for (int i = 0; i < values.length; i++) { ArgumentValue specifiedArg = values[i]; Class parameter = declaredParameters[i]; - switch (specifiedArg) { - case DEFAULT -> arguments[i] = createDefault(parameter); - case NUMBER_42 -> { - TestFormat.check(isNumber(parameter), - "Provided invalid NUMBER_42 argument for non-number " + parameter + " for " + m); - arguments[i] = create((byte) 42); - } - case NUMBER_MINUS_42 -> { - TestFormat.check(isNumber(parameter), - "Provided invalid NUMBER_MINUS_42 argument for non-number " + parameter + " for " + m); - arguments[i] = create((byte) -42); - } - case BOOLEAN_TOGGLE_FIRST_FALSE -> { - TestFormat.check(isBoolean(parameter), - "Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + parameter + " for " + m); - arguments[i] = createToggleBoolean(false); - } - case BOOLEAN_TOGGLE_FIRST_TRUE -> { - TestFormat.check(Argument.isBoolean(parameter), - "Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + parameter + " for " + m); - arguments[i] = createToggleBoolean(true); - } - case TRUE -> { - TestFormat.check(Argument.isBoolean(parameter), - "Provided invalid TRUE argument for non-boolean " + parameter + " for " + m); - arguments[i] = create(true); - } - case FALSE -> { - TestFormat.check(Argument.isBoolean(parameter), - "Provided invalid FALSE argument for non-boolean " + parameter + " for " + m); - arguments[i] = create(false); - } - case RANDOM_ONCE -> { - TestFormat.check(isPrimitiveType(parameter), - "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameter + " for " + m); - arguments[i] = createRandom(parameter); - } - case RANDOM_EACH -> { - TestFormat.check(isPrimitiveType(parameter), - "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameter + " for " + m); - arguments[i] = createRandomEach(parameter); + Parameter parameterObj = declaredParameterObjects[i]; + try { + switch (specifiedArg) { + case DEFAULT -> arguments[i] = createDefault(parameter); + case NUMBER_42 -> { + TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_42 argument for non-number " + parameterObj + " for " + m); + arguments[i] = create((byte) 42); + } + case NUMBER_MINUS_42 -> { + TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_MINUS_42 argument for non-number " + parameterObj + " for " + m); + arguments[i] = create((byte) -42); + } + case BOOLEAN_TOGGLE_FIRST_FALSE -> { + TestFormat.check(isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + parameterObj + " for " + m); + arguments[i] = createToggleBoolean(false); + } + case BOOLEAN_TOGGLE_FIRST_TRUE -> { + TestFormat.check(Argument.isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + parameterObj + " for " + m); + arguments[i] = createToggleBoolean(true); + } + case TRUE -> { + TestFormat.check(Argument.isBoolean(parameter), "Provided invalid TRUE argument for non-boolean " + parameterObj + " for " + m); + arguments[i] = create(true); + } + case FALSE -> { + TestFormat.check(Argument.isBoolean(parameter), "Provided invalid FALSE argument for non-boolean " + parameterObj + " for " + m); + arguments[i] = create(false); + } + case RANDOM_ONCE -> { + TestFormat.check(isPrimitiveType(parameter), "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameterObj + " for " + m); + arguments[i] = createRandom(parameter); + } + case RANDOM_EACH -> { + TestFormat.check(isPrimitiveType(parameter), "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameterObj + " for " + m); + arguments[i] = createRandomEach(parameter); + } } + } catch (TestFormatException e) { + // Catch and continue to check arguments. } } return arguments; @@ -116,7 +115,7 @@ private static Argument createDefault(Class c) { constructor.setAccessible(true); return Argument.create(constructor.newInstance()); } catch (Exception e) { - TestFormat.fail("Cannot create new default instance of " + c, e); + TestFormat.fail("Cannot create new default instance of " + c + ": " + e.getCause()); return null; } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java index c197fdc8c2d..ec84deac2e9 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java @@ -7,7 +7,6 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; -import java.util.function.BiPredicate; import java.util.function.Function; // Only used by TestVM @@ -139,15 +138,17 @@ private boolean check(Method m, String flag, String value) { .findAny().orElse(null); if (actualFlagValue != null) { long actualLongFlagValue = (Long) actualFlagValue; - long longValue = 0; - ParsedComparator parsedComparator = null; + long longValue; + ParsedComparator parsedComparator ; try { parsedComparator = ParsedComparator.parseComparator(value); longValue = Long.parseLong(parsedComparator.getStrippedString()); } catch (NumberFormatException e) { TestFormat.fail("Invalid value " + value + " for number based flag " + flag); + return false; } catch (Exception e) { - TestFormat.fail("Invalid comparator in \"" + value + "\" for number based flag " + flag, e); + TestFormat.fail("Invalid comparator in \"" + value + "\" for number based flag " + flag + ": " + e.getCause()); + return false; } return parsedComparator.getPredicate().test(actualLongFlagValue, longValue); } @@ -165,15 +166,17 @@ private boolean check(Method m, String flag, String value) { actualFlagValue = WHITE_BOX.getDoubleVMFlag(flag); if (actualFlagValue != null) { double actualDoubleFlagValue = (Double) actualFlagValue; - double doubleValue = 0; - ParsedComparator parsedComparator = null; + double doubleValue; + ParsedComparator parsedComparator; try { parsedComparator = ParsedComparator.parseComparator(value); doubleValue = Double.parseDouble(parsedComparator.getStrippedString()); } catch (NumberFormatException e) { TestFormat.fail("Invalid value " + value + " for number based flag " + flag); + return false; } catch (Exception e) { - TestFormat.fail("Invalid comparator in \"" + value + "\" for number based flag " + flag, e); + TestFormat.fail("Invalid comparator in \"" + value + "\" for number based flag " + flag + ": " + e.getCause()); + return false; } return parsedComparator.getPredicate().test(actualDoubleFlagValue, doubleValue); } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java index 4db7634c174..aa7c7a95c32 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java @@ -84,7 +84,6 @@ public void applyRules() { for (Method m : testClass.getDeclaredMethods()) { IR[] irAnnos = m.getAnnotationsByType(IR.class); if (irAnnos.length > 0) { - TestFormat.check(m.isAnnotationPresent(Test.class), "Found @IR annotation at non-@Test method " + m); Integer[] ids = irRulesMap.get(m.getName()); TestFramework.check(ids != null, "Should find method name in validIrRulesMap for " + m); TestFramework.check(ids.length > 0, "Did not find any rule indices for " + m); @@ -95,16 +94,24 @@ public void applyRules() { } } } + reportFailuresIfAny(); + } + + private void reportFailuresIfAny() { if (!fails.isEmpty()) { - StringBuilder builder = new StringBuilder("\n"); - builder.append("One or more @IR rules failed:\n"); - builder.append("-----------------------------\n"); - fails.forEach((method, list) -> { + StringBuilder builder = new StringBuilder(); + int failures = 0; + for (Map.Entry> entry : fails.entrySet()) { + Method method = entry.getKey(); + List list = entry.getValue(); builder.append("- Method \"").append(method).append("\":\n"); + failures += list.size(); list.forEach(s -> builder.append(" * ").append(s.replace("\n", "\n ").trim()).append("\n")); builder.append("\n"); - }); - builder.append("\n"); + } + builder.insert(0, "------------\n"); + builder.insert(0, "Failures (" + failures + ")\n"); + builder.insert(0, ("\nOne or more @IR rules failed:\n\n")); Asserts.fail(builder.toString()); } } @@ -140,16 +147,17 @@ private void applyCount(Method m, String testOutput, IR irAnno, int annoId) { String node = nodesWithCount.get(i); TestFormat.check(i + 1 < nodesWithCount.size(), "Missing count for IR node \"" + node + "\" at " + m); String countString = nodesWithCount.get(i + 1); - long expectedCount = 0; - - ParsedComparator parsedComparator = null; + long expectedCount; + ParsedComparator parsedComparator; try { parsedComparator = ParsedComparator.parseComparator(countString); expectedCount = Long.parseLong(parsedComparator.getStrippedString()); } catch (NumberFormatException e) { TestFormat.fail("Provided invalid count \"" + countString + "\" for IR node \"" + node + "\" at " + m); + return; } catch (Exception e) { - TestFormat.fail("Invalid comparator in \"" + countString + "\" for count of node " + node, e); + TestFormat.fail("Invalid comparator in \"" + countString + "\" for count of node " + node + ": " + e.getCause()); + return; } TestFormat.check(expectedCount >= 0,"Provided invalid negative count \"" + countString + "\" for IR node \"" + node + "\" at " + m); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java index 48b5c2d8042..bcd5f180546 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java @@ -1,16 +1,36 @@ package compiler.valhalla.framework; +import java.util.ArrayList; +import java.util.List; + public class TestFormat { + private static final List FAILURES = new ArrayList<>(); + public static void check(boolean test, String failureMessage) { if (!test) { + FAILURES.add(failureMessage); throw new TestFormatException(failureMessage); } } + public static void fail(String failureMessage) { + FAILURES.add(failureMessage); throw new TestFormatException(failureMessage); } - public static void fail(String failureMessage, Exception e) { - throw new TestFormatException(failureMessage, e); + public static void reportIfAnyFailures() { + if (FAILURES.isEmpty()) { + // No format violation detected. + return; + } + StringBuilder builder = new StringBuilder(); + builder.append("One or more format violations have been detected:\n\n"); + builder.append("Violations (").append(FAILURES.size()).append(")\n"); + builder.append("--------------\n"); + for (String failure : FAILURES) { + builder.append(" - ").append(failure).append("\n"); + } + FAILURES.clear(); + throw new TestFormatException(builder.toString()); } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 57e8a25dfff..ea0aa31573c 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -248,7 +248,7 @@ public static void run(Class testClass, List> helperClasses) { // Can be called from tests for non-@Test methods public static void compile(Method m, CompLevel compLevel) { - TestFormat.check(getAnnotation(m, Test.class) == null, + TestRun.check(getAnnotation(m, Test.class) == null, "Cannot call enqueueMethodForCompilation() for @Test annotated method " + m); enqueueMethodForCompilation(m, compLevel); } @@ -285,19 +285,18 @@ private void runTestsOnSameVM(Class testClass, ArrayList> helperClas // Process the helper classes and apply the explicit compile commands processExplicitCompileCommands(helperClass); } - runTestsOnSameVM(testClass); - } - - private void runTestsOnSameVM(Class testClass) { parseTestClass(testClass); runTests(); } // Only called by tests testing the framework itself. Accessed by reflection. Do not expose this to normal users. - private static void runTestsOnSameVM() { - StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + private static void runTestsOnSameVM(Class testClass) { + if (testClass == null) { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + testClass = walker.getCallerClass(); + } TestFramework framework = new TestFramework(); - framework.runTestsOnSameVM(walker.getCallerClass()); + framework.runTestsOnSameVM(testClass, new ArrayList<>()); } private void runTestVM(Class testClass, List> helperClasses, Scenario scenario) { @@ -409,11 +408,24 @@ private void parseTestClass(Class clazz) { setupCheckAndRunMethods(clazz); // All remaining tests are simple base tests without check or specific way to run them - declaredTests.forEach((key, value) -> allTests.put(key, new BaseTest(value))); + addBaseTests(); + TestFormat.reportIfAnyFailures(); declaredTests.clear(); testMethodMap.clear(); } + private void addBaseTests() { + declaredTests.forEach((m, test) -> { + try { + Arguments argumentsAnno = getAnnotation(m, Arguments.class); + TestFormat.check(argumentsAnno != null || m.getParameterCount() == 0, "Missing @Arguments annotation to define arguments of " + m); + allTests.put(m, new BaseTest(test)); + } catch (TestFormatException e) { + // Failure logged. Continue and report later. + } + }); + } + private void addReplay() { if (DUMP_REPLAY) { // Generate replay compilation files @@ -426,12 +438,20 @@ private void processExplicitCompileCommands(Class clazz) { if (USE_COMPILE_COMMAND_ANNOTATIONS) { Method[] methods = clazz.getDeclaredMethods(); for (Method m : methods) { - applyIndependentCompilationCommands(m); + try { + applyIndependentCompilationCommands(m); + } catch (TestFormatException e) { + // Failure logged. Continue and report later. + } } // Only force compilation now because above annotations affect inlining for (Method m : methods) { - applyForceCompileCommand(m); + try { + applyForceCompileCommand(m); + } catch (TestFormatException e) { + // Failure logged. Continue and report later. + } } } } @@ -444,13 +464,8 @@ private void applyIndependentCompilationCommands(Method m) { Test testAnno = getAnnotation(m, Test.class); TestFormat.check(testAnno == null || Stream.of(forceCompileAnno, dontCompileAnno, forceInlineAnno, dontInlineAnno).noneMatch(Objects::nonNull), "Not allowed to use explicit compile command annotations (@ForceInline, @DontInline," + - "@ForceCompile or @DontCompile) together with @Test at " + m + ". Use compLevel and skip in @Test for fine tuning."); - if (Stream.of(forceCompileAnno, dontCompileAnno, dontInlineAnno).filter(Objects::nonNull).count() > 1) { - // Failure - TestFormat.check(dontCompileAnno == null || dontInlineAnno == null, - "@DontInline is implicitely done with @DontCompile annotation at " + m); - TestFormat.fail("Cannot mix @ForceInline, @DontInline and @DontCompile at the same time at " + m); - } + "@ForceCompile or @DontCompile) together with @Test at " + m + ". Use compLevel in @Test for fine tuning."); + TestFormat.check(forceInlineAnno == null || dontInlineAnno == null, "Cannot have @ForceInline and @DontInline at the same time at " + m); TestFormat.check(forceCompileAnno == null || dontCompileAnno == null, "Cannot have @ForceCompile and @DontCompile at the same time at " + m); // First handle inline annotations @@ -497,16 +512,20 @@ private void setupTests(Class clazz) { boolean hasExcludeList = excludeList != null; for (Method m : clazz.getDeclaredMethods()) { Test testAnno = getAnnotation(m, Test.class); - if (testAnno != null) { - if (hasIncludeList && includeList.contains(m.getName()) && (!hasExcludeList || !excludeList.contains(m.getName()))) { - addTest(m); - } else if (hasExcludeList && !excludeList.contains(m.getName())) { - addTest(m); + try { + if (testAnno != null) { + if (hasIncludeList && includeList.contains(m.getName()) && (!hasExcludeList || !excludeList.contains(m.getName()))) { + addTest(m); + } else if (hasExcludeList && !excludeList.contains(m.getName())) { + addTest(m); + } else { + addTest(m); + } } else { - addTest(m); + TestFormat.check(!m.isAnnotationPresent(IR.class), "Found @IR annotation on non-@Test method " + m); } - } else { - TestFormat.check(!m.isAnnotationPresent(IR.class), "Found @IR annotation on non-@Test method " + m); + } catch (TestFormatException e) { + // Failure logged. Continue and report later. } } if (PRINT_VALID_IR_RULES) { @@ -515,18 +534,8 @@ private void setupTests(Class clazz) { } private void addTest(Method m) { - TestFormat.check(!testMethodMap.containsKey(m.getName()), - "Cannot overload two @Test methods " + m + " and " + testMethodMap.get(m.getName())); Test testAnno = getAnnotation(m, Test.class); - TestFormat.check(testAnno != null, m + " must be a method with a @Test annotation"); - - Check checkAnno = getAnnotation(m, Check.class); - Run runAnno = getAnnotation(m, Run.class); - TestFormat.check(checkAnno == null && runAnno == null, - m + " has invalid @Check or @Run annotation while @Test annotation is present."); - - TestFormat.check(!Arrays.asList(m.getParameterTypes()).contains(TestInfo.class), - "Forbidden use of " + TestInfo.class + " as parameter at @Test method " + m); + checkTestAnnotations(m, testAnno); Warmup warmup = getAnnotation(m, Warmup.class); int warmupIterations = WARMUP_ITERATIONS; @@ -551,6 +560,20 @@ private void addTest(Method m) { testMethodMap.put(m.getName(), m); } + private void checkTestAnnotations(Method m, Test testAnno) { + TestFormat.check(!testMethodMap.containsKey(m.getName()), + "Cannot overload two @Test methods " + m + " and " + testMethodMap.get(m.getName())); + TestFormat.check(testAnno != null, m + " must be a method with a @Test annotation"); + + Check checkAnno = getAnnotation(m, Check.class); + Run runAnno = getAnnotation(m, Run.class); + TestFormat.check(checkAnno == null && runAnno == null, + m + " has invalid @Check or @Run annotation while @Test annotation is present."); + + TestFormat.check(!Arrays.asList(m.getParameterTypes()).contains(TestInfo.class), + "Forbidden use of " + TestInfo.class + " as parameter at @Test method " + m); + } + // Get the appropriate level as permitted by the test scenario and VM options. private static CompLevel restrictCompLevel(CompLevel compLevel) { @@ -587,12 +610,15 @@ private void setupCheckAndRunMethods(Class clazz) { Check checkAnno = getAnnotation(m, Check.class); Run runAnno = getAnnotation(m, Run.class); Arguments argumentsAnno = getAnnotation(m, Arguments.class); - TestFormat.check(argumentsAnno == null || (checkAnno == null && runAnno == null), - "Cannot have @Argument annotation in combination with @Run or @Check at " + m); - if (checkAnno != null) { - addCheckedTest(m, checkAnno, runAnno); - } else if (runAnno != null) { - addCustomRunTest(m, runAnno); + try { + TestFormat.check(argumentsAnno == null || (checkAnno == null && runAnno == null), "Cannot have @Argument annotation in combination with @Run or @Check at " + m); + if (checkAnno != null) { + addCheckedTest(m, checkAnno, runAnno); + } else if (runAnno != null) { + addCustomRunTest(m, runAnno); + } + } catch (TestFormatException e) { + // Failure logged. Continue and report later. } } } @@ -630,24 +656,26 @@ private void addCheckedTest(Method m, Check checkAnno, Run runAnno) { DeclaredTest test = declaredTests.remove(testMethod); TestFormat.check(test != null, "Missing @Test annotation for associated test method " + checkAnno.test() + " for @Check at " + m); - applyCompileCommands(m); + applyCompileCommands(m, false); // Don't inline check methods WHITE_BOX.testSetDontInlineMethod(m, true); CheckedTest checkedTest = new CheckedTest(test, m, checkAnno, parameter); allTests.put(testMethod, checkedTest); } - private void applyCompileCommands(Method m) { + private void applyCompileCommands(Method m, boolean defaultDontCompile) { ForceInline forceInlineAnno = getAnnotation(m, ForceInline.class); DontInline dontInlineAnno = getAnnotation(m, DontInline.class); ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); DontCompile dontCompileAnno = getAnnotation(m, DontCompile.class); - if (Stream.of(forceCompileAnno, dontCompileAnno, forceCompileAnno, dontInlineAnno).anyMatch(Objects::nonNull)) { + if (Stream.of(forceCompileAnno, dontCompileAnno, forceInlineAnno, dontInlineAnno).anyMatch(Objects::nonNull)) { applyIndependentCompilationCommands(m); applyForceCompileCommand(m); } else { - // Implicitely @DontCompile if nothing specified - dontCompileMethod(m); + if (defaultDontCompile) { + // @DontCompile if nothing specified. Done for @Run. + dontCompileMethod(m); + } } } @@ -659,7 +687,7 @@ private void addCustomRunTest(Method m, Run runAnno) { TestFormat.check(!test.hasArguments(), "Invalid @Arguments annotation for associated test method " + runAnno.test() + " for @Run at " + m); TestFormat.check(m.getParameterCount() == 0 || (m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(TestInfo.class)), "@Run method " + m + " must specify either no TestInfo parameter or exactly one"); - applyCompileCommands(m); + applyCompileCommands(m, true); // Don't inline run methods WHITE_BOX.testSetDontInlineMethod(m, true); CustomRunTest customRunTest = new CustomRunTest(test, m, runAnno); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java new file mode 100644 index 00000000000..3b4ee809497 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java @@ -0,0 +1,131 @@ +package compiler.valhalla.framework.tests; + +import compiler.valhalla.framework.*; +import jdk.test.lib.Asserts; + +import java.lang.reflect.Method; + +public class TestBadFormat { + + private static Method runTestsOnSameVM; + public static void main(String[] args) throws NoSuchMethodException { + runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); + runTestsOnSameVM.setAccessible(true); + expectTestFormatException(BadArguments.class); + expectTestFormatException(BadOverloadedMethod.class); + expectTestFormatException(BadCompilerControl.class); +// expectTestFormatException(BadWarmup.class); + } + + private static void expectTestFormatException(Class clazz) { + try { + runTestsOnSameVM.invoke(null, clazz); + } catch (Exception e) { + Throwable cause = e.getCause(); + if (cause != null) { + System.out.println(cause.getMessage()); + } + Asserts.assertTrue(cause instanceof TestFormatException, "Unexpected exception: " + cause); + String msg = cause.getMessage(); + Asserts.assertTrue(msg.contains("Violations")); + return; + } + throw new RuntimeException("Should catch an exception"); + } +} + +class BadArguments { + + @Test + public void noArgAnnotation(int a) {} + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void argNumberMismatch(int a, int b) {} + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void argNumberMismatch2() {} + + @Test + @Arguments(ArgumentValue.NUMBER_42) + public void notBoolean(boolean a) {} + + @Test + @Arguments(ArgumentValue.NUMBER_MINUS_42) + public void notBoolean2(boolean a) {} + + @Test + @Arguments(ArgumentValue.TRUE) + public void notNumber(int a) {} + + @Test + @Arguments(ArgumentValue.FALSE) + public void notNumber2(int a) {} + + @Test + @Arguments(ArgumentValue.BOOLEAN_TOGGLE_FIRST_TRUE) + public void notNumber3(int a) {} + + @Test + @Arguments(ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE) + public void notNumber4(int a) {} + + @Test + @Arguments({ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE, ArgumentValue.TRUE}) + public void notNumber5(boolean a, int b) {} + + + @Test + @Arguments({ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE, ArgumentValue.NUMBER_42}) + public void notNumber6(int a, boolean b) {} +} + +class BadOverloadedMethod { + + @Test + public void sameName() {} + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void sameName(boolean a) {} + + @Test + @Arguments(ArgumentValue.DEFAULT) + public void sameName(double a) {} +} + +class BadCompilerControl { + + @Test + @DontCompile + public void test1() {} + + @Test + @ForceCompile + public void test2() {} + + @Test + @DontInline + public void test3() {} + + @Test + @ForceInline + public void test4() {} + + @Test + @ForceInline + @ForceCompile + @DontInline + @DontCompile + public void test5() {} + + @DontInline + @ForceInline + public void mix1() {} + + @DontCompile + @ForceCompile + public void mix2() {} +} + diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java index e3d0934658f..b413a6650c1 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -9,9 +9,9 @@ public class TestBasics { public static void main(String[] args) throws Exception { // Run on same VM to make this test easier as we are not interested in any output processing. - Method runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM"); + Method runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); - runTestsOnSameVM.invoke(null); + runTestsOnSameVM.invoke(null, new Object[]{ null }); if (wasExecuted) { throw new RuntimeException("Executed non @Test method or a method that was not intended to be run"); @@ -73,7 +73,7 @@ public static void main(String[] args) throws Exception { // } static boolean wasExecuted = false; - static int[] testExecuted = new int[76]; + static int[] testExecuted = new int[78]; static int[] checkExecuted = new int[5]; boolean lastToggleBoolean = true; long[] nonFloatingRandomNumbers = new long[10]; @@ -702,7 +702,7 @@ public void runTestRun(TestInfo info) { } @Test - public void testRunNoTestInfo(int i) { + public void testRunNoTestInfo(int i) { // Argument allowed when run by @Run testExecuted[62]++; } @@ -844,6 +844,21 @@ public void runTestRunOnce2(TestInfo info) { testRunOnce2(); } } + + @Test + public void sameName() { + testExecuted[76]++; + } + + // Allowed to overload test method if not test method itself + public void sameName(boolean a) { + wasExecuted = true; + } + + @Check(test="sameName") + public void checkSameName() { + testExecuted[77]++; + } } class DefaultObject { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java index 6fc20ef519d..cf38e16506f 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java @@ -3,20 +3,23 @@ import compiler.valhalla.framework.*; import jdk.test.lib.Asserts; -// Run test with SuspendRetryCount=50 public class TestScenarios { - public static final String[] TEST_KEYS = { "test-key0", "test-key1" }; - public static void main(String[] args) { Scenario s1 = new Scenario(1, "-XX:SuspendRetryCount=51"); Scenario s2 = new Scenario(2, "-XX:SuspendRetryCount=52"); Scenario s3 = new Scenario(3, "-XX:SuspendRetryCount=53"); Scenario s3dup = new Scenario(3, "-XX:SuspendRetryCount=53"); try { - TestFramework.runWithScenarios(s1, s2, s3); + TestFramework.runWithScenarios(Scenario.Run.INCLUDE_DEFAULT, s1, s2, s3); } catch (TestRunException e) { Asserts.assertTrue(e.getMessage().contains("The following scenarios have failed: #1, #3, #Default Scenario")); } + try { + TestFramework.runWithScenarios(s1, s2, s3); // Default scenario excluded by default. + } catch (TestRunException e) { + Asserts.assertTrue(e.getMessage().contains("The following scenarios have failed: #1, #3")); + } + TestFramework.runWithScenarios(ScenarioTest.class, s1, s2, s3); try { TestFramework.runWithScenarios(s1, s3dup, s2, s3); From ab5de84ab59887ceb89f622797efb4109af7492a Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 26 Jan 2021 18:05:00 +0100 Subject: [PATCH 012/131] Fix @Warmup and @DontCompile, add compile commands tests and more Bad tests --- .../valhalla/framework/CompileOnly.java | 9 -- .../valhalla/framework/DontCompile.java | 1 + .../valhalla/framework/ForceCompile.java | 2 +- .../valhalla/framework/TestFormat.java | 6 + .../valhalla/framework/TestFramework.java | 116 +++++++++++--- .../compiler/valhalla/framework/TestInfo.java | 42 ++--- .../framework/tests/TestBadFormat.java | 21 ++- .../framework/tests/TestCompLevels.java | 9 +- .../framework/tests/TestControls.java | 149 ++++++++++++++++++ 9 files changed, 294 insertions(+), 61 deletions(-) delete mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompileOnly.java create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompileOnly.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompileOnly.java deleted file mode 100644 index fb1aee0ede5..00000000000 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompileOnly.java +++ /dev/null @@ -1,9 +0,0 @@ -package compiler.valhalla.framework; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -// -@Retention(RetentionPolicy.RUNTIME) -public @interface CompileOnly { -} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java index 9f22f208ece..5b8c742d9b3 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java @@ -6,4 +6,5 @@ // Prevent method compilation @Retention(RetentionPolicy.RUNTIME) public @interface DontCompile { + CompLevel[] value() default {}; } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java index 7376188a795..aaebe8d92c8 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java @@ -6,5 +6,5 @@ // Force method compilation @Retention(RetentionPolicy.RUNTIME) public @interface ForceCompile { - CompLevel value() default CompLevel.ANY; + CompLevel value() default CompLevel.C2; } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java index bcd5f180546..e476f472497 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java @@ -13,6 +13,12 @@ public static void check(boolean test, String failureMessage) { } } + public static void checkNoThrow(boolean test, String failureMessage) { + if (!test) { + FAILURES.add(failureMessage); + } + } + public static void fail(String failureMessage) { FAILURES.add(failureMessage); throw new TestFormatException(failureMessage); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index ea0aa31573c..48e8a6ddfd1 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -266,6 +266,15 @@ public static void assertCompiledByC2(Method m) { TestRun.check(compiledByC2(m) != TriState.No, m + " should have been compiled"); } + public static void assertCompiledAtLevel(Method m, CompLevel level) { + TestRun.check(isCompiledAtLevel(m, level), m + " should have been compiled at level " + level.name()); + } + + public static void assertNotCompiled(Method m) { + TestRun.check(!WHITE_BOX.isMethodCompiled(m, false) && !WHITE_BOX.isMethodCompiled(m, true), + m + " should not have been compiled"); + } + public static String getLastVmOutput() { return lastVmOutput; } @@ -461,13 +470,7 @@ private void applyIndependentCompilationCommands(Method m) { DontInline dontInlineAnno = getAnnotation(m, DontInline.class); ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); DontCompile dontCompileAnno = getAnnotation(m, DontCompile.class); - Test testAnno = getAnnotation(m, Test.class); - TestFormat.check(testAnno == null || Stream.of(forceCompileAnno, dontCompileAnno, forceInlineAnno, dontInlineAnno).noneMatch(Objects::nonNull), - "Not allowed to use explicit compile command annotations (@ForceInline, @DontInline," + - "@ForceCompile or @DontCompile) together with @Test at " + m + ". Use compLevel in @Test for fine tuning."); - TestFormat.check(forceInlineAnno == null || dontInlineAnno == null, "Cannot have @ForceInline and @DontInline at the same time at " + m); - TestFormat.check(forceCompileAnno == null || dontCompileAnno == null, - "Cannot have @ForceCompile and @DontCompile at the same time at " + m); + checkCompilationCommandAnnotations(m, forceInlineAnno, dontInlineAnno, forceCompileAnno, dontCompileAnno); // First handle inline annotations if (dontInlineAnno != null) { WHITE_BOX.testSetDontInlineMethod(m, true); @@ -475,7 +478,13 @@ private void applyIndependentCompilationCommands(Method m) { WHITE_BOX.testSetForceInlineMethod(m, true); } if (dontCompileAnno != null) { - dontCompileMethod(m); + if (dontCompileAnno.value().length == 0) { + dontCompileMethod(m); + } else { + for (CompLevel compLevel : dontCompileAnno.value()) { + dontCompileMethodAtLevel(m, compLevel); + } + } } if (STRESS_CC) { @@ -487,12 +496,49 @@ private void applyIndependentCompilationCommands(Method m) { } } + private void checkCompilationCommandAnnotations(Method m, ForceInline forceInlineAnno, DontInline dontInlineAnno, ForceCompile forceCompileAnno, DontCompile dontCompileAnno) { + Test testAnno = getAnnotation(m, Test.class); + TestFormat.check(testAnno == null || Stream.of(forceCompileAnno, dontCompileAnno, forceInlineAnno, dontInlineAnno).noneMatch(Objects::nonNull), + "Not allowed to use explicit compile command annotations (@ForceInline, @DontInline," + + "@ForceCompile or @DontCompile) together with @Test at " + m + ". Use compLevel in @Test for fine tuning."); + if (Stream.of(forceInlineAnno, dontCompileAnno, dontInlineAnno).filter(Objects::nonNull).count() > 1) { + // Failure + TestFormat.check(dontCompileAnno == null || dontInlineAnno == null, + "@DontInline is implicitely done with @DontCompile annotation at " + m); + TestFormat.fail("Cannot mix @ForceInline, @DontInline and @DontCompile at the same time at " + m); + } + TestFormat.check(forceInlineAnno == null || dontInlineAnno == null, "Cannot have @ForceInline and @DontInline at the same time at " + m); + if (forceCompileAnno != null && dontCompileAnno != null) { + CompLevel forceCompile = forceCompileAnno.value(); + CompLevel[] dontCompile = dontCompileAnno.value(); + TestFormat.check(dontCompile.length != 0, + "Cannot have @ForceCompile and default @DontCompile (exclude all) at the same time at " + m); + TestFormat.check(forceCompile != CompLevel.ANY, + "Cannot have @ForceCompile with ANY and @DontCompile at the same time at " + m); + TestFormat.check(Arrays.stream(dontCompile).noneMatch(a -> a == forceCompile), + "Overlapping compilation levels with @ForceCompile and @DontCompile at " + m); + } + TestFormat.check(forceCompileAnno == null || dontCompileAnno == null, + "Cannot have @ForceCompile and @DontCompile at the same time at " + m); + } + private void dontCompileMethod(Method m) { WHITE_BOX.makeMethodNotCompilable(m, CompLevel.ANY.getValue(), true); WHITE_BOX.makeMethodNotCompilable(m, CompLevel.ANY.getValue(), false); WHITE_BOX.testSetDontInlineMethod(m, true); } + private void dontCompileMethodAtLevel(Method m, CompLevel compLevel) { + if (VERBOSE) { + System.out.println("dontCompileMethodAtLevel " + m + " , level = " + compLevel.name()); + } + WHITE_BOX.makeMethodNotCompilable(m, compLevel.getValue(), true); + WHITE_BOX.makeMethodNotCompilable(m, compLevel.getValue(), false); + if (compLevel == CompLevel.ANY) { + WHITE_BOX.testSetDontInlineMethod(m, true); + } + } + private void applyForceCompileCommand(Method m) { ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); if (forceCompileAnno != null) { @@ -504,6 +550,7 @@ static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { if (TestFramework.VERBOSE) { System.out.println("enqueueMethodForCompilation " + m + ", level = " + compLevel); } + compLevel = restrictCompLevel(compLevel); WHITE_BOX.enqueueMethodForCompilation(m, compLevel.getValue()); } @@ -522,7 +569,9 @@ private void setupTests(Class clazz) { addTest(m); } } else { - TestFormat.check(!m.isAnnotationPresent(IR.class), "Found @IR annotation on non-@Test method " + m); + TestFormat.checkNoThrow(!m.isAnnotationPresent(IR.class), "Found @IR annotation on non-@Test method " + m); + TestFormat.checkNoThrow(!m.isAnnotationPresent(Warmup.class) || getAnnotation(m, Run.class) != null, + "Found @Warmup annotation on non-@Test or non-@Run method " + m); } } catch (TestFormatException e) { // Failure logged. Continue and report later. @@ -541,6 +590,7 @@ private void addTest(Method m) { int warmupIterations = WARMUP_ITERATIONS; if (warmup != null) { warmupIterations = warmup.value(); + TestFormat.check(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + m); } boolean osrOnly = getAnnotation(m, OSROnly.class) != null; @@ -554,7 +604,6 @@ private void addTest(Method m) { if (FLIP_C1_C2) { compLevel = flipCompLevel(compLevel); } - compLevel = restrictCompLevel(compLevel); DeclaredTest test = new DeclaredTest(m, Argument.getArguments(m), compLevel, warmupIterations, osrOnly); declaredTests.put(m, test); testMethodMap.put(m.getName(), m); @@ -681,19 +730,29 @@ private void applyCompileCommands(Method m, boolean defaultDontCompile) { private void addCustomRunTest(Method m, Run runAnno) { Method testMethod = testMethodMap.get(runAnno.test()); - TestFormat.check(testMethod != null, "Did not find associated test method " + runAnno.test() + " for @Run at " + m); DeclaredTest test = declaredTests.remove(testMethod); - TestFormat.check(test != null, "Missing @Test annotation for associated test method " + runAnno.test() + " for @Run at " + m); - TestFormat.check(!test.hasArguments(), "Invalid @Arguments annotation for associated test method " + runAnno.test() + " for @Run at " + m); - TestFormat.check(m.getParameterCount() == 0 || (m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(TestInfo.class)), - "@Run method " + m + " must specify either no TestInfo parameter or exactly one"); + checkCustomRunTest(m, runAnno, testMethod, test); applyCompileCommands(m, true); // Don't inline run methods WHITE_BOX.testSetDontInlineMethod(m, true); - CustomRunTest customRunTest = new CustomRunTest(test, m, runAnno); + CustomRunTest customRunTest = new CustomRunTest(test, m, getAnnotation(m, Warmup.class), runAnno); allTests.put(m, customRunTest); } + private void checkCustomRunTest(Method m, Run runAnno, Method testMethod, DeclaredTest test) { + TestFormat.check(testMethod != null, "Did not find associated test method " + runAnno.test() + " for @Run at " + m); + TestFormat.check(test != null, "Missing @Test annotation for associated test method " + runAnno.test() + " for @Run at " + m); + TestFormat.check(!test.hasArguments(), "Invalid @Arguments annotation for associated test method " + runAnno.test() + " for @Run at " + m); + TestFormat.check(m.getParameterCount() == 0 || (m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(TestInfo.class)), + "@Run method " + m + " must specify either no TestInfo parameter or exactly one"); + Warmup warmupAnno = getAnnotation(testMethod, Warmup.class); + TestFormat.checkNoThrow(warmupAnno == null, + "Cannot set @Warmup at @Test method " + testMethod + " when used with its @Run method " + m + ". Use @Warmup at @Run method instead."); + warmupAnno = getAnnotation(m, Warmup.class); + TestFormat.checkNoThrow(warmupAnno == null || runAnno.mode() != RunMode.ONCE, + "Cannot set @Warmup at @Run method " + m + " when used with RunMode.ONCE. The @Run method is only invoked once."); + } + private static T getAnnotation(Method m, Class c) { T[] annos = m.getAnnotationsByType(c); TestFormat.check(annos.length < 2, m + " has duplicated annotations"); @@ -758,6 +817,11 @@ private static TriState compiledByC2(Method m) { } return TriState.No; } + + private static boolean isCompiledAtLevel(Method m, CompLevel level) { + return WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) == level.getValue(); +// return compiledByC2(m) == TriState.Yes; + } } // Errors in the framework @@ -847,11 +911,13 @@ class BaseTest { protected final Method testMethod; protected final TestInfo testInfo; protected final Object invocationTarget; + protected int warmupIterations; public BaseTest(DeclaredTest test) { this.test = test; this.testMethod = test.getTestMethod(); this.testInfo = new TestInfo(testMethod); + this.warmupIterations = test.getWarmupIterations(); Class clazz = testMethod.getDeclaringClass(); if (Modifier.isStatic(testMethod.getModifiers())) { this.invocationTarget = null; @@ -880,7 +946,7 @@ public void run() { return; } test.printFixedRandomArguments(); - for (int i = 0; i < test.getWarmupIterations(); i++) { + for (int i = 0; i < warmupIterations; i++) { runMethod(); } testInfo.setWarmUpFinished(); @@ -961,8 +1027,15 @@ private void compileNormallyAndRun() { WHITE_BOX.setBooleanVMFlag("VerifyOops", true); } if (!TestFramework.STRESS_CC && TestFramework.USE_COMPILER) { - for (int i = 0; !WHITE_BOX.isMethodCompiled(testMethod, false) && i < 10 ; i++) { + Asserts.assertTrue(WHITE_BOX.isMethodCompilable(testMethod, test.getCompLevel().getValue(), false)); + for (int i = 0; WHITE_BOX.getMethodCompilationLevel(testMethod, false) != test.getCompLevel().getValue() && i < 5 ; i++) { try { + if (i > 0) { + if (TestFramework.VERBOSE) { + System.out.println(testMethod + " is not yet compiled. Enqueue again"); + } + enqueueMethodForCompilation(); + } Thread.sleep(100); } catch (InterruptedException e) { TestFormat.fail("Error while waiting for compilation to be completed of " + testMethod); @@ -974,12 +1047,12 @@ private void compileNormallyAndRun() { runMethod(); } - private void enqueueMethodForCompilation() { + private void enqueueMethodForCompilation() { TestFramework.enqueueMethodForCompilation(test.getTestMethod(), test.getCompLevel()); } protected void checkCompilationLevel() { - CompLevel level = CompLevel.forValue(WhiteBox.getWhiteBox().getMethodCompilationLevel(testMethod)); + CompLevel level = CompLevel.forValue(WHITE_BOX.getMethodCompilationLevel(testMethod)); TestRun.check(level == test.getCompLevel(), "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod); } @@ -1034,12 +1107,13 @@ class CustomRunTest extends BaseTest { private final Method runMethod; private final RunMode mode; - public CustomRunTest(DeclaredTest test, Method runMethod, Run runSpecification) { + public CustomRunTest(DeclaredTest test, Method runMethod, Warmup warmUpAnno, Run runSpecification) { super(test); // Make sure we can also call non-public or public methods in package private classes runMethod.setAccessible(true); this.runMethod = runMethod; this.mode = runSpecification.mode(); + this.warmupIterations = warmUpAnno != null ? warmUpAnno.value() : test.getWarmupIterations(); } @Override diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java index 3301ced0480..9be58e7d0ed 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java @@ -48,25 +48,25 @@ public Method getTest() { return testMethod; } - public boolean isC2Compiled(Method m) { - return WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) == CompLevel.C2.getValue(); -// return compiledByC2(m) == TriState.Yes; - } - - public boolean isCompiledAtLevel(Method m, CompLevel level) { - return WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) == level.getValue(); -// return compiledByC2(m) == TriState.Yes; - } - - public void assertDeoptimizedByC2(Method m) { - TestRun.check(!isC2Compiled(m) || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized"); - } - - public void assertCompiledByC2(Method m) { - TestRun.check(isC2Compiled(m), m + " should have been compiled"); - } - - public void assertCompiledAtLevel(Method m, CompLevel level) { - TestRun.check(isCompiledAtLevel(m, level), m + " should have been compiled at level " + level.name()); - } +// public boolean isC2Compiled(Method m) { +// return WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) == CompLevel.C2.getValue(); +//// return compiledByC2(m) == TriState.Yes; +// } +// +// public boolean isCompiledAtLevel(Method m, CompLevel level) { +// return WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) == level.getValue(); +//// return compiledByC2(m) == TriState.Yes; +// } +// +// public void assertDeoptimizedByC2(Method m) { +// TestRun.check(!isC2Compiled(m) || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized"); +// } +// +// public void assertCompiledByC2(Method m) { +// TestRun.check(isC2Compiled(m), m + " should have been compiled"); +// } +// +// public void assertCompiledAtLevel(Method m, CompLevel level) { +// TestRun.check(isCompiledAtLevel(m, level), m + " should have been compiled at level " + level.name()); +// } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java index 3b4ee809497..4dacd998e44 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java @@ -11,10 +11,10 @@ public class TestBadFormat { public static void main(String[] args) throws NoSuchMethodException { runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); - expectTestFormatException(BadArguments.class); - expectTestFormatException(BadOverloadedMethod.class); - expectTestFormatException(BadCompilerControl.class); -// expectTestFormatException(BadWarmup.class); +// expectTestFormatException(BadArguments.class); +// expectTestFormatException(BadOverloadedMethod.class); +// expectTestFormatException(BadCompilerControl.class); + expectTestFormatException(BadWarmup.class); } private static void expectTestFormatException(Class clazz) { @@ -129,3 +129,16 @@ public void mix1() {} public void mix2() {} } +class BadWarmup { + + @Warmup(10000) + public void warmUpNonTest() {} + + @Test + @Warmup(-1) + public void negativeWarmup() {} + + @Run(test = "negativeWarmup") + @Warmup(-1) + public void negativeWarmup2() {} +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java index 942b0b89b9a..1f899a6ae65 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java @@ -7,7 +7,6 @@ // Requires C1 and C2 enabled public class TestCompLevels { - public static final String[] TEST_KEYS = { "test-key0", "test-key1" }; static int[] testExecuted = new int[4]; public static void main(String[] args) throws Exception { @@ -36,7 +35,7 @@ public void testC1() { @Check(test = "testC1", when = CheckAt.COMPILED) public void checkTestC1(TestInfo info) { - info.assertCompiledAtLevel(info.getTest(), CompLevel.C1); + TestFramework.assertCompiledAtLevel(info.getTest(), CompLevel.C1); } @Test(compLevel = CompLevel.C1_LIMITED_PROFILE) @@ -46,7 +45,7 @@ public void testC1Limited() { @Check(test = "testC1Limited", when = CheckAt.COMPILED) public void checkTestLimited(TestInfo info) { - info.assertCompiledAtLevel(info.getTest(), CompLevel.C1_LIMITED_PROFILE); + TestFramework.assertCompiledAtLevel(info.getTest(), CompLevel.C1_LIMITED_PROFILE); } @Test(compLevel = CompLevel.C1_FULL_PROFILE) @@ -56,7 +55,7 @@ public void testC1Full() { @Check(test = "testC1Full", when = CheckAt.COMPILED) public void checkTestC1Full(TestInfo info) { - info.assertCompiledAtLevel(info.getTest(), CompLevel.C1_FULL_PROFILE); + TestFramework.assertCompiledAtLevel(info.getTest(), CompLevel.C1_FULL_PROFILE); } @Test(compLevel = CompLevel.C2) @@ -66,7 +65,7 @@ public void testC2() { @Check(test = "testC2", when = CheckAt.COMPILED) public void checkTestC2(TestInfo info) { - info.assertCompiledAtLevel(info.getTest(), CompLevel.C2); + TestFramework.assertCompiledAtLevel(info.getTest(), CompLevel.C2); } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java new file mode 100644 index 00000000000..b5a0e912488 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java @@ -0,0 +1,149 @@ +package compiler.valhalla.framework.tests; + +import compiler.valhalla.framework.*; +import jdk.test.lib.Asserts; +import sun.hotspot.WhiteBox; + +import java.lang.reflect.Method; + +public class TestControls { + static int[] executed = new int[13]; + static boolean wasExecuted = false; + static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + + public static void main(String[] args) throws Exception { + Method runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); + runTestsOnSameVM.setAccessible(true); + runTestsOnSameVM.invoke(null, new Object[]{ null }); + final int defaultIterations = TestFramework.WARMUP_ITERATIONS + 1; + Asserts.assertEQ(executed[0], 1001); + Asserts.assertEQ(executed[1], 101); + Asserts.assertEQ(executed[2], 10000); + Asserts.assertEQ(executed[3], 10000); + Asserts.assertEQ(executed[4], defaultIterations); + Asserts.assertEQ(executed[5], defaultIterations); + Asserts.assertEQ(executed[6], 5001); + Asserts.assertEQ(executed[7], 5001); + Asserts.assertEQ(executed[8], 1); + Asserts.assertEQ(executed[9], 5000); + Asserts.assertEQ(executed[10], 1); + Asserts.assertEQ(executed[11], 2); + Asserts.assertEQ(executed[12], 1); + Asserts.assertFalse(wasExecuted); + } + + @Test + @Warmup(1000) + public void test1() { + executed[0]++; + } + + @Check(test = "test1") + public void check1(TestInfo info) { + if (executed[0] <= 1000) { + Asserts.assertTrue(info.isWarmUp()); + } else { + Asserts.assertTrue(!info.isWarmUp() && executed[0] == 1001); + TestFramework.assertCompiledByC2(info.getTest()); + } + } + + @Test + @Warmup(100) + public void test2() { + executed[1]++; + } + + @Check(test = "test2", when = CheckAt.COMPILED) + public void check2(TestInfo info) throws NoSuchMethodException{ + Asserts.assertTrue(!info.isWarmUp() && executed[1] == 101); + TestFramework.assertCompiledByC2(info.getTest()); + TestFramework.assertCompiledByC2(TestControls.class.getDeclaredMethod("overload", int.class)); + TestFramework.assertCompiledAtLevel(TestControls.class.getDeclaredMethod("overload", double.class), CompLevel.C1_LIMITED_PROFILE); + } + + @Test + public void overload() { + executed[4]++; + } + + @ForceCompile + @DontInline + public static void overload(int i) { + wasExecuted = true; + } + + @ForceCompile(CompLevel.C1_LIMITED_PROFILE) + @ForceInline + public static void overload(double i) { + wasExecuted = true; + } + + @Check(test = "overload") + public void checkOverload() { + executed[5]++; + } + + @Test + public void testDontCompile() { + executed[2]++; + } + + @DontCompile + public static void dontCompile() { + executed[3]++; + } + + @Run(test = "testDontCompile", mode = RunMode.ONCE) + public void runTestDontCompile() throws NoSuchMethodException { + for (int i = 0; i < 10000; i++) { + dontCompile(); // Should not compile this method + testDontCompile(); + } + TestFramework.assertNotCompiled(TestControls.class.getDeclaredMethod("dontCompile")); + } + + @Test + public void testCompileAtLevel1() { + executed[6]++; + } + + @DontCompile({CompLevel.C1_FULL_PROFILE, CompLevel.C1_LIMITED_PROFILE, CompLevel.C2}) + public static void dontCompile2() { + executed[7]++; + } + + @Run(test = "testCompileAtLevel1") + @Warmup(5000) + public void runTestDontCompile2(TestInfo info) throws NoSuchMethodException { + dontCompile2(); + testCompileAtLevel1(); + if (!info.isWarmUp()) { + executed[8]++; + int compLevel = WHITE_BOX.getMethodCompilationLevel(TestControls.class.getDeclaredMethod("dontCompile2"), false); + Asserts.assertLessThan(compLevel, CompLevel.C1_LIMITED_PROFILE.getValue()); + } else { + executed[9]++; + } + } + + @Test + @Warmup(0) + public void noWarmup() { + executed[10]++; + } + + @Test + public void noWarmup2() { + executed[11]++; + } + + @Run(test = "noWarmup2") + @Warmup(0) + public void runNoWarmup2(TestInfo info) { + noWarmup2(); + noWarmup2(); + Asserts.assertTrue(!info.isWarmUp()); + executed[12]++; + } +} From a7fb1ac1952c886ab16260228d46e171f970ebe0 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 27 Jan 2021 11:20:00 +0100 Subject: [PATCH 013/131] Add PRINT_GRAPH, Xcomp and UseCompile handling, fix public Framework checks with TriState, fix tests, fix compilation scheduling for BaseTests, add SanityTest, cleanup naming of public interface --- .../valhalla/framework/IRMatcher.java | 11 +- .../{OSROnly.java => OSRCompileOnly.java} | 2 +- .../compiler/valhalla/framework/RunMode.java | 2 +- .../compiler/valhalla/framework/Scenario.java | 4 + .../valhalla/framework/TestFramework.java | 196 ++++++++++-------- .../framework/tests/TestBadFormat.java | 6 +- .../valhalla/framework/tests/TestBasics.java | 13 +- .../framework/tests/TestCompLevels.java | 6 +- .../framework/tests/TestControls.java | 13 +- .../framework/tests/TestIRMatching.java | 2 - .../valhalla/framework/tests/TestSanity.java | 46 ++++ .../tests/TestWithHelperClasses.java | 6 +- 12 files changed, 201 insertions(+), 106 deletions(-) rename test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/{OSROnly.java => OSRCompileOnly.java} (90%) create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java index aa7c7a95c32..f463f108839 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java @@ -8,6 +8,7 @@ import java.util.regex.Pattern; class IRMatcher { + private static final boolean PRINT_GRAPH = true; private final Map irRulesMap; private final Map compilations; private final Class testClass; @@ -47,8 +48,8 @@ private void parseIREncoding(String output) { } private void splitCompilations(String output, Class testClass) { - Pattern comp_re = Pattern.compile("\\n\\s+\\d+\\s+\\d+\\s+([% ])([s ])([! ])b([n ])\\s+\\d?\\s+\\S+\\.(?[^.]+::\\S+)\\s+(?@ \\d+\\s+)?[(]\\d+ bytes[)]"); - Matcher m = comp_re.matcher(output); + Pattern pattern = Pattern.compile("\\n\\s+\\d+\\s+\\d+\\s+([% ])([s ])([! ])b([n ])\\s+\\d?\\s+\\S+\\.(?[^.]+::\\S+)\\s+(?@ \\d+\\s+)?[(]\\d+ bytes[)]"); + Matcher m = pattern.matcher(output); int prev = 0; String methodName = null; String keyMatchPrefix = testClass.getSimpleName() + "::"; @@ -73,7 +74,11 @@ private void splitCompilations(String output, Class testClass) { if (methodName.startsWith(keyMatchPrefix)) { String shortMethodName = methodName.split("::")[1]; if (irRulesMap.containsKey(methodName.split("::")[1])) { - compilations.put(shortMethodName, output.substring(prev)); + String testOutput = output.substring(prev); + if (PRINT_GRAPH) { + System.out.println("\nGraph for " + methodName + "\n" + testOutput); + } + compilations.put(shortMethodName, testOutput); } } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSROnly.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSRCompileOnly.java similarity index 90% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSROnly.java rename to test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSRCompileOnly.java index 39fce2bb6b9..62c1bad51f0 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSROnly.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSRCompileOnly.java @@ -6,4 +6,4 @@ // Do not enqueue the test method for compilation immediately after warmup loops have finished. Instead // let the test method be compiled with on-stack-replacement. @Retention(RetentionPolicy.RUNTIME) -public @interface OSROnly {} \ No newline at end of file +public @interface OSRCompileOnly {} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java index 22b3068e7f9..137a935020a 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java @@ -1,6 +1,6 @@ package compiler.valhalla.framework; public enum RunMode { - ONCE, + INVOKE_ONCE, NORMAL } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java index 217c0a7472b..c8771436275 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java @@ -39,6 +39,10 @@ public Scenario(int index, String... flags) { } } + public void addFlag(String flag) { + flags.add(flag); + } + public List getFlags() { return flags; } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 48e8a6ddfd1..942fc567ef0 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -40,38 +40,35 @@ public class TestFramework { // User defined settings static final boolean XCOMP = Platform.isComp(); - private static final boolean PRINT_GRAPH = true; // private static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "true")); private static final boolean PRINT_TIMES = Boolean.parseBoolean(System.getProperty("PrintTimes", "false")); private static final boolean COMPILE_COMMANDS = Boolean.parseBoolean(System.getProperty("CompileCommands", "true")) && !XCOMP; - private static boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")) - && !XCOMP && !TEST_C1 && COMPILE_COMMANDS && Platform.isDebugBuild() && !Platform.isInt(); + static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); + static final boolean STRESS_CC = Boolean.parseBoolean(System.getProperty("StressCC", "false")); + private static final boolean REQUESTED_VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); + private static boolean VERIFY_IR = REQUESTED_VERIFY_IR && USE_COMPILER && !XCOMP && !STRESS_CC && !TEST_C1 && COMPILE_COMMANDS + && Platform.isDebugBuild() && !Platform.isInt(); private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false")) && Platform.isDebugBuild(); private static final String TESTLIST = System.getProperty("Testlist", ""); private static final String EXCLUDELIST = System.getProperty("Exclude", ""); public static final int WARMUP_ITERATIONS = Integer.parseInt(System.getProperty("Warmup", "251")); private static final boolean DUMP_REPLAY = Boolean.parseBoolean(System.getProperty("DumpReplay", "false")); private static final boolean GC_AFTER = Boolean.parseBoolean(System.getProperty("GCAfter", "false")); - static final boolean STRESS_CC = Boolean.parseBoolean(System.getProperty("StressCC", "false")); private static final boolean SHUFFLE_TESTS = Boolean.parseBoolean(System.getProperty("ShuffleTests", "true")); private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); - private static final boolean USE_COMPILE_COMMAND_ANNOTATIONS = Boolean.parseBoolean(System.getProperty("UseCompileCommandAnnotations", "true")); private static final boolean PRINT_VALID_IR_RULES = Boolean.parseBoolean(System.getProperty("PrintValidIRRules", "false")); protected static final long PerMethodTrapLimit = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); protected static final boolean ProfileInterpreter = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); private static final boolean FLIP_C1_C2 = Boolean.parseBoolean(System.getProperty("FlipC1C2", "false")); - static final boolean TESTING_TEST_FRAMEWORK = Boolean.parseBoolean(System.getProperty("TestingTestFramework", "false")); - private final String[] fixedDefaultFlags; private final String[] compileCommandFlags; private final String[] printFlags; private final String[] verifyFlags; private static String lastVmOutput; // Only used to test TestFramework - static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); static final boolean VERIFY_OOPS = (Boolean)WHITE_BOX.getVMFlag("VerifyOops"); private final HashMap declaredTests = new HashMap<>(); @@ -142,7 +139,7 @@ private List createTestFilterList(String list, Class testClass) { public static void main(String[] args) { String testClassName = args[0]; - System.out.println("Framework main(), about to run test class " + testClassName); + System.out.println("Framework main(), about to run tests in class " + testClassName); Class testClass; try { testClass = Class.forName(testClassName); @@ -195,18 +192,18 @@ public static void runWithScenarios(Scenario.Run runMode, Scenario... scenarios) } public static void runWithScenarios(Class testClass, Scenario... scenarios) { - runWithScenarios(Scenario.Run.EXCLUDE_DEFAULT, testClass, null, scenarios); + runWithScenariosAndHelperClasses(Scenario.Run.EXCLUDE_DEFAULT, testClass, null, scenarios); } public static void runWithScenarios(Scenario.Run runMode, Class testClass, Scenario... scenarios) { - runWithScenarios(runMode, testClass, null, scenarios); + runWithScenariosAndHelperClasses(runMode, testClass, null, scenarios); } - public static void runWithScenarios(Class testClass, List> helperClasses, Scenario... scenarios) { - runWithScenarios(Scenario.Run.EXCLUDE_DEFAULT, testClass, helperClasses, scenarios); + public static void runWithScenariosAndHelperClasses(Class testClass, List> helperClasses, Scenario... scenarios) { + runWithScenariosAndHelperClasses(Scenario.Run.EXCLUDE_DEFAULT, testClass, helperClasses, scenarios); } - public static void runWithScenarios(Scenario.Run runMode, Class testClass, List> helperClasses, Scenario... scenarios) { + public static void runWithScenariosAndHelperClasses(Scenario.Run runMode, Class testClass, List> helperClasses, Scenario... scenarios) { TestFramework framework = new TestFramework(); Map exceptionMap = new HashMap<>(); // First run without additional scenario flags. @@ -242,10 +239,6 @@ public static void runWithScenarios(Scenario.Run runMode, Class testClass, Li } } - public static void run(Class testClass, List> helperClasses) { - doRun(testClass, helperClasses); - } - // Can be called from tests for non-@Test methods public static void compile(Method m, CompLevel compLevel) { TestRun.check(getAnnotation(m, Test.class) == null, @@ -254,8 +247,11 @@ public static void compile(Method m, CompLevel compLevel) { } public static boolean isC2Compiled(Method m) { - return WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) == CompLevel.C2.getValue(); -// return compiledByC2(m) == TriState.Yes; + return compiledByC2(m) == TriState.Yes; + } + + public static boolean isCompiledAtLevel(Method m, CompLevel compLevel) { + return compiledAtLevel(m, compLevel) == TriState.Yes; } public static void assertDeoptimizedByC2(Method m) { @@ -267,7 +263,7 @@ public static void assertCompiledByC2(Method m) { } public static void assertCompiledAtLevel(Method m, CompLevel level) { - TestRun.check(isCompiledAtLevel(m, level), m + " should have been compiled at level " + level.name()); + TestRun.check(compiledAtLevel(m, level) != TriState.No, m + " should have been compiled at level " + level.name()); } public static void assertNotCompiled(Method m) { @@ -310,8 +306,8 @@ private static void runTestsOnSameVM(Class testClass) { private void runTestVM(Class testClass, List> helperClasses, Scenario scenario) { if (scenario != null && !scenario.isEnabled()) { - System.out.println("Disabled scenario #" + scenario.getIndex() + "! This scenario is not present in set flag -DScenarios and" + - "is therefore not executed."); + System.out.println("Disabled scenario #" + scenario.getIndex() + "! This scenario is not present in set flag -DScenarios " + + "and is therefore not executed."); return; } @@ -321,18 +317,16 @@ private void runTestVM(Class testClass, List> helperClasses, Scenari // Calls 'main' of this class to run all specified tests with commands 'cmds'. oa = ProcessTools.executeTestJvm(cmds); } catch (Exception e) { - throw new TestRunException("Error while executing Test VM", e); + throw new TestFrameworkException("Error while executing Test VM", e); } String output = oa.getOutput(); - if (VERBOSE) { + lastVmOutput = output; + + if (VERBOSE || oa.getExitValue() != 0) { System.out.println(" ----- OUTPUT -----"); System.out.println(output); } - lastVmOutput = output; - if (!TESTING_TEST_FRAMEWORK) { - // Tests for the framework itself might expect certain exceptions. - oa.shouldHaveExitValue(0); - } + oa.shouldHaveExitValue(0); if (VERIFY_IR) { IRMatcher irMatcher = new IRMatcher(output, testClass); @@ -364,7 +358,7 @@ private ArrayList prepareTestVmFlags(Class testClass, List> // TODO: Only for debugging if (cmds.get(0).startsWith("-agentlib")) { - cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=n,server=y"); + cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=y,server=y"); } if (PREFER_COMMAND_LINE_FLAGS) { @@ -391,6 +385,9 @@ private void setupIrVerificationFlags(Class testClass, ArrayList cmds System.out.println("Disabled IR verification due to CompileThreshold flag"); } VERIFY_IR = false; + } else if (!VERIFY_IR && REQUESTED_VERIFY_IR) { + System.out.println("IR Verification disabled either due to not running a debug build, running with -Xint, or other " + + "VM flags that make the verification inaccurate or impossible (e.g. running with C1 only)."); } if (VERIFY_IR) { @@ -416,7 +413,7 @@ private void parseTestClass(Class clazz) { setupTests(clazz); setupCheckAndRunMethods(clazz); - // All remaining tests are simple base tests without check or specific way to run them + // All remaining tests are simple base tests without check or specific way to run them. addBaseTests(); TestFormat.reportIfAnyFailures(); declaredTests.clear(); @@ -444,11 +441,18 @@ private void addReplay() { } private void processExplicitCompileCommands(Class clazz) { - if (USE_COMPILE_COMMAND_ANNOTATIONS) { + if (!XCOMP) { + // Don't control compilations if -Xcomp is enabled. Method[] methods = clazz.getDeclaredMethods(); for (Method m : methods) { try { applyIndependentCompilationCommands(m); + + if (STRESS_CC) { + if (getAnnotation(m, Test.class) != null) { + excludeCompilationRandomly(m); + } + } } catch (TestFormatException e) { // Failure logged. Continue and report later. } @@ -465,6 +469,17 @@ private void processExplicitCompileCommands(Class clazz) { } } + static boolean excludeCompilationRandomly(Method m) { + // Exclude some methods from compilation with C2 to stress test the calling convention + boolean exclude = Utils.getRandomInstance().nextBoolean(); + if (exclude) { + System.out.println("Excluding from C2 compilation: " + m); + WHITE_BOX.makeMethodNotCompilable(m, CompLevel.C2.getValue(), false); + WHITE_BOX.makeMethodNotCompilable(m, CompLevel.C2.getValue(), true); + } + return exclude; + } + private void applyIndependentCompilationCommands(Method m) { ForceInline forceInlineAnno = getAnnotation(m, ForceInline.class); DontInline dontInlineAnno = getAnnotation(m, DontInline.class); @@ -486,14 +501,6 @@ private void applyIndependentCompilationCommands(Method m) { } } } - - if (STRESS_CC) { - // Exclude some methods from compilation with C2 to stress test the calling convention - if (Utils.getRandomInstance().nextBoolean()) { - System.out.println("Excluding from C2 compilation: " + m); - WHITE_BOX.makeMethodNotCompilable(m, CompLevel.C2.getValue(), false); - } - } } private void checkCompilationCommandAnnotations(Method m, ForceInline forceInlineAnno, DontInline dontInlineAnno, ForceCompile forceCompileAnno, DontCompile dontCompileAnno) { @@ -593,13 +600,16 @@ private void addTest(Method m) { TestFormat.check(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + m); } - boolean osrOnly = getAnnotation(m, OSROnly.class) != null; + boolean osrOnly = getAnnotation(m, OSRCompileOnly.class) != null; if (PRINT_VALID_IR_RULES) { irMatchRulePrinter.emitRuleEncoding(m); } - // Don't inline test methods - WHITE_BOX.testSetDontInlineMethod(m, true); + + if (!XCOMP) { + // Don't inline test methods. Don't care when -Xcomp set. + WHITE_BOX.testSetDontInlineMethod(m, true); + } CompLevel compLevel = testAnno.compLevel(); if (FLIP_C1_C2) { compLevel = flipCompLevel(compLevel); @@ -749,8 +759,11 @@ private void checkCustomRunTest(Method m, Run runAnno, Method testMethod, Declar TestFormat.checkNoThrow(warmupAnno == null, "Cannot set @Warmup at @Test method " + testMethod + " when used with its @Run method " + m + ". Use @Warmup at @Run method instead."); warmupAnno = getAnnotation(m, Warmup.class); - TestFormat.checkNoThrow(warmupAnno == null || runAnno.mode() != RunMode.ONCE, + TestFormat.checkNoThrow(warmupAnno == null || runAnno.mode() != RunMode.INVOKE_ONCE, "Cannot set @Warmup at @Run method " + m + " when used with RunMode.ONCE. The @Run method is only invoked once."); + OSRCompileOnly osrAnno = getAnnotation(testMethod, OSRCompileOnly.class); + TestFormat.checkNoThrow(osrAnno == null || runAnno.mode() != RunMode.INVOKE_ONCE, + "Cannot set @OSRCompileOnly at @Run method " + m + " when used with RunMode.ONCE. The @Run method is responsible for triggering compilation."); } private static T getAnnotation(Method m, Class c) { @@ -807,21 +820,20 @@ enum TriState { } private static TriState compiledByC2(Method m) { -// if (!TestFramework.USE_COMPILER || TestFramework.XCOMP || TestFramework.TEST_C1 || -// (TestFramework.STRESS_CC && !WHITE_BOX.isMethodCompilable(m, CompLevel.C2.getValue(), false))) { -// return TriState.Maybe; -// } + return compiledAtLevel(m, CompLevel.C2); + } + + private static TriState compiledAtLevel(Method m, CompLevel level) { + if (!TestFramework.USE_COMPILER || TestFramework.XCOMP || TestFramework.TEST_C1 || + (TestFramework.STRESS_CC && !WHITE_BOX.isMethodCompilable(m, level.getValue(), false))) { + return TriState.Maybe; + } if (WHITE_BOX.isMethodCompiled(m, false) - && WHITE_BOX.getMethodCompilationLevel(m, false) >= CompLevel.C2.getValue()) { + && WHITE_BOX.getMethodCompilationLevel(m, false) == level.getValue()) { return TriState.Yes; } return TriState.No; } - - private static boolean isCompiledAtLevel(Method m, CompLevel level) { - return WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) == level.getValue(); -// return compiledByC2(m) == TriState.Yes; - } } // Errors in the framework @@ -906,11 +918,13 @@ public Object invoke(Object obj, Object... args) { class BaseTest { private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); private static final int OSR_TEST_TIMEOUT = Integer.parseInt(System.getProperty("OSRTestTimeOut", "5000")); + private static final int TEST_COMPILATION_TIMEOUT = Integer.parseInt(System.getProperty("TestCompilationTimeout", "5000")); protected final DeclaredTest test; protected final Method testMethod; protected final TestInfo testInfo; protected final Object invocationTarget; + private final boolean shouldCompile; protected int warmupIterations; public BaseTest(DeclaredTest test) { @@ -931,6 +945,13 @@ public BaseTest(DeclaredTest test) { + ". Make sure there is a constructor without arguments.", e); } } + if (!TestFramework.USE_COMPILER) { + this.shouldCompile = false; + } else if (TestFramework.STRESS_CC) { + this.shouldCompile = !TestFramework.excludeCompilationRandomly(testMethod); + } else { + this.shouldCompile = true; + } } public String getTestName() { @@ -945,6 +966,9 @@ public void run() { // Exclude test if compilation level is SKIP either set through test or by not matching the current VM flags. return; } + if (TestFramework.VERBOSE) { + System.out.println("Starting " + testMethod); + } test.printFixedRandomArguments(); for (int i = 0; i < warmupIterations; i++) { runMethod(); @@ -952,9 +976,13 @@ public void run() { testInfo.setWarmUpFinished(); if (test.isOSROnly()) { - compileOSRAndRun(); + compileOSRAndRun(); // TODO: Keep this? } else { - compileNormallyAndRun(); + if (shouldCompile) { + compileTest(); + } + // Always run method. + runMethod(); } } @@ -1015,36 +1043,36 @@ private void retryDisabledVerifyOops(boolean stateCleared) { } } - private void compileNormallyAndRun() { + private void compileTest() { final boolean maybeCodeBufferOverflow = (TestFramework.TEST_C1 && TestFramework.VERIFY_OOPS); final Method testMethod = test.getTestMethod(); + long started = System.currentTimeMillis(); + long elapsed = 0; + Asserts.assertTrue(WHITE_BOX.isMethodCompilable(testMethod, test.getCompLevel().getValue(), false)); enqueueMethodForCompilation(); - if (maybeCodeBufferOverflow && !WHITE_BOX.isMethodCompiled(testMethod, false)) { - // Let's disable VerifyOops temporarily and retry. - WHITE_BOX.setBooleanVMFlag("VerifyOops", false); - WHITE_BOX.clearMethodState(testMethod); - enqueueMethodForCompilation(); - WHITE_BOX.setBooleanVMFlag("VerifyOops", true); - } - if (!TestFramework.STRESS_CC && TestFramework.USE_COMPILER) { - Asserts.assertTrue(WHITE_BOX.isMethodCompilable(testMethod, test.getCompLevel().getValue(), false)); - for (int i = 0; WHITE_BOX.getMethodCompilationLevel(testMethod, false) != test.getCompLevel().getValue() && i < 5 ; i++) { - try { - if (i > 0) { - if (TestFramework.VERBOSE) { - System.out.println(testMethod + " is not yet compiled. Enqueue again"); - } - enqueueMethodForCompilation(); - } - Thread.sleep(100); - } catch (InterruptedException e) { - TestFormat.fail("Error while waiting for compilation to be completed of " + testMethod); + + do { + if (!WHITE_BOX.isMethodQueuedForCompilation(testMethod)) { + if (elapsed > 0 && TestFramework.VERBOSE) { + System.out.println(testMethod + " is not in queue anymore due to compiling it simultaneously on a different level. Enqueue again."); + enqueueMethodForCompilation(); } } - Asserts.assertTrue(WHITE_BOX.isMethodCompiled(testMethod, false), testMethod + " not compiled after waiting 1s"); - checkCompilationLevel(); - } - runMethod(); + if (maybeCodeBufferOverflow && elapsed > 1000 && !WHITE_BOX.isMethodCompiled(testMethod, false)) { + // Let's disable VerifyOops temporarily and retry. + WHITE_BOX.setBooleanVMFlag("VerifyOops", false); + WHITE_BOX.clearMethodState(testMethod); + enqueueMethodForCompilation(); + WHITE_BOX.setBooleanVMFlag("VerifyOops", true); + } + + if (WHITE_BOX.getMethodCompilationLevel(testMethod, false) == test.getCompLevel().getValue()) { + break; + } + elapsed = System.currentTimeMillis() - started; + } while (elapsed < TEST_COMPILATION_TIMEOUT); + TestRun.check(elapsed < TEST_COMPILATION_TIMEOUT, "Could not compile" + testMethod + " after " + TEST_COMPILATION_TIMEOUT/1000 + "s"); + checkCompilationLevel(); } private void enqueueMethodForCompilation() { @@ -1119,7 +1147,7 @@ public CustomRunTest(DeclaredTest test, Method runMethod, Warmup warmUpAnno, Run @Override public void run() { switch (mode) { - case ONCE -> runMethod(); + case INVOKE_ONCE -> runMethod(); case NORMAL -> super.run(); } } @@ -1146,7 +1174,7 @@ protected void checkCompilationLevel() { if (level != test.getCompLevel()) { String message = "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod + "."; switch (mode) { - case ONCE -> message = message + "\nCheck your @Run method (invoked once) " + runMethod + " to ensure that " + testMethod + " will be complied at the requested level."; + case INVOKE_ONCE -> message = message + "\nCheck your @Run method (invoked once) " + runMethod + " to ensure that " + testMethod + " will be complied at the requested level."; case NORMAL -> message = message + "\nCheck your @Run method " + runMethod + " to ensure that " + testMethod + " is called at least once in each iteration."; } TestRun.fail(message); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java index 4dacd998e44..10affb6a205 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java @@ -11,9 +11,9 @@ public class TestBadFormat { public static void main(String[] args) throws NoSuchMethodException { runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); -// expectTestFormatException(BadArguments.class); -// expectTestFormatException(BadOverloadedMethod.class); -// expectTestFormatException(BadCompilerControl.class); + expectTestFormatException(BadArguments.class); + expectTestFormatException(BadOverloadedMethod.class); + expectTestFormatException(BadCompilerControl.class); expectTestFormatException(BadWarmup.class); } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java index b413a6650c1..840bc755298 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -107,11 +107,16 @@ public void test2() { wasExecuted = true; } - // Can overload when not a @Test + // Can overload non- @Test public static void test2(int i) { wasExecuted = true; } + // Can overload a @Test if it is not a @Test itself. + public static void test(double i) { + wasExecuted = true; + } + @Test public static void staticTest() { testExecuted[1]++; @@ -827,7 +832,7 @@ public void testRunOnce() { checkExecuted[4]++; } - @Run(test = "testRunOnce", mode=RunMode.ONCE) + @Run(test = "testRunOnce", mode=RunMode.INVOKE_ONCE) public void runTestRunOnce(TestInfo info) { testRunOnce(); } @@ -838,7 +843,7 @@ public void testRunOnce2() { testExecuted[75]++; } - @Run(test = "testRunOnce2", mode=RunMode.ONCE) + @Run(test = "testRunOnce2", mode=RunMode.INVOKE_ONCE) public void runTestRunOnce2(TestInfo info) { for (int i = 0; i < TestFramework.WARMUP_ITERATIONS + 1; i++) { testRunOnce2(); @@ -855,7 +860,7 @@ public void sameName(boolean a) { wasExecuted = true; } - @Check(test="sameName") + @Check(test = "sameName") public void checkSameName() { testExecuted[77]++; } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java index 1f899a6ae65..fcdc51a3594 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java @@ -10,9 +10,9 @@ public class TestCompLevels { static int[] testExecuted = new int[4]; public static void main(String[] args) throws Exception { - Method runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM"); + Method runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); - runTestsOnSameVM.invoke(null); + runTestsOnSameVM.invoke(null, new Object[]{null}); for (int i = 0; i < testExecuted.length; i++) { int value = testExecuted[i]; if (value != TestFramework.WARMUP_ITERATIONS + 1) { @@ -23,7 +23,7 @@ public static void main(String[] args) throws Exception { } Scenario s = new Scenario(1, "-XX:-TieredCompilation"); TestFramework.runWithScenarios(TestNoTiered.class, s); - s = new Scenario(1, "-XX:TieredStopAtLevel=1"); + s = new Scenario(2, "-XX:TieredStopAtLevel=1"); TestFramework.runWithScenarios(TestStopAtLevel1.class, s); Asserts.assertTrue(TestFramework.getLastVmOutput().contains("TestStopAtLevel1=34")); } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java index b5a0e912488..2edaf70b832 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java @@ -30,6 +30,15 @@ public static void main(String[] args) throws Exception { Asserts.assertEQ(executed[11], 2); Asserts.assertEQ(executed[12], 1); Asserts.assertFalse(wasExecuted); + final long started = System.currentTimeMillis(); + long elapsed = 0; + Method overloadDouble = TestControls.class.getDeclaredMethod("overload", double.class); + Method overloadInt = TestControls.class.getDeclaredMethod("overload", int.class); + while (!(TestFramework.isC2Compiled(overloadInt) && TestFramework.isCompiledAtLevel(overloadDouble, CompLevel.C1_LIMITED_PROFILE)) && elapsed < 5000) { + elapsed = System.currentTimeMillis() - started; + } + TestFramework.assertCompiledAtLevel(TestControls.class.getDeclaredMethod("overload", double.class), CompLevel.C1_LIMITED_PROFILE); + TestFramework.assertCompiledByC2(TestControls.class.getDeclaredMethod("overload", int.class)); } @Test @@ -58,8 +67,6 @@ public void test2() { public void check2(TestInfo info) throws NoSuchMethodException{ Asserts.assertTrue(!info.isWarmUp() && executed[1] == 101); TestFramework.assertCompiledByC2(info.getTest()); - TestFramework.assertCompiledByC2(TestControls.class.getDeclaredMethod("overload", int.class)); - TestFramework.assertCompiledAtLevel(TestControls.class.getDeclaredMethod("overload", double.class), CompLevel.C1_LIMITED_PROFILE); } @Test @@ -94,7 +101,7 @@ public static void dontCompile() { executed[3]++; } - @Run(test = "testDontCompile", mode = RunMode.ONCE) + @Run(test = "testDontCompile", mode = RunMode.INVOKE_ONCE) public void runTestDontCompile() throws NoSuchMethodException { for (int i = 0; i < 10000; i++) { dontCompile(); // Should not compile this method diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java index 4706829d557..aa3f7a31a79 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java @@ -94,8 +94,6 @@ private static void runFailOnTests(Constraint constraint, String... args) { Scenario scenario = new Scenario(0, args); TestFramework.runWithScenarios(constraint.getKlass(), scenario); // All constraints have the same class. shouldNotReach(); - } catch (ShouldNotReachException e) { - throw e; } catch (TestRunException e) { System.out.println(e.getMessage()); constraint.checkConstraint(e); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java new file mode 100644 index 00000000000..544ae18700b --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java @@ -0,0 +1,46 @@ +package compiler.valhalla.framework.tests; + +import compiler.valhalla.framework.Scenario; +import compiler.valhalla.framework.Test; +import compiler.valhalla.framework.TestFramework; + +import java.util.ArrayList; + +public class TestSanity { + + public static void main(String[] args) { + TestFramework.run(); + TestFramework.run(TestSanity.class); + TestFramework.runWithHelperClasses(TestSanity.class, HelperA.class); + TestFramework.runWithHelperClasses(TestSanity.class, HelperA.class, HelperB.class); + Scenario s1 = new Scenario(1, "-XX:SuspendRetryCount=52", "-XX:+UseTLAB"); + Scenario s2 = new Scenario(2, "-XX:SuspendRetryCount=53", "-XX:+UseTLAB"); + TestFramework.runWithScenarios(s1); + TestFramework.runWithScenarios(s1, s2); + TestFramework.runWithScenarios(TestSanity.class, s1, s2); + TestFramework.runWithScenarios(Scenario.Run.INCLUDE_DEFAULT, s1); + TestFramework.runWithScenarios(Scenario.Run.INCLUDE_DEFAULT, s1, s2); + TestFramework.runWithScenarios(Scenario.Run.INCLUDE_DEFAULT, TestSanity.class, s1); + TestFramework.runWithScenarios(Scenario.Run.INCLUDE_DEFAULT, TestSanity.class, s1, s2); + ArrayList> helperClasses = new ArrayList<>(); + helperClasses.add(HelperA.class); + helperClasses.add(HelperB.class); + TestFramework.runWithScenariosAndHelperClasses(TestSanity.class, helperClasses, s2); + TestFramework.runWithScenariosAndHelperClasses(TestSanity.class, helperClasses, s1, s2); + TestFramework.runWithScenariosAndHelperClasses(Scenario.Run.INCLUDE_DEFAULT, TestSanity.class, helperClasses, s2); + TestFramework.runWithScenariosAndHelperClasses(Scenario.Run.INCLUDE_DEFAULT, TestSanity.class, helperClasses, s1, s2); + } + + @Test + public void test() { + System.out.println("test"); + } +} + +class HelperA { + +} + +class HelperB { + +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java index 5e7617344b4..43f9c1c5965 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java @@ -9,9 +9,11 @@ public static void main(String[] args) { TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class, Helper2.class); try { TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class); - } catch (TestRunException e) { - Asserts.assertTrue(e.getMessage().contains("public static void compiler.valhalla.framework.tests.Helper2.foo() should have been compiled")); + } catch (Exception e) { + Asserts.assertTrue(TestFramework.getLastVmOutput().contains("public static void compiler.valhalla.framework.tests.Helper2.foo() should have been compiled")); + return; } + throw new RuntimeException("Did not catch exception"); } @Test From 23113880a00c33b90d71562df708b4ccff88dbc1 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 29 Jan 2021 13:22:05 +0100 Subject: [PATCH 014/131] Redesign TestFramework interface --- .../compiler/valhalla/framework/Scenario.java | 15 +- .../valhalla/framework/TestFramework.java | 196 ++++++----- .../framework/TestFrameworkValhalla.java | 20 -- .../valhalla/framework/tests/TestBasics.java | 311 ++++++++++-------- .../framework/tests/TestIRMatching.java | 40 +-- .../valhalla/framework/tests/TestSanity.java | 39 +-- .../framework/tests/TestScenarios.java | 7 +- 7 files changed, 331 insertions(+), 297 deletions(-) delete mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFrameworkValhalla.java diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java index c8771436275..3b71b8061a9 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java @@ -3,7 +3,7 @@ import java.util.*; public class Scenario { - // "jtreg -DXcomp=true" runs all the scenarios with -Xcomp. This is faster than "jtreg -javaoptions:-Xcomp". + static final String ADDITIONAL_SCENARIO_FLAGS = System.getProperty("ScenarioFlags", ""); private static final String SCENARIOS = System.getProperty("Scenarios", ""); private static final List additionalScenarioFlags = new ArrayList<>(); @@ -12,10 +12,7 @@ public class Scenario { private final List flags; private final int index; boolean enabled; - - public enum Run { - EXCLUDE_DEFAULT, INCLUDE_DEFAULT - } + private String vmOutput; static { if (!SCENARIOS.isEmpty()) { @@ -54,4 +51,12 @@ public int getIndex() { public boolean isEnabled() { return enabled; } + + public void setVMOutput(String vmOutput) { + this.vmOutput = vmOutput; + } + + public String getVMOutput() { + return vmOutput; + } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 942fc567ef0..4039a6a8be7 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -76,15 +76,23 @@ public class TestFramework { private final HashMap testMethodMap = new HashMap<>(); private List excludeList = null; private List includeList = null; + private List> helperClasses = null; + private List scenarios = null; private final IREncodingPrinter irMatchRulePrinter; + private Class testClass = null; - TestFramework() { + public TestFramework(Class testClass) { + TestRun.check(testClass != null, "Test class cannot be null"); + this.testClass = testClass; // These flags can be overridden fixedDefaultFlags = initDefaultFlags(); compileCommandFlags = initCompileCommandFlags(); printFlags = initPrintFlags(); verifyFlags = initVerifyFlags(); + this.includeList = createTestFilterList(TESTLIST, testClass); + this.excludeList = createTestFilterList(EXCLUDELIST, testClass); + if (PRINT_VALID_IR_RULES) { irMatchRulePrinter = new IREncodingPrinter(); } else { @@ -92,13 +100,6 @@ public class TestFramework { } } - // Only used by a TestVM - private TestFramework(Class testClass) { - this(); - includeList = createTestFilterList(TESTLIST, testClass); - excludeList = createTestFilterList(EXCLUDELIST, testClass); - } - protected String[] initDefaultFlags() { return new String[] {"-XX:-BackgroundCompilation"}; } @@ -148,15 +149,22 @@ public static void main(String[] args) { } TestFramework framework = new TestFramework(testClass); - framework.runTestsOnSameVM(testClass, getHelperClasses(args)); + Class[] helperClasses = getHelperClasses(args); + if (helperClasses != null) { + framework.addHelperClasses(helperClasses); + } + framework.runTestsOnSameVM(); } - private static ArrayList> getHelperClasses(String[] args) { - ArrayList> helperClasses = new ArrayList<>(); + private static Class[] getHelperClasses(String[] args) { + if (args.length == 1) { + return null; + } + Class[] helperClasses = new Class[args.length - 1]; // First argument is test class for (int i = 1; i < args.length; i++) { String helperClassName = args[i]; try { - helperClasses.add(Class.forName(helperClassName)); + helperClasses[i - 1] = Class.forName(helperClassName); } catch (Exception e) { throw new TestRunException("Could not find helper class " + helperClassName, e); } @@ -170,72 +178,72 @@ private static ArrayList> getHelperClasses(String[] args) { */ public static void run() { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - doRun(walker.getCallerClass(), null); + run(walker.getCallerClass()); } public static void run(Class testClass) { - doRun(testClass, null); + TestFramework framework = new TestFramework(testClass); + framework.runTestVM(null); } public static void runWithHelperClasses(Class testClass, Class... helperClasses) { - doRun(testClass, Arrays.asList(helperClasses)); + TestFramework framework = new TestFramework(testClass); + framework.addHelperClasses(helperClasses); + framework.runTestVM(null); } public static void runWithScenarios(Scenario... scenarios) { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - runWithScenarios(Scenario.Run.EXCLUDE_DEFAULT, walker.getCallerClass(), scenarios); + runWithScenarios(walker.getCallerClass(), scenarios); } - public static void runWithScenarios(Scenario.Run runMode, Scenario... scenarios) { - StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - runWithScenarios(runMode, walker.getCallerClass(), scenarios); + public static void runWithScenarios(Class testClass, Scenario... scenarios) { + TestFramework framework = new TestFramework(testClass); + framework.addScenarios(scenarios); + framework.doRunWithScenarios(); } - public static void runWithScenarios(Class testClass, Scenario... scenarios) { - runWithScenariosAndHelperClasses(Scenario.Run.EXCLUDE_DEFAULT, testClass, null, scenarios); + public TestFramework addHelperClasses(Class... helperClasses) { + TestRun.check(helperClasses != null && Arrays.stream(helperClasses).noneMatch(Objects::isNull), "A Helper class cannot be null"); + if (this.helperClasses == null) { + this.helperClasses = new ArrayList<>(); + } + + for (Class helperClass : helperClasses) { + TestRun.check(!this.helperClasses.contains(helperClass), "Cannot add the same class twice: " + helperClass); + this.helperClasses.add(helperClass); + } + return this; } - public static void runWithScenarios(Scenario.Run runMode, Class testClass, Scenario... scenarios) { - runWithScenariosAndHelperClasses(runMode, testClass, null, scenarios); + public TestFramework addScenarios(Scenario... scenarios) { + TestRun.check(scenarios != null && Arrays.stream(scenarios).noneMatch(Objects::isNull), "A scenario cannot be null"); + if (this.scenarios == null) { + this.scenarios = new ArrayList<>(Arrays.asList(scenarios)); + } else { + this.scenarios.addAll(Arrays.asList(scenarios)); + } + return this; } - public static void runWithScenariosAndHelperClasses(Class testClass, List> helperClasses, Scenario... scenarios) { - runWithScenariosAndHelperClasses(Scenario.Run.EXCLUDE_DEFAULT, testClass, helperClasses, scenarios); + public void clear() { + clearHelperClasses(); + clearScenarios(); } - public static void runWithScenariosAndHelperClasses(Scenario.Run runMode, Class testClass, List> helperClasses, Scenario... scenarios) { - TestFramework framework = new TestFramework(); - Map exceptionMap = new HashMap<>(); - // First run without additional scenario flags. - if (runMode == Scenario.Run.INCLUDE_DEFAULT) { - try { - framework.runTestVM(testClass, helperClasses, null); - } catch (Exception e) { - exceptionMap.put("Default Scenario", e); - } - } + public void clearHelperClasses() { + this.helperClasses = null; + } - Set scenarioIndecies = new HashSet<>(); - for (Scenario scenario : scenarios) { - int scenarioIndex = scenario.getIndex(); - TestFormat.check(!scenarioIndecies.contains(scenarioIndex), - "Cannot define two scenarios with the same index " + scenarioIndex); - scenarioIndecies.add(scenarioIndex); - try { - framework.runTestVM(testClass, helperClasses, scenario); - } catch (Exception e) { - exceptionMap.put(String.valueOf(scenarioIndex), e); - } - } - if (!exceptionMap.isEmpty()) { - StringBuilder builder = new StringBuilder("The following scenarios have failed: #"); - builder.append(String.join(", #", exceptionMap.keySet())).append("\n\n"); - for (Map.Entry entry: exceptionMap.entrySet()) { - String title = "Stacktrace for Scenario #" + entry.getKey(); - builder.append(title).append("\n").append("=".repeat(title.length())).append("\n"); - builder.append(entry.getValue().getMessage()).append("\n"); - } - TestRun.fail(builder.toString()); + public void clearScenarios() { + this.scenarios = null; + } + + public void start() { + if (scenarios != null) { + doRunWithScenarios(); + } else { + runTestVM(null); } } @@ -278,19 +286,40 @@ public static String getLastVmOutput() { * End of public interface */ - - private static void doRun(Class testClass, List> helperClasses) { - TestFramework framework = new TestFramework(); - framework.runTestVM(testClass, helperClasses, null); + private void doRunWithScenarios() { + Map exceptionMap = new HashMap<>(); + Set scenarioIndecies = new HashSet<>(); + for (Scenario scenario : scenarios) { + int scenarioIndex = scenario.getIndex(); + TestFormat.check(!scenarioIndecies.contains(scenarioIndex), + "Cannot define two scenarios with the same index " + scenarioIndex); + scenarioIndecies.add(scenarioIndex); + try { + runTestVM(scenario); + } catch (Exception e) { + exceptionMap.put(String.valueOf(scenarioIndex), e); + } + } + if (!exceptionMap.isEmpty()) { + StringBuilder builder = new StringBuilder("The following scenarios have failed: #"); + builder.append(String.join(", #", exceptionMap.keySet())).append("\n\n"); + for (Map.Entry entry: exceptionMap.entrySet()) { + String title = "Stacktrace for Scenario #" + entry.getKey(); + builder.append(title).append("\n").append("=".repeat(title.length())).append("\n"); + builder.append(entry.getValue().getMessage()).append("\n"); + } + TestRun.fail(builder.toString()); + } } - - private void runTestsOnSameVM(Class testClass, ArrayList> helperClasses) { - for (Class helperClass : helperClasses) { - // Process the helper classes and apply the explicit compile commands - processExplicitCompileCommands(helperClass); + private void runTestsOnSameVM() { + if (helperClasses != null) { + for (Class helperClass : helperClasses) { + // Process the helper classes and apply the explicit compile commands + processExplicitCompileCommands(helperClass); + } } - parseTestClass(testClass); + parseTestClass(); runTests(); } @@ -300,18 +329,18 @@ private static void runTestsOnSameVM(Class testClass) { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); testClass = walker.getCallerClass(); } - TestFramework framework = new TestFramework(); - framework.runTestsOnSameVM(testClass, new ArrayList<>()); + TestFramework framework = new TestFramework(testClass); + framework.runTestsOnSameVM(); } - private void runTestVM(Class testClass, List> helperClasses, Scenario scenario) { + private void runTestVM(Scenario scenario) { if (scenario != null && !scenario.isEnabled()) { System.out.println("Disabled scenario #" + scenario.getIndex() + "! This scenario is not present in set flag -DScenarios " + "and is therefore not executed."); return; } - ArrayList cmds = prepareTestVmFlags(testClass, helperClasses, scenario); + ArrayList cmds = prepareTestVmFlags(scenario); OutputAnalyzer oa; try { // Calls 'main' of this class to run all specified tests with commands 'cmds'. @@ -321,6 +350,9 @@ private void runTestVM(Class testClass, List> helperClasses, Scenari } String output = oa.getOutput(); lastVmOutput = output; + if (scenario != null) { + scenario.setVMOutput(output); + } if (VERBOSE || oa.getExitValue() != 0) { System.out.println(" ----- OUTPUT -----"); @@ -334,7 +366,7 @@ private void runTestVM(Class testClass, List> helperClasses, Scenari } } - private ArrayList prepareTestVmFlags(Class testClass, List> helperClasses, Scenario scenario) { + private ArrayList prepareTestVmFlags(Scenario scenario) { String[] vmInputArguments = InputArguments.getVmInputArgs(); ArrayList cmds = new ArrayList<>(); if (!PREFER_COMMAND_LINE_FLAGS) { @@ -371,10 +403,6 @@ private ArrayList prepareTestVmFlags(Class testClass, List> if (helperClasses != null) { helperClasses.forEach(c -> cmds.add(c.getCanonicalName())); } - - if (VERBOSE) { - System.out.println("Command Line: " + String.join(" ", cmds)); - } return cmds; } @@ -407,11 +435,11 @@ private void addBoolOptionForClass(ArrayList cmds, Class testClass, S cmds.add("-XX:CompileCommand=option," + testClass.getCanonicalName() + "::*,bool," + option + ",true"); } - private void parseTestClass(Class clazz) { + private void parseTestClass() { addReplay(); - processExplicitCompileCommands(clazz); - setupTests(clazz); - setupCheckAndRunMethods(clazz); + processExplicitCompileCommands(testClass); + setupTests(); + setupCheckAndRunMethods(); // All remaining tests are simple base tests without check or specific way to run them. addBaseTests(); @@ -561,10 +589,10 @@ static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { WHITE_BOX.enqueueMethodForCompilation(m, compLevel.getValue()); } - private void setupTests(Class clazz) { + private void setupTests() { boolean hasIncludeList = includeList != null; boolean hasExcludeList = excludeList != null; - for (Method m : clazz.getDeclaredMethods()) { + for (Method m : testClass.getDeclaredMethods()) { Test testAnno = getAnnotation(m, Test.class); try { if (testAnno != null) { @@ -664,8 +692,8 @@ private static CompLevel flipCompLevel(CompLevel compLevel) { return compLevel; } - private void setupCheckAndRunMethods(Class clazz) { - for (Method m : clazz.getDeclaredMethods()) { + private void setupCheckAndRunMethods() { + for (Method m : testClass.getDeclaredMethods()) { Check checkAnno = getAnnotation(m, Check.class); Run runAnno = getAnnotation(m, Run.class); Arguments argumentsAnno = getAnnotation(m, Arguments.class); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFrameworkValhalla.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFrameworkValhalla.java deleted file mode 100644 index 767ec829bc6..00000000000 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFrameworkValhalla.java +++ /dev/null @@ -1,20 +0,0 @@ -package compiler.valhalla.framework; - -import jdk.test.lib.Platform; -import jdk.test.lib.management.InputArguments; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.process.ProcessTools; -import sun.hotspot.WhiteBox; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - - -public class TestFrameworkValhalla extends TestFramework { - -} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java index 840bc755298..79616c73423 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -16,8 +16,8 @@ public static void main(String[] args) throws Exception { if (wasExecuted) { throw new RuntimeException("Executed non @Test method or a method that was not intended to be run"); } - for (int i = 0; i < testExecuted.length; i++) { - int value = testExecuted[i]; + for (int i = 0; i < executed.length; i++) { + int value = executed[i]; if (value != TestFramework.WARMUP_ITERATIONS + 1) { // Warmups + 1 C2 compiled invocation throw new RuntimeException("Test " + i + " was executed " + value + " times stead of " @@ -25,7 +25,7 @@ public static void main(String[] args) throws Exception { } } - for (int value : checkExecuted) { + for (int value : executedOnce) { if (value != 1) { throw new RuntimeException("Check function should have been executed exactly once"); } @@ -73,8 +73,8 @@ public static void main(String[] args) throws Exception { // } static boolean wasExecuted = false; - static int[] testExecuted = new int[78]; - static int[] checkExecuted = new int[5]; + static int[] executed = new int[78]; + static int[] executedOnce = new int[5]; boolean lastToggleBoolean = true; long[] nonFloatingRandomNumbers = new long[10]; double[] floatingRandomNumbers = new double[10]; @@ -92,9 +92,10 @@ private void clearRandomBooleans() { randomBooleans = new Boolean[64]; } + // Base test, no arguments, directly invoked. @Test public void test() { - testExecuted[0]++; + executed[0]++; } // Not a test @@ -119,24 +120,26 @@ public static void test(double i) { @Test public static void staticTest() { - testExecuted[1]++; + executed[1]++; } @Test public final void finalTest() { - testExecuted[2]++; + executed[2]++; } @Test public int returnValueTest() { - testExecuted[3]++; + executed[3]++; return 4; } + // Base test, with arguments, directly invoked. + // Specify the argument values with @Arguments @Test @Arguments(ArgumentValue.DEFAULT) public void byteDefaultArgument(byte x) { - testExecuted[4]++; + executed[4]++; if (x != 0) { throw new RuntimeException("Must be 0"); } @@ -145,7 +148,7 @@ public void byteDefaultArgument(byte x) { @Test @Arguments(ArgumentValue.DEFAULT) public void shortDefaultArgument(short x) { - testExecuted[5]++; + executed[5]++; if (x != 0) { throw new RuntimeException("Must be 0"); } @@ -154,7 +157,7 @@ public void shortDefaultArgument(short x) { @Test @Arguments(ArgumentValue.DEFAULT) public void intDefaultArgument(int x) { - testExecuted[6]++; + executed[6]++; if (x != 0) { throw new RuntimeException("Must be 0"); } @@ -163,7 +166,7 @@ public void intDefaultArgument(int x) { @Test @Arguments(ArgumentValue.DEFAULT) public void longDefaultArgument(long x) { - testExecuted[7]++; + executed[7]++; if (x != 0L) { throw new RuntimeException("Must be 0"); } @@ -172,7 +175,7 @@ public void longDefaultArgument(long x) { @Test @Arguments(ArgumentValue.DEFAULT) public void floatDefaultArgument(float x) { - testExecuted[8]++; + executed[8]++; if (x != 0.0f) { throw new RuntimeException("Must be 0.0"); } @@ -181,7 +184,7 @@ public void floatDefaultArgument(float x) { @Test @Arguments(ArgumentValue.DEFAULT) public void doubleDefaultArgument(double x) { - testExecuted[9]++; + executed[9]++; if (x != 0.0f) { throw new RuntimeException("Must be 0.0"); } @@ -190,7 +193,7 @@ public void doubleDefaultArgument(double x) { @Test @Arguments(ArgumentValue.DEFAULT) public void charDefaultArgument(char x) { - testExecuted[10]++; + executed[10]++; if (x != '\u0000') { throw new RuntimeException("Must be \u0000"); } @@ -199,7 +202,7 @@ public void charDefaultArgument(char x) { @Test @Arguments(ArgumentValue.DEFAULT) public void booleanDefaultArgument(boolean x) { - testExecuted[11]++; + executed[11]++; if (x) { throw new RuntimeException("Must be false"); } @@ -208,7 +211,7 @@ public void booleanDefaultArgument(boolean x) { @Test @Arguments(ArgumentValue.DEFAULT) public void stringObjectDefaultArgument(String x) { - testExecuted[12]++; + executed[12]++; if (x == null || x.length() != 0) { throw new RuntimeException("Default string object must be non-null and having a length of zero"); } @@ -217,7 +220,7 @@ public void stringObjectDefaultArgument(String x) { @Test @Arguments(ArgumentValue.DEFAULT) public void defaultObjectDefaultArgument(DefaultObject x) { - testExecuted[13]++; + executed[13]++; if (x == null || x.i != 4) { throw new RuntimeException("Default object must not be null and its i field must be 4"); } @@ -226,7 +229,7 @@ public void defaultObjectDefaultArgument(DefaultObject x) { @Test @Arguments(ArgumentValue.NUMBER_42) public void byte42(byte x) { - testExecuted[14]++; + executed[14]++; if (x != 42) { throw new RuntimeException("Must be 42"); } @@ -235,7 +238,7 @@ public void byte42(byte x) { @Test @Arguments(ArgumentValue.NUMBER_42) public void short42(short x) { - testExecuted[15]++; + executed[15]++; if (x != 42) { throw new RuntimeException("Must be 42"); } @@ -244,7 +247,7 @@ public void short42(short x) { @Test @Arguments(ArgumentValue.NUMBER_42) public void int42(int x) { - testExecuted[16]++; + executed[16]++; if (x != 42) { throw new RuntimeException("Must be 42"); } @@ -253,7 +256,7 @@ public void int42(int x) { @Test @Arguments(ArgumentValue.NUMBER_42) public void long42(long x) { - testExecuted[17]++; + executed[17]++; if (x != 42) { throw new RuntimeException("Must be 42"); } @@ -262,7 +265,7 @@ public void long42(long x) { @Test @Arguments(ArgumentValue.NUMBER_42) public void float42(float x) { - testExecuted[18]++; + executed[18]++; if (x != 42.0) { throw new RuntimeException("Must be 42"); } @@ -271,7 +274,7 @@ public void float42(float x) { @Test @Arguments(ArgumentValue.NUMBER_42) public void double42(double x) { - testExecuted[19]++; + executed[19]++; if (x != 42.0) { throw new RuntimeException("Must be 42"); } @@ -280,7 +283,7 @@ public void double42(double x) { @Test @Arguments(ArgumentValue.FALSE) public void booleanFalse(boolean x) { - testExecuted[20]++; + executed[20]++; if (x) { throw new RuntimeException("Must be false"); } @@ -289,7 +292,7 @@ public void booleanFalse(boolean x) { @Test @Arguments(ArgumentValue.TRUE) public void booleanTrue(boolean x) { - testExecuted[21]++; + executed[21]++; if (!x) { throw new RuntimeException("Must be true"); } @@ -298,37 +301,37 @@ public void booleanTrue(boolean x) { @Test @Arguments(ArgumentValue.RANDOM_ONCE) public void randomByte(byte x) { - testExecuted[22]++; + executed[22]++; } @Test @Arguments(ArgumentValue.RANDOM_ONCE) public void randomShort(short x) { - testExecuted[23]++; + executed[23]++; } @Test @Arguments(ArgumentValue.RANDOM_ONCE) public void randomInt(int x) { - testExecuted[24]++; + executed[24]++; } @Test @Arguments(ArgumentValue.RANDOM_ONCE) public void randomLong(long x) { - testExecuted[25]++; + executed[25]++; } @Test @Arguments(ArgumentValue.RANDOM_ONCE) public void randomFloat(float x) { - testExecuted[26]++; + executed[26]++; } @Test @Arguments(ArgumentValue.RANDOM_ONCE) public void randomDouble(double x) { - testExecuted[27]++; + executed[27]++; } // Not executed @@ -339,13 +342,13 @@ public void randomNotExecutedTest(double x) { @Test @Arguments(ArgumentValue.RANDOM_ONCE) public void randomBoolean(boolean x) { - testExecuted[28]++; + executed[28]++; } @Test @Arguments(ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE) public void booleanToggleFirstFalse(boolean x) { - if (testExecuted[29] == 0) { + if (executed[29] == 0) { // First invocation if (x) { throw new RuntimeException("BOOLEAN_TOGGLE_FIRST_FALSE must be false on first invocation"); @@ -354,63 +357,63 @@ public void booleanToggleFirstFalse(boolean x) { throw new RuntimeException("BOOLEAN_TOGGLE_FIRST_FALSE did not toggle"); } lastToggleBoolean = x; - testExecuted[29]++; + executed[29]++; } @Test @Arguments(ArgumentValue.RANDOM_EACH) public void randomEachByte(byte x) { - checkNonFloatingRandomNumber(x, testExecuted[30]); - testExecuted[30]++; + checkNonFloatingRandomNumber(x, executed[30]); + executed[30]++; } @Test @Arguments(ArgumentValue.RANDOM_EACH) public void randomEachShort(short x) { - checkNonFloatingRandomNumber(x, testExecuted[31]); - testExecuted[31]++; + checkNonFloatingRandomNumber(x, executed[31]); + executed[31]++; } @Test @Arguments(ArgumentValue.RANDOM_EACH) public void randomEachInt(int x) { - checkNonFloatingRandomNumber(x, testExecuted[32]); - testExecuted[32]++; + checkNonFloatingRandomNumber(x, executed[32]); + executed[32]++; } @Test @Arguments(ArgumentValue.RANDOM_EACH) public void randomEachLong(long x) { - checkNonFloatingRandomNumber(x, testExecuted[33]); - testExecuted[33]++; + checkNonFloatingRandomNumber(x, executed[33]); + executed[33]++; } @Test @Arguments(ArgumentValue.RANDOM_EACH) public void randomEachChar(char x) { - checkNonFloatingRandomNumber(x, testExecuted[34]); - testExecuted[34]++; + checkNonFloatingRandomNumber(x, executed[34]); + executed[34]++; } @Test @Arguments(ArgumentValue.RANDOM_EACH) public void randomEachFloat(float x) { - checkFloatingRandomNumber(x, testExecuted[35]); - testExecuted[35]++; + checkFloatingRandomNumber(x, executed[35]); + executed[35]++; } @Test @Arguments(ArgumentValue.RANDOM_EACH) public void randomEachDouble(double x) { - checkFloatingRandomNumber(x, testExecuted[36]); - testExecuted[36]++; + checkFloatingRandomNumber(x, executed[36]); + executed[36]++; } @Test @Arguments(ArgumentValue.RANDOM_EACH) public void randomEachBoolean(boolean x) { - checkRandomBoolean(x, testExecuted[37]); - testExecuted[37]++; + checkRandomBoolean(x, executed[37]); + executed[37]++; } private void checkNonFloatingRandomNumber(long x, int invocationCount) { @@ -462,7 +465,7 @@ private void checkRandomBoolean(boolean x, int invocationCount) { @Test @Arguments(ArgumentValue.NUMBER_MINUS_42) public void byteMinus42(byte x) { - testExecuted[38]++; + executed[38]++; if (x != -42) { throw new RuntimeException("Must be -42"); } @@ -471,7 +474,7 @@ public void byteMinus42(byte x) { @Test @Arguments(ArgumentValue.NUMBER_MINUS_42) public void shortMinus42(short x) { - testExecuted[39]++; + executed[39]++; if (x != -42) { throw new RuntimeException("Must be -42"); } @@ -480,7 +483,7 @@ public void shortMinus42(short x) { @Test @Arguments(ArgumentValue.NUMBER_MINUS_42) public void intMinus42(int x) { - testExecuted[40]++; + executed[40]++; if (x != -42) { throw new RuntimeException("Must be -42"); } @@ -489,7 +492,7 @@ public void intMinus42(int x) { @Test @Arguments(ArgumentValue.NUMBER_MINUS_42) public void longMinus42(long x) { - testExecuted[41]++; + executed[41]++; if (x != -42) { throw new RuntimeException("Must be -42"); } @@ -498,7 +501,7 @@ public void longMinus42(long x) { @Test @Arguments(ArgumentValue.NUMBER_MINUS_42) public void floatMinus42(float x) { - testExecuted[42]++; + executed[42]++; if (x != -42.0) { throw new RuntimeException("Must be -42"); } @@ -507,7 +510,7 @@ public void floatMinus42(float x) { @Test @Arguments(ArgumentValue.NUMBER_MINUS_42) public void doubleMinus42(double x) { - testExecuted[43]++; + executed[43]++; if (x != -42.0) { throw new RuntimeException("Must be -42"); } @@ -516,7 +519,7 @@ public void doubleMinus42(double x) { @Test @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) public void twoArgsDefault1(byte x, short y) { - testExecuted[44]++; + executed[44]++; if (x != 0 || y != 0) { throw new RuntimeException("Both must be 0"); } @@ -525,7 +528,7 @@ public void twoArgsDefault1(byte x, short y) { @Test @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) public void twoArgsDefault2(int x, short y) { - testExecuted[45]++; + executed[45]++; if (x != 0 || y != 0) { throw new RuntimeException("Both must be 0"); } @@ -534,7 +537,7 @@ public void twoArgsDefault2(int x, short y) { @Test @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) public void twoArgsDefault3(short x, long y) { - testExecuted[46]++; + executed[46]++; if (x != 0 || y != 0) { throw new RuntimeException("Both must be 0"); } @@ -543,7 +546,7 @@ public void twoArgsDefault3(short x, long y) { @Test @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) public void twoArgsDefault4(float x, boolean y) { - testExecuted[47]++; + executed[47]++; if (x != 0.0 || y) { throw new RuntimeException("Must be 0 and false"); } @@ -552,7 +555,7 @@ public void twoArgsDefault4(float x, boolean y) { @Test @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) public void twoArgsDefault5(boolean x, char y) { - testExecuted[48]++; + executed[48]++; if (x || y != '\u0000') { throw new RuntimeException("Must be false and \u0000"); } @@ -561,7 +564,7 @@ public void twoArgsDefault5(boolean x, char y) { @Test @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) public void twoArgsDefault6(char x, byte y) { - testExecuted[49]++; + executed[49]++; if (x != '\u0000' || y != 0) { throw new RuntimeException("Must be\u0000 and 0"); } @@ -570,7 +573,7 @@ public void twoArgsDefault6(char x, byte y) { @Test @Arguments({ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE}) public void twoArgsRandomOnce(char x, byte y) { - testExecuted[50]++; + executed[50]++; } @Test @@ -582,7 +585,7 @@ public void checkRandomOnceDifferentArgs(int a, int b, int c, int d, int e, int if (Stream.of(a, b, c, d, e, f, g, h).allMatch(i -> i == a)) { throw new RuntimeException("RANDOM_ONCE does not produce random values for different arguments"); } - testExecuted[51]++; + executed[51]++; } @Test @@ -591,7 +594,7 @@ public void checkRandomOnceDifferentArgs(int a, int b, int c, int d, int e, int ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE}) public void checkMixedRandoms1(byte a, short b, int c, long d, char e, boolean f, float g, double h) { - testExecuted[52]++; + executed[52]++; } @Test @@ -600,7 +603,7 @@ public void checkMixedRandoms1(byte a, short b, int c, long d, char e, boolean f ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_EACH}) public void checkMixedRandoms2(byte a, short b, int c, long d, char e, boolean f, float g, double h) { - testExecuted[53]++; + executed[53]++; } @Test @@ -609,7 +612,7 @@ public void checkMixedRandoms2(byte a, short b, int c, long d, char e, boolean f ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_ONCE}) public void checkMixedRandoms3(byte a, short b, int c, long d, char e, boolean f, float g, double h) { - testExecuted[54]++; + executed[54]++; } @Test @@ -620,7 +623,7 @@ public void check42Mix1(byte a, short b, int c, long d, float e, double f) { if (a != 42 || b != 42 || c != 42 || d != 42 || e != 42.0 || f != 42.0) { throw new RuntimeException("Must all be 42"); } - testExecuted[55]++; + executed[55]++; } @Test @@ -631,7 +634,7 @@ public void check42Mix2(byte a, short b, int c, long d, float e, double f) { if (a != -42 || b != -42 || c != -42 || d != -42 || e != -42.0 || f != -42.0) { throw new RuntimeException("Must all be -42"); } - testExecuted[56]++; + executed[56]++; } @Test @@ -642,14 +645,14 @@ public void check42Mix3(byte a, short b, int c, long d, float e, double f) { if (a != -42 || b != 42 || c != -42 || d != -42 || e != 42.0 || f != -42.0) { throw new RuntimeException("Do not match the right 42 version"); } - testExecuted[57]++; + executed[57]++; } @Test @Arguments(ArgumentValue.BOOLEAN_TOGGLE_FIRST_TRUE) public void booleanToggleFirstTrue(boolean x) { - if (testExecuted[58] == 0) { + if (executed[58] == 0) { // First invocation if (!x) { throw new RuntimeException("BOOLEAN_TOGGLE_FIRST_FALSE must be false on first invocation"); @@ -658,13 +661,13 @@ public void booleanToggleFirstTrue(boolean x) { throw new RuntimeException("BOOLEAN_TOGGLE_FIRST_FALSE did not toggle"); } lastToggleBoolean = x; - testExecuted[58]++; + executed[58]++; } @Test @Arguments({ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE, ArgumentValue.BOOLEAN_TOGGLE_FIRST_TRUE}) public void checkTwoToggles(boolean b1, boolean b2) { - if (testExecuted[59] == 0) { + if (executed[59] == 0) { // First invocation if (b1 || !b2) { throw new RuntimeException("BOOLEAN_TOGGLES have wrong initial value"); @@ -675,14 +678,14 @@ public void checkTwoToggles(boolean b1, boolean b2) { throw new RuntimeException("Booleans did not toggle"); } lastToggleBoolean = b1; - testExecuted[59]++; + executed[59]++; } @Test @Arguments({ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE, ArgumentValue.FALSE, ArgumentValue.TRUE, ArgumentValue.BOOLEAN_TOGGLE_FIRST_TRUE}) public void booleanMix(boolean b1, boolean b2, boolean b3, boolean b4) { - if (testExecuted[60] == 0) { + if (executed[60] == 0) { // First invocation if (b1 || b2 || !b3 || !b4) { throw new RuntimeException("BOOLEAN_TOGGLES have wrong initial value"); @@ -693,176 +696,192 @@ public void booleanMix(boolean b1, boolean b2, boolean b3, boolean b4) { throw new RuntimeException("Booleans did not toggle"); } lastToggleBoolean = b1; - testExecuted[60]++; + executed[60]++; } - @Test - public void testRun() { - testExecuted[61]++; - } - - @Run(test = "testRun") - public void runTestRun(TestInfo info) { - testRun(); - } - - @Test - public void testRunNoTestInfo(int i) { // Argument allowed when run by @Run - testExecuted[62]++; - } - - @Run(test = "testRunNoTestInfo") - public void runTestRunNoTestInfo() { - testRunNoTestInfo(3); - } - - @Test - public void testNotRun() { - wasExecuted = true; - } - - @Run(test = "testNotRun") - public void runTestNotRun() { - // Do not execute the test. Pointless but need to test that as well. - } + /* + * Checked tests. + */ @Test public int testCheck() { - testExecuted[63]++; + executed[63]++; return 1; } + // Checked test. Check invoked after invoking "testCheck". Perform some more things after invocation. @Check(test = "testCheck") public void checkTestCheck() { - testExecuted[64]++; // Executed on each invocation + executed[64]++; // Executed on each invocation } @Test public int testCheckReturn() { - testExecuted[65]++; + executed[65]++; return 2; } + // Checked test with return value. Perform checks on it. @Check(test = "testCheckReturn") public void checkTestCheckReturn(int returnValue) { if (returnValue != 2) { throw new RuntimeException("Must be 2"); } - testExecuted[66]++; // Executed on each invocation + executed[66]++; // Executed on each invocation } @Test public int testCheckTestInfo() { - testExecuted[67]++; + executed[67]++; return 3; } + // Checked test with info object about test. @Check(test = "testCheckTestInfo") public void checkTestCheckTestInfo(TestInfo testInfo) { - testExecuted[68]++; // Executed on each invocation + executed[68]++; // Executed on each invocation } @Test public int testCheckBoth() { - testExecuted[69]++; + executed[69]++; return 4; } + // Checked test with return value and info object about test. @Check(test = "testCheckBoth") public void checkTestCheckTestInfo(int returnValue, TestInfo testInfo) { if (returnValue != 4) { throw new RuntimeException("Must be 4"); } - testExecuted[70]++; // Executed on each invocation + executed[70]++; // Executed on each invocation } @Test public int testCheckOnce() { - testExecuted[71]++; + executed[71]++; return 1; } - @Check(test = "testCheckOnce", when=CheckAt.COMPILED) + // Check method only invoked once after method is compiled after warm up. + @Check(test = "testCheckOnce", when = CheckAt.COMPILED) public void checkTestCheckOnce() { - checkExecuted[0]++; // Executed once + executedOnce[0]++; // Executed once } @Test public int testCheckReturnOnce() { - testExecuted[72]++; + executed[72]++; return 2; } - @Check(test = "testCheckReturnOnce", when=CheckAt.COMPILED) + @Check(test = "testCheckReturnOnce", when = CheckAt.COMPILED) public void checkTestCheckReturnOnce(int returnValue) { if (returnValue != 2) { throw new RuntimeException("Must be 2"); } - checkExecuted[1]++; // Executed once + executedOnce[1]++; // Executed once } @Test public int testCheckTestInfoOnce() { - testExecuted[73]++; + executed[73]++; return 3; } - @Check(test = "testCheckTestInfoOnce", when=CheckAt.COMPILED) + @Check(test = "testCheckTestInfoOnce", when = CheckAt.COMPILED) public void checkTestCheckTestInfoOnce(TestInfo testInfo) { - checkExecuted[2]++; // Executed once + executedOnce[2]++; // Executed once } @Test public int testCheckBothOnce() { - testExecuted[74]++; + executed[74]++; return 4; } - @Check(test = "testCheckBothOnce", when=CheckAt.COMPILED) + @Check(test = "testCheckBothOnce", when = CheckAt.COMPILED) public void checkTestCheckBothOnce(int returnValue, TestInfo testInfo) { if (returnValue != 4) { throw new RuntimeException("Must be 4"); } - checkExecuted[3]++; // Executed once + executedOnce[3]++; // Executed once } @Test - public void testRunOnce() { - checkExecuted[4]++; + public void sameName() { + executed[76]++; } - @Run(test = "testRunOnce", mode=RunMode.INVOKE_ONCE) - public void runTestRunOnce(TestInfo info) { - testRunOnce(); + // Allowed to overload test method if not test method itself + public void sameName(boolean a) { + wasExecuted = true; + } + + @Check(test = "sameName") + public void checkSameName() { + executed[77]++; } + /* + * Custom run tests. + */ @Test - public void testRunOnce2() { - testExecuted[75]++; + public void testRun() { + executed[61]++; } - @Run(test = "testRunOnce2", mode=RunMode.INVOKE_ONCE) - public void runTestRunOnce2(TestInfo info) { - for (int i = 0; i < TestFramework.WARMUP_ITERATIONS + 1; i++) { - testRunOnce2(); - } + // Custom run test. This method is invoked each time instead of @Test method. This method responsible for calling + // the @Test method. @Test method is compiled after warm up. This is similar to the verifiers in the old Valhalla framework. + @Run(test = "testRun") + public void runTestRun(TestInfo info) { + testRun(); } @Test - public void sameName() { - testExecuted[76]++; + public void testRunNoTestInfo(int i) { // Argument allowed when run by @Run + executed[62]++; } - // Allowed to overload test method if not test method itself - public void sameName(boolean a) { + @Run(test = "testRunNoTestInfo") + public void runTestRunNoTestInfo() { + testRunNoTestInfo(3); + } + + @Test + public void testNotRun() { wasExecuted = true; } - @Check(test = "sameName") - public void checkSameName() { - testExecuted[77]++; + @Run(test = "testNotRun") + public void runTestNotRun() { + // Do not execute the test. Pointless but need to test that as well. + } + + @Test + public void testRunOnce() { + executedOnce[4]++; + } + + // Custom run test that is only invoked once. There is no warm up and no compilation. This method is responsible + // for triggering compilation. + @Run(test = "testRunOnce", mode = RunMode.INVOKE_ONCE) + public void runTestRunOnce(TestInfo info) { + testRunOnce(); + } + + @Test + public void testRunOnce2() { + executed[75]++; + } + + @Run(test = "testRunOnce2", mode = RunMode.INVOKE_ONCE) + public void runTestRunOnce2(TestInfo info) { + for (int i = 0; i < TestFramework.WARMUP_ITERATIONS + 1; i++) { + testRunOnce2(); + } } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java index aa3f7a31a79..fcecebcdbbd 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java @@ -42,22 +42,22 @@ public static void main(String[] args) { Constraint.failOnNodes(MultipleFailOnBad.class, "fail9()", 1,true, "Store", "CallStaticJava"), Constraint.failOnMatches(MultipleFailOnBad.class, "fail10()", 1,true, "Store", "iFld")); - runFailOnTests(Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 1,true, "MyClass"), - Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 2,true, "MyClass"), - Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 3,false, "MyClass"), - Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 4,false, "MyClass"), - Constraint.failOnArrayAlloc(VariousIrNodes.class, "allocArray()", 5,true, "MyClass"), - Constraint.failOnNodes(VariousIrNodes.class, "loop()", 1, true, "Loop"), - Constraint.failOnNodes(VariousIrNodes.class, "loop()", 2, false, "CountedLoop"), - Constraint.failOnNodes(VariousIrNodes.class, "countedLoop()", 1, false, "Loop"), - Constraint.failOnNodes(VariousIrNodes.class, "countedLoop()", 2, true, "CountedLoop"), - Constraint.failOnNodes(VariousIrNodes.class, "loopAndCountedLoop()", 1, true, "Loop"), - Constraint.failOnNodes(VariousIrNodes.class, "loopAndCountedLoop()", 2, true, "CountedLoop"), - Constraint.failOnNodes(VariousIrNodes.class, "load()", 1, true, "Load"), - Constraint.failOnNodes(VariousIrNodes.class, "load()", 2, true, "VariousIrNodes"), - Constraint.failOnNodes(VariousIrNodes.class, "load()", 3, true, "VariousIrNodes"), - Constraint.failOnMatches(VariousIrNodes.class, "load()", 4, true, "Load", "iFld"), - Constraint.failOnNodes(VariousIrNodes.class, "load()", 5, false, "Load") + runFailOnTests(Constraint.failOnArrayAlloc(VariousIRNodes.class, "allocArray()", 1, true, "MyClass"), + Constraint.failOnArrayAlloc(VariousIRNodes.class, "allocArray()", 2, true, "MyClass"), + Constraint.failOnArrayAlloc(VariousIRNodes.class, "allocArray()", 3, false, "MyClass"), + Constraint.failOnArrayAlloc(VariousIRNodes.class, "allocArray()", 4, false, "MyClass"), + Constraint.failOnArrayAlloc(VariousIRNodes.class, "allocArray()", 5, true, "MyClass"), + Constraint.failOnNodes(VariousIRNodes.class, "loop()", 1, true, "Loop"), + Constraint.failOnNodes(VariousIRNodes.class, "loop()", 2, false, "CountedLoop"), + Constraint.failOnNodes(VariousIRNodes.class, "countedLoop()", 1, false, "Loop"), + Constraint.failOnNodes(VariousIRNodes.class, "countedLoop()", 2, true, "CountedLoop"), + Constraint.failOnNodes(VariousIRNodes.class, "loopAndCountedLoop()", 1, true, "Loop"), + Constraint.failOnNodes(VariousIRNodes.class, "loopAndCountedLoop()", 2, true, "CountedLoop"), + Constraint.failOnNodes(VariousIRNodes.class, "load()", 1, true, "Load"), + Constraint.failOnNodes(VariousIRNodes.class, "load()", 2, true, "VariousIRNodes"), + Constraint.failOnNodes(VariousIRNodes.class, "load()", 3, true, "VariousIRNodes"), + Constraint.failOnMatches(VariousIRNodes.class, "load()", 4, true, "Load", "iFld"), + Constraint.failOnNodes(VariousIRNodes.class, "load()", 5, false, "Load") ); runWithArguments(CountComparisons.class, "-XX:SuspendRetryCount=50"); @@ -273,7 +273,7 @@ class FlagComparisons { @IR(applyIf = {"SuspendRetryCount", "50"}) // Index 0 @IR(applyIf = {"SuspendRetryCount", "=50"}) @IR(applyIf = {"SuspendRetryCount", "= 50"}) - @IR(applyIf = {"SuspendRetryCount", " = 50"}) + @IR(applyIf = {"SuspendRetryCount", " = 50"}) @IR(applyIf = {"SuspendRetryCount", "<=50"}) // Index 4 @IR(applyIf = {"SuspendRetryCount", "<= 50"}) @IR(applyIf = {"SuspendRetryCount", " <= 50"}) @@ -466,7 +466,7 @@ public void bad3() { } // Test on remaining IR nodes that we have not tested above, yet. -class VariousIrNodes { +class VariousIRNodes { MyClass[] myClassArray; int limit = 1024; int iFld = 34; @@ -515,8 +515,8 @@ public void dontInline() {} @Test @IR(failOn = {IRNode.LOAD}) - @IR(failOn = {IRNode.LOAD_OF_CLASS, "compiler/valhalla/framework/tests/VariousIrNodes"}) - @IR(failOn = {IRNode.LOAD_OF_CLASS, "VariousIrNodes"}) + @IR(failOn = {IRNode.LOAD_OF_CLASS, "compiler/valhalla/framework/tests/VariousIRNodes"}) + @IR(failOn = {IRNode.LOAD_OF_CLASS, "VariousIRNodes"}) @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld"}) @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld2", IRNode.LOAD_OF_CLASS, "Various"}) // Does not fail public void load() { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java index 544ae18700b..2daa8fda2a7 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java @@ -13,34 +13,35 @@ public static void main(String[] args) { TestFramework.run(TestSanity.class); TestFramework.runWithHelperClasses(TestSanity.class, HelperA.class); TestFramework.runWithHelperClasses(TestSanity.class, HelperA.class, HelperB.class); + Scenario sDefault = new Scenario(0); Scenario s1 = new Scenario(1, "-XX:SuspendRetryCount=52", "-XX:+UseTLAB"); Scenario s2 = new Scenario(2, "-XX:SuspendRetryCount=53", "-XX:+UseTLAB"); TestFramework.runWithScenarios(s1); TestFramework.runWithScenarios(s1, s2); TestFramework.runWithScenarios(TestSanity.class, s1, s2); - TestFramework.runWithScenarios(Scenario.Run.INCLUDE_DEFAULT, s1); - TestFramework.runWithScenarios(Scenario.Run.INCLUDE_DEFAULT, s1, s2); - TestFramework.runWithScenarios(Scenario.Run.INCLUDE_DEFAULT, TestSanity.class, s1); - TestFramework.runWithScenarios(Scenario.Run.INCLUDE_DEFAULT, TestSanity.class, s1, s2); - ArrayList> helperClasses = new ArrayList<>(); - helperClasses.add(HelperA.class); - helperClasses.add(HelperB.class); - TestFramework.runWithScenariosAndHelperClasses(TestSanity.class, helperClasses, s2); - TestFramework.runWithScenariosAndHelperClasses(TestSanity.class, helperClasses, s1, s2); - TestFramework.runWithScenariosAndHelperClasses(Scenario.Run.INCLUDE_DEFAULT, TestSanity.class, helperClasses, s2); - TestFramework.runWithScenariosAndHelperClasses(Scenario.Run.INCLUDE_DEFAULT, TestSanity.class, helperClasses, s1, s2); + TestFramework.runWithScenarios(sDefault, s1); + TestFramework.runWithScenarios(sDefault, s1, s2); + TestFramework.runWithScenarios(TestSanity.class, sDefault, s1); + TestFramework.runWithScenarios(TestSanity.class, sDefault, s1, s2); + TestFramework testFramework = new TestFramework(TestSanity.class); + testFramework.start(); + testFramework.addHelperClasses(HelperA.class, HelperB.class).start(); + testFramework.clearHelperClasses(); + testFramework.addHelperClasses(HelperA.class, HelperB.class).addHelperClasses(HelperC.class).start(); + testFramework.clearHelperClasses(); + testFramework.addScenarios(sDefault).addScenarios(s1, s2).start(); + testFramework.clearScenarios(); + testFramework.addHelperClasses(HelperA.class).addScenarios(sDefault).start(); + testFramework.clear(); + testFramework.addHelperClasses(HelperA.class).addScenarios(sDefault).addHelperClasses(HelperB.class, HelperC.class) + .addScenarios(s1, s2).start(); } @Test public void test() { - System.out.println("test"); } } -class HelperA { - -} - -class HelperB { - -} +class HelperA { } +class HelperB { } +class HelperC { } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java index cf38e16506f..ee1cadbda2b 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java @@ -5,17 +5,18 @@ public class TestScenarios { public static void main(String[] args) { + Scenario sDefault = new Scenario(0); Scenario s1 = new Scenario(1, "-XX:SuspendRetryCount=51"); Scenario s2 = new Scenario(2, "-XX:SuspendRetryCount=52"); Scenario s3 = new Scenario(3, "-XX:SuspendRetryCount=53"); Scenario s3dup = new Scenario(3, "-XX:SuspendRetryCount=53"); try { - TestFramework.runWithScenarios(Scenario.Run.INCLUDE_DEFAULT, s1, s2, s3); + TestFramework.runWithScenarios(sDefault, s1, s2, s3); } catch (TestRunException e) { - Asserts.assertTrue(e.getMessage().contains("The following scenarios have failed: #1, #3, #Default Scenario")); + Asserts.assertTrue(e.getMessage().contains("The following scenarios have failed: #0, #1, #3")); } try { - TestFramework.runWithScenarios(s1, s2, s3); // Default scenario excluded by default. + TestFramework.runWithScenarios(s1, s2, s3); } catch (TestRunException e) { Asserts.assertTrue(e.getMessage().contains("The following scenarios have failed: #1, #3")); } From c99eb3bc982a5b014cd32b5ca0e56debcc05bd4c Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 1 Feb 2021 13:50:47 +0100 Subject: [PATCH 015/131] Rename ArgumentValue <-> Argument --- .../compiler/valhalla/framework/Argument.java | 209 +----------------- .../valhalla/framework/ArgumentValue.java | 207 ++++++++++++++++- .../valhalla/framework/Arguments.java | 2 +- .../valhalla/framework/TestFramework.java | 10 +- .../framework/tests/TestBadFormat.java | 24 +- .../valhalla/framework/tests/TestBasics.java | 152 ++++++------- .../framework/tests/TestIRMatching.java | 2 +- .../framework/tests/TestPackagePrivate.java | 7 +- 8 files changed, 305 insertions(+), 308 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java index b5c5253a536..34a1bcf96e5 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java @@ -1,200 +1,15 @@ package compiler.valhalla.framework; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.lang.reflect.Parameter; -import java.util.Random; - -class Argument { - private static final Random random = new Random(); - - final private Object argumentValue; - final private boolean isToggleBoolean; - final private boolean isRandomEach; - final private boolean isFixedRandom; - final private Class randomClass; - private boolean previousBoolean; - - private Argument(Object argumentValue, Boolean booleanToggle, boolean isFixedRandom) { - this.argumentValue = argumentValue; - this.isToggleBoolean = booleanToggle != null; - this.previousBoolean = isToggleBoolean && !booleanToggle; - this.isRandomEach = false; - this.randomClass = null; - this.isFixedRandom = isFixedRandom; - } - - private Argument(Object argumentValue, Class randomClass) { - this.argumentValue = argumentValue; - this.isToggleBoolean = false; - this.isRandomEach = true; - this.randomClass = randomClass; - this.isFixedRandom = false; - } - - /** - * Return all arguments for the @Arguments annotation. - * @param m The @Test method - * @return Return array with Argument objects for each specified argument in the @Arguments annotation of m. - * Return null if method has no @Arguments annotation. - */ - public static Argument[] getArguments(Method m) { - Arguments argumentsAnno = m.getAnnotation(Arguments.class); - if (argumentsAnno == null) { - return null; - } - ArgumentValue[] values = argumentsAnno.value(); - Argument[] arguments = new Argument[values.length]; - Class[] declaredParameters = m.getParameterTypes(); - Parameter[] declaredParameterObjects = m.getParameters(); - TestFormat.check(values.length == declaredParameters.length, - "Number of argument values provided in @Arguments does not match the number of actual arguments in " + m); - - for (int i = 0; i < values.length; i++) { - ArgumentValue specifiedArg = values[i]; - Class parameter = declaredParameters[i]; - Parameter parameterObj = declaredParameterObjects[i]; - try { - switch (specifiedArg) { - case DEFAULT -> arguments[i] = createDefault(parameter); - case NUMBER_42 -> { - TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_42 argument for non-number " + parameterObj + " for " + m); - arguments[i] = create((byte) 42); - } - case NUMBER_MINUS_42 -> { - TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_MINUS_42 argument for non-number " + parameterObj + " for " + m); - arguments[i] = create((byte) -42); - } - case BOOLEAN_TOGGLE_FIRST_FALSE -> { - TestFormat.check(isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + parameterObj + " for " + m); - arguments[i] = createToggleBoolean(false); - } - case BOOLEAN_TOGGLE_FIRST_TRUE -> { - TestFormat.check(Argument.isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + parameterObj + " for " + m); - arguments[i] = createToggleBoolean(true); - } - case TRUE -> { - TestFormat.check(Argument.isBoolean(parameter), "Provided invalid TRUE argument for non-boolean " + parameterObj + " for " + m); - arguments[i] = create(true); - } - case FALSE -> { - TestFormat.check(Argument.isBoolean(parameter), "Provided invalid FALSE argument for non-boolean " + parameterObj + " for " + m); - arguments[i] = create(false); - } - case RANDOM_ONCE -> { - TestFormat.check(isPrimitiveType(parameter), "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameterObj + " for " + m); - arguments[i] = createRandom(parameter); - } - case RANDOM_EACH -> { - TestFormat.check(isPrimitiveType(parameter), "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameterObj + " for " + m); - arguments[i] = createRandomEach(parameter); - } - } - } catch (TestFormatException e) { - // Catch and continue to check arguments. - } - } - return arguments; - } - - private static Argument create(Object argumentValue) { - return new Argument(argumentValue, null,false); - } - - private static Argument createDefault(Class c) { - if (Argument.isNumber(c)) { - return Argument.create((byte)0); - } else if (Argument.isChar(c)) { - return Argument.create('\u0000'); - } else if (Argument.isBoolean(c)) { - return Argument.create(false); - } else { - // Object - try { - Constructor constructor = c.getDeclaredConstructor(); - constructor.setAccessible(true); - return Argument.create(constructor.newInstance()); - } catch (Exception e) { - TestFormat.fail("Cannot create new default instance of " + c + ": " + e.getCause()); - return null; - } - } - } - - private static Argument createRandom(Class c) { - return new Argument(getRandom(c), null, true); - } - private static Argument createToggleBoolean(boolean firstBoolean) { - return new Argument(null, firstBoolean, false); - } - - private static Argument createRandomEach(Class c) { - return new Argument(null, c); - } - - public boolean isFixedRandom() { - return isFixedRandom; - } - - public Object getArgument() { - if (isToggleBoolean) { - previousBoolean = !previousBoolean; - return previousBoolean; - } else if (isRandomEach) { - return getRandom(randomClass); - } else { - return argumentValue; - } - } - - private static boolean isPrimitiveType(Class c) { - return isNumber(c) || isBoolean(c) || isChar(c); - } - - private static boolean isBoolean(Class c) { - return c.equals(boolean.class); - } - - private static boolean isChar(Class c) { - return c.equals(char.class); - } - private static boolean isNumber(Class c) { - return isIntNumber(c) || isFloatNumber(c); - } - - private static boolean isIntNumber(Class c) { - return c.equals(byte.class) - || c.equals(short.class) - || c.equals(int.class) - || c.equals(long.class); - } - - public static boolean isFloatNumber(Class c) { - return c.equals(float.class) || c.equals(double.class); - } - - private static Object getRandom(Class c) { - if (isBoolean(c)) { - return random.nextBoolean(); - } else if (c.equals(byte.class)) { - return (byte)random.nextInt(256); - } else if (isChar(c)) { - return (char)random.nextInt(65536); - } else if (c.equals(short.class)) { - return (short)random.nextInt(65536); - } else if (c.equals(int.class)) { - return random.nextInt(); - } else if (c.equals(long.class)) { - return random.nextLong(); - } else if (c.equals(float.class)) { - // Get number between 0 and 1000. - return random.nextFloat() * 1000; - } else if (c.equals(double.class)) { - // Get number between 0 and 1000. - return random.nextDouble() * 1000; - } else { - TestFormat.fail("Cannot generate random value for non-primitive type"); - return null; - } - } +public enum Argument { + DEFAULT, + NUMBER_MINUS_42, + NUMBER_42, + BOOLEAN_TOGGLE_FIRST_FALSE, + BOOLEAN_TOGGLE_FIRST_TRUE, + TRUE, + FALSE, + RANDOM_ONCE, + RANDOM_EACH, + MAX, // TODO -> for numbers + MIN // TODO -> for numbers } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java index 0d3c66ede2d..82e413d2371 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java @@ -1,13 +1,200 @@ package compiler.valhalla.framework; -public enum ArgumentValue { - DEFAULT, - NUMBER_MINUS_42, - NUMBER_42, - BOOLEAN_TOGGLE_FIRST_FALSE, - BOOLEAN_TOGGLE_FIRST_TRUE, - TRUE, - FALSE, - RANDOM_ONCE, - RANDOM_EACH +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.Random; + +class ArgumentValue { + private static final Random random = new Random(); + + final private Object argumentValue; + final private boolean isToggleBoolean; + final private boolean isRandomEach; + final private boolean isFixedRandom; + final private Class randomClass; + private boolean previousBoolean; + + private ArgumentValue(Object argumentValue, Boolean booleanToggle, boolean isFixedRandom) { + this.argumentValue = argumentValue; + this.isToggleBoolean = booleanToggle != null; + this.previousBoolean = isToggleBoolean && !booleanToggle; + this.isRandomEach = false; + this.randomClass = null; + this.isFixedRandom = isFixedRandom; + } + + private ArgumentValue(Object argumentValue, Class randomClass) { + this.argumentValue = argumentValue; + this.isToggleBoolean = false; + this.isRandomEach = true; + this.randomClass = randomClass; + this.isFixedRandom = false; + } + + /** + * Return all arguments for the @Arguments annotation. + * @param m The @Test method + * @return Return array with Argument objects for each specified argument in the @Arguments annotation of m. + * Return null if method has no @Arguments annotation. + */ + public static ArgumentValue[] getArguments(Method m) { + Arguments argumentsAnno = m.getAnnotation(Arguments.class); + if (argumentsAnno == null) { + return null; + } + Argument[] values = argumentsAnno.value(); + ArgumentValue[] arguments = new ArgumentValue[values.length]; + Class[] declaredParameters = m.getParameterTypes(); + Parameter[] declaredParameterObjects = m.getParameters(); + TestFormat.check(values.length == declaredParameters.length, + "Number of argument values provided in @Arguments does not match the number of actual arguments in " + m); + + for (int i = 0; i < values.length; i++) { + Argument specifiedArg = values[i]; + Class parameter = declaredParameters[i]; + Parameter parameterObj = declaredParameterObjects[i]; + try { + switch (specifiedArg) { + case DEFAULT -> arguments[i] = createDefault(parameter); + case NUMBER_42 -> { + TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_42 argument for non-number " + parameterObj + " for " + m); + arguments[i] = create((byte) 42); + } + case NUMBER_MINUS_42 -> { + TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_MINUS_42 argument for non-number " + parameterObj + " for " + m); + arguments[i] = create((byte) -42); + } + case BOOLEAN_TOGGLE_FIRST_FALSE -> { + TestFormat.check(isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + parameterObj + " for " + m); + arguments[i] = createToggleBoolean(false); + } + case BOOLEAN_TOGGLE_FIRST_TRUE -> { + TestFormat.check(ArgumentValue.isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + parameterObj + " for " + m); + arguments[i] = createToggleBoolean(true); + } + case TRUE -> { + TestFormat.check(ArgumentValue.isBoolean(parameter), "Provided invalid TRUE argument for non-boolean " + parameterObj + " for " + m); + arguments[i] = create(true); + } + case FALSE -> { + TestFormat.check(ArgumentValue.isBoolean(parameter), "Provided invalid FALSE argument for non-boolean " + parameterObj + " for " + m); + arguments[i] = create(false); + } + case RANDOM_ONCE -> { + TestFormat.check(isPrimitiveType(parameter), "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameterObj + " for " + m); + arguments[i] = createRandom(parameter); + } + case RANDOM_EACH -> { + TestFormat.check(isPrimitiveType(parameter), "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameterObj + " for " + m); + arguments[i] = createRandomEach(parameter); + } + } + } catch (TestFormatException e) { + // Catch and continue to check arguments. + } + } + return arguments; + } + + private static ArgumentValue create(Object argumentValue) { + return new ArgumentValue(argumentValue, null, false); + } + + private static ArgumentValue createDefault(Class c) { + if (ArgumentValue.isNumber(c)) { + return ArgumentValue.create((byte)0); + } else if (ArgumentValue.isChar(c)) { + return ArgumentValue.create('\u0000'); + } else if (ArgumentValue.isBoolean(c)) { + return ArgumentValue.create(false); + } else { + // Object + try { + Constructor constructor = c.getDeclaredConstructor(); + constructor.setAccessible(true); + return ArgumentValue.create(constructor.newInstance()); + } catch (Exception e) { + TestFormat.fail("Cannot create new default instance of " + c + ": " + e.getCause()); + return null; + } + } + } + + private static ArgumentValue createRandom(Class c) { + return new ArgumentValue(getRandom(c), null, true); + } + private static ArgumentValue createToggleBoolean(boolean firstBoolean) { + return new ArgumentValue(null, firstBoolean, false); + } + + private static ArgumentValue createRandomEach(Class c) { + return new ArgumentValue(null, c); + } + + public boolean isFixedRandom() { + return isFixedRandom; + } + + public Object getArgument() { + if (isToggleBoolean) { + previousBoolean = !previousBoolean; + return previousBoolean; + } else if (isRandomEach) { + return getRandom(randomClass); + } else { + return argumentValue; + } + } + + private static boolean isPrimitiveType(Class c) { + return isNumber(c) || isBoolean(c) || isChar(c); + } + + private static boolean isBoolean(Class c) { + return c.equals(boolean.class); + } + + private static boolean isChar(Class c) { + return c.equals(char.class); + } + private static boolean isNumber(Class c) { + return isIntNumber(c) || isFloatNumber(c); + } + + private static boolean isIntNumber(Class c) { + return c.equals(byte.class) + || c.equals(short.class) + || c.equals(int.class) + || c.equals(long.class); + } + + public static boolean isFloatNumber(Class c) { + return c.equals(float.class) || c.equals(double.class); + } + + private static Object getRandom(Class c) { + if (isBoolean(c)) { + return random.nextBoolean(); + } else if (c.equals(byte.class)) { + return (byte)random.nextInt(256); + } else if (isChar(c)) { + return (char)random.nextInt(65536); + } else if (c.equals(short.class)) { + return (short)random.nextInt(65536); + } else if (c.equals(int.class)) { + return random.nextInt(); + } else if (c.equals(long.class)) { + return random.nextLong(); + } else if (c.equals(float.class)) { + // Get number between 0 and 1000. + return random.nextFloat() * 1000; + } else if (c.equals(double.class)) { + // Get number between 0 and 1000. + return random.nextDouble() * 1000; + } else { + TestFormat.fail("Cannot generate random value for non-primitive type"); + return null; + } + } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java index 667ef43cfc3..69877f8284a 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java @@ -5,5 +5,5 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Arguments { - ArgumentValue[] value(); + Argument[] value(); } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 4039a6a8be7..59d28d36940 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -642,7 +642,7 @@ private void addTest(Method m) { if (FLIP_C1_C2) { compLevel = flipCompLevel(compLevel); } - DeclaredTest test = new DeclaredTest(m, Argument.getArguments(m), compLevel, warmupIterations, osrOnly); + DeclaredTest test = new DeclaredTest(m, ArgumentValue.getArguments(m), compLevel, warmupIterations, osrOnly); declaredTests.put(m, test); testMethodMap.put(m.getName(), m); } @@ -876,12 +876,12 @@ public TestFrameworkException(String message, Exception e) { class DeclaredTest { private final Method testMethod; - private final Argument[] arguments; + private final ArgumentValue[] arguments; private final int warmupIterations; private final CompLevel compLevel; private final boolean osrOnly; - public DeclaredTest(Method testMethod, Argument[] arguments, CompLevel compLevel, int warmupIterations, boolean osrOnly) { + public DeclaredTest(Method testMethod, ArgumentValue[] arguments, CompLevel compLevel, int warmupIterations, boolean osrOnly) { // Make sure we can also call non-public or public methods in package private classes testMethod.setAccessible(true); this.testMethod = testMethod; @@ -912,7 +912,7 @@ public boolean hasArguments() { } public Object[] getArguments() { - return Arrays.stream(arguments).map(Argument::getArgument).toArray(); + return Arrays.stream(arguments).map(ArgumentValue::getArgument).toArray(); } public void printFixedRandomArguments() { @@ -920,7 +920,7 @@ public void printFixedRandomArguments() { boolean hasRandomArgs = false; StringBuilder builder = new StringBuilder("Random Arguments: "); for (int i = 0; i < arguments.length; i++) { - Argument argument = arguments[i]; + ArgumentValue argument = arguments[i]; if (argument.isFixedRandom()) { hasRandomArgs = true; builder.append("arg ").append(i).append(": ").append(argument.getArgument()).append(", "); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java index 10affb6a205..098b1700697 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java @@ -40,44 +40,44 @@ class BadArguments { public void noArgAnnotation(int a) {} @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void argNumberMismatch(int a, int b) {} @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void argNumberMismatch2() {} @Test - @Arguments(ArgumentValue.NUMBER_42) + @Arguments(Argument.NUMBER_42) public void notBoolean(boolean a) {} @Test - @Arguments(ArgumentValue.NUMBER_MINUS_42) + @Arguments(Argument.NUMBER_MINUS_42) public void notBoolean2(boolean a) {} @Test - @Arguments(ArgumentValue.TRUE) + @Arguments(Argument.TRUE) public void notNumber(int a) {} @Test - @Arguments(ArgumentValue.FALSE) + @Arguments(Argument.FALSE) public void notNumber2(int a) {} @Test - @Arguments(ArgumentValue.BOOLEAN_TOGGLE_FIRST_TRUE) + @Arguments(Argument.BOOLEAN_TOGGLE_FIRST_TRUE) public void notNumber3(int a) {} @Test - @Arguments(ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE) + @Arguments(Argument.BOOLEAN_TOGGLE_FIRST_FALSE) public void notNumber4(int a) {} @Test - @Arguments({ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE, ArgumentValue.TRUE}) + @Arguments({Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.TRUE}) public void notNumber5(boolean a, int b) {} @Test - @Arguments({ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE, ArgumentValue.NUMBER_42}) + @Arguments({Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.NUMBER_42}) public void notNumber6(int a, boolean b) {} } @@ -87,11 +87,11 @@ class BadOverloadedMethod { public void sameName() {} @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void sameName(boolean a) {} @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void sameName(double a) {} } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java index 79616c73423..8223fdce83a 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -137,7 +137,7 @@ public int returnValueTest() { // Base test, with arguments, directly invoked. // Specify the argument values with @Arguments @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void byteDefaultArgument(byte x) { executed[4]++; if (x != 0) { @@ -146,7 +146,7 @@ public void byteDefaultArgument(byte x) { } @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void shortDefaultArgument(short x) { executed[5]++; if (x != 0) { @@ -155,7 +155,7 @@ public void shortDefaultArgument(short x) { } @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void intDefaultArgument(int x) { executed[6]++; if (x != 0) { @@ -164,7 +164,7 @@ public void intDefaultArgument(int x) { } @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void longDefaultArgument(long x) { executed[7]++; if (x != 0L) { @@ -173,7 +173,7 @@ public void longDefaultArgument(long x) { } @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void floatDefaultArgument(float x) { executed[8]++; if (x != 0.0f) { @@ -182,7 +182,7 @@ public void floatDefaultArgument(float x) { } @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void doubleDefaultArgument(double x) { executed[9]++; if (x != 0.0f) { @@ -191,7 +191,7 @@ public void doubleDefaultArgument(double x) { } @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void charDefaultArgument(char x) { executed[10]++; if (x != '\u0000') { @@ -200,7 +200,7 @@ public void charDefaultArgument(char x) { } @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void booleanDefaultArgument(boolean x) { executed[11]++; if (x) { @@ -209,7 +209,7 @@ public void booleanDefaultArgument(boolean x) { } @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void stringObjectDefaultArgument(String x) { executed[12]++; if (x == null || x.length() != 0) { @@ -218,7 +218,7 @@ public void stringObjectDefaultArgument(String x) { } @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void defaultObjectDefaultArgument(DefaultObject x) { executed[13]++; if (x == null || x.i != 4) { @@ -227,7 +227,7 @@ public void defaultObjectDefaultArgument(DefaultObject x) { } @Test - @Arguments(ArgumentValue.NUMBER_42) + @Arguments(Argument.NUMBER_42) public void byte42(byte x) { executed[14]++; if (x != 42) { @@ -236,7 +236,7 @@ public void byte42(byte x) { } @Test - @Arguments(ArgumentValue.NUMBER_42) + @Arguments(Argument.NUMBER_42) public void short42(short x) { executed[15]++; if (x != 42) { @@ -245,7 +245,7 @@ public void short42(short x) { } @Test - @Arguments(ArgumentValue.NUMBER_42) + @Arguments(Argument.NUMBER_42) public void int42(int x) { executed[16]++; if (x != 42) { @@ -254,7 +254,7 @@ public void int42(int x) { } @Test - @Arguments(ArgumentValue.NUMBER_42) + @Arguments(Argument.NUMBER_42) public void long42(long x) { executed[17]++; if (x != 42) { @@ -263,7 +263,7 @@ public void long42(long x) { } @Test - @Arguments(ArgumentValue.NUMBER_42) + @Arguments(Argument.NUMBER_42) public void float42(float x) { executed[18]++; if (x != 42.0) { @@ -272,7 +272,7 @@ public void float42(float x) { } @Test - @Arguments(ArgumentValue.NUMBER_42) + @Arguments(Argument.NUMBER_42) public void double42(double x) { executed[19]++; if (x != 42.0) { @@ -281,7 +281,7 @@ public void double42(double x) { } @Test - @Arguments(ArgumentValue.FALSE) + @Arguments(Argument.FALSE) public void booleanFalse(boolean x) { executed[20]++; if (x) { @@ -290,7 +290,7 @@ public void booleanFalse(boolean x) { } @Test - @Arguments(ArgumentValue.TRUE) + @Arguments(Argument.TRUE) public void booleanTrue(boolean x) { executed[21]++; if (!x) { @@ -299,37 +299,37 @@ public void booleanTrue(boolean x) { } @Test - @Arguments(ArgumentValue.RANDOM_ONCE) + @Arguments(Argument.RANDOM_ONCE) public void randomByte(byte x) { executed[22]++; } @Test - @Arguments(ArgumentValue.RANDOM_ONCE) + @Arguments(Argument.RANDOM_ONCE) public void randomShort(short x) { executed[23]++; } @Test - @Arguments(ArgumentValue.RANDOM_ONCE) + @Arguments(Argument.RANDOM_ONCE) public void randomInt(int x) { executed[24]++; } @Test - @Arguments(ArgumentValue.RANDOM_ONCE) + @Arguments(Argument.RANDOM_ONCE) public void randomLong(long x) { executed[25]++; } @Test - @Arguments(ArgumentValue.RANDOM_ONCE) + @Arguments(Argument.RANDOM_ONCE) public void randomFloat(float x) { executed[26]++; } @Test - @Arguments(ArgumentValue.RANDOM_ONCE) + @Arguments(Argument.RANDOM_ONCE) public void randomDouble(double x) { executed[27]++; } @@ -340,13 +340,13 @@ public void randomNotExecutedTest(double x) { } @Test - @Arguments(ArgumentValue.RANDOM_ONCE) + @Arguments(Argument.RANDOM_ONCE) public void randomBoolean(boolean x) { executed[28]++; } @Test - @Arguments(ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE) + @Arguments(Argument.BOOLEAN_TOGGLE_FIRST_FALSE) public void booleanToggleFirstFalse(boolean x) { if (executed[29] == 0) { // First invocation @@ -361,56 +361,56 @@ public void booleanToggleFirstFalse(boolean x) { } @Test - @Arguments(ArgumentValue.RANDOM_EACH) + @Arguments(Argument.RANDOM_EACH) public void randomEachByte(byte x) { checkNonFloatingRandomNumber(x, executed[30]); executed[30]++; } @Test - @Arguments(ArgumentValue.RANDOM_EACH) + @Arguments(Argument.RANDOM_EACH) public void randomEachShort(short x) { checkNonFloatingRandomNumber(x, executed[31]); executed[31]++; } @Test - @Arguments(ArgumentValue.RANDOM_EACH) + @Arguments(Argument.RANDOM_EACH) public void randomEachInt(int x) { checkNonFloatingRandomNumber(x, executed[32]); executed[32]++; } @Test - @Arguments(ArgumentValue.RANDOM_EACH) + @Arguments(Argument.RANDOM_EACH) public void randomEachLong(long x) { checkNonFloatingRandomNumber(x, executed[33]); executed[33]++; } @Test - @Arguments(ArgumentValue.RANDOM_EACH) + @Arguments(Argument.RANDOM_EACH) public void randomEachChar(char x) { checkNonFloatingRandomNumber(x, executed[34]); executed[34]++; } @Test - @Arguments(ArgumentValue.RANDOM_EACH) + @Arguments(Argument.RANDOM_EACH) public void randomEachFloat(float x) { checkFloatingRandomNumber(x, executed[35]); executed[35]++; } @Test - @Arguments(ArgumentValue.RANDOM_EACH) + @Arguments(Argument.RANDOM_EACH) public void randomEachDouble(double x) { checkFloatingRandomNumber(x, executed[36]); executed[36]++; } @Test - @Arguments(ArgumentValue.RANDOM_EACH) + @Arguments(Argument.RANDOM_EACH) public void randomEachBoolean(boolean x) { checkRandomBoolean(x, executed[37]); executed[37]++; @@ -463,7 +463,7 @@ private void checkRandomBoolean(boolean x, int invocationCount) { @Test - @Arguments(ArgumentValue.NUMBER_MINUS_42) + @Arguments(Argument.NUMBER_MINUS_42) public void byteMinus42(byte x) { executed[38]++; if (x != -42) { @@ -472,7 +472,7 @@ public void byteMinus42(byte x) { } @Test - @Arguments(ArgumentValue.NUMBER_MINUS_42) + @Arguments(Argument.NUMBER_MINUS_42) public void shortMinus42(short x) { executed[39]++; if (x != -42) { @@ -481,7 +481,7 @@ public void shortMinus42(short x) { } @Test - @Arguments(ArgumentValue.NUMBER_MINUS_42) + @Arguments(Argument.NUMBER_MINUS_42) public void intMinus42(int x) { executed[40]++; if (x != -42) { @@ -490,7 +490,7 @@ public void intMinus42(int x) { } @Test - @Arguments(ArgumentValue.NUMBER_MINUS_42) + @Arguments(Argument.NUMBER_MINUS_42) public void longMinus42(long x) { executed[41]++; if (x != -42) { @@ -499,7 +499,7 @@ public void longMinus42(long x) { } @Test - @Arguments(ArgumentValue.NUMBER_MINUS_42) + @Arguments(Argument.NUMBER_MINUS_42) public void floatMinus42(float x) { executed[42]++; if (x != -42.0) { @@ -508,7 +508,7 @@ public void floatMinus42(float x) { } @Test - @Arguments(ArgumentValue.NUMBER_MINUS_42) + @Arguments(Argument.NUMBER_MINUS_42) public void doubleMinus42(double x) { executed[43]++; if (x != -42.0) { @@ -517,7 +517,7 @@ public void doubleMinus42(double x) { } @Test - @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) + @Arguments({Argument.DEFAULT, Argument.DEFAULT}) public void twoArgsDefault1(byte x, short y) { executed[44]++; if (x != 0 || y != 0) { @@ -526,7 +526,7 @@ public void twoArgsDefault1(byte x, short y) { } @Test - @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) + @Arguments({Argument.DEFAULT, Argument.DEFAULT}) public void twoArgsDefault2(int x, short y) { executed[45]++; if (x != 0 || y != 0) { @@ -535,7 +535,7 @@ public void twoArgsDefault2(int x, short y) { } @Test - @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) + @Arguments({Argument.DEFAULT, Argument.DEFAULT}) public void twoArgsDefault3(short x, long y) { executed[46]++; if (x != 0 || y != 0) { @@ -544,7 +544,7 @@ public void twoArgsDefault3(short x, long y) { } @Test - @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) + @Arguments({Argument.DEFAULT, Argument.DEFAULT}) public void twoArgsDefault4(float x, boolean y) { executed[47]++; if (x != 0.0 || y) { @@ -553,7 +553,7 @@ public void twoArgsDefault4(float x, boolean y) { } @Test - @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) + @Arguments({Argument.DEFAULT, Argument.DEFAULT}) public void twoArgsDefault5(boolean x, char y) { executed[48]++; if (x || y != '\u0000') { @@ -562,7 +562,7 @@ public void twoArgsDefault5(boolean x, char y) { } @Test - @Arguments({ArgumentValue.DEFAULT, ArgumentValue.DEFAULT}) + @Arguments({Argument.DEFAULT, Argument.DEFAULT}) public void twoArgsDefault6(char x, byte y) { executed[49]++; if (x != '\u0000' || y != 0) { @@ -571,16 +571,16 @@ public void twoArgsDefault6(char x, byte y) { } @Test - @Arguments({ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE}) + @Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE}) public void twoArgsRandomOnce(char x, byte y) { executed[50]++; } @Test - @Arguments({ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, - ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, - ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, - ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE}) + @Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, + Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, + Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, + Argument.RANDOM_ONCE, Argument.RANDOM_ONCE}) public void checkRandomOnceDifferentArgs(int a, int b, int c, int d, int e, int f, int g, int h) { if (Stream.of(a, b, c, d, e, f, g, h).allMatch(i -> i == a)) { throw new RuntimeException("RANDOM_ONCE does not produce random values for different arguments"); @@ -589,36 +589,36 @@ public void checkRandomOnceDifferentArgs(int a, int b, int c, int d, int e, int } @Test - @Arguments({ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, - ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, - ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, - ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE}) + @Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, + Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, + Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, + Argument.RANDOM_ONCE, Argument.RANDOM_ONCE}) public void checkMixedRandoms1(byte a, short b, int c, long d, char e, boolean f, float g, double h) { executed[52]++; } @Test - @Arguments({ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_EACH, - ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_EACH, - ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_EACH, - ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_EACH}) + @Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH, + Argument.RANDOM_EACH, Argument.RANDOM_EACH, + Argument.RANDOM_EACH, Argument.RANDOM_EACH, + Argument.RANDOM_EACH, Argument.RANDOM_EACH}) public void checkMixedRandoms2(byte a, short b, int c, long d, char e, boolean f, float g, double h) { executed[53]++; } @Test - @Arguments({ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_ONCE, - ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_EACH, - ArgumentValue.RANDOM_ONCE, ArgumentValue.RANDOM_EACH, - ArgumentValue.RANDOM_EACH, ArgumentValue.RANDOM_ONCE}) + @Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, + Argument.RANDOM_EACH, Argument.RANDOM_EACH, + Argument.RANDOM_ONCE, Argument.RANDOM_EACH, + Argument.RANDOM_EACH, Argument.RANDOM_ONCE}) public void checkMixedRandoms3(byte a, short b, int c, long d, char e, boolean f, float g, double h) { executed[54]++; } @Test - @Arguments({ArgumentValue.NUMBER_42, ArgumentValue.NUMBER_42, - ArgumentValue.NUMBER_42, ArgumentValue.NUMBER_42, - ArgumentValue.NUMBER_42, ArgumentValue.NUMBER_42}) + @Arguments({Argument.NUMBER_42, Argument.NUMBER_42, + Argument.NUMBER_42, Argument.NUMBER_42, + Argument.NUMBER_42, Argument.NUMBER_42}) public void check42Mix1(byte a, short b, int c, long d, float e, double f) { if (a != 42 || b != 42 || c != 42 || d != 42 || e != 42.0 || f != 42.0) { throw new RuntimeException("Must all be 42"); @@ -627,9 +627,9 @@ public void check42Mix1(byte a, short b, int c, long d, float e, double f) { } @Test - @Arguments({ArgumentValue.NUMBER_MINUS_42, ArgumentValue.NUMBER_MINUS_42, - ArgumentValue.NUMBER_MINUS_42, ArgumentValue.NUMBER_MINUS_42, - ArgumentValue.NUMBER_MINUS_42, ArgumentValue.NUMBER_MINUS_42}) + @Arguments({Argument.NUMBER_MINUS_42, Argument.NUMBER_MINUS_42, + Argument.NUMBER_MINUS_42, Argument.NUMBER_MINUS_42, + Argument.NUMBER_MINUS_42, Argument.NUMBER_MINUS_42}) public void check42Mix2(byte a, short b, int c, long d, float e, double f) { if (a != -42 || b != -42 || c != -42 || d != -42 || e != -42.0 || f != -42.0) { throw new RuntimeException("Must all be -42"); @@ -638,9 +638,9 @@ public void check42Mix2(byte a, short b, int c, long d, float e, double f) { } @Test - @Arguments({ArgumentValue.NUMBER_MINUS_42, ArgumentValue.NUMBER_42, - ArgumentValue.NUMBER_MINUS_42, ArgumentValue.NUMBER_MINUS_42, - ArgumentValue.NUMBER_42, ArgumentValue.NUMBER_MINUS_42}) + @Arguments({Argument.NUMBER_MINUS_42, Argument.NUMBER_42, + Argument.NUMBER_MINUS_42, Argument.NUMBER_MINUS_42, + Argument.NUMBER_42, Argument.NUMBER_MINUS_42}) public void check42Mix3(byte a, short b, int c, long d, float e, double f) { if (a != -42 || b != 42 || c != -42 || d != -42 || e != 42.0 || f != -42.0) { throw new RuntimeException("Do not match the right 42 version"); @@ -650,7 +650,7 @@ public void check42Mix3(byte a, short b, int c, long d, float e, double f) { @Test - @Arguments(ArgumentValue.BOOLEAN_TOGGLE_FIRST_TRUE) + @Arguments(Argument.BOOLEAN_TOGGLE_FIRST_TRUE) public void booleanToggleFirstTrue(boolean x) { if (executed[58] == 0) { // First invocation @@ -665,7 +665,7 @@ public void booleanToggleFirstTrue(boolean x) { } @Test - @Arguments({ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE, ArgumentValue.BOOLEAN_TOGGLE_FIRST_TRUE}) + @Arguments({Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.BOOLEAN_TOGGLE_FIRST_TRUE}) public void checkTwoToggles(boolean b1, boolean b2) { if (executed[59] == 0) { // First invocation @@ -682,8 +682,8 @@ public void checkTwoToggles(boolean b1, boolean b2) { } @Test - @Arguments({ArgumentValue.BOOLEAN_TOGGLE_FIRST_FALSE, ArgumentValue.FALSE, - ArgumentValue.TRUE, ArgumentValue.BOOLEAN_TOGGLE_FIRST_TRUE}) + @Arguments({Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.FALSE, + Argument.TRUE, Argument.BOOLEAN_TOGGLE_FIRST_TRUE}) public void booleanMix(boolean b1, boolean b2, boolean b3, boolean b4) { if (executed[60] == 0) { // First invocation diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java index fcecebcdbbd..2dd3d3d7c8b 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java @@ -121,7 +121,7 @@ public static void findIrIds(String output, String method, int... numbers) { class AndOr1 { @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) @IR(applyIfAnd = {"UsePerfData", "true", "SuspendRetryCount", "50", "UseTLAB", "true"}, failOn = {IRNode.CALL}) public void test1(int i) { dontInline(); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java index 13c17a17fd6..fcdef4b1cdd 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java @@ -2,11 +2,6 @@ import compiler.valhalla.framework.*; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.Arrays; -import java.util.stream.Stream; - public class TestPackagePrivate { public static void main(String[] args) { TestFramework.run(PackagePrivate.class); @@ -19,7 +14,7 @@ public void test() { } @Test - @Arguments(ArgumentValue.DEFAULT) + @Arguments(Argument.DEFAULT) public void test2(int x) { } } From bc5375efec15738fbe16f239ed4b80279e7abdf0 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 3 Feb 2021 15:08:11 +0100 Subject: [PATCH 016/131] Add MIN/MAX as possible Argument --- .../compiler/valhalla/framework/Argument.java | 4 +- .../valhalla/framework/ArgumentValue.java | 84 +++++++- .../valhalla/framework/TestFramework.java | 4 +- .../valhalla/framework/tests/TestBasics.java | 182 +++++++++++++----- 4 files changed, 212 insertions(+), 62 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java index 34a1bcf96e5..460124f1569 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java @@ -10,6 +10,6 @@ public enum Argument { FALSE, RANDOM_ONCE, RANDOM_EACH, - MAX, // TODO -> for numbers - MIN // TODO -> for numbers + MAX, + MIN } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java index 82e413d2371..4e2e6d22193 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java @@ -58,35 +58,53 @@ public static ArgumentValue[] getArguments(Method m) { switch (specifiedArg) { case DEFAULT -> arguments[i] = createDefault(parameter); case NUMBER_42 -> { - TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_42 argument for non-number " + parameterObj + " for " + m); + TestFormat.check(isNumber(parameter), + "Provided invalid NUMBER_42 argument for non-number " + parameterObj + " for " + m); arguments[i] = create((byte) 42); } case NUMBER_MINUS_42 -> { - TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_MINUS_42 argument for non-number " + parameterObj + " for " + m); + TestFormat.check(isNumber(parameter), + "Provided invalid NUMBER_MINUS_42 argument for non-number " + parameterObj + " for " + m); arguments[i] = create((byte) -42); } + case MIN -> { + TestFormat.check(isNumber(parameter) || isChar(parameter), + "Provided invalid MIN argument for non-number " + parameterObj + " for " + m); + arguments[i] = createMin(parameter); + } + case MAX -> { + TestFormat.check(isNumber(parameter) || isChar(parameter), + "Provided invalid MAX argument for non-number " + parameterObj + " for " + m); + arguments[i] = createMax(parameter); + } case BOOLEAN_TOGGLE_FIRST_FALSE -> { - TestFormat.check(isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + parameterObj + " for " + m); + TestFormat.check(isBoolean(parameter), + "Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + parameterObj + " for " + m); arguments[i] = createToggleBoolean(false); } case BOOLEAN_TOGGLE_FIRST_TRUE -> { - TestFormat.check(ArgumentValue.isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + parameterObj + " for " + m); + TestFormat.check(ArgumentValue.isBoolean(parameter), + "Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + parameterObj + " for " + m); arguments[i] = createToggleBoolean(true); } case TRUE -> { - TestFormat.check(ArgumentValue.isBoolean(parameter), "Provided invalid TRUE argument for non-boolean " + parameterObj + " for " + m); + TestFormat.check(ArgumentValue.isBoolean(parameter), + "Provided invalid TRUE argument for non-boolean " + parameterObj + " for " + m); arguments[i] = create(true); } case FALSE -> { - TestFormat.check(ArgumentValue.isBoolean(parameter), "Provided invalid FALSE argument for non-boolean " + parameterObj + " for " + m); + TestFormat.check(ArgumentValue.isBoolean(parameter), + "Provided invalid FALSE argument for non-boolean " + parameterObj + " for " + m); arguments[i] = create(false); } case RANDOM_ONCE -> { - TestFormat.check(isPrimitiveType(parameter), "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameterObj + " for " + m); + TestFormat.check(isPrimitiveType(parameter), + "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameterObj + " for " + m); arguments[i] = createRandom(parameter); } case RANDOM_EACH -> { - TestFormat.check(isPrimitiveType(parameter), "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameterObj + " for " + m); + TestFormat.check(isPrimitiveType(parameter), + "Provided invalid RANDOM_EACH argument for non-primitive type " + parameterObj + " for " + m); arguments[i] = createRandomEach(parameter); } } @@ -121,13 +139,59 @@ private static ArgumentValue createDefault(Class c) { } } - private static ArgumentValue createRandom(Class c) { - return new ArgumentValue(getRandom(c), null, true); + + private static ArgumentValue createMin(Class c) { + Object argument = null; + if (c.equals(byte.class)) { + argument = Byte.MIN_VALUE; + } else if (isChar(c)) { + argument = Character.MIN_VALUE; + } else if (c.equals(short.class)) { + argument = Short.MIN_VALUE; + } else if (c.equals(int.class)) { + argument = Integer.MIN_VALUE; + } else if (c.equals(long.class)) { + argument = Long.MIN_VALUE; + } else if (c.equals(float.class)) { + argument = Float.MIN_VALUE; + } else if (c.equals(double.class)) { + argument = Double.MIN_VALUE; + } else { + throw new TestFrameworkException("Invalid class passed to createMin()"); + } + return new ArgumentValue(argument, null, false); + } + + private static ArgumentValue createMax(Class c) { + Object argument = null; + if (c.equals(byte.class)) { + argument = Byte.MAX_VALUE; + } else if (isChar(c)) { + argument = Character.MAX_VALUE; + } else if (c.equals(short.class)) { + argument = Short.MAX_VALUE; + } else if (c.equals(int.class)) { + argument = Integer.MAX_VALUE; + } else if (c.equals(long.class)) { + argument = Long.MAX_VALUE; + } else if (c.equals(float.class)) { + argument = Float.MAX_VALUE; + } else if (c.equals(double.class)) { + argument = Double.MAX_VALUE; + } else { + throw new TestFrameworkException("Invalid class passed to createMin()"); + } + return new ArgumentValue(argument, null, false); } + private static ArgumentValue createToggleBoolean(boolean firstBoolean) { return new ArgumentValue(null, firstBoolean, false); } + private static ArgumentValue createRandom(Class c) { + return new ArgumentValue(getRandom(c), null, true); + } + private static ArgumentValue createRandomEach(Class c) { return new ArgumentValue(null, c); } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 59d28d36940..01c2b1e9eac 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -638,7 +638,7 @@ private void addTest(Method m) { // Don't inline test methods. Don't care when -Xcomp set. WHITE_BOX.testSetDontInlineMethod(m, true); } - CompLevel compLevel = testAnno.compLevel(); + CompLevel compLevel = restrictCompLevel(testAnno.compLevel()); if (FLIP_C1_C2) { compLevel = flipCompLevel(compLevel); } @@ -669,7 +669,7 @@ private static CompLevel restrictCompLevel(CompLevel compLevel) { } if (compLevel == CompLevel.ANY) { // Use C2 by default. - return CompLevel.C2; + compLevel = CompLevel.C2; } if (!TIERED_COMPILATION && compLevel.getValue() < CompLevel.C2.getValue()) { return CompLevel.SKIP; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java index 8223fdce83a..d43b59680f5 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -7,6 +7,14 @@ import java.util.stream.Stream; public class TestBasics { + private static boolean wasExecuted = false; + private boolean lastToggleBoolean = true; + private final static int[] executed = new int[92]; + private final static int[] executedOnce = new int[5]; + private long[] nonFloatingRandomNumbers = new long[10]; + private double[] floatingRandomNumbers = new double[10]; + private Boolean[] randomBooleans = new Boolean[64]; + public static void main(String[] args) throws Exception { // Run on same VM to make this test easier as we are not interested in any output processing. Method runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); @@ -32,54 +40,6 @@ public static void main(String[] args) throws Exception { } } -// @Test -// @Arguments({ArgumentValue.DEFAULT, ArgumentValue.FALSE, ArgumentValue.NUMBER_42, ArgumentValue.RANDOM_ALL, ArgumentValue.RANDOM_ONCE, ArgumentValue.BOOLEAN_TOGGLE}) -// public int test(int arg1, boolean arg2, double arg3, double arg4, int arg5, boolean arg6) { -// return 0; -// } -// -// // Useful for quick checking, nothing fancy going on. This method is optional. -// @Check(test = "test", when=CheckAt.C2_COMPILED) -// // Must match method 'test' when removing '_check'. Could also think about matching in annotation, e.g. @Check(test = "test2"). -// public void test_check(int result /* must match return argument of 'test', possible to check? */) { -// // This method runs in interpreter, DontCompile. -// // Check that there is a method 'test' with @Test, no method 'test_check' or when present no @Run at it (bad style though, better use check in annotation?), -// // 'test' has non-void return (if void, what do you need the check for then?) -// // If 'test' has arguments but no @Arguments annotation, framework takes default arguments (bad style though). -// // Framework executes 'test' with warmup (specified or default). -// // This method is then called from framework once after 'test' compiled or once when 'test' is called the first time by framework and after 'test' is compiled -//// Asserts.assertEQ(result, 0); -// } -// -// @Test -// public void test2(int arg1, boolean arg2, int arg3, int arg4) { -// } -// -// // Optional method. -// // Useful when more complex/changing arguments are required. Framework calls this method in interpreter and let it handle how to call the method -// // 'test'. Framework could verify that this method has at least one call to 'test2'? -// @Run(test = "test2") -// // Must match method 'test2' when removing '_run'. Could also think about matching in annotation, e.g. @Run(test = "test2"). -// public void test2_run(TestInfo info) { -// // This method runs in interpreter, DontCompile -// // Check that there is a method 'test2' with @Test. -// // Check that no @Arguments present in 'test2' (not useful when specifying here how to call the method) -// // Called each time by framework, specifies how to run test -// if (info.isWarmUp()) { -// test2(34, info.toggleBoolean(), info.getRandomInt(), 0); -// } else { -// test2(12, true, info.getRandomInt(), -555); -// } -// } - - static boolean wasExecuted = false; - static int[] executed = new int[78]; - static int[] executedOnce = new int[5]; - boolean lastToggleBoolean = true; - long[] nonFloatingRandomNumbers = new long[10]; - double[] floatingRandomNumbers = new double[10]; - Boolean[] randomBooleans = new Boolean[64]; - private void clearNonFloatingRandomNumbers() { nonFloatingRandomNumbers = new long[10]; } @@ -516,6 +476,132 @@ public void doubleMinus42(double x) { } } + @Test + @Arguments(Argument.MIN) + public void byteMin(byte x) { + executed[79]++; + if (x != Byte.MIN_VALUE) { + throw new RuntimeException("Must be MIN_VALUE"); + } + } + + @Test + @Arguments(Argument.MIN) + public void charMin(char x) { + executed[80]++; + if (x != Character.MIN_VALUE) { + throw new RuntimeException("Must be MIN_VALUE"); + } + } + + @Test + @Arguments(Argument.MIN) + public void shortMin(short x) { + executed[81]++; + if (x != Short.MIN_VALUE) { + throw new RuntimeException("Must be MIN_VALUE"); + } + } + + @Test + @Arguments(Argument.MIN) + public void intMin(int x) { + executed[82]++; + if (x != Integer.MIN_VALUE) { + throw new RuntimeException("Must be MIN_VALUE"); + } + } + + @Test + @Arguments(Argument.MIN) + public void longMin(long x) { + executed[83]++; + if (x != Long.MIN_VALUE) { + throw new RuntimeException("Must be MIN_VALUE"); + } + } + + @Test + @Arguments(Argument.MIN) + public void floatMin(float x) { + executed[84]++; + if (x != Float.MIN_VALUE) { + throw new RuntimeException("Must be MIN_VALUE"); + } + } + + @Test + @Arguments(Argument.MIN) + public void doubleMin(double x) { + executed[85]++; + if (x != Double.MIN_VALUE) { + throw new RuntimeException("Must be MIN_VALUE"); + } + } + + @Test + @Arguments(Argument.MAX) + public void byteMax(byte x) { + executed[86]++; + if (x != Byte.MAX_VALUE) { + throw new RuntimeException("Must be MAX_VALUE"); + } + } + + @Test + @Arguments(Argument.MAX) + public void charMax(char x) { + executed[87]++; + if (x != Character.MAX_VALUE) { + throw new RuntimeException("Must be MAX_VALUE"); + } + } + + @Test + @Arguments(Argument.MAX) + public void shortMax(short x) { + executed[88]++; + if (x != Short.MAX_VALUE) { + throw new RuntimeException("Must be MAX_VALUE"); + } + } + + @Test + @Arguments(Argument.MAX) + public void intMax(int x) { + executed[89]++; + if (x != Integer.MAX_VALUE) { + throw new RuntimeException("Must be MAX_VALUE"); + } + } + + @Test + @Arguments(Argument.MAX) + public void longMax(long x) { + executed[90]++; + if (x != Long.MAX_VALUE) { + throw new RuntimeException("Must be MAX_VALUE"); + } + } + + @Test + @Arguments(Argument.MAX) + public void floatMax(float x) { + executed[91]++; + if (x != Float.MAX_VALUE) { + throw new RuntimeException("Must be MAX_VALUE"); + } + } + + @Test + @Arguments(Argument.MAX) + public void doubleMax(double x) { + executed[78]++; + if (x != Double.MAX_VALUE) { + throw new RuntimeException("Must be MAX_VALUE"); + } + } + @Test @Arguments({Argument.DEFAULT, Argument.DEFAULT}) public void twoArgsDefault1(byte x, short y) { From 31e1be92b782011330efaa0ce624fb30f4ee06d8 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 15 Feb 2021 11:28:51 +0100 Subject: [PATCH 017/131] Insert Copyright headers and small clean ups --- .../compiler/valhalla/framework/Argument.java | 23 +++++++++ .../valhalla/framework/ArgumentValue.java | 27 ++++++++++- .../valhalla/framework/Arguments.java | 23 +++++++++ .../compiler/valhalla/framework/Check.java | 23 +++++++++ .../compiler/valhalla/framework/CheckAt.java | 23 +++++++++ .../valhalla/framework/CompLevel.java | 23 +++++++++ .../valhalla/framework/DontCompile.java | 23 +++++++++ .../valhalla/framework/DontInline.java | 23 +++++++++ .../src/compiler/valhalla/framework/Foo.java | 23 +++++++++ .../valhalla/framework/ForceCompile.java | 23 +++++++++ .../valhalla/framework/ForceInline.java | 23 +++++++++ .../src/compiler/valhalla/framework/IR.java | 23 +++++++++ .../valhalla/framework/IREncodingPrinter.java | 23 +++++++++ .../valhalla/framework/IRMatcher.java | 23 +++++++++ .../compiler/valhalla/framework/IRNode.java | 47 ++++++++++++------- .../src/compiler/valhalla/framework/IRs.java | 23 +++++++++ .../valhalla/framework/OSRCompileOnly.java | 23 +++++++++ .../src/compiler/valhalla/framework/Run.java | 23 +++++++++ .../compiler/valhalla/framework/RunMode.java | 23 +++++++++ .../compiler/valhalla/framework/Scenario.java | 23 +++++++++ .../src/compiler/valhalla/framework/Test.java | 23 +++++++++ .../valhalla/framework/TestFormat.java | 23 +++++++++ .../framework/TestFormatException.java | 23 +++++++++ .../valhalla/framework/TestFramework.java | 29 ++++++++++-- .../compiler/valhalla/framework/TestInfo.java | 23 +++++++++ .../compiler/valhalla/framework/TestRun.java | 23 +++++++++ .../valhalla/framework/TestRunException.java | 23 +++++++++ .../compiler/valhalla/framework/VMFlag.java | 23 +++++++++ .../valhalla/framework/VMFlagValhalla.java | 23 +++++++++ .../compiler/valhalla/framework/Warmup.java | 23 +++++++++ .../framework/tests/TestBadFormat.java | 23 +++++++++ .../valhalla/framework/tests/TestBasics.java | 23 +++++++++ .../framework/tests/TestCompLevels.java | 23 +++++++++ .../framework/tests/TestControls.java | 23 +++++++++ .../framework/tests/TestIRMatching.java | 23 +++++++++ .../framework/tests/TestPackagePrivate.java | 23 +++++++++ .../valhalla/framework/tests/TestSanity.java | 23 +++++++++ .../framework/tests/TestScenarios.java | 23 +++++++++ .../tests/TestWithHelperClasses.java | 23 +++++++++ 39 files changed, 908 insertions(+), 23 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java index 460124f1569..389474bb566 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; public enum Argument { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java index 4e2e6d22193..b4513fcd0fc 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.lang.reflect.Constructor; @@ -141,7 +164,7 @@ private static ArgumentValue createDefault(Class c) { private static ArgumentValue createMin(Class c) { - Object argument = null; + Object argument; if (c.equals(byte.class)) { argument = Byte.MIN_VALUE; } else if (isChar(c)) { @@ -163,7 +186,7 @@ private static ArgumentValue createMin(Class c) { } private static ArgumentValue createMax(Class c) { - Object argument = null; + Object argument; if (c.equals(byte.class)) { argument = Byte.MAX_VALUE; } else if (isChar(c)) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java index 69877f8284a..bcc11d5c268 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.lang.annotation.Retention; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java index 035d2e5a7eb..f3f4614a46d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.lang.annotation.Retention; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java index 50243d983b9..6dcfa5e249a 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; public enum CheckAt { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java index 944b9c17b53..b1c8eca1e83 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.util.HashMap; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java index 5b8c742d9b3..55c80b4ce53 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.lang.annotation.Retention; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java index 8eb16b4e8ec..e0a4a4b1148 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.lang.annotation.Retention; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java index 13eb58a104a..433b65549ee 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; public @interface Foo { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java index aaebe8d92c8..ad123f0197b 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.lang.annotation.Retention; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java index 9726214230c..65df165cf00 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.lang.annotation.Retention; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java index f911e013582..b622f44aab6 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.lang.annotation.Repeatable; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java index ec84deac2e9..06ab8c4de46 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import sun.hotspot.WhiteBox; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java index f463f108839..b3be938b65c 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import jdk.test.lib.Asserts; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java index aaee73916fc..401067976e8 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.util.ArrayList; @@ -66,24 +89,12 @@ static List mergeNodes(String[] nodes) { for (int i = 0; i < nodes.length; i += 2) { String node = nodes[i]; switch (node) { - case ALLOC_OF -> { - mergeCompositeNodes(nodes, mergedNodes, i, node, ALLOC_OF_POSTFIX, "ALLOC_OF"); - } - case ALLOC_ARRAY_OF -> { - mergeCompositeNodes(nodes, mergedNodes, i, node, ALLOC_ARRAY_OF_POSTFIX, "ALLOC_ARRAY_OF"); - } - case STORE_OF_CLASS -> { - mergeCompositeNodes(nodes, mergedNodes, i, node, STORE_OF_CLASS_POSTFIX, "STORE_OF_CLASS"); - } - case STORE_OF_FIELD -> { - mergeCompositeNodes(nodes, mergedNodes, i, node, STORE_OF_FIELD_POSTFIX, "STORE_OF_FIELD"); - } - case LOAD_OF_CLASS -> { - mergeCompositeNodes(nodes, mergedNodes, i, node, LOAD_OF_CLASS_POSTFIX, "LOAD_OF_CLASS"); - } - case LOAD_OF_FIELD -> { - mergeCompositeNodes(nodes, mergedNodes, i, node, LOAD_OF_FIELD_POSTFIX, "LOAD_OF_FIELD"); - } + case ALLOC_OF -> mergeCompositeNodes(nodes, mergedNodes, i, node, ALLOC_OF_POSTFIX, "ALLOC_OF"); + case ALLOC_ARRAY_OF -> mergeCompositeNodes(nodes, mergedNodes, i, node, ALLOC_ARRAY_OF_POSTFIX, "ALLOC_ARRAY_OF"); + case STORE_OF_CLASS -> mergeCompositeNodes(nodes, mergedNodes, i, node, STORE_OF_CLASS_POSTFIX, "STORE_OF_CLASS"); + case STORE_OF_FIELD -> mergeCompositeNodes(nodes, mergedNodes, i, node, STORE_OF_FIELD_POSTFIX, "STORE_OF_FIELD"); + case LOAD_OF_CLASS -> mergeCompositeNodes(nodes, mergedNodes, i, node, LOAD_OF_CLASS_POSTFIX, "LOAD_OF_CLASS"); + case LOAD_OF_FIELD -> mergeCompositeNodes(nodes, mergedNodes, i, node, LOAD_OF_FIELD_POSTFIX, "LOAD_OF_FIELD"); default -> { i--; // No composite node, do not increment by 2. mergedNodes.add(node); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java index 96617913043..178ffa1c09f 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.lang.annotation.Retention; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSRCompileOnly.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSRCompileOnly.java index 62c1bad51f0..dfb19aeecca 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSRCompileOnly.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSRCompileOnly.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.lang.annotation.Retention; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java index 6bd472154e7..0cd2cb9ef53 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.lang.annotation.Retention; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java index 137a935020a..3283845c70b 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; public enum RunMode { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java index 3b71b8061a9..9c3bbc91872 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.util.*; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java index 6c7f703d3ca..e258437f034 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.lang.annotation.Repeatable; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java index e476f472497..15f6eb003a3 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.util.ArrayList; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java index a0ece7d124f..f46cd5b9aae 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; public class TestFormatException extends RuntimeException { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 01c2b1e9eac..d8d3338e833 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.lang.annotation.Annotation; @@ -74,12 +97,12 @@ public class TestFramework { private final HashMap declaredTests = new HashMap<>(); private final LinkedHashMap allTests = new LinkedHashMap<>(); // Keep order private final HashMap testMethodMap = new HashMap<>(); - private List excludeList = null; - private List includeList = null; + private final List excludeList; + private final List includeList; private List> helperClasses = null; private List scenarios = null; private final IREncodingPrinter irMatchRulePrinter; - private Class testClass = null; + private final Class testClass; public TestFramework(Class testClass) { TestRun.check(testClass != null, "Test class cannot be null"); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java index 9be58e7d0ed..fa4184bf166 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import sun.hotspot.WhiteBox; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java index ea2446f0996..dc54189662b 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; public class TestRun { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java index eebe4d8428e..29ffbfb3220 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; public class TestRunException extends RuntimeException { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java index 302d05a7b3a..b28156d1a3d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; public class VMFlag { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java index da830c2c7c1..56ac3139f71 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; public class VMFlagValhalla { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java index 05e61ab3a0a..02e381cf1d1 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework; import java.lang.annotation.Retention; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java index 098b1700697..4eb66162c32 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework.tests; import compiler.valhalla.framework.*; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java index d43b59680f5..eefb999fd7f 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework.tests; import compiler.valhalla.framework.*; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java index fcdc51a3594..49db39be344 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework.tests; import compiler.valhalla.framework.*; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java index 2edaf70b832..e416f669c60 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework.tests; import compiler.valhalla.framework.*; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java index 2dd3d3d7c8b..b37c911a999 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework.tests; import compiler.valhalla.framework.*; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java index fcdef4b1cdd..cfe421d294d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework.tests; import compiler.valhalla.framework.*; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java index 2daa8fda2a7..d5bbf455a08 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework.tests; import compiler.valhalla.framework.Scenario; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java index ee1cadbda2b..1769d1d8da4 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework.tests; import compiler.valhalla.framework.*; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java index 43f9c1c5965..b2e03d0fc33 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java @@ -1,3 +1,26 @@ +/* + * Copyright (c) 2020, 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.valhalla.framework.tests; import compiler.valhalla.framework.*; From a7868109206cd7e195abe9da8e60287957d0de12 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 15 Feb 2021 17:25:24 +0100 Subject: [PATCH 018/131] Add more "bad" tests --- .../valhalla/framework/ArgumentValue.java | 5 +- .../valhalla/framework/TestFramework.java | 83 +++++---- .../framework/tests/TestBadFormat.java | 176 +++++++++++++++++- .../valhalla/framework/tests/TestBasics.java | 17 +- .../framework/tests/TestControls.java | 48 ++++- 5 files changed, 281 insertions(+), 48 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java index b4513fcd0fc..4586ee6cd15 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java @@ -153,8 +153,11 @@ private static ArgumentValue createDefault(Class c) { // Object try { Constructor constructor = c.getDeclaredConstructor(); - constructor.setAccessible(true); + constructor.setAccessible(true); // Make sure to have access to private default constructor return ArgumentValue.create(constructor.newInstance()); + } catch (NoSuchMethodException e) { + TestFormat.fail("Cannot create new default instance of " + c + " due to missing default constructor"); + return null; } catch (Exception e) { TestFormat.fail("Cannot create new default instance of " + c + ": " + e.getCause()); return null; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index d8d3338e833..8694acca3b7 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -473,12 +473,14 @@ private void parseTestClass() { private void addBaseTests() { declaredTests.forEach((m, test) -> { - try { - Arguments argumentsAnno = getAnnotation(m, Arguments.class); - TestFormat.check(argumentsAnno != null || m.getParameterCount() == 0, "Missing @Arguments annotation to define arguments of " + m); - allTests.put(m, new BaseTest(test)); - } catch (TestFormatException e) { - // Failure logged. Continue and report later. + if (test.getAttachedMethod() == null) { + try { + Arguments argumentsAnno = getAnnotation(m, Arguments.class); + TestFormat.check(argumentsAnno != null || m.getParameterCount() == 0, "Missing @Arguments annotation to define arguments of " + m); + allTests.put(m, new BaseTest(test)); + } catch (TestFormatException e) { + // Failure logged. Continue and report later. + } } }); } @@ -556,9 +558,11 @@ private void applyIndependentCompilationCommands(Method m) { private void checkCompilationCommandAnnotations(Method m, ForceInline forceInlineAnno, DontInline dontInlineAnno, ForceCompile forceCompileAnno, DontCompile dontCompileAnno) { Test testAnno = getAnnotation(m, Test.class); - TestFormat.check(testAnno == null || Stream.of(forceCompileAnno, dontCompileAnno, forceInlineAnno, dontInlineAnno).noneMatch(Objects::nonNull), - "Not allowed to use explicit compile command annotations (@ForceInline, @DontInline," + - "@ForceCompile or @DontCompile) together with @Test at " + m + ". Use compLevel in @Test for fine tuning."); + Run runAnno = getAnnotation(m, Run.class); + Check checkAnno = getAnnotation(m, Check.class); + TestFormat.check((testAnno == null && runAnno == null && checkAnno == null) || Stream.of(forceCompileAnno, dontCompileAnno, forceInlineAnno, dontInlineAnno).noneMatch(Objects::nonNull), + "Cannot use explicit compile command annotations (@ForceInline, @DontInline," + + "@ForceCompile or @DontCompile) together with @Test, @Check or @Run: " + m + ". Use compLevel in @Test for fine tuning."); if (Stream.of(forceInlineAnno, dontCompileAnno, dontInlineAnno).filter(Objects::nonNull).count() > 1) { // Failure TestFormat.check(dontCompileAnno == null || dontInlineAnno == null, @@ -576,8 +580,6 @@ private void checkCompilationCommandAnnotations(Method m, ForceInline forceInlin TestFormat.check(Arrays.stream(dontCompile).noneMatch(a -> a == forceCompile), "Overlapping compilation levels with @ForceCompile and @DontCompile at " + m); } - TestFormat.check(forceCompileAnno == null || dontCompileAnno == null, - "Cannot have @ForceCompile and @DontCompile at the same time at " + m); } private void dontCompileMethod(Method m) { @@ -648,7 +650,7 @@ private void addTest(Method m) { int warmupIterations = WARMUP_ITERATIONS; if (warmup != null) { warmupIterations = warmup.value(); - TestFormat.check(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + m); + TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + m); } boolean osrOnly = getAnnotation(m, OSRCompileOnly.class) != null; @@ -672,7 +674,7 @@ private void addTest(Method m) { private void checkTestAnnotations(Method m, Test testAnno) { TestFormat.check(!testMethodMap.containsKey(m.getName()), - "Cannot overload two @Test methods " + m + " and " + testMethodMap.get(m.getName())); + "Cannot overload two @Test methods: " + m + ", " + testMethodMap.get(m.getName())); TestFormat.check(testAnno != null, m + " must be a method with a @Test annotation"); Check checkAnno = getAnnotation(m, Check.class); @@ -766,34 +768,21 @@ private void addCheckedTest(Method m, Check checkAnno, Run runAnno) { DeclaredTest test = declaredTests.remove(testMethod); TestFormat.check(test != null, "Missing @Test annotation for associated test method " + checkAnno.test() + " for @Check at " + m); - applyCompileCommands(m, false); + Method attachedMethod = test.getAttachedMethod(); + TestFormat.check(attachedMethod == null, + "Cannot use @Test " + testMethod + " for more than one @Run/@Check method. Found: " + m + ", " + attachedMethod); + dontCompileMethod(m); // Don't inline check methods WHITE_BOX.testSetDontInlineMethod(m, true); CheckedTest checkedTest = new CheckedTest(test, m, checkAnno, parameter); allTests.put(testMethod, checkedTest); } - private void applyCompileCommands(Method m, boolean defaultDontCompile) { - ForceInline forceInlineAnno = getAnnotation(m, ForceInline.class); - DontInline dontInlineAnno = getAnnotation(m, DontInline.class); - ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); - DontCompile dontCompileAnno = getAnnotation(m, DontCompile.class); - if (Stream.of(forceCompileAnno, dontCompileAnno, forceInlineAnno, dontInlineAnno).anyMatch(Objects::nonNull)) { - applyIndependentCompilationCommands(m); - applyForceCompileCommand(m); - } else { - if (defaultDontCompile) { - // @DontCompile if nothing specified. Done for @Run. - dontCompileMethod(m); - } - } - } - private void addCustomRunTest(Method m, Run runAnno) { Method testMethod = testMethodMap.get(runAnno.test()); - DeclaredTest test = declaredTests.remove(testMethod); + DeclaredTest test = declaredTests.get(testMethod); checkCustomRunTest(m, runAnno, testMethod, test); - applyCompileCommands(m, true); + dontCompileMethod(m); // Don't inline run methods WHITE_BOX.testSetDontInlineMethod(m, true); CustomRunTest customRunTest = new CustomRunTest(test, m, getAnnotation(m, Warmup.class), runAnno); @@ -801,11 +790,14 @@ private void addCustomRunTest(Method m, Run runAnno) { } private void checkCustomRunTest(Method m, Run runAnno, Method testMethod, DeclaredTest test) { - TestFormat.check(testMethod != null, "Did not find associated test method " + runAnno.test() + " for @Run at " + m); + TestFormat.check(testMethod != null, "Did not find associated test method \"" + runAnno.test() + "\" specified in @Run at " + m); TestFormat.check(test != null, "Missing @Test annotation for associated test method " + runAnno.test() + " for @Run at " + m); - TestFormat.check(!test.hasArguments(), "Invalid @Arguments annotation for associated test method " + runAnno.test() + " for @Run at " + m); + Method attachedMethod = test.getAttachedMethod(); + TestFormat.check(attachedMethod == null, + "Cannot use @Test " + testMethod + " for more than one @Run/@Check method. Found: " + m + ", " + attachedMethod); + TestFormat.check(!test.hasArguments(), "Cannot use @Arguments at test method " + testMethod + " in combination with @Run method " + m); TestFormat.check(m.getParameterCount() == 0 || (m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(TestInfo.class)), - "@Run method " + m + " must specify either no TestInfo parameter or exactly one"); + "@Run method " + m + " must specify either no parameter or exactly one of " + TestInfo.class); Warmup warmupAnno = getAnnotation(testMethod, Warmup.class); TestFormat.checkNoThrow(warmupAnno == null, "Cannot set @Warmup at @Test method " + testMethod + " when used with its @Run method " + m + ". Use @Warmup at @Run method instead."); @@ -903,6 +895,7 @@ class DeclaredTest { private final int warmupIterations; private final CompLevel compLevel; private final boolean osrOnly; + private Method attachedMethod; public DeclaredTest(Method testMethod, ArgumentValue[] arguments, CompLevel compLevel, int warmupIterations, boolean osrOnly) { // Make sure we can also call non-public or public methods in package private classes @@ -912,6 +905,7 @@ public DeclaredTest(Method testMethod, ArgumentValue[] arguments, CompLevel comp this.arguments = arguments; this.warmupIterations = warmupIterations; this.osrOnly = osrOnly; + this.attachedMethod = null; } public Method getTestMethod() { @@ -938,6 +932,14 @@ public Object[] getArguments() { return Arrays.stream(arguments).map(ArgumentValue::getArgument).toArray(); } + public void setAttachedMethod(Method m) { + attachedMethod = m; + } + + public Method getAttachedMethod() { + return attachedMethod; + } + public void printFixedRandomArguments() { if (hasArguments()) { boolean hasRandomArgs = false; @@ -1009,6 +1011,8 @@ public String getTestName() { return testMethod.getName(); } + public Method getAttachedMethod() { return null; } + /** * Run the associated test */ @@ -1155,11 +1159,15 @@ public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecificati super(test); // Make sure we can also call non-public or public methods in package private classes checkMethod.setAccessible(true); + test.setAttachedMethod(checkMethod); this.checkMethod = checkMethod; this.checkAt = checkSpecification.when(); this.parameter = parameter; } + @Override + public Method getAttachedMethod() { return checkMethod; } + @Override public void verify(Object result) { boolean shouldVerify = false; @@ -1190,11 +1198,16 @@ public CustomRunTest(DeclaredTest test, Method runMethod, Warmup warmUpAnno, Run super(test); // Make sure we can also call non-public or public methods in package private classes runMethod.setAccessible(true); + test.setAttachedMethod(runMethod); this.runMethod = runMethod; this.mode = runSpecification.mode(); this.warmupIterations = warmUpAnno != null ? warmUpAnno.value() : test.getWarmupIterations(); + TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + runMethod); } + @Override + public Method getAttachedMethod() { return runMethod; } + @Override public void run() { switch (mode) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java index 4eb66162c32..09ca764f95c 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java @@ -34,13 +34,14 @@ public class TestBadFormat { public static void main(String[] args) throws NoSuchMethodException { runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); - expectTestFormatException(BadArguments.class); - expectTestFormatException(BadOverloadedMethod.class); - expectTestFormatException(BadCompilerControl.class); - expectTestFormatException(BadWarmup.class); +// expectTestFormatException(BadArguments.class); +// expectTestFormatException(BadOverloadedMethod.class); + expectTestFormatException(BadCompilerControl.class, -1); +// expectTestFormatException(BadWarmup.class, 5); +// expectTestFormatException(BadRunTests.class, -1); } - private static void expectTestFormatException(Class clazz) { + private static void expectTestFormatException(Class clazz, int count) { try { runTestsOnSameVM.invoke(null, clazz); } catch (Exception e) { @@ -48,9 +49,15 @@ private static void expectTestFormatException(Class clazz) { if (cause != null) { System.out.println(cause.getMessage()); } - Asserts.assertTrue(cause instanceof TestFormatException, "Unexpected exception: " + cause); + if (!(cause instanceof TestFormatException)) { + e.printStackTrace(); + Asserts.fail("Unexpected exception: " + cause); + } String msg = cause.getMessage(); - Asserts.assertTrue(msg.contains("Violations")); + // TODO: + if (count != -1) { + Asserts.assertTrue(msg.contains("Violations (" + count + ")")); + } return; } throw new RuntimeException("Should catch an exception"); @@ -98,10 +105,17 @@ public void notNumber4(int a) {} @Arguments({Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.TRUE}) public void notNumber5(boolean a, int b) {} - @Test @Arguments({Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.NUMBER_42}) public void notNumber6(int a, boolean b) {} + + @Test + @Arguments({Argument.MIN, Argument.MAX}) + public void notNumber7(boolean a, boolean b) {} + + @Test + @Arguments({Argument.DEFAULT}) + public void missingDefaultConstructor(ClassNoDefaultConstructor a) {} } class BadOverloadedMethod { @@ -150,6 +164,82 @@ public void mix1() {} @DontCompile @ForceCompile public void mix2() {} + + @Test + public void test6() {} + + @Run(test = "test6") + @DontCompile + public void notAtRun() {} + + @Test + public void test7() {} + + @Run(test = "test7") + @ForceCompile + public void notAtRun2() {} + + @Test + public void test8() {} + + @Run(test = "test8") + @DontInline + public void notAtRun3() {} + + @Test + public void test9() {} + + @Run(test = "test9") + @ForceInline + public void notAtRun4() {} + + @Test + public void test10() {} + + @Run(test = "test10") + @ForceInline + @ForceCompile + @DontInline + @DontCompile + public void notAtRun5() {} + + @Test + public void test11() {} + + @Check(test = "test11") + @DontCompile + public void notAtCheck() {} + + @Test + public void test12() {} + + @Check(test = "test12") + @ForceCompile + public void notAtCheck2() {} + + @Test + public void test13() {} + + @Check(test = "test13") + @DontInline + public void notAtCheck3() {} + + @Test + public void test14() {} + + @Check(test = "test14") + @ForceInline + public void notAtCheck4() {} + + @Test + public void test15() {} + + @Check(test = "test15") + @ForceInline + @ForceCompile + @DontInline + @DontCompile + public void notAtCheck5() {} } class BadWarmup { @@ -157,11 +247,79 @@ class BadWarmup { @Warmup(10000) public void warmUpNonTest() {} + @Test + @Warmup(1) + public void someTest() {} + + @Run(test = "someTest") + @Warmup(1) + public void twoWarmups() {} + @Test @Warmup(-1) public void negativeWarmup() {} - @Run(test = "negativeWarmup") + @Test + public void someTest2() {} + + @Run(test = "someTest2") @Warmup(-1) public void negativeWarmup2() {} + + @Test + public void someTest3() {} + + @Run(test = "someTest2", mode = RunMode.INVOKE_ONCE) + @Warmup(-1) + public void noWarmupAtInvokeOnce() {} + +} + +class BadRunTests { + @Test + public void sharedByTwo() {} + + @Run(test = "sharedByTwo") + public void share1() {} + + @Run(test = "sharedByTwo") + public void share2() {} + + @Run(test = "doesNotExist") + public void noTestExists() {} + + @Test + @Arguments({Argument.DEFAULT}) + public void argTest(int x) {} + + @Run(test = "argTest") + public void noArgumentAnnotationForRun() {} + + @Test + public void test1() {} + + @Run(test = "test1") + public void wrongParameters1(int x) {} + + @Test + public void test2() {} + + @Run(test = "test2") + public void wrongParameters(TestInfo info, int x) {} + + @Test + public void invalidShare() {} + + @Run(test = "invalidShare") + public void shareSameTestTwice1() {} + + @Run(test = "invalidShare") + public void shareSameTestTwice2() {} + + +} + +class ClassNoDefaultConstructor { + private ClassNoDefaultConstructor(int i) { + } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java index eefb999fd7f..f00d6665f92 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -32,7 +32,7 @@ public class TestBasics { private static boolean wasExecuted = false; private boolean lastToggleBoolean = true; - private final static int[] executed = new int[92]; + private final static int[] executed = new int[94]; private final static int[] executedOnce = new int[5]; private long[] nonFloatingRandomNumbers = new long[10]; private double[] floatingRandomNumbers = new double[10]; @@ -928,11 +928,24 @@ public void sameName(boolean a) { wasExecuted = true; } + // Allowed to overload test method if not test method itself @Check(test = "sameName") - public void checkSameName() { + public void sameName(TestInfo info) { executed[77]++; } + @Test + public void sameName2() { + executed[92]++; + } + + // Allowed to overload test method if not test method itself + @Run(test = "sameName2") + public void sameName2(TestInfo info) { + executed[93]++; + sameName2(); + } + /* * Custom run tests. */ diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java index e416f669c60..8f1eb09c34f 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java @@ -30,10 +30,12 @@ import java.lang.reflect.Method; public class TestControls { - static int[] executed = new int[13]; + static int[] executed = new int[15]; static boolean wasExecuted = false; static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + public int iFld; + public static void main(String[] args) throws Exception { Method runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); @@ -176,4 +178,48 @@ public void runNoWarmup2(TestInfo info) { Asserts.assertTrue(!info.isWarmUp()); executed[12]++; } + + @Test + public void testDontCompile3() { + wasExecuted = true; + } + + @DontCompile({CompLevel.C1, CompLevel.C1_LIMITED_PROFILE, CompLevel.C1_FULL_PROFILE}) + public void dontCompile3() { + for (int i = 0; i < 100; i++) + iFld = 3; + } + + + @Run(test = "testDontCompile3") + @Warmup(0) + public void runDontCompile3(TestInfo info) { + for (int i = 0; i < 10000; i++) { + dontCompile3(); + } + TestFramework.assertCompiledByC2(info.getTest()); + executed[13]++; + } + + @Test + public void testDontCompile4() { + wasExecuted = true; + } + + @DontCompile({CompLevel.C1_FULL_PROFILE, CompLevel.C2}) + public void dontCompile4() { + for (int i = 0; i < 100; i++) + iFld = 3; + } + + + @Run(test = "testDontCompile4") + @Warmup(0) + public void runDontCompile4(TestInfo info) { + for (int i = 0; i < 10000; i++) { + dontCompile4(); + } +// TestFramework.assertCompiledByC2(info.getTest()); + executed[14]++; + } } From 6dfadf29ff5c61011d8b8eb288dc69c0273d076e Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 16 Feb 2021 10:51:56 +0100 Subject: [PATCH 019/131] Add more compiler control tests --- .../valhalla/framework/TestFramework.java | 5 + .../compiler/valhalla/framework/TestInfo.java | 56 ++++++----- .../framework/tests/TestControls.java | 92 ++++++++++++++----- 3 files changed, 110 insertions(+), 43 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 8694acca3b7..16472e794cb 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -302,6 +302,11 @@ public static void assertNotCompiled(Method m) { m + " should not have been compiled"); } + public static void assertCompiled(Method m) { + TestRun.check(WHITE_BOX.isMethodCompiled(m, false) || WHITE_BOX.isMethodCompiled(m, true), + m + " should have been compiled"); + } + public static String getLastVmOutput() { return lastVmOutput; } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java index fa4184bf166..0af021fb7a0 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java @@ -26,7 +26,9 @@ import sun.hotspot.WhiteBox; import java.lang.reflect.Method; +import java.util.Arrays; import java.util.Random; +import java.util.stream.Collectors; public class TestInfo { private static final Random random = new Random(); @@ -71,25 +73,37 @@ public Method getTest() { return testMethod; } -// public boolean isC2Compiled(Method m) { -// return WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) == CompLevel.C2.getValue(); -//// return compiledByC2(m) == TriState.Yes; -// } -// -// public boolean isCompiledAtLevel(Method m, CompLevel level) { -// return WHITE_BOX.isMethodCompiled(m, false) && WHITE_BOX.getMethodCompilationLevel(m, false) == level.getValue(); -//// return compiledByC2(m) == TriState.Yes; -// } -// -// public void assertDeoptimizedByC2(Method m) { -// TestRun.check(!isC2Compiled(m) || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized"); -// } -// -// public void assertCompiledByC2(Method m) { -// TestRun.check(isC2Compiled(m), m + " should have been compiled"); -// } -// -// public void assertCompiledAtLevel(Method m, CompLevel level) { -// TestRun.check(isCompiledAtLevel(m, level), m + " should have been compiled at level " + level.name()); -// } + public Method getMethod(Class c, String name, Class... args) { + try { + return c.getMethod(name, args); + } catch (NoSuchMethodException e) { + String parameters = args == null || args.length == 0 ? "" : + " with arguments [" + Arrays.stream(args).map(Class::getName).collect(Collectors.joining(",")) + "]"; + throw new TestRunException("Could not find method " + name + " in " + c + parameters); + } + } + + public Method getTestClassMethod(String name, Class... args) { + return getMethod(testMethod.getDeclaringClass(), name, args); + } + + public boolean isC2Compiled(Method m) { + return TestFramework.isC2Compiled(testMethod); + } + + public boolean isCompiledAtLevel(CompLevel compLevel) { + return TestFramework.isCompiledAtLevel(testMethod, compLevel); + } + + public void assertDeoptimizedByC2() { + TestFramework.assertDeoptimizedByC2(testMethod); + } + + public void assertCompiledByC2() { + TestFramework.assertCompiledByC2(testMethod); + } + + public void assertCompiledAtLevel(CompLevel level) { + TestFramework.assertCompiledAtLevel(testMethod, level); + } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java index 8f1eb09c34f..0ffbfa7cfe9 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java @@ -54,6 +54,7 @@ public static void main(String[] args) throws Exception { Asserts.assertEQ(executed[10], 1); Asserts.assertEQ(executed[11], 2); Asserts.assertEQ(executed[12], 1); + Asserts.assertEQ(executed[13], 1); Asserts.assertFalse(wasExecuted); final long started = System.currentTimeMillis(); long elapsed = 0; @@ -180,46 +181,93 @@ public void runNoWarmup2(TestInfo info) { } @Test - public void testDontCompile3() { + public void testCompilation() { wasExecuted = true; } - @DontCompile({CompLevel.C1, CompLevel.C1_LIMITED_PROFILE, CompLevel.C1_FULL_PROFILE}) - public void dontCompile3() { - for (int i = 0; i < 100; i++) + @DontCompile({CompLevel.C1}) + public void dontCompileC1() { + for (int i = 0; i < 10; i++) { iFld = 3; + } } + @DontCompile({CompLevel.C1, CompLevel.C1_LIMITED_PROFILE, CompLevel.C1_FULL_PROFILE}) + public void dontCompileC1AllLevels(int x) { + for (int i = 0; i < 10; i++) { + iFld = x; + } + } - @Run(test = "testDontCompile3") - @Warmup(0) - public void runDontCompile3(TestInfo info) { - for (int i = 0; i < 10000; i++) { - dontCompile3(); + @DontCompile({CompLevel.C2}) + public void dontCompileC2(int x, boolean b) { + for (int i = 0; i < 10; i++) { + iFld = x; } - TestFramework.assertCompiledByC2(info.getTest()); - executed[13]++; } - @Test - public void testDontCompile4() { + // Default is C2. + @ForceCompile + public void forceCompileDefault() { wasExecuted = true; } - @DontCompile({CompLevel.C1_FULL_PROFILE, CompLevel.C2}) - public void dontCompile4() { - for (int i = 0; i < 100; i++) - iFld = 3; + // ANY maps to C2. + @ForceCompile + public void forceCompileAny() { + wasExecuted = true; + } + + @DontCompile({CompLevel.ANY}) + public void dontCompileAny() { + for (int i = 0; i < 10; i++) { + iFld = i; + } + } + + @ForceCompile(CompLevel.C1) + public void forceCompileC1() { + wasExecuted = true; + } + + @ForceCompile(CompLevel.C1_LIMITED_PROFILE) + public void forceCompileC1Limited() { + wasExecuted = true; } + @ForceCompile(CompLevel.C1_FULL_PROFILE) + public void forceCompileC1Full() { + wasExecuted = true; + } + + @ForceCompile(CompLevel.C2) + public void forceCompileC2() { + wasExecuted = true; + } - @Run(test = "testDontCompile4") + @Run(test = "testCompilation") @Warmup(0) - public void runDontCompile4(TestInfo info) { + public void runTestCompilation(TestInfo info) { for (int i = 0; i < 10000; i++) { - dontCompile4(); + dontCompileAny(); + dontCompileC1(); + dontCompileC1AllLevels(i); + dontCompileC2(i, i % 2 == 0); } -// TestFramework.assertCompiledByC2(info.getTest()); - executed[14]++; + TestFramework.assertCompiledByC2(info.getTest()); + TestFramework.assertNotCompiled(info.getTestClassMethod("dontCompileAny")); + Asserts.assertTrue(TestFramework.isC2Compiled(info.getTestClassMethod("dontCompileC1"))); + Asserts.assertTrue(TestFramework.isC2Compiled(info.getTestClassMethod("dontCompileC1AllLevels", int.class))); + Method dontCompileC2 = info.getTestClassMethod("dontCompileC2", int.class, boolean.class); + Asserts.assertFalse(TestFramework.isC2Compiled(dontCompileC2)); + TestFramework.assertCompiled(dontCompileC2); + + TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileDefault"), CompLevel.C2); + TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileAny"), CompLevel.C2); + TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileC2"), CompLevel.C2); + TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileC1"), CompLevel.C1); + TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileC1Limited"), CompLevel.C1_LIMITED_PROFILE); + TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileC1Full"), CompLevel.C1_FULL_PROFILE); + executed[13]++; } } From f480f754f0f348a9e1559df0bf194e5d8582ce19 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 16 Feb 2021 16:18:31 +0100 Subject: [PATCH 020/131] Fix @DontCompile and @ForceCompile and add tests for it, fix TestBadFormat reporting, added bad CompileCommand tests, added more interface methods to TestFramework and TestInfo --- .../valhalla/framework/ArgumentValue.java | 27 ++-- .../valhalla/framework/CompLevel.java | 41 +++++- .../valhalla/framework/TestFormat.java | 2 +- .../valhalla/framework/TestFramework.java | 50 ++++++- .../compiler/valhalla/framework/TestInfo.java | 12 ++ .../framework/tests/TestBadFormat.java | 138 ++++++++++++++++-- .../framework/tests/TestControls.java | 51 ++++--- .../tests/TestWithHelperClasses.java | 3 +- 8 files changed, 262 insertions(+), 62 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java index 4586ee6cd15..10b142f08d5 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java @@ -79,7 +79,16 @@ public static ArgumentValue[] getArguments(Method m) { Parameter parameterObj = declaredParameterObjects[i]; try { switch (specifiedArg) { - case DEFAULT -> arguments[i] = createDefault(parameter); + case DEFAULT -> { + try { + arguments[i] = createDefault(parameter); + } catch (NoSuchMethodException e) { + TestFormat.fail("Cannot create new default instance of " + parameter + " for " + m + + " due to missing default constructor"); + } catch (Exception e) { + TestFormat.fail("Cannot create new default instance of " + parameter + " for " + m + ": " + e.getCause()); + } + } case NUMBER_42 -> { TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_42 argument for non-number " + parameterObj + " for " + m); @@ -142,7 +151,7 @@ private static ArgumentValue create(Object argumentValue) { return new ArgumentValue(argumentValue, null, false); } - private static ArgumentValue createDefault(Class c) { + private static ArgumentValue createDefault(Class c) throws Exception { if (ArgumentValue.isNumber(c)) { return ArgumentValue.create((byte)0); } else if (ArgumentValue.isChar(c)) { @@ -151,17 +160,9 @@ private static ArgumentValue createDefault(Class c) { return ArgumentValue.create(false); } else { // Object - try { - Constructor constructor = c.getDeclaredConstructor(); - constructor.setAccessible(true); // Make sure to have access to private default constructor - return ArgumentValue.create(constructor.newInstance()); - } catch (NoSuchMethodException e) { - TestFormat.fail("Cannot create new default instance of " + c + " due to missing default constructor"); - return null; - } catch (Exception e) { - TestFormat.fail("Cannot create new default instance of " + c + ": " + e.getCause()); - return null; - } + Constructor constructor = c.getDeclaredConstructor(); + constructor.setAccessible(true); // Make sure to have access to private default constructor + return ArgumentValue.create(constructor.newInstance()); } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java index b1c8eca1e83..615e22648a7 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java @@ -27,13 +27,34 @@ import java.util.Map; public enum CompLevel { - SKIP(-3), // Skip a @Test having this value + /** + * Skip a {@link Test @Test} when set as {@link Test#compLevel()}. + */ + SKIP(-3), + /** + * Any compilation level: + *
    + *
  • Defaults to C2 for {@link Test @Test} and {@link ForceCompile @ForceCompile}.
  • + *
  • Excludes all compilations for {@link DontCompile @DontCompile}.
  • + *
+ */ ANY(-2), - C1(1), // C1 - C1_LIMITED_PROFILE(2), // C1, invocation & backedge counters - C1_FULL_PROFILE(3), // C1, invocation & backedge counters + mdo - C2(4); // C2 or JVMCI - + /** + * Compilation level 1: C1 compilation without any profile information. + */ + C1(1), + /** + * Compilation level 2: C1 compilation with limited profile information: Includes Invocation and backedge counters. + */ + C1_LIMITED_PROFILE(2), + /** + * Compilation level 3: C1 compilation with full profile information: Includes Invocation and backedge counters with MDO. + */ + C1_FULL_PROFILE(3), + /** + * Compilation level 4: C2 compilation with full optimizations. + */ + C2(4); private static final Map typesByValue = new HashMap<>(); private final int value; @@ -55,4 +76,12 @@ public int getValue() { public static CompLevel forValue(int value) { return typesByValue.get(value); } + + public static boolean overlapping(CompLevel l1, CompLevel l2) { + return l1.isC1() == l2.isC1() || (l1 == C2 && l2 == C2); + } + + private boolean isC1() { + return this == C1 || this == C1_LIMITED_PROFILE || this == C1_FULL_PROFILE; + } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java index 15f6eb003a3..6c1e4cdb94d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java @@ -53,7 +53,7 @@ public static void reportIfAnyFailures() { return; } StringBuilder builder = new StringBuilder(); - builder.append("One or more format violations have been detected:\n\n"); + builder.append("\nOne or more format violations have been detected:\n\n"); builder.append("Violations (").append(FAILURES.size()).append(")\n"); builder.append("--------------\n"); for (String failure : FAILURES) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 16472e794cb..17c268ce3d8 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -277,6 +277,10 @@ public static void compile(Method m, CompLevel compLevel) { enqueueMethodForCompilation(m, compLevel); } + public static boolean isC1Compiled(Method m) { + return compiledByC1(m) == TriState.Yes; + } + public static boolean isC2Compiled(Method m) { return compiledByC2(m) == TriState.Yes; } @@ -285,12 +289,20 @@ public static boolean isCompiledAtLevel(Method m, CompLevel compLevel) { return compiledAtLevel(m, compLevel) == TriState.Yes; } + public static void assertDeoptimizedByC1(Method m) { + TestRun.check(compiledByC1(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized by C1"); + } + public static void assertDeoptimizedByC2(Method m) { - TestRun.check(compiledByC2(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized"); + TestRun.check(compiledByC2(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized by C2"); + } + + public static void assertCompiledByC1(Method m) { + TestRun.check(compiledByC1(m) != TriState.No, m + " should have been C1 compiled"); } public static void assertCompiledByC2(Method m) { - TestRun.check(compiledByC2(m) != TriState.No, m + " should have been compiled"); + TestRun.check(compiledByC2(m) != TriState.No, m + " should have been C2 compiled"); } public static void assertCompiledAtLevel(Method m, CompLevel level) { @@ -555,6 +567,9 @@ private void applyIndependentCompilationCommands(Method m) { dontCompileMethod(m); } else { for (CompLevel compLevel : dontCompileAnno.value()) { + TestFormat.check(compLevel == CompLevel.C1 || compLevel == CompLevel.C2 || compLevel == CompLevel.ANY, + "Can only specify compilation level C1 (no individual C1 levels), " + + "C2 or ANY (no compilation, same as specifying anything) in @DontCompile at " + m); dontCompileMethodAtLevel(m, compLevel); } } @@ -579,10 +594,10 @@ private void checkCompilationCommandAnnotations(Method m, ForceInline forceInlin CompLevel forceCompile = forceCompileAnno.value(); CompLevel[] dontCompile = dontCompileAnno.value(); TestFormat.check(dontCompile.length != 0, - "Cannot have @ForceCompile and default @DontCompile (exclude all) at the same time at " + m); + "Cannot have @ForceCompile and default @DontCompile (CompLevel.ANY) at the same time at " + m); TestFormat.check(forceCompile != CompLevel.ANY, - "Cannot have @ForceCompile with ANY and @DontCompile at the same time at " + m); - TestFormat.check(Arrays.stream(dontCompile).noneMatch(a -> a == forceCompile), + "Cannot have @ForceCompile(CompLevel.ANY) and @DontCompile at the same time at " + m); + TestFormat.check(Arrays.stream(dontCompile).noneMatch(a -> CompLevel.overlapping(a, forceCompile)), "Overlapping compilation levels with @ForceCompile and @DontCompile at " + m); } } @@ -607,6 +622,8 @@ private void dontCompileMethodAtLevel(Method m, CompLevel compLevel) { private void applyForceCompileCommand(Method m) { ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); if (forceCompileAnno != null) { + TestFormat.check(forceCompileAnno.value() != CompLevel.SKIP, + "Cannot define compilation level SKIP in @ForceCompile at " + m); enqueueMethodForCompilation(m, forceCompileAnno.value()); } } @@ -743,8 +760,8 @@ private void setupCheckAndRunMethods() { private void addCheckedTest(Method m, Check checkAnno, Run runAnno) { TestFormat.check(runAnno == null, m + " has invalid @Run annotation while @Check annotation is present."); Method testMethod = testMethodMap.get(checkAnno.test()); - TestFormat.check(testMethod != null,"Did not find associated test method " + checkAnno.test() + " for @Check at " + m); - + TestFormat.check(testMethod != null,"Did not find associated test method \"" + m.getDeclaringClass().getName() + + "." + checkAnno.test() + "\" for @Check at " + m); boolean firstParameterTestInfo = m.getParameterCount() > 0 && m.getParameterTypes()[0].equals(TestInfo.class); boolean secondParameterTestInfo = m.getParameterCount() > 1 && m.getParameterTypes()[1].equals(TestInfo.class); @@ -795,7 +812,8 @@ private void addCustomRunTest(Method m, Run runAnno) { } private void checkCustomRunTest(Method m, Run runAnno, Method testMethod, DeclaredTest test) { - TestFormat.check(testMethod != null, "Did not find associated test method \"" + runAnno.test() + "\" specified in @Run at " + m); + TestFormat.check(testMethod != null, "Did not find associated test method \"" + m.getDeclaringClass().getName() + + "." + runAnno.test() + "\" specified in @Run at " + m); TestFormat.check(test != null, "Missing @Test annotation for associated test method " + runAnno.test() + " for @Run at " + m); Method attachedMethod = test.getAttachedMethod(); TestFormat.check(attachedMethod == null, @@ -867,6 +885,22 @@ enum TriState { No } + private static TriState compiledByC1(Method m) { + TriState triState = compiledAtLevel(m, CompLevel.C1); + if (triState != TriState.No) { + return triState; + } + triState = compiledAtLevel(m, CompLevel.C1_LIMITED_PROFILE); + if (triState != TriState.No) { + return triState; + } + triState = compiledAtLevel(m, CompLevel.C1_FULL_PROFILE); + if (triState != TriState.No) { + return triState; + } + return TriState.No; + } + private static TriState compiledByC2(Method m) { return compiledAtLevel(m, CompLevel.C2); } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java index 0af021fb7a0..34452e98966 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java @@ -87,6 +87,10 @@ public Method getTestClassMethod(String name, Class... args) { return getMethod(testMethod.getDeclaringClass(), name, args); } + public boolean isC1Compiled(Method m) { + return TestFramework.isC1Compiled(testMethod); + } + public boolean isC2Compiled(Method m) { return TestFramework.isC2Compiled(testMethod); } @@ -95,6 +99,14 @@ public boolean isCompiledAtLevel(CompLevel compLevel) { return TestFramework.isCompiledAtLevel(testMethod, compLevel); } + public void assertDeoptimizedByC1() { + TestFramework.assertDeoptimizedByC1(testMethod); + } + + public void assertCompiledByC1() { + TestFramework.assertCompiledByC1(testMethod); + } + public void assertDeoptimizedByC2() { TestFramework.assertDeoptimizedByC2(testMethod); } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java index 09ca764f95c..9a7ff6b8375 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java @@ -26,7 +26,11 @@ import compiler.valhalla.framework.*; import jdk.test.lib.Asserts; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; public class TestBadFormat { @@ -34,14 +38,14 @@ public class TestBadFormat { public static void main(String[] args) throws NoSuchMethodException { runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); -// expectTestFormatException(BadArguments.class); -// expectTestFormatException(BadOverloadedMethod.class); - expectTestFormatException(BadCompilerControl.class, -1); -// expectTestFormatException(BadWarmup.class, 5); -// expectTestFormatException(BadRunTests.class, -1); + expectTestFormatException(BadArguments.class); + expectTestFormatException(BadOverloadedMethod.class); + expectTestFormatException(BadCompilerControl.class); + expectTestFormatException(BadWarmup.class); + expectTestFormatException(BadRunTests.class); } - private static void expectTestFormatException(Class clazz, int count) { + private static void expectTestFormatException(Class clazz) { try { runTestsOnSameVM.invoke(null, clazz); } catch (Exception e) { @@ -54,14 +58,34 @@ private static void expectTestFormatException(Class clazz, int count) { Asserts.fail("Unexpected exception: " + cause); } String msg = cause.getMessage(); - // TODO: - if (count != -1) { - Asserts.assertTrue(msg.contains("Violations (" + count + ")")); - } + + Violations violations = getViolations(clazz); + Asserts.assertTrue(violations.getFailedMethods().stream().allMatch(msg::contains)); + Asserts.assertTrue(msg.contains("Violations (" + violations.getViolationCount() + ")")); return; } throw new RuntimeException("Should catch an exception"); } + + private static Violations getViolations(Class clazz) { + Violations violations = new Violations(); + for (Method m : clazz.getDeclaredMethods()) { + NoFail noFail = m.getDeclaredAnnotation(NoFail.class); + if (noFail == null) { + FailCount failCount = m.getDeclaredAnnotation(FailCount.class); + if (failCount != null) { + violations.addFail(m, failCount.value()); + } else { + violations.addFail(m, 1); + } + } else { + // Cannot define both annotation at the same method. + Asserts.assertEQ(m.getDeclaredAnnotation(FailCount.class), null); + } + } + return violations; + } + } class BadArguments { @@ -105,10 +129,12 @@ public void notNumber4(int a) {} @Arguments({Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.TRUE}) public void notNumber5(boolean a, int b) {} + @FailCount(2) @Test @Arguments({Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.NUMBER_42}) public void notNumber6(int a, boolean b) {} + @FailCount(2) @Test @Arguments({Argument.MIN, Argument.MAX}) public void notNumber7(boolean a, boolean b) {} @@ -120,6 +146,7 @@ public void missingDefaultConstructor(ClassNoDefaultConstructor a) {} class BadOverloadedMethod { + @FailCount(0) // Combined with both sameName() below @Test public void sameName() {} @@ -165,6 +192,7 @@ public void mix1() {} @ForceCompile public void mix2() {} + @NoFail @Test public void test6() {} @@ -172,6 +200,7 @@ public void test6() {} @DontCompile public void notAtRun() {} + @NoFail @Test public void test7() {} @@ -179,6 +208,7 @@ public void test7() {} @ForceCompile public void notAtRun2() {} + @NoFail @Test public void test8() {} @@ -186,6 +216,7 @@ public void test8() {} @DontInline public void notAtRun3() {} + @NoFail @Test public void test9() {} @@ -193,6 +224,7 @@ public void test9() {} @ForceInline public void notAtRun4() {} + @NoFail @Test public void test10() {} @@ -203,6 +235,7 @@ public void test10() {} @DontCompile public void notAtRun5() {} + @NoFail @Test public void test11() {} @@ -210,6 +243,7 @@ public void test11() {} @DontCompile public void notAtCheck() {} + @NoFail @Test public void test12() {} @@ -217,6 +251,7 @@ public void test12() {} @ForceCompile public void notAtCheck2() {} + @NoFail @Test public void test13() {} @@ -224,6 +259,7 @@ public void test13() {} @DontInline public void notAtCheck3() {} + @NoFail @Test public void test14() {} @@ -231,6 +267,7 @@ public void test14() {} @ForceInline public void notAtCheck4() {} + @NoFail @Test public void test15() {} @@ -240,6 +277,41 @@ public void test15() {} @DontInline @DontCompile public void notAtCheck5() {} + + @ForceCompile(CompLevel.SKIP) + public void invalidSkip1() {} + + @DontCompile(CompLevel.SKIP) + public void invalidSkip2() {} + + @DontCompile({CompLevel.C1, CompLevel.SKIP}) + public void invalidSkip3() {} + + @ForceCompile(CompLevel.C1) + @DontCompile(CompLevel.C1) + public void overlappingCompile1() {} + + @ForceCompile(CompLevel.C2) + @DontCompile(CompLevel.C2) + public void overlappingCompile2() {} + + @ForceCompile(CompLevel.ANY) + @DontCompile(CompLevel.C1) + public void invalidMix1() {} + + @ForceCompile(CompLevel.ANY) + @DontCompile(CompLevel.C2) + public void invalidMix2() {} + + @ForceCompile(CompLevel.ANY) + @DontCompile + public void invalidMix3() {} + + @DontCompile(CompLevel.C1_LIMITED_PROFILE) + public void invalidDontCompile1() {} + + @DontCompile(CompLevel.C1_FULL_PROFILE) + public void invalidDontCompile2() {} } class BadWarmup { @@ -251,6 +323,7 @@ public void warmUpNonTest() {} @Warmup(1) public void someTest() {} + @FailCount(0) // Combined with someTest() @Run(test = "someTest") @Warmup(1) public void twoWarmups() {} @@ -259,6 +332,7 @@ public void twoWarmups() {} @Warmup(-1) public void negativeWarmup() {} + @NoFail @Test public void someTest2() {} @@ -266,22 +340,25 @@ public void someTest2() {} @Warmup(-1) public void negativeWarmup2() {} + @NoFail @Test public void someTest3() {} + @FailCount(2) // Negative warmup and invoke once @Run(test = "someTest2", mode = RunMode.INVOKE_ONCE) @Warmup(-1) public void noWarmupAtInvokeOnce() {} - } class BadRunTests { @Test public void sharedByTwo() {} + @FailCount(0) // Combined with sharedByTwo() @Run(test = "sharedByTwo") public void share1() {} + @FailCount(0) // Combined with sharedByTwo() @Run(test = "sharedByTwo") public void share2() {} @@ -289,18 +366,21 @@ public void share2() {} public void noTestExists() {} @Test - @Arguments({Argument.DEFAULT}) + @Arguments(Argument.DEFAULT) public void argTest(int x) {} + @FailCount(0) // Combined with argTest() @Run(test = "argTest") public void noArgumentAnnotationForRun() {} + @NoFail @Test public void test1() {} @Run(test = "test1") public void wrongParameters1(int x) {} + @NoFail @Test public void test2() {} @@ -310,16 +390,46 @@ public void wrongParameters(TestInfo info, int x) {} @Test public void invalidShare() {} + @FailCount(0) // Combined with invalidShare() @Run(test = "invalidShare") public void shareSameTestTwice1() {} + @FailCount(0) // Combined with invalidShare() @Run(test = "invalidShare") public void shareSameTestTwice2() {} - - } class ClassNoDefaultConstructor { private ClassNoDefaultConstructor(int i) { } } + +// All methods without such an annotation must occur in the violation messages. +@Retention(RetentionPolicy.RUNTIME) +@interface NoFail {} + +// Specify a fail count for a method without @NoFail. Use the value 0 if multiple methods are part of the same violation. +@Retention(RetentionPolicy.RUNTIME) +@interface FailCount { + int value(); +} + +class Violations { + private final List failedMethods = new ArrayList<>(); + private int violations; + + public int getViolationCount() { + return violations; + } + + public List getFailedMethods() { + return failedMethods; + } + + public void addFail(Method m, int count) { + failedMethods.add(m.getName()); + violations += count; + } +} + + diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java index 0ffbfa7cfe9..7f26df9fda5 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java @@ -141,7 +141,7 @@ public void testCompileAtLevel1() { executed[6]++; } - @DontCompile({CompLevel.C1_FULL_PROFILE, CompLevel.C1_LIMITED_PROFILE, CompLevel.C2}) + @DontCompile({CompLevel.C1, CompLevel.C2}) public static void dontCompile2() { executed[7]++; } @@ -185,22 +185,29 @@ public void testCompilation() { wasExecuted = true; } - @DontCompile({CompLevel.C1}) + @DontCompile(CompLevel.ANY) + public void dontCompileAny() { + for (int i = 0; i < 10; i++) { + iFld = i; + } + } + + @DontCompile(CompLevel.C1) public void dontCompileC1() { for (int i = 0; i < 10; i++) { iFld = 3; } } - @DontCompile({CompLevel.C1, CompLevel.C1_LIMITED_PROFILE, CompLevel.C1_FULL_PROFILE}) - public void dontCompileC1AllLevels(int x) { + @DontCompile(CompLevel.C2) + public void dontCompileC2(int x, boolean b) { for (int i = 0; i < 10; i++) { iFld = x; } } - @DontCompile({CompLevel.C2}) - public void dontCompileC2(int x, boolean b) { + @DontCompile({CompLevel.C1, CompLevel.C2}) + public void dontCompileC1C2(int x) { for (int i = 0; i < 10; i++) { iFld = x; } @@ -218,13 +225,6 @@ public void forceCompileAny() { wasExecuted = true; } - @DontCompile({CompLevel.ANY}) - public void dontCompileAny() { - for (int i = 0; i < 10; i++) { - iFld = i; - } - } - @ForceCompile(CompLevel.C1) public void forceCompileC1() { wasExecuted = true; @@ -245,22 +245,32 @@ public void forceCompileC2() { wasExecuted = true; } + @ForceCompile(CompLevel.C1) + @DontCompile(CompLevel.C2) + public void forceC1DontC2() { + wasExecuted = true; + } + + @ForceCompile(CompLevel.C2) + @DontCompile(CompLevel.C1) + public void forceC2DontC1() { + wasExecuted = true; + } + @Run(test = "testCompilation") @Warmup(0) public void runTestCompilation(TestInfo info) { for (int i = 0; i < 10000; i++) { dontCompileAny(); dontCompileC1(); - dontCompileC1AllLevels(i); dontCompileC2(i, i % 2 == 0); + dontCompileC1C2(i); } TestFramework.assertCompiledByC2(info.getTest()); TestFramework.assertNotCompiled(info.getTestClassMethod("dontCompileAny")); - Asserts.assertTrue(TestFramework.isC2Compiled(info.getTestClassMethod("dontCompileC1"))); - Asserts.assertTrue(TestFramework.isC2Compiled(info.getTestClassMethod("dontCompileC1AllLevels", int.class))); - Method dontCompileC2 = info.getTestClassMethod("dontCompileC2", int.class, boolean.class); - Asserts.assertFalse(TestFramework.isC2Compiled(dontCompileC2)); - TestFramework.assertCompiled(dontCompileC2); + TestFramework.assertCompiledByC2(info.getTestClassMethod("dontCompileC1")); + TestFramework.assertNotCompiled(info.getTestClassMethod("dontCompileC1C2", int.class)); + TestFramework.assertCompiledByC1(info.getTestClassMethod("dontCompileC2", int.class, boolean.class)); TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileDefault"), CompLevel.C2); TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileAny"), CompLevel.C2); @@ -268,6 +278,9 @@ public void runTestCompilation(TestInfo info) { TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileC1"), CompLevel.C1); TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileC1Limited"), CompLevel.C1_LIMITED_PROFILE); TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileC1Full"), CompLevel.C1_FULL_PROFILE); + + TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceC1DontC2"), CompLevel.C1); + TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceC2DontC1"), CompLevel.C2); executed[13]++; } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java index b2e03d0fc33..de620c69189 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java @@ -33,7 +33,8 @@ public static void main(String[] args) { try { TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class); } catch (Exception e) { - Asserts.assertTrue(TestFramework.getLastVmOutput().contains("public static void compiler.valhalla.framework.tests.Helper2.foo() should have been compiled")); + Asserts.assertFalse(TestFramework.getLastVmOutput().contains("public static void compiler.valhalla.framework.tests.Helper1.foo() should have been C2 compiled")); + Asserts.assertTrue(TestFramework.getLastVmOutput().contains("public static void compiler.valhalla.framework.tests.Helper2.foo() should have been C2 compiled")); return; } throw new RuntimeException("Did not catch exception"); From 5963c88aacf354b99bef7c9bacbef9c7916dbc13 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 16 Feb 2021 16:49:36 +0100 Subject: [PATCH 021/131] Update Copyright to 2021, rename INVOKE_ONCE to STANDALONE --- .../src/compiler/valhalla/framework/Argument.java | 2 +- .../compiler/valhalla/framework/ArgumentValue.java | 2 +- .../src/compiler/valhalla/framework/Arguments.java | 2 +- .../src/compiler/valhalla/framework/Check.java | 2 +- .../src/compiler/valhalla/framework/CheckAt.java | 2 +- .../src/compiler/valhalla/framework/CompLevel.java | 2 +- .../compiler/valhalla/framework/DontCompile.java | 2 +- .../compiler/valhalla/framework/DontInline.java | 2 +- .../src/compiler/valhalla/framework/Foo.java | 2 +- .../compiler/valhalla/framework/ForceCompile.java | 2 +- .../compiler/valhalla/framework/ForceInline.java | 2 +- .../src/compiler/valhalla/framework/IR.java | 2 +- .../valhalla/framework/IREncodingPrinter.java | 2 +- .../src/compiler/valhalla/framework/IRMatcher.java | 2 +- .../src/compiler/valhalla/framework/IRNode.java | 2 +- .../src/compiler/valhalla/framework/IRs.java | 2 +- .../valhalla/framework/OSRCompileOnly.java | 2 +- .../src/compiler/valhalla/framework/Run.java | 2 +- .../src/compiler/valhalla/framework/RunMode.java | 14 +++++++++++--- .../src/compiler/valhalla/framework/Scenario.java | 2 +- .../src/compiler/valhalla/framework/Test.java | 2 +- .../compiler/valhalla/framework/TestFormat.java | 2 +- .../valhalla/framework/TestFormatException.java | 2 +- .../compiler/valhalla/framework/TestFramework.java | 14 +++++++------- .../src/compiler/valhalla/framework/TestInfo.java | 2 +- .../src/compiler/valhalla/framework/TestRun.java | 2 +- .../valhalla/framework/TestRunException.java | 2 +- .../src/compiler/valhalla/framework/VMFlag.java | 2 +- .../valhalla/framework/VMFlagValhalla.java | 2 +- .../src/compiler/valhalla/framework/Warmup.java | 2 +- .../valhalla/framework/tests/TestBadFormat.java | 4 ++-- .../valhalla/framework/tests/TestBasics.java | 6 +++--- .../valhalla/framework/tests/TestCompLevels.java | 2 +- .../valhalla/framework/tests/TestControls.java | 4 ++-- .../valhalla/framework/tests/TestIRMatching.java | 2 +- .../framework/tests/TestPackagePrivate.java | 2 +- .../valhalla/framework/tests/TestSanity.java | 2 +- .../valhalla/framework/tests/TestScenarios.java | 2 +- .../framework/tests/TestWithHelperClasses.java | 2 +- 39 files changed, 59 insertions(+), 51 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java index 389474bb566..0a0abe0845d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java index 10b142f08d5..ca914bca153 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java index bcc11d5c268..c6b9d71cc86 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java index f3f4614a46d..fe13e50dacd 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java index 6dcfa5e249a..db577df93d7 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java index 615e22648a7..7847effa583 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java index 55c80b4ce53..a338695adf6 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java index e0a4a4b1148..27d3ed0751d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java index 433b65549ee..54b896ad5e4 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java index ad123f0197b..5aa26edfc12 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java index 65df165cf00..8a23c5658bd 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java index b622f44aab6..9c53f45ed24 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java index 06ab8c4de46..4bab160a217 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java index b3be938b65c..77b58004264 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java index 401067976e8..653d8618fd7 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java index 178ffa1c09f..86f305fba13 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSRCompileOnly.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSRCompileOnly.java index dfb19aeecca..66babc05383 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSRCompileOnly.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSRCompileOnly.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java index 0cd2cb9ef53..501a56b8670 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java index 3283845c70b..6fb2dbce97b 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -24,6 +24,14 @@ package compiler.valhalla.framework; public enum RunMode { - INVOKE_ONCE, - NORMAL + /** + * Default mode: First warm up run method, then compile the associated + * test method and finally invoke the run method once more. + */ + NORMAL, + /** + * Standalone mode: There is no warm up and no forced compilation. + * The run method is responsible to trigger the compilation(s). + */ + STANDALONE } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java index 9c3bbc91872..b5ff5872825 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java index e258437f034..8e9c197ae74 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java index 6c1e4cdb94d..79e0f2e2200 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java index f46cd5b9aae..0fc2477e615 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 17c268ce3d8..e3c707c7645 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -825,11 +825,11 @@ private void checkCustomRunTest(Method m, Run runAnno, Method testMethod, Declar TestFormat.checkNoThrow(warmupAnno == null, "Cannot set @Warmup at @Test method " + testMethod + " when used with its @Run method " + m + ". Use @Warmup at @Run method instead."); warmupAnno = getAnnotation(m, Warmup.class); - TestFormat.checkNoThrow(warmupAnno == null || runAnno.mode() != RunMode.INVOKE_ONCE, - "Cannot set @Warmup at @Run method " + m + " when used with RunMode.ONCE. The @Run method is only invoked once."); + TestFormat.checkNoThrow(warmupAnno == null || runAnno.mode() != RunMode.STANDALONE, + "Cannot set @Warmup at @Run method " + m + " when used with RunMode.STANDALONE. The @Run method is only invoked once."); OSRCompileOnly osrAnno = getAnnotation(testMethod, OSRCompileOnly.class); - TestFormat.checkNoThrow(osrAnno == null || runAnno.mode() != RunMode.INVOKE_ONCE, - "Cannot set @OSRCompileOnly at @Run method " + m + " when used with RunMode.ONCE. The @Run method is responsible for triggering compilation."); + TestFormat.checkNoThrow(osrAnno == null || runAnno.mode() != RunMode.STANDALONE, + "Cannot set @OSRCompileOnly at @Run method " + m + " when used with RunMode.STANDALONE. The @Run method is responsible for triggering compilation."); } private static T getAnnotation(Method m, Class c) { @@ -1250,7 +1250,7 @@ public CustomRunTest(DeclaredTest test, Method runMethod, Warmup warmUpAnno, Run @Override public void run() { switch (mode) { - case INVOKE_ONCE -> runMethod(); + case STANDALONE -> runMethod(); case NORMAL -> super.run(); } } @@ -1277,7 +1277,7 @@ protected void checkCompilationLevel() { if (level != test.getCompLevel()) { String message = "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod + "."; switch (mode) { - case INVOKE_ONCE -> message = message + "\nCheck your @Run method (invoked once) " + runMethod + " to ensure that " + testMethod + " will be complied at the requested level."; + case STANDALONE -> message = message + "\nCheck your @Run method (invoked once) " + runMethod + " to ensure that " + testMethod + " will be complied at the requested level."; case NORMAL -> message = message + "\nCheck your @Run method " + runMethod + " to ensure that " + testMethod + " is called at least once in each iteration."; } TestRun.fail(message); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java index 34452e98966..c9f1bbfa900 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java index dc54189662b..50248f66ecc 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java index 29ffbfb3220..7eb5d96a7e8 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java index b28156d1a3d..9a8d34ab124 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java index 56ac3139f71..986c2255b89 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java index 02e381cf1d1..7a135765aaf 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java index 9a7ff6b8375..31581cf9bf5 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -345,7 +345,7 @@ public void negativeWarmup2() {} public void someTest3() {} @FailCount(2) // Negative warmup and invoke once - @Run(test = "someTest2", mode = RunMode.INVOKE_ONCE) + @Run(test = "someTest2", mode = RunMode.STANDALONE) @Warmup(-1) public void noWarmupAtInvokeOnce() {} } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java index f00d6665f92..ca69b6a1d07 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -989,7 +989,7 @@ public void testRunOnce() { // Custom run test that is only invoked once. There is no warm up and no compilation. This method is responsible // for triggering compilation. - @Run(test = "testRunOnce", mode = RunMode.INVOKE_ONCE) + @Run(test = "testRunOnce", mode = RunMode.STANDALONE) public void runTestRunOnce(TestInfo info) { testRunOnce(); } @@ -999,7 +999,7 @@ public void testRunOnce2() { executed[75]++; } - @Run(test = "testRunOnce2", mode = RunMode.INVOKE_ONCE) + @Run(test = "testRunOnce2", mode = RunMode.STANDALONE) public void runTestRunOnce2(TestInfo info) { for (int i = 0; i < TestFramework.WARMUP_ITERATIONS + 1; i++) { testRunOnce2(); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java index 49db39be344..68d6ce7bce0 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java index 7f26df9fda5..da42df9ffb7 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -127,7 +127,7 @@ public static void dontCompile() { executed[3]++; } - @Run(test = "testDontCompile", mode = RunMode.INVOKE_ONCE) + @Run(test = "testDontCompile", mode = RunMode.STANDALONE) public void runTestDontCompile() throws NoSuchMethodException { for (int i = 0; i < 10000; i++) { dontCompile(); // Should not compile this method diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java index b37c911a999..2fbc49af1a0 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java index cfe421d294d..d95e456a884 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java index d5bbf455a08..158496d16f6 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java index 1769d1d8da4..b17c0d59d5f 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java index de620c69189..2d0b5e950a8 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 From a78e2323e47224cb590feb03043ff817b31b3fb2 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 17 Feb 2021 14:06:20 +0100 Subject: [PATCH 022/131] Finish bad tests (check, run, IR), clean up some unused code --- .../valhalla/framework/ArgumentValue.java | 20 +- .../compiler/valhalla/framework/Check.java | 2 +- .../src/compiler/valhalla/framework/Foo.java | 28 --- .../valhalla/framework/IRMatcher.java | 3 +- .../src/compiler/valhalla/framework/Run.java | 2 +- .../valhalla/framework/TestFramework.java | 40 ++-- .../compiler/valhalla/framework/TestInfo.java | 2 +- .../compiler/valhalla/framework/VMFlag.java | 30 --- .../valhalla/framework/VMFlagValhalla.java | 34 --- .../framework/tests/TestBadFormat.java | 196 +++++++++++++++++- .../valhalla/framework/tests/TestBasics.java | 26 ++- 11 files changed, 249 insertions(+), 134 deletions(-) delete mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java delete mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java delete mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java index ca914bca153..5703937ec8d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java @@ -109,6 +109,16 @@ public static ArgumentValue[] getArguments(Method m) { "Provided invalid MAX argument for non-number " + parameterObj + " for " + m); arguments[i] = createMax(parameter); } + case FALSE -> { + TestFormat.check(ArgumentValue.isBoolean(parameter), + "Provided invalid FALSE argument for non-boolean " + parameterObj + " for " + m); + arguments[i] = create(false); + } + case TRUE -> { + TestFormat.check(ArgumentValue.isBoolean(parameter), + "Provided invalid TRUE argument for non-boolean " + parameterObj + " for " + m); + arguments[i] = create(true); + } case BOOLEAN_TOGGLE_FIRST_FALSE -> { TestFormat.check(isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + parameterObj + " for " + m); @@ -119,16 +129,6 @@ public static ArgumentValue[] getArguments(Method m) { "Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + parameterObj + " for " + m); arguments[i] = createToggleBoolean(true); } - case TRUE -> { - TestFormat.check(ArgumentValue.isBoolean(parameter), - "Provided invalid TRUE argument for non-boolean " + parameterObj + " for " + m); - arguments[i] = create(true); - } - case FALSE -> { - TestFormat.check(ArgumentValue.isBoolean(parameter), - "Provided invalid FALSE argument for non-boolean " + parameterObj + " for " + m); - arguments[i] = create(false); - } case RANDOM_ONCE -> { TestFormat.check(isPrimitiveType(parameter), "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameterObj + " for " + m); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java index fe13e50dacd..bde58a4ae38 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java @@ -28,6 +28,6 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Check { - String test() default ""; + String test(); CheckAt when() default CheckAt.EACH_INVOCATION; } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java deleted file mode 100644 index 54b896ad5e4..00000000000 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Foo.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2021, 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.valhalla.framework; - -public @interface Foo { - -} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java index 77b58004264..fb81d21310a 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java @@ -112,12 +112,13 @@ public void applyRules() { 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. Integer[] ids = irRulesMap.get(m.getName()); TestFramework.check(ids != null, "Should find method name in validIrRulesMap for " + m); TestFramework.check(ids.length > 0, "Did not find any rule indices for " + m); TestFramework.check(ids[ids.length - 1] < irAnnos.length, "Invalid IR rule index found in validIrRulesMap for " + m); if (ids[0] != IREncodingPrinter.NO_RULE_APPLIED) { - // If -1, than there was no matching IR rule for given conditions. + // If -1, than there was no matching IR rule for the given conditions. applyRuleToMethod(m, irAnnos, ids); } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java index 501a56b8670..d88479114f4 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java @@ -28,6 +28,6 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Run { - String test() default ""; + String test(); RunMode mode() default RunMode.NORMAL; } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index e3c707c7645..45470634343 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -667,7 +667,7 @@ private void setupTests() { private void addTest(Method m) { Test testAnno = getAnnotation(m, Test.class); checkTestAnnotations(m, testAnno); - + checkIRAnnotations(m); Warmup warmup = getAnnotation(m, Warmup.class); int warmupIterations = WARMUP_ITERATIONS; if (warmup != null) { @@ -704,8 +704,29 @@ private void checkTestAnnotations(Method m, Test testAnno) { TestFormat.check(checkAnno == null && runAnno == null, m + " has invalid @Check or @Run annotation while @Test annotation is present."); - TestFormat.check(!Arrays.asList(m.getParameterTypes()).contains(TestInfo.class), - "Forbidden use of " + TestInfo.class + " as parameter at @Test method " + m); + TestFormat.checkNoThrow(!Arrays.asList(m.getParameterTypes()).contains(TestInfo.class), + "Cannot use of " + TestInfo.class + " as parameter type at @Test method " + m); + + TestFormat.checkNoThrow(!m.getReturnType().equals(TestInfo.class), + "Cannot use of " + TestInfo.class + " as return type at @Test method " + m); + } + + + private void checkIRAnnotations(Method m) { + IR[] irAnnos = m.getAnnotationsByType(IR.class); + if (irAnnos.length == 0) { + return; + } + int i = 1; + for (IR ir : irAnnos) { + TestFormat.checkNoThrow(ir.counts().length != 0 || ir.failOn().length != 0, + "Must specify either counts or failOn constraint for @IR rule " + i + " at " + m); + System.out.println(Stream.of(ir.applyIf(), ir.applyIfNot(), ir.applyIfAnd(), ir.applyIfOr()).filter(a -> a.length != 0).count()); + TestFormat.checkNoThrow(Stream.of(ir.applyIf(), ir.applyIfNot(), ir.applyIfAnd(), ir.applyIfOr()).filter(a -> a.length != 0).count() <= 1, + "Can only specify one apply constraint (applyIf, applyIfNot, applyIfAnd, applyIfOr) " + + "for @Ir rule " + i + " at " + m); + i++; + } } @@ -783,16 +804,11 @@ private void addCheckedTest(Method m, Check checkAnno, Run runAnno) { default -> TestFormat.fail("@Check method " + m + " must provide either a none, single or two-parameter variant."); } - if (allTests.containsKey(testMethod)) { - TestFormat.fail("Method " + m + " and " + allTests.get(testMethod).getTestName() - + " cannot both reference test method " + testMethod); - } - - DeclaredTest test = declaredTests.remove(testMethod); - TestFormat.check(test != null, "Missing @Test annotation for associated test method " + checkAnno.test() + " for @Check at " + m); + DeclaredTest test = declaredTests.get(testMethod); + TestFormat.check(test != null, "Missing @Test annotation for associated test method " + testMethod + " for @Check at " + m); Method attachedMethod = test.getAttachedMethod(); TestFormat.check(attachedMethod == null, - "Cannot use @Test " + testMethod + " for more than one @Run/@Check method. Found: " + m + ", " + attachedMethod); + "Cannot use @Test " + testMethod + " for more than one @Run or one @Check method. Found: " + m + ", " + attachedMethod); dontCompileMethod(m); // Don't inline check methods WHITE_BOX.testSetDontInlineMethod(m, true); @@ -812,7 +828,7 @@ private void addCustomRunTest(Method m, Run runAnno) { } private void checkCustomRunTest(Method m, Run runAnno, Method testMethod, DeclaredTest test) { - TestFormat.check(testMethod != null, "Did not find associated test method \"" + m.getDeclaringClass().getName() + TestFormat.check(testMethod != null, "Did not find associated @Test method \"" + m.getDeclaringClass().getName() + "." + runAnno.test() + "\" specified in @Run at " + m); TestFormat.check(test != null, "Missing @Test annotation for associated test method " + runAnno.test() + " for @Run at " + m); Method attachedMethod = test.getAttachedMethod(); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java index c9f1bbfa900..0ad8388bd3d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java @@ -40,7 +40,7 @@ public class TestInfo { private boolean onWarmUp = true; private final Method testMethod; - public TestInfo(Method testMethod) { + TestInfo(Method testMethod) { this.testMethod = testMethod; } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java deleted file mode 100644 index 9a8d34ab124..00000000000 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlag.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2021, 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.valhalla.framework; - -public class VMFlag { - public static final String G1GC = "UseG1GC"; - public static final String ZGC = "UseZGC"; - public static final String AVX = "UseAVX"; -} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java deleted file mode 100644 index 986c2255b89..00000000000 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/VMFlagValhalla.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2021, 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.valhalla.framework; - -public class VMFlagValhalla { - public static final String InlineTypePassFieldsAsArgsOn = "InlineTypePassFieldsAsArgsOn"; - public static final String InlineTypePassFieldsAsArgsOff = "InlineTypePassFieldsAsArgsOff"; - public static final String InlineTypeArrayFlattenOn = "InlineTypeArrayFlattenOn"; - public static final String InlineTypeArrayFlattenOff = "InlineTypeArrayFlattenOff"; - public static final String InlineTypeReturnedAsFieldsOn = "InlineTypeReturnedAsFieldsOn"; - public static final String InlineTypeReturnedAsFieldsOff = "InlineTypeReturnedAsFieldsOff"; - -} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java index 31581cf9bf5..cb2d78fb45d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java @@ -31,6 +31,8 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class TestBadFormat { @@ -38,11 +40,14 @@ public class TestBadFormat { public static void main(String[] args) throws NoSuchMethodException { runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); - expectTestFormatException(BadArguments.class); - expectTestFormatException(BadOverloadedMethod.class); - expectTestFormatException(BadCompilerControl.class); - expectTestFormatException(BadWarmup.class); - expectTestFormatException(BadRunTests.class); +// expectTestFormatException(BadArgumentsAnnotation.class); +// expectTestFormatException(BadOverloadedMethod.class); +// expectTestFormatException(BadCompilerControl.class); +// expectTestFormatException(BadWarmup.class); +// expectTestFormatException(BadBaseTests.class); +// expectTestFormatException(BadRunTests.class); +// expectTestFormatException(BadCheckTest.class); + expectTestFormatException(BadIRAnnotations.class); } private static void expectTestFormatException(Class clazz) { @@ -60,8 +65,12 @@ private static void expectTestFormatException(Class clazz) { String msg = cause.getMessage(); Violations violations = getViolations(clazz); - Asserts.assertTrue(violations.getFailedMethods().stream().allMatch(msg::contains)); - Asserts.assertTrue(msg.contains("Violations (" + violations.getViolationCount() + ")")); + violations.getFailedMethods().forEach(f -> Asserts.assertTrue(msg.contains(f), "Could not find " + f + " in violations")); + Pattern pattern = Pattern.compile("Violations \\((\\d+)\\)"); + Matcher matcher = pattern.matcher(msg); + Asserts.assertTrue(matcher.find(), "Could not find violations"); + int violationCount = Integer.parseInt(matcher.group(1)); + Asserts.assertEQ(violationCount, violations.getViolationCount()); return; } throw new RuntimeException("Should catch an exception"); @@ -88,7 +97,7 @@ private static Violations getViolations(Class clazz) { } -class BadArguments { +class BadArgumentsAnnotation { @Test public void noArgAnnotation(int a) {} @@ -140,7 +149,7 @@ public void notNumber6(int a, boolean b) {} public void notNumber7(boolean a, boolean b) {} @Test - @Arguments({Argument.DEFAULT}) + @Arguments(Argument.DEFAULT) public void missingDefaultConstructor(ClassNoDefaultConstructor a) {} } @@ -350,7 +359,22 @@ public void someTest3() {} public void noWarmupAtInvokeOnce() {} } +class BadBaseTests { + @Test + @Arguments(Argument.DEFAULT) + @FailCount(3) // No default constructor + parameter + return + public TestInfo cannotUseTestInfoAsParameterOrReturn(TestInfo info) { + return null; + } +} + class BadRunTests { + @Run(test = "runForRun2") + public void runForRun() {} + + @Run(test = "runForRun") + public void runForRun2() {} + @Test public void sharedByTwo() {} @@ -397,6 +421,156 @@ public void shareSameTestTwice1() {} @FailCount(0) // Combined with invalidShare() @Run(test = "invalidShare") public void shareSameTestTwice2() {} + + @Test + public void invalidShareCheckRun() {} + + @FailCount(0) // Combined with invalidShare() + @Run(test = "invalidShareCheckRun") + public void invalidShareCheckRun1() {} + + @FailCount(0) // Combined with invalidShare() + @Check(test = "invalidShareCheckRun") + public void invalidShareCheckRun2() {} + + @NoFail + @Test + public void testInvalidRunWithArgAnnotation() {} + + @Arguments(Argument.DEFAULT) + @Run(test = "testInvalidRunWithArgAnnotation") + public void invalidRunWithArgAnnotation(TestInfo info) {} +} + +class BadCheckTest { + @Check(test = "checkForCheck2") + public void checkForCheck() {} + + @Check(test = "checkForCheck") + public void checkForCheck2() {} + + @Test + public void sharedByTwo() {} + + @FailCount(0) // Combined with sharedByTwo() + @Check(test = "sharedByTwo") + public void share1() {} + + @FailCount(0) // Combined with sharedByTwo() + @Check(test = "sharedByTwo") + public void share2() {} + + @Check(test = "doesNotExist") + public void noTestExists() {} + + @NoFail + @Test + public void test1() {} + + @Check(test = "test1") + public void wrongReturnParameter1(int x) {} + + @NoFail + @Test + public short test2() { + return 3; + } + + @Check(test = "test2") + public void wrongReturnParameter2(int x) {} + + @NoFail + @Test + public short test3() { + return 3; + } + + @Check(test = "test3") + public void wrongReturnParameter3(String x) {} + + @NoFail + @Test + public short test4() { + return 3; + } + + @Check(test = "test4") + public void wrongReturnParameter4(TestInfo info, int x) {} // Must flip parameters + + @NoFail + @Test + public int test5() { + return 3; + } + + @Check(test = "test5") + public void wrongReturnParameter5(short x, TestInfo info) {} + + @Test + public void invalidShare() {} + + @FailCount(0) // Combined with invalidShare() + @Check(test = "invalidShare") + public void shareSameTestTwice1() {} + + @FailCount(0) // Combined with invalidShare() + @Check(test = "invalidShare") + public void shareSameTestTwice2() {} + + @NoFail + @Test + public void testInvalidRunWithArgAnnotation() {} + + @Arguments(Argument.DEFAULT) + @Check(test = "testInvalidRunWithArgAnnotation") + public void invalidRunWithArgAnnotation(TestInfo info) {} +} + +class BadIRAnnotations { + + @IR(failOn = IRNode.CALL) + public void noIRAtNonTest() {} + + @NoFail + @Test + public void test() {} + + @Run(test = "test") + @IR(failOn = IRNode.CALL) + public void noIRAtRun() {} + + @NoFail + @Test + public void test2() {} + + @Check(test = "test2") + @IR(failOn = IRNode.CALL) + public void noIRAtCheck() {} + + @Test + @IR + public void mustSpecifyAtLeastOneConstraint() { + } + + @FailCount(2) + @Test + @IR + @IR + public void mustSpecifyAtLeastOneConstraint2() { + } + + @Test + @IR(applyIf = {"SuspendRetryCount", "50"}) + public void mustSpecifyAtLeastOneConstraint3() { + } + + @FailCount(3) + @Test + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "50"}, applyIfNot = {"SuspendRetryCount", "50"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "50"}, applyIfOr = {"SuspendRetryCount", "50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "50"}, applyIfNot = {"SuspendRetryCount", "50"}, applyIfAnd = {"SuspendRetryCount", "50"}, applyIfOr = {"SuspendRetryCount", "50"}) + public void onlyOneApply() { + } } class ClassNoDefaultConstructor { @@ -404,10 +578,12 @@ private ClassNoDefaultConstructor(int i) { } } +// Test specific annotation: // All methods without such an annotation must occur in the violation messages. @Retention(RetentionPolicy.RUNTIME) @interface NoFail {} +// Test specific annotation: // Specify a fail count for a method without @NoFail. Use the value 0 if multiple methods are part of the same violation. @Retention(RetentionPolicy.RUNTIME) @interface FailCount { @@ -431,5 +607,3 @@ public void addFail(Method m, int count) { violations += count; } } - - diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java index ca69b6a1d07..21d25bd539c 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java @@ -32,7 +32,7 @@ public class TestBasics { private static boolean wasExecuted = false; private boolean lastToggleBoolean = true; - private final static int[] executed = new int[94]; + private final static int[] executed = new int[96]; private final static int[] executedOnce = new int[5]; private long[] nonFloatingRandomNumbers = new long[10]; private double[] floatingRandomNumbers = new double[10]; @@ -839,6 +839,21 @@ public void checkTestCheckReturn(int returnValue) { executed[66]++; // Executed on each invocation } + @Test + @Arguments(Argument.NUMBER_42) + public short testCheckWithArgs(short x) { + executed[94]++; + return x; + } + + @Check(test = "testCheckWithArgs") + public void checkTestCheckWithArgs(short returnValue) { + if (returnValue != 42) { + throw new RuntimeException("Must be 42"); + } + executed[95]++; // Executed on each invocation + } + @Test public int testCheckTestInfo() { executed[67]++; @@ -934,6 +949,11 @@ public void sameName(TestInfo info) { executed[77]++; } + + /* + * Custom run tests. + */ + @Test public void sameName2() { executed[92]++; @@ -946,10 +966,6 @@ public void sameName2(TestInfo info) { sameName2(); } - /* - * Custom run tests. - */ - @Test public void testRun() { executed[61]++; From 247285c1c6e033f34ebe8e08176ce5d80360de9b Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 17 Feb 2021 15:41:39 +0100 Subject: [PATCH 023/131] Fixing @DontCompile to only allow one option, start writing Javadocs --- .../compiler/valhalla/framework/Argument.java | 45 ++++++++++++++++--- .../valhalla/framework/CompLevel.java | 7 +-- .../valhalla/framework/DontCompile.java | 17 ++++++- .../valhalla/framework/DontInline.java | 6 +++ .../valhalla/framework/ForceCompile.java | 18 +++++++- .../valhalla/framework/ForceInline.java | 6 ++- .../valhalla/framework/TestFramework.java | 33 +++++--------- .../framework/tests/TestBadFormat.java | 18 +++----- .../framework/tests/TestControls.java | 13 +----- 9 files changed, 107 insertions(+), 56 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java index 0a0abe0845d..c00ddc1abeb 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java @@ -24,15 +24,48 @@ package compiler.valhalla.framework; public enum Argument { + /** + * Provides the default value for any kind of primitive type and objects type if the class provides a default constructor. + */ DEFAULT, - NUMBER_MINUS_42, + /** + * Provides the number 42 for any primitive number type. + */ NUMBER_42, + /** + * Provides the number -42 for any primitive number type. + */ + NUMBER_MINUS_42, + /** + * Provides the minimum value of the specified primitive number type. + */ + MIN, + /** + * Provides the maximum value of the specified primitive number type. + */ + MAX, + /** + * Provides the boolean value false. + */ + FALSE, + /** + * Provides the boolean value true. + */ + TRUE, + /** + * Provides a different boolean value on each test invocation, starting with false. + */ BOOLEAN_TOGGLE_FIRST_FALSE, + /** + * Provides a different boolean value on each test invocation, starting with true. + */ BOOLEAN_TOGGLE_FIRST_TRUE, - TRUE, - FALSE, + /** + * Provides a random primitive value on the first test invocation and reuses the same value for all invocation of the test. + */ RANDOM_ONCE, - RANDOM_EACH, - MAX, - MIN + /** + * Provides a different random primitive value on each test invocation. + */ + RANDOM_EACH } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java index 7847effa583..85c8c805d16 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java @@ -32,10 +32,11 @@ public enum CompLevel { */ SKIP(-3), /** - * Any compilation level: + * Use any compilation level depending on the usage: *
    - *
  • Defaults to C2 for {@link Test @Test} and {@link ForceCompile @ForceCompile}.
  • - *
  • Excludes all compilations for {@link DontCompile @DontCompile}.
  • + *
  • {@link Test @Test}, {@link ForceCompile @ForceCompile}: Use the highest available compilation level + * which is usually C2.

  • + *
  • {@link DontCompile @DontCompile}: Prevents any compilation of the associated helper method.

  • *
*/ ANY(-2), diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java index a338695adf6..0f76478d2d2 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java @@ -26,8 +26,21 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -// Prevent method compilation +/** + * Prevent compilation of the associated helper method (not specifying {@link Test @Test}, + * {@link Check @Check} or {@link Test @Run}): + * + *
    + *
  • {@link CompLevel#ANY} (default): No C1 or C2 compilation.

  • + *
  • {@link CompLevel#C1}: No C1 compilation, C2 compilation still possible.

  • + *
  • {@link CompLevel#C2}: No C2 compilation, C1 compilation still possible.

  • + *
  • The usage of any other compilation level is forbidden and results in a + * {@link TestFormatException TestFormatException}.

  • + *
+ *

+ * Using this annotation on non-helper methods results in a {@link TestFormatException TestFormatException}. + */ @Retention(RetentionPolicy.RUNTIME) public @interface DontCompile { - CompLevel[] value() default {}; + CompLevel value() default CompLevel.ANY; } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java index 27d3ed0751d..71d7e143c09 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java @@ -27,6 +27,12 @@ import java.lang.annotation.RetentionPolicy; // Prevent method inlining during compilation +/** + * Prevent inlining of the associated helper method (not specifying {@link Test @Test}, + * {@link Check @Check} or {@link Test @Run}). Non-helper methods are never inlined. + * Explicitly using this annotation on non-helper methods results in a + * {@link TestFormatException TestFormatException}. + */ @Retention(RetentionPolicy.RUNTIME) public @interface DontInline { } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java index 5aa26edfc12..f641d89f534 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java @@ -26,7 +26,23 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -// Force method compilation +/** + * Force compilation of the associated helper method (not specifying {@link Test @Test}, + * {@link Check @Check} or {@link Test @Run}) immediately at the specified level: + *

    + *
  • {@link CompLevel#ANY} (default): Highest available compilation level which is usually C2.

  • + *
  • {@link CompLevel#C1}: Level 1: C1 compilation without any profile information.

  • + *
  • {@link CompLevel#C1_LIMITED_PROFILE}: Level 2: C1 compilation with limited profile information: + * Includes Invocation and backedge counters.

  • + *
  • {@link CompLevel#C1_FULL_PROFILE}: Level 3: C1 compilation with full profile information: + * Includes Invocation and backedge counters with MDO.

  • + *
  • {@link CompLevel#C2}: Level 4: C2 compilation with full optimizations.

  • + *
  • {@link CompLevel#SKIP}: Does not apply to {@link ForceCompile @ForceCompile} and results in a + * {@link TestFormatException TestFormatException}.

  • + *
+ *

+ * Using this annotation on non-helper methods results in a {@link TestFormatException TestFormatException}. + */ @Retention(RetentionPolicy.RUNTIME) public @interface ForceCompile { CompLevel value() default CompLevel.C2; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java index 8a23c5658bd..e9251dbd60d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java @@ -26,7 +26,11 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -// Force method inlining during compilation +/** + * Force inlining of the associated helper method (not specifying {@link Test @Test}, + * {@link Check @Check} or {@link Test @Run}). Using this annotation on non-helper methods + * results in a {@link TestFormatException TestFormatException}. + */ @Retention(RetentionPolicy.RUNTIME) public @interface ForceInline { } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 45470634343..ac6b7cb7810 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -563,16 +563,11 @@ private void applyIndependentCompilationCommands(Method m) { WHITE_BOX.testSetForceInlineMethod(m, true); } if (dontCompileAnno != null) { - if (dontCompileAnno.value().length == 0) { - dontCompileMethod(m); - } else { - for (CompLevel compLevel : dontCompileAnno.value()) { - TestFormat.check(compLevel == CompLevel.C1 || compLevel == CompLevel.C2 || compLevel == CompLevel.ANY, - "Can only specify compilation level C1 (no individual C1 levels), " + - "C2 or ANY (no compilation, same as specifying anything) in @DontCompile at " + m); - dontCompileMethodAtLevel(m, compLevel); - } - } + CompLevel compLevel = dontCompileAnno.value(); + TestFormat.check(compLevel == CompLevel.C1 || compLevel == CompLevel.C2 || compLevel == CompLevel.ANY, + "Can only specify compilation level C1 (no individual C1 levels), " + + "C2 or ANY (no compilation, same as specifying anything) in @DontCompile at " + m); + dontCompileMethodAtLevel(m, compLevel); } } @@ -592,12 +587,12 @@ private void checkCompilationCommandAnnotations(Method m, ForceInline forceInlin TestFormat.check(forceInlineAnno == null || dontInlineAnno == null, "Cannot have @ForceInline and @DontInline at the same time at " + m); if (forceCompileAnno != null && dontCompileAnno != null) { CompLevel forceCompile = forceCompileAnno.value(); - CompLevel[] dontCompile = dontCompileAnno.value(); - TestFormat.check(dontCompile.length != 0, - "Cannot have @ForceCompile and default @DontCompile (CompLevel.ANY) at the same time at " + m); + CompLevel dontCompile = dontCompileAnno.value(); + TestFormat.check(dontCompile != CompLevel.ANY, + "Cannot have @DontCompile(CompLevel.ANY) and @ForceCompile at the same time at " + m); TestFormat.check(forceCompile != CompLevel.ANY, "Cannot have @ForceCompile(CompLevel.ANY) and @DontCompile at the same time at " + m); - TestFormat.check(Arrays.stream(dontCompile).noneMatch(a -> CompLevel.overlapping(a, forceCompile)), + TestFormat.check(!CompLevel.overlapping(dontCompile, forceCompile), "Overlapping compilation levels with @ForceCompile and @DontCompile at " + m); } } @@ -721,7 +716,6 @@ private void checkIRAnnotations(Method m) { for (IR ir : irAnnos) { TestFormat.checkNoThrow(ir.counts().length != 0 || ir.failOn().length != 0, "Must specify either counts or failOn constraint for @IR rule " + i + " at " + m); - System.out.println(Stream.of(ir.applyIf(), ir.applyIfNot(), ir.applyIfAnd(), ir.applyIfOr()).filter(a -> a.length != 0).count()); TestFormat.checkNoThrow(Stream.of(ir.applyIf(), ir.applyIfNot(), ir.applyIfAnd(), ir.applyIfOr()).filter(a -> a.length != 0).count() <= 1, "Can only specify one apply constraint (applyIf, applyIfNot, applyIfAnd, applyIfOr) " + "for @Ir rule " + i + " at " + m); @@ -736,8 +730,8 @@ private static CompLevel restrictCompLevel(CompLevel compLevel) { return CompLevel.SKIP; } if (compLevel == CompLevel.ANY) { - // Use C2 by default. - compLevel = CompLevel.C2; + // Use highest available compilation level by default (usually C2). + compLevel = TIERED_COMPILATION_STOP_AT_LEVEL; } if (!TIERED_COMPILATION && compLevel.getValue() < CompLevel.C2.getValue()) { return CompLevel.SKIP; @@ -911,10 +905,7 @@ private static TriState compiledByC1(Method m) { return triState; } triState = compiledAtLevel(m, CompLevel.C1_FULL_PROFILE); - if (triState != TriState.No) { - return triState; - } - return TriState.No; + return triState; } private static TriState compiledByC2(Method m) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java index cb2d78fb45d..3d0782b521e 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java @@ -40,13 +40,13 @@ public class TestBadFormat { public static void main(String[] args) throws NoSuchMethodException { runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); -// expectTestFormatException(BadArgumentsAnnotation.class); -// expectTestFormatException(BadOverloadedMethod.class); -// expectTestFormatException(BadCompilerControl.class); -// expectTestFormatException(BadWarmup.class); -// expectTestFormatException(BadBaseTests.class); -// expectTestFormatException(BadRunTests.class); -// expectTestFormatException(BadCheckTest.class); + expectTestFormatException(BadArgumentsAnnotation.class); + expectTestFormatException(BadOverloadedMethod.class); + expectTestFormatException(BadCompilerControl.class); + expectTestFormatException(BadWarmup.class); + expectTestFormatException(BadBaseTests.class); + expectTestFormatException(BadRunTests.class); + expectTestFormatException(BadCheckTest.class); expectTestFormatException(BadIRAnnotations.class); } @@ -63,7 +63,6 @@ private static void expectTestFormatException(Class clazz) { Asserts.fail("Unexpected exception: " + cause); } String msg = cause.getMessage(); - Violations violations = getViolations(clazz); violations.getFailedMethods().forEach(f -> Asserts.assertTrue(msg.contains(f), "Could not find " + f + " in violations")); Pattern pattern = Pattern.compile("Violations \\((\\d+)\\)"); @@ -293,9 +292,6 @@ public void invalidSkip1() {} @DontCompile(CompLevel.SKIP) public void invalidSkip2() {} - @DontCompile({CompLevel.C1, CompLevel.SKIP}) - public void invalidSkip3() {} - @ForceCompile(CompLevel.C1) @DontCompile(CompLevel.C1) public void overlappingCompile1() {} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java index da42df9ffb7..ca670987b0c 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java @@ -90,7 +90,7 @@ public void test2() { } @Check(test = "test2", when = CheckAt.COMPILED) - public void check2(TestInfo info) throws NoSuchMethodException{ + public void check2(TestInfo info) { Asserts.assertTrue(!info.isWarmUp() && executed[1] == 101); TestFramework.assertCompiledByC2(info.getTest()); } @@ -141,7 +141,7 @@ public void testCompileAtLevel1() { executed[6]++; } - @DontCompile({CompLevel.C1, CompLevel.C2}) + @DontCompile(CompLevel.ANY) public static void dontCompile2() { executed[7]++; } @@ -206,13 +206,6 @@ public void dontCompileC2(int x, boolean b) { } } - @DontCompile({CompLevel.C1, CompLevel.C2}) - public void dontCompileC1C2(int x) { - for (int i = 0; i < 10; i++) { - iFld = x; - } - } - // Default is C2. @ForceCompile public void forceCompileDefault() { @@ -264,12 +257,10 @@ public void runTestCompilation(TestInfo info) { dontCompileAny(); dontCompileC1(); dontCompileC2(i, i % 2 == 0); - dontCompileC1C2(i); } TestFramework.assertCompiledByC2(info.getTest()); TestFramework.assertNotCompiled(info.getTestClassMethod("dontCompileAny")); TestFramework.assertCompiledByC2(info.getTestClassMethod("dontCompileC1")); - TestFramework.assertNotCompiled(info.getTestClassMethod("dontCompileC1C2", int.class)); TestFramework.assertCompiledByC1(info.getTestClassMethod("dontCompileC2", int.class, boolean.class)); TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileDefault"), CompLevel.C2); From 3815a1c941190fd5a457a3bad10a2b9af219f903 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 18 Feb 2021 16:53:28 +0100 Subject: [PATCH 024/131] Add more bad IR tests and doing some related small fixes and clean-ups --- .../valhalla/framework/IREncodingPrinter.java | 247 +++++++++++------- .../valhalla/framework/ParsedComparator.java | 101 +++++++ .../valhalla/framework/TestFormat.java | 4 + .../valhalla/framework/TestFramework.java | 84 +----- .../framework/tests/TestBadFormat.java | 211 ++++++++++++++- 5 files changed, 470 insertions(+), 177 deletions(-) create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ParsedComparator.java diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java index 4bab160a217..eeaa4529e2d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java @@ -34,15 +34,18 @@ // Only used by TestVM class IREncodingPrinter { + public static final String START = "##### IRMatchRulesEncoding - used by TestFramework #####"; + public static final String END = "----- END -----"; + public static final int NO_RULE_APPLIED = -1; private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); private static final List> longGetters = Arrays.asList( WHITE_BOX::getIntVMFlag, WHITE_BOX::getUintVMFlag, WHITE_BOX::getIntxVMFlag, WHITE_BOX::getUintxVMFlag, WHITE_BOX::getUint64VMFlag, WHITE_BOX::getSizeTVMFlag); - public static final String START = "##### IRMatchRulesEncoding - used by TestFramework #####"; - public static final String END = "----- END -----"; - public static final int NO_RULE_APPLIED = -1; private final StringBuilder output = new StringBuilder(); + private Method method; + private int ruleIndex; + public IREncodingPrinter() { output.append(START).append("\n"); output.append(",{comma separated applied @IR rule ids}\n"); @@ -54,12 +57,18 @@ public IREncodingPrinter() { * - "-1" if no @IR rule should not be applied */ public void emitRuleEncoding(Method m) { + method = m; int i = 0; ArrayList validRules = new ArrayList<>(); IR[] irAnnos = m.getAnnotationsByType(IR.class); for (IR irAnno : irAnnos) { - if (shouldApplyIrRule(m, irAnno)) { - validRules.add(i); + ruleIndex = i + 1; + try { + if (shouldApplyIrRule(irAnno)) { + validRules.add(i); + } + } catch (TestFormatException e) { + // Catch logged failure and continue to check other IR annotations. } i++; } @@ -76,141 +85,195 @@ public void emitRuleEncoding(Method m) { } } - public void dump() { - output.append(END); - System.out.println(output.toString()); - } - - private boolean shouldApplyIrRule(Method m, IR irAnnotation) { - checkAnnotation(m, irAnnotation); - if (irAnnotation.applyIf().length != 0) { - return hasAllRequiredFlags(m, irAnnotation.applyIf(), "applyIf"); + private boolean shouldApplyIrRule(IR irAnno) { + checkIRAnnotations(irAnno); + if (irAnno.applyIf().length != 0) { + return hasAllRequiredFlags(irAnno.applyIf(), "applyIf"); } - if (irAnnotation.applyIfNot().length != 0) { - return hasNoRequiredFlags(m, irAnnotation.applyIfNot(), "applyIfNot"); + if (irAnno.applyIfNot().length != 0) { + return hasNoRequiredFlags(irAnno.applyIfNot(), "applyIfNot"); } - if (irAnnotation.applyIfAnd().length != 0) { - return hasAllRequiredFlags(m, irAnnotation.applyIfAnd(), "applyIfAnd"); + if (irAnno.applyIfAnd().length != 0) { + return hasAllRequiredFlags(irAnno.applyIfAnd(), "applyIfAnd"); } - if (irAnnotation.applyIfOr().length != 0) { - return !hasNoRequiredFlags(m, irAnnotation.applyIfOr(), "applyIfOr"); + if (irAnno.applyIfOr().length != 0) { + return !hasNoRequiredFlags(irAnno.applyIfOr(), "applyIfOr"); } // No conditions, always apply. return true; } - private static void checkAnnotation(Method m, IR irAnnotation) { + private void checkIRAnnotations(IR irAnno) { + TestFormat.checkNoThrow(irAnno.counts().length != 0 || irAnno.failOn().length != 0, + "Must specify either counts or failOn constraint" + failAt()); int applyRules = 0; - if (irAnnotation.applyIfAnd().length != 0) { + if (irAnno.applyIfAnd().length != 0) { applyRules++; - TestFormat.check(irAnnotation.applyIfAnd().length > 2, - "Use [applyIf|applyIfNot] or at least 2 conditions for applyIfAnd in @IR at " + m); + TestFormat.checkNoThrow(irAnno.applyIfAnd().length > 2, + "Use applyIf or applyIfNot or at least 2 conditions for applyIfAnd" + failAt()); } - if (irAnnotation.applyIfOr().length != 0) { + if (irAnno.applyIfOr().length != 0) { applyRules++; - TestFormat.check(irAnnotation.applyIfOr().length > 2, - "Use [applyIf|applyIfNot] or at least 2 conditions for applyIfOr in @IR at " + m); + TestFormat.checkNoThrow(irAnno.applyIfOr().length > 2, + "Use applyIf or applyIfNot or at least 2 conditions for applyIfOr" + failAt()); } - if (irAnnotation.applyIf().length != 0) { + if (irAnno.applyIf().length != 0) { applyRules++; - TestFormat.check(irAnnotation.applyIf().length <= 2, - "Use [applyIfAnd|applyIfOr] or only 1 condition for applyIf in @IR at " + m); + TestFormat.checkNoThrow(irAnno.applyIf().length <= 2, + "Use applyIfAnd or applyIfOr or only 1 condition for applyIf" + failAt()); } - if (irAnnotation.applyIfNot().length != 0) { + if (irAnno.applyIfNot().length != 0) { applyRules++; - TestFormat.check(irAnnotation.applyIfNot().length <= 2, - "Use [applyIfAnd|applyIfOr] or only 1 condition for applyIfNot in @IR at " + m); + TestFormat.checkNoThrow(irAnno.applyIfNot().length <= 2, + "Use applyIfAnd or applyIfOr or only 1 condition for applyIfNot" + failAt()); } - TestFormat.check(applyRules <= 1, "Can only use one of [applyIf|applyIfNot|applyIfAnd|applyIfOr] in @IR at " + m); + TestFormat.checkNoThrow(applyRules <= 1, + "Can only specify one apply constraint " + failAt()); + } - private boolean hasAllRequiredFlags(Method m, String[] andRules, String ruleType) { + private boolean hasAllRequiredFlags(String[] andRules, String ruleType) { + boolean returnValue = true; for (int i = 0; i < andRules.length; i++) { - String flag = andRules[i]; + String flag = andRules[i].trim(); i++; - TestFormat.check(i < andRules.length, "Missing value for flag " + flag + " in " + ruleType + " for @IR at " + m); - String value = andRules[i]; - if (!check(m, flag, value)) { - return false; + TestFormat.check(i < andRules.length, "Missing value for flag " + flag + " in " + ruleType + failAt()); + String value = andRules[i].trim(); + if (!check(flag, value) && returnValue) { + // Rule will not be applied but keep processing the other flags to verify that they are sane. + returnValue = false; } } - return true; + return returnValue; } - private boolean hasNoRequiredFlags(Method m, String[] orRules, String ruleType) { + private boolean hasNoRequiredFlags(String[] orRules, String ruleType) { + boolean returnValue = true; for (int i = 0; i < orRules.length; i++) { String flag = orRules[i]; i++; - TestFormat.check(i < orRules.length, "Missing value for flag " + flag + " in " + ruleType + " for @IR at " + m); + TestFormat.check(i < orRules.length, "Missing value for flag " + flag + " in " + ruleType + failAt()); String value = orRules[i]; - if (check(m, flag, value)) { - return false; + if (check(flag, value) && returnValue) { + // Rule will not be applied but keep processing the other flags to verify that they are sane. + returnValue = false; } } - return true; + return returnValue; } - private boolean check(Method m, String flag, String value) { - TestFormat.check(!value.isEmpty(), "Provided empty value for flag " + flag + " at " + m); - Object actualFlagValue = longGetters.stream() - .map(f -> f.apply(flag)) - .filter(Objects::nonNull) - .findAny().orElse(null); + private boolean check(String flag, String value) { + if (flag.isEmpty()) { + TestFormat.failNoThrow("Provided empty flag" + failAt()); + return false; + } + if (value.isEmpty()) { + TestFormat.failNoThrow("Provided empty value for flag " + flag + failAt()); + return false; + } + Object actualFlagValue = WHITE_BOX.getBooleanVMFlag(flag); if (actualFlagValue != null) { - long actualLongFlagValue = (Long) actualFlagValue; - long longValue; - ParsedComparator parsedComparator ; - try { - parsedComparator = ParsedComparator.parseComparator(value); - longValue = Long.parseLong(parsedComparator.getStrippedString()); - } catch (NumberFormatException e) { - TestFormat.fail("Invalid value " + value + " for number based flag " + flag); - return false; - } catch (Exception e) { - TestFormat.fail("Invalid comparator in \"" + value + "\" for number based flag " + flag + ": " + e.getCause()); - return false; - } - return parsedComparator.getPredicate().test(actualLongFlagValue, longValue); + return checkBooleanFlag(flag, value, (Boolean) actualFlagValue); } - actualFlagValue = WHITE_BOX.getBooleanVMFlag(flag); + actualFlagValue = longGetters.stream().map(f -> f.apply(flag)).filter(Objects::nonNull).findAny().orElse(null); if (actualFlagValue != null) { - boolean actualBooleanFlagValue = (Boolean) actualFlagValue; - boolean booleanValue = false; - try { - booleanValue = Boolean.parseBoolean(value); - } catch (Exception e) { - TestFormat.fail("Invalid value " + value + " for boolean flag " + flag); - } - return booleanValue == actualBooleanFlagValue; + return checkLongFlag(flag, value, (Long) actualFlagValue); } actualFlagValue = WHITE_BOX.getDoubleVMFlag(flag); if (actualFlagValue != null) { - double actualDoubleFlagValue = (Double) actualFlagValue; - double doubleValue; - ParsedComparator parsedComparator; - try { - parsedComparator = ParsedComparator.parseComparator(value); - doubleValue = Double.parseDouble(parsedComparator.getStrippedString()); - } catch (NumberFormatException e) { - TestFormat.fail("Invalid value " + value + " for number based flag " + flag); - return false; - } catch (Exception e) { - TestFormat.fail("Invalid comparator in \"" + value + "\" for number based flag " + flag + ": " + e.getCause()); - return false; - } - return parsedComparator.getPredicate().test(actualDoubleFlagValue, doubleValue); + return checkDoubleFlag(flag, value, (Double) actualFlagValue); } actualFlagValue = WHITE_BOX.getStringVMFlag(flag); if (actualFlagValue != null) { - String actualStringFlagValue = (String) actualFlagValue; - return actualStringFlagValue.equals(value); + return value.equals(actualFlagValue); + } + + // This could be improved if the Whitebox offers a "isVMFlag" function. For now, just check if we can actually set + // a value for a string flag. If we find this value, it's a string flag. If null is returned, the flag is unknown. + WHITE_BOX.setStringVMFlag(flag, "test"); + String stringFlagValue = WHITE_BOX.getStringVMFlag(flag); + if (stringFlagValue == null) { + TestFormat.failNoThrow("Could not find VM flag \"" + flag + "\"" + failAt()); + return false; } - TestFormat.fail("Could not find flag " + flag); + TestFramework.check(stringFlagValue.equals("test"), + "Must find newly set flag value \"test\" but found " + failAt()); + WHITE_BOX.setStringVMFlag(flag, null); // reset flag to NULL return false; } + + private boolean checkBooleanFlag(String flag, String value, Boolean actualFlagValue) { + boolean actualBooleanFlagValue = actualFlagValue; + boolean booleanValue = false; + if ("true".equalsIgnoreCase(value)) { + booleanValue = true; + } else if (!"false".equalsIgnoreCase(value)) { + TestFormat.failNoThrow("Invalid value \"" + value + "\" for boolean flag " + flag + failAt()); + return false; + } + return booleanValue == actualBooleanFlagValue; + } + + + private boolean checkLongFlag(String flag, String value, Long actualFlagValue) { + long actualLongFlagValue = actualFlagValue; + long longValue; + ParsedComparator parsedComparator; + try { + parsedComparator = ParsedComparator.parseComparator(value); + } catch (CheckedTestFrameworkException e) { + TestFormat.failNoThrow("Invalid comparator in \"" + value + "\" for integer based flag " + flag + failAt()); + return false; + } + try { + longValue = Long.parseLong(parsedComparator.getStrippedString()); + } catch (NumberFormatException e) { + String comparator = parsedComparator.getComparator(); + if (!comparator.isEmpty()) { + comparator = "after comparator \"" + parsedComparator.getComparator() + "\""; + } + TestFormat.failNoThrow("Invalid value \"" + parsedComparator.getStrippedString() + "\" " + + comparator + " for integer based flag " + flag + failAt()); + return false; + } + return parsedComparator.getPredicate().test(actualLongFlagValue, longValue); + } + + private boolean checkDoubleFlag(String flag, String value, Double actualFlagValue) { + double actualDoubleFlagValue = actualFlagValue; + double doubleValue; + ParsedComparator parsedComparator; + try { + parsedComparator = ParsedComparator.parseComparator(value); + } catch (CheckedTestFrameworkException e) { + TestFormat.failNoThrow("Invalid comparator in \"" + value + "\" for floating point based flag " + flag + failAt()); + return false; + } + try { + doubleValue = Double.parseDouble(parsedComparator.getStrippedString()); + } catch (NumberFormatException e) { + String comparator = parsedComparator.getComparator(); + if (!comparator.isEmpty()) { + comparator = "after comparator \"" + parsedComparator.getComparator() + "\""; + } + TestFormat.failNoThrow("Invalid value \"" + parsedComparator.getStrippedString() + "\" " + + comparator + " for floating point based flag " + flag + failAt()); + return false; + } + return parsedComparator.getPredicate().test(actualDoubleFlagValue, doubleValue); + } + + private String failAt() { + return " for @IR rule " + ruleIndex + " at " + method; + } + + public void emit() { + output.append(END); + System.out.println(output.toString()); + } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ParsedComparator.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ParsedComparator.java new file mode 100644 index 00000000000..cffbe57bff0 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ParsedComparator.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2021, 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.valhalla.framework; + +import java.util.function.BiPredicate; + +class ParsedComparator> { + private final String strippedString; + private final BiPredicate predicate; + private String comparator; + + public ParsedComparator(String strippedString, BiPredicate predicate, String comparator) { + this.strippedString = strippedString; + this.predicate = predicate; + this.comparator = comparator; + } + + public String getStrippedString() { + return strippedString; + } + + public BiPredicate getPredicate() { + return predicate; + } + + public String getComparator() { + return comparator; + } + + public static > ParsedComparator parseComparator(String value) throws CheckedTestFrameworkException { + BiPredicate comparison; + value = value.trim(); + String comparator = ""; + try { + switch (value.charAt(0)) { + case '<': + if (value.charAt(1) == '=') { + comparator = "<="; + comparison = (x, y) -> x.compareTo(y) <= 0; + value = value.substring(2).trim(); + } else { + comparator = "<"; + comparison = (x, y) -> x.compareTo(y) < 0; + value = value.substring(1).trim(); + } + break; + case '>': + if (value.charAt(1) == '=') { + comparator = ">="; + comparison = (x, y) -> x.compareTo(y) >= 0; + value = value.substring(2).trim(); + } else { + comparator = ">"; + comparison = (x, y) -> x.compareTo(y) > 0; + value = value.substring(1).trim(); + } + break; + case '!': + if (value.charAt(1) != '=') { + throw new CheckedTestFrameworkException(); + } + comparator = "!="; + comparison = (x, y) -> x.compareTo(y) != 0; + value = value.substring(2).trim(); + break; + case '=': // Allowed syntax, equivalent to not using any symbol. + comparator = "="; + value = value.substring(1).trim(); + // Fall through + default: + comparison = (x, y) -> x.compareTo(y) == 0; + value = value.trim(); + break; + } + } catch (IndexOutOfBoundsException e) { + throw new CheckedTestFrameworkException(); + } + return new ParsedComparator<>(value, comparison, comparator); + } +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java index 79e0f2e2200..29f01db5f9c 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java @@ -47,6 +47,10 @@ public static void fail(String failureMessage) { throw new TestFormatException(failureMessage); } + public static void failNoThrow(String failureMessage) { + FAILURES.add(failureMessage); + } + public static void reportIfAnyFailures() { if (FAILURES.isEmpty()) { // No format violation detected. diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index ac6b7cb7810..50c574904ba 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -28,7 +28,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; -import java.util.function.BiPredicate; import java.util.stream.Stream; import jdk.test.lib.Asserts; @@ -655,14 +654,13 @@ private void setupTests() { } } if (PRINT_VALID_IR_RULES) { - irMatchRulePrinter.dump(); + irMatchRulePrinter.emit(); } } private void addTest(Method m) { Test testAnno = getAnnotation(m, Test.class); checkTestAnnotations(m, testAnno); - checkIRAnnotations(m); Warmup warmup = getAnnotation(m, Warmup.class); int warmupIterations = WARMUP_ITERATIONS; if (warmup != null) { @@ -707,23 +705,6 @@ private void checkTestAnnotations(Method m, Test testAnno) { } - private void checkIRAnnotations(Method m) { - IR[] irAnnos = m.getAnnotationsByType(IR.class); - if (irAnnos.length == 0) { - return; - } - int i = 1; - for (IR ir : irAnnos) { - TestFormat.checkNoThrow(ir.counts().length != 0 || ir.failOn().length != 0, - "Must specify either counts or failOn constraint for @IR rule " + i + " at " + m); - TestFormat.checkNoThrow(Stream.of(ir.applyIf(), ir.applyIfNot(), ir.applyIfAnd(), ir.applyIfOr()).filter(a -> a.length != 0).count() <= 1, - "Can only specify one apply constraint (applyIf, applyIfNot, applyIfAnd, applyIfOr) " + - "for @Ir rule " + i + " at " + m); - i++; - } - } - - // Get the appropriate level as permitted by the test scenario and VM options. private static CompLevel restrictCompLevel(CompLevel compLevel) { if (!USE_COMPILER) { @@ -935,6 +916,10 @@ public TestFrameworkException(String message, Exception e) { } } +// Checked exceptions in the framework to propagate error handling. +class CheckedTestFrameworkException extends Exception { +} + class DeclaredTest { private final Method testMethod; private final ArgumentValue[] arguments; @@ -1293,62 +1278,3 @@ protected void checkCompilationLevel() { } -class ParsedComparator> { - private final String strippedString; - private final BiPredicate predicate; - - public ParsedComparator(String strippedString, BiPredicate predicate) { - this.strippedString = strippedString; - this.predicate = predicate; - } - - public String getStrippedString() { - return strippedString; - } - - public BiPredicate getPredicate() { - return predicate; - } - - - public static > ParsedComparator parseComparator(String value) { - BiPredicate comparison = null; - value = value.trim(); - try { - switch (value.charAt(0)) { - case '<': - if (value.charAt(1) == '=') { - comparison = (x, y) -> x.compareTo(y) <= 0; - value = value.substring(2).trim(); - } else { - comparison = (x, y) -> x.compareTo(y) < 0; - value = value.substring(1).trim(); - } - break; - case '>': - if (value.charAt(1) == '=') { - comparison = (x, y) -> x.compareTo(y) >= 0; - value = value.substring(2).trim(); - } else { - comparison = (x, y) -> x.compareTo(y) > 0; - value = value.substring(1).trim(); - } - break; - case '!': - TestFormat.check(value.charAt(1) == '=', "Invalid comparator sign used."); - comparison = (x, y) -> x.compareTo(y) != 0; - value = value.substring(2).trim(); - break; - case '=': // Allowed syntax, equivalent to not using any symbol. - value = value.substring(1).trim(); - default: - comparison = (x, y) -> x.compareTo(y) == 0; - value = value.trim(); - break; - } - } catch (IndexOutOfBoundsException e) { - TestFormat.fail("Invalid value format."); - } - return new ParsedComparator<>(value, comparison); - } -} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java index 3d0782b521e..af34372b619 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java @@ -523,7 +523,6 @@ public void invalidRunWithArgAnnotation(TestInfo info) {} } class BadIRAnnotations { - @IR(failOn = IRNode.CALL) public void noIRAtNonTest() {} @@ -562,11 +561,211 @@ public void mustSpecifyAtLeastOneConstraint3() { @FailCount(3) @Test - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "50"}, applyIfNot = {"SuspendRetryCount", "50"}) - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "50"}, applyIfOr = {"SuspendRetryCount", "50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "50"}, applyIfNot = {"SuspendRetryCount", "50"}, applyIfAnd = {"SuspendRetryCount", "50"}, applyIfOr = {"SuspendRetryCount", "50"}) - public void onlyOneApply() { - } + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "50"}, applyIfNot = {"UseTLAB", "true"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "50", "UseTLAB", "true"}, + applyIfOr = {"SuspendRetryCount", "50", "UseTLAB", "true"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "50"}, applyIfNot = {"SuspendRetryCount", "50"}, + applyIfAnd = {"SuspendRetryCount", "50", "UseTLAB", "true"}, + applyIfOr = {"SuspendRetryCount", "50", "UseTLAB", "true"}) + public void onlyOneApply() {} + + @FailCount(3) + @Test + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "50", "UseTLAB", "true"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "51", "UseTLAB"}) + public void applyIfTooManyFlags() {} + + @FailCount(2) + @Test + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount"}) + @IR(failOn = IRNode.CALL, applyIf = {"Bla"}) + public void applyIfMissingValue() {} + + @FailCount(2) + @Test + @IR(failOn = IRNode.CALL, applyIf = {"PrintIdealGraphFilee", "true"}) + @IR(failOn = IRNode.CALL, applyIf = {"Bla", "foo"}) + public void applyIfUnknownFlag() {} + + @FailCount(5) + @Test + @IR(failOn = IRNode.CALL, applyIf = {"PrintIdealGraphFile", ""}) + @IR(failOn = IRNode.CALL, applyIf = {"UseTLAB", ""}) + @IR(failOn = IRNode.CALL, applyIf = {"", "true"}) + @IR(failOn = IRNode.CALL, applyIf = {"", ""}) + @IR(failOn = IRNode.CALL, applyIf = {" ", " "}) + public void applyIfEmptyValue() {} + + @FailCount(5) + @Test + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "! 34"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!== 34"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<<= 34"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "=<34"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<"}) + public void applyIfFaultyComparator() {} + + @FailCount(3) + @Test + @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount", "50", "UseTLAB", "true"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount", "50", "UseTLAB"}) + public void applyIfNotTooManyFlags() {} + + @FailCount(2) + @Test + @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"Bla"}) + public void applyIfNotMissingValue() {} + + @FailCount(2) + @Test + @IR(failOn = IRNode.CALL, applyIfNot = {"PrintIdealGraphFilee", "true"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"Bla", "foo"}) + public void applyIfNotUnknownFlag() {} + + @FailCount(5) + @Test + @IR(failOn = IRNode.CALL, applyIfNot = {"PrintIdealGraphFile", ""}) + @IR(failOn = IRNode.CALL, applyIfNot = {"UseTLAB", ""}) + @IR(failOn = IRNode.CALL, applyIfNot = {"", "true"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"", ""}) + @IR(failOn = IRNode.CALL, applyIfNot = {" ", " "}) + public void applyIfNotEmptyValue() {} + + @FailCount(5) + @Test + @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount", "! 34"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount", "!== 34"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount", "<<= 34"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount", "=<34"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount", "<"}) + public void applyIfNotFaultyComparator() {} + + + @FailCount(2) + @Test + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "50"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "51", "UseTLAB"}) + public void applyIfAndNotEnoughFlags() {} + + @FailCount(5) + @Test + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "51", "UseTLAB"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"Bla"}) + public void applyIfAndMissingValue() {} + + @FailCount(3) + @Test + @IR(failOn = IRNode.CALL, applyIfAnd = {"PrintIdealGraphFilee", "true", "SuspendRetryCount", "< 34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "!= 50", "Bla", "bla", "Bla2", "bla2"}) + public void applyIfAndUnknownFlag() {} + + @FailCount(18) + @Test + @IR(failOn = IRNode.CALL, applyIfAnd = {"PrintIdealGraphFile", ""}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"PrintIdealGraphFile", "", "PrintIdealGraphFile", ""}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"UseTLAB", ""}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"UseTLAB", "", "UseTLAB", ""}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"", "true"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"", "true", "", "true"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"", ""}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"", "", "", ""}) + @IR(failOn = IRNode.CALL, applyIfAnd = {" ", " ", " ", " "}) + public void applyIfAndEmptyValue() {} + + @FailCount(20) + @Test + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "! 34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "! 34", "SuspendRetryCount", "! 34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "!== 34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "!== 34", "SuspendRetryCount", "=== 34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "<<= 34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "<<= 34", "SuspendRetryCount", ">>= 34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "=<34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "=<34", "SuspendRetryCount", "=<34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "<"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "<", "SuspendRetryCount", "!="}) + public void applyIfAndFaultyComparator() {} + + @FailCount(2) + @Test + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "50"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "51", "UseTLAB"}) + public void applyIfOrNotEnoughFlags() {} + + @FailCount(5) + @Test + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "51", "UseTLAB"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"Bla"}) + public void applyIfOrMissingValue() {} + + @FailCount(3) + @Test + @IR(failOn = IRNode.CALL, applyIfOr = {"PrintIdealGraphFilee", "true", "SuspendRetryCount", "< 34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "!= 50", "Bla", "bla", "Bla2", "bla2"}) + public void applyIfOrUnknownFlag() {} + + @FailCount(18) + @Test + @IR(failOn = IRNode.CALL, applyIfOr = {"PrintIdealGraphFile", ""}) + @IR(failOn = IRNode.CALL, applyIfOr = {"PrintIdealGraphFile", "", "PrintIdealGraphFile", ""}) + @IR(failOn = IRNode.CALL, applyIfOr = {"UseTLAB", ""}) + @IR(failOn = IRNode.CALL, applyIfOr = {"UseTLAB", "", "UseTLAB", ""}) + @IR(failOn = IRNode.CALL, applyIfOr = {"", "true"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"", "true", "", "true"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"", ""}) + @IR(failOn = IRNode.CALL, applyIfOr = {"", "", "", ""}) + @IR(failOn = IRNode.CALL, applyIfOr = {" ", " ", " ", " "}) + public void applyIfOrEmptyValue() {} + + @FailCount(20) + @Test + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "! 34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "! 34", "SuspendRetryCount", "! 34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "!== 34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "!== 34", "SuspendRetryCount", "=== 34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "<<= 34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "<<= 34", "SuspendRetryCount", ">>= 34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "=<34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "=<34", "SuspendRetryCount", "=<34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "<"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "<", "SuspendRetryCount", "!="}) + public void applyIfOrFaultyComparator() {} + + + @Test + @FailCount(3) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "true"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "SomeString"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "48"}) // valid + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "48.5"}) + public void wrongFlagValueLongFlag() {} + + @Test + @FailCount(3) + @IR(failOn = IRNode.CALL, applyIf = {"UseTLAB", "true"}) // valid + @IR(failOn = IRNode.CALL, applyIf = {"UseTLAB", "SomeString"}) + @IR(failOn = IRNode.CALL, applyIf = {"UseTLAB", "48"}) + @IR(failOn = IRNode.CALL, applyIf = {"UseTLAB", "48.5"}) + public void wrongFlagValueBooleanFlag() {} + + @Test + @FailCount(2) + @IR(failOn = IRNode.CALL, applyIf = {"CompileThresholdScaling", "true"}) + @IR(failOn = IRNode.CALL, applyIf = {"CompileThresholdScaling", "SomeString"}) + @IR(failOn = IRNode.CALL, applyIf = {"CompileThresholdScaling", "48"}) // valid + @IR(failOn = IRNode.CALL, applyIf = {"CompileThresholdScaling", "48.5"}) // valid + public void wrongFlagValueDoubleFlag() {} + + @Test + @NoFail + @IR(failOn = IRNode.CALL, applyIf = {"ErrorFile", "true"}) // valid + @IR(failOn = IRNode.CALL, applyIf = {"ErrorFile", "SomeString"}) // valid + @IR(failOn = IRNode.CALL, applyIf = {"ErrorFile", "48"}) // valid + @IR(failOn = IRNode.CALL, applyIf = {"ErrorFile", "48.5"}) // valid + public void anyValueForStringFlags() {} } class ClassNoDefaultConstructor { From 6801f53099c8acb25aaabe1e7d0f405b1dd8521a Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 19 Feb 2021 16:02:05 +0100 Subject: [PATCH 025/131] Adding more IR tests --- .../compiler/valhalla/framework/IRNode.java | 27 +- .../framework/tests/TestIRMatching.java | 398 ++++++++++++------ .../framework/tests/TestScenarios.java | 11 +- 3 files changed, 286 insertions(+), 150 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java index 653d8618fd7..a33a9d368fd 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java @@ -45,25 +45,35 @@ public class IRNode { private static final String STORE_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; public static final String STORE_OF_FIELD = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@.*name="; private static final String STORE_OF_FIELD_POSTFIX = ",.*" + END; + public static final String LOAD = START + "Load(B|S|I|L|F|D|P|N)" + MID + END; public static final String LOAD_OF_CLASS = START + "Load(B|C|S|I|L|F|D|P|N)" + MID + "@\\S*"; private static final String LOAD_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; public static final String LOAD_OF_FIELD = START + "Load(B|C|S|I|L|F|D|P|N)" + MID + "@.*name="; private static final String LOAD_OF_FIELD_POSTFIX = ",.*" + END; + public static final String LOAD_KLASS = START + "LoadK" + MID + END; + public static final String LOOP = START + "Loop" + MID + "" + END; public static final String COUNTEDLOOP = START + "CountedLoop\\b" + MID + "" + END; + public static final String COUNTEDLOOP_MAIN = START + "CountedLoop\\b" + MID + "main" + END; + + public static final String CALL = START + "CallStaticJava" + MID + END; + public static final String TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*reason" + END; + public static final String PREDICATE_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*predicate" + END; + public static final String UNSTABLE_IF_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*unstable_if" + END; + public static final String CLASS_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*class_check" + END; + public static final String NULL_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*null_check" + END; + public static final String NULL_ASSERT_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*null_assert" + END; + public static final String RANGE_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*range_check" + END; + public static final String UNHANDLED_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*unhandled" + END; + // Inline type allocation public static final String ALLOCA = "(.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_array_Java" + END; - public static final String LOADK = START + "LoadK" + MID + END; - public static final String COUNTEDLOOP_MAIN = START + "CountedLoop\\b" + MID + "main" + END; - public static final String TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*(unstable_if|predicate)" + END; - public static final String RETURN = START + "Return" + MID + END; public static final String LINKTOSTATIC = START + "CallStaticJava" + MID + "linkToStatic" + END; public static final String NPE = START + "CallStaticJava" + MID + "null_check" + END; - public static final String CALL = START + "CallStaticJava" + MID + END; public static final String STORE_INLINE_FIELDS = START + "CallStaticJava" + MID + "store_inline_type_fields" + END; public static final String SCOBJ = "(.*# ScObj.*" + END; public static final String LOAD_UNKNOWN_INLINE = "(.*call_leaf,runtime load_unknown_inline.*" + END; @@ -71,12 +81,7 @@ public class IRNode { public static final String INLINE_ARRAY_NULL_GUARD = "(.*call,static wrapper for: uncommon_trap.*reason='null_check' action='none'.*" + END; public static final String INTRINSIC_SLOW_PATH = "(.*call,static wrapper for: uncommon_trap.*reason='intrinsic_or_type_checked_inlining'.*" + END; public static final String CLONE_INTRINSIC_SLOW_PATH = "(.*call,static.*java.lang.Object::clone.*" + END; - public static final String CLASS_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*class_check" + END; - public static final String NULL_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*null_check" + END; - public static final String NULL_ASSERT_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*null_assert" + END; - public static final String RANGE_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*range_check" + END; - public static final String UNHANDLED_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*unhandled" + END; - public static final String PREDICATE_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*predicate" + END; + public static final String MEMBAR = START + "MemBar" + MID + END; public static final String CHECKCAST_ARRAY = "(cmp.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*" + END; public static final String CHECKCAST_ARRAYCOPY = "(.*call_leaf_nofp,runtime checkcast_arraycopy.*" + END; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java index 2fbc49af1a0..16fad10517e 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java @@ -30,73 +30,105 @@ import java.util.Arrays; import java.util.List; import java.util.function.Predicate; +import java.util.regex.Matcher; import java.util.regex.Pattern; public class TestIRMatching { public static void main(String[] args) { - runFailOnTests(Constraint.failOnNodes(AndOr1.class, "test1(int)", 1, true,"CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:+UsePerfData", "-XX:+UseTLAB"); - runFailOnTests(Constraint.failOnNodes(AndOr1.class, "test2()", 1, true,"CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:-UsePerfData", "-XX:+UseTLAB"); - - runWithArguments(AndOr1.class, "-XX:SuspendRetryCount=52", "-XX:+UsePerfData", "-XX:+UseTLAB"); - - runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=50"); - findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 0, 21); - findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", -1, -1); - - runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=49"); - findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 4, 6, 13, 18); - findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); - - runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=51"); - findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 7, 12, 19, 21); - findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 4, 7, 11, 16, 20, 22); - - runWithArguments(MultipleFailOnGood.class, "-XX:SuspendRetryCount=50"); - - runFailOnTests(Constraint.failOnNodes(MultipleFailOnBad.class, "fail1()", 1,true, "Store"), - Constraint.failOnNodes(MultipleFailOnBad.class, "fail2()", 1,true, "CallStaticJava"), - Constraint.failOnNodes(MultipleFailOnBad.class, "fail3()", 1,true, "Store"), - Constraint.failOnNodes(MultipleFailOnBad.class, "fail4()", 1,true, "Store"), - Constraint.failOnMatches(MultipleFailOnBad.class, "fail5()", 1,true, "Store", "iFld"), - Constraint.failOnAlloc(MultipleFailOnBad.class, "fail6()", 1,true, "MyClass"), - Constraint.failOnAlloc(MultipleFailOnBad.class, "fail7()", 1,true, "MyClass"), - Constraint.failOnAlloc(MultipleFailOnBad.class, "fail8()", 1,true, "MyClass"), - Constraint.failOnNodes(MultipleFailOnBad.class, "fail9()", 1,true, "Store", "CallStaticJava"), - Constraint.failOnMatches(MultipleFailOnBad.class, "fail10()", 1,true, "Store", "iFld")); - - runFailOnTests(Constraint.failOnArrayAlloc(VariousIRNodes.class, "allocArray()", 1, true, "MyClass"), - Constraint.failOnArrayAlloc(VariousIRNodes.class, "allocArray()", 2, true, "MyClass"), - Constraint.failOnArrayAlloc(VariousIRNodes.class, "allocArray()", 3, false, "MyClass"), - Constraint.failOnArrayAlloc(VariousIRNodes.class, "allocArray()", 4, false, "MyClass"), - Constraint.failOnArrayAlloc(VariousIRNodes.class, "allocArray()", 5, true, "MyClass"), - Constraint.failOnNodes(VariousIRNodes.class, "loop()", 1, true, "Loop"), - Constraint.failOnNodes(VariousIRNodes.class, "loop()", 2, false, "CountedLoop"), - Constraint.failOnNodes(VariousIRNodes.class, "countedLoop()", 1, false, "Loop"), - Constraint.failOnNodes(VariousIRNodes.class, "countedLoop()", 2, true, "CountedLoop"), - Constraint.failOnNodes(VariousIRNodes.class, "loopAndCountedLoop()", 1, true, "Loop"), - Constraint.failOnNodes(VariousIRNodes.class, "loopAndCountedLoop()", 2, true, "CountedLoop"), - Constraint.failOnNodes(VariousIRNodes.class, "load()", 1, true, "Load"), - Constraint.failOnNodes(VariousIRNodes.class, "load()", 2, true, "VariousIRNodes"), - Constraint.failOnNodes(VariousIRNodes.class, "load()", 3, true, "VariousIRNodes"), - Constraint.failOnMatches(VariousIRNodes.class, "load()", 4, true, "Load", "iFld"), - Constraint.failOnNodes(VariousIRNodes.class, "load()", 5, false, "Load") - ); - - runWithArguments(CountComparisons.class, "-XX:SuspendRetryCount=50"); - runWithArguments(GoodCount.class, "-XX:SuspendRetryCount=50"); - runFailOnTests(Constraint.countsMatches(BadCount.class, "bad1()", 1,true), - Constraint.countsMatches(BadCount.class, "bad1()", 2,false), - Constraint.countsMatches(BadCount.class, "bad2()", 1,false), - Constraint.countsMatches(BadCount.class, "bad2()", 2,true), - Constraint.countsMatches(BadCount.class, "bad3()", 1,true), - Constraint.countsMatches(BadCount.class, "bad3()", 2,true)); +// runFailOnTests(Constraint.failOnMatches(AndOr1.class, "test1(int)", 1, true,"CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:+UsePerfData", "-XX:+UseTLAB"); +// runFailOnTests(Constraint.failOnMatches(AndOr1.class, "test2()", 1, true,"CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:-UsePerfData", "-XX:+UseTLAB"); +// +// runWithArguments(AndOr1.class, "-XX:SuspendRetryCount=52", "-XX:+UsePerfData", "-XX:+UseTLAB"); +// +// runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=50"); +// findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 0, 21); +// findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", -1, -1); +// +// runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=49"); +// findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 4, 6, 13, 18); +// findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); +// +// runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=51"); +// findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 7, 12, 19, 21); +// findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 4, 7, 11, 16, 20, 22); +// +// runWithArguments(MultipleFailOnGood.class, "-XX:SuspendRetryCount=50"); +// +// runFailOnTests(Constraint.failOnMatches(MultipleFailOnBad.class, "fail1()", 1,true, "Store"), +// Constraint.failOnMatches(MultipleFailOnBad.class, "fail2()", 1,true, "CallStaticJava"), +// Constraint.failOnMatches(MultipleFailOnBad.class, "fail3()", 1,true, "Store"), +// Constraint.failOnMatches(MultipleFailOnBad.class, "fail4()", 1,true, "Store"), +// Constraint.failOnMatches(MultipleFailOnBad.class, "fail5()", 1,true, "Store", "iFld"), +// Constraint.failOnAlloc(MultipleFailOnBad.class, "fail6()", 1,true, "MyClass"), +// Constraint.failOnAlloc(MultipleFailOnBad.class, "fail7()", 1,true, "MyClass"), +// Constraint.failOnAlloc(MultipleFailOnBad.class, "fail8()", 1,true, "MyClass"), +// Constraint.failOnMatches(MultipleFailOnBad.class, "fail9()", 1,true, "Store", "CallStaticJava"), +// Constraint.failOnMatches(MultipleFailOnBad.class, "fail10()", 1,true, "Store", "iFld")); +// +// runWithArguments(CountComparisons.class, "-XX:SuspendRetryCount=50"); +// runWithArguments(GoodCount.class, "-XX:SuspendRetryCount=50"); +// runFailOnTests(Constraint.countsMatches(BadCount.class, "bad1()", 1,true), +// Constraint.countsMatches(BadCount.class, "bad1()", 2,false), +// Constraint.countsMatches(BadCount.class, "bad2()", 1,false), +// Constraint.countsMatches(BadCount.class, "bad2()", 2,true), +// Constraint.countsMatches(BadCount.class, "bad3()", 1,true), +// Constraint.countsMatches(BadCount.class, "bad3()", 2,true)); +// +// runFailOnTests(Constraint.failOnArrayAlloc(AllocArray.class, "allocArray()", 1, true, "MyClass"), +// Constraint.failOnArrayAlloc(AllocArray.class, "allocArray()", 2, true, "MyClass"), +// Constraint.failOnArrayAlloc(AllocArray.class, "allocArray()", 3, false, "MyClass"), +// Constraint.failOnArrayAlloc(AllocArray.class, "allocArray()", 4, false, "MyClass"), +// Constraint.failOnArrayAlloc(AllocArray.class, "allocArray()", 5, true, "MyClass")); +// +// runFailOnTests(new String[] {"-XX:-UseCompressedClassPointers"}, +// Constraint.failOnMatches(Loads.class, "load()", 1, true, "Load"), +// Constraint.failOnMatches(Loads.class, "load()", 2, true, "Loads"), +// Constraint.failOnMatches(Loads.class, "load()", 3, true, "Loads"), +// Constraint.failOnMatches(Loads.class, "load()", 4, true, "Load", "iFld"), +// Constraint.failOnMatches(Loads.class, "load()", 5, false, "Load"), +// Constraint.failOnMatches(Loads.class, "load()", 6, false, "LoadKlass"), +// Constraint.failOnMatches(Loads.class, "loadKlass()", 1, false, "LoadKlass")); +// +// runFailOnTests(Constraint.failOnMatches(Loops.class, "loop()", 1, true, "Loop"), +// Constraint.failOnMatches(Loops.class, "loop()", 2, false, "CountedLoop"), +// Constraint.failOnMatches(Loops.class, "loop()", 3, false, "CountedLoop", "main"), +// Constraint.failOnMatches(Loops.class, "countedLoop()", 1, false, "Loop"), +// Constraint.failOnMatches(Loops.class, "countedLoop()", 2, true, "CountedLoop"), +// Constraint.failOnMatches(Loops.class, "countedLoop()", 3, false, "CountedLoop", "main"), +// Constraint.failOnMatches(Loops.class, "loopAndCountedLoop()", 1, true, "Loop"), +// Constraint.failOnMatches(Loops.class, "loopAndCountedLoop()", 2, true, "CountedLoop"), +// Constraint.failOnMatches(Loops.class, "loopAndCountedLoop()", 3, false, "CountedLoop", "main"), +// Constraint.failOnMatches(Loops.class, "countedLoopMain()", 1, false, "Loop"), +// Constraint.failOnMatches(Loops.class, "countedLoopMain()", 2, true, "CountedLoop"), +// Constraint.failOnMatches(Loops.class, "countedLoopMain()", 3, true, "CountedLoop", "main")); + runFailOnTests(Constraint.failOnMatches(Traps.class, "traps()", 1, true, "CallStaticJava", "uncommon_trap"), + Constraint.failOnMatches(Traps.class, "traps()", 2, true, "CallStaticJava", "uncommon_trap", "predicate"), + Constraint.failOnMatches(Traps.class, "traps()", 3, false, "Store", "iFld"), + Constraint.failOnMatches(Traps.class, "noTraps()", 1, false, "CallStaticJava", "uncommon_trap"), + Constraint.failOnMatches(Traps.class, "noTraps()", 2, true, "Store", "iFld"), + Constraint.failOnMatches(Traps.class, "nullCheck()", 1, true, "CallStaticJava", "uncommon_trap"), + Constraint.failOnMatches(Traps.class, "nullCheck()", 2, true, "CallStaticJava", "uncommon_trap", "null_check") + ); + } private static void runWithArguments(Class clazz, String... args) { TestFramework.runWithScenarios(clazz, new Scenario(0, args)); } + private static void runFailOnTests(String[] args , Constraint... constraints) { + try { + Scenario s = new Scenario(0, args); + TestFramework.runWithScenarios(constraints[0].getKlass(), s); // All constraints have the same class. + shouldNotReach(); + } catch (ShouldNotReachException e) { + throw e; + } catch (RuntimeException e) { + checkConstraints(e, constraints); + } + } + private static void runFailOnTests(Constraint... constraints) { try { TestFramework.run(constraints[0].getKlass()); // All constraints have the same class. @@ -104,10 +136,31 @@ private static void runFailOnTests(Constraint... constraints) { } catch (ShouldNotReachException e) { throw e; } catch (RuntimeException e) { - System.out.println(e.getMessage()); + checkConstraints(e, constraints); + } + } + + private static void checkConstraints(RuntimeException e, Constraint[] constraints) { + String message = e.getMessage(); + try { + long expectedFailures = Arrays.stream(constraints).filter(Constraint::shouldMatch).count(); + Pattern pattern = Pattern.compile("Failures \\((\\d+)\\)"); + Matcher matcher = pattern.matcher(message); + if (expectedFailures > 0) { + Asserts.assertTrue(matcher.find(), "Could not find failures"); + long foundFailuresCount = Long.parseLong(matcher.group(1)); + Asserts.assertEQ(foundFailuresCount, expectedFailures); + } else { + Asserts.assertFalse(matcher.find(), "Should not have found failures"); + } + for (Constraint constraint : constraints) { constraint.checkConstraint(e); } + } catch (Exception e1) { + System.out.println(TestFramework.getLastVmOutput()); + System.out.println(message); + throw e1; } } @@ -168,7 +221,7 @@ class MultipleFailOnGood { @Test @IR(applyIf = {"SuspendRetryCount", "50"}, failOn = {IRNode.STORE, IRNode.CALL}) @IR(failOn = {IRNode.STORE, IRNode.CALL}) - @IR(applyIfOr = {"SuspendRetryCount", "99", "SuspendRetryCount", "100"}, failOn = {IRNode.RETURN, IRNode.CALL}) // Not applied + @IR(applyIfOr = {"SuspendRetryCount", "99", "SuspendRetryCount", "100"}, failOn = {IRNode.LOOP, IRNode.CALL}) // Not applied public void good1() { forceInline(); } @@ -293,56 +346,56 @@ private void dontInline() { class FlagComparisons { // Applies all IR rules if SuspendRetryCount=50 @Test - @IR(applyIf = {"SuspendRetryCount", "50"}) // Index 0 - @IR(applyIf = {"SuspendRetryCount", "=50"}) - @IR(applyIf = {"SuspendRetryCount", "= 50"}) - @IR(applyIf = {"SuspendRetryCount", " = 50"}) - @IR(applyIf = {"SuspendRetryCount", "<=50"}) // Index 4 - @IR(applyIf = {"SuspendRetryCount", "<= 50"}) - @IR(applyIf = {"SuspendRetryCount", " <= 50"}) - @IR(applyIf = {"SuspendRetryCount", ">=50"}) // Index 7 - @IR(applyIf = {"SuspendRetryCount", ">= 50"}) - @IR(applyIf = {"SuspendRetryCount", " >= 50"}) - @IR(applyIf = {"SuspendRetryCount", ">49"}) - @IR(applyIf = {"SuspendRetryCount", "> 49"}) - @IR(applyIf = {"SuspendRetryCount", " > 49"}) - @IR(applyIf = {"SuspendRetryCount", "<51"}) // Index 13 - @IR(applyIf = {"SuspendRetryCount", "< 51"}) - @IR(applyIf = {"SuspendRetryCount", " < 51"}) - @IR(applyIf = {"SuspendRetryCount", "!=51"}) - @IR(applyIf = {"SuspendRetryCount", "!= 51"}) - @IR(applyIf = {"SuspendRetryCount", " != 51"}) - @IR(applyIf = {"SuspendRetryCount", "!=49"}) - @IR(applyIf = {"SuspendRetryCount", "!= 49"}) - @IR(applyIf = {"SuspendRetryCount", " != 49"}) // Index 21 + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "50"}) // Index 0 + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "=50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "= 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " = 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<=50"}) // Index 4 + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<= 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " <= 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", ">=50"}) // Index 7 + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", ">= 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " >= 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", ">49"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "> 49"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " > 49"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<51"}) // Index 13 + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "< 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " < 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!=51"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!= 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " != 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!=49"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!= 49"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " != 49"}) // Index 21 public void testMatchAllIf50() { } // Applies no IR rules if SuspendRetryCount=50 @Test - @IR(applyIf = {"SuspendRetryCount", "49"}) // Index 0 - @IR(applyIf = {"SuspendRetryCount", "=49"}) - @IR(applyIf = {"SuspendRetryCount", "= 49"}) - @IR(applyIf = {"SuspendRetryCount", " = 49"}) - @IR(applyIf = {"SuspendRetryCount", "51"}) // Index 4 - @IR(applyIf = {"SuspendRetryCount", "=51"}) - @IR(applyIf = {"SuspendRetryCount", "= 51"}) - @IR(applyIf = {"SuspendRetryCount", " = 51"}) - @IR(applyIf = {"SuspendRetryCount", "<=49"}) // Index 8 - @IR(applyIf = {"SuspendRetryCount", "<= 49"}) - @IR(applyIf = {"SuspendRetryCount", " <= 49"}) - @IR(applyIf = {"SuspendRetryCount", ">=51"}) // Index 11 - @IR(applyIf = {"SuspendRetryCount", ">= 51"}) - @IR(applyIf = {"SuspendRetryCount", " >= 51"}) - @IR(applyIf = {"SuspendRetryCount", ">50"}) - @IR(applyIf = {"SuspendRetryCount", "> 50"}) - @IR(applyIf = {"SuspendRetryCount", " > 50"}) - @IR(applyIf = {"SuspendRetryCount", "<50"}) // Index 17 - @IR(applyIf = {"SuspendRetryCount", "< 50"}) - @IR(applyIf = {"SuspendRetryCount", " < 50"}) - @IR(applyIf = {"SuspendRetryCount", "!=50"}) - @IR(applyIf = {"SuspendRetryCount", "!= 50"}) - @IR(applyIf = {"SuspendRetryCount", " != 50"}) // Index 22 + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "49"}) // Index 0 + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "=49"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "= 49"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " = 49"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "51"}) // Index 4 + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "=51"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "= 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " = 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<=49"}) // Index 8 + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<= 49"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " <= 49"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", ">=51"}) // Index 11 + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", ">= 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " >= 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", ">50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "> 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " > 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<50"}) // Index 17 + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "< 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " < 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!=50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!= 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " != 50"}) // Index 22 public void testMatchNoneIf50() { } } @@ -389,7 +442,6 @@ class GoodCount { MyClass myClassSubPoly = new MyClassSub(); MyClassSub myClassSub = new MyClassSub(); - @Test @IR(counts = {IRNode.STORE, "1"}) public void good1() { @@ -488,12 +540,35 @@ public void bad3() { } } -// Test on remaining IR nodes that we have not tested above, yet. -class VariousIRNodes { - MyClass[] myClassArray; - int limit = 1024; +class Loads { int iFld = 34; int result = 0; + Object[] myClassArr = new MyClass[3]; + Object myClass = new MyClass(); + + @Test + @IR(failOn = {IRNode.LOAD}) + @IR(failOn = {IRNode.LOAD_OF_CLASS, "compiler/valhalla/framework/tests/Loads"}) + @IR(failOn = {IRNode.LOAD_OF_CLASS, "Loads"}) + @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld"}) + @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld2", IRNode.LOAD_OF_CLASS, "Load"}) // Does not fail + @IR(failOn = {IRNode.LOAD_KLASS}) // Does not fail + public void load() { + result = iFld; + } + + @Test + @IR(failOn = {IRNode.LOAD_KLASS}) + public void loadKlass() { + if (myClass instanceof MyClass) { + result = 3; + } + } +} + +class AllocArray { + MyClass[] myClassArray; + @Test @IR(failOn = {IRNode.ALLOC_ARRAY}) @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClass"}) @@ -503,10 +578,19 @@ class VariousIRNodes { public void allocArray() { myClassArray = new MyClass[2]; } +} + +class Loops { + int limit = 1024; + int[] iArr = new int[100]; + + @DontInline + public void dontInline() {} @Test - @IR(failOn = {IRNode.LOOP}) - @IR(failOn = {IRNode.COUNTEDLOOP}) // Does not fail + @IR(failOn = IRNode.LOOP) // fails + @IR(failOn = IRNode.COUNTEDLOOP) + @IR(failOn = IRNode.COUNTEDLOOP_MAIN) public void loop() { for (int i = 0; i < limit; i++) { dontInline(); @@ -514,8 +598,9 @@ public void loop() { } @Test - @IR(failOn = {IRNode.LOOP}) // Does not fail - @IR(failOn = {IRNode.COUNTEDLOOP}) + @IR(failOn = IRNode.LOOP) + @IR(failOn = IRNode.COUNTEDLOOP) // fails + @IR(failOn = IRNode.COUNTEDLOOP_MAIN) public void countedLoop() { for (int i = 0; i < 2000; i++) { dontInline(); @@ -523,8 +608,9 @@ public void countedLoop() { } @Test - @IR(failOn = {IRNode.LOOP}) - @IR(failOn = {IRNode.COUNTEDLOOP}) + @IR(failOn = IRNode.LOOP) // fails + @IR(failOn = IRNode.COUNTEDLOOP) // fails + @IR(failOn = IRNode.COUNTEDLOOP_MAIN) public void loopAndCountedLoop() { for (int i = 0; i < 2000; i++) { for (int j = 0; j < limit; j++) { @@ -533,25 +619,67 @@ public void loopAndCountedLoop() { } } - @DontInline - public void dontInline() {} + @Test + @IR(failOn = IRNode.LOOP) // fails + @IR(failOn = IRNode.COUNTEDLOOP) + @IR(failOn = IRNode.COUNTEDLOOP_MAIN) // fails + public void countedLoopMain() { + // Cannot unroll completely -> create pre/main/post + for (int i = 0; i < 100; i++) { + iArr[i] = i; + } + } @Test - @IR(failOn = {IRNode.LOAD}) - @IR(failOn = {IRNode.LOAD_OF_CLASS, "compiler/valhalla/framework/tests/VariousIRNodes"}) - @IR(failOn = {IRNode.LOAD_OF_CLASS, "VariousIRNodes"}) - @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld"}) - @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld2", IRNode.LOAD_OF_CLASS, "Various"}) // Does not fail - public void load() { - result = iFld; + @IR(failOn = IRNode.LOOP) // fails + @IR(failOn = IRNode.COUNTEDLOOP) + @IR(failOn = IRNode.COUNTEDLOOP_MAIN) + public void countedLoopUnrolled() { + // Completely unrolled -> no pre/main/post + for (int i = 0; i < 8; i++) { + iArr[i] = i; + } } +} + +class Traps { + int number42 = 42; + int iFld = 42; + MyClass myClass = new MyClass(); @Test - @IR(failOn = {IRNode.RETURN}) - public void returns() { - dontInline(); + @IR(failOn = IRNode.TRAP) // fails + @IR(failOn = IRNode.PREDICATE_TRAP) // fails + @IR(failOn = {IRNode.STORE_OF_FIELD, "iFld"}) + public void traps() { + for (int i = 0; i < 100; i++) { + if (number42 != 42) { + // Never reached + iFld = i; + } + } } + @Test + @IR(failOn = IRNode.TRAP) + @IR(failOn = {IRNode.STORE_OF_FIELD, "iFld"}) // fails + public void noTraps() { + for (int i = 0; i < 100; i++) { + if (i < 42) { + // Reached, no uncommon trap + iFld = i; + } + } + } + + @Test + @IR(failOn = IRNode.TRAP) // fails + @IR(failOn = IRNode.NULL_CHECK_TRAP) // fails + public void nullCheck() { + if (myClass instanceof MyClassSub) { + iFld = 4; + } + } } class MyClass { @@ -568,14 +696,14 @@ enum FailType { } class Constraint { - final private Class klass; - final private int ruleIdx; - final private Pattern irPattern; - final private List matches; - final private Pattern methodPattern; + private final Class klass; + private final int ruleIdx; + private final Pattern irPattern; + private final List matches; + private final Pattern methodPattern; private final String classAndMethod; - final FailType failType; - final boolean shouldMatch; + private final FailType failType; + private final boolean shouldMatch; private Constraint(Class klass, String methodName, int ruleIdx, FailType failType, List matches, boolean shouldMatch) { this.klass = klass; @@ -596,8 +724,8 @@ public Class getKlass() { return klass; } - public static Constraint failOnNodes(Class klass, String methodName, int ruleIdx, boolean shouldMatch, String... nodes) { - return new Constraint(klass, methodName, ruleIdx, FailType.FAIL_ON, new ArrayList<>(Arrays.asList(nodes)), shouldMatch); + public boolean shouldMatch() { + return shouldMatch; } public static Constraint failOnAlloc(Class klass, String methodName, int ruleIdx, boolean shouldMatch, String allocKlass) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java index b17c0d59d5f..e350b248c1d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java @@ -35,11 +35,13 @@ public static void main(String[] args) { Scenario s3dup = new Scenario(3, "-XX:SuspendRetryCount=53"); try { TestFramework.runWithScenarios(sDefault, s1, s2, s3); + Asserts.fail("Should not reach"); } catch (TestRunException e) { Asserts.assertTrue(e.getMessage().contains("The following scenarios have failed: #0, #1, #3")); } try { TestFramework.runWithScenarios(s1, s2, s3); + Asserts.fail("Should not reach"); } catch (TestRunException e) { Asserts.assertTrue(e.getMessage().contains("The following scenarios have failed: #1, #3")); } @@ -47,26 +49,27 @@ public static void main(String[] args) { TestFramework.runWithScenarios(ScenarioTest.class, s1, s2, s3); try { TestFramework.runWithScenarios(s1, s3dup, s2, s3); + Asserts.fail("Should not reach"); } catch (RuntimeException e) { Asserts.assertTrue(e.getMessage().contains("Cannot define two scenarios with the same index 3")); } } @Test - @IR(applyIf = {"SuspendRetryCount", "50"}, failOn = {IRNode.RETURN}) + @IR(applyIf = {"SuspendRetryCount", "50"}, counts = {IRNode.CALL, "1"}) public void failDefault() { } @Test - @IR(applyIf = {"SuspendRetryCount", "51"}, failOn = {IRNode.RETURN}) - @IR(applyIf = {"SuspendRetryCount", "53"}, failOn = {IRNode.RETURN}) + @IR(applyIf = {"SuspendRetryCount", "51"}, counts = {IRNode.CALL, "1"}) + @IR(applyIf = {"SuspendRetryCount", "53"}, counts = {IRNode.CALL, "1"}) public void failS3() { } } class ScenarioTest { @Test - @IR(applyIf = {"SuspendRetryCount", "54"}, failOn = {IRNode.RETURN}) + @IR(applyIf = {"SuspendRetryCount", "54"}, counts = {IRNode.CALL, "1"}) public void doesNotFail() { } } From 2d5f9830ed28b396f31a6f009cdcee2853f45a35 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 24 Feb 2021 11:03:06 +0100 Subject: [PATCH 026/131] Add IR tests for trap, scope object, completely updated the format of IR failure reporting and refactored the constraint matching of the IR test, add individual store/loads selection --- .../valhalla/framework/ArgumentValue.java | 129 ++- .../valhalla/framework/IRMatcher.java | 73 +- .../compiler/valhalla/framework/IRNode.java | 66 +- .../framework/IRViolationException.java | 30 + .../valhalla/framework/TestFormat.java | 3 +- .../valhalla/framework/TestFramework.java | 78 +- .../framework/tests/TestBadFormat.java | 20 + .../framework/tests/TestIRMatching.java | 832 +++++++++++++----- .../valhalla/framework/tests/TestSanity.java | 7 +- 9 files changed, 897 insertions(+), 341 deletions(-) create mode 100644 test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRViolationException.java diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java index 5703937ec8d..d633bb921cd 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java @@ -70,79 +70,72 @@ public static ArgumentValue[] getArguments(Method m) { ArgumentValue[] arguments = new ArgumentValue[values.length]; Class[] declaredParameters = m.getParameterTypes(); Parameter[] declaredParameterObjects = m.getParameters(); - TestFormat.check(values.length == declaredParameters.length, - "Number of argument values provided in @Arguments does not match the number of actual arguments in " + m); + try { + TestFormat.check(values.length == declaredParameters.length, "Number of argument values provided in @Arguments does not match the number of actual arguments in " + m); - for (int i = 0; i < values.length; i++) { - Argument specifiedArg = values[i]; - Class parameter = declaredParameters[i]; - Parameter parameterObj = declaredParameterObjects[i]; - try { - switch (specifiedArg) { - case DEFAULT -> { - try { - arguments[i] = createDefault(parameter); - } catch (NoSuchMethodException e) { - TestFormat.fail("Cannot create new default instance of " + parameter + " for " + m - + " due to missing default constructor"); - } catch (Exception e) { - TestFormat.fail("Cannot create new default instance of " + parameter + " for " + m + ": " + e.getCause()); + for (int i = 0; i < values.length; i++) { + Argument specifiedArg = values[i]; + Class parameter = declaredParameters[i]; + Parameter parameterObj = declaredParameterObjects[i]; + try { + switch (specifiedArg) { + case DEFAULT -> { + try { + arguments[i] = createDefault(parameter); + } catch (NoSuchMethodException e) { + TestFormat.fail("Cannot create new default instance of " + parameter + " for " + m + " due to missing default constructor"); + } catch (Exception e) { + TestFormat.fail("Cannot create new default instance of " + parameter + " for " + m + ": " + e.getCause()); + } + } + case NUMBER_42 -> { + TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_42 argument for non-number " + parameterObj + " for " + m); + arguments[i] = create((byte) 42); + } + case NUMBER_MINUS_42 -> { + TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_MINUS_42 argument for non-number " + parameterObj + " for " + m); + arguments[i] = create((byte) -42); + } + case MIN -> { + TestFormat.check(isNumber(parameter) || isChar(parameter), "Provided invalid MIN argument for non-number " + parameterObj + " for " + m); + arguments[i] = createMin(parameter); + } + case MAX -> { + TestFormat.check(isNumber(parameter) || isChar(parameter), "Provided invalid MAX argument for non-number " + parameterObj + " for " + m); + arguments[i] = createMax(parameter); + } + case FALSE -> { + TestFormat.check(ArgumentValue.isBoolean(parameter), "Provided invalid FALSE argument for non-boolean " + parameterObj + " for " + m); + arguments[i] = create(false); + } + case TRUE -> { + TestFormat.check(ArgumentValue.isBoolean(parameter), "Provided invalid TRUE argument for non-boolean " + parameterObj + " for " + m); + arguments[i] = create(true); + } + case BOOLEAN_TOGGLE_FIRST_FALSE -> { + TestFormat.check(isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + parameterObj + " for " + m); + arguments[i] = createToggleBoolean(false); + } + case BOOLEAN_TOGGLE_FIRST_TRUE -> { + TestFormat.check(ArgumentValue.isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + parameterObj + " for " + m); + arguments[i] = createToggleBoolean(true); + } + case RANDOM_ONCE -> { + TestFormat.check(isPrimitiveType(parameter), "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameterObj + " for " + m); + arguments[i] = createRandom(parameter); + } + case RANDOM_EACH -> { + TestFormat.check(isPrimitiveType(parameter), "Provided invalid RANDOM_EACH argument for non-primitive type " + parameterObj + " for " + m); + arguments[i] = createRandomEach(parameter); } } - case NUMBER_42 -> { - TestFormat.check(isNumber(parameter), - "Provided invalid NUMBER_42 argument for non-number " + parameterObj + " for " + m); - arguments[i] = create((byte) 42); - } - case NUMBER_MINUS_42 -> { - TestFormat.check(isNumber(parameter), - "Provided invalid NUMBER_MINUS_42 argument for non-number " + parameterObj + " for " + m); - arguments[i] = create((byte) -42); - } - case MIN -> { - TestFormat.check(isNumber(parameter) || isChar(parameter), - "Provided invalid MIN argument for non-number " + parameterObj + " for " + m); - arguments[i] = createMin(parameter); - } - case MAX -> { - TestFormat.check(isNumber(parameter) || isChar(parameter), - "Provided invalid MAX argument for non-number " + parameterObj + " for " + m); - arguments[i] = createMax(parameter); - } - case FALSE -> { - TestFormat.check(ArgumentValue.isBoolean(parameter), - "Provided invalid FALSE argument for non-boolean " + parameterObj + " for " + m); - arguments[i] = create(false); - } - case TRUE -> { - TestFormat.check(ArgumentValue.isBoolean(parameter), - "Provided invalid TRUE argument for non-boolean " + parameterObj + " for " + m); - arguments[i] = create(true); - } - case BOOLEAN_TOGGLE_FIRST_FALSE -> { - TestFormat.check(isBoolean(parameter), - "Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + parameterObj + " for " + m); - arguments[i] = createToggleBoolean(false); - } - case BOOLEAN_TOGGLE_FIRST_TRUE -> { - TestFormat.check(ArgumentValue.isBoolean(parameter), - "Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + parameterObj + " for " + m); - arguments[i] = createToggleBoolean(true); - } - case RANDOM_ONCE -> { - TestFormat.check(isPrimitiveType(parameter), - "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameterObj + " for " + m); - arguments[i] = createRandom(parameter); - } - case RANDOM_EACH -> { - TestFormat.check(isPrimitiveType(parameter), - "Provided invalid RANDOM_EACH argument for non-primitive type " + parameterObj + " for " + m); - arguments[i] = createRandomEach(parameter); - } + } catch (TestFormatException e) { + // Catch and continue to check arguments. } - } catch (TestFormatException e) { - // Catch and continue to check arguments. } + } catch (TestFormatException e) { + // Catch and return empty array to check for additional failures. + return new ArgumentValue[0]; } return arguments; } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java index fb81d21310a..fab9ab8035f 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java @@ -138,10 +138,10 @@ private void reportFailuresIfAny() { list.forEach(s -> builder.append(" * ").append(s.replace("\n", "\n ").trim()).append("\n")); builder.append("\n"); } - builder.insert(0, "------------\n"); - builder.insert(0, "Failures (" + failures + ")\n"); - builder.insert(0, ("\nOne or more @IR rules failed:\n\n")); - Asserts.fail(builder.toString()); + builder.insert(0, ("\nOne or more @IR rules failed:\n\n" + + "Failed IR Rules (" + failures + ")\n") + + "-----------------" + "-".repeat(String.valueOf(failures).length()) + "\n"); + throw new IRViolationException(builder.toString()); } } @@ -152,25 +152,51 @@ private void applyRuleToMethod(Method m, IR[] irAnnos, Integer[] ids) { } for (Integer id : ids) { IR irAnno = irAnnos[id]; - applyFailOn(m, testOutput, irAnno, id + 1); - applyCount(m, testOutput, irAnno, id + 1); + StringBuilder failMsg = new StringBuilder(); + applyFailOn(testOutput, failMsg, irAnno); + applyCounts(m, testOutput, failMsg, irAnno); + if (!failMsg.isEmpty()) { + failMsg.insert(0, "@IR rule " + (id + 1) + ": \"" + irAnno + "\"\n"); + fails.computeIfAbsent(m, k -> new ArrayList<>()).add(failMsg.toString()); + } } } - private void applyFailOn(Method m, String testOutput, IR irAnno, int annoId) { + private void applyFailOn(String testOutput, StringBuilder failMsg, IR irAnno) { if (irAnno.failOn().length != 0) { String failOnRegex = String.join("|", IRNode.mergeNodes(irAnno.failOn())); Pattern pattern = Pattern.compile(failOnRegex); Matcher matcher = pattern.matcher(testOutput); - boolean found = matcher.find(); - if (found) { - addFail(m, irAnno, annoId, matcher, "contains forbidden node(s)"); + if (matcher.find()) { + addFailOnFails(irAnno, failMsg, testOutput); } } } - private void applyCount(Method m, String testOutput, IR irAnno, int annoId) { + private void addFailOnFails(IR irAnno, StringBuilder failMsg, String testOutput) { + List failOnNodes = IRNode.mergeNodes(irAnno.failOn()); + Pattern pattern; + Matcher matcher; + failMsg.append("- failOn: Graph contains forbidden nodes:\n"); + int nodeId = 1; + for (String nodeRegex : failOnNodes) { + pattern = Pattern.compile(nodeRegex); + matcher = pattern.matcher(testOutput); + long matchCount = matcher.results().count(); + if (matchCount > 0) { + matcher.reset(); + failMsg.append(" Regex ").append(nodeId).append(") ").append(nodeRegex).append("\n"); + failMsg.append(" Matched forbidden node").append(matchCount > 1 ? "s" : "").append(":\n"); + matcher.results().forEach(r -> failMsg.append(" ").append(r.group()).append("\n")); + } + nodeId++; + } + } + + private void applyCounts(Method m, String testOutput, StringBuilder failMsg, IR irAnno) { if (irAnno.counts().length != 0) { + boolean hasFails = false; + int countsId = 1; final List nodesWithCount = IRNode.mergeNodes(irAnno.counts()); for (int i = 0; i < nodesWithCount.size(); i += 2) { String node = nodesWithCount.get(i); @@ -194,21 +220,26 @@ private void applyCount(Method m, String testOutput, IR irAnno, int annoId) { Matcher matcher = pattern.matcher(testOutput); long actualCount = matcher.results().count(); if (!parsedComparator.getPredicate().test(actualCount, expectedCount)) { - String message = "contains wrong number of nodes. Failed constraint: " + actualCount + " (found) " + countString.trim(); - addFail(m, irAnno, annoId, matcher, message); + if (!hasFails) { + failMsg.append("- counts: Graph contains wrong number of nodes:\n"); + hasFails = true; + } + addCountsFail(failMsg, node, matcher, expectedCount, actualCount, countsId); } + countsId++; } } } - private void addFail(Method m, IR irAnno, int annoId, Matcher matcher, String message) { + private void addCountsFail(StringBuilder failMsg, String node, Matcher matcher, long expectedCount, long actualCount, int countsId) { matcher.reset(); - StringBuilder builder = new StringBuilder(); - builder.append("@IR rule ").append(annoId).append(": \"").append(irAnno).append("\"\n"); - builder.append("Failing Regex: ").append(matcher.pattern().toString()).append("\n"); - builder.append("Failure: Graph for '").append(m).append(" ").append(message).append(":\n"); - matcher.results().forEach(r -> builder.append(r.group()).append("\n")); - List failsList = fails.computeIfAbsent(m, k -> new ArrayList<>()); - failsList.add(builder.toString()); + failMsg.append(" Regex ").append(countsId).append(") ").append(node).append("\n"); + failMsg.append(" Expected ").append(expectedCount).append(" but found ").append(actualCount); + if (actualCount > 0) { + failMsg.append(" node").append(actualCount > 1 ? "s" : "").append(":\n"); + matcher.results().forEach(r -> failMsg.append(" ").append(r.group()).append("\n")); + } else { + failMsg.append(" nodes.\n"); + } } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java index a33a9d368fd..347a3e77ac7 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java @@ -34,27 +34,53 @@ public class IRNode { public static final String ALLOC = "(.*precise klass .*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_instance_Java" + END; public static final String ALLOC_OF = "(.*precise klass .*"; - private static final String ALLOC_OF_POSTFIX = ":.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_instance_Java" + END; public static final String ALLOC_ARRAY = "(.*precise klass \\[L.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_array_Java" + END; public static final String ALLOC_ARRAY_OF = "(.*precise klass \\[L.*"; - private static final String ALLOC_ARRAY_OF_POSTFIX = ";:.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_array_Java" + END; public static final String STORE = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + END; + public static final String STORE_B = START + "StoreB" + MID + END; + public static final String STORE_C = START + "StoreC" + MID + END; + public static final String STORE_I = START + "StoreI" + MID + END; // Store to short is also mapped to int + public static final String STORE_L = START + "StoreL" + MID + END; + public static final String STORE_F = START + "StoreF" + MID + END; + public static final String STORE_D = START + "StoreD" + MID + END; + public static final String STORE_P = START + "StoreP" + MID + END; + public static final String STORE_N = START + "StoreN" + MID + END; public static final String STORE_OF_CLASS = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@\\S*"; - private static final String STORE_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; + public static final String STORE_B_OF_CLASS = START + "StoreB" + MID + "@\\S*"; + public static final String STORE_C_OF_CLASS = START + "StoreC" + MID + "@\\S*"; + public static final String STORE_I_OF_CLASS = START + "StoreI" + MID + "@\\S*"; + public static final String STORE_L_OF_CLASS = START + "StoreL" + MID + "@\\S*"; + public static final String STORE_F_OF_CLASS = START + "StoreF" + MID + "@\\S*"; + public static final String STORE_D_OF_CLASS = START + "StoreD" + MID + "@\\S*"; + public static final String STORE_P_OF_CLASS = START + "StoreP" + MID + "@\\S*"; + public static final String STORE_N_OF_CLASS = START + "StoreN" + MID + "@\\S*"; public static final String STORE_OF_FIELD = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@.*name="; - private static final String STORE_OF_FIELD_POSTFIX = ",.*" + END; public static final String LOAD = START + "Load(B|S|I|L|F|D|P|N)" + MID + END; + public static final String LOAD_B = START + "LoadB" + MID + END; + public static final String LOAD_C = START + "LoadC" + MID + END; + public static final String LOAD_S = START + "LoadS" + MID + END; + public static final String LOAD_I = START + "LoadI" + MID + END; + public static final String LOAD_L = START + "LoadL" + MID + END; + public static final String LOAD_F = START + "LoadF" + MID + END; + public static final String LOAD_D = START + "LoadD" + MID + END; + public static final String LOAD_P = START + "LoadP" + MID + END; + public static final String LOAD_N = START + "LoadN" + MID + END; public static final String LOAD_OF_CLASS = START + "Load(B|C|S|I|L|F|D|P|N)" + MID + "@\\S*"; - private static final String LOAD_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; + public static final String LOAD_B_OF_CLASS = START + "LoadB" + MID + "@\\S*"; + public static final String LOAD_C_OF_CLASS = START + "LoadC" + MID + "@\\S*"; + public static final String LOAD_S_OF_CLASS = START + "LoadS" + MID + "@\\S*"; + public static final String LOAD_I_OF_CLASS = START + "LoadI" + MID + "@\\S*"; + public static final String LOAD_L_OF_CLASS = START + "LoadL" + MID + "@\\S*"; + public static final String LOAD_F_OF_CLASS = START + "LoadF" + MID + "@\\S*"; + public static final String LOAD_D_OF_CLASS = START + "LoadD" + MID + "@\\S*"; + public static final String LOAD_P_OF_CLASS = START + "LoadP" + MID + "@\\S*"; + public static final String LOAD_N_OF_CLASS = START + "LoadN" + MID + "@\\S*"; public static final String LOAD_OF_FIELD = START + "Load(B|C|S|I|L|F|D|P|N)" + MID + "@.*name="; - private static final String LOAD_OF_FIELD_POSTFIX = ",.*" + END; public static final String LOAD_KLASS = START + "LoadK" + MID + END; - - public static final String LOOP = START + "Loop" + MID + "" + END; public static final String COUNTEDLOOP = START + "CountedLoop\\b" + MID + "" + END; public static final String COUNTEDLOOP_MAIN = START + "CountedLoop\\b" + MID + "main" + END; @@ -69,26 +95,33 @@ public class IRNode { public static final String RANGE_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*range_check" + END; public static final String UNHANDLED_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*unhandled" + END; + public static final String SCOPE_OBJECT = "(.*# ScObj.*" + END; + + public static final String MEMBAR = START + "MemBar" + MID + END; + public static final String FIELD_ACCESS = "(.*Field: *" + END; + public static final String CHECKCAST_ARRAY = "(cmp.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*" + END; + public static final String CHECKCAST_ARRAYCOPY = "(.*call_leaf_nofp,runtime checkcast_arraycopy.*" + END; // Inline type allocation public static final String ALLOCA = "(.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_array_Java" + END; - public static final String LINKTOSTATIC = START + "CallStaticJava" + MID + "linkToStatic" + END; - public static final String NPE = START + "CallStaticJava" + MID + "null_check" + END; public static final String STORE_INLINE_FIELDS = START + "CallStaticJava" + MID + "store_inline_type_fields" + END; - public static final String SCOBJ = "(.*# ScObj.*" + END; public static final String LOAD_UNKNOWN_INLINE = "(.*call_leaf,runtime load_unknown_inline.*" + END; public static final String STORE_UNKNOWN_INLINE = "(.*call_leaf,runtime store_unknown_inline.*" + END; public static final String INLINE_ARRAY_NULL_GUARD = "(.*call,static wrapper for: uncommon_trap.*reason='null_check' action='none'.*" + END; public static final String INTRINSIC_SLOW_PATH = "(.*call,static wrapper for: uncommon_trap.*reason='intrinsic_or_type_checked_inlining'.*" + END; public static final String CLONE_INTRINSIC_SLOW_PATH = "(.*call,static.*java.lang.Object::clone.*" + END; - public static final String MEMBAR = START + "MemBar" + MID + END; - public static final String CHECKCAST_ARRAY = "(cmp.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*" + END; - public static final String CHECKCAST_ARRAYCOPY = "(.*call_leaf_nofp,runtime checkcast_arraycopy.*" + END; public static final String JLONG_ARRAYCOPY = "(.*call_leaf_nofp,runtime jlong_disjoint_arraycopy.*" + END; - public static final String FIELD_ACCESS = "(.*Field: *" + END; public static final String SUBSTITUTABILITY_TEST = START + "CallStaticJava" + MID + "java.lang.invoke.ValueBootstrapMethods::isSubstitutable" + END; + + private static final String ALLOC_OF_POSTFIX = ":.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_instance_Java" + END; + private static final String ALLOC_ARRAY_OF_POSTFIX = ";:.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_array_Java" + END; + private static final String STORE_OF_FIELD_POSTFIX = ",.*" + END; + private static final String STORE_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; + private static final String LOAD_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; + private static final String LOAD_OF_FIELD_POSTFIX = ",.*" + END; + static List mergeNodes(String[] nodes) { final List mergedNodes = new ArrayList<>(); for (int i = 0; i < nodes.length; i += 2) { @@ -96,7 +129,8 @@ static List mergeNodes(String[] nodes) { switch (node) { case ALLOC_OF -> mergeCompositeNodes(nodes, mergedNodes, i, node, ALLOC_OF_POSTFIX, "ALLOC_OF"); case ALLOC_ARRAY_OF -> mergeCompositeNodes(nodes, mergedNodes, i, node, ALLOC_ARRAY_OF_POSTFIX, "ALLOC_ARRAY_OF"); - case STORE_OF_CLASS -> mergeCompositeNodes(nodes, mergedNodes, i, node, STORE_OF_CLASS_POSTFIX, "STORE_OF_CLASS"); + case STORE_OF_CLASS, STORE_B_OF_CLASS, STORE_C_OF_CLASS, STORE_D_OF_CLASS, STORE_F_OF_CLASS, STORE_I_OF_CLASS, STORE_L_OF_CLASS, + STORE_N_OF_CLASS, STORE_P_OF_CLASS -> mergeCompositeNodes(nodes, mergedNodes, i, node, STORE_OF_CLASS_POSTFIX, "STORE_OF_CLASS"); case STORE_OF_FIELD -> mergeCompositeNodes(nodes, mergedNodes, i, node, STORE_OF_FIELD_POSTFIX, "STORE_OF_FIELD"); case LOAD_OF_CLASS -> mergeCompositeNodes(nodes, mergedNodes, i, node, LOAD_OF_CLASS_POSTFIX, "LOAD_OF_CLASS"); case LOAD_OF_FIELD -> mergeCompositeNodes(nodes, mergedNodes, i, node, LOAD_OF_FIELD_POSTFIX, "LOAD_OF_FIELD"); diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRViolationException.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRViolationException.java new file mode 100644 index 00000000000..81b5c331b72 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRViolationException.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021, 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.valhalla.framework; + +public class IRViolationException extends RuntimeException { + public IRViolationException(String message) { + super(message); + } +} diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java index 29f01db5f9c..0a60d18399d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java @@ -59,10 +59,11 @@ public static void reportIfAnyFailures() { StringBuilder builder = new StringBuilder(); builder.append("\nOne or more format violations have been detected:\n\n"); builder.append("Violations (").append(FAILURES.size()).append(")\n"); - builder.append("--------------\n"); + builder.append("-------------").append("-".repeat(String.valueOf(FAILURES.size()).length())).append("\n"); for (String failure : FAILURES) { builder.append(" - ").append(failure).append("\n"); } + builder.append("/============/"); FAILURES.clear(); throw new TestFormatException(builder.toString()); } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java index 50c574904ba..5ddc950d842 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java @@ -23,20 +23,24 @@ package compiler.valhalla.framework; -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.*; -import java.util.stream.Stream; - import jdk.test.lib.Asserts; +import jdk.test.lib.Platform; import jdk.test.lib.Utils; import jdk.test.lib.management.InputArguments; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import sun.hotspot.WhiteBox; -import jdk.test.lib.Platform; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Stream; public class TestFramework { @@ -75,7 +79,7 @@ public class TestFramework { private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false")) && Platform.isDebugBuild(); private static final String TESTLIST = System.getProperty("Testlist", ""); private static final String EXCLUDELIST = System.getProperty("Exclude", ""); - public static final int WARMUP_ITERATIONS = Integer.parseInt(System.getProperty("Warmup", "251")); + public static final int WARMUP_ITERATIONS = Integer.parseInt(System.getProperty("Warmup", "2000")); private static final boolean DUMP_REPLAY = Boolean.parseBoolean(System.getProperty("DumpReplay", "false")); private static final boolean GC_AFTER = Boolean.parseBoolean(System.getProperty("GCAfter", "false")); private static final boolean SHUFFLE_TESTS = Boolean.parseBoolean(System.getProperty("ShuffleTests", "true")); @@ -345,12 +349,32 @@ private void doRunWithScenarios() { for (Map.Entry entry: exceptionMap.entrySet()) { String title = "Stacktrace for Scenario #" + entry.getKey(); builder.append(title).append("\n").append("=".repeat(title.length())).append("\n"); - builder.append(entry.getValue().getMessage()).append("\n"); + Exception e = entry.getValue(); + if (e instanceof TestFormatException || e instanceof IRViolationException) { + // For format or IR violations, only show the actual message and not the (uninteresting) stack trace. + builder.append(e.getMessage()); + } else { + // Print stack trace if it was not a format violation or test run exception + StringWriter errors = new StringWriter(); + entry.getValue().printStackTrace(new PrintWriter(errors)); + builder.append(errors.toString()); + } + builder.append("\n"); } TestRun.fail(builder.toString()); } } + // Only called by tests testing the framework itself. Accessed by reflection. Do not expose this to normal users. + private static void runTestsOnSameVM(Class testClass) { + if (testClass == null) { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + testClass = walker.getCallerClass(); + } + TestFramework framework = new TestFramework(testClass); + framework.runTestsOnSameVM(); + } + private void runTestsOnSameVM() { if (helperClasses != null) { for (Class helperClass : helperClasses) { @@ -362,16 +386,6 @@ private void runTestsOnSameVM() { runTests(); } - // Only called by tests testing the framework itself. Accessed by reflection. Do not expose this to normal users. - private static void runTestsOnSameVM(Class testClass) { - if (testClass == null) { - StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - testClass = walker.getCallerClass(); - } - TestFramework framework = new TestFramework(testClass); - framework.runTestsOnSameVM(); - } - private void runTestVM(Scenario scenario) { if (scenario != null && !scenario.isEnabled()) { System.out.println("Disabled scenario #" + scenario.getIndex() + "! This scenario is not present in set flag -DScenarios " + @@ -393,11 +407,15 @@ private void runTestVM(Scenario scenario) { scenario.setVMOutput(output); } - if (VERBOSE || oa.getExitValue() != 0) { + final int exitCode = oa.getExitValue(); + if (VERBOSE || exitCode != 0) { System.out.println(" ----- OUTPUT -----"); System.out.println(output); + + } + if (exitCode != 0) { + throwTestException(oa, exitCode); } - oa.shouldHaveExitValue(0); if (VERIFY_IR) { IRMatcher irMatcher = new IRMatcher(output, testClass); @@ -429,7 +447,7 @@ private ArrayList prepareTestVmFlags(Scenario scenario) { // TODO: Only for debugging if (cmds.get(0).startsWith("-agentlib")) { - cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=y,server=y"); + cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=n,server=y"); } if (PREFER_COMMAND_LINE_FLAGS) { @@ -474,6 +492,18 @@ private void addBoolOptionForClass(ArrayList cmds, Class testClass, S cmds.add("-XX:CompileCommand=option," + testClass.getCanonicalName() + "::*,bool," + option + ",true"); } + private void throwTestException(OutputAnalyzer oa, int exitCode) { + String stdErr = oa.getStderr(); + if (stdErr.contains("TestFormat.reportIfAnyFailures")) { + Pattern pattern = Pattern.compile("Violations \\(\\d+\\)[\\s\\S]*(?=/============/)"); + Matcher matcher = pattern.matcher(stdErr); + TestFramework.check(matcher.find(), "Must find violation matches"); + throw new TestFormatException("\n\n" + matcher.group()); + } else { + throw new TestRunException("\nVM exited with " + exitCode + "\n\nError Output:\n" + stdErr); + } + } + private void parseTestClass() { addReplay(); processExplicitCompileCommands(testClass); @@ -866,7 +896,7 @@ private void runTests() { static void check(boolean test, String failureMessage) { if (!test) { - throw new TestFrameworkException("Internal TestFramework exception:\n" + failureMessage); + throw new TestFrameworkException("Internal TestFramework exception - please file a bug:\n" + failureMessage); } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java index af34372b619..391c7ed8157 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java @@ -150,6 +150,26 @@ public void notNumber7(boolean a, boolean b) {} @Test @Arguments(Argument.DEFAULT) public void missingDefaultConstructor(ClassNoDefaultConstructor a) {} + + @Test + @Arguments(Argument.TRUE) + public void wrongArgumentNumberWithRun(Object o1, Object o2) { + } + + // Also fails: Cannot use @Arguments together with @Run + @Run(test="wrongArgumentNumberWithRun") + public void forRun() { + } + + @Test + @Arguments(Argument.TRUE) + public void wrongArgumentNumberWithCheck(Object o1, Object o2) { + } + + @NoFail + @Check(test="wrongArgumentNumberWithCheck") + public void forCheck() { + } } class BadOverloadedMethod { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java index 16fad10517e..ee828c95bfd 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java @@ -29,95 +29,152 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; public class TestIRMatching { public static void main(String[] args) { -// runFailOnTests(Constraint.failOnMatches(AndOr1.class, "test1(int)", 1, true,"CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:+UsePerfData", "-XX:+UseTLAB"); -// runFailOnTests(Constraint.failOnMatches(AndOr1.class, "test2()", 1, true,"CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:-UsePerfData", "-XX:+UseTLAB"); -// -// runWithArguments(AndOr1.class, "-XX:SuspendRetryCount=52", "-XX:+UsePerfData", "-XX:+UseTLAB"); -// -// runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=50"); -// findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 0, 21); -// findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", -1, -1); -// -// runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=49"); -// findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 4, 6, 13, 18); -// findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); -// -// runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=51"); -// findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 7, 12, 19, 21); -// findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 4, 7, 11, 16, 20, 22); -// -// runWithArguments(MultipleFailOnGood.class, "-XX:SuspendRetryCount=50"); -// -// runFailOnTests(Constraint.failOnMatches(MultipleFailOnBad.class, "fail1()", 1,true, "Store"), -// Constraint.failOnMatches(MultipleFailOnBad.class, "fail2()", 1,true, "CallStaticJava"), -// Constraint.failOnMatches(MultipleFailOnBad.class, "fail3()", 1,true, "Store"), -// Constraint.failOnMatches(MultipleFailOnBad.class, "fail4()", 1,true, "Store"), -// Constraint.failOnMatches(MultipleFailOnBad.class, "fail5()", 1,true, "Store", "iFld"), -// Constraint.failOnAlloc(MultipleFailOnBad.class, "fail6()", 1,true, "MyClass"), -// Constraint.failOnAlloc(MultipleFailOnBad.class, "fail7()", 1,true, "MyClass"), -// Constraint.failOnAlloc(MultipleFailOnBad.class, "fail8()", 1,true, "MyClass"), -// Constraint.failOnMatches(MultipleFailOnBad.class, "fail9()", 1,true, "Store", "CallStaticJava"), -// Constraint.failOnMatches(MultipleFailOnBad.class, "fail10()", 1,true, "Store", "iFld")); -// -// runWithArguments(CountComparisons.class, "-XX:SuspendRetryCount=50"); -// runWithArguments(GoodCount.class, "-XX:SuspendRetryCount=50"); -// runFailOnTests(Constraint.countsMatches(BadCount.class, "bad1()", 1,true), -// Constraint.countsMatches(BadCount.class, "bad1()", 2,false), -// Constraint.countsMatches(BadCount.class, "bad2()", 1,false), -// Constraint.countsMatches(BadCount.class, "bad2()", 2,true), -// Constraint.countsMatches(BadCount.class, "bad3()", 1,true), -// Constraint.countsMatches(BadCount.class, "bad3()", 2,true)); -// -// runFailOnTests(Constraint.failOnArrayAlloc(AllocArray.class, "allocArray()", 1, true, "MyClass"), -// Constraint.failOnArrayAlloc(AllocArray.class, "allocArray()", 2, true, "MyClass"), -// Constraint.failOnArrayAlloc(AllocArray.class, "allocArray()", 3, false, "MyClass"), -// Constraint.failOnArrayAlloc(AllocArray.class, "allocArray()", 4, false, "MyClass"), -// Constraint.failOnArrayAlloc(AllocArray.class, "allocArray()", 5, true, "MyClass")); -// -// runFailOnTests(new String[] {"-XX:-UseCompressedClassPointers"}, -// Constraint.failOnMatches(Loads.class, "load()", 1, true, "Load"), -// Constraint.failOnMatches(Loads.class, "load()", 2, true, "Loads"), -// Constraint.failOnMatches(Loads.class, "load()", 3, true, "Loads"), -// Constraint.failOnMatches(Loads.class, "load()", 4, true, "Load", "iFld"), -// Constraint.failOnMatches(Loads.class, "load()", 5, false, "Load"), -// Constraint.failOnMatches(Loads.class, "load()", 6, false, "LoadKlass"), -// Constraint.failOnMatches(Loads.class, "loadKlass()", 1, false, "LoadKlass")); -// -// runFailOnTests(Constraint.failOnMatches(Loops.class, "loop()", 1, true, "Loop"), -// Constraint.failOnMatches(Loops.class, "loop()", 2, false, "CountedLoop"), -// Constraint.failOnMatches(Loops.class, "loop()", 3, false, "CountedLoop", "main"), -// Constraint.failOnMatches(Loops.class, "countedLoop()", 1, false, "Loop"), -// Constraint.failOnMatches(Loops.class, "countedLoop()", 2, true, "CountedLoop"), -// Constraint.failOnMatches(Loops.class, "countedLoop()", 3, false, "CountedLoop", "main"), -// Constraint.failOnMatches(Loops.class, "loopAndCountedLoop()", 1, true, "Loop"), -// Constraint.failOnMatches(Loops.class, "loopAndCountedLoop()", 2, true, "CountedLoop"), -// Constraint.failOnMatches(Loops.class, "loopAndCountedLoop()", 3, false, "CountedLoop", "main"), -// Constraint.failOnMatches(Loops.class, "countedLoopMain()", 1, false, "Loop"), -// Constraint.failOnMatches(Loops.class, "countedLoopMain()", 2, true, "CountedLoop"), -// Constraint.failOnMatches(Loops.class, "countedLoopMain()", 3, true, "CountedLoop", "main")); - runFailOnTests(Constraint.failOnMatches(Traps.class, "traps()", 1, true, "CallStaticJava", "uncommon_trap"), - Constraint.failOnMatches(Traps.class, "traps()", 2, true, "CallStaticJava", "uncommon_trap", "predicate"), - Constraint.failOnMatches(Traps.class, "traps()", 3, false, "Store", "iFld"), - Constraint.failOnMatches(Traps.class, "noTraps()", 1, false, "CallStaticJava", "uncommon_trap"), - Constraint.failOnMatches(Traps.class, "noTraps()", 2, true, "Store", "iFld"), - Constraint.failOnMatches(Traps.class, "nullCheck()", 1, true, "CallStaticJava", "uncommon_trap"), - Constraint.failOnMatches(Traps.class, "nullCheck()", 2, true, "CallStaticJava", "uncommon_trap", "null_check") - ); - + runFailOnTestsArgs(BadFailOnConstraint.create(AndOr1.class, "test1(int)", 1, "CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:+UsePerfData", "-XX:+UseTLAB"); + runFailOnTestsArgs(BadFailOnConstraint.create(AndOr1.class, "test2()", 1, "CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:-UsePerfData", "-XX:+UseTLAB"); + + runWithArguments(AndOr1.class, "-XX:SuspendRetryCount=52", "-XX:+UsePerfData", "-XX:+UseTLAB"); + runWithArguments(CountComparisons.class, "-XX:SuspendRetryCount=50"); + runWithArguments(GoodCount.class, "-XX:SuspendRetryCount=50"); + runWithArguments(MultipleFailOnGood.class, "-XX:SuspendRetryCount=50"); + + runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=50"); + findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 0, 21); + findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", -1, -1); + + runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=49"); + findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 4, 6, 13, 18); + findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); + + runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=51"); + findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 7, 12, 19, 21); + findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 4, 7, 11, 16, 20, 22); + + String[] allocMatches = { "MyClass", "call,static wrapper for: _new_instance_Java" }; + runCheck(BadFailOnConstraint.create(MultipleFailOnBad.class, "fail1()", 1, 1, "Store"), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail1()", 1, 3, "Store"), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail1()", 1, 2, 4), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail2()", 1, 1), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail2()", 1, 2, "CallStaticJava"), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail3()", 1, 2, "Store"), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail3()", 1, 1, 3), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail4()", 1, 1, "Store"), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail4()", 1, 2, 3), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail5()", 1, 1, "Store"), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail5()", 1, 2, 3), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail6()", 1, 1), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail6()", 1, 2, allocMatches), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail6()", 1, 3, "CallStaticJava"), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail7()", 1, 1), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail7()", 1, 2, allocMatches), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail8()", 1, 1), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail8()", 1, 2, allocMatches), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail9()", 1, 1, "Store"), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail9()", 1, 2, "CallStaticJava"), + BadFailOnConstraint.create(MultipleFailOnBad.class, "fail10()", 1, 1, "Store", "iFld"), + GoodFailOnRegexConstraint.create(MultipleFailOnBad.class, "fail10()", 1, 2, 3) + ); + + runCheck(BadCountsConstraint.create(BadCount.class, "bad1()", 1, 1, "Load"), + GoodCountsConstraint.create(BadCount.class, "bad1()", 2), + GoodCountsConstraint.create(BadCount.class, "bad2()", 1), + BadCountsConstraint.create(BadCount.class, "bad2()", 2, 1, "Store"), + BadCountsConstraint.create(BadCount.class, "bad3()", 1, 1, "Load"), + BadCountsConstraint.create(BadCount.class, "bad3()", 2, 1, "Store") + ); + + String[] allocArrayMatches = { "MyClass", "call,static wrapper for: _new_array_Java"}; + runCheck(BadFailOnConstraint.create(AllocArray.class, "allocArray()", 1, allocArrayMatches), + BadFailOnConstraint.create(AllocArray.class, "allocArray()", 2, allocArrayMatches), + GoodFailOnConstraint.create(AllocArray.class, "allocArray()", 3), + GoodFailOnConstraint.create(AllocArray.class, "allocArray()", 4), + BadFailOnConstraint.create(AllocArray.class, "allocArray()", 5, allocArrayMatches) + ); + + runCheck(new String[] {"-XX:-UseCompressedClassPointers"}, + BadFailOnConstraint.create(Loads.class, "load()", 1, 1, "Load"), + BadFailOnConstraint.create(Loads.class, "load()", 1, 3, "LoadI"), + BadCountsConstraint.create(Loads.class, "load()", 1, 1, 0), + BadCountsConstraint.create(Loads.class, "load()", 1, 2, 1,"Load"), + GoodRuleConstraint.create(Loads.class, "load()", 2), + GoodFailOnConstraint.create(Loads.class, "load()", 3), + BadCountsConstraint.create(Loads.class, "load()", 3, 2, 2,"Store"), + BadFailOnConstraint.create(Loads.class, "load()", 4, 2, "Store"), + BadFailOnConstraint.create(Loads.class, "load()", 5, "Load"), + BadFailOnConstraint.create(Loads.class, "load()", 6, "Load"), + BadFailOnConstraint.create(Loads.class, "load()", 7, "Load"), + GoodRuleConstraint.create(Loads.class, "load()", 8), + GoodRuleConstraint.create(Loads.class, "load()", 9), + BadFailOnConstraint.create(Loads.class, "loadKlass()", 1) + ); + + // Loops + runCheck(BadFailOnConstraint.create(Loops.class, "loop()", 1, "Loop"), + GoodRuleConstraint.create(Loops.class, "loop()", 2), + GoodRuleConstraint.create(Loops.class, "loop()", 3), + GoodRuleConstraint.create(Loops.class, "countedLoop()", 1), + BadFailOnConstraint.create(Loops.class, "countedLoop()", 2, "CountedLoop"), + GoodRuleConstraint.create(Loops.class, "countedLoop()", 3), + BadFailOnConstraint.create(Loops.class, "loopAndCountedLoop()", 1, "Loop"), + BadFailOnConstraint.create(Loops.class, "loopAndCountedLoop()", 2, "CountedLoop"), + GoodRuleConstraint.create(Loops.class, "loopAndCountedLoop()", 3), + GoodRuleConstraint.create(Loops.class, "countedLoopMain()", 1), + BadFailOnConstraint.create(Loops.class, "countedLoopMain()", 2, "CountedLoop"), + BadFailOnConstraint.create(Loops.class, "countedLoopMain()", 3, "CountedLoop", "main"), + GoodRuleConstraint.create(Loops.class, "countedLoopUnrolled()", 1), + GoodRuleConstraint.create(Loops.class, "countedLoopUnrolled()", 2), + GoodRuleConstraint.create(Loops.class, "countedLoopUnrolled()", 3) + ); + + // Traps + runCheck(GoodRuleConstraint.create(Traps.class, "noTraps()", 1), + BadFailOnConstraint.create(Traps.class, "noTraps()", 2, "Store", "iFld"), + GoodRuleConstraint.create(Traps.class, "noTraps()", 3), + BadFailOnConstraint.create(Traps.class, "predicateTrap()", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(Traps.class, "predicateTrap()", 2, "CallStaticJava", "uncommon_trap", "predicate"), + GoodRuleConstraint.create(Traps.class, "predicateTrap()", 3), + GoodRuleConstraint.create(Traps.class, "predicateTrap()", 4), + BadFailOnConstraint.create(Traps.class, "nullCheck()", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(Traps.class, "nullCheck()", 2, "CallStaticJava", "uncommon_trap", "null_check"), + BadFailOnConstraint.create(Traps.class, "nullCheck()", 3, "uncommon_trap", "unstable_if"), + GoodRuleConstraint.create(Traps.class, "nullCheck()", 4), + BadFailOnConstraint.create(Traps.class, "nullAssert()", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(Traps.class, "nullAssert()", 2, "CallStaticJava", "uncommon_trap", "null_assert"), + BadFailOnConstraint.create(Traps.class, "nullAssert()", 3, "CallStaticJava", "uncommon_trap", "null_check"), + GoodRuleConstraint.create(Traps.class, "nullAssert()", 4), + BadFailOnConstraint.create(Traps.class, "unstableIf(boolean)", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(Traps.class, "unstableIf(boolean)", 2, "CallStaticJava", "uncommon_trap", "unstable_if"), + GoodRuleConstraint.create(Traps.class, "unstableIf(boolean)", 3), + BadFailOnConstraint.create(Traps.class, "classCheck()", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(Traps.class, "classCheck()", 2, "CallStaticJava", "uncommon_trap", "class_check"), + BadFailOnConstraint.create(Traps.class, "classCheck()", 3, "CallStaticJava", "uncommon_trap", "null_check"), + GoodRuleConstraint.create(Traps.class, "classCheck()", 4), + BadFailOnConstraint.create(Traps.class, "rangeCheck()", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(Traps.class, "rangeCheck()", 2, "CallStaticJava", "uncommon_trap", "range_check"), + BadFailOnConstraint.create(Traps.class, "rangeCheck()", 3, "CallStaticJava", "uncommon_trap", "null_check"), + GoodRuleConstraint.create(Traps.class, "rangeCheck()", 4) + ); + + + runCheck(new String[] {"-XX:+BailoutToInterpreterForThrows"}, + BadFailOnConstraint.create(UnhandledTrap.class, "unhandled()", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(UnhandledTrap.class, "unhandled()", 2, "CallStaticJava", "uncommon_trap", "unhandled"), + GoodRuleConstraint.create(UnhandledTrap.class, "unhandled()", 3) + ); + + runCheck(BadFailOnConstraint.create(ScopeObj.class, "scopeObject()", 1, "ScObj")); } private static void runWithArguments(Class clazz, String... args) { TestFramework.runWithScenarios(clazz, new Scenario(0, args)); } - private static void runFailOnTests(String[] args , Constraint... constraints) { + private static void runCheck(String[] args , Constraint... constraints) { try { Scenario s = new Scenario(0, args); TestFramework.runWithScenarios(constraints[0].getKlass(), s); // All constraints have the same class. @@ -129,7 +186,7 @@ private static void runFailOnTests(String[] args , Constraint... constraints) { } } - private static void runFailOnTests(Constraint... constraints) { + private static void runCheck(Constraint... constraints) { try { TestFramework.run(constraints[0].getKlass()); // All constraints have the same class. shouldNotReach(); @@ -143,17 +200,6 @@ private static void runFailOnTests(Constraint... constraints) { private static void checkConstraints(RuntimeException e, Constraint[] constraints) { String message = e.getMessage(); try { - long expectedFailures = Arrays.stream(constraints).filter(Constraint::shouldMatch).count(); - Pattern pattern = Pattern.compile("Failures \\((\\d+)\\)"); - Matcher matcher = pattern.matcher(message); - if (expectedFailures > 0) { - Asserts.assertTrue(matcher.find(), "Could not find failures"); - long foundFailuresCount = Long.parseLong(matcher.group(1)); - Asserts.assertEQ(foundFailuresCount, expectedFailures); - } else { - Asserts.assertFalse(matcher.find(), "Should not have found failures"); - } - for (Constraint constraint : constraints) { constraint.checkConstraint(e); } @@ -165,7 +211,7 @@ private static void checkConstraints(RuntimeException e, Constraint[] constraint } // Single constraint - private static void runFailOnTests(Constraint constraint, String... args) { + private static void runFailOnTestsArgs(Constraint constraint, String... args) { try { Scenario scenario = new Scenario(0, args); TestFramework.runWithScenarios(constraint.getKlass(), scenario); // All constraints have the same class. @@ -267,16 +313,16 @@ public void good7() { } @ForceInline - private void forceInline() { - } + private void forceInline() {} } class MultipleFailOnBad { private int iFld; private int myInt; private MyClass myClass; + @Test - @IR(failOn = {IRNode.STORE, IRNode.CALL}) + @IR(failOn = {IRNode.STORE, IRNode.CALL, IRNode.STORE_I, IRNode.LOOP}) public void fail1() { iFld = 42; } @@ -306,7 +352,7 @@ public void fail5() { } @Test - @IR(failOn = {IRNode.STORE_OF_CLASS, "MyClass", IRNode.ALLOC}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "MyClass", IRNode.ALLOC, IRNode.CALL}) public void fail6() { myClass = new MyClass(); } @@ -338,8 +384,7 @@ public void fail10() { } @DontInline - private void dontInline() { - } + private void dontInline() {} } // Called with -XX:SuspendRetryCount=X. @@ -368,8 +413,7 @@ class FlagComparisons { @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!=49"}) @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!= 49"}) @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " != 49"}) // Index 21 - public void testMatchAllIf50() { - } + public void testMatchAllIf50() {} // Applies no IR rules if SuspendRetryCount=50 @Test @@ -396,8 +440,7 @@ public void testMatchAllIf50() { @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!=50"}) @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!= 50"}) @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " != 50"}) // Index 22 - public void testMatchNoneIf50() { - } + public void testMatchNoneIf50() {} } class CountComparisons { @@ -435,47 +478,98 @@ public void countComparison() { } class GoodCount { + boolean flag; + char cFld; + byte bFld; + short sFld; int iFld; - int iFld2; + long lFld; + float fFld; + double dFld; + long x; + long result; MyClass myClass = new MyClass(); MyClass myClassSubPoly = new MyClassSub(); MyClassSub myClassSub = new MyClassSub(); @Test - @IR(counts = {IRNode.STORE, "1"}) + @IR(counts = {IRNode.STORE, "1", IRNode.STORE_I, "1"}, + failOn = {IRNode.STORE_B, IRNode.STORE_C, IRNode.STORE_D, + IRNode.STORE_F, IRNode.STORE_L}) public void good1() { iFld = 3; } @Test - @IR(counts = {IRNode.STORE, "2"}) + @IR(counts = {IRNode.STORE, "8", + IRNode.STORE_B, "2", // bFld + flag + IRNode.STORE_C, "2", // cFld + sFld + IRNode.STORE_I, "1", + IRNode.STORE_L, "1", + IRNode.STORE_F, "1", + IRNode.STORE_D, "1"}) public void good2() { + flag = true; + cFld = 'a'; + bFld = 1; + sFld = 2; iFld = 3; - iFld2 = 4; + lFld = 4L; + fFld = 5.0f; + dFld = 6.0; } @Test - @IR(counts = {IRNode.STORE, "2", IRNode.STORE_OF_CLASS, "GoodCount", "2"}) + @IR(counts = {IRNode.STORE, "8", IRNode.STORE_OF_CLASS, "GoodCount", "8", + IRNode.STORE_B, "2", IRNode.STORE_B_OF_CLASS, "GoodCount", "2", + IRNode.STORE_C, "2", IRNode.STORE_C_OF_CLASS, "GoodCount", "2", + IRNode.STORE_I, "1", IRNode.STORE_I_OF_CLASS, "GoodCount", "1", + IRNode.STORE_L, "1", IRNode.STORE_L_OF_CLASS, "GoodCount", "1", + IRNode.STORE_F, "1", IRNode.STORE_F_OF_CLASS, "GoodCount", "1", + IRNode.STORE_D, "1", IRNode.STORE_D_OF_CLASS, "GoodCount", "1"}) public void good3() { + flag = true; + cFld = 'a'; + bFld = 1; + sFld = 2; iFld = 3; - iFld2 = 4; + lFld = 4L; + fFld = 5.0f; + dFld = 6.0; } @Test - @IR(counts = {IRNode.STORE_OF_FIELD, "iFld", "1", IRNode.STORE, "2", IRNode.STORE_OF_CLASS, "GoodCount", "2"}) + @IR(counts = {IRNode.STORE, "8", IRNode.STORE_OF_CLASS, "GoodCount", "8", + IRNode.STORE_B, "2", IRNode.STORE_B_OF_CLASS, "GoodCount", "2", + IRNode.STORE_C, "2", IRNode.STORE_C_OF_CLASS, "GoodCount", "2", + IRNode.STORE_I, "1", IRNode.STORE_I_OF_CLASS, "GoodCount", "1", + IRNode.STORE_L, "1", IRNode.STORE_L_OF_CLASS, "GoodCount", "1", + IRNode.STORE_F, "1", IRNode.STORE_F_OF_CLASS, "GoodCount", "1", + IRNode.STORE_D, "1", IRNode.STORE_D_OF_CLASS, "GoodCount", "1", + IRNode.STORE_OF_FIELD, "lFld", "1"}) public void good4() { + flag = true; + cFld = 'a'; + bFld = 1; + sFld = 2; iFld = 3; - iFld2 = 4; + lFld = 4L; + fFld = 5.0f; + dFld = 6.0; } @Test - @IR(counts = {IRNode.STORE_OF_FIELD, "iFld", "2", IRNode.STORE, "2", IRNode.STORE_OF_CLASS, "GoodCount", "1", + @IR(counts = {IRNode.STORE, "2", IRNode.STORE_I, "1", IRNode.STORE_L, "1", + IRNode.STORE_OF_CLASS, "GoodCount", "1", IRNode.STORE_L_OF_CLASS, "GoodCount", "1", IRNode.STORE_OF_CLASS, "compiler/valhalla/framework/tests/MyClass", "1", - IRNode.STORE_OF_CLASS, "framework/tests/GoodCount", "1"}) + IRNode.STORE_I_OF_CLASS, "compiler/valhalla/framework/tests/MyClass", "1", + IRNode.STORE_OF_CLASS, "framework/tests/GoodCount", "1", + IRNode.STORE_L_OF_CLASS, "framework/tests/GoodCount", "1", + IRNode.STORE_OF_FIELD, "x", "2"}) public void good5() { - iFld = 3; - myClass.iFld = 4; + x = 3; // long + myClass.x = 4; // int } @Test @@ -540,14 +634,31 @@ public void bad3() { } } + +class AllocArray { + MyClass[] myClassArray; + + @Test + @IR(failOn = {IRNode.ALLOC_ARRAY}) + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClass"}) + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClasss"}) // Does not fail + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/valhalla/framework/tests/MySubClass"}) // Does not fail + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/valhalla/framework/tests/MyClass"}) + public void allocArray() { + myClassArray = new MyClass[2]; + } +} + class Loads { int iFld = 34; int result = 0; - Object[] myClassArr = new MyClass[3]; Object myClass = new MyClass(); @Test - @IR(failOn = {IRNode.LOAD}) + @IR(failOn = {IRNode.LOAD, IRNode.LOOP, IRNode.LOAD_I}, counts = {IRNode.LOOP, "2", IRNode.LOAD, "2", IRNode.STORE, "2"}) + @IR(failOn = {IRNode.LOOP, IRNode.LOOP}, counts = {IRNode.LOOP, "0", IRNode.LOAD, "1"}) // Does not fail + @IR(failOn = {IRNode.LOOP, IRNode.LOOP}, counts = {IRNode.LOOP, "0", IRNode.STORE, "1"}) + @IR(failOn = {IRNode.LOOP, IRNode.STORE}, counts = {IRNode.LOOP, "0", IRNode.LOAD, "1"}) @IR(failOn = {IRNode.LOAD_OF_CLASS, "compiler/valhalla/framework/tests/Loads"}) @IR(failOn = {IRNode.LOAD_OF_CLASS, "Loads"}) @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld"}) @@ -555,6 +666,7 @@ class Loads { @IR(failOn = {IRNode.LOAD_KLASS}) // Does not fail public void load() { result = iFld; + iFld = 3; } @Test @@ -566,20 +678,6 @@ public void loadKlass() { } } -class AllocArray { - MyClass[] myClassArray; - - @Test - @IR(failOn = {IRNode.ALLOC_ARRAY}) - @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClass"}) - @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClasss"}) // Does not fail - @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/valhalla/framework/tests/MySubClass"}) // Does not fail - @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/valhalla/framework/tests/MyClass"}) - public void allocArray() { - myClassArray = new MyClass[2]; - } -} - class Loops { int limit = 1024; int[] iArr = new int[100]; @@ -620,8 +718,8 @@ public void loopAndCountedLoop() { } @Test - @IR(failOn = IRNode.LOOP) // fails - @IR(failOn = IRNode.COUNTEDLOOP) + @IR(failOn = IRNode.LOOP) + @IR(failOn = IRNode.COUNTEDLOOP) // fails @IR(failOn = IRNode.COUNTEDLOOP_MAIN) // fails public void countedLoopMain() { // Cannot unroll completely -> create pre/main/post @@ -631,7 +729,7 @@ public void countedLoopMain() { } @Test - @IR(failOn = IRNode.LOOP) // fails + @IR(failOn = IRNode.LOOP) @IR(failOn = IRNode.COUNTEDLOOP) @IR(failOn = IRNode.COUNTEDLOOP_MAIN) public void countedLoopUnrolled() { @@ -644,29 +742,45 @@ public void countedLoopUnrolled() { class Traps { int number42 = 42; - int iFld = 42; + int iFld = 10; + int[] iArr = new int[2]; MyClass myClass = new MyClass(); + MyClassSub myClassSub = new MyClassSub(); + NotLoaded notLoaded = new NotLoaded(); @Test - @IR(failOn = IRNode.TRAP) // fails - @IR(failOn = IRNode.PREDICATE_TRAP) // fails - @IR(failOn = {IRNode.STORE_OF_FIELD, "iFld"}) - public void traps() { + @IR(failOn = IRNode.TRAP) + @IR(failOn = {IRNode.STORE_OF_FIELD, "iFld"}) // fails + @IR(failOn = {IRNode.PREDICATE_TRAP, + IRNode.UNSTABLE_IF_TRAP, + IRNode.NULL_CHECK_TRAP, + IRNode.NULL_ASSERT_TRAP, + IRNode.RANGE_CHECK_TRAP, + IRNode.CLASS_CHECK_TRAP, + IRNode.UNHANDLED_TRAP}) + public void noTraps() { for (int i = 0; i < 100; i++) { - if (number42 != 42) { - // Never reached + if (i < 42) { + // Reached, no uncommon trap iFld = i; } } } @Test - @IR(failOn = IRNode.TRAP) - @IR(failOn = {IRNode.STORE_OF_FIELD, "iFld"}) // fails - public void noTraps() { + @IR(failOn = IRNode.TRAP) // fails + @IR(failOn = IRNode.PREDICATE_TRAP) // fails + @IR(failOn = {IRNode.STORE_OF_FIELD, "iFld"}) + @IR(failOn = {IRNode.UNSTABLE_IF_TRAP, + IRNode.NULL_CHECK_TRAP, + IRNode.NULL_ASSERT_TRAP, + IRNode.RANGE_CHECK_TRAP, + IRNode.CLASS_CHECK_TRAP, + IRNode.UNHANDLED_TRAP}) + public void predicateTrap() { for (int i = 0; i < 100; i++) { - if (i < 42) { - // Reached, no uncommon trap + if (number42 != 42) { + // Never reached iFld = i; } } @@ -675,117 +789,423 @@ public void noTraps() { @Test @IR(failOn = IRNode.TRAP) // fails @IR(failOn = IRNode.NULL_CHECK_TRAP) // fails + @IR(failOn = IRNode.UNSTABLE_IF_TRAP) // fails + @IR(failOn = {IRNode.PREDICATE_TRAP, + IRNode.NULL_ASSERT_TRAP, + IRNode.RANGE_CHECK_TRAP, + IRNode.CLASS_CHECK_TRAP, + IRNode.UNHANDLED_TRAP}) public void nullCheck() { if (myClass instanceof MyClassSub) { iFld = 4; } } + + @Test + @IR(failOn = IRNode.TRAP) // fails + @IR(failOn = IRNode.NULL_ASSERT_TRAP) // fails + @IR(failOn = IRNode.NULL_CHECK_TRAP) // fails + @IR(failOn = {IRNode.PREDICATE_TRAP, + IRNode.UNSTABLE_IF_TRAP, + IRNode.RANGE_CHECK_TRAP, + IRNode.CLASS_CHECK_TRAP, + IRNode.UNHANDLED_TRAP}) + public Object nullAssert() { + return notLoaded.notLoadedFld; + } + + @Test + @Arguments(Argument.TRUE) + @IR(failOn = IRNode.TRAP) // fails + @IR(failOn = IRNode.UNSTABLE_IF_TRAP) // fails + @IR(failOn = {IRNode.PREDICATE_TRAP, + IRNode.NULL_CHECK_TRAP, + IRNode.NULL_ASSERT_TRAP, + IRNode.RANGE_CHECK_TRAP, + IRNode.CLASS_CHECK_TRAP, + IRNode.UNHANDLED_TRAP}) + public void unstableIf(boolean flag) { + if (flag) { + iFld++; + } else { + iFld--; + } + } + + @Test + @IR(failOn = IRNode.TRAP) // fails + @IR(failOn = IRNode.CLASS_CHECK_TRAP) // fails + @IR(failOn = IRNode.NULL_CHECK_TRAP) // fails + @IR(failOn = {IRNode.PREDICATE_TRAP, + IRNode.UNSTABLE_IF_TRAP, + IRNode.NULL_ASSERT_TRAP, + IRNode.RANGE_CHECK_TRAP, + IRNode.UNHANDLED_TRAP}) + public void classCheck() { + try { + myClassSub = (MyClassSub) myClass; + } catch (ClassCastException e) { + // Expected + } + } + + @Test + @IR(failOn = IRNode.TRAP) // fails + @IR(failOn = IRNode.RANGE_CHECK_TRAP) // fails + @IR(failOn = IRNode.NULL_CHECK_TRAP) // fails + @IR(failOn = {IRNode.PREDICATE_TRAP, + IRNode.UNSTABLE_IF_TRAP, + IRNode.NULL_ASSERT_TRAP, + IRNode.CLASS_CHECK_TRAP, + IRNode.UNHANDLED_TRAP}) + public void rangeCheck() { + iArr[1] = 3; + } +} + +class UnhandledTrap { + int iFld = 34; + + @Test + @IR(failOn = IRNode.TRAP) // fails + @IR(failOn = IRNode.UNHANDLED_TRAP) // fails + @IR(failOn = {IRNode.PREDICATE_TRAP, + IRNode.UNSTABLE_IF_TRAP, + IRNode.NULL_CHECK_TRAP, + IRNode.NULL_ASSERT_TRAP, + IRNode.RANGE_CHECK_TRAP, + IRNode.CLASS_CHECK_TRAP}) + public void unhandled() { + try { + throw new RuntimeException(); + } catch (RuntimeException e) { + // Expected + } + } +} + +class ScopeObj { + + @DontInline + public void dontInline(int i) {} + + @Test + @IR(failOn = IRNode.SCOPE_OBJECT) // fails + public int scopeObject() { + MyClass myClass = new MyClass(); + for (int i = 0; i < 100; i++) { + dontInline(myClass.iFld); + } + return 3; + } } +// Used only by class Traps +class NotLoaded { + NotLoadedHelper notLoadedFld; +} + +// Used only by class Traps +class NotLoadedHelper {} + class MyClass { - int iFld; + int iFld = 3; + int x = 5; static long lFldStatic; } + class MyClassSub extends MyClass { int iFld; static int iFldStatic; } -enum FailType { - FAIL_ON, COUNTS +class ShouldNotReachException extends RuntimeException { + ShouldNotReachException(String s) { + super(s); + } } -class Constraint { + +// Base class for any kind of constraint that is used to verify if the framework reports the correct IR failures. +abstract class Constraint { private final Class klass; - private final int ruleIdx; - private final Pattern irPattern; - private final List matches; + protected final int ruleIdx; private final Pattern methodPattern; private final String classAndMethod; - private final FailType failType; - private final boolean shouldMatch; + protected final Pattern irPattern; + private final String methodName; + protected boolean matched; - private Constraint(Class klass, String methodName, int ruleIdx, FailType failType, List matches, boolean shouldMatch) { + Constraint(Class klass, String methodName, int ruleIdx, Pattern irPattern) { this.klass = klass; classAndMethod = klass.getSimpleName() + "." + methodName; this.ruleIdx = ruleIdx; - this.failType = failType; this.methodPattern = Pattern.compile(Pattern.quote(classAndMethod)); - if (failType == FailType.FAIL_ON) { - irPattern = Pattern.compile("rule " + ruleIdx + ":.*\\R.*Failing Regex.*\\R.*Failure:.*contains forbidden node\\(s\\):"); - } else { - irPattern = Pattern.compile("rule " + ruleIdx + ":.*\\R.*Failing Regex.*\\R.*Failure:.*contains wrong number of nodes. Failed constraint:.*"); - } - this.shouldMatch = shouldMatch; - this.matches = matches; + this.irPattern = irPattern; + this.methodName = methodName; + this.matched = false; + } + + // For good constraints only + Constraint(Class klass, String methodName, int ruleIdx) { + this.klass = klass; + classAndMethod = klass.getSimpleName() + "." + methodName; + this.ruleIdx = ruleIdx; + this.methodPattern = Pattern.compile(Pattern.quote(classAndMethod)); + this.irPattern = null; + this.methodName = methodName; + this.matched = false; + } + + @Override + public String toString() { + return "Constraint " + getClass().getSimpleName() + ", method: " + methodName + ", rule: " + ruleIdx; } public Class getKlass() { return klass; } - public boolean shouldMatch() { - return shouldMatch; + protected String errorPrefix() { + return "Method " + methodName + ", Rule " + ruleIdx; + } + + public void checkConstraint(RuntimeException e) { + String message = e.getMessage(); + String[] splitMethods = message.split("Method"); + for (int i = 1; i < splitMethods.length; i++) { + String method = splitMethods[i]; + if (methodPattern.matcher(method).find()) { + String[] splitIrRules = method.split("@IR "); + for (int j = 1; j < splitIrRules.length; j++) { + String irRule = splitIrRules[j]; + if (irRule.startsWith("rule " + ruleIdx)) { + checkIRRule(irRule); + } + } + } + } + Asserts.assertTrue(matched, toString() + " should have been matched"); + } + + abstract protected void checkIRRule(String irRule); + + protected void checkOnMethod(String method) {} +} + +// Constraint for rule that does not fail. +class GoodRuleConstraint extends Constraint { + + GoodRuleConstraint(Class klass, String methodName, int ruleIdx) { + super(klass, methodName, ruleIdx); + matched = true; } - public static Constraint failOnAlloc(Class klass, String methodName, int ruleIdx, boolean shouldMatch, String allocKlass) { - List list = new ArrayList<>(); - list.add(allocKlass); - list.add("call,static wrapper for: _new_instance_Java"); - return new Constraint(klass, methodName, ruleIdx, FailType.FAIL_ON, list, shouldMatch); + public static GoodRuleConstraint create(Class klass, String methodName, int ruleIdx) { + return new GoodRuleConstraint(klass, methodName, ruleIdx); } - public static Constraint failOnArrayAlloc(Class klass, String methodName, int ruleIdx, boolean shouldMatch, String allocKlass) { - List list = new ArrayList<>(); - list.add(allocKlass); - list.add("call,static wrapper for: _new_array_Java"); - return new Constraint(klass, methodName, ruleIdx, FailType.FAIL_ON, list, shouldMatch); + @Override + protected void checkIRRule(String irRule) { + Asserts.fail(errorPrefix() + " should not fail:\n" + irRule); } +} - public static Constraint failOnMatches(Class klass, String methodName, int ruleIdx, boolean shouldMatch, String... matches) { - return new Constraint(klass, methodName, ruleIdx, FailType.FAIL_ON, new ArrayList<>(Arrays.asList(matches)), shouldMatch); +// Constraint for rule that might fail but not with "failOn". +class GoodFailOnConstraint extends GoodRuleConstraint { + + private GoodFailOnConstraint(Class klass, String methodName, int ruleIdx) { + super(klass, methodName, ruleIdx); } - public static Constraint countsMatches(Class klass, String methodName, int ruleIdx, boolean shouldMatch) { - return new Constraint(klass, methodName, ruleIdx, FailType.COUNTS, new ArrayList<>(), shouldMatch); + public static GoodFailOnConstraint create(Class klass, String methodName, int ruleIdx) { + return new GoodFailOnConstraint(klass, methodName, ruleIdx); } - public void checkConstraint(RuntimeException e) { - String message = e.getMessage(); - String[] splitMethods = message.split("Method"); - for (String method : splitMethods) { - if (methodPattern.matcher(method).find()) { - String[] splitIrRules = method.split("@IR"); - for (String irRule : splitIrRules) { - if (irPattern.matcher(irRule).find()) { - boolean allMatch = matches.stream().allMatch(irRule::contains); - if (shouldMatch) { - Asserts.assertTrue(allMatch, "Constraint for method " + classAndMethod + ", rule " + ruleIdx + " could not be matched:\n" + message); - } else { - Asserts.assertFalse(allMatch, "Constraint for method " + classAndMethod + ", rule " + ruleIdx + " should not have been matched:\n" + message); + @Override + protected void checkIRRule(String irRule) { + Asserts.assertFalse(irRule.contains("- failOn"), errorPrefix() + " should not have failed:\n" + irRule); + } +} + +// Constraint for rule that might fail but not with "counts". +class GoodCountsConstraint extends GoodRuleConstraint { + + private GoodCountsConstraint(Class klass, String methodName, int ruleIdx) { + super(klass, methodName, ruleIdx); + } + + public static GoodCountsConstraint create(Class klass, String methodName, int ruleIdx) { + return new GoodCountsConstraint(klass, methodName, ruleIdx); + } + + @Override + protected void checkIRRule(String irRule) { + Asserts.assertFalse(irRule.contains("- counts"), errorPrefix() + " should not have failed with counts:\n" + irRule); + } +} + +// Base class for all Regex based constraint. +abstract class RegexConstraint extends Constraint { + final String category; + final String otherCategory; + final int[] regexIndexes; + final boolean isGood; + final List matches; + + RegexConstraint(Class klass, String methodName, String category, boolean isGood, List matches, int ruleIdx, int... regexIndexes) { + super(klass, methodName, ruleIdx, initIRPattern(category, ruleIdx)); + this.category = category; + this.regexIndexes = regexIndexes; + if (category.equals("failOn")) { + this.otherCategory = "counts"; + } else { + Asserts.assertTrue(category.equals("counts")); + this.otherCategory = "failOn"; + } + this.isGood = isGood; + this.matches = matches; + } + + @Override + public String toString() { + String msg = super.toString() + ", "; + if (regexIndexes.length > 1) { + msg += "regexes: [" + String.join(", ", Arrays.stream(regexIndexes).mapToObj(String::valueOf).toArray(String[]::new)) + "]"; + } else { + msg += "regex: " + regexIndexes[0]; + } + return msg; + } + + @Override + protected String errorPrefix() { + return super.errorPrefix() + " with \"" + category + "\""; + } + + private static Pattern initIRPattern(String category, int ruleIdx) { + if (category.equals("failOn")) { + return Pattern.compile("rule " + ruleIdx + ":.*\\R.*- failOn: Graph contains forbidden nodes.*\\R" + + ".*Regex \\d+\\).*\\R.*Matched forbidden node.*"); + } else { + return Pattern.compile("rule " + ruleIdx + ":.*\\R.*- counts: Graph contains wrong number of nodes:\\R" + + ".*Regex \\d+\\).*\\R.*Expected.*"); + } + } + + @Override + protected void checkIRRule(String irRule) { + int categoryIndex = irRule.indexOf("- " + category); + Asserts.assertTrue(categoryIndex != -1, errorPrefix() + " should have failed"); + + int endIndex; + int otherCategoryIndex = irRule.indexOf("- " + otherCategory); + if (otherCategoryIndex == -1 || categoryIndex > otherCategoryIndex) { + endIndex = irRule.length(); + } else { + endIndex = otherCategoryIndex; + } + String categoryString = irRule.substring(irRule.indexOf("- " + category), endIndex); + Pattern pattern; + Matcher matcher; + for (int regexIndex : this.regexIndexes) { + pattern = Pattern.compile("Regex " + regexIndex + "\\).*"); + matcher = pattern.matcher(categoryString); + if (isGood) { + Asserts.assertFalse(matcher.find(), errorPrefix() + " failed with Regex " + regexIndex); + matched = true; + } else { + Asserts.assertTrue(matcher.find(), errorPrefix() + " should have failed at Regex " + regexIndex); + String[] splitRegex = categoryString.split("Regex "); + if (matches != null) { + for (int i = 1; i < splitRegex.length; i++) { + String regexString = splitRegex[i]; + if (regexString.startsWith(String.valueOf(regexIndex))) { + Asserts.assertTrue(matches.stream().allMatch(regexString::contains), + errorPrefix() + " could not find all matches at Regex " + regexIndex); + matched = true; } - return; } } - Predicate irPredicate = s -> irPattern.matcher(s).find(); - if (shouldMatch) { - Asserts.assertTrue(Arrays.stream(splitIrRules).anyMatch(irPredicate), "Constraint for method " + classAndMethod + ", rule " - + ruleIdx + " could not be matched:\n" + message); - } else { - Asserts.assertTrue(Arrays.stream(splitIrRules).noneMatch(irPredicate), "Constraint for method " + classAndMethod + ", rule " - + ruleIdx + " should not have been matched:\n" + message); - } - return; } } - if (shouldMatch) { - Asserts.fail("Constraint for method " + classAndMethod + ", rule " + ruleIdx + " could not be matched:\n" + message); - } } } -class ShouldNotReachException extends RuntimeException { - ShouldNotReachException(String s) { - super(s); +// Base class for all good regex based constraints. +abstract class GoodRegexConstraint extends RegexConstraint { + + GoodRegexConstraint(Class klass, String methodName, String category, int ruleIdx, int... regexIndexes) { + super(klass, methodName, category, true, null, ruleIdx, regexIndexes); + } +} + +// Constraint for rule that might fail with "counts" or "failOn", but the specified regex in "failOn" does not fail. +class GoodFailOnRegexConstraint extends GoodRegexConstraint { + + private GoodFailOnRegexConstraint(Class klass, String methodName, int ruleIdx, int... regexIndexes) { + super(klass, methodName, "failOn", ruleIdx, regexIndexes); + } + + + public static GoodFailOnRegexConstraint create(Class klass, String methodName, int ruleIdx, int... regexIndexes) { + return new GoodFailOnRegexConstraint(klass, methodName, ruleIdx, regexIndexes); + } +} + + +// Constraint for rule that might fail with "counts" or "failOn", but the specified regex in "counts" does not fail. +class GoodCountsRegexConstraint extends GoodRegexConstraint { + + private GoodCountsRegexConstraint(Class klass, String methodName, int ruleIdx, int... regexIndexes) { + super(klass, methodName, "counts", ruleIdx, regexIndexes); + } + + + public static GoodCountsRegexConstraint create(Class klass, String methodName, int ruleIdx, int... regexIndexes) { + return new GoodCountsRegexConstraint(klass, methodName, ruleIdx, regexIndexes); + } +} + +// Constraint for rule that fails with "failOn" and the specified regex must also fail. +class BadFailOnConstraint extends RegexConstraint { + + BadFailOnConstraint(Class klass, String methodName, int ruleIdx, List matches, int... regexIndexes) { + super(klass, methodName, "failOn", false, matches, ruleIdx, regexIndexes); + } + + public static BadFailOnConstraint create(Class klass, String methodName, int ruleIdx, int regexId, String... matches) { + return new BadFailOnConstraint(klass, methodName, ruleIdx, new ArrayList<>(Arrays.asList(matches)), regexId); + } + + public static BadFailOnConstraint create(Class klass, String methodName, int ruleIdx, String... matches) { + return new BadFailOnConstraint(klass, methodName, ruleIdx, new ArrayList<>(Arrays.asList(matches)), 1); + } +} + +// Constraint for rule that fails with "counts" and the specified regex must also fail. +class BadCountsConstraint extends RegexConstraint { + + BadCountsConstraint(Class klass, String methodName, int ruleIdx, List matches, int... regexIndexes) { + super(klass, methodName, "counts", false, matches, ruleIdx, regexIndexes); + } + + public static BadCountsConstraint create(Class klass, String methodName, int ruleIdx, int regexId, int foundCount, String... matches) { + List matchesList = getMatchesList(foundCount, matches, Arrays.asList(matches)); + return new BadCountsConstraint(klass, methodName, ruleIdx, matchesList, regexId); + } + + public static BadCountsConstraint create(Class klass, String methodName, int ruleIdx, int foundCount, String... matches) { + List matchesList = getMatchesList(foundCount, matches, Arrays.asList(matches)); + return new BadCountsConstraint(klass, methodName, ruleIdx, matchesList, 1); + } + + private static List getMatchesList(int foundCount, String[] matches, List strings) { + List matchesList = new ArrayList<>(); + matchesList.add("but found " + foundCount); + if (matches != null) { + matchesList.addAll(strings); + } + return matchesList; } } diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java index 158496d16f6..37ab848ecc8 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java @@ -23,9 +23,7 @@ package compiler.valhalla.framework.tests; -import compiler.valhalla.framework.Scenario; -import compiler.valhalla.framework.Test; -import compiler.valhalla.framework.TestFramework; +import compiler.valhalla.framework.*; import java.util.ArrayList; @@ -61,8 +59,7 @@ public static void main(String[] args) { } @Test - public void test() { - } + public void test() {} } class HelperA { } From e612085480abfb635438793778dc690284ef98ba Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 24 Feb 2021 15:43:18 +0100 Subject: [PATCH 027/131] Added remaining IR nodes for mainline with tests for them --- .../compiler/valhalla/framework/IRNode.java | 39 ++++-- .../framework/tests/TestIRMatching.java | 129 +++++++++++++++++- 2 files changed, 149 insertions(+), 19 deletions(-) diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java index 347a3e77ac7..2320ff51d66 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java @@ -34,12 +34,17 @@ public class IRNode { public static final String ALLOC = "(.*precise klass .*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_instance_Java" + END; public static final String ALLOC_OF = "(.*precise klass .*"; - public static final String ALLOC_ARRAY = "(.*precise klass \\[L.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_array_Java" + END; public static final String ALLOC_ARRAY_OF = "(.*precise klass \\[L.*"; + public static final String CHECKCAST_ARRAY = "(cmp.*precise klass \\[.*;:" + END; + public static final String CHECKCAST_ARRAY_OF = "(cmp.*precise klass \\[.*"; + public static final String CHECKCAST_ARRAYCOPY = "(.*call_leaf_nofp,runtime checkcast_arraycopy.*" + END; + + public static final String FIELD_ACCESS = "(.*Field: *" + END; + public static final String STORE = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + END; - public static final String STORE_B = START + "StoreB" + MID + END; + public static final String STORE_B = START + "StoreB" + MID + END; // Store to boolean is also mapped to byte public static final String STORE_C = START + "StoreC" + MID + END; public static final String STORE_I = START + "StoreI" + MID + END; // Store to short is also mapped to int public static final String STORE_L = START + "StoreL" + MID + END; @@ -58,20 +63,22 @@ public class IRNode { public static final String STORE_N_OF_CLASS = START + "StoreN" + MID + "@\\S*"; public static final String STORE_OF_FIELD = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@.*name="; - public static final String LOAD = START + "Load(B|S|I|L|F|D|P|N)" + MID + END; + public static final String LOAD = START + "Load(B|UB|S|US|I|L|F|D|P|N)" + MID + END; public static final String LOAD_B = START + "LoadB" + MID + END; - public static final String LOAD_C = START + "LoadC" + MID + END; + public static final String LOAD_UB = START + "LoadUB" + MID + END; // Load from boolean public static final String LOAD_S = START + "LoadS" + MID + END; + public static final String LOAD_US = START + "LoadUS" + MID + END; // Load from char public static final String LOAD_I = START + "LoadI" + MID + END; public static final String LOAD_L = START + "LoadL" + MID + END; public static final String LOAD_F = START + "LoadF" + MID + END; public static final String LOAD_D = START + "LoadD" + MID + END; public static final String LOAD_P = START + "LoadP" + MID + END; public static final String LOAD_N = START + "LoadN" + MID + END; - public static final String LOAD_OF_CLASS = START + "Load(B|C|S|I|L|F|D|P|N)" + MID + "@\\S*"; + public static final String LOAD_OF_CLASS = START + "Load(B|UB|S|US|I|L|F|D|P|N)" + MID + "@\\S*"; public static final String LOAD_B_OF_CLASS = START + "LoadB" + MID + "@\\S*"; - public static final String LOAD_C_OF_CLASS = START + "LoadC" + MID + "@\\S*"; + public static final String LOAD_UB_OF_CLASS = START + "LoadUB" + MID + "@\\S*"; public static final String LOAD_S_OF_CLASS = START + "LoadS" + MID + "@\\S*"; + public static final String LOAD_US_OF_CLASS = START + "LoadUS" + MID + "@\\S*"; public static final String LOAD_I_OF_CLASS = START + "LoadI" + MID + "@\\S*"; public static final String LOAD_L_OF_CLASS = START + "LoadL" + MID + "@\\S*"; public static final String LOAD_F_OF_CLASS = START + "LoadF" + MID + "@\\S*"; @@ -94,15 +101,13 @@ public class IRNode { public static final String NULL_ASSERT_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*null_assert" + END; public static final String RANGE_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*range_check" + END; public static final String UNHANDLED_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*unhandled" + END; + public static final String INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*intrinsic_or_type_checked_inlining" + END; public static final String SCOPE_OBJECT = "(.*# ScObj.*" + END; - public static final String MEMBAR = START + "MemBar" + MID + END; - public static final String FIELD_ACCESS = "(.*Field: *" + END; - public static final String CHECKCAST_ARRAY = "(cmp.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*" + END; - public static final String CHECKCAST_ARRAYCOPY = "(.*call_leaf_nofp,runtime checkcast_arraycopy.*" + END; - // Inline type allocation + // Inline Type things -> TODO: Move to separate class + public static final String CHECKCAST_ARRAY_INLINE = "(cmp.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*" + END; public static final String ALLOCA = "(.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_array_Java" + END; public static final String STORE_INLINE_FIELDS = START + "CallStaticJava" + MID + "store_inline_type_fields" + END; public static final String LOAD_UNKNOWN_INLINE = "(.*call_leaf,runtime load_unknown_inline.*" + END; @@ -110,13 +115,13 @@ public class IRNode { public static final String INLINE_ARRAY_NULL_GUARD = "(.*call,static wrapper for: uncommon_trap.*reason='null_check' action='none'.*" + END; public static final String INTRINSIC_SLOW_PATH = "(.*call,static wrapper for: uncommon_trap.*reason='intrinsic_or_type_checked_inlining'.*" + END; public static final String CLONE_INTRINSIC_SLOW_PATH = "(.*call,static.*java.lang.Object::clone.*" + END; - public static final String JLONG_ARRAYCOPY = "(.*call_leaf_nofp,runtime jlong_disjoint_arraycopy.*" + END; public static final String SUBSTITUTABILITY_TEST = START + "CallStaticJava" + MID + "java.lang.invoke.ValueBootstrapMethods::isSubstitutable" + END; private static final String ALLOC_OF_POSTFIX = ":.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_instance_Java" + END; private static final String ALLOC_ARRAY_OF_POSTFIX = ";:.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_array_Java" + END; + private static final String CHECKCAST_ARRAY_OF_POSTFIX = ";:" + END; private static final String STORE_OF_FIELD_POSTFIX = ",.*" + END; private static final String STORE_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; private static final String LOAD_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; @@ -129,10 +134,14 @@ static List mergeNodes(String[] nodes) { switch (node) { case ALLOC_OF -> mergeCompositeNodes(nodes, mergedNodes, i, node, ALLOC_OF_POSTFIX, "ALLOC_OF"); case ALLOC_ARRAY_OF -> mergeCompositeNodes(nodes, mergedNodes, i, node, ALLOC_ARRAY_OF_POSTFIX, "ALLOC_ARRAY_OF"); - case STORE_OF_CLASS, STORE_B_OF_CLASS, STORE_C_OF_CLASS, STORE_D_OF_CLASS, STORE_F_OF_CLASS, STORE_I_OF_CLASS, STORE_L_OF_CLASS, - STORE_N_OF_CLASS, STORE_P_OF_CLASS -> mergeCompositeNodes(nodes, mergedNodes, i, node, STORE_OF_CLASS_POSTFIX, "STORE_OF_CLASS"); + case CHECKCAST_ARRAY_OF -> mergeCompositeNodes(nodes, mergedNodes, i, node, CHECKCAST_ARRAY_OF_POSTFIX, "CHECKCAST_ARRAY_OF"); + case STORE_OF_CLASS, STORE_B_OF_CLASS, STORE_C_OF_CLASS, STORE_D_OF_CLASS, STORE_F_OF_CLASS, STORE_I_OF_CLASS, + STORE_L_OF_CLASS, STORE_N_OF_CLASS, STORE_P_OF_CLASS + -> mergeCompositeNodes(nodes, mergedNodes, i, node, STORE_OF_CLASS_POSTFIX, "STORE_OF_CLASS"); case STORE_OF_FIELD -> mergeCompositeNodes(nodes, mergedNodes, i, node, STORE_OF_FIELD_POSTFIX, "STORE_OF_FIELD"); - case LOAD_OF_CLASS -> mergeCompositeNodes(nodes, mergedNodes, i, node, LOAD_OF_CLASS_POSTFIX, "LOAD_OF_CLASS"); + case LOAD_OF_CLASS, LOAD_B_OF_CLASS, LOAD_UB_OF_CLASS, LOAD_D_OF_CLASS, LOAD_F_OF_CLASS, LOAD_I_OF_CLASS, LOAD_L_OF_CLASS, + LOAD_N_OF_CLASS, LOAD_P_OF_CLASS, LOAD_S_OF_CLASS, LOAD_US_OF_CLASS + -> mergeCompositeNodes(nodes, mergedNodes, i, node, LOAD_OF_CLASS_POSTFIX, "LOAD_OF_CLASS"); case LOAD_OF_FIELD -> mergeCompositeNodes(nodes, mergedNodes, i, node, LOAD_OF_FIELD_POSTFIX, "LOAD_OF_FIELD"); default -> { i--; // No composite node, do not increment by 2. diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java index ee828c95bfd..db937e8b56d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java +++ b/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java @@ -110,8 +110,10 @@ public static void main(String[] args) { BadFailOnConstraint.create(Loads.class, "load()", 7, "Load"), GoodRuleConstraint.create(Loads.class, "load()", 8), GoodRuleConstraint.create(Loads.class, "load()", 9), - BadFailOnConstraint.create(Loads.class, "loadKlass()", 1) - ); + GoodRuleConstraint.create(Loads.class, "load()", 10), + BadFailOnConstraint.create(Loads.class, "loadKlass()", 1), + BadCountsConstraint.create(Loads.class, "loadKlass()", 2, 2,"Field") + ); // Loops runCheck(BadFailOnConstraint.create(Loops.class, "loop()", 1, "Loop"), @@ -157,7 +159,11 @@ public static void main(String[] args) { BadFailOnConstraint.create(Traps.class, "rangeCheck()", 1, "CallStaticJava", "uncommon_trap"), BadFailOnConstraint.create(Traps.class, "rangeCheck()", 2, "CallStaticJava", "uncommon_trap", "range_check"), BadFailOnConstraint.create(Traps.class, "rangeCheck()", 3, "CallStaticJava", "uncommon_trap", "null_check"), - GoodRuleConstraint.create(Traps.class, "rangeCheck()", 4) + GoodRuleConstraint.create(Traps.class, "rangeCheck()", 4), + BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 1, "CallStaticJava", "uncommon_trap"), + BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 2, "CallStaticJava", "uncommon_trap", "intrinsic_or_type_checked_inlining"), + BadFailOnConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 3, "CallStaticJava", "uncommon_trap", "null_check"), + GoodRuleConstraint.create(Traps.class, "instrinsicOrTypeCheckedInlining()", 4) ); @@ -168,6 +174,13 @@ public static void main(String[] args) { ); runCheck(BadFailOnConstraint.create(ScopeObj.class, "scopeObject()", 1, "ScObj")); + runCheck(BadFailOnConstraint.create(Membar.class, "membar()", 1, "MemBar")); + runCheck(BadFailOnConstraint.create(CheckCastArray.class, "array()", 1, "cmp", "precise klass"), + BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 1,"cmp", "precise klass", "MyClass"), + BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 2,"cmp", "precise klass", "tests/MyClass"), + GoodFailOnConstraint.create(CheckCastArray.class, "array()", 3), + BadFailOnConstraint.create(CheckCastArray.class, "arrayCopy(java.lang.Object[],java.lang.Class)", 1, "checkcast_arraycopy") + ); } private static void runWithArguments(Class clazz, String... args) { @@ -222,7 +235,7 @@ private static void runFailOnTestsArgs(Constraint constraint, String... args) { } } - private static void shouldNotReach() { + public static void shouldNotReach() { throw new ShouldNotReachException("Framework did not fail but it should have!"); } @@ -606,6 +619,48 @@ public void good8() { public void good9() { result = iFld + MyClass.lFldStatic + myClass.iFld; // 1 + 1 + 2 loads (myClass is LoadN of GoodCount and myClass.iFld a LoadI of MyClass) } + + @Test + @IR(counts = {IRNode.LOAD, "8", + IRNode.LOAD_B, "1", + IRNode.LOAD_UB, "1", + IRNode.LOAD_S, "1", + IRNode.LOAD_US, "1", + IRNode.LOAD_I, "1", + IRNode.LOAD_L, "1", + IRNode.LOAD_F, "1", + IRNode.LOAD_D, "1"}) + public void good10() { + bFld++; + cFld++; + sFld++; + iFld++; + lFld++; + fFld++; + dFld++; + flag = !flag; + } + + @Test + @IR(counts = {IRNode.LOAD, "8", IRNode.LOAD_OF_CLASS, "GoodCount", "8", + IRNode.LOAD_B, "1", IRNode.LOAD_B_OF_CLASS, "GoodCount", "1", + IRNode.LOAD_UB, "1", IRNode.LOAD_UB_OF_CLASS, "GoodCount", "1", + IRNode.LOAD_S, "1", IRNode.LOAD_S_OF_CLASS, "GoodCount", "1", + IRNode.LOAD_US, "1", IRNode.LOAD_US_OF_CLASS, "GoodCount", "1", + IRNode.LOAD_I, "1", IRNode.LOAD_I_OF_CLASS, "GoodCount", "1", + IRNode.LOAD_L, "1", IRNode.LOAD_L_OF_CLASS, "GoodCount", "1", + IRNode.LOAD_F, "1", IRNode.LOAD_F_OF_CLASS, "GoodCount", "1", + IRNode.LOAD_D, "1", IRNode.LOAD_D_OF_CLASS, "GoodCount", "1"}) + public void good11() { + bFld++; + cFld++; + sFld++; + iFld++; + lFld++; + fFld++; + dFld++; + flag = !flag; + } } class BadCount { @@ -664,6 +719,7 @@ class Loads { @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld"}) @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld2", IRNode.LOAD_OF_CLASS, "Load"}) // Does not fail @IR(failOn = {IRNode.LOAD_KLASS}) // Does not fail + @IR(counts = {IRNode.FIELD_ACCESS, "3"}) // Does not fail public void load() { result = iFld; iFld = 3; @@ -671,6 +727,7 @@ public void load() { @Test @IR(failOn = {IRNode.LOAD_KLASS}) + @IR(counts = {IRNode.FIELD_ACCESS, "3"}) public void loadKlass() { if (myClass instanceof MyClass) { result = 3; @@ -747,6 +804,8 @@ class Traps { MyClass myClass = new MyClass(); MyClassSub myClassSub = new MyClassSub(); NotLoaded notLoaded = new NotLoaded(); + Object[] oArr = new Object[10]; + MyClass[] mArr = new MyClass[10]; @Test @IR(failOn = IRNode.TRAP) @@ -757,6 +816,7 @@ class Traps { IRNode.NULL_ASSERT_TRAP, IRNode.RANGE_CHECK_TRAP, IRNode.CLASS_CHECK_TRAP, + IRNode.INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP, IRNode.UNHANDLED_TRAP}) public void noTraps() { for (int i = 0; i < 100; i++) { @@ -776,6 +836,7 @@ public void noTraps() { IRNode.NULL_ASSERT_TRAP, IRNode.RANGE_CHECK_TRAP, IRNode.CLASS_CHECK_TRAP, + IRNode.INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP, IRNode.UNHANDLED_TRAP}) public void predicateTrap() { for (int i = 0; i < 100; i++) { @@ -794,6 +855,7 @@ public void predicateTrap() { IRNode.NULL_ASSERT_TRAP, IRNode.RANGE_CHECK_TRAP, IRNode.CLASS_CHECK_TRAP, + IRNode.INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP, IRNode.UNHANDLED_TRAP}) public void nullCheck() { if (myClass instanceof MyClassSub) { @@ -809,6 +871,7 @@ public void nullCheck() { IRNode.UNSTABLE_IF_TRAP, IRNode.RANGE_CHECK_TRAP, IRNode.CLASS_CHECK_TRAP, + IRNode.INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP, IRNode.UNHANDLED_TRAP}) public Object nullAssert() { return notLoaded.notLoadedFld; @@ -823,6 +886,7 @@ public Object nullAssert() { IRNode.NULL_ASSERT_TRAP, IRNode.RANGE_CHECK_TRAP, IRNode.CLASS_CHECK_TRAP, + IRNode.INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP, IRNode.UNHANDLED_TRAP}) public void unstableIf(boolean flag) { if (flag) { @@ -840,6 +904,7 @@ public void unstableIf(boolean flag) { IRNode.UNSTABLE_IF_TRAP, IRNode.NULL_ASSERT_TRAP, IRNode.RANGE_CHECK_TRAP, + IRNode.INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP, IRNode.UNHANDLED_TRAP}) public void classCheck() { try { @@ -857,10 +922,26 @@ public void classCheck() { IRNode.UNSTABLE_IF_TRAP, IRNode.NULL_ASSERT_TRAP, IRNode.CLASS_CHECK_TRAP, + IRNode.INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP, IRNode.UNHANDLED_TRAP}) public void rangeCheck() { iArr[1] = 3; } + + + @Test + @IR(failOn = IRNode.TRAP) // fails + @IR(failOn = IRNode.INTRINSIC_OR_TYPE_CHECKED_INLINING_TRAP) // fails + @IR(failOn = IRNode.NULL_CHECK_TRAP) // fails + @IR(failOn = {IRNode.PREDICATE_TRAP, + IRNode.UNSTABLE_IF_TRAP, + IRNode.NULL_ASSERT_TRAP, + IRNode.CLASS_CHECK_TRAP, + IRNode.RANGE_CHECK_TRAP, + IRNode.UNHANDLED_TRAP}) + public void instrinsicOrTypeCheckedInlining() { + System.arraycopy(oArr, 0, mArr, 0, 8); + } } class UnhandledTrap { @@ -900,6 +981,44 @@ public int scopeObject() { } } +class Membar { + volatile MyClass myClass; + + @Test + @IR(failOn = IRNode.MEMBAR) // fails + public int membar() { + myClass = new MyClass(); + return myClass.x; + } +} + +class CheckCastArray { + Object[] oArr = new Object[10]; + MyClass[] mArr = new MyClass[10]; + + @Test + @IR(failOn = IRNode.CHECKCAST_ARRAY) // fails + @IR(failOn = {IRNode.CHECKCAST_ARRAY_OF, "MyClass", // fails + IRNode.CHECKCAST_ARRAY_OF, "tests/MyClass"}) // fails + @IR(failOn = {IRNode.CHECKCAST_ARRAY_OF, "MyClasss", IRNode.CHECKCAST_ARRAY_OF, "Object"}) + public boolean array() { + return oArr instanceof MyClass[]; + } + + @Test + @IR(failOn = IRNode.CHECKCAST_ARRAYCOPY) // fails + public Object[] arrayCopy(Object[] src, Class klass) { + return Arrays.copyOf(src, 8, klass); + } + + @Run(test = "arrayCopy") + public void testArrayCopy() { + arrayCopy(mArr, MyClass[].class); + arrayCopy(mArr, Object[].class); + arrayCopy(mArr, MyClass2[].class); + } +} + // Used only by class Traps class NotLoaded { NotLoadedHelper notLoadedFld; @@ -914,6 +1033,8 @@ class MyClass { static long lFldStatic; } +class MyClass2 {} + class MyClassSub extends MyClass { int iFld; static int iFldStatic; From 89dd17181674ccd11d797eb55efdf050c2669f21 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 24 Feb 2021 15:58:48 +0100 Subject: [PATCH 028/131] Rename package into compiler.testframework --- .../framework => testframework}/Argument.java | 2 +- .../ArgumentValue.java | 2 +- .../Arguments.java | 2 +- .../framework => testframework}/Check.java | 2 +- .../framework => testframework}/CheckAt.java | 2 +- .../CompLevel.java | 2 +- .../DontCompile.java | 2 +- .../DontInline.java | 2 +- .../ForceCompile.java | 2 +- .../ForceInline.java | 2 +- .../framework => testframework}/IR.java | 2 +- .../IREncodingPrinter.java | 2 +- .../IRMatcher.java | 4 +- .../framework => testframework}/IRNode.java | 14 +------ .../IRViolationException.java | 2 +- .../framework => testframework}/IRs.java | 2 +- .../OSRCompileOnly.java | 2 +- .../ParsedComparator.java | 2 +- .../framework => testframework}/Run.java | 2 +- .../framework => testframework}/RunMode.java | 2 +- .../framework => testframework}/Scenario.java | 2 +- .../framework => testframework}/Test.java | 3 +- .../TestFormat.java | 2 +- .../TestFormatException.java | 2 +- .../TestFramework.java | 2 +- .../framework => testframework}/TestInfo.java | 2 +- .../framework => testframework}/TestRun.java | 2 +- .../TestRunException.java | 2 +- .../framework => testframework}/Warmup.java | 2 +- .../tests/TestBadFormat.java | 4 +- .../tests/TestBasics.java | 4 +- .../tests/TestCompLevels.java | 4 +- .../tests/TestControls.java | 4 +- .../tests/TestIRMatching.java | 18 ++++---- .../tests/TestPackagePrivate.java | 7 +++- .../tests/TestSanity.java | 8 ++-- .../tests/TestScenarios.java | 4 +- .../tests/TestWithHelperClasses.java | 11 +++-- .../valhallatests/ValhallaIRNode.java | 41 +++++++++++++++++++ 39 files changed, 105 insertions(+), 73 deletions(-) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/Argument.java (98%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/ArgumentValue.java (99%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/Arguments.java (97%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/Check.java (97%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/CheckAt.java (96%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/CompLevel.java (98%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/DontCompile.java (98%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/DontInline.java (97%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/ForceCompile.java (98%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/ForceInline.java (97%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/IR.java (97%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/IREncodingPrinter.java (99%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/IRMatcher.java (99%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/IRNode.java (87%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/IRViolationException.java (96%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/IRs.java (97%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/OSRCompileOnly.java (97%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/ParsedComparator.java (99%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/Run.java (97%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/RunMode.java (97%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/Scenario.java (98%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/Test.java (94%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/TestFormat.java (98%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/TestFormatException.java (97%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/TestFramework.java (99%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/TestInfo.java (99%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/TestRun.java (97%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/TestRunException.java (97%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/Warmup.java (97%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/tests/TestBadFormat.java (99%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/tests/TestBasics.java (99%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/tests/TestCompLevels.java (98%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/tests/TestControls.java (99%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/tests/TestIRMatching.java (98%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/tests/TestPackagePrivate.java (86%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/tests/TestSanity.java (94%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/tests/TestScenarios.java (97%) rename test/hotspot/TestingTestFramework/src/compiler/{valhalla/framework => testframework}/tests/TestWithHelperClasses.java (83%) create mode 100644 test/hotspot/TestingTestFramework/src/compiler/testframework/valhallatests/ValhallaIRNode.java diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/Argument.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/Argument.java index c00ddc1abeb..7571643c489 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Argument.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/Argument.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; public enum Argument { /** diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/ArgumentValue.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/ArgumentValue.java index d633bb921cd..eb8fd6b56e8 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ArgumentValue.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/ArgumentValue.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.lang.reflect.Constructor; import java.lang.reflect.Method; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/Arguments.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/Arguments.java index c6b9d71cc86..a76ba4241a1 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Arguments.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/Arguments.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/Check.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/Check.java index bde58a4ae38..f90c40d30ba 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Check.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/Check.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/CheckAt.java similarity index 96% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/CheckAt.java index db577df93d7..0141359493e 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CheckAt.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/CheckAt.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; public enum CheckAt { EACH_INVOCATION, COMPILED diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/CompLevel.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/CompLevel.java index 85c8c805d16..b891f0d079a 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/CompLevel.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/CompLevel.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.util.HashMap; import java.util.Map; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/DontCompile.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/DontCompile.java index 0f76478d2d2..ae30a53d176 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontCompile.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/DontCompile.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/DontInline.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/DontInline.java index 71d7e143c09..0cd49a54b76 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/DontInline.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/DontInline.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/ForceCompile.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/ForceCompile.java index f641d89f534..3d659f11912 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceCompile.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/ForceCompile.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/ForceInline.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/ForceInline.java index e9251dbd60d..64aac9ecb85 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ForceInline.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/ForceInline.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/IR.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/IR.java index 9c53f45ed24..78d1c40e07a 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IR.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/IR.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/IREncodingPrinter.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/IREncodingPrinter.java index eeaa4529e2d..503c770c0ea 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IREncodingPrinter.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/IREncodingPrinter.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import sun.hotspot.WhiteBox; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/IRMatcher.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/IRMatcher.java index fab9ab8035f..32909384f80 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRMatcher.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/IRMatcher.java @@ -21,9 +21,7 @@ * questions. */ -package compiler.valhalla.framework; - -import jdk.test.lib.Asserts; +package compiler.testframework; import java.lang.reflect.Method; import java.util.*; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/IRNode.java similarity index 87% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/IRNode.java index 2320ff51d66..0d9d6821414 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRNode.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/IRNode.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.util.ArrayList; import java.util.List; @@ -106,18 +106,6 @@ public class IRNode { public static final String SCOPE_OBJECT = "(.*# ScObj.*" + END; public static final String MEMBAR = START + "MemBar" + MID + END; - // Inline Type things -> TODO: Move to separate class - public static final String CHECKCAST_ARRAY_INLINE = "(cmp.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*" + END; - public static final String ALLOCA = "(.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_array_Java" + END; - public static final String STORE_INLINE_FIELDS = START + "CallStaticJava" + MID + "store_inline_type_fields" + END; - public static final String LOAD_UNKNOWN_INLINE = "(.*call_leaf,runtime load_unknown_inline.*" + END; - public static final String STORE_UNKNOWN_INLINE = "(.*call_leaf,runtime store_unknown_inline.*" + END; - public static final String INLINE_ARRAY_NULL_GUARD = "(.*call,static wrapper for: uncommon_trap.*reason='null_check' action='none'.*" + END; - public static final String INTRINSIC_SLOW_PATH = "(.*call,static wrapper for: uncommon_trap.*reason='intrinsic_or_type_checked_inlining'.*" + END; - public static final String CLONE_INTRINSIC_SLOW_PATH = "(.*call,static.*java.lang.Object::clone.*" + END; - public static final String JLONG_ARRAYCOPY = "(.*call_leaf_nofp,runtime jlong_disjoint_arraycopy.*" + END; - public static final String SUBSTITUTABILITY_TEST = START + "CallStaticJava" + MID + "java.lang.invoke.ValueBootstrapMethods::isSubstitutable" + END; - private static final String ALLOC_OF_POSTFIX = ":.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_instance_Java" + END; private static final String ALLOC_ARRAY_OF_POSTFIX = ";:.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*call,static wrapper for: _new_array_Java" + END; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRViolationException.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/IRViolationException.java similarity index 96% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRViolationException.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/IRViolationException.java index 81b5c331b72..d2350719b88 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRViolationException.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/IRViolationException.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; public class IRViolationException extends RuntimeException { public IRViolationException(String message) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/IRs.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/IRs.java index 86f305fba13..26b3c387f2a 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/IRs.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/IRs.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSRCompileOnly.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/OSRCompileOnly.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSRCompileOnly.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/OSRCompileOnly.java index 66babc05383..24314b325d2 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/OSRCompileOnly.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/OSRCompileOnly.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ParsedComparator.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/ParsedComparator.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ParsedComparator.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/ParsedComparator.java index cffbe57bff0..d4bdb020e6b 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/ParsedComparator.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/ParsedComparator.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.util.function.BiPredicate; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/Run.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/Run.java index d88479114f4..7514c7d20ff 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Run.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/Run.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/RunMode.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/RunMode.java index 6fb2dbce97b..d0f641ed5b3 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/RunMode.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/RunMode.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; public enum RunMode { /** diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/Scenario.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/Scenario.java index b5ff5872825..f68d39820c7 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Scenario.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/Scenario.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.util.*; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/Test.java similarity index 94% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/Test.java index 8e9c197ae74..1ba553f202b 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Test.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/Test.java @@ -21,9 +21,8 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; -import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/TestFormat.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/TestFormat.java index 0a60d18399d..62b02928ff3 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/TestFormat.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.util.ArrayList; import java.util.List; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/TestFormatException.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/TestFormatException.java index 0fc2477e615..9f5abc6f234 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFormatException.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/TestFormatException.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; public class TestFormatException extends RuntimeException { public TestFormatException(String message) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/TestFramework.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/TestFramework.java index 5ddc950d842..03ed8ee4e10 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestFramework.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/TestFramework.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import jdk.test.lib.Asserts; import jdk.test.lib.Platform; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/TestInfo.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/TestInfo.java index 0ad8388bd3d..59d63a31dd0 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestInfo.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/TestInfo.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import sun.hotspot.WhiteBox; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/TestRun.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/TestRun.java index 50248f66ecc..64e2178fada 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRun.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/TestRun.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; public class TestRun { public static void check(boolean test, String failureMessage) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/TestRunException.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/TestRunException.java index 7eb5d96a7e8..e17f87f2a26 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/TestRunException.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/TestRunException.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; public class TestRunException extends RuntimeException { public TestRunException(String message) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/Warmup.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/Warmup.java index 7a135765aaf..96bca1f316a 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/Warmup.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/Warmup.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.framework; +package compiler.testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestBadFormat.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestBadFormat.java index 391c7ed8157..7fd38ff9aa1 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBadFormat.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestBadFormat.java @@ -21,9 +21,9 @@ * questions. */ -package compiler.valhalla.framework.tests; +package compiler.testframework.tests; -import compiler.valhalla.framework.*; +import compiler.testframework.*; import jdk.test.lib.Asserts; import java.lang.annotation.Retention; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestBasics.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestBasics.java index 21d25bd539c..01635a5fb8a 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestBasics.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestBasics.java @@ -21,9 +21,9 @@ * questions. */ -package compiler.valhalla.framework.tests; +package compiler.testframework.tests; -import compiler.valhalla.framework.*; +import compiler.testframework.*; import java.lang.reflect.Method; import java.util.Arrays; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestCompLevels.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestCompLevels.java index 68d6ce7bce0..d63e7f3ac0a 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestCompLevels.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestCompLevels.java @@ -21,9 +21,9 @@ * questions. */ -package compiler.valhalla.framework.tests; +package compiler.testframework.tests; -import compiler.valhalla.framework.*; +import compiler.testframework.*; import jdk.test.lib.Asserts; import java.lang.reflect.Method; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestControls.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestControls.java index ca670987b0c..20e18322b2e 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestControls.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestControls.java @@ -21,9 +21,9 @@ * questions. */ -package compiler.valhalla.framework.tests; +package compiler.testframework.tests; -import compiler.valhalla.framework.*; +import compiler.testframework.*; import jdk.test.lib.Asserts; import sun.hotspot.WhiteBox; diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestIRMatching.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestIRMatching.java index db937e8b56d..b3fb4244b57 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestIRMatching.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestIRMatching.java @@ -21,9 +21,9 @@ * questions. */ -package compiler.valhalla.framework.tests; +package compiler.testframework.tests; -import compiler.valhalla.framework.*; +import compiler.testframework.*; import jdk.test.lib.Asserts; import java.util.ArrayList; @@ -353,7 +353,7 @@ public void fail3() { } @Test - @IR(failOn = {IRNode.STORE_OF_CLASS, "compiler/valhalla/framework/tests/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "compiler/testframework/tests/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) public void fail4() { iFld = 42; } @@ -377,7 +377,7 @@ public void fail7() { } @Test - @IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "compiler/valhalla/framework/tests/MyClassSub"}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "compiler/testframework/tests/MyClassSub"}) public void fail8() { myClass = new MyClassSub(); } @@ -575,8 +575,8 @@ public void good4() { @Test @IR(counts = {IRNode.STORE, "2", IRNode.STORE_I, "1", IRNode.STORE_L, "1", IRNode.STORE_OF_CLASS, "GoodCount", "1", IRNode.STORE_L_OF_CLASS, "GoodCount", "1", - IRNode.STORE_OF_CLASS, "compiler/valhalla/framework/tests/MyClass", "1", - IRNode.STORE_I_OF_CLASS, "compiler/valhalla/framework/tests/MyClass", "1", + IRNode.STORE_OF_CLASS, "compiler/testframework/tests/MyClass", "1", + IRNode.STORE_I_OF_CLASS, "compiler/testframework/tests/MyClass", "1", IRNode.STORE_OF_CLASS, "framework/tests/GoodCount", "1", IRNode.STORE_L_OF_CLASS, "framework/tests/GoodCount", "1", IRNode.STORE_OF_FIELD, "x", "2"}) @@ -697,8 +697,8 @@ class AllocArray { @IR(failOn = {IRNode.ALLOC_ARRAY}) @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClass"}) @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClasss"}) // Does not fail - @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/valhalla/framework/tests/MySubClass"}) // Does not fail - @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/valhalla/framework/tests/MyClass"}) + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/testframework/tests/MySubClass"}) // Does not fail + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/testframework/tests/MyClass"}) public void allocArray() { myClassArray = new MyClass[2]; } @@ -714,7 +714,7 @@ class Loads { @IR(failOn = {IRNode.LOOP, IRNode.LOOP}, counts = {IRNode.LOOP, "0", IRNode.LOAD, "1"}) // Does not fail @IR(failOn = {IRNode.LOOP, IRNode.LOOP}, counts = {IRNode.LOOP, "0", IRNode.STORE, "1"}) @IR(failOn = {IRNode.LOOP, IRNode.STORE}, counts = {IRNode.LOOP, "0", IRNode.LOAD, "1"}) - @IR(failOn = {IRNode.LOAD_OF_CLASS, "compiler/valhalla/framework/tests/Loads"}) + @IR(failOn = {IRNode.LOAD_OF_CLASS, "compiler/testframework/tests/Loads"}) @IR(failOn = {IRNode.LOAD_OF_CLASS, "Loads"}) @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld"}) @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld2", IRNode.LOAD_OF_CLASS, "Load"}) // Does not fail diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestPackagePrivate.java similarity index 86% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestPackagePrivate.java index d95e456a884..7d62a8f5130 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestPackagePrivate.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestPackagePrivate.java @@ -21,9 +21,12 @@ * questions. */ -package compiler.valhalla.framework.tests; +package compiler.testframework.tests; -import compiler.valhalla.framework.*; +import compiler.testframework.Argument; +import compiler.testframework.Arguments; +import compiler.testframework.Test; +import compiler.testframework.TestFramework; public class TestPackagePrivate { public static void main(String[] args) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestSanity.java similarity index 94% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestSanity.java index 37ab848ecc8..ad350c95729 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestSanity.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestSanity.java @@ -21,11 +21,11 @@ * questions. */ -package compiler.valhalla.framework.tests; +package compiler.testframework.tests; -import compiler.valhalla.framework.*; - -import java.util.ArrayList; +import compiler.testframework.Scenario; +import compiler.testframework.Test; +import compiler.testframework.TestFramework; public class TestSanity { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestScenarios.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestScenarios.java index e350b248c1d..f1b294371c6 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestScenarios.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestScenarios.java @@ -21,9 +21,9 @@ * questions. */ -package compiler.valhalla.framework.tests; +package compiler.testframework.tests; -import compiler.valhalla.framework.*; +import compiler.testframework.*; import jdk.test.lib.Asserts; public class TestScenarios { diff --git a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestWithHelperClasses.java similarity index 83% rename from test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java rename to test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestWithHelperClasses.java index 2d0b5e950a8..1dac636344f 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/valhalla/framework/tests/TestWithHelperClasses.java +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestWithHelperClasses.java @@ -21,9 +21,12 @@ * questions. */ -package compiler.valhalla.framework.tests; +package compiler.testframework.tests; -import compiler.valhalla.framework.*; +import compiler.testframework.CompLevel; +import compiler.testframework.ForceCompile; +import compiler.testframework.Test; +import compiler.testframework.TestFramework; import jdk.test.lib.Asserts; public class TestWithHelperClasses { @@ -33,8 +36,8 @@ public static void main(String[] args) { try { TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class); } catch (Exception e) { - Asserts.assertFalse(TestFramework.getLastVmOutput().contains("public static void compiler.valhalla.framework.tests.Helper1.foo() should have been C2 compiled")); - Asserts.assertTrue(TestFramework.getLastVmOutput().contains("public static void compiler.valhalla.framework.tests.Helper2.foo() should have been C2 compiled")); + Asserts.assertFalse(TestFramework.getLastVmOutput().contains("public static void compiler.testframework.tests.Helper1.foo() should have been C2 compiled")); + Asserts.assertTrue(TestFramework.getLastVmOutput().contains("public static void compiler.testframework.tests.Helper2.foo() should have been C2 compiled")); return; } throw new RuntimeException("Did not catch exception"); diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/valhallatests/ValhallaIRNode.java b/test/hotspot/TestingTestFramework/src/compiler/testframework/valhallatests/ValhallaIRNode.java new file mode 100644 index 00000000000..6184ec0dc90 --- /dev/null +++ b/test/hotspot/TestingTestFramework/src/compiler/testframework/valhallatests/ValhallaIRNode.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021, 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.testframework.valhallatests; + +public class ValhallaIRNode { + private static final String START = "(\\d+(\\s){2}("; + private static final String MID = ".*)+(\\s){2}===.*"; + private static final String END = ")"; + + public static final String CHECKCAST_ARRAY_INLINE = "(cmp.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*" + END; + public static final String ALLOCA = "(.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_array_Java" + END; + public static final String STORE_INLINE_FIELDS = START + "CallStaticJava" + MID + "store_inline_type_fields" + END; + public static final String LOAD_UNKNOWN_INLINE = "(.*call_leaf,runtime load_unknown_inline.*" + END; + public static final String STORE_UNKNOWN_INLINE = "(.*call_leaf,runtime store_unknown_inline.*" + END; + public static final String INLINE_ARRAY_NULL_GUARD = "(.*call,static wrapper for: uncommon_trap.*reason='null_check' action='none'.*" + END; + public static final String INTRINSIC_SLOW_PATH = "(.*call,static wrapper for: uncommon_trap.*reason='intrinsic_or_type_checked_inlining'.*" + END; + public static final String CLONE_INTRINSIC_SLOW_PATH = "(.*call,static.*java.lang.Object::clone.*" + END; + public static final String JLONG_ARRAYCOPY = "(.*call_leaf_nofp,runtime jlong_disjoint_arraycopy.*" + END; + public static final String SUBSTITUTABILITY_TEST = START + "CallStaticJava" + MID + "java.lang.invoke.ValueBootstrapMethods::isSubstitutable" + END; +} From 4760539eeb7ca3a09d33bf86a306da65169b1ee9 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 1 Mar 2021 12:08:54 +0100 Subject: [PATCH 029/131] Rename and move project --- .../src}/testframework/Argument.java | 2 +- .../src}/testframework/ArgumentValue.java | 2 +- .../src}/testframework/Arguments.java | 2 +- .../src}/testframework/Check.java | 2 +- .../src}/testframework/CheckAt.java | 2 +- .../src}/testframework/CompLevel.java | 2 +- .../src}/testframework/DontCompile.java | 2 +- .../src}/testframework/DontInline.java | 2 +- .../src}/testframework/ForceCompile.java | 2 +- .../src}/testframework/ForceInline.java | 2 +- .../TestFramework/src}/testframework/IR.java | 2 +- .../src}/testframework/IREncodingPrinter.java | 2 +- .../src}/testframework/IRMatcher.java | 2 +- .../src}/testframework/IRNode.java | 2 +- .../testframework/IRViolationException.java | 2 +- .../TestFramework/src}/testframework/IRs.java | 2 +- .../src}/testframework/OSRCompileOnly.java | 2 +- .../src}/testframework/ParsedComparator.java | 2 +- .../TestFramework/src}/testframework/Run.java | 2 +- .../src}/testframework/RunMode.java | 2 +- .../src}/testframework/Scenario.java | 2 +- .../TestFramework/src}/testframework/Test.java | 2 +- .../src}/testframework/TestFormat.java | 2 +- .../testframework/TestFormatException.java | 2 +- .../src}/testframework/TestFramework.java | 2 +- .../src}/testframework/TestInfo.java | 2 +- .../src}/testframework/TestRun.java | 2 +- .../src}/testframework/TestRunException.java | 2 +- .../src}/testframework/Warmup.java | 2 +- .../testframework/tests/TestBadFormat.java | 4 ++-- .../src}/testframework/tests/TestBasics.java | 4 ++-- .../testframework/tests/TestCompLevels.java | 4 ++-- .../src}/testframework/tests/TestControls.java | 4 ++-- .../testframework/tests/TestIRMatching.java | 18 +++++++++--------- .../tests/TestPackagePrivate.java | 10 +++++----- .../src}/testframework/tests/TestSanity.java | 8 ++++---- .../testframework/tests/TestScenarios.java | 4 ++-- .../tests/TestWithHelperClasses.java | 14 +++++++------- .../src}/valhallatests/ValhallaIRNode.java | 2 +- 39 files changed, 65 insertions(+), 65 deletions(-) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/Argument.java (98%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/ArgumentValue.java (99%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/Arguments.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/Check.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/CheckAt.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/CompLevel.java (98%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/DontCompile.java (98%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/DontInline.java (98%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/ForceCompile.java (98%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/ForceInline.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/IR.java (98%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/IREncodingPrinter.java (99%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/IRMatcher.java (99%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/IRNode.java (99%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/IRViolationException.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/IRs.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/OSRCompileOnly.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/ParsedComparator.java (99%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/Run.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/RunMode.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/Scenario.java (98%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/Test.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/TestFormat.java (98%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/TestFormatException.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/TestFramework.java (99%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/TestInfo.java (99%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/TestRun.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/TestRunException.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/Warmup.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/tests/TestBadFormat.java (99%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/tests/TestBasics.java (99%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/tests/TestCompLevels.java (98%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/tests/TestControls.java (99%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/tests/TestIRMatching.java (98%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/tests/TestPackagePrivate.java (86%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/tests/TestSanity.java (94%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/tests/TestScenarios.java (97%) rename test/hotspot/{TestingTestFramework/src/compiler => jtreg/TestFramework/src}/testframework/tests/TestWithHelperClasses.java (83%) rename test/hotspot/{TestingTestFramework/src/compiler/testframework => jtreg/TestFramework/src}/valhallatests/ValhallaIRNode.java (98%) diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/Argument.java b/test/hotspot/jtreg/TestFramework/src/testframework/Argument.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/Argument.java rename to test/hotspot/jtreg/TestFramework/src/testframework/Argument.java index 7571643c489..e73dc47d5a5 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/Argument.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/Argument.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; public enum Argument { /** diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/ArgumentValue.java b/test/hotspot/jtreg/TestFramework/src/testframework/ArgumentValue.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/ArgumentValue.java rename to test/hotspot/jtreg/TestFramework/src/testframework/ArgumentValue.java index eb8fd6b56e8..0475ee73e69 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/ArgumentValue.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/ArgumentValue.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.lang.reflect.Constructor; import java.lang.reflect.Method; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/Arguments.java b/test/hotspot/jtreg/TestFramework/src/testframework/Arguments.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/Arguments.java rename to test/hotspot/jtreg/TestFramework/src/testframework/Arguments.java index a76ba4241a1..38e89312444 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/Arguments.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/Arguments.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/Check.java b/test/hotspot/jtreg/TestFramework/src/testframework/Check.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/Check.java rename to test/hotspot/jtreg/TestFramework/src/testframework/Check.java index f90c40d30ba..f586c4e682d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/Check.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/Check.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/CheckAt.java b/test/hotspot/jtreg/TestFramework/src/testframework/CheckAt.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/CheckAt.java rename to test/hotspot/jtreg/TestFramework/src/testframework/CheckAt.java index 0141359493e..11bd1f6612b 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/CheckAt.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/CheckAt.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; public enum CheckAt { EACH_INVOCATION, COMPILED diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/CompLevel.java b/test/hotspot/jtreg/TestFramework/src/testframework/CompLevel.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/CompLevel.java rename to test/hotspot/jtreg/TestFramework/src/testframework/CompLevel.java index b891f0d079a..89b4ef00e9e 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/CompLevel.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/CompLevel.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.util.HashMap; import java.util.Map; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/DontCompile.java b/test/hotspot/jtreg/TestFramework/src/testframework/DontCompile.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/DontCompile.java rename to test/hotspot/jtreg/TestFramework/src/testframework/DontCompile.java index ae30a53d176..c96b80c0545 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/DontCompile.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/DontCompile.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/DontInline.java b/test/hotspot/jtreg/TestFramework/src/testframework/DontInline.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/DontInline.java rename to test/hotspot/jtreg/TestFramework/src/testframework/DontInline.java index 0cd49a54b76..c600bdc777b 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/DontInline.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/DontInline.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/ForceCompile.java b/test/hotspot/jtreg/TestFramework/src/testframework/ForceCompile.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/ForceCompile.java rename to test/hotspot/jtreg/TestFramework/src/testframework/ForceCompile.java index 3d659f11912..26d724c9dd5 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/ForceCompile.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/ForceCompile.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/ForceInline.java b/test/hotspot/jtreg/TestFramework/src/testframework/ForceInline.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/ForceInline.java rename to test/hotspot/jtreg/TestFramework/src/testframework/ForceInline.java index 64aac9ecb85..ce7c9e78d14 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/ForceInline.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/ForceInline.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/IR.java b/test/hotspot/jtreg/TestFramework/src/testframework/IR.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/IR.java rename to test/hotspot/jtreg/TestFramework/src/testframework/IR.java index 78d1c40e07a..561ede75bce 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/IR.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/IR.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/IREncodingPrinter.java b/test/hotspot/jtreg/TestFramework/src/testframework/IREncodingPrinter.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/IREncodingPrinter.java rename to test/hotspot/jtreg/TestFramework/src/testframework/IREncodingPrinter.java index 503c770c0ea..04f97222835 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/IREncodingPrinter.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/IREncodingPrinter.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import sun.hotspot.WhiteBox; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/IRMatcher.java b/test/hotspot/jtreg/TestFramework/src/testframework/IRMatcher.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/IRMatcher.java rename to test/hotspot/jtreg/TestFramework/src/testframework/IRMatcher.java index 32909384f80..f170811cc34 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/IRMatcher.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/IRMatcher.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.lang.reflect.Method; import java.util.*; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/IRNode.java b/test/hotspot/jtreg/TestFramework/src/testframework/IRNode.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/IRNode.java rename to test/hotspot/jtreg/TestFramework/src/testframework/IRNode.java index 0d9d6821414..273f5b295fa 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/IRNode.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/IRNode.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.util.ArrayList; import java.util.List; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/IRViolationException.java b/test/hotspot/jtreg/TestFramework/src/testframework/IRViolationException.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/IRViolationException.java rename to test/hotspot/jtreg/TestFramework/src/testframework/IRViolationException.java index d2350719b88..645031f6570 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/IRViolationException.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/IRViolationException.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; public class IRViolationException extends RuntimeException { public IRViolationException(String message) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/IRs.java b/test/hotspot/jtreg/TestFramework/src/testframework/IRs.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/IRs.java rename to test/hotspot/jtreg/TestFramework/src/testframework/IRs.java index 26b3c387f2a..37cdff5acf4 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/IRs.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/IRs.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/OSRCompileOnly.java b/test/hotspot/jtreg/TestFramework/src/testframework/OSRCompileOnly.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/OSRCompileOnly.java rename to test/hotspot/jtreg/TestFramework/src/testframework/OSRCompileOnly.java index 24314b325d2..b57eb1bbad1 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/OSRCompileOnly.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/OSRCompileOnly.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/ParsedComparator.java b/test/hotspot/jtreg/TestFramework/src/testframework/ParsedComparator.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/ParsedComparator.java rename to test/hotspot/jtreg/TestFramework/src/testframework/ParsedComparator.java index d4bdb020e6b..f144b356d2d 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/ParsedComparator.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/ParsedComparator.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.util.function.BiPredicate; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/Run.java b/test/hotspot/jtreg/TestFramework/src/testframework/Run.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/Run.java rename to test/hotspot/jtreg/TestFramework/src/testframework/Run.java index 7514c7d20ff..2794e53cd23 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/Run.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/Run.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/RunMode.java b/test/hotspot/jtreg/TestFramework/src/testframework/RunMode.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/RunMode.java rename to test/hotspot/jtreg/TestFramework/src/testframework/RunMode.java index d0f641ed5b3..328df33c63c 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/RunMode.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/RunMode.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; public enum RunMode { /** diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/Scenario.java b/test/hotspot/jtreg/TestFramework/src/testframework/Scenario.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/Scenario.java rename to test/hotspot/jtreg/TestFramework/src/testframework/Scenario.java index f68d39820c7..d9d2ded505f 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/Scenario.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/Scenario.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.util.*; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/Test.java b/test/hotspot/jtreg/TestFramework/src/testframework/Test.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/Test.java rename to test/hotspot/jtreg/TestFramework/src/testframework/Test.java index 1ba553f202b..9220e488ca0 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/Test.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/Test.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/TestFormat.java b/test/hotspot/jtreg/TestFramework/src/testframework/TestFormat.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/TestFormat.java rename to test/hotspot/jtreg/TestFramework/src/testframework/TestFormat.java index 62b02928ff3..8f850749b7f 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/TestFormat.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/TestFormat.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.util.ArrayList; import java.util.List; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/TestFormatException.java b/test/hotspot/jtreg/TestFramework/src/testframework/TestFormatException.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/TestFormatException.java rename to test/hotspot/jtreg/TestFramework/src/testframework/TestFormatException.java index 9f5abc6f234..1307f50d7ed 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/TestFormatException.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/TestFormatException.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; public class TestFormatException extends RuntimeException { public TestFormatException(String message) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/TestFramework.java b/test/hotspot/jtreg/TestFramework/src/testframework/TestFramework.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/TestFramework.java rename to test/hotspot/jtreg/TestFramework/src/testframework/TestFramework.java index 03ed8ee4e10..e69d8ac1140 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/TestFramework.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/TestFramework.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import jdk.test.lib.Asserts; import jdk.test.lib.Platform; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/TestInfo.java b/test/hotspot/jtreg/TestFramework/src/testframework/TestInfo.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/TestInfo.java rename to test/hotspot/jtreg/TestFramework/src/testframework/TestInfo.java index 59d63a31dd0..d12369b69b3 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/TestInfo.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/TestInfo.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import sun.hotspot.WhiteBox; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/TestRun.java b/test/hotspot/jtreg/TestFramework/src/testframework/TestRun.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/TestRun.java rename to test/hotspot/jtreg/TestFramework/src/testframework/TestRun.java index 64e2178fada..972d23cb2b6 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/TestRun.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/TestRun.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; public class TestRun { public static void check(boolean test, String failureMessage) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/TestRunException.java b/test/hotspot/jtreg/TestFramework/src/testframework/TestRunException.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/TestRunException.java rename to test/hotspot/jtreg/TestFramework/src/testframework/TestRunException.java index e17f87f2a26..534563dc89e 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/TestRunException.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/TestRunException.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; public class TestRunException extends RuntimeException { public TestRunException(String message) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/Warmup.java b/test/hotspot/jtreg/TestFramework/src/testframework/Warmup.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/Warmup.java rename to test/hotspot/jtreg/TestFramework/src/testframework/Warmup.java index 96bca1f316a..739d175eb16 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/Warmup.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/Warmup.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework; +package testframework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestBadFormat.java b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestBadFormat.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestBadFormat.java rename to test/hotspot/jtreg/TestFramework/src/testframework/tests/TestBadFormat.java index 7fd38ff9aa1..734a11dc8fc 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestBadFormat.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestBadFormat.java @@ -21,9 +21,9 @@ * questions. */ -package compiler.testframework.tests; +package testframework.tests; -import compiler.testframework.*; +import testframework.*; import jdk.test.lib.Asserts; import java.lang.annotation.Retention; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestBasics.java b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestBasics.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestBasics.java rename to test/hotspot/jtreg/TestFramework/src/testframework/tests/TestBasics.java index 01635a5fb8a..3acfab600ee 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestBasics.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestBasics.java @@ -21,9 +21,9 @@ * questions. */ -package compiler.testframework.tests; +package testframework.tests; -import compiler.testframework.*; +import testframework.*; import java.lang.reflect.Method; import java.util.Arrays; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestCompLevels.java b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestCompLevels.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestCompLevels.java rename to test/hotspot/jtreg/TestFramework/src/testframework/tests/TestCompLevels.java index d63e7f3ac0a..b83b30c48ab 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestCompLevels.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestCompLevels.java @@ -21,9 +21,9 @@ * questions. */ -package compiler.testframework.tests; +package testframework.tests; -import compiler.testframework.*; +import testframework.*; import jdk.test.lib.Asserts; import java.lang.reflect.Method; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestControls.java b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestControls.java similarity index 99% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestControls.java rename to test/hotspot/jtreg/TestFramework/src/testframework/tests/TestControls.java index 20e18322b2e..7c5a148428b 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestControls.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestControls.java @@ -21,9 +21,9 @@ * questions. */ -package compiler.testframework.tests; +package testframework.tests; -import compiler.testframework.*; +import testframework.*; import jdk.test.lib.Asserts; import sun.hotspot.WhiteBox; diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestIRMatching.java b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestIRMatching.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestIRMatching.java rename to test/hotspot/jtreg/TestFramework/src/testframework/tests/TestIRMatching.java index b3fb4244b57..5d6fe2a1c19 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestIRMatching.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestIRMatching.java @@ -21,9 +21,9 @@ * questions. */ -package compiler.testframework.tests; +package testframework.tests; -import compiler.testframework.*; +import testframework.*; import jdk.test.lib.Asserts; import java.util.ArrayList; @@ -353,7 +353,7 @@ public void fail3() { } @Test - @IR(failOn = {IRNode.STORE_OF_CLASS, "compiler/testframework/tests/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "testframework/tests/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) public void fail4() { iFld = 42; } @@ -377,7 +377,7 @@ public void fail7() { } @Test - @IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "compiler/testframework/tests/MyClassSub"}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "testframework/tests/MyClassSub"}) public void fail8() { myClass = new MyClassSub(); } @@ -575,8 +575,8 @@ public void good4() { @Test @IR(counts = {IRNode.STORE, "2", IRNode.STORE_I, "1", IRNode.STORE_L, "1", IRNode.STORE_OF_CLASS, "GoodCount", "1", IRNode.STORE_L_OF_CLASS, "GoodCount", "1", - IRNode.STORE_OF_CLASS, "compiler/testframework/tests/MyClass", "1", - IRNode.STORE_I_OF_CLASS, "compiler/testframework/tests/MyClass", "1", + IRNode.STORE_OF_CLASS, "testframework/tests/MyClass", "1", + IRNode.STORE_I_OF_CLASS, "testframework/tests/MyClass", "1", IRNode.STORE_OF_CLASS, "framework/tests/GoodCount", "1", IRNode.STORE_L_OF_CLASS, "framework/tests/GoodCount", "1", IRNode.STORE_OF_FIELD, "x", "2"}) @@ -697,8 +697,8 @@ class AllocArray { @IR(failOn = {IRNode.ALLOC_ARRAY}) @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClass"}) @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClasss"}) // Does not fail - @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/testframework/tests/MySubClass"}) // Does not fail - @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/testframework/tests/MyClass"}) + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "testframework/tests/MySubClass"}) // Does not fail + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "testframework/tests/MyClass"}) public void allocArray() { myClassArray = new MyClass[2]; } @@ -714,7 +714,7 @@ class Loads { @IR(failOn = {IRNode.LOOP, IRNode.LOOP}, counts = {IRNode.LOOP, "0", IRNode.LOAD, "1"}) // Does not fail @IR(failOn = {IRNode.LOOP, IRNode.LOOP}, counts = {IRNode.LOOP, "0", IRNode.STORE, "1"}) @IR(failOn = {IRNode.LOOP, IRNode.STORE}, counts = {IRNode.LOOP, "0", IRNode.LOAD, "1"}) - @IR(failOn = {IRNode.LOAD_OF_CLASS, "compiler/testframework/tests/Loads"}) + @IR(failOn = {IRNode.LOAD_OF_CLASS, "testframework/tests/Loads"}) @IR(failOn = {IRNode.LOAD_OF_CLASS, "Loads"}) @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld"}) @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld2", IRNode.LOAD_OF_CLASS, "Load"}) // Does not fail diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestPackagePrivate.java b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestPackagePrivate.java similarity index 86% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestPackagePrivate.java rename to test/hotspot/jtreg/TestFramework/src/testframework/tests/TestPackagePrivate.java index 7d62a8f5130..84005a60935 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestPackagePrivate.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestPackagePrivate.java @@ -21,12 +21,12 @@ * questions. */ -package compiler.testframework.tests; +package testframework.tests; -import compiler.testframework.Argument; -import compiler.testframework.Arguments; -import compiler.testframework.Test; -import compiler.testframework.TestFramework; +import testframework.Argument; +import testframework.Arguments; +import testframework.Test; +import testframework.TestFramework; public class TestPackagePrivate { public static void main(String[] args) { diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestSanity.java b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestSanity.java similarity index 94% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestSanity.java rename to test/hotspot/jtreg/TestFramework/src/testframework/tests/TestSanity.java index ad350c95729..af3f6b42869 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestSanity.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestSanity.java @@ -21,11 +21,11 @@ * questions. */ -package compiler.testframework.tests; +package testframework.tests; -import compiler.testframework.Scenario; -import compiler.testframework.Test; -import compiler.testframework.TestFramework; +import testframework.Scenario; +import testframework.Test; +import testframework.TestFramework; public class TestSanity { diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestScenarios.java b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestScenarios.java similarity index 97% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestScenarios.java rename to test/hotspot/jtreg/TestFramework/src/testframework/tests/TestScenarios.java index f1b294371c6..22d6e61e4d0 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestScenarios.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestScenarios.java @@ -21,9 +21,9 @@ * questions. */ -package compiler.testframework.tests; +package testframework.tests; -import compiler.testframework.*; +import testframework.*; import jdk.test.lib.Asserts; public class TestScenarios { diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestWithHelperClasses.java b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestWithHelperClasses.java similarity index 83% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestWithHelperClasses.java rename to test/hotspot/jtreg/TestFramework/src/testframework/tests/TestWithHelperClasses.java index 1dac636344f..5fdf81072f9 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/tests/TestWithHelperClasses.java +++ b/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestWithHelperClasses.java @@ -21,12 +21,12 @@ * questions. */ -package compiler.testframework.tests; +package testframework.tests; -import compiler.testframework.CompLevel; -import compiler.testframework.ForceCompile; -import compiler.testframework.Test; -import compiler.testframework.TestFramework; +import testframework.CompLevel; +import testframework.ForceCompile; +import testframework.Test; +import testframework.TestFramework; import jdk.test.lib.Asserts; public class TestWithHelperClasses { @@ -36,8 +36,8 @@ public static void main(String[] args) { try { TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class); } catch (Exception e) { - Asserts.assertFalse(TestFramework.getLastVmOutput().contains("public static void compiler.testframework.tests.Helper1.foo() should have been C2 compiled")); - Asserts.assertTrue(TestFramework.getLastVmOutput().contains("public static void compiler.testframework.tests.Helper2.foo() should have been C2 compiled")); + Asserts.assertFalse(TestFramework.getLastVmOutput().contains("public static void testframework.tests.Helper1.foo() should have been C2 compiled")); + Asserts.assertTrue(TestFramework.getLastVmOutput().contains("public static void testframework.tests.Helper2.foo() should have been C2 compiled")); return; } throw new RuntimeException("Did not catch exception"); diff --git a/test/hotspot/TestingTestFramework/src/compiler/testframework/valhallatests/ValhallaIRNode.java b/test/hotspot/jtreg/TestFramework/src/valhallatests/ValhallaIRNode.java similarity index 98% rename from test/hotspot/TestingTestFramework/src/compiler/testframework/valhallatests/ValhallaIRNode.java rename to test/hotspot/jtreg/TestFramework/src/valhallatests/ValhallaIRNode.java index 6184ec0dc90..534cf5a9d2b 100644 --- a/test/hotspot/TestingTestFramework/src/compiler/testframework/valhallatests/ValhallaIRNode.java +++ b/test/hotspot/jtreg/TestFramework/src/valhallatests/ValhallaIRNode.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.testframework.valhallatests; +package valhallatests; public class ValhallaIRNode { private static final String START = "(\\d+(\\s){2}("; From b6ddfdc0fd8909e020105702b53120192e55ff77 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 2 Mar 2021 16:06:31 +0100 Subject: [PATCH 030/131] Move framework to /test/lib, add TestFrameworkDriver with example test --- .../testframework/TestSimpleExample.java | 51 +++++++++ test/lib/TestFrameworkDriver.java | 101 ++++++++++++++++++ test/lib/jdk/test/lib/Utils.java | 11 ++ .../src => lib}/testframework/Argument.java | 0 .../testframework/ArgumentValue.java | 0 .../src => lib}/testframework/Arguments.java | 0 .../src => lib}/testframework/Check.java | 0 .../src => lib}/testframework/CheckAt.java | 0 .../src => lib}/testframework/CompLevel.java | 0 .../testframework/DontCompile.java | 0 .../src => lib}/testframework/DontInline.java | 0 .../testframework/ForceCompile.java | 0 .../testframework/ForceInline.java | 0 .../src => lib}/testframework/IR.java | 0 .../testframework/IREncodingPrinter.java | 0 .../src => lib}/testframework/IRMatcher.java | 0 .../src => lib}/testframework/IRNode.java | 0 .../testframework/IRViolationException.java | 0 .../src => lib}/testframework/IRs.java | 0 .../testframework/OSRCompileOnly.java | 0 .../testframework/ParsedComparator.java | 0 .../src => lib}/testframework/Run.java | 0 .../src => lib}/testframework/RunMode.java | 0 .../src => lib}/testframework/Scenario.java | 0 .../src => lib}/testframework/Test.java | 0 .../src => lib}/testframework/TestFormat.java | 0 .../testframework/TestFormatException.java | 0 .../testframework/TestFramework.java | 0 .../src => lib}/testframework/TestInfo.java | 0 .../src => lib}/testframework/TestRun.java | 0 .../testframework/TestRunException.java | 0 .../src => lib}/testframework/Warmup.java | 0 .../testframework/tests/TestBadFormat.java | 0 .../testframework/tests/TestBasics.java | 0 .../testframework/tests/TestCompLevels.java | 0 .../testframework/tests/TestControls.java | 0 .../testframework/tests/TestIRMatching.java | 0 .../tests/TestPackagePrivate.java | 0 .../testframework/tests/TestSanity.java | 0 .../testframework/tests/TestScenarios.java | 0 .../tests/TestWithHelperClasses.java | 0 41 files changed, 163 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java create mode 100644 test/lib/TestFrameworkDriver.java rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/Argument.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/ArgumentValue.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/Arguments.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/Check.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/CheckAt.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/CompLevel.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/DontCompile.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/DontInline.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/ForceCompile.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/ForceInline.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/IR.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/IREncodingPrinter.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/IRMatcher.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/IRNode.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/IRViolationException.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/IRs.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/OSRCompileOnly.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/ParsedComparator.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/Run.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/RunMode.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/Scenario.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/Test.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/TestFormat.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/TestFormatException.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/TestFramework.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/TestInfo.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/TestRun.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/TestRunException.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/Warmup.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/tests/TestBadFormat.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/tests/TestBasics.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/tests/TestCompLevels.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/tests/TestControls.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/tests/TestIRMatching.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/tests/TestPackagePrivate.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/tests/TestSanity.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/tests/TestScenarios.java (100%) rename test/{hotspot/jtreg/TestFramework/src => lib}/testframework/tests/TestWithHelperClasses.java (100%) diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java b/test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java new file mode 100644 index 00000000000..3250cab664f --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021, 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. + */ + +/* + * @test + * @summary Example test to use the new test framework. + * @library /test/lib + * @run driver TestFrameworkDriver compiler.valhalla.testframework.TestSimpleExample + */ + +package compiler.valhalla.testframework; + +import testframework.*; + +public class TestSimpleExample { + + int iFld; + + public static void main(String[] args) { + TestFramework.run(); // Framework will use this class (TestSimpleExample.class) as test class. + } + + // TestFramework will verify that this @IR rule works if it is called with a debug build. + // With a product build, it just executes this method without IR verification (Print flags + // for verification are only available in debug builds). + @Test + @IR(failOn = IRNode.LOOP, counts = {IRNode.STORE_I, "1"}) + public void test() { + iFld = 42; + } +} diff --git a/test/lib/TestFrameworkDriver.java b/test/lib/TestFrameworkDriver.java new file mode 100644 index 00000000000..6eb60764555 --- /dev/null +++ b/test/lib/TestFrameworkDriver.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2021, 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. + */ + + +import jdk.test.lib.Utils; +import jdk.test.lib.management.InputArguments; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import sun.hotspot.WhiteBox; +import testframework.TestFormatException; +import testframework.TestRunException; + +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; +import java.io.File; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * Call the driver with jtreg: + * @library /test/lib + * @run driver TestFrameworkDriver some.package.Test + * + * package some.package; + * + * public class Test { ... } + */ +public class TestFrameworkDriver { + public static void main(String[] args) throws Exception { + if (args.length == 0) { + throw new TestFormatException("Must specify at least the test as argument for the driver:\n" + + "@run driver TestFrameworkDriver some.package.Test"); + } + compileTest(); + installWhiteBox(); + runJtregTestInVM(args); + } + + private static void runJtregTestInVM(String[] args) throws Exception { + LinkedList testVMArgs = new LinkedList<>(); + testVMArgs.add("-Dtest.jdk=" + Utils.TEST_JDK); + testVMArgs.add("-cp"); + testVMArgs.add(Utils.TEST_CLASS_PATH); + testVMArgs.addAll(Arrays.asList(InputArguments.getVmInputArgs())); + testVMArgs.add("-Xbootclasspath/a:."); + testVMArgs.add("-XX:+UnlockDiagnosticVMOptions"); + testVMArgs.add("-XX:+WhiteBoxAPI"); + testVMArgs.addAll(Arrays.asList(args)); // add all specified flags + OutputAnalyzer oa = ProcessTools.executeProcess(ProcessTools.createTestJvm(testVMArgs)); + if (oa.getExitValue() != 0) { + System.err.println(oa.getOutput()); + throw new TestRunException("Non-zero exit value of VM: " + oa.getExitValue()); + } + } + + private static void installWhiteBox() throws Exception { + ClassFileInstaller.main(WhiteBox.class.getName()); + } + + private static void compileTest() { + JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + StringWriter output = new StringWriter(); + StandardJavaFileManager fileManager = javac.getStandardFileManager(null, null, null); + Iterable compilationSource = fileManager.getJavaFileObjects(Utils.TEST_FILE); + List javacOptions = new ArrayList<>(); + javacOptions.add("-sourcepath"); + javacOptions.add(Utils.TEST_CLASS_PATH + File.pathSeparator + Utils.TEST_SRC_PATH); + javacOptions.add("-d"); + javacOptions.add(Utils.TEST_CLASS_PATH.split(File.pathSeparator)[0]); + boolean success = javac.getTask(output, fileManager, null, javacOptions, + null, compilationSource).call(); + if (!success) { + throw new TestFormatException("Compilation of " + Utils.TEST_FILE + " failed: " + output); + } + } +} diff --git a/test/lib/jdk/test/lib/Utils.java b/test/lib/jdk/test/lib/Utils.java index be91030ebdb..d719a227dc2 100644 --- a/test/lib/jdk/test/lib/Utils.java +++ b/test/lib/jdk/test/lib/Utils.java @@ -95,6 +95,11 @@ public final class Utils { */ public static final String TEST_SRC = System.getProperty("test.src", "").trim(); + /** + * Returns the value of 'test.src.path' system property + */ + public static final String TEST_SRC_PATH = System.getProperty("test.src.path", "").trim(); + /** * Returns the value of 'test.root' system property. */ @@ -120,11 +125,17 @@ public final class Utils { */ public static final String TEST_NAME = System.getProperty("test.name", "."); + /** + * Returns the value of 'test.file' system property + */ + public static final String TEST_FILE = System.getProperty("test.file", "").trim(); + /** * Returns the value of 'test.nativepath' system property */ public static final String TEST_NATIVE_PATH = System.getProperty("test.nativepath", "."); + /** * Defines property name for seed value. */ diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/Argument.java b/test/lib/testframework/Argument.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/Argument.java rename to test/lib/testframework/Argument.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/ArgumentValue.java b/test/lib/testframework/ArgumentValue.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/ArgumentValue.java rename to test/lib/testframework/ArgumentValue.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/Arguments.java b/test/lib/testframework/Arguments.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/Arguments.java rename to test/lib/testframework/Arguments.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/Check.java b/test/lib/testframework/Check.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/Check.java rename to test/lib/testframework/Check.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/CheckAt.java b/test/lib/testframework/CheckAt.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/CheckAt.java rename to test/lib/testframework/CheckAt.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/CompLevel.java b/test/lib/testframework/CompLevel.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/CompLevel.java rename to test/lib/testframework/CompLevel.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/DontCompile.java b/test/lib/testframework/DontCompile.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/DontCompile.java rename to test/lib/testframework/DontCompile.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/DontInline.java b/test/lib/testframework/DontInline.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/DontInline.java rename to test/lib/testframework/DontInline.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/ForceCompile.java b/test/lib/testframework/ForceCompile.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/ForceCompile.java rename to test/lib/testframework/ForceCompile.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/ForceInline.java b/test/lib/testframework/ForceInline.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/ForceInline.java rename to test/lib/testframework/ForceInline.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/IR.java b/test/lib/testframework/IR.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/IR.java rename to test/lib/testframework/IR.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/IREncodingPrinter.java b/test/lib/testframework/IREncodingPrinter.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/IREncodingPrinter.java rename to test/lib/testframework/IREncodingPrinter.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/IRMatcher.java b/test/lib/testframework/IRMatcher.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/IRMatcher.java rename to test/lib/testframework/IRMatcher.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/IRNode.java b/test/lib/testframework/IRNode.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/IRNode.java rename to test/lib/testframework/IRNode.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/IRViolationException.java b/test/lib/testframework/IRViolationException.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/IRViolationException.java rename to test/lib/testframework/IRViolationException.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/IRs.java b/test/lib/testframework/IRs.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/IRs.java rename to test/lib/testframework/IRs.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/OSRCompileOnly.java b/test/lib/testframework/OSRCompileOnly.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/OSRCompileOnly.java rename to test/lib/testframework/OSRCompileOnly.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/ParsedComparator.java b/test/lib/testframework/ParsedComparator.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/ParsedComparator.java rename to test/lib/testframework/ParsedComparator.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/Run.java b/test/lib/testframework/Run.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/Run.java rename to test/lib/testframework/Run.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/RunMode.java b/test/lib/testframework/RunMode.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/RunMode.java rename to test/lib/testframework/RunMode.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/Scenario.java b/test/lib/testframework/Scenario.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/Scenario.java rename to test/lib/testframework/Scenario.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/Test.java b/test/lib/testframework/Test.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/Test.java rename to test/lib/testframework/Test.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/TestFormat.java b/test/lib/testframework/TestFormat.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/TestFormat.java rename to test/lib/testframework/TestFormat.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/TestFormatException.java b/test/lib/testframework/TestFormatException.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/TestFormatException.java rename to test/lib/testframework/TestFormatException.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/TestFramework.java b/test/lib/testframework/TestFramework.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/TestFramework.java rename to test/lib/testframework/TestFramework.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/TestInfo.java b/test/lib/testframework/TestInfo.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/TestInfo.java rename to test/lib/testframework/TestInfo.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/TestRun.java b/test/lib/testframework/TestRun.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/TestRun.java rename to test/lib/testframework/TestRun.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/TestRunException.java b/test/lib/testframework/TestRunException.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/TestRunException.java rename to test/lib/testframework/TestRunException.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/Warmup.java b/test/lib/testframework/Warmup.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/Warmup.java rename to test/lib/testframework/Warmup.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestBadFormat.java b/test/lib/testframework/tests/TestBadFormat.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/tests/TestBadFormat.java rename to test/lib/testframework/tests/TestBadFormat.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestBasics.java b/test/lib/testframework/tests/TestBasics.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/tests/TestBasics.java rename to test/lib/testframework/tests/TestBasics.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestCompLevels.java b/test/lib/testframework/tests/TestCompLevels.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/tests/TestCompLevels.java rename to test/lib/testframework/tests/TestCompLevels.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestControls.java b/test/lib/testframework/tests/TestControls.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/tests/TestControls.java rename to test/lib/testframework/tests/TestControls.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestIRMatching.java b/test/lib/testframework/tests/TestIRMatching.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/tests/TestIRMatching.java rename to test/lib/testframework/tests/TestIRMatching.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestPackagePrivate.java b/test/lib/testframework/tests/TestPackagePrivate.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/tests/TestPackagePrivate.java rename to test/lib/testframework/tests/TestPackagePrivate.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestSanity.java b/test/lib/testframework/tests/TestSanity.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/tests/TestSanity.java rename to test/lib/testframework/tests/TestSanity.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestScenarios.java b/test/lib/testframework/tests/TestScenarios.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/tests/TestScenarios.java rename to test/lib/testframework/tests/TestScenarios.java diff --git a/test/hotspot/jtreg/TestFramework/src/testframework/tests/TestWithHelperClasses.java b/test/lib/testframework/tests/TestWithHelperClasses.java similarity index 100% rename from test/hotspot/jtreg/TestFramework/src/testframework/tests/TestWithHelperClasses.java rename to test/lib/testframework/tests/TestWithHelperClasses.java From 8a5c6d42c928918b535172d890df196ecbb0e750 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 3 Mar 2021 14:05:49 +0100 Subject: [PATCH 031/131] Improve jtreg support with suggestions from Igor I., split TestFramework into TestFrameworkRunner and TestFrameworkExecution, use TestFramework class as driver and interface --- .../testframework/TestSimpleExample.java | 6 +- test/lib/ClassFileInstaller.java | 190 +-- test/lib/RedefineClassHelper.java | 8 +- test/lib/TestFrameworkDriver.java | 101 -- .../CheckedTestFrameworkException.java | 5 + test/lib/testframework/TestFramework.java | 1156 +--------------- .../testframework/TestFrameworkException.java | 11 + .../testframework/TestFrameworkExecution.java | 1165 +++++++++++++++++ .../testframework/TestFrameworkRunner.java | 183 +++ test/lib/testframework/TestInfo.java | 5 +- test/lib/testframework/tests/TestBasics.java | 6 +- .../testframework/tests/TestCompLevels.java | 6 +- .../lib/testframework/tests/TestControls.java | 2 +- .../testframework/tests/TestIRMatching.java | 14 +- .../tests/TestWithHelperClasses.java | 4 +- 15 files changed, 1470 insertions(+), 1392 deletions(-) delete mode 100644 test/lib/TestFrameworkDriver.java create mode 100644 test/lib/testframework/CheckedTestFrameworkException.java create mode 100644 test/lib/testframework/TestFrameworkException.java create mode 100644 test/lib/testframework/TestFrameworkExecution.java create mode 100644 test/lib/testframework/TestFrameworkRunner.java diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java b/test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java index 3250cab664f..fab72f35fb0 100644 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java @@ -25,7 +25,7 @@ * @test * @summary Example test to use the new test framework. * @library /test/lib - * @run driver TestFrameworkDriver compiler.valhalla.testframework.TestSimpleExample + * @run driver compiler.valhalla.testframework.TestSimpleExample */ package compiler.valhalla.testframework; @@ -34,10 +34,10 @@ public class TestSimpleExample { - int iFld; + static int iFld; public static void main(String[] args) { - TestFramework.run(); // Framework will use this class (TestSimpleExample.class) as test class. + TestFramework.run(); } // TestFramework will verify that this @IR rule works if it is called with a debug build. diff --git a/test/lib/ClassFileInstaller.java b/test/lib/ClassFileInstaller.java index 0d1335a14cd..e88014b4afa 100644 --- a/test/lib/ClassFileInstaller.java +++ b/test/lib/ClassFileInstaller.java @@ -21,20 +21,7 @@ * questions. */ -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.io.ByteArrayInputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.ArrayList; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; +import jdk.test.lib.util.ClassFileInstaller.Manifest; /** * Dump a class file for a class on the class path in the current directory, or @@ -68,112 +55,13 @@ * @run driver ClassFileInstaller -jar myjar.jar sun.hotspot.WhiteBox */ public class ClassFileInstaller { - /** - * You can enable debug tracing of ClassFileInstaller by running JTREG with - * jtreg -DClassFileInstaller.debug=true ... - */ - public static boolean DEBUG = Boolean.getBoolean("ClassFileInstaller.debug"); - - /** + /** * @param args The names of the classes to dump * @throws Exception + * @deprecated use {@link jdk.test.lib.util.ClassFileInstaller} instead */ public static void main(String... args) throws Exception { - if (args.length > 1 && args[0].equals("-jar")) { - if (args.length < 2) { - throw new RuntimeException("Usage: ClassFileInstaller \n" + - "where possible options include:\n" + - " -jar Write to the JAR file "); - } - String jarFile = args[1]; - String[] classes = addInnerClasses(args, 2); - writeJar_impl(jarFile, null, classes); - } else { - if (DEBUG) { - System.out.println("ClassFileInstaller: Writing to " + System.getProperty("user.dir")); - } - String[] classes = addInnerClasses(args, 0); - for (String cls : classes) { - writeClassToDisk(cls); - } - } - } - - // Add commonly used inner classes that are often omitted by mistake. Currently - // we support only sun.hotspot.WhiteBox$WhiteBoxPermission. See JDK-8199290 - private static String[] addInnerClasses(String[] classes, int startIdx) { - boolean seenWB = false; - boolean seenWBInner = false; - final String wb = "sun.hotspot.WhiteBox"; - final String wbInner = "sun.hotspot.WhiteBox$WhiteBoxPermission"; - - ArrayList list = new ArrayList<>(); - - for (int i = startIdx; i < classes.length; i++) { - String cls = classes[i]; - list.add(cls); - switch (cls) { - case wb: seenWB = true; break; - case wbInner: seenWBInner = true; break; - } - } - if (seenWB && !seenWBInner) { - list.add(wbInner); - } - - String[] array = new String[list.size()]; - list.toArray(array); - return array; - } - - public static class Manifest { - private InputStream in; - - private Manifest(InputStream in) { - this.in = in; - } - - static Manifest fromSourceFile(String fileName) throws Exception { - String pathName = System.getProperty("test.src") + File.separator + fileName; - return new Manifest(new FileInputStream(pathName)); - } - - // Example: - // String manifest = "Premain-Class: RedefineClassHelper\n" + - // "Can-Redefine-Classes: true\n"; - // ClassFileInstaller.writeJar("redefineagent.jar", - // ClassFileInstaller.Manifest.fromString(manifest), - // "RedefineClassHelper"); - static Manifest fromString(String manifest) throws Exception { - return new Manifest(new ByteArrayInputStream(manifest.getBytes())); - } - - public InputStream getInputStream() { - return in; - } - } - - private static void writeJar_impl(String jarFile, Manifest manifest, String classes[]) throws Exception { - if (DEBUG) { - System.out.println("ClassFileInstaller: Writing to " + getJarPath(jarFile)); - } - - (new File(jarFile)).delete(); - FileOutputStream fos = new FileOutputStream(jarFile); - ZipOutputStream zos = new ZipOutputStream(fos); - - // The manifest must be the first or second entry. See comments in JarInputStream - // constructor and JDK-5046178. - if (manifest != null) { - writeToDisk(zos, "META-INF/MANIFEST.MF", manifest.getInputStream()); - } - - for (String cls : classes) { - writeClassToDisk(zos, cls); - } - - zos.close(); - fos.close(); + jdk.test.lib.util.ClassFileInstaller.main(args); } /* @@ -188,15 +76,11 @@ private static void writeJar_impl(String jarFile, Manifest manifest, String clas * @build ClassFileInstaller */ public static String writeJar(String jarFile, String... classes) throws Exception { - classes = addInnerClasses(classes, 0); - writeJar_impl(jarFile, null, classes); - return getJarPath(jarFile); + return jdk.test.lib.util.ClassFileInstaller.writeJar(jarFile, classes); } public static String writeJar(String jarFile, Manifest manifest, String... classes) throws Exception { - classes = addInnerClasses(classes, 0); - writeJar_impl(jarFile, manifest, classes); - return getJarPath(jarFile); + return jdk.test.lib.util.ClassFileInstaller.writeJar(jarFile, manifest, classes); } /** @@ -217,74 +101,22 @@ public static String writeJar(String jarFile, Manifest manifest, String... class * */ public static String getJarPath(String jarFileName) { - return new File(jarFileName).getAbsolutePath(); + return jdk.test.lib.util.ClassFileInstaller.getJarPath(jarFileName); } public static void writeClassToDisk(String className) throws Exception { - writeClassToDisk((ZipOutputStream)null, className); - } - private static void writeClassToDisk(ZipOutputStream zos, String className) throws Exception { - writeClassToDisk(zos, className, ""); + jdk.test.lib.util.ClassFileInstaller.writeClassToDisk(className); } public static void writeClassToDisk(String className, String prependPath) throws Exception { - writeClassToDisk(null, className, prependPath); - } - private static void writeClassToDisk(ZipOutputStream zos, String className, String prependPath) throws Exception { - ClassLoader cl = ClassFileInstaller.class.getClassLoader(); - - // Convert dotted class name to a path to a class file - String pathName = className.replace('.', '/').concat(".class"); - InputStream is = cl.getResourceAsStream(pathName); - if (is == null) { - throw new RuntimeException("Failed to find " + pathName); - } - if (prependPath.length() > 0) { - pathName = prependPath + "/" + pathName; - } - writeToDisk(zos, pathName, is); + jdk.test.lib.util.ClassFileInstaller.writeClassToDisk(className, prependPath); } public static void writeClassToDisk(String className, byte[] bytecode) throws Exception { - writeClassToDisk(null, className, bytecode); - } - private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode) throws Exception { - writeClassToDisk(zos, className, bytecode, ""); + jdk.test.lib.util.ClassFileInstaller.writeClassToDisk(className, bytecode); } public static void writeClassToDisk(String className, byte[] bytecode, String prependPath) throws Exception { - writeClassToDisk(null, className, bytecode, prependPath); - } - private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode, String prependPath) throws Exception { - // Convert dotted class name to a path to a class file - String pathName = className.replace('.', '/').concat(".class"); - if (prependPath.length() > 0) { - pathName = prependPath + "/" + pathName; - } - writeToDisk(zos, pathName, new ByteArrayInputStream(bytecode)); - } - - private static void writeToDisk(ZipOutputStream zos, String pathName, InputStream is) throws Exception { - if (DEBUG) { - System.out.println("ClassFileInstaller: Writing " + pathName); - } - if (zos != null) { - ZipEntry ze = new ZipEntry(pathName); - zos.putNextEntry(ze); - byte[] buf = new byte[1024]; - int len; - while ((len = is.read(buf))>0){ - zos.write(buf, 0, len); - } - } else { - // Create the class file's package directory - Path p = Paths.get(pathName); - if (pathName.contains("/")) { - Files.createDirectories(p.getParent()); - } - // Create the class file - Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING); - } - is.close(); + jdk.test.lib.util.ClassFileInstaller.writeClassToDisk(className, bytecode, prependPath); } } diff --git a/test/lib/RedefineClassHelper.java b/test/lib/RedefineClassHelper.java index f9bedc0e6c9..b35ca3797d8 100644 --- a/test/lib/RedefineClassHelper.java +++ b/test/lib/RedefineClassHelper.java @@ -24,7 +24,7 @@ import java.io.PrintWriter; import java.lang.instrument.Instrumentation; import java.lang.instrument.ClassDefinition; -import jdk.test.lib.compiler.InMemoryJavaCompiler; +//import jdk.test.lib.compiler.InMemoryJavaCompiler; /* * Helper class to write tests that redefine classes. @@ -47,8 +47,8 @@ public static void premain(String agentArgs, Instrumentation inst) { * @param javacode String with the new java code for the class to be redefined */ public static void redefineClass(Class clazz, String javacode) throws Exception { - byte[] bytecode = InMemoryJavaCompiler.compile(clazz.getName(), javacode); - redefineClass(clazz, bytecode); +// byte[] bytecode = InMemoryJavaCompiler.compile(clazz.getName(), javacode); +// redefineClass(clazz, bytecode); } /** @@ -66,6 +66,6 @@ public static void redefineClass(Class clazz, byte[] bytecode) throws Exception */ public static void main(String[] args) throws Exception { String manifest = "Premain-Class: RedefineClassHelper\nCan-Redefine-Classes: true\n"; - ClassFileInstaller.writeJar("redefineagent.jar", ClassFileInstaller.Manifest.fromString(manifest), "RedefineClassHelper"); +// ClassFileInstaller.writeJar("redefineagent.jar", ClassFileInstaller.Manifest.fromString(manifest), "RedefineClassHelper"); } } diff --git a/test/lib/TestFrameworkDriver.java b/test/lib/TestFrameworkDriver.java deleted file mode 100644 index 6eb60764555..00000000000 --- a/test/lib/TestFrameworkDriver.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2021, 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. - */ - - -import jdk.test.lib.Utils; -import jdk.test.lib.management.InputArguments; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.process.ProcessTools; -import sun.hotspot.WhiteBox; -import testframework.TestFormatException; -import testframework.TestRunException; - -import javax.tools.JavaCompiler; -import javax.tools.JavaFileObject; -import javax.tools.StandardJavaFileManager; -import javax.tools.ToolProvider; -import java.io.File; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - -/** - * Call the driver with jtreg: - * @library /test/lib - * @run driver TestFrameworkDriver some.package.Test - * - * package some.package; - * - * public class Test { ... } - */ -public class TestFrameworkDriver { - public static void main(String[] args) throws Exception { - if (args.length == 0) { - throw new TestFormatException("Must specify at least the test as argument for the driver:\n" + - "@run driver TestFrameworkDriver some.package.Test"); - } - compileTest(); - installWhiteBox(); - runJtregTestInVM(args); - } - - private static void runJtregTestInVM(String[] args) throws Exception { - LinkedList testVMArgs = new LinkedList<>(); - testVMArgs.add("-Dtest.jdk=" + Utils.TEST_JDK); - testVMArgs.add("-cp"); - testVMArgs.add(Utils.TEST_CLASS_PATH); - testVMArgs.addAll(Arrays.asList(InputArguments.getVmInputArgs())); - testVMArgs.add("-Xbootclasspath/a:."); - testVMArgs.add("-XX:+UnlockDiagnosticVMOptions"); - testVMArgs.add("-XX:+WhiteBoxAPI"); - testVMArgs.addAll(Arrays.asList(args)); // add all specified flags - OutputAnalyzer oa = ProcessTools.executeProcess(ProcessTools.createTestJvm(testVMArgs)); - if (oa.getExitValue() != 0) { - System.err.println(oa.getOutput()); - throw new TestRunException("Non-zero exit value of VM: " + oa.getExitValue()); - } - } - - private static void installWhiteBox() throws Exception { - ClassFileInstaller.main(WhiteBox.class.getName()); - } - - private static void compileTest() { - JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); - StringWriter output = new StringWriter(); - StandardJavaFileManager fileManager = javac.getStandardFileManager(null, null, null); - Iterable compilationSource = fileManager.getJavaFileObjects(Utils.TEST_FILE); - List javacOptions = new ArrayList<>(); - javacOptions.add("-sourcepath"); - javacOptions.add(Utils.TEST_CLASS_PATH + File.pathSeparator + Utils.TEST_SRC_PATH); - javacOptions.add("-d"); - javacOptions.add(Utils.TEST_CLASS_PATH.split(File.pathSeparator)[0]); - boolean success = javac.getTask(output, fileManager, null, javacOptions, - null, compilationSource).call(); - if (!success) { - throw new TestFormatException("Compilation of " + Utils.TEST_FILE + " failed: " + output); - } - } -} diff --git a/test/lib/testframework/CheckedTestFrameworkException.java b/test/lib/testframework/CheckedTestFrameworkException.java new file mode 100644 index 00000000000..0765a18e6e9 --- /dev/null +++ b/test/lib/testframework/CheckedTestFrameworkException.java @@ -0,0 +1,5 @@ +package testframework; + +// Checked exceptions in the framework to propagate error handling. +class CheckedTestFrameworkException extends Exception { +} diff --git a/test/lib/testframework/TestFramework.java b/test/lib/testframework/TestFramework.java index e69d8ac1140..f8cdde258b2 100644 --- a/test/lib/testframework/TestFramework.java +++ b/test/lib/testframework/TestFramework.java @@ -23,9 +23,8 @@ package testframework; -import jdk.test.lib.Asserts; -import jdk.test.lib.Platform; import jdk.test.lib.Utils; +import jdk.test.lib.util.ClassFileInstaller; import jdk.test.lib.management.InputArguments; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; @@ -33,175 +32,34 @@ import java.io.PrintWriter; import java.io.StringWriter; -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.stream.Stream; - +/** + * Call the driver with jtreg: + * @library /test/lib + * @run driver TestFrameworkDriver some.package.Test + * + * package some.package; + * + * public class Test { ... } + */ public class TestFramework { - private static final WhiteBox WHITE_BOX; - - static { - try { - WHITE_BOX = WhiteBox.getWhiteBox(); - } catch (UnsatisfiedLinkError e) { - System.err.println("Did you set up the jtreg test properly? Ensure that at least the following settings are set:"); - System.err.println(""" - * @library /testlibrary /test/lib /compiler/whitebox / - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI""".indent(1)); - throw e; - } - } - - private static final boolean TIERED_COMPILATION = (Boolean)WHITE_BOX.getVMFlag("TieredCompilation"); - private static final CompLevel TIERED_COMPILATION_STOP_AT_LEVEL = CompLevel.forValue(((Long)WHITE_BOX.getVMFlag("TieredStopAtLevel")).intValue()); - static final boolean TEST_C1 = TIERED_COMPILATION && TIERED_COMPILATION_STOP_AT_LEVEL.getValue() < CompLevel.C2.getValue(); - - // User defined settings - static final boolean XCOMP = Platform.isComp(); -// private static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); - static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "true")); - private static final boolean PRINT_TIMES = Boolean.parseBoolean(System.getProperty("PrintTimes", "false")); - - private static final boolean COMPILE_COMMANDS = Boolean.parseBoolean(System.getProperty("CompileCommands", "true")) && !XCOMP; - static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); - static final boolean STRESS_CC = Boolean.parseBoolean(System.getProperty("StressCC", "false")); - private static final boolean REQUESTED_VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); - private static boolean VERIFY_IR = REQUESTED_VERIFY_IR && USE_COMPILER && !XCOMP && !STRESS_CC && !TEST_C1 && COMPILE_COMMANDS - && Platform.isDebugBuild() && !Platform.isInt(); - private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false")) && Platform.isDebugBuild(); - private static final String TESTLIST = System.getProperty("Testlist", ""); - private static final String EXCLUDELIST = System.getProperty("Exclude", ""); - public static final int WARMUP_ITERATIONS = Integer.parseInt(System.getProperty("Warmup", "2000")); - private static final boolean DUMP_REPLAY = Boolean.parseBoolean(System.getProperty("DumpReplay", "false")); - private static final boolean GC_AFTER = Boolean.parseBoolean(System.getProperty("GCAfter", "false")); - private static final boolean SHUFFLE_TESTS = Boolean.parseBoolean(System.getProperty("ShuffleTests", "true")); + public static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "true")); private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); - private static final boolean PRINT_VALID_IR_RULES = Boolean.parseBoolean(System.getProperty("PrintValidIRRules", "false")); - protected static final long PerMethodTrapLimit = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); - protected static final boolean ProfileInterpreter = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); - private static final boolean FLIP_C1_C2 = Boolean.parseBoolean(System.getProperty("FlipC1C2", "false")); - private final String[] fixedDefaultFlags; - private final String[] compileCommandFlags; - private final String[] printFlags; - private final String[] verifyFlags; - private static String lastVmOutput; // Only used to test TestFramework - - static final boolean VERIFY_OOPS = (Boolean)WHITE_BOX.getVMFlag("VerifyOops"); - - private final HashMap declaredTests = new HashMap<>(); - private final LinkedHashMap allTests = new LinkedHashMap<>(); // Keep order - private final HashMap testMethodMap = new HashMap<>(); - private final List excludeList; - private final List includeList; private List> helperClasses = null; private List scenarios = null; - private final IREncodingPrinter irMatchRulePrinter; private final Class testClass; + private static String lastVMOutput; public TestFramework(Class testClass) { TestRun.check(testClass != null, "Test class cannot be null"); this.testClass = testClass; - // These flags can be overridden - fixedDefaultFlags = initDefaultFlags(); - compileCommandFlags = initCompileCommandFlags(); - printFlags = initPrintFlags(); - verifyFlags = initVerifyFlags(); - - this.includeList = createTestFilterList(TESTLIST, testClass); - this.excludeList = createTestFilterList(EXCLUDELIST, testClass); - - if (PRINT_VALID_IR_RULES) { - irMatchRulePrinter = new IREncodingPrinter(); - } else { - irMatchRulePrinter = null; - } - } - - protected String[] initDefaultFlags() { - return new String[] {"-XX:-BackgroundCompilation"}; - } - - protected String[] initCompileCommandFlags() { - return new String[] {"-XX:CompileCommand=quiet"}; - } - - protected String[] initPrintFlags() { - return new String[] {"-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions"}; - } - - protected String[] initVerifyFlags() { - return new String[] { - "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", "-XX:+VerifyBeforeGC", - "-XX:+VerifyAfterGC", "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing"}; - } - - private List createTestFilterList(String list, Class testClass) { - List filterList = null; - if (!list.isEmpty()) { - String classPrefix = testClass.getSimpleName() + "."; - filterList = new ArrayList<>(Arrays.asList(list.split(","))); - for (int i = filterList.size() - 1; i >= 0; i--) { - String test = filterList.get(i); - if (test.indexOf(".") > 0) { - if (test.startsWith(classPrefix)) { - test = test.substring(classPrefix.length()); - filterList.set(i, test); - } else { - filterList.remove(i); - } - } - } - } - return filterList; - } - - public static void main(String[] args) { - String testClassName = args[0]; - System.out.println("Framework main(), about to run tests in class " + testClassName); - Class testClass; - try { - testClass = Class.forName(testClassName); - } catch (Exception e) { - throw new TestRunException("Could not find test class " + testClassName, e); - } - - TestFramework framework = new TestFramework(testClass); - Class[] helperClasses = getHelperClasses(args); - if (helperClasses != null) { - framework.addHelperClasses(helperClasses); - } - framework.runTestsOnSameVM(); } - private static Class[] getHelperClasses(String[] args) { - if (args.length == 1) { - return null; - } - Class[] helperClasses = new Class[args.length - 1]; // First argument is test class - for (int i = 1; i < args.length; i++) { - String helperClassName = args[i]; - try { - helperClasses[i - 1] = Class.forName(helperClassName); - } catch (Exception e) { - throw new TestRunException("Could not find helper class " + helperClassName, e); - } - } - return helperClasses; - } - - - /* - * Public interface methods - */ public static void run() { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); run(walker.getCallerClass()); @@ -209,13 +67,13 @@ public static void run() { public static void run(Class testClass) { TestFramework framework = new TestFramework(testClass); - framework.runTestVM(null); + framework.start(); } public static void runWithHelperClasses(Class testClass, Class... helperClasses) { TestFramework framework = new TestFramework(testClass); framework.addHelperClasses(helperClasses); - framework.runTestVM(null); + framework.start(); } public static void runWithScenarios(Scenario... scenarios) { @@ -226,7 +84,7 @@ public static void runWithScenarios(Scenario... scenarios) { public static void runWithScenarios(Class testClass, Scenario... scenarios) { TestFramework framework = new TestFramework(testClass); framework.addScenarios(scenarios); - framework.doRunWithScenarios(); + framework.start(); } public TestFramework addHelperClasses(Class... helperClasses) { @@ -266,70 +124,72 @@ public void clearScenarios() { } public void start() { - if (scenarios != null) { - doRunWithScenarios(); + installWhiteBox(); + if (scenarios == null) { + start(null); } else { - runTestVM(null); + startWithScenarios(); } } // Can be called from tests for non-@Test methods public static void compile(Method m, CompLevel compLevel) { - TestRun.check(getAnnotation(m, Test.class) == null, - "Cannot call enqueueMethodForCompilation() for @Test annotated method " + m); - enqueueMethodForCompilation(m, compLevel); + TestFrameworkExecution.compile(m, compLevel); } public static boolean isC1Compiled(Method m) { - return compiledByC1(m) == TriState.Yes; + return TestFrameworkExecution.isC1Compiled(m); } public static boolean isC2Compiled(Method m) { - return compiledByC2(m) == TriState.Yes; + return TestFrameworkExecution.isC2Compiled(m); } public static boolean isCompiledAtLevel(Method m, CompLevel compLevel) { - return compiledAtLevel(m, compLevel) == TriState.Yes; + return TestFrameworkExecution.isCompiledAtLevel(m, compLevel); } public static void assertDeoptimizedByC1(Method m) { - TestRun.check(compiledByC1(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized by C1"); + TestFrameworkExecution.assertDeoptimizedByC1(m); } public static void assertDeoptimizedByC2(Method m) { - TestRun.check(compiledByC2(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized by C2"); + TestFrameworkExecution.assertDeoptimizedByC2(m); } public static void assertCompiledByC1(Method m) { - TestRun.check(compiledByC1(m) != TriState.No, m + " should have been C1 compiled"); + TestFrameworkExecution.assertCompiledByC1(m); } public static void assertCompiledByC2(Method m) { - TestRun.check(compiledByC2(m) != TriState.No, m + " should have been C2 compiled"); + TestFrameworkExecution.assertCompiledByC2(m); } - public static void assertCompiledAtLevel(Method m, CompLevel level) { - TestRun.check(compiledAtLevel(m, level) != TriState.No, m + " should have been compiled at level " + level.name()); + public static void assertCompiledAtLevel(Method m, CompLevel compLevel) { + TestFrameworkExecution.assertCompiledAtLevel(m, compLevel); } public static void assertNotCompiled(Method m) { - TestRun.check(!WHITE_BOX.isMethodCompiled(m, false) && !WHITE_BOX.isMethodCompiled(m, true), - m + " should not have been compiled"); + TestFrameworkExecution.assertNotCompiled(m); } public static void assertCompiled(Method m) { - TestRun.check(WHITE_BOX.isMethodCompiled(m, false) || WHITE_BOX.isMethodCompiled(m, true), - m + " should have been compiled"); + TestFrameworkExecution.assertCompiled(m); } - public static String getLastVmOutput() { - return lastVmOutput; + public static String getLastVMOutput() { + return lastVMOutput; } - /* - * End of public interface - */ - private void doRunWithScenarios() { + private void installWhiteBox() { + try { + ClassFileInstaller.main(WhiteBox.class.getName()); + } catch (Exception e) { + throw new Error("failed to install whitebox classes", e); + } + } + + private void startWithScenarios() { Map exceptionMap = new HashMap<>(); Set scenarioIndecies = new HashSet<>(); for (Scenario scenario : scenarios) { @@ -338,7 +198,7 @@ private void doRunWithScenarios() { "Cannot define two scenarios with the same index " + scenarioIndex); scenarioIndecies.add(scenarioIndex); try { - runTestVM(scenario); + start(scenario); } catch (Exception e) { exceptionMap.put(String.valueOf(scenarioIndex), e); } @@ -365,134 +225,58 @@ private void doRunWithScenarios() { } } - // Only called by tests testing the framework itself. Accessed by reflection. Do not expose this to normal users. - private static void runTestsOnSameVM(Class testClass) { - if (testClass == null) { - StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - testClass = walker.getCallerClass(); - } - TestFramework framework = new TestFramework(testClass); - framework.runTestsOnSameVM(); - } - - private void runTestsOnSameVM() { - if (helperClasses != null) { - for (Class helperClass : helperClasses) { - // Process the helper classes and apply the explicit compile commands - processExplicitCompileCommands(helperClass); - } - } - parseTestClass(); - runTests(); - } - - private void runTestVM(Scenario scenario) { + private void start(Scenario scenario) { if (scenario != null && !scenario.isEnabled()) { System.out.println("Disabled scenario #" + scenario.getIndex() + "! This scenario is not present in set flag -DScenarios " + "and is therefore not executed."); return; } - ArrayList cmds = prepareTestVmFlags(scenario); - OutputAnalyzer oa; - try { - // Calls 'main' of this class to run all specified tests with commands 'cmds'. - oa = ProcessTools.executeTestJvm(cmds); - } catch (Exception e) { - throw new TestFrameworkException("Error while executing Test VM", e); - } - String output = oa.getOutput(); - lastVmOutput = output; - if (scenario != null) { - scenario.setVMOutput(output); - } - - final int exitCode = oa.getExitValue(); - if (VERBOSE || exitCode != 0) { - System.out.println(" ----- OUTPUT -----"); - System.out.println(output); - - } - if (exitCode != 0) { - throwTestException(oa, exitCode); - } - - if (VERIFY_IR) { - IRMatcher irMatcher = new IRMatcher(output, testClass); - irMatcher.applyRules(); - } - } - - private ArrayList prepareTestVmFlags(Scenario scenario) { - String[] vmInputArguments = InputArguments.getVmInputArgs(); ArrayList cmds = new ArrayList<>(); + cmds.add("-Dtest.jdk=" + Utils.TEST_JDK); + cmds.add("-cp"); + cmds.add(Utils.TEST_CLASS_PATH); + cmds.add("-Xbootclasspath/a:."); + cmds.add("-XX:+UnlockDiagnosticVMOptions"); + cmds.add("-XX:+WhiteBoxAPI"); if (!PREFER_COMMAND_LINE_FLAGS) { - cmds.addAll(Arrays.asList(vmInputArguments)); + cmds.addAll(Arrays.asList(InputArguments.getVmInputArgs())); } - if (scenario != null) { System.out.println("Running Scenario #" + scenario.getIndex()); cmds.addAll(scenario.getFlags()); } - setupIrVerificationFlags(testClass, cmds); - - if (VERIFY_VM) { - cmds.addAll(Arrays.asList(verifyFlags)); - } - - cmds.addAll(Arrays.asList(fixedDefaultFlags)); - if (COMPILE_COMMANDS) { - cmds.addAll(Arrays.asList(compileCommandFlags)); - } - - // TODO: Only for debugging - if (cmds.get(0).startsWith("-agentlib")) { - cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=n,server=y"); - } - if (PREFER_COMMAND_LINE_FLAGS) { - // Prefer flags set via the command line over the ones set by scenarios. - cmds.addAll(Arrays.asList(vmInputArguments)); + cmds.addAll(Arrays.asList(InputArguments.getVmInputArgs())); } - - cmds.add(getClass().getCanonicalName()); + cmds.add(TestFrameworkRunner.class.getCanonicalName()); cmds.add(testClass.getCanonicalName()); if (helperClasses != null) { helperClasses.forEach(c -> cmds.add(c.getCanonicalName())); } - return cmds; - } - private void setupIrVerificationFlags(Class testClass, ArrayList cmds) { - if (VERIFY_IR && cmds.stream().anyMatch(flag -> flag.startsWith("-XX:CompileThreshold"))) { - // Disable IR verification if non-default CompileThreshold is set - if (VERBOSE) { - System.out.println("Disabled IR verification due to CompileThreshold flag"); - } - VERIFY_IR = false; - } else if (!VERIFY_IR && REQUESTED_VERIFY_IR) { - System.out.println("IR Verification disabled either due to not running a debug build, running with -Xint, or other " + - "VM flags that make the verification inaccurate or impossible (e.g. running with C1 only)."); + OutputAnalyzer oa; + try { + oa = ProcessTools.executeProcess(ProcessTools.createTestJvm(cmds)); + } catch (Exception e) { + throw new TestRunException("Failed to execute test VM", e); } - if (VERIFY_IR) { - // Add print flags for IR verification - cmds.addAll(Arrays.asList(printFlags)); - addBoolOptionForClass(cmds, testClass, "PrintIdeal"); - addBoolOptionForClass(cmds, testClass, "PrintOptoAssembly"); - // Always trap for exception throwing to not confuse IR verification - cmds.add("-XX:-OmitStackTraceInFastThrow"); - cmds.add("-DPrintValidIRRules=true"); - } else { - cmds.add("-DPrintValidIRRules=false"); + lastVMOutput = oa.getOutput(); + if (scenario != null) { + scenario.setVMOutput(lastVMOutput); + } + final int exitCode = oa.getExitValue(); + if (VERBOSE && exitCode == 0) { + System.out.println(lastVMOutput); } - } - private void addBoolOptionForClass(ArrayList cmds, Class testClass, String option) { - cmds.add("-XX:CompileCommand=option," + testClass.getCanonicalName() + "::*,bool," + option + ",true"); + if (exitCode != 0) { + throwTestException(oa, exitCode); + } } - private void throwTestException(OutputAnalyzer oa, int exitCode) { + private static void throwTestException(OutputAnalyzer oa, int exitCode) { String stdErr = oa.getStderr(); if (stdErr.contains("TestFormat.reportIfAnyFailures")) { Pattern pattern = Pattern.compile("Violations \\(\\d+\\)[\\s\\S]*(?=/============/)"); @@ -500,811 +284,13 @@ private void throwTestException(OutputAnalyzer oa, int exitCode) { TestFramework.check(matcher.find(), "Must find violation matches"); throw new TestFormatException("\n\n" + matcher.group()); } else { - throw new TestRunException("\nVM exited with " + exitCode + "\n\nError Output:\n" + stdErr); - } - } - - private void parseTestClass() { - addReplay(); - processExplicitCompileCommands(testClass); - setupTests(); - setupCheckAndRunMethods(); - - // All remaining tests are simple base tests without check or specific way to run them. - addBaseTests(); - TestFormat.reportIfAnyFailures(); - declaredTests.clear(); - testMethodMap.clear(); - } - - private void addBaseTests() { - declaredTests.forEach((m, test) -> { - if (test.getAttachedMethod() == null) { - try { - Arguments argumentsAnno = getAnnotation(m, Arguments.class); - TestFormat.check(argumentsAnno != null || m.getParameterCount() == 0, "Missing @Arguments annotation to define arguments of " + m); - allTests.put(m, new BaseTest(test)); - } catch (TestFormatException e) { - // Failure logged. Continue and report later. - } - } - }); - } - - private void addReplay() { - if (DUMP_REPLAY) { - // Generate replay compilation files - String directive = "[{ match: \"*.*\", DumpReplay: true }]"; - TestFramework.check(WHITE_BOX.addCompilerDirective(directive) == 1, "Failed to add DUMP_REPLAY directive"); - } - } - - private void processExplicitCompileCommands(Class clazz) { - if (!XCOMP) { - // Don't control compilations if -Xcomp is enabled. - Method[] methods = clazz.getDeclaredMethods(); - for (Method m : methods) { - try { - applyIndependentCompilationCommands(m); - - if (STRESS_CC) { - if (getAnnotation(m, Test.class) != null) { - excludeCompilationRandomly(m); - } - } - } catch (TestFormatException e) { - // Failure logged. Continue and report later. - } - } - - // Only force compilation now because above annotations affect inlining - for (Method m : methods) { - try { - applyForceCompileCommand(m); - } catch (TestFormatException e) { - // Failure logged. Continue and report later. - } - } - } - } - - static boolean excludeCompilationRandomly(Method m) { - // Exclude some methods from compilation with C2 to stress test the calling convention - boolean exclude = Utils.getRandomInstance().nextBoolean(); - if (exclude) { - System.out.println("Excluding from C2 compilation: " + m); - WHITE_BOX.makeMethodNotCompilable(m, CompLevel.C2.getValue(), false); - WHITE_BOX.makeMethodNotCompilable(m, CompLevel.C2.getValue(), true); - } - return exclude; - } - - private void applyIndependentCompilationCommands(Method m) { - ForceInline forceInlineAnno = getAnnotation(m, ForceInline.class); - DontInline dontInlineAnno = getAnnotation(m, DontInline.class); - ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); - DontCompile dontCompileAnno = getAnnotation(m, DontCompile.class); - checkCompilationCommandAnnotations(m, forceInlineAnno, dontInlineAnno, forceCompileAnno, dontCompileAnno); - // First handle inline annotations - if (dontInlineAnno != null) { - WHITE_BOX.testSetDontInlineMethod(m, true); - } else if (forceInlineAnno != null) { - WHITE_BOX.testSetForceInlineMethod(m, true); - } - if (dontCompileAnno != null) { - CompLevel compLevel = dontCompileAnno.value(); - TestFormat.check(compLevel == CompLevel.C1 || compLevel == CompLevel.C2 || compLevel == CompLevel.ANY, - "Can only specify compilation level C1 (no individual C1 levels), " + - "C2 or ANY (no compilation, same as specifying anything) in @DontCompile at " + m); - dontCompileMethodAtLevel(m, compLevel); - } - } - - private void checkCompilationCommandAnnotations(Method m, ForceInline forceInlineAnno, DontInline dontInlineAnno, ForceCompile forceCompileAnno, DontCompile dontCompileAnno) { - Test testAnno = getAnnotation(m, Test.class); - Run runAnno = getAnnotation(m, Run.class); - Check checkAnno = getAnnotation(m, Check.class); - TestFormat.check((testAnno == null && runAnno == null && checkAnno == null) || Stream.of(forceCompileAnno, dontCompileAnno, forceInlineAnno, dontInlineAnno).noneMatch(Objects::nonNull), - "Cannot use explicit compile command annotations (@ForceInline, @DontInline," + - "@ForceCompile or @DontCompile) together with @Test, @Check or @Run: " + m + ". Use compLevel in @Test for fine tuning."); - if (Stream.of(forceInlineAnno, dontCompileAnno, dontInlineAnno).filter(Objects::nonNull).count() > 1) { - // Failure - TestFormat.check(dontCompileAnno == null || dontInlineAnno == null, - "@DontInline is implicitely done with @DontCompile annotation at " + m); - TestFormat.fail("Cannot mix @ForceInline, @DontInline and @DontCompile at the same time at " + m); - } - TestFormat.check(forceInlineAnno == null || dontInlineAnno == null, "Cannot have @ForceInline and @DontInline at the same time at " + m); - if (forceCompileAnno != null && dontCompileAnno != null) { - CompLevel forceCompile = forceCompileAnno.value(); - CompLevel dontCompile = dontCompileAnno.value(); - TestFormat.check(dontCompile != CompLevel.ANY, - "Cannot have @DontCompile(CompLevel.ANY) and @ForceCompile at the same time at " + m); - TestFormat.check(forceCompile != CompLevel.ANY, - "Cannot have @ForceCompile(CompLevel.ANY) and @DontCompile at the same time at " + m); - TestFormat.check(!CompLevel.overlapping(dontCompile, forceCompile), - "Overlapping compilation levels with @ForceCompile and @DontCompile at " + m); - } - } - - private void dontCompileMethod(Method m) { - WHITE_BOX.makeMethodNotCompilable(m, CompLevel.ANY.getValue(), true); - WHITE_BOX.makeMethodNotCompilable(m, CompLevel.ANY.getValue(), false); - WHITE_BOX.testSetDontInlineMethod(m, true); - } - - private void dontCompileMethodAtLevel(Method m, CompLevel compLevel) { - if (VERBOSE) { - System.out.println("dontCompileMethodAtLevel " + m + " , level = " + compLevel.name()); - } - WHITE_BOX.makeMethodNotCompilable(m, compLevel.getValue(), true); - WHITE_BOX.makeMethodNotCompilable(m, compLevel.getValue(), false); - if (compLevel == CompLevel.ANY) { - WHITE_BOX.testSetDontInlineMethod(m, true); - } - } - - private void applyForceCompileCommand(Method m) { - ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); - if (forceCompileAnno != null) { - TestFormat.check(forceCompileAnno.value() != CompLevel.SKIP, - "Cannot define compilation level SKIP in @ForceCompile at " + m); - enqueueMethodForCompilation(m, forceCompileAnno.value()); - } - } - - static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { - if (TestFramework.VERBOSE) { - System.out.println("enqueueMethodForCompilation " + m + ", level = " + compLevel); - } - compLevel = restrictCompLevel(compLevel); - WHITE_BOX.enqueueMethodForCompilation(m, compLevel.getValue()); - } - - private void setupTests() { - boolean hasIncludeList = includeList != null; - boolean hasExcludeList = excludeList != null; - for (Method m : testClass.getDeclaredMethods()) { - Test testAnno = getAnnotation(m, Test.class); - try { - if (testAnno != null) { - if (hasIncludeList && includeList.contains(m.getName()) && (!hasExcludeList || !excludeList.contains(m.getName()))) { - addTest(m); - } else if (hasExcludeList && !excludeList.contains(m.getName())) { - addTest(m); - } else { - addTest(m); - } - } else { - TestFormat.checkNoThrow(!m.isAnnotationPresent(IR.class), "Found @IR annotation on non-@Test method " + m); - TestFormat.checkNoThrow(!m.isAnnotationPresent(Warmup.class) || getAnnotation(m, Run.class) != null, - "Found @Warmup annotation on non-@Test or non-@Run method " + m); - } - } catch (TestFormatException e) { - // Failure logged. Continue and report later. - } - } - if (PRINT_VALID_IR_RULES) { - irMatchRulePrinter.emit(); - } - } - - private void addTest(Method m) { - Test testAnno = getAnnotation(m, Test.class); - checkTestAnnotations(m, testAnno); - Warmup warmup = getAnnotation(m, Warmup.class); - int warmupIterations = WARMUP_ITERATIONS; - if (warmup != null) { - warmupIterations = warmup.value(); - TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + m); - } - - boolean osrOnly = getAnnotation(m, OSRCompileOnly.class) != null; - - if (PRINT_VALID_IR_RULES) { - irMatchRulePrinter.emitRuleEncoding(m); - } - - if (!XCOMP) { - // Don't inline test methods. Don't care when -Xcomp set. - WHITE_BOX.testSetDontInlineMethod(m, true); - } - CompLevel compLevel = restrictCompLevel(testAnno.compLevel()); - if (FLIP_C1_C2) { - compLevel = flipCompLevel(compLevel); - } - DeclaredTest test = new DeclaredTest(m, ArgumentValue.getArguments(m), compLevel, warmupIterations, osrOnly); - declaredTests.put(m, test); - testMethodMap.put(m.getName(), m); - } - - private void checkTestAnnotations(Method m, Test testAnno) { - TestFormat.check(!testMethodMap.containsKey(m.getName()), - "Cannot overload two @Test methods: " + m + ", " + testMethodMap.get(m.getName())); - TestFormat.check(testAnno != null, m + " must be a method with a @Test annotation"); - - Check checkAnno = getAnnotation(m, Check.class); - Run runAnno = getAnnotation(m, Run.class); - TestFormat.check(checkAnno == null && runAnno == null, - m + " has invalid @Check or @Run annotation while @Test annotation is present."); - - TestFormat.checkNoThrow(!Arrays.asList(m.getParameterTypes()).contains(TestInfo.class), - "Cannot use of " + TestInfo.class + " as parameter type at @Test method " + m); - - TestFormat.checkNoThrow(!m.getReturnType().equals(TestInfo.class), - "Cannot use of " + TestInfo.class + " as return type at @Test method " + m); - } - - - // Get the appropriate level as permitted by the test scenario and VM options. - private static CompLevel restrictCompLevel(CompLevel compLevel) { - if (!USE_COMPILER) { - return CompLevel.SKIP; - } - if (compLevel == CompLevel.ANY) { - // Use highest available compilation level by default (usually C2). - compLevel = TIERED_COMPILATION_STOP_AT_LEVEL; - } - if (!TIERED_COMPILATION && compLevel.getValue() < CompLevel.C2.getValue()) { - return CompLevel.SKIP; - } - if (TIERED_COMPILATION && compLevel.getValue() > TIERED_COMPILATION_STOP_AT_LEVEL.getValue()) { - return CompLevel.SKIP; - } - return compLevel; - } - - private static CompLevel flipCompLevel(CompLevel compLevel) { - switch (compLevel) { - case C1, C1_LIMITED_PROFILE, C1_FULL_PROFILE -> { - return CompLevel.C2; - } - case C2 -> { - return CompLevel.C1; - } - } - return compLevel; - } - - private void setupCheckAndRunMethods() { - for (Method m : testClass.getDeclaredMethods()) { - Check checkAnno = getAnnotation(m, Check.class); - Run runAnno = getAnnotation(m, Run.class); - Arguments argumentsAnno = getAnnotation(m, Arguments.class); - try { - TestFormat.check(argumentsAnno == null || (checkAnno == null && runAnno == null), "Cannot have @Argument annotation in combination with @Run or @Check at " + m); - if (checkAnno != null) { - addCheckedTest(m, checkAnno, runAnno); - } else if (runAnno != null) { - addCustomRunTest(m, runAnno); - } - } catch (TestFormatException e) { - // Failure logged. Continue and report later. - } - } - } - - private void addCheckedTest(Method m, Check checkAnno, Run runAnno) { - TestFormat.check(runAnno == null, m + " has invalid @Run annotation while @Check annotation is present."); - Method testMethod = testMethodMap.get(checkAnno.test()); - TestFormat.check(testMethod != null,"Did not find associated test method \"" + m.getDeclaringClass().getName() - + "." + checkAnno.test() + "\" for @Check at " + m); - boolean firstParameterTestInfo = m.getParameterCount() > 0 && m.getParameterTypes()[0].equals(TestInfo.class); - boolean secondParameterTestInfo = m.getParameterCount() > 1 && m.getParameterTypes()[1].equals(TestInfo.class); - - CheckedTest.Parameter parameter = null; - Class testReturnType = testMethod.getReturnType(); - switch (m.getParameterCount()) { - case 0 -> parameter = CheckedTest.Parameter.NONE; - case 1 -> { - TestFormat.check(firstParameterTestInfo || m.getParameterTypes()[0] == testReturnType, - "Single-parameter version of @Check method " + m + " must match return type of @Test " + testMethod); - parameter = firstParameterTestInfo ? CheckedTest.Parameter.TEST_INFO_ONLY : CheckedTest.Parameter.RETURN_ONLY; - } - case 2 -> { - TestFormat.check(m.getParameterTypes()[0] == testReturnType && secondParameterTestInfo, - "Two-parameter version of @Check method " + m + " must provide as first parameter the same" - + " return type as @Test method " + testMethod + " and as second parameter an object of " + TestInfo.class); - parameter = CheckedTest.Parameter.BOTH; - } - default -> TestFormat.fail("@Check method " + m + " must provide either a none, single or two-parameter variant."); - } - - DeclaredTest test = declaredTests.get(testMethod); - TestFormat.check(test != null, "Missing @Test annotation for associated test method " + testMethod + " for @Check at " + m); - Method attachedMethod = test.getAttachedMethod(); - TestFormat.check(attachedMethod == null, - "Cannot use @Test " + testMethod + " for more than one @Run or one @Check method. Found: " + m + ", " + attachedMethod); - dontCompileMethod(m); - // Don't inline check methods - WHITE_BOX.testSetDontInlineMethod(m, true); - CheckedTest checkedTest = new CheckedTest(test, m, checkAnno, parameter); - allTests.put(testMethod, checkedTest); - } - - private void addCustomRunTest(Method m, Run runAnno) { - Method testMethod = testMethodMap.get(runAnno.test()); - DeclaredTest test = declaredTests.get(testMethod); - checkCustomRunTest(m, runAnno, testMethod, test); - dontCompileMethod(m); - // Don't inline run methods - WHITE_BOX.testSetDontInlineMethod(m, true); - CustomRunTest customRunTest = new CustomRunTest(test, m, getAnnotation(m, Warmup.class), runAnno); - allTests.put(m, customRunTest); - } - - private void checkCustomRunTest(Method m, Run runAnno, Method testMethod, DeclaredTest test) { - TestFormat.check(testMethod != null, "Did not find associated @Test method \"" + m.getDeclaringClass().getName() - + "." + runAnno.test() + "\" specified in @Run at " + m); - TestFormat.check(test != null, "Missing @Test annotation for associated test method " + runAnno.test() + " for @Run at " + m); - Method attachedMethod = test.getAttachedMethod(); - TestFormat.check(attachedMethod == null, - "Cannot use @Test " + testMethod + " for more than one @Run/@Check method. Found: " + m + ", " + attachedMethod); - TestFormat.check(!test.hasArguments(), "Cannot use @Arguments at test method " + testMethod + " in combination with @Run method " + m); - TestFormat.check(m.getParameterCount() == 0 || (m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(TestInfo.class)), - "@Run method " + m + " must specify either no parameter or exactly one of " + TestInfo.class); - Warmup warmupAnno = getAnnotation(testMethod, Warmup.class); - TestFormat.checkNoThrow(warmupAnno == null, - "Cannot set @Warmup at @Test method " + testMethod + " when used with its @Run method " + m + ". Use @Warmup at @Run method instead."); - warmupAnno = getAnnotation(m, Warmup.class); - TestFormat.checkNoThrow(warmupAnno == null || runAnno.mode() != RunMode.STANDALONE, - "Cannot set @Warmup at @Run method " + m + " when used with RunMode.STANDALONE. The @Run method is only invoked once."); - OSRCompileOnly osrAnno = getAnnotation(testMethod, OSRCompileOnly.class); - TestFormat.checkNoThrow(osrAnno == null || runAnno.mode() != RunMode.STANDALONE, - "Cannot set @OSRCompileOnly at @Run method " + m + " when used with RunMode.STANDALONE. The @Run method is responsible for triggering compilation."); - } - - private static T getAnnotation(Method m, Class c) { - T[] annos = m.getAnnotationsByType(c); - TestFormat.check(annos.length < 2, m + " has duplicated annotations"); - return Arrays.stream(annos).findFirst().orElse(null); - } - - private void runTests() { - TreeMap durations = (PRINT_TIMES || VERBOSE) ? new TreeMap<>() : null; - long startTime = System.nanoTime(); - Collection testCollection = allTests.values(); - if (SHUFFLE_TESTS) { - // Execute tests in random order (execution sequence affects profiling) - ArrayList shuffledList = new ArrayList<>(allTests.values()); - Collections.shuffle(shuffledList); - testCollection = shuffledList; - } - for (BaseTest test : testCollection) { - test.run(); - if (PRINT_TIMES || VERBOSE) { - long endTime = System.nanoTime(); - long duration = (endTime - startTime); - durations.put(duration, test.getTestName()); - if (VERBOSE) { - System.out.println("Done " + test.getTestName() + ": " + duration + " ns = " + (duration / 1000000) + " ms"); - } - } - if (GC_AFTER) { - System.out.println("doing GC"); - System.gc(); - } - } - - // Print execution times - if (PRINT_TIMES) { - System.out.println("\n\nTest execution times:"); - for (Map.Entry entry : durations.entrySet()) { - System.out.format("%-10s%15d ns\n", entry.getValue() + ":", entry.getKey()); - } + throw new TestRunException("\nTestFramework runner VM exited with " + exitCode + "\n\nError Output:\n" + stdErr); } } static void check(boolean test, String failureMessage) { if (!test) { - throw new TestFrameworkException("Internal TestFramework exception - please file a bug:\n" + failureMessage); - } - } - - enum TriState { - Maybe, - Yes, - No - } - - private static TriState compiledByC1(Method m) { - TriState triState = compiledAtLevel(m, CompLevel.C1); - if (triState != TriState.No) { - return triState; + throw new TestFrameworkException("Internal TestFrameworkExecution exception - please file a bug:\n" + failureMessage); } - triState = compiledAtLevel(m, CompLevel.C1_LIMITED_PROFILE); - if (triState != TriState.No) { - return triState; - } - triState = compiledAtLevel(m, CompLevel.C1_FULL_PROFILE); - return triState; - } - - private static TriState compiledByC2(Method m) { - return compiledAtLevel(m, CompLevel.C2); - } - - private static TriState compiledAtLevel(Method m, CompLevel level) { - if (!TestFramework.USE_COMPILER || TestFramework.XCOMP || TestFramework.TEST_C1 || - (TestFramework.STRESS_CC && !WHITE_BOX.isMethodCompilable(m, level.getValue(), false))) { - return TriState.Maybe; - } - if (WHITE_BOX.isMethodCompiled(m, false) - && WHITE_BOX.getMethodCompilationLevel(m, false) == level.getValue()) { - return TriState.Yes; - } - return TriState.No; } } - -// Errors in the framework -class TestFrameworkException extends RuntimeException { - public TestFrameworkException(String message) { - super(message); - } - public TestFrameworkException(String message, Exception e) { - super(message, e); - } -} - -// Checked exceptions in the framework to propagate error handling. -class CheckedTestFrameworkException extends Exception { -} - -class DeclaredTest { - private final Method testMethod; - private final ArgumentValue[] arguments; - private final int warmupIterations; - private final CompLevel compLevel; - private final boolean osrOnly; - private Method attachedMethod; - - public DeclaredTest(Method testMethod, ArgumentValue[] arguments, CompLevel compLevel, int warmupIterations, boolean osrOnly) { - // Make sure we can also call non-public or public methods in package private classes - testMethod.setAccessible(true); - this.testMethod = testMethod; - this.compLevel = compLevel; - this.arguments = arguments; - this.warmupIterations = warmupIterations; - this.osrOnly = osrOnly; - this.attachedMethod = null; - } - - public Method getTestMethod() { - return testMethod; - } - - public CompLevel getCompLevel() { - return compLevel; - } - - public int getWarmupIterations() { - return warmupIterations; - } - - public boolean isOSROnly() { - return osrOnly; - } - - public boolean hasArguments() { - return arguments != null; - } - - public Object[] getArguments() { - return Arrays.stream(arguments).map(ArgumentValue::getArgument).toArray(); - } - - public void setAttachedMethod(Method m) { - attachedMethod = m; - } - - public Method getAttachedMethod() { - return attachedMethod; - } - - public void printFixedRandomArguments() { - if (hasArguments()) { - boolean hasRandomArgs = false; - StringBuilder builder = new StringBuilder("Random Arguments: "); - for (int i = 0; i < arguments.length; i++) { - ArgumentValue argument = arguments[i]; - if (argument.isFixedRandom()) { - hasRandomArgs = true; - builder.append("arg ").append(i).append(": ").append(argument.getArgument()).append(", "); - } - } - if (hasRandomArgs) { - // Drop the last comma and space. - builder.setLength(builder.length() - 2); - System.out.println(builder.toString()); - } - } - } - - public Object invoke(Object obj, Object... args) { - try { - return testMethod.invoke(obj, args); - } catch (Exception e) { - throw new TestRunException("There was an error while invoking @Test method " + testMethod, e); - } - } -} - -class BaseTest { - private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); - private static final int OSR_TEST_TIMEOUT = Integer.parseInt(System.getProperty("OSRTestTimeOut", "5000")); - private static final int TEST_COMPILATION_TIMEOUT = Integer.parseInt(System.getProperty("TestCompilationTimeout", "5000")); - - protected final DeclaredTest test; - protected final Method testMethod; - protected final TestInfo testInfo; - protected final Object invocationTarget; - private final boolean shouldCompile; - protected int warmupIterations; - - public BaseTest(DeclaredTest test) { - this.test = test; - this.testMethod = test.getTestMethod(); - this.testInfo = new TestInfo(testMethod); - this.warmupIterations = test.getWarmupIterations(); - Class clazz = testMethod.getDeclaringClass(); - if (Modifier.isStatic(testMethod.getModifiers())) { - this.invocationTarget = null; - } else { - try { - Constructor constructor = clazz.getDeclaredConstructor(); - constructor.setAccessible(true); - this.invocationTarget = constructor.newInstance(); - } catch (Exception e) { - throw new TestRunException("Could not create instance of " + clazz - + ". Make sure there is a constructor without arguments.", e); - } - } - if (!TestFramework.USE_COMPILER) { - this.shouldCompile = false; - } else if (TestFramework.STRESS_CC) { - this.shouldCompile = !TestFramework.excludeCompilationRandomly(testMethod); - } else { - this.shouldCompile = true; - } - } - - public String getTestName() { - return testMethod.getName(); - } - - public Method getAttachedMethod() { return null; } - - /** - * Run the associated test - */ - public void run() { - if (test.getCompLevel() == CompLevel.SKIP) { - // Exclude test if compilation level is SKIP either set through test or by not matching the current VM flags. - return; - } - if (TestFramework.VERBOSE) { - System.out.println("Starting " + testMethod); - } - test.printFixedRandomArguments(); - for (int i = 0; i < warmupIterations; i++) { - runMethod(); - } - testInfo.setWarmUpFinished(); - - if (test.isOSROnly()) { - compileOSRAndRun(); // TODO: Keep this? - } else { - if (shouldCompile) { - compileTest(); - } - // Always run method. - runMethod(); - } - } - - protected void runMethod() { - verify(invokeTestMethod()); - } - - private Object invokeTestMethod() { - try { - if (test.hasArguments()) { - return testMethod.invoke(invocationTarget, test.getArguments()); - } else { - return testMethod.invoke(invocationTarget); - } - } catch (Exception e) { - throw new TestRunException("There was an error while invoking @Test method " + testMethod, e); - } - } - - private void compileOSRAndRun() { - final boolean maybeCodeBufferOverflow = (TestFramework.TEST_C1 && TestFramework.VERIFY_OOPS); - final long started = System.currentTimeMillis(); - boolean stateCleared = false; - while (true) { - long elapsed = System.currentTimeMillis() - started; - int level = WHITE_BOX.getMethodCompilationLevel(testMethod); - if (maybeCodeBufferOverflow && elapsed > 5000 - && (!WHITE_BOX.isMethodCompiled(testMethod, false) || level != test.getCompLevel().getValue())) { - retryDisabledVerifyOops(stateCleared); - stateCleared = true; - } else { - runMethod(); - } - - boolean b = WHITE_BOX.isMethodCompiled(testMethod, false); - if (TestFramework.VERBOSE) { - System.out.println("Is " + testMethod + " compiled? " + b); - } - if (b || TestFramework.XCOMP || TestFramework.STRESS_CC || !TestFramework.USE_COMPILER) { - // Don't control compilation if -Xcomp is enabled, or if compiler is disabled - break; - } - Asserts.assertTrue(OSR_TEST_TIMEOUT < 0 || elapsed < OSR_TEST_TIMEOUT, testMethod + " not compiled after " + OSR_TEST_TIMEOUT + " ms"); - } - } - - private void retryDisabledVerifyOops(boolean stateCleared) { - System.out.println("Temporarily disabling VerifyOops"); - try { - WHITE_BOX.setBooleanVMFlag("VerifyOops", false); - if (!stateCleared) { - WHITE_BOX.clearMethodState(testMethod); - } - runMethod(); - } finally { - WHITE_BOX.setBooleanVMFlag("VerifyOops", true); - System.out.println("Re-enabled VerifyOops"); - } - } - - private void compileTest() { - final boolean maybeCodeBufferOverflow = (TestFramework.TEST_C1 && TestFramework.VERIFY_OOPS); - final Method testMethod = test.getTestMethod(); - long started = System.currentTimeMillis(); - long elapsed = 0; - Asserts.assertTrue(WHITE_BOX.isMethodCompilable(testMethod, test.getCompLevel().getValue(), false)); - enqueueMethodForCompilation(); - - do { - if (!WHITE_BOX.isMethodQueuedForCompilation(testMethod)) { - if (elapsed > 0 && TestFramework.VERBOSE) { - System.out.println(testMethod + " is not in queue anymore due to compiling it simultaneously on a different level. Enqueue again."); - enqueueMethodForCompilation(); - } - } - if (maybeCodeBufferOverflow && elapsed > 1000 && !WHITE_BOX.isMethodCompiled(testMethod, false)) { - // Let's disable VerifyOops temporarily and retry. - WHITE_BOX.setBooleanVMFlag("VerifyOops", false); - WHITE_BOX.clearMethodState(testMethod); - enqueueMethodForCompilation(); - WHITE_BOX.setBooleanVMFlag("VerifyOops", true); - } - - if (WHITE_BOX.getMethodCompilationLevel(testMethod, false) == test.getCompLevel().getValue()) { - break; - } - elapsed = System.currentTimeMillis() - started; - } while (elapsed < TEST_COMPILATION_TIMEOUT); - TestRun.check(elapsed < TEST_COMPILATION_TIMEOUT, "Could not compile" + testMethod + " after " + TEST_COMPILATION_TIMEOUT/1000 + "s"); - checkCompilationLevel(); - } - - private void enqueueMethodForCompilation() { - TestFramework.enqueueMethodForCompilation(test.getTestMethod(), test.getCompLevel()); - } - - protected void checkCompilationLevel() { - CompLevel level = CompLevel.forValue(WHITE_BOX.getMethodCompilationLevel(testMethod)); - TestRun.check(level == test.getCompLevel(), - "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod); - } - - /** - * Verify the result - */ - public void verify(Object result) { /* no verification in BaseTests */ } -} - -class CheckedTest extends BaseTest { - private final Method checkMethod; - private final CheckAt checkAt; - private final Parameter parameter; - - enum Parameter { - NONE, RETURN_ONLY, TEST_INFO_ONLY, BOTH - } - - public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecification, Parameter parameter) { - super(test); - // Make sure we can also call non-public or public methods in package private classes - checkMethod.setAccessible(true); - test.setAttachedMethod(checkMethod); - this.checkMethod = checkMethod; - this.checkAt = checkSpecification.when(); - this.parameter = parameter; - } - - @Override - public Method getAttachedMethod() { return checkMethod; } - - @Override - public void verify(Object result) { - boolean shouldVerify = false; - switch (checkAt) { - case EACH_INVOCATION -> shouldVerify = true; - case COMPILED -> shouldVerify = !testInfo.isWarmUp(); - } - if (shouldVerify) { - try { - switch (parameter) { - case NONE -> checkMethod.invoke(invocationTarget); - case RETURN_ONLY -> checkMethod.invoke(invocationTarget, result); - case TEST_INFO_ONLY -> checkMethod.invoke(invocationTarget, testInfo); - case BOTH -> checkMethod.invoke(invocationTarget, result, testInfo); - } - } catch (Exception e) { - throw new TestRunException("There was an error while invoking @Check method " + checkMethod, e); - } - } - } -} - -class CustomRunTest extends BaseTest { - private final Method runMethod; - private final RunMode mode; - - public CustomRunTest(DeclaredTest test, Method runMethod, Warmup warmUpAnno, Run runSpecification) { - super(test); - // Make sure we can also call non-public or public methods in package private classes - runMethod.setAccessible(true); - test.setAttachedMethod(runMethod); - this.runMethod = runMethod; - this.mode = runSpecification.mode(); - this.warmupIterations = warmUpAnno != null ? warmUpAnno.value() : test.getWarmupIterations(); - TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + runMethod); - } - - @Override - public Method getAttachedMethod() { return runMethod; } - - @Override - public void run() { - switch (mode) { - case STANDALONE -> runMethod(); - case NORMAL -> super.run(); - } - } - - /** - * Do not directly run the test but rather the run method that is responsible for invoking the actual test. - */ - @Override - protected void runMethod() { - try { - if (runMethod.getParameterCount() == 1) { - runMethod.invoke(invocationTarget, testInfo); - } else { - runMethod.invoke(invocationTarget); - } - } catch (Exception e) { - throw new TestRunException("There was an error while invoking @Run method " + runMethod, e); - } - } - - @Override - protected void checkCompilationLevel() { - CompLevel level = CompLevel.forValue(WhiteBox.getWhiteBox().getMethodCompilationLevel(testMethod)); - if (level != test.getCompLevel()) { - String message = "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod + "."; - switch (mode) { - case STANDALONE -> message = message + "\nCheck your @Run method (invoked once) " + runMethod + " to ensure that " + testMethod + " will be complied at the requested level."; - case NORMAL -> message = message + "\nCheck your @Run method " + runMethod + " to ensure that " + testMethod + " is called at least once in each iteration."; - } - TestRun.fail(message); - } - } -} - - diff --git a/test/lib/testframework/TestFrameworkException.java b/test/lib/testframework/TestFrameworkException.java new file mode 100644 index 00000000000..8f2b09c62a6 --- /dev/null +++ b/test/lib/testframework/TestFrameworkException.java @@ -0,0 +1,11 @@ +package testframework; + +// Errors in the framework +class TestFrameworkException extends RuntimeException { + public TestFrameworkException(String message) { + super(message); + } + public TestFrameworkException(String message, Exception e) { + super(message, e); + } +} diff --git a/test/lib/testframework/TestFrameworkExecution.java b/test/lib/testframework/TestFrameworkExecution.java new file mode 100644 index 00000000000..f5818cb2299 --- /dev/null +++ b/test/lib/testframework/TestFrameworkExecution.java @@ -0,0 +1,1165 @@ +/* + * Copyright (c) 2021, 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 testframework; + +import jdk.test.lib.Asserts; +import jdk.test.lib.Platform; +import jdk.test.lib.Utils; +import jdk.test.lib.management.InputArguments; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import sun.hotspot.WhiteBox; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Stream; + + +public class TestFrameworkExecution { + private static final WhiteBox WHITE_BOX; + + static { + try { + WHITE_BOX = WhiteBox.getWhiteBox(); + } catch (UnsatisfiedLinkError e) { + System.err.println("Did you set up the jtreg test properly? Ensure that at least the following settings are set:"); + System.err.println(""" + * @library /testlibrary /test/lib /compiler/whitebox / + * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions + * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI""".indent(1)); + throw e; + } + } + + private static final boolean TIERED_COMPILATION = (Boolean)WHITE_BOX.getVMFlag("TieredCompilation"); + private static final CompLevel TIERED_COMPILATION_STOP_AT_LEVEL = CompLevel.forValue(((Long)WHITE_BOX.getVMFlag("TieredStopAtLevel")).intValue()); + static final boolean TEST_C1 = TIERED_COMPILATION && TIERED_COMPILATION_STOP_AT_LEVEL.getValue() < CompLevel.C2.getValue(); + + // User defined settings + static final boolean XCOMP = Platform.isComp(); +// private static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); + static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "true")); + private static final boolean PRINT_TIMES = Boolean.parseBoolean(System.getProperty("PrintTimes", "false")); + + private static final boolean COMPILE_COMMANDS = Boolean.parseBoolean(System.getProperty("CompileCommands", "true")) && !XCOMP; + static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); + static final boolean STRESS_CC = Boolean.parseBoolean(System.getProperty("StressCC", "false")); + private static final boolean REQUESTED_VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); + private static boolean VERIFY_IR = REQUESTED_VERIFY_IR && USE_COMPILER && !XCOMP && !STRESS_CC && !TEST_C1 && COMPILE_COMMANDS + && Platform.isDebugBuild() && !Platform.isInt(); + private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false")) && Platform.isDebugBuild(); + private static final String TESTLIST = System.getProperty("Testlist", ""); + private static final String EXCLUDELIST = System.getProperty("Exclude", ""); + public static final int WARMUP_ITERATIONS = Integer.parseInt(System.getProperty("Warmup", "2000")); + private static final boolean DUMP_REPLAY = Boolean.parseBoolean(System.getProperty("DumpReplay", "false")); + private static final boolean GC_AFTER = Boolean.parseBoolean(System.getProperty("GCAfter", "false")); + private static final boolean SHUFFLE_TESTS = Boolean.parseBoolean(System.getProperty("ShuffleTests", "true")); + private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); + private static final boolean PRINT_VALID_IR_RULES = Boolean.parseBoolean(System.getProperty("PrintValidIRRules", "false")); + protected static final long PerMethodTrapLimit = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); + protected static final boolean ProfileInterpreter = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); + private static final boolean FLIP_C1_C2 = Boolean.parseBoolean(System.getProperty("FlipC1C2", "false")); + + private final String[] fixedDefaultFlags; + private final String[] compileCommandFlags; + private final String[] printFlags; + private final String[] verifyFlags; + + static final boolean VERIFY_OOPS = (Boolean)WHITE_BOX.getVMFlag("VerifyOops"); + + private final HashMap declaredTests = new HashMap<>(); + private final LinkedHashMap allTests = new LinkedHashMap<>(); // Keep order + private final HashMap testMethodMap = new HashMap<>(); + private final List excludeList; + private final List includeList; + private List> helperClasses = null; + private final IREncodingPrinter irMatchRulePrinter; + private final Class testClass; + + private TestFrameworkExecution(Class testClass) { + TestRun.check(testClass != null, "Test class cannot be null"); + this.testClass = testClass; + // These flags can be overridden + fixedDefaultFlags = initDefaultFlags(); + compileCommandFlags = initCompileCommandFlags(); + printFlags = initPrintFlags(); + verifyFlags = initVerifyFlags(); + + this.includeList = createTestFilterList(TESTLIST, testClass); + this.excludeList = createTestFilterList(EXCLUDELIST, testClass); + + if (PRINT_VALID_IR_RULES) { + irMatchRulePrinter = new IREncodingPrinter(); + } else { + irMatchRulePrinter = null; + } + } + + protected String[] initDefaultFlags() { + return new String[] {"-XX:-BackgroundCompilation"}; + } + + protected String[] initCompileCommandFlags() { + return new String[] {"-XX:CompileCommand=quiet"}; + } + + protected String[] initPrintFlags() { + return new String[] {"-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions"}; + } + + protected String[] initVerifyFlags() { + return new String[] { + "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", "-XX:+VerifyBeforeGC", + "-XX:+VerifyAfterGC", "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing"}; + } + + private List createTestFilterList(String list, Class testClass) { + List filterList = null; + if (!list.isEmpty()) { + String classPrefix = testClass.getSimpleName() + "."; + filterList = new ArrayList<>(Arrays.asList(list.split(","))); + for (int i = filterList.size() - 1; i >= 0; i--) { + String test = filterList.get(i); + if (test.indexOf(".") > 0) { + if (test.startsWith(classPrefix)) { + test = test.substring(classPrefix.length()); + filterList.set(i, test); + } else { + filterList.remove(i); + } + } + } + } + return filterList; + } + + public static void main(String[] args) { + String testClassName = args[0]; + System.out.println("Framework main(), about to run tests in class " + testClassName); + Class testClass; + try { + testClass = Class.forName(testClassName); + } catch (Exception e) { + throw new TestRunException("Could not find test class " + testClassName, e); + } + + TestFrameworkExecution framework = new TestFrameworkExecution(testClass); + framework.addHelperClasses(args); + framework.runTestsOnSameVM(); + } + + private void addHelperClasses(String[] args) { + Class[] helperClasses = getHelperClasses(args); + if (helperClasses != null) { + TestRun.check(Arrays.stream(helperClasses).noneMatch(Objects::isNull), "A Helper class cannot be null"); + this.helperClasses = new ArrayList<>(); + + for (Class helperClass : helperClasses) { + TestRun.check(!this.helperClasses.contains(helperClass), "Cannot add the same class twice: " + helperClass); + this.helperClasses.add(helperClass); + } + } + } + + private static Class[] getHelperClasses(String[] args) { + if (args.length == 1) { + return null; + } + Class[] helperClasses = new Class[args.length - 1]; // First argument is test class + for (int i = 1; i < args.length; i++) { + String helperClassName = args[i]; + try { + helperClasses[i - 1] = Class.forName(helperClassName); + } catch (Exception e) { + throw new TestRunException("Could not find helper class " + helperClassName, e); + } + } + return helperClasses; + } + + // Only called by tests testing the framework itself. Accessed by reflection. Do not expose this to normal users. + private static void runTestsOnSameVM(Class testClass) { + if (testClass == null) { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + testClass = walker.getCallerClass(); + } + TestFrameworkExecution framework = new TestFrameworkExecution(testClass); + framework.runTestsOnSameVM(); + } + + private void runTestsOnSameVM() { + if (helperClasses != null) { + for (Class helperClass : helperClasses) { + // Process the helper classes and apply the explicit compile commands + processExplicitCompileCommands(helperClass); + } + } + parseTestClass(); + runTests(); + } + + private void runTestVM() { + ArrayList cmds = prepareTestVmFlags(); + OutputAnalyzer oa; + try { + // Calls 'main' of this class to run all specified tests with commands 'cmds'. + oa = ProcessTools.executeTestJvm(cmds); + } catch (Exception e) { + throw new TestFrameworkException("Error while executing Test VM", e); + } + String output = oa.getOutput(); + final int exitCode = oa.getExitValue(); + if (VERBOSE || exitCode != 0) { + System.out.println(" ----- OUTPUT -----"); + System.out.println(output); + + } + if (exitCode != 0) { + throwTestException(oa, exitCode); + } + + if (VERIFY_IR) { + IRMatcher irMatcher = new IRMatcher(output, testClass); + irMatcher.applyRules(); + } + } + + private ArrayList prepareTestVmFlags() { + String[] vmInputArguments = InputArguments.getVmInputArgs(); + ArrayList cmds = new ArrayList<>(); + if (!PREFER_COMMAND_LINE_FLAGS) { + cmds.addAll(Arrays.asList(vmInputArguments)); + } + + setupIrVerificationFlags(testClass, cmds); + + if (VERIFY_VM) { + cmds.addAll(Arrays.asList(verifyFlags)); + } + + cmds.addAll(Arrays.asList(fixedDefaultFlags)); + if (COMPILE_COMMANDS) { + cmds.addAll(Arrays.asList(compileCommandFlags)); + } + + // TODO: Only for debugging + if (cmds.get(0).startsWith("-agentlib")) { + cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=n,server=y"); + } + + if (PREFER_COMMAND_LINE_FLAGS) { + // Prefer flags set via the command line over the ones set by scenarios. + cmds.addAll(Arrays.asList(vmInputArguments)); + } + + cmds.add(getClass().getCanonicalName()); + cmds.add(testClass.getCanonicalName()); + if (helperClasses != null) { + helperClasses.forEach(c -> cmds.add(c.getCanonicalName())); + } + return cmds; + } + + private void setupIrVerificationFlags(Class testClass, ArrayList cmds) { + if (VERIFY_IR && cmds.stream().anyMatch(flag -> flag.startsWith("-XX:CompileThreshold"))) { + // Disable IR verification if non-default CompileThreshold is set + if (VERBOSE) { + System.out.println("Disabled IR verification due to CompileThreshold flag"); + } + VERIFY_IR = false; + } else if (!VERIFY_IR && REQUESTED_VERIFY_IR) { + System.out.println("IR Verification disabled either due to not running a debug build, running with -Xint, or other " + + "VM flags that make the verification inaccurate or impossible (e.g. running with C1 only)."); + } + + if (VERIFY_IR) { + // Add print flags for IR verification + cmds.addAll(Arrays.asList(printFlags)); + addBoolOptionForClass(cmds, testClass, "PrintIdeal"); + addBoolOptionForClass(cmds, testClass, "PrintOptoAssembly"); + // Always trap for exception throwing to not confuse IR verification + cmds.add("-XX:-OmitStackTraceInFastThrow"); + cmds.add("-DPrintValidIRRules=true"); + } else { + cmds.add("-DPrintValidIRRules=false"); + } + } + + private void addBoolOptionForClass(ArrayList cmds, Class testClass, String option) { + cmds.add("-XX:CompileCommand=option," + testClass.getCanonicalName() + "::*,bool," + option + ",true"); + } + + private void throwTestException(OutputAnalyzer oa, int exitCode) { + String stdErr = oa.getStderr(); + if (stdErr.contains("TestFormat.reportIfAnyFailures")) { + Pattern pattern = Pattern.compile("Violations \\(\\d+\\)[\\s\\S]*(?=/============/)"); + Matcher matcher = pattern.matcher(stdErr); + TestFramework.check(matcher.find(), "Must find violation matches"); + throw new TestFormatException("\n\n" + matcher.group()); + } else { + throw new TestRunException("\nVM exited with " + exitCode + "\n\nError Output:\n" + stdErr); + } + } + + private void parseTestClass() { + addReplay(); + processExplicitCompileCommands(testClass); + setupTests(); + setupCheckAndRunMethods(); + + // All remaining tests are simple base tests without check or specific way to run them. + addBaseTests(); + TestFormat.reportIfAnyFailures(); + declaredTests.clear(); + testMethodMap.clear(); + } + + private void addBaseTests() { + declaredTests.forEach((m, test) -> { + if (test.getAttachedMethod() == null) { + try { + Arguments argumentsAnno = getAnnotation(m, Arguments.class); + TestFormat.check(argumentsAnno != null || m.getParameterCount() == 0, "Missing @Arguments annotation to define arguments of " + m); + allTests.put(m, new BaseTest(test)); + } catch (TestFormatException e) { + // Failure logged. Continue and report later. + } + } + }); + } + + private void addReplay() { + if (DUMP_REPLAY) { + // Generate replay compilation files + String directive = "[{ match: \"*.*\", DumpReplay: true }]"; + TestFramework.check(WHITE_BOX.addCompilerDirective(directive) == 1, "Failed to add DUMP_REPLAY directive"); + } + } + + private void processExplicitCompileCommands(Class clazz) { + if (!XCOMP) { + // Don't control compilations if -Xcomp is enabled. + Method[] methods = clazz.getDeclaredMethods(); + for (Method m : methods) { + try { + applyIndependentCompilationCommands(m); + + if (STRESS_CC) { + if (getAnnotation(m, Test.class) != null) { + excludeCompilationRandomly(m); + } + } + } catch (TestFormatException e) { + // Failure logged. Continue and report later. + } + } + + // Only force compilation now because above annotations affect inlining + for (Method m : methods) { + try { + applyForceCompileCommand(m); + } catch (TestFormatException e) { + // Failure logged. Continue and report later. + } + } + } + } + + static boolean excludeCompilationRandomly(Method m) { + // Exclude some methods from compilation with C2 to stress test the calling convention + boolean exclude = Utils.getRandomInstance().nextBoolean(); + if (exclude) { + System.out.println("Excluding from C2 compilation: " + m); + WHITE_BOX.makeMethodNotCompilable(m, CompLevel.C2.getValue(), false); + WHITE_BOX.makeMethodNotCompilable(m, CompLevel.C2.getValue(), true); + } + return exclude; + } + + private void applyIndependentCompilationCommands(Method m) { + ForceInline forceInlineAnno = getAnnotation(m, ForceInline.class); + DontInline dontInlineAnno = getAnnotation(m, DontInline.class); + ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); + DontCompile dontCompileAnno = getAnnotation(m, DontCompile.class); + checkCompilationCommandAnnotations(m, forceInlineAnno, dontInlineAnno, forceCompileAnno, dontCompileAnno); + // First handle inline annotations + if (dontInlineAnno != null) { + WHITE_BOX.testSetDontInlineMethod(m, true); + } else if (forceInlineAnno != null) { + WHITE_BOX.testSetForceInlineMethod(m, true); + } + if (dontCompileAnno != null) { + CompLevel compLevel = dontCompileAnno.value(); + TestFormat.check(compLevel == CompLevel.C1 || compLevel == CompLevel.C2 || compLevel == CompLevel.ANY, + "Can only specify compilation level C1 (no individual C1 levels), " + + "C2 or ANY (no compilation, same as specifying anything) in @DontCompile at " + m); + dontCompileMethodAtLevel(m, compLevel); + } + } + + private void checkCompilationCommandAnnotations(Method m, ForceInline forceInlineAnno, DontInline dontInlineAnno, ForceCompile forceCompileAnno, DontCompile dontCompileAnno) { + Test testAnno = getAnnotation(m, Test.class); + Run runAnno = getAnnotation(m, Run.class); + Check checkAnno = getAnnotation(m, Check.class); + TestFormat.check((testAnno == null && runAnno == null && checkAnno == null) || Stream.of(forceCompileAnno, dontCompileAnno, forceInlineAnno, dontInlineAnno).noneMatch(Objects::nonNull), + "Cannot use explicit compile command annotations (@ForceInline, @DontInline," + + "@ForceCompile or @DontCompile) together with @Test, @Check or @Run: " + m + ". Use compLevel in @Test for fine tuning."); + if (Stream.of(forceInlineAnno, dontCompileAnno, dontInlineAnno).filter(Objects::nonNull).count() > 1) { + // Failure + TestFormat.check(dontCompileAnno == null || dontInlineAnno == null, + "@DontInline is implicitely done with @DontCompile annotation at " + m); + TestFormat.fail("Cannot mix @ForceInline, @DontInline and @DontCompile at the same time at " + m); + } + TestFormat.check(forceInlineAnno == null || dontInlineAnno == null, "Cannot have @ForceInline and @DontInline at the same time at " + m); + if (forceCompileAnno != null && dontCompileAnno != null) { + CompLevel forceCompile = forceCompileAnno.value(); + CompLevel dontCompile = dontCompileAnno.value(); + TestFormat.check(dontCompile != CompLevel.ANY, + "Cannot have @DontCompile(CompLevel.ANY) and @ForceCompile at the same time at " + m); + TestFormat.check(forceCompile != CompLevel.ANY, + "Cannot have @ForceCompile(CompLevel.ANY) and @DontCompile at the same time at " + m); + TestFormat.check(!CompLevel.overlapping(dontCompile, forceCompile), + "Overlapping compilation levels with @ForceCompile and @DontCompile at " + m); + } + } + + private void dontCompileMethod(Method m) { + WHITE_BOX.makeMethodNotCompilable(m, CompLevel.ANY.getValue(), true); + WHITE_BOX.makeMethodNotCompilable(m, CompLevel.ANY.getValue(), false); + WHITE_BOX.testSetDontInlineMethod(m, true); + } + + private void dontCompileMethodAtLevel(Method m, CompLevel compLevel) { + if (VERBOSE) { + System.out.println("dontCompileMethodAtLevel " + m + " , level = " + compLevel.name()); + } + WHITE_BOX.makeMethodNotCompilable(m, compLevel.getValue(), true); + WHITE_BOX.makeMethodNotCompilable(m, compLevel.getValue(), false); + if (compLevel == CompLevel.ANY) { + WHITE_BOX.testSetDontInlineMethod(m, true); + } + } + + private void applyForceCompileCommand(Method m) { + ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); + if (forceCompileAnno != null) { + TestFormat.check(forceCompileAnno.value() != CompLevel.SKIP, + "Cannot define compilation level SKIP in @ForceCompile at " + m); + enqueueMethodForCompilation(m, forceCompileAnno.value()); + } + } + + static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { + if (TestFrameworkExecution.VERBOSE) { + System.out.println("enqueueMethodForCompilation " + m + ", level = " + compLevel); + } + compLevel = restrictCompLevel(compLevel); + WHITE_BOX.enqueueMethodForCompilation(m, compLevel.getValue()); + } + + private void setupTests() { + boolean hasIncludeList = includeList != null; + boolean hasExcludeList = excludeList != null; + for (Method m : testClass.getDeclaredMethods()) { + Test testAnno = getAnnotation(m, Test.class); + try { + if (testAnno != null) { + if (hasIncludeList && includeList.contains(m.getName()) && (!hasExcludeList || !excludeList.contains(m.getName()))) { + addTest(m); + } else if (hasExcludeList && !excludeList.contains(m.getName())) { + addTest(m); + } else { + addTest(m); + } + } else { + TestFormat.checkNoThrow(!m.isAnnotationPresent(IR.class), "Found @IR annotation on non-@Test method " + m); + TestFormat.checkNoThrow(!m.isAnnotationPresent(Warmup.class) || getAnnotation(m, Run.class) != null, + "Found @Warmup annotation on non-@Test or non-@Run method " + m); + } + } catch (TestFormatException e) { + // Failure logged. Continue and report later. + } + } + if (PRINT_VALID_IR_RULES) { + irMatchRulePrinter.emit(); + } + } + + private void addTest(Method m) { + Test testAnno = getAnnotation(m, Test.class); + checkTestAnnotations(m, testAnno); + Warmup warmup = getAnnotation(m, Warmup.class); + int warmupIterations = WARMUP_ITERATIONS; + if (warmup != null) { + warmupIterations = warmup.value(); + TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + m); + } + + boolean osrOnly = getAnnotation(m, OSRCompileOnly.class) != null; + + if (PRINT_VALID_IR_RULES) { + irMatchRulePrinter.emitRuleEncoding(m); + } + + if (!XCOMP) { + // Don't inline test methods. Don't care when -Xcomp set. + WHITE_BOX.testSetDontInlineMethod(m, true); + } + CompLevel compLevel = restrictCompLevel(testAnno.compLevel()); + if (FLIP_C1_C2) { + compLevel = flipCompLevel(compLevel); + } + DeclaredTest test = new DeclaredTest(m, ArgumentValue.getArguments(m), compLevel, warmupIterations, osrOnly); + declaredTests.put(m, test); + testMethodMap.put(m.getName(), m); + } + + private void checkTestAnnotations(Method m, Test testAnno) { + TestFormat.check(!testMethodMap.containsKey(m.getName()), + "Cannot overload two @Test methods: " + m + ", " + testMethodMap.get(m.getName())); + TestFormat.check(testAnno != null, m + " must be a method with a @Test annotation"); + + Check checkAnno = getAnnotation(m, Check.class); + Run runAnno = getAnnotation(m, Run.class); + TestFormat.check(checkAnno == null && runAnno == null, + m + " has invalid @Check or @Run annotation while @Test annotation is present."); + + TestFormat.checkNoThrow(!Arrays.asList(m.getParameterTypes()).contains(TestInfo.class), + "Cannot use of " + TestInfo.class + " as parameter type at @Test method " + m); + + TestFormat.checkNoThrow(!m.getReturnType().equals(TestInfo.class), + "Cannot use of " + TestInfo.class + " as return type at @Test method " + m); + } + + + // Get the appropriate level as permitted by the test scenario and VM options. + private static CompLevel restrictCompLevel(CompLevel compLevel) { + if (!USE_COMPILER) { + return CompLevel.SKIP; + } + if (compLevel == CompLevel.ANY) { + // Use highest available compilation level by default (usually C2). + compLevel = TIERED_COMPILATION_STOP_AT_LEVEL; + } + if (!TIERED_COMPILATION && compLevel.getValue() < CompLevel.C2.getValue()) { + return CompLevel.SKIP; + } + if (TIERED_COMPILATION && compLevel.getValue() > TIERED_COMPILATION_STOP_AT_LEVEL.getValue()) { + return CompLevel.SKIP; + } + return compLevel; + } + + private static CompLevel flipCompLevel(CompLevel compLevel) { + switch (compLevel) { + case C1, C1_LIMITED_PROFILE, C1_FULL_PROFILE -> { + return CompLevel.C2; + } + case C2 -> { + return CompLevel.C1; + } + } + return compLevel; + } + + private void setupCheckAndRunMethods() { + for (Method m : testClass.getDeclaredMethods()) { + Check checkAnno = getAnnotation(m, Check.class); + Run runAnno = getAnnotation(m, Run.class); + Arguments argumentsAnno = getAnnotation(m, Arguments.class); + try { + TestFormat.check(argumentsAnno == null || (checkAnno == null && runAnno == null), "Cannot have @Argument annotation in combination with @Run or @Check at " + m); + if (checkAnno != null) { + addCheckedTest(m, checkAnno, runAnno); + } else if (runAnno != null) { + addCustomRunTest(m, runAnno); + } + } catch (TestFormatException e) { + // Failure logged. Continue and report later. + } + } + } + + private void addCheckedTest(Method m, Check checkAnno, Run runAnno) { + TestFormat.check(runAnno == null, m + " has invalid @Run annotation while @Check annotation is present."); + Method testMethod = testMethodMap.get(checkAnno.test()); + TestFormat.check(testMethod != null,"Did not find associated test method \"" + m.getDeclaringClass().getName() + + "." + checkAnno.test() + "\" for @Check at " + m); + boolean firstParameterTestInfo = m.getParameterCount() > 0 && m.getParameterTypes()[0].equals(TestInfo.class); + boolean secondParameterTestInfo = m.getParameterCount() > 1 && m.getParameterTypes()[1].equals(TestInfo.class); + + CheckedTest.Parameter parameter = null; + Class testReturnType = testMethod.getReturnType(); + switch (m.getParameterCount()) { + case 0 -> parameter = CheckedTest.Parameter.NONE; + case 1 -> { + TestFormat.check(firstParameterTestInfo || m.getParameterTypes()[0] == testReturnType, + "Single-parameter version of @Check method " + m + " must match return type of @Test " + testMethod); + parameter = firstParameterTestInfo ? CheckedTest.Parameter.TEST_INFO_ONLY : CheckedTest.Parameter.RETURN_ONLY; + } + case 2 -> { + TestFormat.check(m.getParameterTypes()[0] == testReturnType && secondParameterTestInfo, + "Two-parameter version of @Check method " + m + " must provide as first parameter the same" + + " return type as @Test method " + testMethod + " and as second parameter an object of " + TestInfo.class); + parameter = CheckedTest.Parameter.BOTH; + } + default -> TestFormat.fail("@Check method " + m + " must provide either a none, single or two-parameter variant."); + } + + DeclaredTest test = declaredTests.get(testMethod); + TestFormat.check(test != null, "Missing @Test annotation for associated test method " + testMethod + " for @Check at " + m); + Method attachedMethod = test.getAttachedMethod(); + TestFormat.check(attachedMethod == null, + "Cannot use @Test " + testMethod + " for more than one @Run or one @Check method. Found: " + m + ", " + attachedMethod); + dontCompileMethod(m); + // Don't inline check methods + WHITE_BOX.testSetDontInlineMethod(m, true); + CheckedTest checkedTest = new CheckedTest(test, m, checkAnno, parameter); + allTests.put(testMethod, checkedTest); + } + + private void addCustomRunTest(Method m, Run runAnno) { + Method testMethod = testMethodMap.get(runAnno.test()); + DeclaredTest test = declaredTests.get(testMethod); + checkCustomRunTest(m, runAnno, testMethod, test); + dontCompileMethod(m); + // Don't inline run methods + WHITE_BOX.testSetDontInlineMethod(m, true); + CustomRunTest customRunTest = new CustomRunTest(test, m, getAnnotation(m, Warmup.class), runAnno); + allTests.put(m, customRunTest); + } + + private void checkCustomRunTest(Method m, Run runAnno, Method testMethod, DeclaredTest test) { + TestFormat.check(testMethod != null, "Did not find associated @Test method \"" + m.getDeclaringClass().getName() + + "." + runAnno.test() + "\" specified in @Run at " + m); + TestFormat.check(test != null, "Missing @Test annotation for associated test method " + runAnno.test() + " for @Run at " + m); + Method attachedMethod = test.getAttachedMethod(); + TestFormat.check(attachedMethod == null, + "Cannot use @Test " + testMethod + " for more than one @Run/@Check method. Found: " + m + ", " + attachedMethod); + TestFormat.check(!test.hasArguments(), "Cannot use @Arguments at test method " + testMethod + " in combination with @Run method " + m); + TestFormat.check(m.getParameterCount() == 0 || (m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(TestInfo.class)), + "@Run method " + m + " must specify either no parameter or exactly one of " + TestInfo.class); + Warmup warmupAnno = getAnnotation(testMethod, Warmup.class); + TestFormat.checkNoThrow(warmupAnno == null, + "Cannot set @Warmup at @Test method " + testMethod + " when used with its @Run method " + m + ". Use @Warmup at @Run method instead."); + warmupAnno = getAnnotation(m, Warmup.class); + TestFormat.checkNoThrow(warmupAnno == null || runAnno.mode() != RunMode.STANDALONE, + "Cannot set @Warmup at @Run method " + m + " when used with RunMode.STANDALONE. The @Run method is only invoked once."); + OSRCompileOnly osrAnno = getAnnotation(testMethod, OSRCompileOnly.class); + TestFormat.checkNoThrow(osrAnno == null || runAnno.mode() != RunMode.STANDALONE, + "Cannot set @OSRCompileOnly at @Run method " + m + " when used with RunMode.STANDALONE. The @Run method is responsible for triggering compilation."); + } + + private static T getAnnotation(Method m, Class c) { + T[] annos = m.getAnnotationsByType(c); + TestFormat.check(annos.length < 2, m + " has duplicated annotations"); + return Arrays.stream(annos).findFirst().orElse(null); + } + + private void runTests() { + TreeMap durations = (PRINT_TIMES || VERBOSE) ? new TreeMap<>() : null; + long startTime = System.nanoTime(); + Collection testCollection = allTests.values(); + if (SHUFFLE_TESTS) { + // Execute tests in random order (execution sequence affects profiling) + ArrayList shuffledList = new ArrayList<>(allTests.values()); + Collections.shuffle(shuffledList); + testCollection = shuffledList; + } + for (BaseTest test : testCollection) { + test.run(); + if (PRINT_TIMES || VERBOSE) { + long endTime = System.nanoTime(); + long duration = (endTime - startTime); + durations.put(duration, test.getTestName()); + if (VERBOSE) { + System.out.println("Done " + test.getTestName() + ": " + duration + " ns = " + (duration / 1000000) + " ms"); + } + } + if (GC_AFTER) { + System.out.println("doing GC"); + System.gc(); + } + } + + // Print execution times + if (PRINT_TIMES) { + System.out.println("\n\nTest execution times:"); + for (Map.Entry entry : durations.entrySet()) { + System.out.format("%-10s%15d ns\n", entry.getValue() + ":", entry.getKey()); + } + } + } + + enum TriState { + Maybe, + Yes, + No + } + + // Can be called from tests for non-@Test methods + static void compile(Method m, CompLevel compLevel) { + TestRun.check(getAnnotation(m, Test.class) == null, + "Cannot call enqueueMethodForCompilation() for @Test annotated method " + m); + enqueueMethodForCompilation(m, compLevel); + } + + static boolean isC1Compiled(Method m) { + return compiledByC1(m) == TriState.Yes; + } + + static boolean isC2Compiled(Method m) { + return compiledByC2(m) == TriState.Yes; + } + + static boolean isCompiledAtLevel(Method m, CompLevel compLevel) { + return compiledAtLevel(m, compLevel) == TriState.Yes; + } + + static void assertDeoptimizedByC1(Method m) { + TestRun.check(compiledByC1(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized by C1"); + } + + static void assertDeoptimizedByC2(Method m) { + TestRun.check(compiledByC2(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized by C2"); + } + + static void assertCompiledByC1(Method m) { + TestRun.check(compiledByC1(m) != TriState.No, m + " should have been C1 compiled"); + } + + static void assertCompiledByC2(Method m) { + TestRun.check(compiledByC2(m) != TriState.No, m + " should have been C2 compiled"); + } + + static void assertCompiledAtLevel(Method m, CompLevel level) { + TestRun.check(compiledAtLevel(m, level) != TriState.No, m + " should have been compiled at level " + level.name()); + } + + static void assertNotCompiled(Method m) { + TestRun.check(!WHITE_BOX.isMethodCompiled(m, false) && !WHITE_BOX.isMethodCompiled(m, true), + m + " should not have been compiled"); + } + + static void assertCompiled(Method m) { + TestRun.check(WHITE_BOX.isMethodCompiled(m, false) || WHITE_BOX.isMethodCompiled(m, true), + m + " should have been compiled"); + } + + private static TriState compiledByC1(Method m) { + TriState triState = compiledAtLevel(m, CompLevel.C1); + if (triState != TriState.No) { + return triState; + } + triState = compiledAtLevel(m, CompLevel.C1_LIMITED_PROFILE); + if (triState != TriState.No) { + return triState; + } + triState = compiledAtLevel(m, CompLevel.C1_FULL_PROFILE); + return triState; + } + + private static TriState compiledByC2(Method m) { + return compiledAtLevel(m, CompLevel.C2); + } + + private static TriState compiledAtLevel(Method m, CompLevel level) { + if (!TestFrameworkExecution.USE_COMPILER || TestFrameworkExecution.XCOMP || TestFrameworkExecution.TEST_C1 || + (TestFrameworkExecution.STRESS_CC && !WHITE_BOX.isMethodCompilable(m, level.getValue(), false))) { + return TriState.Maybe; + } + if (WHITE_BOX.isMethodCompiled(m, false) + && WHITE_BOX.getMethodCompilationLevel(m, false) == level.getValue()) { + return TriState.Yes; + } + return TriState.No; + } +} + +class DeclaredTest { + private final Method testMethod; + private final ArgumentValue[] arguments; + private final int warmupIterations; + private final CompLevel compLevel; + private final boolean osrOnly; + private Method attachedMethod; + + public DeclaredTest(Method testMethod, ArgumentValue[] arguments, CompLevel compLevel, int warmupIterations, boolean osrOnly) { + // Make sure we can also call non-public or public methods in package private classes + testMethod.setAccessible(true); + this.testMethod = testMethod; + this.compLevel = compLevel; + this.arguments = arguments; + this.warmupIterations = warmupIterations; + this.osrOnly = osrOnly; + this.attachedMethod = null; + } + + public Method getTestMethod() { + return testMethod; + } + + public CompLevel getCompLevel() { + return compLevel; + } + + public int getWarmupIterations() { + return warmupIterations; + } + + public boolean isOSROnly() { + return osrOnly; + } + + public boolean hasArguments() { + return arguments != null; + } + + public Object[] getArguments() { + return Arrays.stream(arguments).map(ArgumentValue::getArgument).toArray(); + } + + public void setAttachedMethod(Method m) { + attachedMethod = m; + } + + public Method getAttachedMethod() { + return attachedMethod; + } + + public void printFixedRandomArguments() { + if (hasArguments()) { + boolean hasRandomArgs = false; + StringBuilder builder = new StringBuilder("Random Arguments: "); + for (int i = 0; i < arguments.length; i++) { + ArgumentValue argument = arguments[i]; + if (argument.isFixedRandom()) { + hasRandomArgs = true; + builder.append("arg ").append(i).append(": ").append(argument.getArgument()).append(", "); + } + } + if (hasRandomArgs) { + // Drop the last comma and space. + builder.setLength(builder.length() - 2); + System.out.println(builder.toString()); + } + } + } + + public Object invoke(Object obj, Object... args) { + try { + return testMethod.invoke(obj, args); + } catch (Exception e) { + throw new TestRunException("There was an error while invoking @Test method " + testMethod, e); + } + } +} + +class BaseTest { + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private static final int OSR_TEST_TIMEOUT = Integer.parseInt(System.getProperty("OSRTestTimeOut", "5000")); + private static final int TEST_COMPILATION_TIMEOUT = Integer.parseInt(System.getProperty("TestCompilationTimeout", "5000")); + + protected final DeclaredTest test; + protected final Method testMethod; + protected final TestInfo testInfo; + protected final Object invocationTarget; + private final boolean shouldCompile; + protected int warmupIterations; + + public BaseTest(DeclaredTest test) { + this.test = test; + this.testMethod = test.getTestMethod(); + this.testInfo = new TestInfo(testMethod); + this.warmupIterations = test.getWarmupIterations(); + Class clazz = testMethod.getDeclaringClass(); + if (Modifier.isStatic(testMethod.getModifiers())) { + this.invocationTarget = null; + } else { + try { + Constructor constructor = clazz.getDeclaredConstructor(); + constructor.setAccessible(true); + this.invocationTarget = constructor.newInstance(); + } catch (Exception e) { + throw new TestRunException("Could not create instance of " + clazz + + ". Make sure there is a constructor without arguments.", e); + } + } + if (!TestFrameworkExecution.USE_COMPILER) { + this.shouldCompile = false; + } else if (TestFrameworkExecution.STRESS_CC) { + this.shouldCompile = !TestFrameworkExecution.excludeCompilationRandomly(testMethod); + } else { + this.shouldCompile = true; + } + } + + public String getTestName() { + return testMethod.getName(); + } + + public Method getAttachedMethod() { return null; } + + /** + * Run the associated test + */ + public void run() { + if (test.getCompLevel() == CompLevel.SKIP) { + // Exclude test if compilation level is SKIP either set through test or by not matching the current VM flags. + return; + } + if (TestFrameworkExecution.VERBOSE) { + System.out.println("Starting " + testMethod); + } + test.printFixedRandomArguments(); + for (int i = 0; i < warmupIterations; i++) { + runMethod(); + } + testInfo.setWarmUpFinished(); + + if (test.isOSROnly()) { + compileOSRAndRun(); // TODO: Keep this? + } else { + if (shouldCompile) { + compileTest(); + } + // Always run method. + runMethod(); + } + } + + protected void runMethod() { + verify(invokeTestMethod()); + } + + private Object invokeTestMethod() { + try { + if (test.hasArguments()) { + return testMethod.invoke(invocationTarget, test.getArguments()); + } else { + return testMethod.invoke(invocationTarget); + } + } catch (Exception e) { + throw new TestRunException("There was an error while invoking @Test method " + testMethod, e); + } + } + + private void compileOSRAndRun() { + final boolean maybeCodeBufferOverflow = (TestFrameworkExecution.TEST_C1 && TestFrameworkExecution.VERIFY_OOPS); + final long started = System.currentTimeMillis(); + boolean stateCleared = false; + while (true) { + long elapsed = System.currentTimeMillis() - started; + int level = WHITE_BOX.getMethodCompilationLevel(testMethod); + if (maybeCodeBufferOverflow && elapsed > 5000 + && (!WHITE_BOX.isMethodCompiled(testMethod, false) || level != test.getCompLevel().getValue())) { + retryDisabledVerifyOops(stateCleared); + stateCleared = true; + } else { + runMethod(); + } + + boolean b = WHITE_BOX.isMethodCompiled(testMethod, false); + if (TestFrameworkExecution.VERBOSE) { + System.out.println("Is " + testMethod + " compiled? " + b); + } + if (b || TestFrameworkExecution.XCOMP || TestFrameworkExecution.STRESS_CC || !TestFrameworkExecution.USE_COMPILER) { + // Don't control compilation if -Xcomp is enabled, or if compiler is disabled + break; + } + Asserts.assertTrue(OSR_TEST_TIMEOUT < 0 || elapsed < OSR_TEST_TIMEOUT, testMethod + " not compiled after " + OSR_TEST_TIMEOUT + " ms"); + } + } + + private void retryDisabledVerifyOops(boolean stateCleared) { + System.out.println("Temporarily disabling VerifyOops"); + try { + WHITE_BOX.setBooleanVMFlag("VerifyOops", false); + if (!stateCleared) { + WHITE_BOX.clearMethodState(testMethod); + } + runMethod(); + } finally { + WHITE_BOX.setBooleanVMFlag("VerifyOops", true); + System.out.println("Re-enabled VerifyOops"); + } + } + + private void compileTest() { + final boolean maybeCodeBufferOverflow = (TestFrameworkExecution.TEST_C1 && TestFrameworkExecution.VERIFY_OOPS); + final Method testMethod = test.getTestMethod(); + long started = System.currentTimeMillis(); + long elapsed = 0; + Asserts.assertTrue(WHITE_BOX.isMethodCompilable(testMethod, test.getCompLevel().getValue(), false)); + enqueueMethodForCompilation(); + + do { + if (!WHITE_BOX.isMethodQueuedForCompilation(testMethod)) { + if (elapsed > 0 && TestFrameworkExecution.VERBOSE) { + System.out.println(testMethod + " is not in queue anymore due to compiling it simultaneously on a different level. Enqueue again."); + enqueueMethodForCompilation(); + } + } + if (maybeCodeBufferOverflow && elapsed > 1000 && !WHITE_BOX.isMethodCompiled(testMethod, false)) { + // Let's disable VerifyOops temporarily and retry. + WHITE_BOX.setBooleanVMFlag("VerifyOops", false); + WHITE_BOX.clearMethodState(testMethod); + enqueueMethodForCompilation(); + WHITE_BOX.setBooleanVMFlag("VerifyOops", true); + } + + if (WHITE_BOX.getMethodCompilationLevel(testMethod, false) == test.getCompLevel().getValue()) { + break; + } + elapsed = System.currentTimeMillis() - started; + } while (elapsed < TEST_COMPILATION_TIMEOUT); + TestRun.check(elapsed < TEST_COMPILATION_TIMEOUT, "Could not compile" + testMethod + " after " + TEST_COMPILATION_TIMEOUT/1000 + "s"); + checkCompilationLevel(); + } + + private void enqueueMethodForCompilation() { + TestFrameworkExecution.enqueueMethodForCompilation(test.getTestMethod(), test.getCompLevel()); + } + + protected void checkCompilationLevel() { + CompLevel level = CompLevel.forValue(WHITE_BOX.getMethodCompilationLevel(testMethod)); + TestRun.check(level == test.getCompLevel(), + "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod); + } + + /** + * Verify the result + */ + public void verify(Object result) { /* no verification in BaseTests */ } +} + +class CheckedTest extends BaseTest { + private final Method checkMethod; + private final CheckAt checkAt; + private final Parameter parameter; + + enum Parameter { + NONE, RETURN_ONLY, TEST_INFO_ONLY, BOTH + } + + public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecification, Parameter parameter) { + super(test); + // Make sure we can also call non-public or public methods in package private classes + checkMethod.setAccessible(true); + test.setAttachedMethod(checkMethod); + this.checkMethod = checkMethod; + this.checkAt = checkSpecification.when(); + this.parameter = parameter; + } + + @Override + public Method getAttachedMethod() { return checkMethod; } + + @Override + public void verify(Object result) { + boolean shouldVerify = false; + switch (checkAt) { + case EACH_INVOCATION -> shouldVerify = true; + case COMPILED -> shouldVerify = !testInfo.isWarmUp(); + } + if (shouldVerify) { + try { + switch (parameter) { + case NONE -> checkMethod.invoke(invocationTarget); + case RETURN_ONLY -> checkMethod.invoke(invocationTarget, result); + case TEST_INFO_ONLY -> checkMethod.invoke(invocationTarget, testInfo); + case BOTH -> checkMethod.invoke(invocationTarget, result, testInfo); + } + } catch (Exception e) { + throw new TestRunException("There was an error while invoking @Check method " + checkMethod, e); + } + } + } +} + +class CustomRunTest extends BaseTest { + private final Method runMethod; + private final RunMode mode; + + public CustomRunTest(DeclaredTest test, Method runMethod, Warmup warmUpAnno, Run runSpecification) { + super(test); + // Make sure we can also call non-public or public methods in package private classes + runMethod.setAccessible(true); + test.setAttachedMethod(runMethod); + this.runMethod = runMethod; + this.mode = runSpecification.mode(); + this.warmupIterations = warmUpAnno != null ? warmUpAnno.value() : test.getWarmupIterations(); + TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + runMethod); + } + + @Override + public Method getAttachedMethod() { return runMethod; } + + @Override + public void run() { + switch (mode) { + case STANDALONE -> runMethod(); + case NORMAL -> super.run(); + } + } + + /** + * Do not directly run the test but rather the run method that is responsible for invoking the actual test. + */ + @Override + protected void runMethod() { + try { + if (runMethod.getParameterCount() == 1) { + runMethod.invoke(invocationTarget, testInfo); + } else { + runMethod.invoke(invocationTarget); + } + } catch (Exception e) { + throw new TestRunException("There was an error while invoking @Run method " + runMethod, e); + } + } + + @Override + protected void checkCompilationLevel() { + CompLevel level = CompLevel.forValue(WhiteBox.getWhiteBox().getMethodCompilationLevel(testMethod)); + if (level != test.getCompLevel()) { + String message = "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod + "."; + switch (mode) { + case STANDALONE -> message = message + "\nCheck your @Run method (invoked once) " + runMethod + " to ensure that " + testMethod + " will be complied at the requested level."; + case NORMAL -> message = message + "\nCheck your @Run method " + runMethod + " to ensure that " + testMethod + " is called at least once in each iteration."; + } + TestRun.fail(message); + } + } +} + + diff --git a/test/lib/testframework/TestFrameworkRunner.java b/test/lib/testframework/TestFrameworkRunner.java new file mode 100644 index 00000000000..b0a62a5767b --- /dev/null +++ b/test/lib/testframework/TestFrameworkRunner.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2021, 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 testframework; + +import jdk.test.lib.Platform; +import jdk.test.lib.management.InputArguments; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import sun.hotspot.WhiteBox; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +class TestFrameworkRunner { + private static final WhiteBox WHITE_BOX; + + static { + try { + WHITE_BOX = WhiteBox.getWhiteBox(); + } catch (UnsatisfiedLinkError e) { + throw new TestFrameworkException("Could not load WhiteBox"); + } + } + + private static final boolean TIERED_COMPILATION = (Boolean)WHITE_BOX.getVMFlag("TieredCompilation"); + private static final CompLevel TIERED_COMPILATION_STOP_AT_LEVEL = CompLevel.forValue(((Long)WHITE_BOX.getVMFlag("TieredStopAtLevel")).intValue()); + static final boolean TEST_C1 = TIERED_COMPILATION && TIERED_COMPILATION_STOP_AT_LEVEL.getValue() < CompLevel.C2.getValue(); + + // User defined settings + static final boolean XCOMP = Platform.isComp(); +// private static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); + static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "true")); + + private static final boolean COMPILE_COMMANDS = Boolean.parseBoolean(System.getProperty("CompileCommands", "true")) && !XCOMP; + static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); + static final boolean STRESS_CC = Boolean.parseBoolean(System.getProperty("StressCC", "false")); + private static final boolean REQUESTED_VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); + private static boolean VERIFY_IR = REQUESTED_VERIFY_IR && USE_COMPILER && !XCOMP && !STRESS_CC && !TEST_C1 && COMPILE_COMMANDS + && Platform.isDebugBuild() && !Platform.isInt(); + private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false")) && Platform.isDebugBuild(); + private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); + + private static String[] getDefaultFlags() { + return new String[] {"-XX:-BackgroundCompilation"}; + } + + private static String[] getCompileCommandFlags() { + return new String[] {"-XX:CompileCommand=quiet"}; + } + + private static String[] getPrintFlags() { + return new String[] {"-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions"}; + } + + private static String[] getVerifyFlags() { + return new String[] { + "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", "-XX:+VerifyBeforeGC", + "-XX:+VerifyAfterGC", "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing"}; + } + + public static void main(String[] args) { + String testClassName = args[0]; + System.out.println("Framework main(), about to run tests in class " + testClassName); + Class testClass; + try { + testClass = Class.forName(testClassName); + } catch (Exception e) { + throw new TestRunException("Could not find test class " + testClassName, e); + } + runTestVM(testClass, args); + } + + private static void runTestVM(Class testClass, String[] args) { + ArrayList cmds = prepareTestVmFlags(testClass, args); + OutputAnalyzer oa; + try { + // Calls 'main' of this class to run all specified tests with commands 'cmds'. + oa = ProcessTools.executeTestJvm(cmds); + } catch (Exception e) { + throw new TestFrameworkException("Error while executing Test VM", e); + } + String output = oa.getOutput(); + final int exitCode = oa.getExitValue(); + if (VERBOSE || exitCode != 0) { + System.out.println(" ----- OUTPUT -----"); + System.out.println(output); + + } + if (exitCode != 0) { + throw new RuntimeException("\nTestFramework runner VM exited with " + exitCode); + } + + if (VERIFY_IR) { + IRMatcher irMatcher = new IRMatcher(output, testClass); + irMatcher.applyRules(); + } + } + + private static ArrayList prepareTestVmFlags(Class testClass, String[] args) { + String[] vmInputArguments = InputArguments.getVmInputArgs(); + ArrayList cmds = new ArrayList<>(); + if (!PREFER_COMMAND_LINE_FLAGS) { + cmds.addAll(Arrays.asList(vmInputArguments)); + } + + setupIrVerificationFlags(testClass, cmds); + + if (VERIFY_VM) { + cmds.addAll(Arrays.asList(getVerifyFlags())); + } + + cmds.addAll(Arrays.asList(getDefaultFlags())); + if (COMPILE_COMMANDS) { + cmds.addAll(Arrays.asList(getCompileCommandFlags())); + } + + // TODO: Only for debugging + if (cmds.get(0).startsWith("-agentlib")) { + cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=n,server=y"); + } + + if (PREFER_COMMAND_LINE_FLAGS) { + // Prefer flags set via the command line over the ones set by scenarios. + cmds.addAll(Arrays.asList(vmInputArguments)); + } + + cmds.add(TestFrameworkExecution.class.getCanonicalName()); + cmds.addAll(Arrays.asList(args)); // add test class and helpers last + return cmds; + } + + private static void setupIrVerificationFlags(Class testClass, ArrayList cmds) { + if (VERIFY_IR && cmds.stream().anyMatch(flag -> flag.startsWith("-XX:CompileThreshold"))) { + // Disable IR verification if non-default CompileThreshold is set + if (VERBOSE) { + System.out.println("Disabled IR verification due to CompileThreshold flag"); + } + VERIFY_IR = false; + } else if (!VERIFY_IR && REQUESTED_VERIFY_IR) { + System.out.println("IR Verification disabled either due to not running a debug build, running with -Xint, or other " + + "VM flags that make the verification inaccurate or impossible (e.g. running with C1 only)."); + } + + if (VERIFY_IR) { + // Add print flags for IR verification + cmds.addAll(Arrays.asList(getPrintFlags())); + addBoolOptionForClass(cmds, testClass, "PrintIdeal"); + addBoolOptionForClass(cmds, testClass, "PrintOptoAssembly"); + // Always trap for exception throwing to not confuse IR verification + cmds.add("-XX:-OmitStackTraceInFastThrow"); + cmds.add("-DPrintValidIRRules=true"); + } else { + cmds.add("-DPrintValidIRRules=false"); + } + } + + private static void addBoolOptionForClass(ArrayList cmds, Class testClass, String option) { + cmds.add("-XX:CompileCommand=option," + testClass.getCanonicalName() + "::*,bool," + option + ",true"); + } +} diff --git a/test/lib/testframework/TestInfo.java b/test/lib/testframework/TestInfo.java index d12369b69b3..c78a29f4bea 100644 --- a/test/lib/testframework/TestInfo.java +++ b/test/lib/testframework/TestInfo.java @@ -32,13 +32,10 @@ public class TestInfo { private static final Random random = new Random(); - private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); - protected static final long PerMethodTrapLimit = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); - protected static final boolean ProfileInterpreter = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); + private final Method testMethod; private boolean toggleBool = false; private boolean onWarmUp = true; - private final Method testMethod; TestInfo(Method testMethod) { this.testMethod = testMethod; diff --git a/test/lib/testframework/tests/TestBasics.java b/test/lib/testframework/tests/TestBasics.java index 3acfab600ee..30cc7b4a4d7 100644 --- a/test/lib/testframework/tests/TestBasics.java +++ b/test/lib/testframework/tests/TestBasics.java @@ -49,10 +49,10 @@ public static void main(String[] args) throws Exception { } for (int i = 0; i < executed.length; i++) { int value = executed[i]; - if (value != TestFramework.WARMUP_ITERATIONS + 1) { + if (value != TestFrameworkExecution.WARMUP_ITERATIONS + 1) { // Warmups + 1 C2 compiled invocation throw new RuntimeException("Test " + i + " was executed " + value + " times stead of " - + TestFramework.WARMUP_ITERATIONS + 1 + " times." ); + + TestFrameworkExecution.WARMUP_ITERATIONS + 1 + " times." ); } } @@ -1017,7 +1017,7 @@ public void testRunOnce2() { @Run(test = "testRunOnce2", mode = RunMode.STANDALONE) public void runTestRunOnce2(TestInfo info) { - for (int i = 0; i < TestFramework.WARMUP_ITERATIONS + 1; i++) { + for (int i = 0; i < TestFrameworkExecution.WARMUP_ITERATIONS + 1; i++) { testRunOnce2(); } } diff --git a/test/lib/testframework/tests/TestCompLevels.java b/test/lib/testframework/tests/TestCompLevels.java index b83b30c48ab..79df630f72f 100644 --- a/test/lib/testframework/tests/TestCompLevels.java +++ b/test/lib/testframework/tests/TestCompLevels.java @@ -38,17 +38,17 @@ public static void main(String[] args) throws Exception { runTestsOnSameVM.invoke(null, new Object[]{null}); for (int i = 0; i < testExecuted.length; i++) { int value = testExecuted[i]; - if (value != TestFramework.WARMUP_ITERATIONS + 1) { + if (value != TestFrameworkExecution.WARMUP_ITERATIONS + 1) { // Warmups + 1 compiled invocation throw new RuntimeException("Test " + i + " was executed " + value + " times stead of " - + TestFramework.WARMUP_ITERATIONS + 1 + " times." ); + + TestFrameworkExecution.WARMUP_ITERATIONS + 1 + " times." ); } } Scenario s = new Scenario(1, "-XX:-TieredCompilation"); TestFramework.runWithScenarios(TestNoTiered.class, s); s = new Scenario(2, "-XX:TieredStopAtLevel=1"); TestFramework.runWithScenarios(TestStopAtLevel1.class, s); - Asserts.assertTrue(TestFramework.getLastVmOutput().contains("TestStopAtLevel1=34")); + Asserts.assertTrue(s.getVMOutput().contains("TestStopAtLevel1=34")); } @Test(compLevel = CompLevel.C1) diff --git a/test/lib/testframework/tests/TestControls.java b/test/lib/testframework/tests/TestControls.java index 7c5a148428b..d5cd36031b0 100644 --- a/test/lib/testframework/tests/TestControls.java +++ b/test/lib/testframework/tests/TestControls.java @@ -40,7 +40,7 @@ public static void main(String[] args) throws Exception { Method runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); runTestsOnSameVM.invoke(null, new Object[]{ null }); - final int defaultIterations = TestFramework.WARMUP_ITERATIONS + 1; + final int defaultIterations = TestFrameworkExecution.WARMUP_ITERATIONS + 1; Asserts.assertEQ(executed[0], 1001); Asserts.assertEQ(executed[1], 101); Asserts.assertEQ(executed[2], 10000); diff --git a/test/lib/testframework/tests/TestIRMatching.java b/test/lib/testframework/tests/TestIRMatching.java index 5d6fe2a1c19..23d171213db 100644 --- a/test/lib/testframework/tests/TestIRMatching.java +++ b/test/lib/testframework/tests/TestIRMatching.java @@ -44,16 +44,16 @@ public static void main(String[] args) { runWithArguments(MultipleFailOnGood.class, "-XX:SuspendRetryCount=50"); runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=50"); - findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 0, 21); - findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", -1, -1); + findIrIds(TestFramework.getLastVMOutput(), "testMatchAllIf50", 0, 21); + findIrIds(TestFramework.getLastVMOutput(), "testMatchNoneIf50", -1, -1); runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=49"); - findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 4, 6, 13, 18); - findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); + findIrIds(TestFramework.getLastVMOutput(), "testMatchAllIf50", 4, 6, 13, 18); + findIrIds(TestFramework.getLastVMOutput(), "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=51"); - findIrIds(TestFramework.getLastVmOutput(), "testMatchAllIf50", 7, 12, 19, 21); - findIrIds(TestFramework.getLastVmOutput(), "testMatchNoneIf50", 4, 7, 11, 16, 20, 22); + findIrIds(TestFramework.getLastVMOutput(), "testMatchAllIf50", 7, 12, 19, 21); + findIrIds(TestFramework.getLastVMOutput(), "testMatchNoneIf50", 4, 7, 11, 16, 20, 22); String[] allocMatches = { "MyClass", "call,static wrapper for: _new_instance_Java" }; runCheck(BadFailOnConstraint.create(MultipleFailOnBad.class, "fail1()", 1, 1, "Store"), @@ -217,7 +217,7 @@ private static void checkConstraints(RuntimeException e, Constraint[] constraint constraint.checkConstraint(e); } } catch (Exception e1) { - System.out.println(TestFramework.getLastVmOutput()); + System.out.println(TestFramework.getLastVMOutput()); System.out.println(message); throw e1; } diff --git a/test/lib/testframework/tests/TestWithHelperClasses.java b/test/lib/testframework/tests/TestWithHelperClasses.java index 5fdf81072f9..06100f17892 100644 --- a/test/lib/testframework/tests/TestWithHelperClasses.java +++ b/test/lib/testframework/tests/TestWithHelperClasses.java @@ -36,8 +36,8 @@ public static void main(String[] args) { try { TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class); } catch (Exception e) { - Asserts.assertFalse(TestFramework.getLastVmOutput().contains("public static void testframework.tests.Helper1.foo() should have been C2 compiled")); - Asserts.assertTrue(TestFramework.getLastVmOutput().contains("public static void testframework.tests.Helper2.foo() should have been C2 compiled")); + Asserts.assertFalse(TestFramework.getLastVMOutput().contains("public static void testframework.tests.Helper1.foo() should have been C2 compiled")); + Asserts.assertTrue(TestFramework.getLastVMOutput().contains("public static void testframework.tests.Helper2.foo() should have been C2 compiled")); return; } throw new RuntimeException("Did not catch exception"); From 1e1a3943018d73b9587a67a58c031d6e3b3ced9d Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 3 Mar 2021 15:42:25 +0100 Subject: [PATCH 032/131] Move and rename framework to test/lib/jdk/jdk/test/lib/hotspot/ir_framework --- .../testframework/TestSimpleExample.java | 4 +-- test/lib/RedefineClassHelper.java | 8 ++--- .../lib/hotspot/ir_framework}/Argument.java | 2 +- .../hotspot/ir_framework}/ArgumentValue.java | 2 +- .../lib/hotspot/ir_framework}/Arguments.java | 2 +- .../test/lib/hotspot/ir_framework}/Check.java | 2 +- .../lib/hotspot/ir_framework}/CheckAt.java | 2 +- .../CheckedTestFrameworkException.java | 28 +++++++++++++++ .../lib/hotspot/ir_framework}/CompLevel.java | 2 +- .../hotspot/ir_framework}/DontCompile.java | 2 +- .../lib/hotspot/ir_framework}/DontInline.java | 2 +- .../hotspot/ir_framework}/ForceCompile.java | 2 +- .../hotspot/ir_framework}/ForceInline.java | 2 +- .../test/lib/hotspot/ir_framework}/IR.java | 2 +- .../ir_framework}/IREncodingPrinter.java | 2 +- .../lib/hotspot/ir_framework}/IRMatcher.java | 2 +- .../lib/hotspot/ir_framework}/IRNode.java | 2 +- .../ir_framework}/IRViolationException.java | 2 +- .../test/lib/hotspot/ir_framework}/IRs.java | 2 +- .../hotspot/ir_framework}/OSRCompileOnly.java | 2 +- .../ir_framework}/ParsedComparator.java | 2 +- .../test/lib/hotspot/ir_framework}/Run.java | 2 +- .../lib/hotspot/ir_framework}/RunMode.java | 2 +- .../lib/hotspot/ir_framework}/Scenario.java | 2 +- .../test/lib/hotspot/ir_framework}/Test.java | 2 +- .../lib/hotspot/ir_framework}/TestFormat.java | 2 +- .../ir_framework}/TestFormatException.java | 2 +- .../hotspot/ir_framework}/TestFramework.java | 22 +++++++++--- .../ir_framework/TestFrameworkException.java | 34 +++++++++++++++++++ .../ir_framework}/TestFrameworkExecution.java | 20 ++++------- .../ir_framework}/TestFrameworkRunner.java | 6 ++-- .../lib/hotspot/ir_framework}/TestInfo.java | 4 +-- .../lib/hotspot/ir_framework}/TestRun.java | 2 +- .../ir_framework}/TestRunException.java | 2 +- .../lib/hotspot/ir_framework}/Warmup.java | 2 +- .../ir_framework}/tests/TestBadFormat.java | 7 ++-- .../ir_framework}/tests/TestBasics.java | 6 ++-- .../ir_framework}/tests/TestCompLevels.java | 6 ++-- .../ir_framework}/tests/TestControls.java | 6 ++-- .../ir_framework}/tests/TestIRMatching.java | 22 ++++++------ .../tests/TestPackagePrivate.java | 10 +++--- .../ir_framework}/tests/TestSanity.java | 8 ++--- .../ir_framework}/tests/TestScenarios.java | 4 +-- .../tests/TestWithHelperClasses.java | 15 ++++---- .../CheckedTestFrameworkException.java | 5 --- .../testframework/TestFrameworkException.java | 11 ------ 46 files changed, 166 insertions(+), 114 deletions(-) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/Argument.java (98%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/ArgumentValue.java (99%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/Arguments.java (96%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/Check.java (96%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/CheckAt.java (96%) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/CompLevel.java (98%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/DontCompile.java (97%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/DontInline.java (97%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/ForceCompile.java (98%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/ForceInline.java (97%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/IR.java (97%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/IREncodingPrinter.java (99%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/IRMatcher.java (99%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/IRNode.java (99%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/IRViolationException.java (96%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/IRs.java (96%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/OSRCompileOnly.java (96%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/ParsedComparator.java (98%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/Run.java (96%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/RunMode.java (97%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/Scenario.java (98%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/Test.java (96%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/TestFormat.java (98%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/TestFormatException.java (96%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/TestFramework.java (96%) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/TestFrameworkExecution.java (98%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/TestFrameworkRunner.java (97%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/TestInfo.java (98%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/TestRun.java (97%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/TestRunException.java (96%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/Warmup.java (96%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/tests/TestBadFormat.java (99%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/tests/TestBasics.java (99%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/tests/TestCompLevels.java (95%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/tests/TestControls.java (97%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/tests/TestIRMatching.java (98%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/tests/TestPackagePrivate.java (83%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/tests/TestSanity.java (93%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/tests/TestScenarios.java (96%) rename test/lib/{testframework => jdk/test/lib/hotspot/ir_framework}/tests/TestWithHelperClasses.java (78%) delete mode 100644 test/lib/testframework/CheckedTestFrameworkException.java delete mode 100644 test/lib/testframework/TestFrameworkException.java diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java b/test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java index fab72f35fb0..f4fffc7d260 100644 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java @@ -30,11 +30,11 @@ package compiler.valhalla.testframework; -import testframework.*; +import jdk.test.lib.hotspot.ir_framework.*; public class TestSimpleExample { - static int iFld; + int iFld; public static void main(String[] args) { TestFramework.run(); diff --git a/test/lib/RedefineClassHelper.java b/test/lib/RedefineClassHelper.java index b35ca3797d8..f9bedc0e6c9 100644 --- a/test/lib/RedefineClassHelper.java +++ b/test/lib/RedefineClassHelper.java @@ -24,7 +24,7 @@ import java.io.PrintWriter; import java.lang.instrument.Instrumentation; import java.lang.instrument.ClassDefinition; -//import jdk.test.lib.compiler.InMemoryJavaCompiler; +import jdk.test.lib.compiler.InMemoryJavaCompiler; /* * Helper class to write tests that redefine classes. @@ -47,8 +47,8 @@ public static void premain(String agentArgs, Instrumentation inst) { * @param javacode String with the new java code for the class to be redefined */ public static void redefineClass(Class clazz, String javacode) throws Exception { -// byte[] bytecode = InMemoryJavaCompiler.compile(clazz.getName(), javacode); -// redefineClass(clazz, bytecode); + byte[] bytecode = InMemoryJavaCompiler.compile(clazz.getName(), javacode); + redefineClass(clazz, bytecode); } /** @@ -66,6 +66,6 @@ public static void redefineClass(Class clazz, byte[] bytecode) throws Exception */ public static void main(String[] args) throws Exception { String manifest = "Premain-Class: RedefineClassHelper\nCan-Redefine-Classes: true\n"; -// ClassFileInstaller.writeJar("redefineagent.jar", ClassFileInstaller.Manifest.fromString(manifest), "RedefineClassHelper"); + ClassFileInstaller.writeJar("redefineagent.jar", ClassFileInstaller.Manifest.fromString(manifest), "RedefineClassHelper"); } } diff --git a/test/lib/testframework/Argument.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java similarity index 98% rename from test/lib/testframework/Argument.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java index e73dc47d5a5..d8fc982aabb 100644 --- a/test/lib/testframework/Argument.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; public enum Argument { /** diff --git a/test/lib/testframework/ArgumentValue.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java similarity index 99% rename from test/lib/testframework/ArgumentValue.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java index 0475ee73e69..5d19a5cb8bd 100644 --- a/test/lib/testframework/ArgumentValue.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.lang.reflect.Constructor; import java.lang.reflect.Method; diff --git a/test/lib/testframework/Arguments.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java similarity index 96% rename from test/lib/testframework/Arguments.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java index 38e89312444..db72d633720 100644 --- a/test/lib/testframework/Arguments.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/lib/testframework/Check.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java similarity index 96% rename from test/lib/testframework/Check.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/Check.java index f586c4e682d..17106ed64db 100644 --- a/test/lib/testframework/Check.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/lib/testframework/CheckAt.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java similarity index 96% rename from test/lib/testframework/CheckAt.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java index 11bd1f6612b..b1c9c9e856d 100644 --- a/test/lib/testframework/CheckAt.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; public enum CheckAt { EACH_INVOCATION, COMPILED diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java new file mode 100644 index 00000000000..5f0174e2a26 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +// Checked exceptions in the framework to propagate error handling. +class CheckedTestFrameworkException extends Exception { +} diff --git a/test/lib/testframework/CompLevel.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java similarity index 98% rename from test/lib/testframework/CompLevel.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java index 89b4ef00e9e..60167daa5ab 100644 --- a/test/lib/testframework/CompLevel.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.util.HashMap; import java.util.Map; diff --git a/test/lib/testframework/DontCompile.java b/test/lib/jdk/test/lib/hotspot/ir_framework/DontCompile.java similarity index 97% rename from test/lib/testframework/DontCompile.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/DontCompile.java index c96b80c0545..d7efaf5a59a 100644 --- a/test/lib/testframework/DontCompile.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/DontCompile.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/lib/testframework/DontInline.java b/test/lib/jdk/test/lib/hotspot/ir_framework/DontInline.java similarity index 97% rename from test/lib/testframework/DontInline.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/DontInline.java index c600bdc777b..e5c84c01ccf 100644 --- a/test/lib/testframework/DontInline.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/DontInline.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/lib/testframework/ForceCompile.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java similarity index 98% rename from test/lib/testframework/ForceCompile.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java index 26d724c9dd5..9d32afedbce 100644 --- a/test/lib/testframework/ForceCompile.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/lib/testframework/ForceInline.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceInline.java similarity index 97% rename from test/lib/testframework/ForceInline.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/ForceInline.java index ce7c9e78d14..1bf57275824 100644 --- a/test/lib/testframework/ForceInline.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceInline.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/lib/testframework/IR.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java similarity index 97% rename from test/lib/testframework/IR.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/IR.java index 561ede75bce..a25c54bcc27 100644 --- a/test/lib/testframework/IR.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; diff --git a/test/lib/testframework/IREncodingPrinter.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java similarity index 99% rename from test/lib/testframework/IREncodingPrinter.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java index 04f97222835..278e94f0fc1 100644 --- a/test/lib/testframework/IREncodingPrinter.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import sun.hotspot.WhiteBox; diff --git a/test/lib/testframework/IRMatcher.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java similarity index 99% rename from test/lib/testframework/IRMatcher.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java index f170811cc34..a3ab8e90aa6 100644 --- a/test/lib/testframework/IRMatcher.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.lang.reflect.Method; import java.util.*; diff --git a/test/lib/testframework/IRNode.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java similarity index 99% rename from test/lib/testframework/IRNode.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java index 273f5b295fa..11021e85101 100644 --- a/test/lib/testframework/IRNode.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.util.ArrayList; import java.util.List; diff --git a/test/lib/testframework/IRViolationException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java similarity index 96% rename from test/lib/testframework/IRViolationException.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java index 645031f6570..a051292bdf0 100644 --- a/test/lib/testframework/IRViolationException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; public class IRViolationException extends RuntimeException { public IRViolationException(String message) { diff --git a/test/lib/testframework/IRs.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRs.java similarity index 96% rename from test/lib/testframework/IRs.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/IRs.java index 37cdff5acf4..8b6335e8268 100644 --- a/test/lib/testframework/IRs.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRs.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/lib/testframework/OSRCompileOnly.java b/test/lib/jdk/test/lib/hotspot/ir_framework/OSRCompileOnly.java similarity index 96% rename from test/lib/testframework/OSRCompileOnly.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/OSRCompileOnly.java index b57eb1bbad1..655c9468b4a 100644 --- a/test/lib/testframework/OSRCompileOnly.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/OSRCompileOnly.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/lib/testframework/ParsedComparator.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java similarity index 98% rename from test/lib/testframework/ParsedComparator.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java index f144b356d2d..738f3e57c41 100644 --- a/test/lib/testframework/ParsedComparator.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.util.function.BiPredicate; diff --git a/test/lib/testframework/Run.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java similarity index 96% rename from test/lib/testframework/Run.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/Run.java index 2794e53cd23..dc62e5074cc 100644 --- a/test/lib/testframework/Run.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/lib/testframework/RunMode.java b/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java similarity index 97% rename from test/lib/testframework/RunMode.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java index 328df33c63c..0550ee3cf26 100644 --- a/test/lib/testframework/RunMode.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; public enum RunMode { /** diff --git a/test/lib/testframework/Scenario.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java similarity index 98% rename from test/lib/testframework/Scenario.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java index d9d2ded505f..9d36d4b12db 100644 --- a/test/lib/testframework/Scenario.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.util.*; diff --git a/test/lib/testframework/Test.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java similarity index 96% rename from test/lib/testframework/Test.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/Test.java index 9220e488ca0..c8330bf5c3f 100644 --- a/test/lib/testframework/Test.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/lib/testframework/TestFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java similarity index 98% rename from test/lib/testframework/TestFormat.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java index 8f850749b7f..33464dabc31 100644 --- a/test/lib/testframework/TestFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.util.ArrayList; import java.util.List; diff --git a/test/lib/testframework/TestFormatException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java similarity index 96% rename from test/lib/testframework/TestFormatException.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java index 1307f50d7ed..d472eaa8986 100644 --- a/test/lib/testframework/TestFormatException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; public class TestFormatException extends RuntimeException { public TestFormatException(String message) { diff --git a/test/lib/testframework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java similarity index 96% rename from test/lib/testframework/TestFramework.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index f8cdde258b2..881e6790e8e 100644 --- a/test/lib/testframework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import jdk.test.lib.Utils; import jdk.test.lib.util.ClassFileInstaller; @@ -47,6 +47,7 @@ * public class Test { ... } */ public class TestFramework { + // TODO: Change back to false by default public static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "true")); private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); @@ -60,6 +61,10 @@ public TestFramework(Class testClass) { this.testClass = testClass; } + /* + * Public interface methods + */ + public static void run() { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); run(walker.getCallerClass()); @@ -132,6 +137,15 @@ public void start() { } } + public static String getLastVMOutput() { + return lastVMOutput; + } + + /** + * The following methods can only be called from actual tests and not from the main() method of a test. + * Calling these methods from main() results in a linking exception (Whitebox not yet loaded and enabled). + */ + // Can be called from tests for non-@Test methods public static void compile(Method m, CompLevel compLevel) { TestFrameworkExecution.compile(m, compLevel); @@ -177,9 +191,9 @@ public static void assertCompiled(Method m) { TestFrameworkExecution.assertCompiled(m); } - public static String getLastVMOutput() { - return lastVMOutput; - } + /* + * End of public interface methods + */ private void installWhiteBox() { try { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java new file mode 100644 index 00000000000..cbfb0a714e6 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +// Errors in the framework +class TestFrameworkException extends RuntimeException { + public TestFrameworkException(String message) { + super(message); + } + public TestFrameworkException(String message, Exception e) { + super(message, e); + } +} diff --git a/test/lib/testframework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java similarity index 98% rename from test/lib/testframework/TestFrameworkExecution.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index f5818cb2299..93542c29fdf 100644 --- a/test/lib/testframework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import jdk.test.lib.Asserts; import jdk.test.lib.Platform; @@ -31,8 +31,6 @@ import jdk.test.lib.process.ProcessTools; import sun.hotspot.WhiteBox; -import java.io.PrintWriter; -import java.io.StringWriter; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -50,12 +48,8 @@ public class TestFrameworkExecution { try { WHITE_BOX = WhiteBox.getWhiteBox(); } catch (UnsatisfiedLinkError e) { - System.err.println("Did you set up the jtreg test properly? Ensure that at least the following settings are set:"); - System.err.println(""" - * @library /testlibrary /test/lib /compiler/whitebox / - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI""".indent(1)); + System.err.println("Did you call a test-related interface method from TestFramework in main() of your test? " + + "Make sure to only call setup/run methods and no checks/assertions from main() of your test!"); throw e; } } @@ -66,7 +60,7 @@ public class TestFrameworkExecution { // User defined settings static final boolean XCOMP = Platform.isComp(); -// private static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); + // TODO: Change back to false by default static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "true")); private static final boolean PRINT_TIMES = Boolean.parseBoolean(System.getProperty("PrintTimes", "false")); @@ -94,7 +88,6 @@ public class TestFrameworkExecution { private final String[] printFlags; private final String[] verifyFlags; - static final boolean VERIFY_OOPS = (Boolean)WHITE_BOX.getVMFlag("VerifyOops"); private final HashMap declaredTests = new HashMap<>(); private final LinkedHashMap allTests = new LinkedHashMap<>(); // Keep order @@ -888,6 +881,7 @@ class BaseTest { private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); private static final int OSR_TEST_TIMEOUT = Integer.parseInt(System.getProperty("OSRTestTimeOut", "5000")); private static final int TEST_COMPILATION_TIMEOUT = Integer.parseInt(System.getProperty("TestCompilationTimeout", "5000")); + private static final boolean VERIFY_OOPS = (Boolean)WHITE_BOX.getVMFlag("VerifyOops"); protected final DeclaredTest test; protected final Method testMethod; @@ -974,7 +968,7 @@ private Object invokeTestMethod() { } private void compileOSRAndRun() { - final boolean maybeCodeBufferOverflow = (TestFrameworkExecution.TEST_C1 && TestFrameworkExecution.VERIFY_OOPS); + final boolean maybeCodeBufferOverflow = (TestFrameworkExecution.TEST_C1 && VERIFY_OOPS); final long started = System.currentTimeMillis(); boolean stateCleared = false; while (true) { @@ -1015,7 +1009,7 @@ private void retryDisabledVerifyOops(boolean stateCleared) { } private void compileTest() { - final boolean maybeCodeBufferOverflow = (TestFrameworkExecution.TEST_C1 && TestFrameworkExecution.VERIFY_OOPS); + final boolean maybeCodeBufferOverflow = (TestFrameworkExecution.TEST_C1 && VERIFY_OOPS); final Method testMethod = test.getTestMethod(); long started = System.currentTimeMillis(); long elapsed = 0; diff --git a/test/lib/testframework/TestFrameworkRunner.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkRunner.java similarity index 97% rename from test/lib/testframework/TestFrameworkRunner.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkRunner.java index b0a62a5767b..b90025a837a 100644 --- a/test/lib/testframework/TestFrameworkRunner.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkRunner.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import jdk.test.lib.Platform; import jdk.test.lib.management.InputArguments; @@ -30,8 +30,6 @@ import sun.hotspot.WhiteBox; import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; class TestFrameworkRunner { @@ -51,7 +49,7 @@ class TestFrameworkRunner { // User defined settings static final boolean XCOMP = Platform.isComp(); -// private static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); + // TODO: Change back to false by default static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "true")); private static final boolean COMPILE_COMMANDS = Boolean.parseBoolean(System.getProperty("CompileCommands", "true")) && !XCOMP; diff --git a/test/lib/testframework/TestInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java similarity index 98% rename from test/lib/testframework/TestInfo.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java index c78a29f4bea..afcf1f5d87b 100644 --- a/test/lib/testframework/TestInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java @@ -21,9 +21,7 @@ * questions. */ -package testframework; - -import sun.hotspot.WhiteBox; +package jdk.test.lib.hotspot.ir_framework; import java.lang.reflect.Method; import java.util.Arrays; diff --git a/test/lib/testframework/TestRun.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java similarity index 97% rename from test/lib/testframework/TestRun.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java index 972d23cb2b6..191b7091e44 100644 --- a/test/lib/testframework/TestRun.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; public class TestRun { public static void check(boolean test, String failureMessage) { diff --git a/test/lib/testframework/TestRunException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java similarity index 96% rename from test/lib/testframework/TestRunException.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java index 534563dc89e..0753d05b194 100644 --- a/test/lib/testframework/TestRunException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; public class TestRunException extends RuntimeException { public TestRunException(String message) { diff --git a/test/lib/testframework/Warmup.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java similarity index 96% rename from test/lib/testframework/Warmup.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java index 739d175eb16..52043d0091a 100644 --- a/test/lib/testframework/Warmup.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java @@ -21,7 +21,7 @@ * questions. */ -package testframework; +package jdk.test.lib.hotspot.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/lib/testframework/tests/TestBadFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java similarity index 99% rename from test/lib/testframework/tests/TestBadFormat.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java index 734a11dc8fc..d2379394c73 100644 --- a/test/lib/testframework/tests/TestBadFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java @@ -21,9 +21,9 @@ * questions. */ -package testframework.tests; +package jdk.test.lib.hotspot.ir_framework.tests; -import testframework.*; +import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; import java.lang.annotation.Retention; @@ -34,11 +34,12 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +// Must run with -DPrintValidIRRules=true public class TestBadFormat { private static Method runTestsOnSameVM; public static void main(String[] args) throws NoSuchMethodException { - runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); + runTestsOnSameVM = TestFrameworkExecution.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); expectTestFormatException(BadArgumentsAnnotation.class); expectTestFormatException(BadOverloadedMethod.class); diff --git a/test/lib/testframework/tests/TestBasics.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java similarity index 99% rename from test/lib/testframework/tests/TestBasics.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java index 30cc7b4a4d7..661e846a605 100644 --- a/test/lib/testframework/tests/TestBasics.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java @@ -21,9 +21,9 @@ * questions. */ -package testframework.tests; +package jdk.test.lib.hotspot.ir_framework.tests; -import testframework.*; +import jdk.test.lib.hotspot.ir_framework.*; import java.lang.reflect.Method; import java.util.Arrays; @@ -40,7 +40,7 @@ public class TestBasics { public static void main(String[] args) throws Exception { // Run on same VM to make this test easier as we are not interested in any output processing. - Method runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); + Method runTestsOnSameVM = TestFrameworkExecution.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); runTestsOnSameVM.invoke(null, new Object[]{ null }); diff --git a/test/lib/testframework/tests/TestCompLevels.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java similarity index 95% rename from test/lib/testframework/tests/TestCompLevels.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java index 79df630f72f..6f988a333d0 100644 --- a/test/lib/testframework/tests/TestCompLevels.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java @@ -21,9 +21,9 @@ * questions. */ -package testframework.tests; +package jdk.test.lib.hotspot.ir_framework.tests; -import testframework.*; +import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; import java.lang.reflect.Method; @@ -33,7 +33,7 @@ public class TestCompLevels { static int[] testExecuted = new int[4]; public static void main(String[] args) throws Exception { - Method runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); + Method runTestsOnSameVM = TestFrameworkExecution.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); runTestsOnSameVM.invoke(null, new Object[]{null}); for (int i = 0; i < testExecuted.length; i++) { diff --git a/test/lib/testframework/tests/TestControls.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java similarity index 97% rename from test/lib/testframework/tests/TestControls.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java index d5cd36031b0..f4ae9137bd8 100644 --- a/test/lib/testframework/tests/TestControls.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java @@ -21,9 +21,9 @@ * questions. */ -package testframework.tests; +package jdk.test.lib.hotspot.ir_framework.tests; -import testframework.*; +import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; import sun.hotspot.WhiteBox; @@ -37,7 +37,7 @@ public class TestControls { public int iFld; public static void main(String[] args) throws Exception { - Method runTestsOnSameVM = TestFramework.class.getDeclaredMethod("runTestsOnSameVM", Class.class); + Method runTestsOnSameVM = TestFrameworkExecution.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); runTestsOnSameVM.invoke(null, new Object[]{ null }); final int defaultIterations = TestFrameworkExecution.WARMUP_ITERATIONS + 1; diff --git a/test/lib/testframework/tests/TestIRMatching.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java similarity index 98% rename from test/lib/testframework/tests/TestIRMatching.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java index 23d171213db..08755ab66df 100644 --- a/test/lib/testframework/tests/TestIRMatching.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java @@ -21,9 +21,9 @@ * questions. */ -package testframework.tests; +package jdk.test.lib.hotspot.ir_framework.tests; -import testframework.*; +import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; import java.util.ArrayList; @@ -353,7 +353,7 @@ public void fail3() { } @Test - @IR(failOn = {IRNode.STORE_OF_CLASS, "testframework/tests/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "jdk/test/lib/hotspot/ir_framework/tests/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) public void fail4() { iFld = 42; } @@ -377,7 +377,7 @@ public void fail7() { } @Test - @IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "testframework/tests/MyClassSub"}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "jdk/test/lib/hotspot/ir_framework/tests/MyClassSub"}) public void fail8() { myClass = new MyClassSub(); } @@ -575,10 +575,10 @@ public void good4() { @Test @IR(counts = {IRNode.STORE, "2", IRNode.STORE_I, "1", IRNode.STORE_L, "1", IRNode.STORE_OF_CLASS, "GoodCount", "1", IRNode.STORE_L_OF_CLASS, "GoodCount", "1", - IRNode.STORE_OF_CLASS, "testframework/tests/MyClass", "1", - IRNode.STORE_I_OF_CLASS, "testframework/tests/MyClass", "1", - IRNode.STORE_OF_CLASS, "framework/tests/GoodCount", "1", - IRNode.STORE_L_OF_CLASS, "framework/tests/GoodCount", "1", + IRNode.STORE_OF_CLASS, "jdk/test/lib/hotspot/ir_framework/tests/MyClass", "1", + IRNode.STORE_I_OF_CLASS, "jdk/test/lib/hotspot/ir_framework/tests/MyClass", "1", + IRNode.STORE_OF_CLASS, "jdk/test/lib/hotspot/ir_framework/tests/GoodCount", "1", + IRNode.STORE_L_OF_CLASS, "jdk/test/lib/hotspot/ir_framework/tests/GoodCount", "1", IRNode.STORE_OF_FIELD, "x", "2"}) public void good5() { x = 3; // long @@ -697,8 +697,8 @@ class AllocArray { @IR(failOn = {IRNode.ALLOC_ARRAY}) @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClass"}) @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClasss"}) // Does not fail - @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "testframework/tests/MySubClass"}) // Does not fail - @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "testframework/tests/MyClass"}) + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "jdk/test/lib/hotspot/ir_framework/tests/MySubClass"}) // Does not fail + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "jdk/test/lib/hotspot/ir_framework/tests/MyClass"}) public void allocArray() { myClassArray = new MyClass[2]; } @@ -714,7 +714,7 @@ class Loads { @IR(failOn = {IRNode.LOOP, IRNode.LOOP}, counts = {IRNode.LOOP, "0", IRNode.LOAD, "1"}) // Does not fail @IR(failOn = {IRNode.LOOP, IRNode.LOOP}, counts = {IRNode.LOOP, "0", IRNode.STORE, "1"}) @IR(failOn = {IRNode.LOOP, IRNode.STORE}, counts = {IRNode.LOOP, "0", IRNode.LOAD, "1"}) - @IR(failOn = {IRNode.LOAD_OF_CLASS, "testframework/tests/Loads"}) + @IR(failOn = {IRNode.LOAD_OF_CLASS, "jdk/test/lib/hotspot/ir_framework/tests/Loads"}) @IR(failOn = {IRNode.LOAD_OF_CLASS, "Loads"}) @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld"}) @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld2", IRNode.LOAD_OF_CLASS, "Load"}) // Does not fail diff --git a/test/lib/testframework/tests/TestPackagePrivate.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestPackagePrivate.java similarity index 83% rename from test/lib/testframework/tests/TestPackagePrivate.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestPackagePrivate.java index 84005a60935..0c579372ee1 100644 --- a/test/lib/testframework/tests/TestPackagePrivate.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestPackagePrivate.java @@ -21,12 +21,12 @@ * questions. */ -package testframework.tests; +package jdk.test.lib.hotspot.ir_framework.tests; -import testframework.Argument; -import testframework.Arguments; -import testframework.Test; -import testframework.TestFramework; +import jdk.test.lib.hotspot.ir_framework.Argument; +import jdk.test.lib.hotspot.ir_framework.Test; +import jdk.test.lib.hotspot.ir_framework.TestFramework; +import jdk.test.lib.hotspot.ir_framework.Arguments; public class TestPackagePrivate { public static void main(String[] args) { diff --git a/test/lib/testframework/tests/TestSanity.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java similarity index 93% rename from test/lib/testframework/tests/TestSanity.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java index af3f6b42869..e4adfa75b6f 100644 --- a/test/lib/testframework/tests/TestSanity.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java @@ -21,11 +21,11 @@ * questions. */ -package testframework.tests; +package jdk.test.lib.hotspot.ir_framework.tests; -import testframework.Scenario; -import testframework.Test; -import testframework.TestFramework; +import jdk.test.lib.hotspot.ir_framework.Scenario; +import jdk.test.lib.hotspot.ir_framework.Test; +import jdk.test.lib.hotspot.ir_framework.TestFramework; public class TestSanity { diff --git a/test/lib/testframework/tests/TestScenarios.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java similarity index 96% rename from test/lib/testframework/tests/TestScenarios.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java index 22d6e61e4d0..b4d90a69661 100644 --- a/test/lib/testframework/tests/TestScenarios.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java @@ -21,9 +21,9 @@ * questions. */ -package testframework.tests; +package jdk.test.lib.hotspot.ir_framework.tests; -import testframework.*; +import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; public class TestScenarios { diff --git a/test/lib/testframework/tests/TestWithHelperClasses.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java similarity index 78% rename from test/lib/testframework/tests/TestWithHelperClasses.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java index 06100f17892..5a2ba0ec053 100644 --- a/test/lib/testframework/tests/TestWithHelperClasses.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java @@ -21,12 +21,12 @@ * questions. */ -package testframework.tests; +package jdk.test.lib.hotspot.ir_framework.tests; -import testframework.CompLevel; -import testframework.ForceCompile; -import testframework.Test; -import testframework.TestFramework; +import jdk.test.lib.hotspot.ir_framework.CompLevel; +import jdk.test.lib.hotspot.ir_framework.ForceCompile; +import jdk.test.lib.hotspot.ir_framework.Test; +import jdk.test.lib.hotspot.ir_framework.TestFramework; import jdk.test.lib.Asserts; public class TestWithHelperClasses { @@ -36,8 +36,9 @@ public static void main(String[] args) { try { TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class); } catch (Exception e) { - Asserts.assertFalse(TestFramework.getLastVMOutput().contains("public static void testframework.tests.Helper1.foo() should have been C2 compiled")); - Asserts.assertTrue(TestFramework.getLastVMOutput().contains("public static void testframework.tests.Helper2.foo() should have been C2 compiled")); + Asserts.assertFalse(TestFramework.getLastVMOutput().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper1.foo() should have been C2 compiled")); + Asserts.assertTrue(TestFramework.getLastVMOutput().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper2.foo() should have been C2 compiled")); + Asserts.assertFalse(TestFramework.getLastVMOutput().contains("Should not be executed")); return; } throw new RuntimeException("Did not catch exception"); diff --git a/test/lib/testframework/CheckedTestFrameworkException.java b/test/lib/testframework/CheckedTestFrameworkException.java deleted file mode 100644 index 0765a18e6e9..00000000000 --- a/test/lib/testframework/CheckedTestFrameworkException.java +++ /dev/null @@ -1,5 +0,0 @@ -package testframework; - -// Checked exceptions in the framework to propagate error handling. -class CheckedTestFrameworkException extends Exception { -} diff --git a/test/lib/testframework/TestFrameworkException.java b/test/lib/testframework/TestFrameworkException.java deleted file mode 100644 index 8f2b09c62a6..00000000000 --- a/test/lib/testframework/TestFrameworkException.java +++ /dev/null @@ -1,11 +0,0 @@ -package testframework; - -// Errors in the framework -class TestFrameworkException extends RuntimeException { - public TestFrameworkException(String message) { - super(message); - } - public TestFrameworkException(String message, Exception e) { - super(message, e); - } -} From c65facb7781e9a930c18813e2a8b82e9152a3fcf Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 4 Mar 2021 12:56:29 +0100 Subject: [PATCH 033/131] Propagate VM, test flags and scenario flags to test VM and exclude it from parent VMs --- test/lib/jdk/test/lib/Utils.java | 28 ++-- .../hotspot/ir_framework/TestFramework.java | 20 ++- .../ir_framework/TestFrameworkExecution.java | 150 +----------------- .../ir_framework/TestFrameworkRunner.java | 14 +- 4 files changed, 39 insertions(+), 173 deletions(-) diff --git a/test/lib/jdk/test/lib/Utils.java b/test/lib/jdk/test/lib/Utils.java index d719a227dc2..2ad27fbf90f 100644 --- a/test/lib/jdk/test/lib/Utils.java +++ b/test/lib/jdk/test/lib/Utils.java @@ -95,11 +95,6 @@ public final class Utils { */ public static final String TEST_SRC = System.getProperty("test.src", "").trim(); - /** - * Returns the value of 'test.src.path' system property - */ - public static final String TEST_SRC_PATH = System.getProperty("test.src.path", "").trim(); - /** * Returns the value of 'test.root' system property. */ @@ -125,17 +120,11 @@ public final class Utils { */ public static final String TEST_NAME = System.getProperty("test.name", "."); - /** - * Returns the value of 'test.file' system property - */ - public static final String TEST_FILE = System.getProperty("test.file", "").trim(); - /** * Returns the value of 'test.nativepath' system property */ public static final String TEST_NATIVE_PATH = System.getProperty("test.nativepath", "."); - /** * Defines property name for seed value. */ @@ -225,6 +214,23 @@ public static String[] getTestJavaOpts() { return opts.toArray(new String[0]); } + /** + * Returns the default JTReg arguments as property flags for a jvm running a test. + * This is the combination of JTReg arguments test.vm.opts with a "-Dtest.vm.opts=" + * and test.java.opts with a "-Dtest.java.opts=" prefix. + * @return A list of prefixed options, or an empty list if no options. + */ + public static List getTestJavaOptsAsPropertyFlags() { + List opts = new ArrayList<>(); + if (!VM_OPTIONS.isEmpty()) { + opts.add("-Dtest.vm.opts=" + VM_OPTIONS); + } + if (!JAVA_OPTIONS.isEmpty()) { + opts.add("-Dtest.java.opts=" + JAVA_OPTIONS); + } + return opts; + } + /** * Combines given arguments with default JTReg arguments for a jvm running a test. * This is the combination of JTReg arguments test.vm.opts and test.java.opts diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 881e6790e8e..dc8fbe93506 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -49,7 +49,6 @@ public class TestFramework { // TODO: Change back to false by default public static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "true")); - private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); private List> helperClasses = null; private List scenarios = null; @@ -246,22 +245,18 @@ private void start(Scenario scenario) { return; } - ArrayList cmds = new ArrayList<>(); + ArrayList cmds = new ArrayList<>(Utils.getTestJavaOptsAsPropertyFlags()); cmds.add("-Dtest.jdk=" + Utils.TEST_JDK); cmds.add("-cp"); cmds.add(Utils.TEST_CLASS_PATH); cmds.add("-Xbootclasspath/a:."); cmds.add("-XX:+UnlockDiagnosticVMOptions"); cmds.add("-XX:+WhiteBoxAPI"); - if (!PREFER_COMMAND_LINE_FLAGS) { - cmds.addAll(Arrays.asList(InputArguments.getVmInputArgs())); - } if (scenario != null) { System.out.println("Running Scenario #" + scenario.getIndex()); - cmds.addAll(scenario.getFlags()); - } - if (PREFER_COMMAND_LINE_FLAGS) { - cmds.addAll(Arrays.asList(InputArguments.getVmInputArgs())); + // Propagate scenario flags to TestFramework runner VM but do not apply them yet. + // These should only be applied to the test VM. + cmds.add("-DScenarioFlags=" + String.join(" ", scenario.getFlags())); } cmds.add(TestFrameworkRunner.class.getCanonicalName()); cmds.add(testClass.getCanonicalName()); @@ -271,9 +266,11 @@ private void start(Scenario scenario) { OutputAnalyzer oa; try { - oa = ProcessTools.executeProcess(ProcessTools.createTestJvm(cmds)); + // Propagate scenario test and VM flags to TestFramework runner VM but do not apply them yet. + // These should only be applied to the test VM. + oa = ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder(cmds)); } catch (Exception e) { - throw new TestRunException("Failed to execute test VM", e); + throw new TestRunException("Failed to execute TestFramework runner VM", e); } lastVMOutput = oa.getOutput(); @@ -282,6 +279,7 @@ private void start(Scenario scenario) { } final int exitCode = oa.getExitValue(); if (VERBOSE && exitCode == 0) { + System.out.println("--- OUTPUT TestFramework runner VM ---"); System.out.println(lastVMOutput); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 93542c29fdf..066421a6e69 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -26,9 +26,6 @@ import jdk.test.lib.Asserts; import jdk.test.lib.Platform; import jdk.test.lib.Utils; -import jdk.test.lib.management.InputArguments; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.process.ProcessTools; import sun.hotspot.WhiteBox; import java.lang.annotation.Annotation; @@ -36,8 +33,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Stream; @@ -64,31 +59,19 @@ public class TestFrameworkExecution { static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "true")); private static final boolean PRINT_TIMES = Boolean.parseBoolean(System.getProperty("PrintTimes", "false")); - private static final boolean COMPILE_COMMANDS = Boolean.parseBoolean(System.getProperty("CompileCommands", "true")) && !XCOMP; static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); static final boolean STRESS_CC = Boolean.parseBoolean(System.getProperty("StressCC", "false")); - private static final boolean REQUESTED_VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); - private static boolean VERIFY_IR = REQUESTED_VERIFY_IR && USE_COMPILER && !XCOMP && !STRESS_CC && !TEST_C1 && COMPILE_COMMANDS - && Platform.isDebugBuild() && !Platform.isInt(); - private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false")) && Platform.isDebugBuild(); private static final String TESTLIST = System.getProperty("Testlist", ""); private static final String EXCLUDELIST = System.getProperty("Exclude", ""); public static final int WARMUP_ITERATIONS = Integer.parseInt(System.getProperty("Warmup", "2000")); private static final boolean DUMP_REPLAY = Boolean.parseBoolean(System.getProperty("DumpReplay", "false")); private static final boolean GC_AFTER = Boolean.parseBoolean(System.getProperty("GCAfter", "false")); private static final boolean SHUFFLE_TESTS = Boolean.parseBoolean(System.getProperty("ShuffleTests", "true")); - private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); private static final boolean PRINT_VALID_IR_RULES = Boolean.parseBoolean(System.getProperty("PrintValidIRRules", "false")); protected static final long PerMethodTrapLimit = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); protected static final boolean ProfileInterpreter = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); private static final boolean FLIP_C1_C2 = Boolean.parseBoolean(System.getProperty("FlipC1C2", "false")); - private final String[] fixedDefaultFlags; - private final String[] compileCommandFlags; - private final String[] printFlags; - private final String[] verifyFlags; - - private final HashMap declaredTests = new HashMap<>(); private final LinkedHashMap allTests = new LinkedHashMap<>(); // Keep order private final HashMap testMethodMap = new HashMap<>(); @@ -101,12 +84,6 @@ public class TestFrameworkExecution { private TestFrameworkExecution(Class testClass) { TestRun.check(testClass != null, "Test class cannot be null"); this.testClass = testClass; - // These flags can be overridden - fixedDefaultFlags = initDefaultFlags(); - compileCommandFlags = initCompileCommandFlags(); - printFlags = initPrintFlags(); - verifyFlags = initVerifyFlags(); - this.includeList = createTestFilterList(TESTLIST, testClass); this.excludeList = createTestFilterList(EXCLUDELIST, testClass); @@ -117,24 +94,6 @@ private TestFrameworkExecution(Class testClass) { } } - protected String[] initDefaultFlags() { - return new String[] {"-XX:-BackgroundCompilation"}; - } - - protected String[] initCompileCommandFlags() { - return new String[] {"-XX:CompileCommand=quiet"}; - } - - protected String[] initPrintFlags() { - return new String[] {"-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions"}; - } - - protected String[] initVerifyFlags() { - return new String[] { - "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", "-XX:+VerifyBeforeGC", - "-XX:+VerifyAfterGC", "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing"}; - } - private List createTestFilterList(String list, Class testClass) { List filterList = null; if (!list.isEmpty()) { @@ -167,7 +126,7 @@ public static void main(String[] args) { TestFrameworkExecution framework = new TestFrameworkExecution(testClass); framework.addHelperClasses(args); - framework.runTestsOnSameVM(); + framework.start(); } private void addHelperClasses(String[] args) { @@ -206,10 +165,10 @@ private static void runTestsOnSameVM(Class testClass) { testClass = walker.getCallerClass(); } TestFrameworkExecution framework = new TestFrameworkExecution(testClass); - framework.runTestsOnSameVM(); + framework.start(); } - private void runTestsOnSameVM() { + private void start() { if (helperClasses != null) { for (Class helperClass : helperClasses) { // Process the helper classes and apply the explicit compile commands @@ -220,109 +179,6 @@ private void runTestsOnSameVM() { runTests(); } - private void runTestVM() { - ArrayList cmds = prepareTestVmFlags(); - OutputAnalyzer oa; - try { - // Calls 'main' of this class to run all specified tests with commands 'cmds'. - oa = ProcessTools.executeTestJvm(cmds); - } catch (Exception e) { - throw new TestFrameworkException("Error while executing Test VM", e); - } - String output = oa.getOutput(); - final int exitCode = oa.getExitValue(); - if (VERBOSE || exitCode != 0) { - System.out.println(" ----- OUTPUT -----"); - System.out.println(output); - - } - if (exitCode != 0) { - throwTestException(oa, exitCode); - } - - if (VERIFY_IR) { - IRMatcher irMatcher = new IRMatcher(output, testClass); - irMatcher.applyRules(); - } - } - - private ArrayList prepareTestVmFlags() { - String[] vmInputArguments = InputArguments.getVmInputArgs(); - ArrayList cmds = new ArrayList<>(); - if (!PREFER_COMMAND_LINE_FLAGS) { - cmds.addAll(Arrays.asList(vmInputArguments)); - } - - setupIrVerificationFlags(testClass, cmds); - - if (VERIFY_VM) { - cmds.addAll(Arrays.asList(verifyFlags)); - } - - cmds.addAll(Arrays.asList(fixedDefaultFlags)); - if (COMPILE_COMMANDS) { - cmds.addAll(Arrays.asList(compileCommandFlags)); - } - - // TODO: Only for debugging - if (cmds.get(0).startsWith("-agentlib")) { - cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=n,server=y"); - } - - if (PREFER_COMMAND_LINE_FLAGS) { - // Prefer flags set via the command line over the ones set by scenarios. - cmds.addAll(Arrays.asList(vmInputArguments)); - } - - cmds.add(getClass().getCanonicalName()); - cmds.add(testClass.getCanonicalName()); - if (helperClasses != null) { - helperClasses.forEach(c -> cmds.add(c.getCanonicalName())); - } - return cmds; - } - - private void setupIrVerificationFlags(Class testClass, ArrayList cmds) { - if (VERIFY_IR && cmds.stream().anyMatch(flag -> flag.startsWith("-XX:CompileThreshold"))) { - // Disable IR verification if non-default CompileThreshold is set - if (VERBOSE) { - System.out.println("Disabled IR verification due to CompileThreshold flag"); - } - VERIFY_IR = false; - } else if (!VERIFY_IR && REQUESTED_VERIFY_IR) { - System.out.println("IR Verification disabled either due to not running a debug build, running with -Xint, or other " + - "VM flags that make the verification inaccurate or impossible (e.g. running with C1 only)."); - } - - if (VERIFY_IR) { - // Add print flags for IR verification - cmds.addAll(Arrays.asList(printFlags)); - addBoolOptionForClass(cmds, testClass, "PrintIdeal"); - addBoolOptionForClass(cmds, testClass, "PrintOptoAssembly"); - // Always trap for exception throwing to not confuse IR verification - cmds.add("-XX:-OmitStackTraceInFastThrow"); - cmds.add("-DPrintValidIRRules=true"); - } else { - cmds.add("-DPrintValidIRRules=false"); - } - } - - private void addBoolOptionForClass(ArrayList cmds, Class testClass, String option) { - cmds.add("-XX:CompileCommand=option," + testClass.getCanonicalName() + "::*,bool," + option + ",true"); - } - - private void throwTestException(OutputAnalyzer oa, int exitCode) { - String stdErr = oa.getStderr(); - if (stdErr.contains("TestFormat.reportIfAnyFailures")) { - Pattern pattern = Pattern.compile("Violations \\(\\d+\\)[\\s\\S]*(?=/============/)"); - Matcher matcher = pattern.matcher(stdErr); - TestFramework.check(matcher.find(), "Must find violation matches"); - throw new TestFormatException("\n\n" + matcher.group()); - } else { - throw new TestRunException("\nVM exited with " + exitCode + "\n\nError Output:\n" + stdErr); - } - } - private void parseTestClass() { addReplay(); processExplicitCompileCommands(testClass); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkRunner.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkRunner.java index b90025a837a..1fe10a50538 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkRunner.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkRunner.java @@ -59,6 +59,7 @@ class TestFrameworkRunner { private static boolean VERIFY_IR = REQUESTED_VERIFY_IR && USE_COMPILER && !XCOMP && !STRESS_CC && !TEST_C1 && COMPILE_COMMANDS && Platform.isDebugBuild() && !Platform.isInt(); private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false")) && Platform.isDebugBuild(); + private static final String SCENARIO_FLAGS = System.getProperty("ScenarioFlags", ""); private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); private static String[] getDefaultFlags() { @@ -95,19 +96,22 @@ private static void runTestVM(Class testClass, String[] args) { ArrayList cmds = prepareTestVmFlags(testClass, args); OutputAnalyzer oa; try { - // Calls 'main' of this class to run all specified tests with commands 'cmds'. + // Calls 'main' of TestFrameworkExecution to run all specified tests with commands 'cmds'. + // It also prepends all -Dtest* properties as flags for the test VM. oa = ProcessTools.executeTestJvm(cmds); } catch (Exception e) { throw new TestFrameworkException("Error while executing Test VM", e); } String output = oa.getOutput(); final int exitCode = oa.getExitValue(); - if (VERBOSE || exitCode != 0) { - System.out.println(" ----- OUTPUT -----"); + if (VERBOSE && exitCode == 0) { + System.out.println(" ----- OUTPUT Test VM-----"); System.out.println(output); } if (exitCode != 0) { + System.err.println(" ----- OUTPUT Test VM -----"); + System.err.println(output); throw new RuntimeException("\nTestFramework runner VM exited with " + exitCode); } @@ -123,7 +127,9 @@ private static ArrayList prepareTestVmFlags(Class testClass, String[] if (!PREFER_COMMAND_LINE_FLAGS) { cmds.addAll(Arrays.asList(vmInputArguments)); } - + if (!SCENARIO_FLAGS.isEmpty()) { + cmds.addAll(Arrays.asList(SCENARIO_FLAGS.split("\\s+"))); + } setupIrVerificationFlags(testClass, cmds); if (VERIFY_VM) { From 0c31c5bf8aaf6d404330b271123fdd6d9603280a Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 4 Mar 2021 15:41:35 +0100 Subject: [PATCH 034/131] Some minor clean ups --- .../lib/hotspot/ir_framework/Scenario.java | 2 +- .../hotspot/ir_framework/TestFramework.java | 12 ++++++----- .../ir_framework/TestFrameworkExecution.java | 3 +-- .../ir_framework/TestFrameworkRunner.java | 3 +-- .../lib/hotspot/ir_framework/TestInfo.java | 20 +++++++++++-------- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java index 9d36d4b12db..90534d81ada 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java @@ -49,7 +49,7 @@ public class Scenario { public Scenario(int index, String... flags) { this.index = index; - if (enabledScenarios.isEmpty() || enabledScenarios.contains(index)) { + if (flags != null && (enabledScenarios.isEmpty() || enabledScenarios.contains(index))) { this.flags = new ArrayList<>(Arrays.asList(flags)); this.flags.addAll(additionalScenarioFlags); this.enabled = true; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index dc8fbe93506..d806a2c191e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -47,8 +47,7 @@ * public class Test { ... } */ public class TestFramework { - // TODO: Change back to false by default - public static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "true")); + public static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); private List> helperClasses = null; private List scenarios = null; @@ -212,6 +211,9 @@ private void startWithScenarios() { scenarioIndecies.add(scenarioIndex); try { start(scenario); + } catch (TestFormatException e) { + // Test format violation is wrong for all the scenarios. Only report once. + throw new TestFormatException(e.getMessage()); } catch (Exception e) { exceptionMap.put(String.valueOf(scenarioIndex), e); } @@ -223,8 +225,8 @@ private void startWithScenarios() { String title = "Stacktrace for Scenario #" + entry.getKey(); builder.append(title).append("\n").append("=".repeat(title.length())).append("\n"); Exception e = entry.getValue(); - if (e instanceof TestFormatException || e instanceof IRViolationException) { - // For format or IR violations, only show the actual message and not the (uninteresting) stack trace. + if (e instanceof IRViolationException) { + // For IR violations, only show the actual message and not the (uninteresting) stack trace. builder.append(e.getMessage()); } else { // Print stack trace if it was not a format violation or test run exception @@ -253,7 +255,7 @@ private void start(Scenario scenario) { cmds.add("-XX:+UnlockDiagnosticVMOptions"); cmds.add("-XX:+WhiteBoxAPI"); if (scenario != null) { - System.out.println("Running Scenario #" + scenario.getIndex()); + System.out.println("Running Scenario #" + scenario.getIndex() + " - [" + String.join(",", scenario.getFlags()) + "]"); // Propagate scenario flags to TestFramework runner VM but do not apply them yet. // These should only be applied to the test VM. cmds.add("-DScenarioFlags=" + String.join(" ", scenario.getFlags())); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 066421a6e69..ee5979a3610 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -55,8 +55,7 @@ public class TestFrameworkExecution { // User defined settings static final boolean XCOMP = Platform.isComp(); - // TODO: Change back to false by default - static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "true")); + static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); private static final boolean PRINT_TIMES = Boolean.parseBoolean(System.getProperty("PrintTimes", "false")); static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkRunner.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkRunner.java index 1fe10a50538..a563dc9a81e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkRunner.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkRunner.java @@ -49,8 +49,7 @@ class TestFrameworkRunner { // User defined settings static final boolean XCOMP = Platform.isComp(); - // TODO: Change back to false by default - static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "true")); + static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); private static final boolean COMPILE_COMMANDS = Boolean.parseBoolean(System.getProperty("CompileCommands", "true")) && !XCOMP; static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java index afcf1f5d87b..0c17bd3a951 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java @@ -82,35 +82,39 @@ public Method getTestClassMethod(String name, Class... args) { return getMethod(testMethod.getDeclaringClass(), name, args); } + public boolean isC1Test() { + return TestFrameworkExecution.TEST_C1; + } + public boolean isC1Compiled(Method m) { - return TestFramework.isC1Compiled(testMethod); + return TestFrameworkExecution.isC1Compiled(testMethod); } public boolean isC2Compiled(Method m) { - return TestFramework.isC2Compiled(testMethod); + return TestFrameworkExecution.isC2Compiled(testMethod); } public boolean isCompiledAtLevel(CompLevel compLevel) { - return TestFramework.isCompiledAtLevel(testMethod, compLevel); + return TestFrameworkExecution.isCompiledAtLevel(testMethod, compLevel); } public void assertDeoptimizedByC1() { - TestFramework.assertDeoptimizedByC1(testMethod); + TestFrameworkExecution.assertDeoptimizedByC1(testMethod); } public void assertCompiledByC1() { - TestFramework.assertCompiledByC1(testMethod); + TestFrameworkExecution.assertCompiledByC1(testMethod); } public void assertDeoptimizedByC2() { - TestFramework.assertDeoptimizedByC2(testMethod); + TestFrameworkExecution.assertDeoptimizedByC2(testMethod); } public void assertCompiledByC2() { - TestFramework.assertCompiledByC2(testMethod); + TestFrameworkExecution.assertCompiledByC2(testMethod); } public void assertCompiledAtLevel(CompLevel level) { - TestFramework.assertCompiledAtLevel(testMethod, level); + TestFrameworkExecution.assertCompiledAtLevel(testMethod, level); } } From 1e9412bed7555e79398df7176f54b6c56ddf6d76 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 4 Mar 2021 15:41:59 +0100 Subject: [PATCH 035/131] Some first conversion attempts --- .../testframework/DefaultScenarios.java | 71 ++++++++++++++ .../valhalla/testframework/InlineHelpers.java | 4 + .../valhalla/testframework/MyAbstract.java | 5 + .../MyConstants.java} | 11 ++- .../MyInterface.java | 4 +- .../MyValue1.java | 14 +-- .../MyValue2.java | 10 +- .../MyValue3.java | 5 +- .../MyValue4.java | 6 +- .../MyValueEmpty.java | 4 +- .../NamedRectangle.java | 4 +- .../{inlinetypes => testframework}/Point.java | 4 +- .../Rectangle.java | 4 +- .../SimpleInlineType.java | 4 +- .../TestNullableInlineTypes.java | 83 ++++++++++++++++ .../TestUnloadedInlineTypeField.java | 95 +++++++++++++++++++ 16 files changed, 299 insertions(+), 29 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/DefaultScenarios.java create mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/InlineHelpers.java create mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/MyAbstract.java rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes/MyAbstract.java => testframework/MyConstants.java} (71%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => testframework}/MyInterface.java (89%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => testframework}/MyValue1.java (91%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => testframework}/MyValue2.java (92%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => testframework}/MyValue3.java (98%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => testframework}/MyValue4.java (93%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => testframework}/MyValueEmpty.java (90%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => testframework}/NamedRectangle.java (92%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => testframework}/Point.java (90%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => testframework}/Rectangle.java (91%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => testframework}/SimpleInlineType.java (91%) create mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/TestNullableInlineTypes.java create mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/TestUnloadedInlineTypeField.java diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/DefaultScenarios.java b/test/hotspot/jtreg/compiler/valhalla/testframework/DefaultScenarios.java new file mode 100644 index 00000000000..333ef7ac89d --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/DefaultScenarios.java @@ -0,0 +1,71 @@ +package compiler.valhalla.testframework; + +import jdk.test.lib.hotspot.ir_framework.Scenario; + +public class DefaultScenarios { + /** + * VM parameters for the 5 built-in test scenarios. If your test needs to append + * extra parameters for (some of) these scenarios, override getExtraVMParameters(). + */ + public static final Scenario[] SCENARIOS = { + new Scenario(0, + "-XX:-UseACmpProfile", + "-XX:+AlwaysIncrementalInline", + "-XX:FlatArrayElementMaxOops=5", + "-XX:FlatArrayElementMaxSize=-1", + "-XX:-UseArrayLoadStoreProfile", + "-XX:InlineFieldMaxFlatSize=-1", + "-XX:+InlineTypePassFieldsAsArgs", + "-XX:+InlineTypeReturnedAsFields" + ), + new Scenario(1, + "-XX:-UseACmpProfile", + "-XX:-UseCompressedOops", + "-XX:FlatArrayElementMaxOops=5", + "-XX:FlatArrayElementMaxSize=-1", + "-XX:-UseArrayLoadStoreProfile", + "-XX:InlineFieldMaxFlatSize=-1", + "-XX:-InlineTypePassFieldsAsArgs", + "-XX:-InlineTypeReturnedAsFields" + ), + new Scenario(2, + "-XX:-UseACmpProfile", + "-XX:-UseCompressedOops", + "-XX:FlatArrayElementMaxOops=0", + "-XX:FlatArrayElementMaxSize=0", + "-XX:-UseArrayLoadStoreProfile", + "-XX:InlineFieldMaxFlatSize=-1", + "-XX:+InlineTypePassFieldsAsArgs", + "-XX:+InlineTypeReturnedAsFields", + "-XX:+StressInlineTypeReturnedAsFields" + ), + new Scenario(3, + "-DVerifyIR=false", + "-XX:+AlwaysIncrementalInline", + "-XX:FlatArrayElementMaxOops=0", + "-XX:FlatArrayElementMaxSize=0", + "-XX:InlineFieldMaxFlatSize=0", + "-XX:+InlineTypePassFieldsAsArgs", + "-XX:+InlineTypeReturnedAsFields" + ), + new Scenario(4, + "-DVerifyIR=false", + "-XX:FlatArrayElementMaxOops=-1", + "-XX:FlatArrayElementMaxSize=-1", + "-XX:InlineFieldMaxFlatSize=0", + "-XX:+InlineTypePassFieldsAsArgs", + "-XX:-InlineTypeReturnedAsFields", + "-XX:-ReduceInitialCardMarks" + ), + new Scenario(5, + "-XX:-UseACmpProfile", + "-XX:+AlwaysIncrementalInline", + "-XX:FlatArrayElementMaxOops=5", + "-XX:FlatArrayElementMaxSize=-1", + "-XX:-UseArrayLoadStoreProfile", + "-XX:InlineFieldMaxFlatSize=-1", + "-XX:-InlineTypePassFieldsAsArgs", + "-XX:-InlineTypeReturnedAsFields" + ) + }; +} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/InlineHelpers.java b/test/hotspot/jtreg/compiler/valhalla/testframework/InlineHelpers.java new file mode 100644 index 00000000000..9120782234d --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/InlineHelpers.java @@ -0,0 +1,4 @@ +package compiler.valhalla.testframework; + +public class InlineHelpers { +} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/MyAbstract.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyAbstract.java new file mode 100644 index 00000000000..d03e4b717ec --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/MyAbstract.java @@ -0,0 +1,5 @@ +package compiler.valhalla.testframework; + +public abstract class MyAbstract implements MyInterface { + +} diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyAbstract.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyConstants.java similarity index 71% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyAbstract.java rename to test/hotspot/jtreg/compiler/valhalla/testframework/MyConstants.java index 2b7718ffa62..6d26296e501 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyAbstract.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/MyConstants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -21,9 +21,12 @@ * questions. */ -package compiler.valhalla.inlinetypes; +package compiler.valhalla.testframework; -public abstract class MyAbstract implements MyInterface { +import jdk.test.lib.Utils; +public class MyConstants { + public static final int rI = Utils.getRandomInstance().nextInt() % 1000; + public static final long rL = Utils.getRandomInstance().nextLong() % 1000; + public static final double rD = Utils.getRandomInstance().nextDouble() % 1000; } - diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyInterface.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyInterface.java similarity index 89% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyInterface.java rename to test/hotspot/jtreg/compiler/valhalla/testframework/MyInterface.java index 20a09a5f774..5f6666c0a08 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyInterface.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/MyInterface.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, 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 @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.inlinetypes; +package compiler.valhalla.testframework; public interface MyInterface { public long hash(); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue1.java similarity index 91% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java rename to test/hotspot/jtreg/compiler/valhalla/testframework/MyValue1.java index 016ebf4dc41..0ae04a0b39b 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -21,11 +21,13 @@ * questions. */ -package compiler.valhalla.inlinetypes; +package compiler.valhalla.testframework; + +import jdk.test.lib.hotspot.ir_framework.*; public final primitive class MyValue1 extends MyAbstract { static int s; - static final long sf = InlineTypeTest.rL; + static final long sf = MyConstants.rL; final int x; final long y; final short z; @@ -33,7 +35,7 @@ public final primitive class MyValue1 extends MyAbstract { final int[] oa; final MyValue2 v1; final MyValue2 v2; - static final MyValue2 v3 = MyValue2.createWithFieldsInline(InlineTypeTest.rI, InlineTypeTest.rD); + static final MyValue2 v3 = MyValue2.createWithFieldsInline(MyConstants.rI, MyConstants.rD); final int c; @ForceInline @@ -74,8 +76,8 @@ static MyValue1 createWithFieldsInline(int x, long y) { v = setO(v, new Integer(x)); int[] oa = {x}; v = setOA(v, oa); - v = setV1(v, MyValue2.createWithFieldsInline(x, y, InlineTypeTest.rD)); - v = setV2(v, MyValue2.createWithFieldsInline(x, y, InlineTypeTest.rD+x)); + v = setV1(v, MyValue2.createWithFieldsInline(x, y, MyConstants.rD)); + v = setV2(v, MyValue2.createWithFieldsInline(x, y, MyConstants.rD + x)); v = setC(v, (int)(x+y)); return v; } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue2.java similarity index 92% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java rename to test/hotspot/jtreg/compiler/valhalla/testframework/MyValue2.java index 859708d8575..0dadfa2cd1b 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -21,7 +21,9 @@ * questions. */ -package compiler.valhalla.inlinetypes; +package compiler.valhalla.testframework; + +import jdk.test.lib.hotspot.ir_framework.*; final primitive class MyValue2Inline { final double d; @@ -88,7 +90,7 @@ public static MyValue2 createWithFieldsInline(int x, double d) { MyValue2 v = createDefaultInline(); v = setX(v, x); v = setY(v, (byte)x); - v = setV(v, MyValue2Inline.createWithFieldsInline(d, InlineTypeTest.rL)); + v = setV(v, MyValue2Inline.createWithFieldsInline(d, MyConstants.rL)); return v; } @@ -97,7 +99,7 @@ public static MyValue2 createWithFieldsDontInline(int x, double d) { MyValue2 v = createDefaultInline(); v = setX(v, x); v = setY(v, (byte)x); - v = setV(v, MyValue2Inline.createWithFieldsInline(d, InlineTypeTest.rL)); + v = setV(v, MyValue2Inline.createWithFieldsInline(d, MyConstants.rL)); return v; } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue3.java similarity index 98% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java rename to test/hotspot/jtreg/compiler/valhalla/testframework/MyValue3.java index fa3b468a790..f9742aefd0d 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue3.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -21,8 +21,9 @@ * questions. */ -package compiler.valhalla.inlinetypes; +package compiler.valhalla.testframework; +import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; import jdk.test.lib.Utils; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue4.java similarity index 93% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java rename to test/hotspot/jtreg/compiler/valhalla/testframework/MyValue4.java index fcf3f38d7ea..eb223519f07 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue4.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -21,7 +21,9 @@ * questions. */ -package compiler.valhalla.inlinetypes; +package compiler.valhalla.testframework; + +import jdk.test.lib.hotspot.ir_framework.*; // Inline type definition with too many fields to return in registers final primitive class MyValue4 extends MyAbstract { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValueEmpty.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValueEmpty.java similarity index 90% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValueEmpty.java rename to test/hotspot/jtreg/compiler/valhalla/testframework/MyValueEmpty.java index 7396f0b42f8..5dd743a3c82 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValueEmpty.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValueEmpty.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, 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 @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.inlinetypes; +package compiler.valhalla.testframework; public final primitive class MyValueEmpty extends MyAbstract { public long hash() { return 0; } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/NamedRectangle.java b/test/hotspot/jtreg/compiler/valhalla/testframework/NamedRectangle.java similarity index 92% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/NamedRectangle.java rename to test/hotspot/jtreg/compiler/valhalla/testframework/NamedRectangle.java index 052c8402f5e..853edff5977 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/NamedRectangle.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/NamedRectangle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, 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 @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.inlinetypes; +package compiler.valhalla.testframework; public class NamedRectangle { Rectangle rect = new Rectangle(); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/Point.java b/test/hotspot/jtreg/compiler/valhalla/testframework/Point.java similarity index 90% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/Point.java rename to test/hotspot/jtreg/compiler/valhalla/testframework/Point.java index 0a57bc4e990..31cd364437d 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/Point.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/Point.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, 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 @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.inlinetypes; +package compiler.valhalla.testframework; public primitive class Point { int x = 4; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/Rectangle.java b/test/hotspot/jtreg/compiler/valhalla/testframework/Rectangle.java similarity index 91% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/Rectangle.java rename to test/hotspot/jtreg/compiler/valhalla/testframework/Rectangle.java index 8d2d3c9bf3e..3ebe9f8f38e 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/Rectangle.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/Rectangle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, 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 @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.inlinetypes; +package compiler.valhalla.testframework; public primitive class Rectangle { Point p0 = new Point(); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/SimpleInlineType.java b/test/hotspot/jtreg/compiler/valhalla/testframework/SimpleInlineType.java similarity index 91% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/SimpleInlineType.java rename to test/hotspot/jtreg/compiler/valhalla/testframework/SimpleInlineType.java index c09cb8d599c..decb480647f 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/SimpleInlineType.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/SimpleInlineType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -21,6 +21,8 @@ * questions. */ +package compiler.valhalla.testframework; + final primitive class SimpleInlineType { final int x; diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/TestNullableInlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/testframework/TestNullableInlineTypes.java new file mode 100644 index 00000000000..0add433f4ee --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/TestNullableInlineTypes.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020, 2021, 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. + */ + +/* + * @test + * @key randomness + * @summary Test correct handling of nullable inline types. + * @library /test/lib + * @run driver compiler.valhalla.testframework.TestNullableInlineTypes + */ + +package compiler.valhalla.testframework; + +import jdk.test.lib.hotspot.ir_framework.*; + +public abstract class TestNullableInlineTypes { + private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(2, 3); + + public static void main(String[] args) { + Scenario[] scenarios = DefaultScenarios.SCENARIOS; + scenarios[3] = new Scenario(3, "-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"); + scenarios[4] = new Scenario(4, "-XX:-MonomorphicArrayCheck"); + TestFramework testFramework = new TestFramework(TestNullableInlineTypes.class); + testFramework.addScenarios(scenarios) + .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class, + TestNullableInlineTypes.Test17Value.class, TestNullableInlineTypes.Test21Value.class) + .start(); + } + + // Test scalarization of default inline type with non-flattenable field + final primitive class Test17Value { + public final MyValue1.ref valueField; + + @ForceInline + public Test17Value(MyValue1.ref valueField) { + this.valueField = valueField; + } + } + + // Test writing null to a flattenable/non-flattenable inline type field in an inline type + final primitive class Test21Value { + final MyValue1.ref valueField1; + final MyValue1 valueField2; + final MyValue1.ref alwaysNull = null; + + @ForceInline + public Test21Value(MyValue1.ref valueField1, MyValue1 valueField2) { + this.valueField1 = testValue1; + this.valueField2 = testValue1; + } + + @ForceInline + public TestNullableInlineTypes.Test21Value test1() { + return new TestNullableInlineTypes.Test21Value(alwaysNull, this.valueField2); // Should not throw NPE + } + + @ForceInline + public TestNullableInlineTypes.Test21Value test2() { + return new TestNullableInlineTypes.Test21Value(this.valueField1, (MyValue1) alwaysNull); // Should throw NPE + } + } +} + diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/TestUnloadedInlineTypeField.java b/test/hotspot/jtreg/compiler/valhalla/testframework/TestUnloadedInlineTypeField.java new file mode 100644 index 00000000000..f0d4d79ed4d --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/TestUnloadedInlineTypeField.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2019, 2021, 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. + */ + +/* + * @test + * @key randomness + * @summary Test the handling of fields of unloaded inline classes. + * @library /test/lib + * @compile MyConstants.java + * @run driver compiler.valhalla.testframework.TestUnloadedInlineTypeField + */ +package compiler.valhalla.testframework; + +import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; + +public class TestUnloadedInlineTypeField { + + public static void main(String[] args) { + Scenario s0 = new Scenario(0); + Scenario s1 = new Scenario(1, "-XX:InlineFieldMaxFlatSize=0"); + Scenario s2 = new Scenario(2, "-XX:+PatchALot"); + Scenario s3 = new Scenario(3, "-XX:InlineFieldMaxFlatSize=0", "-XX:+PatchALot"); + TestFramework.runWithScenarios(s0, s1, s2, s3); + } + + // Test case 1: + // The inline type field class has been loaded, but the holder class has not been loaded. + // + // aload_0 + // getfield MyValue1Holder.v:QMyValue1; + // ^ not loaded ^ already loaded + // + // MyValue1 has already been loaded, because it's in the InlineType attribute of + // TestUnloadedInlineTypeField, due to TestUnloadedInlineTypeField.test1_precondition(). + static final primitive class MyValue1 { + final int foo; + + MyValue1() { + foo = MyConstants.rI; + } + } + + static class MyValue1Holder { + MyValue1 v; + + public MyValue1Holder() { + v = new MyValue1(); + } + } + + static MyValue1 test1_precondition() { + return new MyValue1(); + } + + @Test + public int test1(Object holder) { + if (holder != null) { + // Don't use MyValue1Holder in the signature, it might trigger class loading + return ((MyValue1Holder)holder).v.foo; + } else { + return 0; + } + } + + @Run(test = "test1") + public void test1_verifier(TestInfo info) { + if (info.isWarmUp() && info.isC1Test()) { + test1(null); + } else { + MyValue1Holder holder = new MyValue1Holder(); + Asserts.assertEQ(test1(holder), MyConstants.rI); + } + } +} From ff4b2acb5a3801b07a928afe2c9e32a49a25856e Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 4 Mar 2021 16:29:42 +0100 Subject: [PATCH 036/131] Add some examples --- .../testframework/examples/CheckExample.java | 129 ++++++++++++++++++ .../testframework/examples/RunExample.java | 121 ++++++++++++++++ .../SimpleExample.java} | 6 +- .../testframework/examples/TestExample.java | 79 +++++++++++ 4 files changed, 332 insertions(+), 3 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/examples/CheckExample.java create mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/examples/RunExample.java rename test/hotspot/jtreg/compiler/valhalla/testframework/{TestSimpleExample.java => examples/SimpleExample.java} (91%) create mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/examples/TestExample.java diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/examples/CheckExample.java b/test/hotspot/jtreg/compiler/valhalla/testframework/examples/CheckExample.java new file mode 100644 index 00000000000..56c56a3aa6e --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/examples/CheckExample.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2021, 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. + */ + +/* + * @test + * @summary Example test to use the new test framework. + * @library /test/lib + * @run driver compiler.valhalla.testframework.examples.CheckExample + */ + +package compiler.valhalla.testframework.examples; + +import jdk.test.lib.hotspot.ir_framework.*; + +public class CheckExample { + + public static void main(String[] args) { + TestFramework.run(); // equivalent to TestFramework.run(TestSimpleTest.class) + } + + /* + * If there is no warm up specified the Test Framework will do the following: + * - Invoke @Test method TestFrameworkExecution.WARMUP_ITERATIONS many times. + * - By default, after each invocation, the @Check method of the @Test method is invoked. This can be disabled by + * using CheckAt.COMPILED. + * - After the warmup, the @Test method. + * - Invoke @Test method once again and then always the @Check method once. + */ + + /* + * Configurable things for checked tests: + * - At @Test method: + * - @Warmup: Change warm-up iterations of test (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS) + * - @Arguments: If a @Test method specifies arguments, you need to provide arguments by using @Arguments such + * that the framework knows how to call the method. If you need more complex values, use @Run. + * - @IR: Arbitrary number of @IR rules. + * - At @Check method: + * - when: When should the @Check method be invoked. + * - No @IR annotations. + */ + + @Test + @Arguments(Argument.DEFAULT) // As with normal tests, you need to tell the framework what the argument is. + @Warmup(100) // As with normal tests, you can specify the warmup iterations. + public int test(int x) { + return 42; + } + + // Check method for test(). Invoked directly after test() by the Test Framework. + @Check(test = "test") // Specify the @Test method for which this method is a check. + public void basicCheck() { + // Do some checks after an invocation. + } + + @Test + public int test2() { + return 42; + } + + // This version of @Check passes the return value from test2() as an argument. + // The return type and the parameter type must match. + @Check(test = "test2") + public void checkWithReturn(int returnValue) { + // Do some checks after an invocation. + if (returnValue != 42) { + throw new RuntimeException("Must match"); + } + } + + @Test + public int test3() { + return 42; + } + + // This version of @Check passes a TestInfo object to the check which contains some additional information about the test. + @Check(test = "test3") + public void checkWithTestInfo(TestInfo info) { + // Do some checks after an invocation. Additional queries with TestInfo. + } + + @Test + public int test4() { + return 42; + } + + // This version of @Check passes a TestInfo object to the check which contains some additional information about the test + // and additionally the return value. The order of the arguments is important. The return value must come first and then + // the TestInfo parameter. Any other combination of different arguments are forbidden to specify for @Check methods. + @Check(test = "test4") + public void checkWithReturnAndTestInfo(int returnValue, TestInfo info) { + // Do some checks after an invocation. Additional queries with TestInfo. + if (returnValue != 42) { + throw new RuntimeException("Must match"); + } + } + + + @Test + public int test5() { + return 42; + } + + // Check method for test5() is only invoked once warmup is finished and test() has been compiled by the Test Framework. + @Check(test = "test5", when = CheckAt.COMPILED) // Specify the @Test method for which this method is a check. + public void checkAfterCompiled() { + // Do some checks after compilation. + } + +} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/examples/RunExample.java b/test/hotspot/jtreg/compiler/valhalla/testframework/examples/RunExample.java new file mode 100644 index 00000000000..ec6b2859de9 --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/examples/RunExample.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021, 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. + */ + +/* + * @test + * @summary Example test to use the new test framework. + * @library /test/lib + * @run driver compiler.valhalla.testframework.examples.RunExample + */ + +package compiler.valhalla.testframework.examples; + +import jdk.test.lib.hotspot.ir_framework.*; + +public class RunExample { + + public static void main(String[] args) { + TestFramework.run(); // equivalent to TestFramework.run(TestSimpleTest.class) + } + + /* + * If there is no warm up specified the Test Framework will do the following: + * - Invoke @Run method TestFrameworkExecution.WARMUP_ITERATIONS many times. Note that the @Run method is responsible + * to invoke the @Test method. This is not done by the framework. The @Run method can do any arbitrary argument setup + * and return value verification. + * - After the warmup, the @Test method is compiled. + * - Invoke @Run method once again. + */ + + /* + * Configurable things for custom run tests: + * - At @Test method: + * - @IR: Arbitrary number of @IR rules. + * - No @Warmup, this must be set at @Run method. + * - No @Arguments, these are set by @Run method. + * - At @Run method: + * - @Warmup: Change warm-up iterations of @Run method (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS) + * - mode: Choose between normal invocation as described above or STANDALONE. STANDALONE only invokes the @Run + * method once without warmup or a compilation by the Test Framework. + * - No @IR annotations + */ + + @Test + public int test(int x) { + return x; + } + + // Run method for test(). Invoked directly by Test Framework instead of test(). + // Can do anything you like. It's also possible to skip or do multiple invocations of test() + @Run(test = "test") // Specify the @Test method for which this method is a runner. + public void basicRun() { + int returnValue = test(34); + if (returnValue != 34) { + throw new RuntimeException("Must match"); + } + } + + @Test + public int test2() { + return 42; + } + + // This version of @Run passes the TestInfo object as an argument. No other argument combinations are allowed. + @Run(test = "test2") + public void runWithTestInfo(TestInfo info) { + int returnValue = test(34); + if (returnValue != 34) { + throw new RuntimeException("Must match"); + } + } + + @Test + public int test3() { + return 42; + } + + // This version of @Run uses a user defined @Warmup. + @Run(test = "test3") + @Warmup(100) + public void runWithWarmUp() { + int returnValue = test(34); + if (returnValue != 34) { + throw new RuntimeException("Must match"); + } + } + + @Test + public int test4() { + return 42; + } + + // This version of @Run is only invoked once by the Test Framework. There is no warm up and no compilation done + // by the Test Framework + @Run(test = "test4", mode = RunMode.STANDALONE) + public void runOnlyOnce() { + int returnValue = test(34); + if (returnValue != 34) { + throw new RuntimeException("Must match"); + } + } +} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java b/test/hotspot/jtreg/compiler/valhalla/testframework/examples/SimpleExample.java similarity index 91% rename from test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java rename to test/hotspot/jtreg/compiler/valhalla/testframework/examples/SimpleExample.java index f4fffc7d260..c3fb0263da4 100644 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/TestSimpleExample.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/examples/SimpleExample.java @@ -25,14 +25,14 @@ * @test * @summary Example test to use the new test framework. * @library /test/lib - * @run driver compiler.valhalla.testframework.TestSimpleExample + * @run driver compiler.valhalla.testframework.examples.TestSimpleExample */ -package compiler.valhalla.testframework; +package compiler.valhalla.testframework.examples; import jdk.test.lib.hotspot.ir_framework.*; -public class TestSimpleExample { +public class SimpleExample { int iFld; diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/examples/TestExample.java b/test/hotspot/jtreg/compiler/valhalla/testframework/examples/TestExample.java new file mode 100644 index 00000000000..36bac2e5893 --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/examples/TestExample.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2021, 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. + */ + +/* + * @test + * @summary Example test to use the new test framework. + * @library /test/lib + * @run driver compiler.valhalla.testframework.examples.TestExample + */ + +package compiler.valhalla.testframework.examples; + +import jdk.test.lib.hotspot.ir_framework.*; + +public class TestExample { + + int iFld; + + public static void main(String[] args) { + TestFramework.run(); // equivalent to TestFramework.run(TestSimpleTest.class) + } + + /* + * If there is no warm up specified the Test Framework will do the following: + * - Invoke @Test method TestFrameworkExecution.WARMUP_ITERATIONS many times. + * - Then do compilation of @Test method. + * - Invoke @Test method once again + */ + + /* + * Configurable things for simple tests (no @Run or @Check) at @Test method: + * - @Warmup: Change warm-up iterations of test (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS) + * - @Arguments: If a @Test method specifies arguments, you need to provide arguments by using @Arguments such + * that the framework knows how to call the method. If you need more complex values, use @Run. + * - @IR: Arbitrary number of @IR rules. + */ + + // Test without arguments. + @Test + public void mostBasicTest() { + iFld = 42; + } + + // Test with arguments. Use Argument class to choose a value. + // Object arguments need to have an associated default constructor in its class. + @Test + @Arguments({Argument.DEFAULT, Argument.MAX}) + public void basicTestWithArguments(int x, long y) { + iFld = x; + } + + // @Warmup needs to be positive or zero. In case of zero, the method is directly compiled (simulated -Xcomp). + @Test + @Arguments({Argument.DEFAULT, Argument.MAX}) + @Warmup(100) + public void basicTestWithDifferentWarmup(int x, long y) { + iFld = x; + } +} From a159794400e73b65d844d1c4c496eb422669b971 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 5 Mar 2021 15:46:49 +0100 Subject: [PATCH 037/131] Change VM nesting: driver VM first calls flag VM, parse flags from its sdtout, then calls test VM, improve error reporting for IRMatcher format fails, improve argument printing --- .../testframework/examples/SimpleExample.java | 2 +- test/lib/jdk/test/lib/Utils.java | 17 --- .../CheckedTestFrameworkException.java | 3 + .../ir_framework/IREncodingPrinter.java | 6 + .../lib/hotspot/ir_framework/IRMatcher.java | 49 ++++--- .../ir_framework/ParsedComparator.java | 78 +++++------ .../hotspot/ir_framework/TestFramework.java | 131 +++++++++++++++--- .../ir_framework/TestFrameworkExecution.java | 24 +++- ...er.java => TestFrameworkPrepareFlags.java} | 68 ++------- .../ir_framework/tests/TestControls.java | 1 + .../tests/TestWithHelperClasses.java | 3 + 11 files changed, 234 insertions(+), 148 deletions(-) rename test/lib/jdk/test/lib/hotspot/ir_framework/{TestFrameworkRunner.java => TestFrameworkPrepareFlags.java} (70%) diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/examples/SimpleExample.java b/test/hotspot/jtreg/compiler/valhalla/testframework/examples/SimpleExample.java index c3fb0263da4..446c38f80f3 100644 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/examples/SimpleExample.java +++ b/test/hotspot/jtreg/compiler/valhalla/testframework/examples/SimpleExample.java @@ -25,7 +25,7 @@ * @test * @summary Example test to use the new test framework. * @library /test/lib - * @run driver compiler.valhalla.testframework.examples.TestSimpleExample + * @run driver compiler.valhalla.testframework.examples.SimpleExample */ package compiler.valhalla.testframework.examples; diff --git a/test/lib/jdk/test/lib/Utils.java b/test/lib/jdk/test/lib/Utils.java index 2ad27fbf90f..be91030ebdb 100644 --- a/test/lib/jdk/test/lib/Utils.java +++ b/test/lib/jdk/test/lib/Utils.java @@ -214,23 +214,6 @@ public static String[] getTestJavaOpts() { return opts.toArray(new String[0]); } - /** - * Returns the default JTReg arguments as property flags for a jvm running a test. - * This is the combination of JTReg arguments test.vm.opts with a "-Dtest.vm.opts=" - * and test.java.opts with a "-Dtest.java.opts=" prefix. - * @return A list of prefixed options, or an empty list if no options. - */ - public static List getTestJavaOptsAsPropertyFlags() { - List opts = new ArrayList<>(); - if (!VM_OPTIONS.isEmpty()) { - opts.add("-Dtest.vm.opts=" + VM_OPTIONS); - } - if (!JAVA_OPTIONS.isEmpty()) { - opts.add("-Dtest.java.opts=" + JAVA_OPTIONS); - } - return opts; - } - /** * Combines given arguments with default JTReg arguments for a jvm running a test. * This is the combination of JTReg arguments test.vm.opts and test.java.opts diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java index 5f0174e2a26..596e95bab08 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java @@ -25,4 +25,7 @@ // Checked exceptions in the framework to propagate error handling. class CheckedTestFrameworkException extends Exception { + CheckedTestFrameworkException(String msg) { + super(msg); + } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java index 278e94f0fc1..e71d2ae0cad 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java @@ -227,6 +227,9 @@ private boolean checkLongFlag(String flag, String value, Long actualFlagValue) { } catch (CheckedTestFrameworkException e) { TestFormat.failNoThrow("Invalid comparator in \"" + value + "\" for integer based flag " + flag + failAt()); return false; + } catch (IndexOutOfBoundsException e) { + TestFormat.failNoThrow("Provided empty value for integer based flag " + flag + failAt()); + return false; } try { longValue = Long.parseLong(parsedComparator.getStrippedString()); @@ -251,6 +254,9 @@ private boolean checkDoubleFlag(String flag, String value, Double actualFlagValu } catch (CheckedTestFrameworkException e) { TestFormat.failNoThrow("Invalid comparator in \"" + value + "\" for floating point based flag " + flag + failAt()); return false; + } catch (IndexOutOfBoundsException e) { + TestFormat.failNoThrow("Provided empty value for floating point based flag " + flag + failAt()); + return false; } try { doubleValue = Double.parseDouble(parsedComparator.getStrippedString()); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java index a3ab8e90aa6..8fa9ae6f7c7 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java @@ -34,6 +34,9 @@ class IRMatcher { private final Map compilations; private final Class testClass; private final Map> fails; + private Method method; // Current method to which rules are applied + private IR irAnno; // Current IR annotation that is processed. + private int irRuleIndex; // Current IR rule index; public IRMatcher(String output, Class testClass) { this.irRulesMap = new HashMap<>(); @@ -108,6 +111,7 @@ private void splitCompilations(String output, Class testClass) { public void applyRules() { fails.clear(); for (Method m : testClass.getDeclaredMethods()) { + method = m; 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. @@ -117,7 +121,7 @@ public void applyRules() { TestFramework.check(ids[ids.length - 1] < irAnnos.length, "Invalid IR rule index found in validIrRulesMap for " + m); if (ids[0] != IREncodingPrinter.NO_RULE_APPLIED) { // If -1, than there was no matching IR rule for the given conditions. - applyRuleToMethod(m, irAnnos, ids); + applyRuleToMethod(irAnnos, ids); } } } @@ -125,6 +129,7 @@ public void applyRules() { } private void reportFailuresIfAny() { + TestFormat.reportIfAnyFailures(); if (!fails.isEmpty()) { StringBuilder builder = new StringBuilder(); int failures = 0; @@ -143,35 +148,40 @@ private void reportFailuresIfAny() { } } - private void applyRuleToMethod(Method m, IR[] irAnnos, Integer[] ids) { - String testOutput = compilations.get(m.getName()); + private void applyRuleToMethod(IR[] irAnnos, Integer[] ids) { + String testOutput = compilations.get(method.getName()); if (TestFramework.VERBOSE) { System.out.println(testOutput); } for (Integer id : ids) { - IR irAnno = irAnnos[id]; + irAnno = irAnnos[id]; + irRuleIndex = id; StringBuilder failMsg = new StringBuilder(); - applyFailOn(testOutput, failMsg, irAnno); - applyCounts(m, testOutput, failMsg, irAnno); + applyFailOn(testOutput, failMsg); + try { + applyCounts(testOutput, failMsg); + } catch (TestFormatException e) { + // Logged. Continue to check other rules. + } if (!failMsg.isEmpty()) { failMsg.insert(0, "@IR rule " + (id + 1) + ": \"" + irAnno + "\"\n"); - fails.computeIfAbsent(m, k -> new ArrayList<>()).add(failMsg.toString()); + fails.computeIfAbsent(method, k -> new ArrayList<>()).add(failMsg.toString()); } } } - private void applyFailOn(String testOutput, StringBuilder failMsg, IR irAnno) { + private void applyFailOn(String testOutput, StringBuilder failMsg) { if (irAnno.failOn().length != 0) { String failOnRegex = String.join("|", IRNode.mergeNodes(irAnno.failOn())); Pattern pattern = Pattern.compile(failOnRegex); Matcher matcher = pattern.matcher(testOutput); if (matcher.find()) { - addFailOnFails(irAnno, failMsg, testOutput); + addFailOnFails(failMsg, testOutput); } } } - private void addFailOnFails(IR irAnno, StringBuilder failMsg, String testOutput) { + private void addFailOnFails(StringBuilder failMsg, String testOutput) { List failOnNodes = IRNode.mergeNodes(irAnno.failOn()); Pattern pattern; Matcher matcher; @@ -191,14 +201,14 @@ private void addFailOnFails(IR irAnno, StringBuilder failMsg, String testOutput) } } - private void applyCounts(Method m, String testOutput, StringBuilder failMsg, IR irAnno) { + private void applyCounts(String testOutput, StringBuilder failMsg) { if (irAnno.counts().length != 0) { boolean hasFails = false; int countsId = 1; final List nodesWithCount = IRNode.mergeNodes(irAnno.counts()); for (int i = 0; i < nodesWithCount.size(); i += 2) { String node = nodesWithCount.get(i); - TestFormat.check(i + 1 < nodesWithCount.size(), "Missing count for IR node \"" + node + "\" at " + m); + TestFormat.check(i + 1 < nodesWithCount.size(), "Missing count" + getPostfixErrorMsg(node)); String countString = nodesWithCount.get(i + 1); long expectedCount; ParsedComparator parsedComparator; @@ -206,13 +216,16 @@ private void applyCounts(Method m, String testOutput, StringBuilder failMsg, IR parsedComparator = ParsedComparator.parseComparator(countString); expectedCount = Long.parseLong(parsedComparator.getStrippedString()); } catch (NumberFormatException e) { - TestFormat.fail("Provided invalid count \"" + countString + "\" for IR node \"" + node + "\" at " + m); + TestFormat.fail("Provided invalid count \"" + countString + "\"" + getPostfixErrorMsg(node)); + return; + } catch (CheckedTestFrameworkException e) { + TestFormat.fail("Invalid comparator \"" + e.getMessage() + "\" in \"" + countString + "\" for count" + getPostfixErrorMsg(node)); return; - } catch (Exception e) { - TestFormat.fail("Invalid comparator in \"" + countString + "\" for count of node " + node + ": " + e.getCause()); + } catch (IndexOutOfBoundsException e) { + TestFormat.fail("Provided empty value" + getPostfixErrorMsg(node)); return; } - TestFormat.check(expectedCount >= 0,"Provided invalid negative count \"" + countString + "\" for IR node \"" + node + "\" at " + m); + TestFormat.check(expectedCount >= 0,"Provided invalid negative count \"" + countString + "\"" + getPostfixErrorMsg(node)); Pattern pattern = Pattern.compile(node); Matcher matcher = pattern.matcher(testOutput); @@ -229,6 +242,10 @@ private void applyCounts(Method m, String testOutput, StringBuilder failMsg, IR } } + private String getPostfixErrorMsg(String node) { + return " for IR rule " + irRuleIndex + ", node \"" + node + "\" at " + method; + } + private void addCountsFail(StringBuilder failMsg, String node, Matcher matcher, long expectedCount, long actualCount, int countsId) { matcher.reset(); failMsg.append(" Regex ").append(countsId).append(") ").append(node).append("\n"); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java index 738f3e57c41..42e0135b020 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java @@ -52,49 +52,45 @@ public static > ParsedComparator parseComparator(Stri BiPredicate comparison; value = value.trim(); String comparator = ""; - try { - switch (value.charAt(0)) { - case '<': - if (value.charAt(1) == '=') { - comparator = "<="; - comparison = (x, y) -> x.compareTo(y) <= 0; - value = value.substring(2).trim(); - } else { - comparator = "<"; - comparison = (x, y) -> x.compareTo(y) < 0; - value = value.substring(1).trim(); - } - break; - case '>': - if (value.charAt(1) == '=') { - comparator = ">="; - comparison = (x, y) -> x.compareTo(y) >= 0; - value = value.substring(2).trim(); - } else { - comparator = ">"; - comparison = (x, y) -> x.compareTo(y) > 0; - value = value.substring(1).trim(); - } - break; - case '!': - if (value.charAt(1) != '=') { - throw new CheckedTestFrameworkException(); - } - comparator = "!="; - comparison = (x, y) -> x.compareTo(y) != 0; + switch (value.charAt(0)) { + case '<': + if (value.charAt(1) == '=') { + comparator = "<="; + comparison = (x, y) -> x.compareTo(y) <= 0; value = value.substring(2).trim(); - break; - case '=': // Allowed syntax, equivalent to not using any symbol. - comparator = "="; + } else { + comparator = "<"; + comparison = (x, y) -> x.compareTo(y) < 0; value = value.substring(1).trim(); - // Fall through - default: - comparison = (x, y) -> x.compareTo(y) == 0; - value = value.trim(); - break; - } - } catch (IndexOutOfBoundsException e) { - throw new CheckedTestFrameworkException(); + } + break; + case '>': + if (value.charAt(1) == '=') { + comparator = ">="; + comparison = (x, y) -> x.compareTo(y) >= 0; + value = value.substring(2).trim(); + } else { + comparator = ">"; + comparison = (x, y) -> x.compareTo(y) > 0; + value = value.substring(1).trim(); + } + break; + case '!': + if (value.charAt(1) != '=') { + throw new CheckedTestFrameworkException(value.substring(0, 1)); + } + comparator = "!="; + comparison = (x, y) -> x.compareTo(y) != 0; + value = value.substring(2).trim(); + break; + case '=': // Allowed syntax, equivalent to not using any symbol. + comparator = "="; + value = value.substring(1).trim(); + // Fall through + default: + comparison = (x, y) -> x.compareTo(y) == 0; + value = value.trim(); + break; } return new ParsedComparator<>(value, comparison, comparator); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index d806a2c191e..f3f077a2e76 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -24,10 +24,9 @@ package jdk.test.lib.hotspot.ir_framework; import jdk.test.lib.Utils; -import jdk.test.lib.util.ClassFileInstaller; -import jdk.test.lib.management.InputArguments; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.util.ClassFileInstaller; import sun.hotspot.WhiteBox; import java.io.PrintWriter; @@ -49,6 +48,12 @@ public class TestFramework { public static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); + static final String TEST_VM_FLAGS_START = "##### TestFrameworkPrepareFlags - used by TestFramework #####"; + static final String TEST_VM_FLAGS_DELIMITER = " "; + static final String TEST_VM_FLAGS_END = "----- END -----"; + private static boolean VERIFY_IR = true; // Should we perform IR matching? + private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); + private List> helperClasses = null; private List scenarios = null; private final Class testClass; @@ -240,6 +245,11 @@ private void startWithScenarios() { } } + /** + * Execute a separate "flag" VM with White Box access to determine all test VM flags. The flag VM emits an encoding + * of all required flags for the test VM to the standard output. Once the flag VM exits, this driver VM parses the + * test VM flags, which also determine if IR matching should be done, and then starts the test VM to execute all tests. + */ private void start(Scenario scenario) { if (scenario != null && !scenario.isEnabled()) { System.out.println("Disabled scenario #" + scenario.getIndex() + "! This scenario is not present in set flag -DScenarios " + @@ -247,42 +257,131 @@ private void start(Scenario scenario) { return; } - ArrayList cmds = new ArrayList<>(Utils.getTestJavaOptsAsPropertyFlags()); + String flagVMOutput = runFlagVM(); + List testVMFlags = getTestVMFlags(flagVMOutput); + runTestVM(scenario, testVMFlags); + } + + private String runFlagVM() { + ArrayList cmds = prepareFlagVMFlags(); + OutputAnalyzer oa; + try { + // Run "flag" VM with White Box access to determine the test VM flags and if IR verification should be done. + oa = ProcessTools.executeTestJvm(cmds); + } catch (Exception e) { + throw new TestRunException("Failed to execute TestFramework flag VM", e); + } + checkFlagVMExitCode(oa); + return oa.getOutput(); + } + + /** + * The "flag" VM needs White Box access to prepare all test VM flags. It emits these as encoding to the standard output. + * This driver VM then parses the flags and adds them to the test VM. + */ + private ArrayList prepareFlagVMFlags() { + ArrayList cmds = new ArrayList<>(); cmds.add("-Dtest.jdk=" + Utils.TEST_JDK); cmds.add("-cp"); cmds.add(Utils.TEST_CLASS_PATH); cmds.add("-Xbootclasspath/a:."); cmds.add("-XX:+UnlockDiagnosticVMOptions"); cmds.add("-XX:+WhiteBoxAPI"); - if (scenario != null) { - System.out.println("Running Scenario #" + scenario.getIndex() + " - [" + String.join(",", scenario.getFlags()) + "]"); - // Propagate scenario flags to TestFramework runner VM but do not apply them yet. - // These should only be applied to the test VM. - cmds.add("-DScenarioFlags=" + String.join(" ", scenario.getFlags())); - } - cmds.add(TestFrameworkRunner.class.getCanonicalName()); + cmds.add(TestFrameworkPrepareFlags.class.getCanonicalName()); cmds.add(testClass.getCanonicalName()); - if (helperClasses != null) { - helperClasses.forEach(c -> cmds.add(c.getCanonicalName())); + return cmds; + } + + private void checkFlagVMExitCode(OutputAnalyzer oa) { + String flagVMOutput = oa.getOutput(); + final int exitCode = oa.getExitValue(); + if (VERBOSE && exitCode == 0) { + System.out.println("--- OUTPUT TestFramework flag VM ---"); + System.out.println(flagVMOutput); + } + + if (exitCode != 0) { + System.out.println("--- OUTPUT TestFramework flag VM ---"); + System.err.println(flagVMOutput); + throw new RuntimeException("\nTestFramework flag VM exited with " + exitCode); } + } + /** + * Parse the test VM flags as prepared by the flag VM. Additionally check the property flag DPrintValidIRRules to determine + * if IR matching should be done or not. + */ + private List getTestVMFlags(String flagVMOutput) { + String patternString = "(?<=" + TestFramework.TEST_VM_FLAGS_START + "\\R)" + + "(.*DPrintValidIRRules=(true|false).*)\\R" + "(?=" + IREncodingPrinter.END + ")"; + Pattern pattern = Pattern.compile(patternString); + Matcher matcher = pattern.matcher(flagVMOutput); + if (!matcher.find()) { + throw new TestFrameworkException("Invalid flag encoding emitted by flag VM"); + } + VERIFY_IR = Boolean.parseBoolean(matcher.group(2)); + return new ArrayList<>(Arrays.asList(matcher.group(1).split(TEST_VM_FLAGS_DELIMITER))); + } + + private void runTestVM(Scenario scenario, List testVMflags) { + List cmds = prepareTestVMFlags(scenario, testVMflags); OutputAnalyzer oa; try { - // Propagate scenario test and VM flags to TestFramework runner VM but do not apply them yet. - // These should only be applied to the test VM. + // Calls 'main' of TestFrameworkExecution to run all specified tests with commands 'cmds'. + // Use executeProcess instead of executeTestJvm as we have already added the JTreg VM and + // Java options in prepareTestVMFlags(). oa = ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder(cmds)); } catch (Exception e) { - throw new TestRunException("Failed to execute TestFramework runner VM", e); + throw new TestFrameworkException("Error while executing Test VM", e); } lastVMOutput = oa.getOutput(); + checkTestVMExitCode(oa); if (scenario != null) { scenario.setVMOutput(lastVMOutput); } + if (VERIFY_IR) { + IRMatcher irMatcher = new IRMatcher(lastVMOutput, testClass); + irMatcher.applyRules(); + } + } + + private List prepareTestVMFlags(Scenario scenario, List testVMflags) { + ArrayList cmds = new ArrayList<>(); + + // Need White Box access in test VM. + cmds.add("-Xbootclasspath/a:."); + cmds.add("-XX:+UnlockDiagnosticVMOptions"); + cmds.add("-XX:+WhiteBoxAPI"); + + String[] jtregVMFlags = Utils.getTestJavaOpts(); + if (!PREFER_COMMAND_LINE_FLAGS) { + cmds.addAll(Arrays.asList(jtregVMFlags)); + } + if (scenario != null) { + System.out.println("Running Scenario #" + scenario.getIndex() + " - [" + String.join(",", scenario.getFlags()) + "]"); + cmds.addAll(scenario.getFlags()); + } + cmds.addAll(testVMflags); + + if (PREFER_COMMAND_LINE_FLAGS) { + // Prefer flags set via the command line over the ones set by scenarios. + cmds.addAll(Arrays.asList(jtregVMFlags)); + } + + cmds.add(TestFrameworkExecution.class.getCanonicalName()); + cmds.add(testClass.getCanonicalName()); + if (helperClasses != null) { + helperClasses.forEach(c -> cmds.add(c.getCanonicalName())); + } + return cmds; + } + + private static void checkTestVMExitCode(OutputAnalyzer oa) { final int exitCode = oa.getExitValue(); if (VERBOSE && exitCode == 0) { System.out.println("--- OUTPUT TestFramework runner VM ---"); - System.out.println(lastVMOutput); + System.out.println(oa.getOutput()); } if (exitCode != 0) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index ee5979a3610..2585c3bce0e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -707,7 +707,7 @@ public Method getAttachedMethod() { public void printFixedRandomArguments() { if (hasArguments()) { boolean hasRandomArgs = false; - StringBuilder builder = new StringBuilder("Random Arguments: "); + StringBuilder builder = new StringBuilder("Fixed random arguments for method ").append(testMethod).append(": "); for (int i = 0; i < arguments.length; i++) { ArgumentValue argument = arguments[i]; if (argument.isFixedRandom()) { @@ -723,6 +723,19 @@ public void printFixedRandomArguments() { } } + public String getArgumentsString() { + if (hasArguments()) { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < arguments.length; i++) { + builder.append("arg ").append(i).append(": ").append(arguments[i].getArgument()).append(", "); + } + builder.setLength(builder.length() - 2); + return builder.toString(); + } else { + return ""; + } + } + public Object invoke(Object obj, Object... args) { try { return testMethod.invoke(obj, args); @@ -818,7 +831,8 @@ private Object invokeTestMethod() { return testMethod.invoke(invocationTarget); } } catch (Exception e) { - throw new TestRunException("There was an error while invoking @Test method " + testMethod, e); + throw new TestRunException("There was an error while invoking @Test method " + testMethod + + ". Used arguments: " + test.getArgumentsString(), e); } } @@ -873,8 +887,10 @@ private void compileTest() { do { if (!WHITE_BOX.isMethodQueuedForCompilation(testMethod)) { - if (elapsed > 0 && TestFrameworkExecution.VERBOSE) { - System.out.println(testMethod + " is not in queue anymore due to compiling it simultaneously on a different level. Enqueue again."); + if (elapsed > 0) { + if (TestFrameworkExecution.VERBOSE) { + System.out.println(testMethod + " is not in queue anymore due to compiling it simultaneously on a different level. Enqueue again."); + } enqueueMethodForCompilation(); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkRunner.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java similarity index 70% rename from test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkRunner.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java index a563dc9a81e..b67dd378a82 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkRunner.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java @@ -24,15 +24,12 @@ package jdk.test.lib.hotspot.ir_framework; import jdk.test.lib.Platform; -import jdk.test.lib.management.InputArguments; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.process.ProcessTools; import sun.hotspot.WhiteBox; import java.util.*; -class TestFrameworkRunner { +class TestFrameworkPrepareFlags { private static final WhiteBox WHITE_BOX; static { @@ -58,8 +55,6 @@ class TestFrameworkRunner { private static boolean VERIFY_IR = REQUESTED_VERIFY_IR && USE_COMPILER && !XCOMP && !STRESS_CC && !TEST_C1 && COMPILE_COMMANDS && Platform.isDebugBuild() && !Platform.isInt(); private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false")) && Platform.isDebugBuild(); - private static final String SCENARIO_FLAGS = System.getProperty("ScenarioFlags", ""); - private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); private static String[] getDefaultFlags() { return new String[] {"-XX:-BackgroundCompilation"}; @@ -88,47 +83,20 @@ public static void main(String[] args) { } catch (Exception e) { throw new TestRunException("Could not find test class " + testClassName, e); } - runTestVM(testClass, args); + emitTestVMFlags(prepareTestVmFlags(testClass)); } - private static void runTestVM(Class testClass, String[] args) { - ArrayList cmds = prepareTestVmFlags(testClass, args); - OutputAnalyzer oa; - try { - // Calls 'main' of TestFrameworkExecution to run all specified tests with commands 'cmds'. - // It also prepends all -Dtest* properties as flags for the test VM. - oa = ProcessTools.executeTestJvm(cmds); - } catch (Exception e) { - throw new TestFrameworkException("Error while executing Test VM", e); - } - String output = oa.getOutput(); - final int exitCode = oa.getExitValue(); - if (VERBOSE && exitCode == 0) { - System.out.println(" ----- OUTPUT Test VM-----"); - System.out.println(output); - - } - if (exitCode != 0) { - System.err.println(" ----- OUTPUT Test VM -----"); - System.err.println(output); - throw new RuntimeException("\nTestFramework runner VM exited with " + exitCode); - } - - if (VERIFY_IR) { - IRMatcher irMatcher = new IRMatcher(output, testClass); - irMatcher.applyRules(); - } + /** + * Emit test VM flags to standard output to parse them from the TestFramework "driver" VM again which adds them to the test VM. + */ + private static void emitTestVMFlags(ArrayList flags) { + String info = TestFramework.TEST_VM_FLAGS_START + "\n" + String.join(TestFramework.TEST_VM_FLAGS_DELIMITER, flags) + + "\n" + TestFramework.TEST_VM_FLAGS_END; + System.out.println(info); } - private static ArrayList prepareTestVmFlags(Class testClass, String[] args) { - String[] vmInputArguments = InputArguments.getVmInputArgs(); + private static ArrayList prepareTestVmFlags(Class testClass) { ArrayList cmds = new ArrayList<>(); - if (!PREFER_COMMAND_LINE_FLAGS) { - cmds.addAll(Arrays.asList(vmInputArguments)); - } - if (!SCENARIO_FLAGS.isEmpty()) { - cmds.addAll(Arrays.asList(SCENARIO_FLAGS.split("\\s+"))); - } setupIrVerificationFlags(testClass, cmds); if (VERIFY_VM) { @@ -140,18 +108,12 @@ private static ArrayList prepareTestVmFlags(Class testClass, String[] cmds.addAll(Arrays.asList(getCompileCommandFlags())); } - // TODO: Only for debugging - if (cmds.get(0).startsWith("-agentlib")) { - cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=n,server=y"); - } - - if (PREFER_COMMAND_LINE_FLAGS) { - // Prefer flags set via the command line over the ones set by scenarios. - cmds.addAll(Arrays.asList(vmInputArguments)); - } +// // TODO: Only for debugging +// if (cmds.get(0).startsWith("-agentlib")) { +// cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=n,server=y"); +// } - cmds.add(TestFrameworkExecution.class.getCanonicalName()); - cmds.addAll(Arrays.asList(args)); // add test class and helpers last + return cmds; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java index f4ae9137bd8..92a6b57d8c6 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java @@ -29,6 +29,7 @@ import java.lang.reflect.Method; +// Run with -Xbatch public class TestControls { static int[] executed = new int[15]; static boolean wasExecuted = false; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java index 5a2ba0ec053..4effe087ccd 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java @@ -36,9 +36,12 @@ public static void main(String[] args) { try { TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class); } catch (Exception e) { + Asserts.assertFalse(e.getMessage().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper1.foo() should have been C2 compiled")); Asserts.assertFalse(TestFramework.getLastVMOutput().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper1.foo() should have been C2 compiled")); Asserts.assertTrue(TestFramework.getLastVMOutput().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper2.foo() should have been C2 compiled")); + Asserts.assertTrue(e.getMessage().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper2.foo() should have been C2 compiled")); Asserts.assertFalse(TestFramework.getLastVMOutput().contains("Should not be executed")); + Asserts.assertFalse(e.getMessage().contains("Should not be executed")); return; } throw new RuntimeException("Did not catch exception"); From 7521523d153cf7df05072ea60d02d7fc02c3add4 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 5 Mar 2021 17:29:10 +0100 Subject: [PATCH 038/131] Add support for nested class with compile commands, add checks for nested classes and helper classes --- .../ir_framework/TestFrameworkExecution.java | 58 +++++++++++++------ .../ir_framework/tests/TestBadFormat.java | 24 +++++++- .../tests/TestWithHelperClasses.java | 48 ++++++++++++++- 3 files changed, 110 insertions(+), 20 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 2585c3bce0e..4a6e96cd234 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -171,6 +171,7 @@ private void start() { if (helperClasses != null) { for (Class helperClass : helperClasses) { // Process the helper classes and apply the explicit compile commands + checkHelperClass(helperClass); processExplicitCompileCommands(helperClass); } } @@ -178,7 +179,25 @@ private void start() { runTests(); } + private void checkHelperClass(Class clazz) { + checkTestAnnotationInnerClass(clazz, "helper"); + for (Class c : clazz.getDeclaredClasses()) { + checkTestAnnotationInnerClass(c, "nested (and helper)"); + } + } + + private void checkTestAnnotationInnerClass(Class c, String clazzType) { + Method[] methods = c.getDeclaredMethods(); + for (Method m : methods) { + TestFormat.checkNoThrow(getAnnotation(m, Test.class) == null, + "Cannot use @Test annotation in " + clazzType + " class: " + m); + } + } + private void parseTestClass() { + for (Class clazz : testClass.getDeclaredClasses()) { + checkTestAnnotationInnerClass(clazz, "inner"); + } addReplay(); processExplicitCompileCommands(testClass); setupTests(); @@ -216,27 +235,32 @@ private void addReplay() { private void processExplicitCompileCommands(Class clazz) { if (!XCOMP) { // Don't control compilations if -Xcomp is enabled. - Method[] methods = clazz.getDeclaredMethods(); - for (Method m : methods) { - try { - applyIndependentCompilationCommands(m); - - if (STRESS_CC) { - if (getAnnotation(m, Test.class) != null) { - excludeCompilationRandomly(m); + // Also apply compile commands to all inner classes of 'clazz'. + ArrayList> classes = new ArrayList<>(Arrays.asList(clazz.getDeclaredClasses())); + classes.add(clazz); + for (Class c : classes) { + Method[] methods = c.getDeclaredMethods(); + for (Method m : methods) { + try { + applyIndependentCompilationCommands(m); + + if (STRESS_CC) { + if (getAnnotation(m, Test.class) != null) { + excludeCompilationRandomly(m); + } } + } catch (TestFormatException e) { + // Failure logged. Continue and report later. } - } catch (TestFormatException e) { - // Failure logged. Continue and report later. } - } - // Only force compilation now because above annotations affect inlining - for (Method m : methods) { - try { - applyForceCompileCommand(m); - } catch (TestFormatException e) { - // Failure logged. Continue and report later. + // Only force compilation now because above annotations affect inlining + for (Method m : methods) { + try { + applyForceCompileCommand(m); + } catch (TestFormatException e) { + // Failure logged. Continue and report later. + } } } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java index d2379394c73..e561039b74a 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java @@ -49,6 +49,7 @@ public static void main(String[] args) throws NoSuchMethodException { expectTestFormatException(BadRunTests.class); expectTestFormatException(BadCheckTest.class); expectTestFormatException(BadIRAnnotations.class); + expectTestFormatException(BadInnerClassTest.class); } private static void expectTestFormatException(Class clazz) { @@ -78,6 +79,14 @@ private static void expectTestFormatException(Class clazz) { private static Violations getViolations(Class clazz) { Violations violations = new Violations(); + getViolationsOfClass(clazz, violations); + for (Class c : clazz.getDeclaredClasses()) { + getViolationsOfClass(c, violations); + } + return violations; + } + + private static void getViolationsOfClass(Class clazz, Violations violations) { for (Method m : clazz.getDeclaredMethods()) { NoFail noFail = m.getDeclaredAnnotation(NoFail.class); if (noFail == null) { @@ -92,7 +101,6 @@ private static Violations getViolations(Class clazz) { Asserts.assertEQ(m.getDeclaredAnnotation(FailCount.class), null); } } - return violations; } } @@ -789,6 +797,20 @@ public void wrongFlagValueDoubleFlag() {} public void anyValueForStringFlags() {} } +class BadInnerClassTest { + + class InnerClass { + @Test + public void noTestInInnerClass() {} + } + + + static class StaticInnerClass { + @Test + public void noTestInInnerClass() {} + } +} + class ClassNoDefaultConstructor { private ClassNoDefaultConstructor(int i) { } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java index 4effe087ccd..ec7144ff7be 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java @@ -32,6 +32,7 @@ public class TestWithHelperClasses { public static void main(String[] args) { + int exceptionsCaught = 0; TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class, Helper2.class); try { TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class); @@ -42,15 +43,48 @@ public static void main(String[] args) { Asserts.assertTrue(e.getMessage().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper2.foo() should have been C2 compiled")); Asserts.assertFalse(TestFramework.getLastVMOutput().contains("Should not be executed")); Asserts.assertFalse(e.getMessage().contains("Should not be executed")); - return; + exceptionsCaught++; + } + try { + TestFramework.runWithHelperClasses(BadHelperClasses.class, BadHelper.class); + } catch (Exception e) { + Asserts.assertTrue(e.getMessage().contains("Cannot use @Test annotation in helper class:")); + Asserts.assertTrue(e.getMessage().contains("noTestInHelper")); + exceptionsCaught++; + } + try { + TestFramework.runWithHelperClasses(BadHelperClasses.class, BadHelper.class); + } catch (Exception e) { + Asserts.assertTrue(e.getMessage().contains("Cannot use @Test annotation in helper class:")); + Asserts.assertTrue(e.getMessage().contains("noTestInHelper")); + exceptionsCaught++; + } + if (exceptionsCaught != 2) { + throw new RuntimeException("Did not catch " + exceptionsCaught + " exceptions!"); } - throw new RuntimeException("Did not catch exception"); } @Test public void test() throws NoSuchMethodException { TestFramework.assertCompiledByC2(Helper1.class.getMethod("foo")); TestFramework.assertCompiledByC2(Helper2.class.getMethod("foo")); + TestFramework.assertCompiledByC2(NestedHelper.class.getMethod("foo")); + TestFramework.assertCompiledByC2(StaticNestedHelper.class.getMethod("foo")); + } + + class NestedHelper { + @ForceCompile(CompLevel.C2) + public void foo() { + throw new RuntimeException("Should not be executed"); + } + } + + + static class StaticNestedHelper { + @ForceCompile(CompLevel.C2) + public void foo() { + throw new RuntimeException("Should not be executed"); + } } } @@ -69,3 +103,13 @@ public static void foo() { throw new RuntimeException("Should not be executed"); } } + +class BadHelperClasses { + @Test + public void test() {} +} + +class BadHelper { + @Test + public void noTestInHelper() {} +} From aeb9c6f7e237fe981b4ad56604acd1aae9ec01b7 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 8 Mar 2021 09:45:50 +0100 Subject: [PATCH 039/131] Fix reporting of seemingly wrong format violations due to previously detected format violations --- .../ir_framework/TestFrameworkExecution.java | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 4a6e96cd234..edb52291e94 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -482,47 +482,56 @@ private void setupCheckAndRunMethods() { } private void addCheckedTest(Method m, Check checkAnno, Run runAnno) { - TestFormat.check(runAnno == null, m + " has invalid @Run annotation while @Check annotation is present."); Method testMethod = testMethodMap.get(checkAnno.test()); - TestFormat.check(testMethod != null,"Did not find associated test method \"" + m.getDeclaringClass().getName() - + "." + checkAnno.test() + "\" for @Check at " + m); + DeclaredTest test = declaredTests.get(testMethod); + checkCheckedTest(m, checkAnno, runAnno, testMethod, test); + test.setAttachedMethod(m); + CheckedTest.Parameter parameter = getCheckedTestParameter(m, testMethod); + dontCompileMethod(m); + // Don't inline check methods + WHITE_BOX.testSetDontInlineMethod(m, true); + CheckedTest checkedTest = new CheckedTest(test, m, checkAnno, parameter); + allTests.put(testMethod, checkedTest); + } + + private void checkCheckedTest(Method m, Check checkAnno, Run runAnno, Method testMethod, DeclaredTest test) { + TestFormat.check(runAnno == null, m + " has invalid @Run annotation while @Check annotation is present."); + TestFormat.check(testMethod != null, "Did not find associated test method \"" + m.getDeclaringClass().getName() + + "." + checkAnno.test() + "\" for @Check at " + m); + TestFormat.check(test != null, "Missing @Test annotation for associated test method " + testMethod + " for @Check at " + m); + Method attachedMethod = test.getAttachedMethod(); + TestFormat.check(attachedMethod == null, + "Cannot use @Test " + testMethod + " for more than one @Run or one @Check method. Found: " + m + ", " + attachedMethod); + } + + private CheckedTest.Parameter getCheckedTestParameter(Method m, Method testMethod) { boolean firstParameterTestInfo = m.getParameterCount() > 0 && m.getParameterTypes()[0].equals(TestInfo.class); boolean secondParameterTestInfo = m.getParameterCount() > 1 && m.getParameterTypes()[1].equals(TestInfo.class); - CheckedTest.Parameter parameter = null; Class testReturnType = testMethod.getReturnType(); switch (m.getParameterCount()) { case 0 -> parameter = CheckedTest.Parameter.NONE; case 1 -> { - TestFormat.check(firstParameterTestInfo || m.getParameterTypes()[0] == testReturnType, - "Single-parameter version of @Check method " + m + " must match return type of @Test " + testMethod); + TestFormat.checkNoThrow(firstParameterTestInfo || m.getParameterTypes()[0] == testReturnType, + "Single-parameter version of @Check method " + m + " must match return type of @Test " + testMethod); parameter = firstParameterTestInfo ? CheckedTest.Parameter.TEST_INFO_ONLY : CheckedTest.Parameter.RETURN_ONLY; } case 2 -> { - TestFormat.check(m.getParameterTypes()[0] == testReturnType && secondParameterTestInfo, - "Two-parameter version of @Check method " + m + " must provide as first parameter the same" - + " return type as @Test method " + testMethod + " and as second parameter an object of " + TestInfo.class); + TestFormat.checkNoThrow(m.getParameterTypes()[0] == testReturnType && secondParameterTestInfo, + "Two-parameter version of @Check method " + m + " must provide as first parameter the same" + + " return type as @Test method " + testMethod + " and as second parameter an object of " + TestInfo.class); parameter = CheckedTest.Parameter.BOTH; } - default -> TestFormat.fail("@Check method " + m + " must provide either a none, single or two-parameter variant."); + default -> TestFormat.failNoThrow("@Check method " + m + " must provide either a none, single or two-parameter variant."); } - - DeclaredTest test = declaredTests.get(testMethod); - TestFormat.check(test != null, "Missing @Test annotation for associated test method " + testMethod + " for @Check at " + m); - Method attachedMethod = test.getAttachedMethod(); - TestFormat.check(attachedMethod == null, - "Cannot use @Test " + testMethod + " for more than one @Run or one @Check method. Found: " + m + ", " + attachedMethod); - dontCompileMethod(m); - // Don't inline check methods - WHITE_BOX.testSetDontInlineMethod(m, true); - CheckedTest checkedTest = new CheckedTest(test, m, checkAnno, parameter); - allTests.put(testMethod, checkedTest); + return parameter; } private void addCustomRunTest(Method m, Run runAnno) { Method testMethod = testMethodMap.get(runAnno.test()); DeclaredTest test = declaredTests.get(testMethod); checkCustomRunTest(m, runAnno, testMethod, test); + test.setAttachedMethod(m); dontCompileMethod(m); // Don't inline run methods WHITE_BOX.testSetDontInlineMethod(m, true); @@ -538,7 +547,7 @@ private void checkCustomRunTest(Method m, Run runAnno, Method testMethod, Declar TestFormat.check(attachedMethod == null, "Cannot use @Test " + testMethod + " for more than one @Run/@Check method. Found: " + m + ", " + attachedMethod); TestFormat.check(!test.hasArguments(), "Cannot use @Arguments at test method " + testMethod + " in combination with @Run method " + m); - TestFormat.check(m.getParameterCount() == 0 || (m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(TestInfo.class)), + TestFormat.checkNoThrow(m.getParameterCount() == 0 || (m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(TestInfo.class)), "@Run method " + m + " must specify either no parameter or exactly one of " + TestInfo.class); Warmup warmupAnno = getAnnotation(testMethod, Warmup.class); TestFormat.checkNoThrow(warmupAnno == null, @@ -964,7 +973,6 @@ public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecificati super(test); // Make sure we can also call non-public or public methods in package private classes checkMethod.setAccessible(true); - test.setAttachedMethod(checkMethod); this.checkMethod = checkMethod; this.checkAt = checkSpecification.when(); this.parameter = parameter; @@ -1003,7 +1011,6 @@ public CustomRunTest(DeclaredTest test, Method runMethod, Warmup warmUpAnno, Run super(test); // Make sure we can also call non-public or public methods in package private classes runMethod.setAccessible(true); - test.setAttachedMethod(runMethod); this.runMethod = runMethod; this.mode = runSpecification.mode(); this.warmupIterations = warmUpAnno != null ? warmUpAnno.value() : test.getWarmupIterations(); From 0a1c1e6e9f4ff783c992405dd4c9cc53fd299152 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 8 Mar 2021 10:25:11 +0100 Subject: [PATCH 040/131] Set up everything for Valhalla test conversions, set up helper classes for conversion, add some first working test conversions, move example tests to framework directory --- .../src/valhallatests/ValhallaIRNode.java | 41 -- .../ExampleTestNullableInlineTypes.java} | 75 +- .../ExampleUnloadedInlineTypeField.java} | 4 +- .../valhalla/inlinetypes/InlineTypes.java | 682 ++++++++++++++++++ .../inlinetypes/TestNullableInlineTypes.java | 4 +- .../TestUnloadedInlineTypeField.java | 8 +- .../GetfieldChains.jcod | 0 .../InlineTypeTest.java | 0 .../TestArrayAccessDeopt.java | 0 .../TestArrayCopyWithOops.java | 0 .../TestArrays.java | 0 .../TestBasicFunctionality.java | 0 .../TestBimorphicInlining.java | 0 .../TestBufferTearing.java | 0 .../TestC1.java | 0 .../TestC2CCalls.java | 0 .../TestCallingConvention.java | 0 .../TestCallingConventionC1.java | 0 .../TestDeadAllocationRemoval.java | 0 .../TestDeoptimizationWhenBuffering.java | 0 .../TestFlatArrayAliasesCardMark.java | 0 .../TestFlatArrayThreshold.java | 0 .../TestGenerated.java | 0 .../TestGetfieldChains.java | 0 .../TestIntrinsics.java | 0 .../TestIsSubstitutableReresolution.java | 0 .../TestJNICalls.java | 0 .../TestLWorld.java | 0 .../TestLWorldProfiling.java | 0 .../TestMethodHandles.java | 0 .../TestNativeClone.java | 0 .../TestNestmateAccess.java | 0 .../TestNewAcmp.java | 0 .../TestNullableArrays.java | 0 .../TestOnStackReplacement.java | 0 .../TestOptimizeKlassCmp.java | 0 .../TestStressReturnBuffering.java | 0 .../TestUnloadedInlineTypeArray.java | 0 .../TestUnresolvedDefault.java | 0 .../TestUnresolvedInlineClass.java | 0 .../TestWithfieldC1.java | 0 ...etUnresolvedInlineFieldWrongSignature.java | 0 .../libTestJNICalls.c | 0 .../testframework/DefaultScenarios.java | 71 -- .../valhalla/testframework/InlineHelpers.java | 4 - .../valhalla/testframework/MyAbstract.java | 5 - .../valhalla/testframework/MyConstants.java | 32 - .../valhalla/testframework/MyInterface.java | 29 - .../valhalla/testframework/MyValue1.java | 158 ---- .../valhalla/testframework/MyValue2.java | 135 ---- .../valhalla/testframework/MyValue3.java | 250 ------- .../valhalla/testframework/MyValue4.java | 73 -- .../valhalla/testframework/MyValueEmpty.java | 30 - .../testframework/NamedRectangle.java | 40 - .../valhalla/testframework/Point.java | 29 - .../valhalla/testframework/Rectangle.java | 29 - .../testframework/SimpleInlineType.java | 37 - .../ir_framework}/examples/CheckExample.java | 4 +- .../ir_framework}/examples/RunExample.java | 6 +- .../ir_framework}/examples/SimpleExample.java | 6 +- .../hotspot/ir_framework/examples/TEST.ROOT | 3 + .../ir_framework}/examples/TestExample.java | 6 +- .../tests/TestWithHelperClasses.java | 8 +- 63 files changed, 759 insertions(+), 1010 deletions(-) delete mode 100644 test/hotspot/jtreg/TestFramework/src/valhallatests/ValhallaIRNode.java rename test/hotspot/jtreg/compiler/valhalla/{testframework/TestNullableInlineTypes.java => inlinetypes/ExampleTestNullableInlineTypes.java} (55%) rename test/hotspot/jtreg/compiler/valhalla/{testframework/TestUnloadedInlineTypeField.java => inlinetypes/ExampleUnloadedInlineTypeField.java} (95%) create mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/GetfieldChains.jcod (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/InlineTypeTest.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestArrayAccessDeopt.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestArrayCopyWithOops.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestArrays.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestBasicFunctionality.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestBimorphicInlining.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestBufferTearing.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestC1.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestC2CCalls.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestCallingConvention.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestCallingConventionC1.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestDeadAllocationRemoval.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestDeoptimizationWhenBuffering.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestFlatArrayAliasesCardMark.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestFlatArrayThreshold.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestGenerated.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestGetfieldChains.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestIntrinsics.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestIsSubstitutableReresolution.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestJNICalls.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestLWorld.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestLWorldProfiling.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestMethodHandles.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestNativeClone.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestNestmateAccess.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestNewAcmp.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestNullableArrays.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestOnStackReplacement.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestOptimizeKlassCmp.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestStressReturnBuffering.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestUnloadedInlineTypeArray.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestUnresolvedDefault.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestUnresolvedInlineClass.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestWithfieldC1.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/hack/GetUnresolvedInlineFieldWrongSignature.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/libTestJNICalls.c (100%) delete mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/DefaultScenarios.java delete mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/InlineHelpers.java delete mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/MyAbstract.java delete mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/MyConstants.java delete mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/MyInterface.java delete mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/MyValue1.java delete mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/MyValue2.java delete mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/MyValue3.java delete mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/MyValue4.java delete mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/MyValueEmpty.java delete mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/NamedRectangle.java delete mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/Point.java delete mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/Rectangle.java delete mode 100644 test/hotspot/jtreg/compiler/valhalla/testframework/SimpleInlineType.java rename test/{hotspot/jtreg/compiler/valhalla/testframework => lib/jdk/test/lib/hotspot/ir_framework}/examples/CheckExample.java (97%) rename test/{hotspot/jtreg/compiler/valhalla/testframework => lib/jdk/test/lib/hotspot/ir_framework}/examples/RunExample.java (97%) rename test/{hotspot/jtreg/compiler/valhalla/testframework => lib/jdk/test/lib/hotspot/ir_framework}/examples/SimpleExample.java (93%) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/examples/TEST.ROOT rename test/{hotspot/jtreg/compiler/valhalla/testframework => lib/jdk/test/lib/hotspot/ir_framework}/examples/TestExample.java (95%) diff --git a/test/hotspot/jtreg/TestFramework/src/valhallatests/ValhallaIRNode.java b/test/hotspot/jtreg/TestFramework/src/valhallatests/ValhallaIRNode.java deleted file mode 100644 index 534cf5a9d2b..00000000000 --- a/test/hotspot/jtreg/TestFramework/src/valhallatests/ValhallaIRNode.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2021, 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 valhallatests; - -public class ValhallaIRNode { - private static final String START = "(\\d+(\\s){2}("; - private static final String MID = ".*)+(\\s){2}===.*"; - private static final String END = ")"; - - public static final String CHECKCAST_ARRAY_INLINE = "(cmp.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*" + END; - public static final String ALLOCA = "(.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_array_Java" + END; - public static final String STORE_INLINE_FIELDS = START + "CallStaticJava" + MID + "store_inline_type_fields" + END; - public static final String LOAD_UNKNOWN_INLINE = "(.*call_leaf,runtime load_unknown_inline.*" + END; - public static final String STORE_UNKNOWN_INLINE = "(.*call_leaf,runtime store_unknown_inline.*" + END; - public static final String INLINE_ARRAY_NULL_GUARD = "(.*call,static wrapper for: uncommon_trap.*reason='null_check' action='none'.*" + END; - public static final String INTRINSIC_SLOW_PATH = "(.*call,static wrapper for: uncommon_trap.*reason='intrinsic_or_type_checked_inlining'.*" + END; - public static final String CLONE_INTRINSIC_SLOW_PATH = "(.*call,static.*java.lang.Object::clone.*" + END; - public static final String JLONG_ARRAYCOPY = "(.*call_leaf_nofp,runtime jlong_disjoint_arraycopy.*" + END; - public static final String SUBSTITUTABILITY_TEST = START + "CallStaticJava" + MID + "java.lang.invoke.ValueBootstrapMethods::isSubstitutable" + END; -} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/TestNullableInlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestNullableInlineTypes.java similarity index 55% rename from test/hotspot/jtreg/compiler/valhalla/testframework/TestNullableInlineTypes.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestNullableInlineTypes.java index 0add433f4ee..1dc693a98b3 100644 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/TestNullableInlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestNullableInlineTypes.java @@ -26,37 +26,30 @@ * @key randomness * @summary Test correct handling of nullable inline types. * @library /test/lib - * @run driver compiler.valhalla.testframework.TestNullableInlineTypes + * @compile InlineTypes.java + * @run driver compiler.valhalla.inlinetypes.ExampleTestNullableInlineTypes */ -package compiler.valhalla.testframework; +package compiler.valhalla.inlinetypes; +import jdk.test.lib.Asserts; import jdk.test.lib.hotspot.ir_framework.*; -public abstract class TestNullableInlineTypes { - private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(2, 3); +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; + +public class ExampleTestNullableInlineTypes { + private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(InlineTypes.rI, InlineTypes.rL); public static void main(String[] args) { - Scenario[] scenarios = DefaultScenarios.SCENARIOS; + Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; scenarios[3] = new Scenario(3, "-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"); scenarios[4] = new Scenario(4, "-XX:-MonomorphicArrayCheck"); TestFramework testFramework = new TestFramework(TestNullableInlineTypes.class); testFramework.addScenarios(scenarios) - .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class, - TestNullableInlineTypes.Test17Value.class, TestNullableInlineTypes.Test21Value.class) + .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class) .start(); } - // Test scalarization of default inline type with non-flattenable field - final primitive class Test17Value { - public final MyValue1.ref valueField; - - @ForceInline - public Test17Value(MyValue1.ref valueField) { - this.valueField = valueField; - } - } - // Test writing null to a flattenable/non-flattenable inline type field in an inline type final primitive class Test21Value { final MyValue1.ref valueField1; @@ -70,14 +63,54 @@ public Test21Value(MyValue1.ref valueField1, MyValue1 valueField2) { } @ForceInline - public TestNullableInlineTypes.Test21Value test1() { - return new TestNullableInlineTypes.Test21Value(alwaysNull, this.valueField2); // Should not throw NPE + public Test21Value test1() { + return new Test21Value(alwaysNull, this.valueField2); // Should not throw NPE } @ForceInline - public TestNullableInlineTypes.Test21Value test2() { - return new TestNullableInlineTypes.Test21Value(this.valueField1, (MyValue1) alwaysNull); // Should throw NPE + public Test21Value test2() { + return new Test21Value(this.valueField1, (MyValue1) alwaysNull); // Should throw NPE + } + } + + @Test + public Test21Value test21(Test21Value vt) { + vt = vt.test1(); + try { + vt = vt.test2(); + throw new RuntimeException("NullPointerException expected"); + } catch (NullPointerException e) { + // Expected } + return vt; + } + + @Run(test = "test21") + public void test21_verifier() { + test21(Test21Value.default); + } + + + @DontInline + public void test25_callee(MyValue1 val) { } + + // Test that when checkcasting from null-ok to null-free and back to null-ok we + // keep track of the information that the inline type can never be null. + @Test + @IR(failOn = {ALLOC, STORE}) + public int test25(boolean b, MyValue1.ref vt1, MyValue1 vt2) { + vt1 = (MyValue1)vt1; + Object obj = b ? vt1 : vt2; // We should not allocate here + test25_callee((MyValue1) vt1); + return ((MyValue1)obj).x; + } + + @Run(test = "test25") + public void test25_verifier() { + int res = test25(true, testValue1, testValue1); + Asserts.assertEquals(res, testValue1.x); + res = test25(false, testValue1, testValue1); + Asserts.assertEquals(res, testValue1.x); } } diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/TestUnloadedInlineTypeField.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleUnloadedInlineTypeField.java similarity index 95% rename from test/hotspot/jtreg/compiler/valhalla/testframework/TestUnloadedInlineTypeField.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleUnloadedInlineTypeField.java index f0d4d79ed4d..8fb9d386f81 100644 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/TestUnloadedInlineTypeField.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleUnloadedInlineTypeField.java @@ -27,14 +27,14 @@ * @summary Test the handling of fields of unloaded inline classes. * @library /test/lib * @compile MyConstants.java - * @run driver compiler.valhalla.testframework.TestUnloadedInlineTypeField + * @run driver compiler.valhalla.testframework.ExampleTestUnloadedInlineTypeField */ package compiler.valhalla.testframework; import jdk.test.lib.Asserts; import jdk.test.lib.hotspot.ir_framework.*; -public class TestUnloadedInlineTypeField { +public class ExampleTestUnloadedInlineTypeField { public static void main(String[] args) { Scenario s0 = new Scenario(0); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java new file mode 100644 index 00000000000..8686ad24944 --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java @@ -0,0 +1,682 @@ +package compiler.valhalla.inlinetypes; + +import jdk.test.lib.Asserts; +import jdk.test.lib.Utils; +import jdk.test.lib.hotspot.ir_framework.DontCompile; +import jdk.test.lib.hotspot.ir_framework.DontInline; +import jdk.test.lib.hotspot.ir_framework.ForceInline; +import jdk.test.lib.hotspot.ir_framework.Scenario; + +public class InlineTypes { + public static final int rI = Utils.getRandomInstance().nextInt() % 1000; + public static final long rL = Utils.getRandomInstance().nextLong() % 1000; + public static final double rD = Utils.getRandomInstance().nextDouble() % 1000; + + public static final Scenario[] DEFAULT_SCENARIOS = { + new Scenario(0, + "-XX:-UseACmpProfile", + "-XX:+AlwaysIncrementalInline", + "-XX:FlatArrayElementMaxOops=5", + "-XX:FlatArrayElementMaxSize=-1", + "-XX:-UseArrayLoadStoreProfile", + "-XX:InlineFieldMaxFlatSize=-1", + "-XX:+InlineTypePassFieldsAsArgs", + "-XX:+InlineTypeReturnedAsFields" + ), + new Scenario(1, + "-XX:-UseACmpProfile", + "-XX:-UseCompressedOops", + "-XX:FlatArrayElementMaxOops=5", + "-XX:FlatArrayElementMaxSize=-1", + "-XX:-UseArrayLoadStoreProfile", + "-XX:InlineFieldMaxFlatSize=-1", + "-XX:-InlineTypePassFieldsAsArgs", + "-XX:-InlineTypeReturnedAsFields" + ), + new Scenario(2, + "-XX:-UseACmpProfile", + "-XX:-UseCompressedOops", + "-XX:FlatArrayElementMaxOops=0", + "-XX:FlatArrayElementMaxSize=0", + "-XX:-UseArrayLoadStoreProfile", + "-XX:InlineFieldMaxFlatSize=-1", + "-XX:+InlineTypePassFieldsAsArgs", + "-XX:+InlineTypeReturnedAsFields", + "-XX:+StressInlineTypeReturnedAsFields" + ), + new Scenario(3, + "-DVerifyIR=false", + "-XX:+AlwaysIncrementalInline", + "-XX:FlatArrayElementMaxOops=0", + "-XX:FlatArrayElementMaxSize=0", + "-XX:InlineFieldMaxFlatSize=0", + "-XX:+InlineTypePassFieldsAsArgs", + "-XX:+InlineTypeReturnedAsFields" + ), + new Scenario(4, + "-DVerifyIR=false", + "-XX:FlatArrayElementMaxOops=-1", + "-XX:FlatArrayElementMaxSize=-1", + "-XX:InlineFieldMaxFlatSize=0", + "-XX:+InlineTypePassFieldsAsArgs", + "-XX:-InlineTypeReturnedAsFields", + "-XX:-ReduceInitialCardMarks" + ), + new Scenario(5, + "-XX:-UseACmpProfile", + "-XX:+AlwaysIncrementalInline", + "-XX:FlatArrayElementMaxOops=5", + "-XX:FlatArrayElementMaxSize=-1", + "-XX:-UseArrayLoadStoreProfile", + "-XX:InlineFieldMaxFlatSize=-1", + "-XX:-InlineTypePassFieldsAsArgs", + "-XX:-InlineTypeReturnedAsFields" + ) + }; + + static class IRNode { + // Regular expressions used to match nodes in the PrintIdeal output + protected static final String START = "(\\d+ (.*"; + protected static final String MID = ".*)+ ===.*"; + protected static final String END = ")"; + // Generic allocation + protected static final String ALLOC_G = "(.*call,static wrapper for: _new_instance_Java" + END; + protected static final String ALLOCA_G = "(.*call,static wrapper for: _new_array_Java" + END; + // Inline type allocation + protected static final String ALLOC = "(.*precise klass compiler/valhalla/inlinetypes/MyValue.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_instance_Java" + END; + protected static final String ALLOCA = "(.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_array_Java" + END; + protected static final String LOAD = START + "Load(B|S|I|L|F|D|P|N)" + MID + "@compiler/valhalla/inlinetypes/MyValue.*" + END; + protected static final String LOADK = START + "LoadK" + MID + END; + protected static final String STORE = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@compiler/valhalla/inlinetypes/MyValue.*" + END; + protected static final String LOOP = START + "Loop" + MID + "" + END; + protected static final String COUNTEDLOOP = START + "CountedLoop\\b" + MID + "" + END; + protected static final String COUNTEDLOOP_MAIN = START + "CountedLoop\\b" + MID + "main" + END; + protected static final String TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*(unstable_if|predicate)" + END; + protected static final String LINKTOSTATIC = START + "CallStaticJava" + MID + "linkToStatic" + END; + protected static final String NPE = START + "CallStaticJava" + MID + "null_check" + END; + protected static final String CALL = START + "CallStaticJava" + MID + END; + protected static final String STORE_INLINE_FIELDS = START + "CallStaticJava" + MID + "store_inline_type_fields" + END; + protected static final String SCOBJ = "(.*# ScObj.*" + END; + protected static final String LOAD_UNKNOWN_INLINE = "(.*call_leaf,runtime load_unknown_inline.*" + END; + protected static final String STORE_UNKNOWN_INLINE = "(.*call_leaf,runtime store_unknown_inline.*" + END; + protected static final String INLINE_ARRAY_NULL_GUARD = "(.*call,static wrapper for: uncommon_trap.*reason='null_check' action='none'.*" + END; + protected static final String INTRINSIC_SLOW_PATH = "(.*call,static wrapper for: uncommon_trap.*reason='intrinsic_or_type_checked_inlining'.*" + END; + protected static final String CLONE_INTRINSIC_SLOW_PATH = "(.*call,static.*java.lang.Object::clone.*" + END; + protected static final String CLASS_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*class_check" + END; + protected static final String NULL_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*null_check" + END; + protected static final String NULL_ASSERT_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*null_assert" + END; + protected static final String RANGE_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*range_check" + END; + protected static final String UNHANDLED_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*unhandled" + END; + protected static final String PREDICATE_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*predicate" + END; + protected static final String MEMBAR = START + "MemBar" + MID + END; + protected static final String CHECKCAST_ARRAY = "(cmp.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*" + END; + protected static final String CHECKCAST_ARRAYCOPY = "(.*call_leaf_nofp,runtime checkcast_arraycopy.*" + END; + protected static final String JLONG_ARRAYCOPY = "(.*call_leaf_nofp,runtime jlong_disjoint_arraycopy.*" + END; + protected static final String FIELD_ACCESS = "(.*Field: *" + END; + protected static final String SUBSTITUTABILITY_TEST = START + "CallStaticJava" + MID + "java.lang.invoke.ValueBootstrapMethods::isSubstitutable" + END; + } + +} + +interface MyInterface { + public long hash(); +} + +abstract class MyAbstract implements MyInterface { + +} + +final primitive class MyValueEmpty implements MyInterface { + public long hash() { return 0; } + + public MyValueEmpty copy(MyValueEmpty other) { return other; } +} + +class NamedRectangle { + Rectangle rect = new Rectangle(); + String name = ""; + + static int getP1X(NamedRectangle nr) { + return nr.rect + .p1 + .x; + } + + static Point getP1(NamedRectangle nr) { + return nr.rect + .p1; + } +} + +primitive class Point { + int x = 4; + int y = 7; +} + +primitive class Rectangle { + Point p0 = new Point(); + Point p1 = new Point(); +} + +primitive class SimpleInlineType { + final int x; + + private SimpleInlineType() { + x = 0; + } + + static SimpleInlineType create() { + return SimpleInlineType.default; + } +} + +final primitive class MyValue1 implements MyInterface { + static int s; + static final long sf = InlineTypes.rL; + final int x; + final long y; + final short z; + final Integer o; + final int[] oa; + final MyValue2 v1; + final MyValue2 v2; + static final MyValue2 v3 = MyValue2.createWithFieldsInline(InlineTypes.rI, InlineTypes.rD); + final int c; + + @ForceInline + public MyValue1(int x, long y, short z, Integer o, int[] oa, MyValue2 v1, MyValue2 v2, int c) { + s = 0; + this.x = x; + this.y = y; + this.z = z; + this.o = o; + this.oa = oa; + this.v1 = v1; + this.v2 = v2; + this.c = c; + } + + @DontInline + static MyValue1 createDefaultDontInline() { + return createDefaultInline(); + } + + @ForceInline + static MyValue1 createDefaultInline() { + return MyValue1.default; + } + + @DontInline + static MyValue1 createWithFieldsDontInline(int x, long y) { + return createWithFieldsInline(x, y); + } + + @ForceInline + static MyValue1 createWithFieldsInline(int x, long y) { + MyValue1 v = createDefaultInline(); + v = setX(v, x); + v = setY(v, y); + v = setZ(v, (short)x); + // Don't use Integer.valueOf here to avoid control flow added by Integer cache check + v = setO(v, new Integer(x)); + int[] oa = {x}; + v = setOA(v, oa); + v = setV1(v, MyValue2.createWithFieldsInline(x, y, InlineTypes.rD)); + v = setV2(v, MyValue2.createWithFieldsInline(x, y, InlineTypes.rD + x)); + v = setC(v, (int)(x+y)); + return v; + } + + // Hash only primitive and inline type fields to avoid NullPointerException + @ForceInline + public long hashPrimitive() { + return s + sf + x + y + z + c + v1.hash() + v2.hash() + v3.hash(); + } + + @ForceInline + public long hash() { + long res = hashPrimitive(); + try { + res += o; + } catch(NullPointerException npe) {} + try { + res += oa[0]; + } catch(NullPointerException npe) {} + return res; + } + + @DontCompile + public long hashInterpreted() { + return s + sf + x + y + z + o + oa[0] + c + v1.hashInterpreted() + v2.hashInterpreted() + v3.hashInterpreted(); + } + + @ForceInline + public void print() { + System.out.print("s=" + s + ", sf=" + sf + ", x=" + x + ", y=" + y + ", z=" + z + ", o=" + (o != null ? (Integer)o : "NULL") + ", oa=" + (oa != null ? oa[0] : "NULL") + ", v1["); + v1.print(); + System.out.print("], v2["); + v2.print(); + System.out.print("], v3["); + v3.print(); + System.out.print("], c=" + c); + } + + @ForceInline + static MyValue1 setX(MyValue1 v, int x) { + return new MyValue1(x, v.y, v.z, v.o, v.oa, v.v1, v.v2, v.c); + } + + @ForceInline + static MyValue1 setY(MyValue1 v, long y) { + return new MyValue1(v.x, y, v.z, v.o, v.oa, v.v1, v.v2, v.c); + } + + @ForceInline + static MyValue1 setZ(MyValue1 v, short z) { + return new MyValue1(v.x, v.y, z, v.o, v.oa, v.v1, v.v2, v.c); + } + + @ForceInline + static MyValue1 setO(MyValue1 v, Integer o) { + return new MyValue1(v.x, v.y, v.z, o, v.oa, v.v1, v.v2, v.c); + } + + @ForceInline + static MyValue1 setOA(MyValue1 v, int[] oa) { + return new MyValue1(v.x, v.y, v.z, v.o, oa, v.v1, v.v2, v.c); + } + + @ForceInline + static MyValue1 setC(MyValue1 v, int c) { + return new MyValue1(v.x, v.y, v.z, v.o, v.oa, v.v1, v.v2, c); + } + + @ForceInline + static MyValue1 setV1(MyValue1 v, MyValue2 v1) { + return new MyValue1(v.x, v.y, v.z, v.o, v.oa, v1, v.v2, v.c); + } + + @ForceInline + static MyValue1 setV2(MyValue1 v, MyValue2 v2) { + return new MyValue1(v.x, v.y, v.z, v.o, v.oa, v.v1, v2, v.c); + } +} + +final primitive class MyValue2Inline { + final double d; + final long l; + + @ForceInline + public MyValue2Inline(double d, long l) { + this.d = d; + this.l = l; + } + + @ForceInline + static MyValue2Inline setD(MyValue2Inline v, double d) { + return new MyValue2Inline(d, v.l); + } + + @ForceInline + static MyValue2Inline setL(MyValue2Inline v, long l) { + return new MyValue2Inline(v.d, l); + } + + @ForceInline + public static MyValue2Inline createDefault() { + return MyValue2Inline.default; + } + + @ForceInline + public static MyValue2Inline createWithFieldsInline(double d, long l) { + MyValue2Inline v = MyValue2Inline.createDefault(); + v = MyValue2Inline.setD(v, d); + v = MyValue2Inline.setL(v, l); + return v; + } +} + +final primitive class MyValue2 implements MyInterface { + final int x; + final byte y; + final MyValue2Inline v; + + @ForceInline + public MyValue2(int x, byte y, MyValue2Inline v) { + this.x = x; + this.y = y; + this.v = v; + } + + @ForceInline + public static MyValue2 createDefaultInline() { + return MyValue2.default; + } + + @ForceInline + public static MyValue2 createWithFieldsInline(int x, long y, double d) { + MyValue2 v = createDefaultInline(); + v = setX(v, x); + v = setY(v, (byte)x); + v = setV(v, MyValue2Inline.createWithFieldsInline(d, y)); + return v; + } + + @ForceInline + public static MyValue2 createWithFieldsInline(int x, double d) { + MyValue2 v = createDefaultInline(); + v = setX(v, x); + v = setY(v, (byte)x); + v = setV(v, MyValue2Inline.createWithFieldsInline(d, InlineTypes.rL)); + return v; + } + + @DontInline + public static MyValue2 createWithFieldsDontInline(int x, double d) { + MyValue2 v = createDefaultInline(); + v = setX(v, x); + v = setY(v, (byte)x); + v = setV(v, MyValue2Inline.createWithFieldsInline(d, InlineTypes.rL)); + return v; + } + + @ForceInline + public long hash() { + return x + y + (long)v.d + v.l; + } + + @DontInline + public long hashInterpreted() { + return x + y + (long)v.d + v.l; + } + + @ForceInline + public void print() { + System.out.print("x=" + x + ", y=" + y + ", d=" + v.d + ", l=" + v.l); + } + + @ForceInline + static MyValue2 setX(MyValue2 v, int x) { + return new MyValue2(x, v.y, v.v); + } + + @ForceInline + static MyValue2 setY(MyValue2 v, byte y) { + return new MyValue2(v.x, y, v.v); + } + + @ForceInline + static MyValue2 setV(MyValue2 v, MyValue2Inline vi) { + return new MyValue2(v.x, v.y, vi); + } +} + +final primitive class MyValue3Inline { + final float f7; + final double f8; + + @ForceInline + public MyValue3Inline(float f7, double f8) { + this.f7 = f7; + this.f8 = f8; + } + + @ForceInline + static MyValue3Inline setF7(MyValue3Inline v, float f7) { + return new MyValue3Inline(f7, v.f8); + } + + @ForceInline + static MyValue3Inline setF8(MyValue3Inline v, double f8) { + return new MyValue3Inline(v.f7, f8); + } + + @ForceInline + public static MyValue3Inline createDefault() { + return MyValue3Inline.default; + } + + @ForceInline + public static MyValue3Inline createWithFieldsInline(float f7, double f8) { + MyValue3Inline v = createDefault(); + v = setF7(v, f7); + v = setF8(v, f8); + return v; + } +} + +// Inline type definition to stress test return of an inline type in registers +// (uses all registers of calling convention on x86_64) +final primitive class MyValue3 extends MyAbstract { + final char c; + final byte bb; + final short s; + final int i; + final long l; + final Object o; + final float f1; + final double f2; + final float f3; + final double f4; + final float f5; + final double f6; + final MyValue3Inline v1; + + @ForceInline + public MyValue3(char c, byte bb, short s, int i, long l, Object o, + float f1, double f2, float f3, double f4, float f5, double f6, + MyValue3Inline v1) { + this.c = c; + this.bb = bb; + this.s = s; + this.i = i; + this.l = l; + this.o = o; + this.f1 = f1; + this.f2 = f2; + this.f3 = f3; + this.f4 = f4; + this.f5 = f5; + this.f6 = f6; + this.v1 = v1; + } + + @ForceInline + static MyValue3 setC(MyValue3 v, char c) { + return new MyValue3(c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setBB(MyValue3 v, byte bb) { + return new MyValue3(v.c, bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setS(MyValue3 v, short s) { + return new MyValue3(v.c, v.bb, s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setI(MyValue3 v, int i) { + return new MyValue3(v.c, v.bb, v.s, i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setL(MyValue3 v, long l) { + return new MyValue3(v.c, v.bb, v.s, v.i, l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setO(MyValue3 v, Object o) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setF1(MyValue3 v, float f1) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setF2(MyValue3 v, double f2) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setF3(MyValue3 v, float f3) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setF4(MyValue3 v, double f4) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setF5(MyValue3 v, float f5) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setF6(MyValue3 v, double f6) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, f6, v.v1); + } + + @ForceInline + static MyValue3 setV1(MyValue3 v, MyValue3Inline v1) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v1); + } + + @ForceInline + public static MyValue3 createDefault() { + return MyValue3.default; + } + + @ForceInline + public static MyValue3 create() { + java.util.Random r = Utils.getRandomInstance(); + MyValue3 v = createDefault(); + v = setC(v, (char)r.nextInt()); + v = setBB(v, (byte)r.nextInt()); + v = setS(v, (short)r.nextInt()); + v = setI(v, r.nextInt()); + v = setL(v, r.nextLong()); + v = setO(v, new Object()); + v = setF1(v, r.nextFloat()); + v = setF2(v, r.nextDouble()); + v = setF3(v, r.nextFloat()); + v = setF4(v, r.nextDouble()); + v = setF5(v, r.nextFloat()); + v = setF6(v, r.nextDouble()); + v = setV1(v, MyValue3Inline.createWithFieldsInline(r.nextFloat(), r.nextDouble())); + return v; + } + + @DontInline + public static MyValue3 createDontInline() { + return create(); + } + + @ForceInline + public static MyValue3 copy(MyValue3 other) { + MyValue3 v = createDefault(); + v = setC(v, other.c); + v = setBB(v, other.bb); + v = setS(v, other.s); + v = setI(v, other.i); + v = setL(v, other.l); + v = setO(v, other.o); + v = setF1(v, other.f1); + v = setF2(v, other.f2); + v = setF3(v, other.f3); + v = setF4(v, other.f4); + v = setF5(v, other.f5); + v = setF6(v, other.f6); + v = setV1(v, other.v1); + return v; + } + + @DontInline + public void verify(MyValue3 other) { + Asserts.assertEQ(c, other.c); + Asserts.assertEQ(bb, other.bb); + Asserts.assertEQ(s, other.s); + Asserts.assertEQ(i, other.i); + Asserts.assertEQ(l, other.l); + Asserts.assertEQ(o, other.o); + Asserts.assertEQ(f1, other.f1); + Asserts.assertEQ(f2, other.f2); + Asserts.assertEQ(f3, other.f3); + Asserts.assertEQ(f4, other.f4); + Asserts.assertEQ(f5, other.f5); + Asserts.assertEQ(f6, other.f6); + Asserts.assertEQ(v1.f7, other.v1.f7); + Asserts.assertEQ(v1.f8, other.v1.f8); + } + + @ForceInline + public long hash() { + return c + + bb + + s + + i + + l + + o.hashCode() + + Float.hashCode(f1) + + Double.hashCode(f2) + + Float.hashCode(f3) + + Double.hashCode(f4) + + Float.hashCode(f5) + + Double.hashCode(f6) + + Float.hashCode(v1.f7) + + Double.hashCode(v1.f8); + } +} + +// Inline type definition with too many fields to return in registers +final primitive class MyValue4 implements MyInterface { + final MyValue3 v1; + final MyValue3 v2; + + @ForceInline + public MyValue4(MyValue3 v1, MyValue3 v2) { + this.v1 = v1; + this.v2 = v2; + } + + @ForceInline + static MyValue4 setV1(MyValue4 v, MyValue3 v1) { + return new MyValue4(v1, v.v2); + } + + @ForceInline + static MyValue4 setV2(MyValue4 v, MyValue3 v2) { + return new MyValue4(v.v1, v2); + } + + @ForceInline + public static MyValue4 createDefault() { + return MyValue4.default; + } + + @ForceInline + public static MyValue4 create() { + MyValue4 v = createDefault(); + MyValue3 v1 = MyValue3.create(); + v = setV1(v, v1); + MyValue3 v2 = MyValue3.create(); + v = setV2(v, v2); + return v; + } + + public void verify(MyValue4 other) { + v1.verify(other.v1); + v2.verify(other.v2); + } + + @ForceInline + public long hash() { + return v1.hash() + v2.hash(); + } +} + + diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java index 98ab9441294..a9d68961460 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java @@ -46,8 +46,8 @@ public class TestNullableInlineTypes extends InlineTypeTest { @Override public String[] getExtraVMParameters(int scenario) { switch (scenario) { - case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"}; - case 4: return new String[] {"-XX:-MonomorphicArrayCheck"}; + case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"}; + case 4: return new String[] {"-XX:-MonomorphicArrayCheck"}; } return null; } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java index d5f7e803ae5..a6043fcc1a7 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java @@ -51,10 +51,10 @@ public static void main(String[] args) throws Throwable { } static final String[][] scenarios = { - {}, - {"-XX:InlineFieldMaxFlatSize=0"}, - {"-XX:+PatchALot"}, - {"-XX:InlineFieldMaxFlatSize=0", "-XX:+PatchALot"} + {}, + {"-XX:InlineFieldMaxFlatSize=0"}, + {"-XX:+PatchALot"}, + {"-XX:InlineFieldMaxFlatSize=0", "-XX:+PatchALot"} }; @Override diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/GetfieldChains.jcod b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/GetfieldChains.jcod similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/GetfieldChains.jcod rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/GetfieldChains.jcod diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypeTest.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/InlineTypeTest.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypeTest.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/InlineTypeTest.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrayAccessDeopt.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestArrayAccessDeopt.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrayAccessDeopt.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestArrayAccessDeopt.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrayCopyWithOops.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestArrayCopyWithOops.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrayCopyWithOops.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestArrayCopyWithOops.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestArrays.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestArrays.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBimorphicInlining.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBimorphicInlining.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBimorphicInlining.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBimorphicInlining.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBufferTearing.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBufferTearing.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBufferTearing.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBufferTearing.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestC1.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestC1.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC2CCalls.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestC2CCalls.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC2CCalls.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestC2CCalls.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestCallingConvention.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestCallingConvention.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestCallingConventionC1.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestCallingConventionC1.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestDeadAllocationRemoval.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestDeadAllocationRemoval.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestDeadAllocationRemoval.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestDeadAllocationRemoval.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestDeoptimizationWhenBuffering.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestDeoptimizationWhenBuffering.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestDeoptimizationWhenBuffering.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestDeoptimizationWhenBuffering.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestFlatArrayAliasesCardMark.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestFlatArrayAliasesCardMark.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestFlatArrayAliasesCardMark.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestFlatArrayAliasesCardMark.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestFlatArrayThreshold.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestFlatArrayThreshold.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestFlatArrayThreshold.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestFlatArrayThreshold.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGenerated.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestGenerated.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGenerated.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestGenerated.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestGetfieldChains.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestGetfieldChains.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestIntrinsics.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestIntrinsics.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIsSubstitutableReresolution.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestIsSubstitutableReresolution.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIsSubstitutableReresolution.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestIsSubstitutableReresolution.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestJNICalls.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestJNICalls.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestLWorld.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestLWorld.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestLWorldProfiling.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestLWorldProfiling.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestMethodHandles.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestMethodHandles.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNativeClone.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNativeClone.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNativeClone.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNativeClone.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNestmateAccess.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNestmateAccess.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNestmateAccess.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNestmateAccess.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNewAcmp.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNewAcmp.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNewAcmp.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNewAcmp.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNullableArrays.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNullableArrays.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestOnStackReplacement.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestOnStackReplacement.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOptimizeKlassCmp.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestOptimizeKlassCmp.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOptimizeKlassCmp.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestOptimizeKlassCmp.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestStressReturnBuffering.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestStressReturnBuffering.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestStressReturnBuffering.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestStressReturnBuffering.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeArray.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnloadedInlineTypeArray.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeArray.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnloadedInlineTypeArray.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnresolvedDefault.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnresolvedDefault.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnresolvedDefault.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnresolvedDefault.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnresolvedInlineClass.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnresolvedInlineClass.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnresolvedInlineClass.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnresolvedInlineClass.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestWithfieldC1.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestWithfieldC1.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/hack/GetUnresolvedInlineFieldWrongSignature.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/hack/GetUnresolvedInlineFieldWrongSignature.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/hack/GetUnresolvedInlineFieldWrongSignature.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/hack/GetUnresolvedInlineFieldWrongSignature.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/libTestJNICalls.c b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/libTestJNICalls.c similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/libTestJNICalls.c rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/libTestJNICalls.c diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/DefaultScenarios.java b/test/hotspot/jtreg/compiler/valhalla/testframework/DefaultScenarios.java deleted file mode 100644 index 333ef7ac89d..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/DefaultScenarios.java +++ /dev/null @@ -1,71 +0,0 @@ -package compiler.valhalla.testframework; - -import jdk.test.lib.hotspot.ir_framework.Scenario; - -public class DefaultScenarios { - /** - * VM parameters for the 5 built-in test scenarios. If your test needs to append - * extra parameters for (some of) these scenarios, override getExtraVMParameters(). - */ - public static final Scenario[] SCENARIOS = { - new Scenario(0, - "-XX:-UseACmpProfile", - "-XX:+AlwaysIncrementalInline", - "-XX:FlatArrayElementMaxOops=5", - "-XX:FlatArrayElementMaxSize=-1", - "-XX:-UseArrayLoadStoreProfile", - "-XX:InlineFieldMaxFlatSize=-1", - "-XX:+InlineTypePassFieldsAsArgs", - "-XX:+InlineTypeReturnedAsFields" - ), - new Scenario(1, - "-XX:-UseACmpProfile", - "-XX:-UseCompressedOops", - "-XX:FlatArrayElementMaxOops=5", - "-XX:FlatArrayElementMaxSize=-1", - "-XX:-UseArrayLoadStoreProfile", - "-XX:InlineFieldMaxFlatSize=-1", - "-XX:-InlineTypePassFieldsAsArgs", - "-XX:-InlineTypeReturnedAsFields" - ), - new Scenario(2, - "-XX:-UseACmpProfile", - "-XX:-UseCompressedOops", - "-XX:FlatArrayElementMaxOops=0", - "-XX:FlatArrayElementMaxSize=0", - "-XX:-UseArrayLoadStoreProfile", - "-XX:InlineFieldMaxFlatSize=-1", - "-XX:+InlineTypePassFieldsAsArgs", - "-XX:+InlineTypeReturnedAsFields", - "-XX:+StressInlineTypeReturnedAsFields" - ), - new Scenario(3, - "-DVerifyIR=false", - "-XX:+AlwaysIncrementalInline", - "-XX:FlatArrayElementMaxOops=0", - "-XX:FlatArrayElementMaxSize=0", - "-XX:InlineFieldMaxFlatSize=0", - "-XX:+InlineTypePassFieldsAsArgs", - "-XX:+InlineTypeReturnedAsFields" - ), - new Scenario(4, - "-DVerifyIR=false", - "-XX:FlatArrayElementMaxOops=-1", - "-XX:FlatArrayElementMaxSize=-1", - "-XX:InlineFieldMaxFlatSize=0", - "-XX:+InlineTypePassFieldsAsArgs", - "-XX:-InlineTypeReturnedAsFields", - "-XX:-ReduceInitialCardMarks" - ), - new Scenario(5, - "-XX:-UseACmpProfile", - "-XX:+AlwaysIncrementalInline", - "-XX:FlatArrayElementMaxOops=5", - "-XX:FlatArrayElementMaxSize=-1", - "-XX:-UseArrayLoadStoreProfile", - "-XX:InlineFieldMaxFlatSize=-1", - "-XX:-InlineTypePassFieldsAsArgs", - "-XX:-InlineTypeReturnedAsFields" - ) - }; -} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/InlineHelpers.java b/test/hotspot/jtreg/compiler/valhalla/testframework/InlineHelpers.java deleted file mode 100644 index 9120782234d..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/InlineHelpers.java +++ /dev/null @@ -1,4 +0,0 @@ -package compiler.valhalla.testframework; - -public class InlineHelpers { -} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/MyAbstract.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyAbstract.java deleted file mode 100644 index d03e4b717ec..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/MyAbstract.java +++ /dev/null @@ -1,5 +0,0 @@ -package compiler.valhalla.testframework; - -public abstract class MyAbstract implements MyInterface { - -} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/MyConstants.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyConstants.java deleted file mode 100644 index 6d26296e501..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/MyConstants.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021, 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.valhalla.testframework; - -import jdk.test.lib.Utils; - -public class MyConstants { - public static final int rI = Utils.getRandomInstance().nextInt() % 1000; - public static final long rL = Utils.getRandomInstance().nextLong() % 1000; - public static final double rD = Utils.getRandomInstance().nextDouble() % 1000; -} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/MyInterface.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyInterface.java deleted file mode 100644 index 5f6666c0a08..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/MyInterface.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2018, 2021, 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.valhalla.testframework; - -public interface MyInterface { - public long hash(); -} - diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue1.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue1.java deleted file mode 100644 index 0ae04a0b39b..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue1.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2017, 2021, 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.valhalla.testframework; - -import jdk.test.lib.hotspot.ir_framework.*; - -public final primitive class MyValue1 extends MyAbstract { - static int s; - static final long sf = MyConstants.rL; - final int x; - final long y; - final short z; - final Integer o; - final int[] oa; - final MyValue2 v1; - final MyValue2 v2; - static final MyValue2 v3 = MyValue2.createWithFieldsInline(MyConstants.rI, MyConstants.rD); - final int c; - - @ForceInline - public MyValue1(int x, long y, short z, Integer o, int[] oa, MyValue2 v1, MyValue2 v2, int c) { - s = 0; - this.x = x; - this.y = y; - this.z = z; - this.o = o; - this.oa = oa; - this.v1 = v1; - this.v2 = v2; - this.c = c; - } - - @DontInline - static MyValue1 createDefaultDontInline() { - return createDefaultInline(); - } - - @ForceInline - static MyValue1 createDefaultInline() { - return MyValue1.default; - } - - @DontInline - static MyValue1 createWithFieldsDontInline(int x, long y) { - return createWithFieldsInline(x, y); - } - - @ForceInline - static MyValue1 createWithFieldsInline(int x, long y) { - MyValue1 v = createDefaultInline(); - v = setX(v, x); - v = setY(v, y); - v = setZ(v, (short)x); - // Don't use Integer.valueOf here to avoid control flow added by Integer cache check - v = setO(v, new Integer(x)); - int[] oa = {x}; - v = setOA(v, oa); - v = setV1(v, MyValue2.createWithFieldsInline(x, y, MyConstants.rD)); - v = setV2(v, MyValue2.createWithFieldsInline(x, y, MyConstants.rD + x)); - v = setC(v, (int)(x+y)); - return v; - } - - // Hash only primitive and inline type fields to avoid NullPointerException - @ForceInline - public long hashPrimitive() { - return s + sf + x + y + z + c + v1.hash() + v2.hash() + v3.hash(); - } - - @ForceInline - public long hash() { - long res = hashPrimitive(); - try { - res += o; - } catch(NullPointerException npe) {} - try { - res += oa[0]; - } catch(NullPointerException npe) {} - return res; - } - - @DontCompile - public long hashInterpreted() { - return s + sf + x + y + z + o + oa[0] + c + v1.hashInterpreted() + v2.hashInterpreted() + v3.hashInterpreted(); - } - - @ForceInline - public void print() { - System.out.print("s=" + s + ", sf=" + sf + ", x=" + x + ", y=" + y + ", z=" + z + ", o=" + (o != null ? (Integer)o : "NULL") + ", oa=" + (oa != null ? oa[0] : "NULL") + ", v1["); - v1.print(); - System.out.print("], v2["); - v2.print(); - System.out.print("], v3["); - v3.print(); - System.out.print("], c=" + c); - } - - @ForceInline - static MyValue1 setX(MyValue1 v, int x) { - return new MyValue1(x, v.y, v.z, v.o, v.oa, v.v1, v.v2, v.c); - } - - @ForceInline - static MyValue1 setY(MyValue1 v, long y) { - return new MyValue1(v.x, y, v.z, v.o, v.oa, v.v1, v.v2, v.c); - } - - @ForceInline - static MyValue1 setZ(MyValue1 v, short z) { - return new MyValue1(v.x, v.y, z, v.o, v.oa, v.v1, v.v2, v.c); - } - - @ForceInline - static MyValue1 setO(MyValue1 v, Integer o) { - return new MyValue1(v.x, v.y, v.z, o, v.oa, v.v1, v.v2, v.c); - } - - @ForceInline - static MyValue1 setOA(MyValue1 v, int[] oa) { - return new MyValue1(v.x, v.y, v.z, v.o, oa, v.v1, v.v2, v.c); - } - - @ForceInline - static MyValue1 setC(MyValue1 v, int c) { - return new MyValue1(v.x, v.y, v.z, v.o, v.oa, v.v1, v.v2, c); - } - - @ForceInline - static MyValue1 setV1(MyValue1 v, MyValue2 v1) { - return new MyValue1(v.x, v.y, v.z, v.o, v.oa, v1, v.v2, v.c); - } - - @ForceInline - static MyValue1 setV2(MyValue1 v, MyValue2 v2) { - return new MyValue1(v.x, v.y, v.z, v.o, v.oa, v.v1, v2, v.c); - } -} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue2.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue2.java deleted file mode 100644 index 0dadfa2cd1b..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue2.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2017, 2021, 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.valhalla.testframework; - -import jdk.test.lib.hotspot.ir_framework.*; - -final primitive class MyValue2Inline { - final double d; - final long l; - - @ForceInline - public MyValue2Inline(double d, long l) { - this.d = d; - this.l = l; - } - - @ForceInline - static MyValue2Inline setD(MyValue2Inline v, double d) { - return new MyValue2Inline(d, v.l); - } - - @ForceInline - static MyValue2Inline setL(MyValue2Inline v, long l) { - return new MyValue2Inline(v.d, l); - } - - @ForceInline - public static MyValue2Inline createDefault() { - return MyValue2Inline.default; - } - - @ForceInline - public static MyValue2Inline createWithFieldsInline(double d, long l) { - MyValue2Inline v = MyValue2Inline.createDefault(); - v = MyValue2Inline.setD(v, d); - v = MyValue2Inline.setL(v, l); - return v; - } -} - -public final primitive class MyValue2 extends MyAbstract { - final int x; - final byte y; - final MyValue2Inline v; - - @ForceInline - public MyValue2(int x, byte y, MyValue2Inline v) { - this.x = x; - this.y = y; - this.v = v; - } - - @ForceInline - public static MyValue2 createDefaultInline() { - return MyValue2.default; - } - - @ForceInline - public static MyValue2 createWithFieldsInline(int x, long y, double d) { - MyValue2 v = createDefaultInline(); - v = setX(v, x); - v = setY(v, (byte)x); - v = setV(v, MyValue2Inline.createWithFieldsInline(d, y)); - return v; - } - - @ForceInline - public static MyValue2 createWithFieldsInline(int x, double d) { - MyValue2 v = createDefaultInline(); - v = setX(v, x); - v = setY(v, (byte)x); - v = setV(v, MyValue2Inline.createWithFieldsInline(d, MyConstants.rL)); - return v; - } - - @DontInline - public static MyValue2 createWithFieldsDontInline(int x, double d) { - MyValue2 v = createDefaultInline(); - v = setX(v, x); - v = setY(v, (byte)x); - v = setV(v, MyValue2Inline.createWithFieldsInline(d, MyConstants.rL)); - return v; - } - - @ForceInline - public long hash() { - return x + y + (long)v.d + v.l; - } - - @DontInline - public long hashInterpreted() { - return x + y + (long)v.d + v.l; - } - - @ForceInline - public void print() { - System.out.print("x=" + x + ", y=" + y + ", d=" + v.d + ", l=" + v.l); - } - - @ForceInline - static MyValue2 setX(MyValue2 v, int x) { - return new MyValue2(x, v.y, v.v); - } - - @ForceInline - static MyValue2 setY(MyValue2 v, byte y) { - return new MyValue2(v.x, y, v.v); - } - - @ForceInline - static MyValue2 setV(MyValue2 v, MyValue2Inline vi) { - return new MyValue2(v.x, v.y, vi); - } -} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue3.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue3.java deleted file mode 100644 index f9742aefd0d..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue3.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (c) 2017, 2021, 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.valhalla.testframework; - -import jdk.test.lib.hotspot.ir_framework.*; -import jdk.test.lib.Asserts; -import jdk.test.lib.Utils; - -final primitive class MyValue3Inline { - final float f7; - final double f8; - - @ForceInline - public MyValue3Inline(float f7, double f8) { - this.f7 = f7; - this.f8 = f8; - } - - @ForceInline - static MyValue3Inline setF7(MyValue3Inline v, float f7) { - return new MyValue3Inline(f7, v.f8); - } - - @ForceInline - static MyValue3Inline setF8(MyValue3Inline v, double f8) { - return new MyValue3Inline(v.f7, f8); - } - - @ForceInline - public static MyValue3Inline createDefault() { - return MyValue3Inline.default; - } - - @ForceInline - public static MyValue3Inline createWithFieldsInline(float f7, double f8) { - MyValue3Inline v = createDefault(); - v = setF7(v, f7); - v = setF8(v, f8); - return v; - } -} - -// Inline type definition to stress test return of an inline type in registers -// (uses all registers of calling convention on x86_64) -public final primitive class MyValue3 extends MyAbstract { - final char c; - final byte bb; - final short s; - final int i; - final long l; - final Object o; - final float f1; - final double f2; - final float f3; - final double f4; - final float f5; - final double f6; - final MyValue3Inline v1; - - @ForceInline - public MyValue3(char c, byte bb, short s, int i, long l, Object o, - float f1, double f2, float f3, double f4, float f5, double f6, - MyValue3Inline v1) { - this.c = c; - this.bb = bb; - this.s = s; - this.i = i; - this.l = l; - this.o = o; - this.f1 = f1; - this.f2 = f2; - this.f3 = f3; - this.f4 = f4; - this.f5 = f5; - this.f6 = f6; - this.v1 = v1; - } - - @ForceInline - static MyValue3 setC(MyValue3 v, char c) { - return new MyValue3(c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setBB(MyValue3 v, byte bb) { - return new MyValue3(v.c, bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setS(MyValue3 v, short s) { - return new MyValue3(v.c, v.bb, s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setI(MyValue3 v, int i) { - return new MyValue3(v.c, v.bb, v.s, i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setL(MyValue3 v, long l) { - return new MyValue3(v.c, v.bb, v.s, v.i, l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setO(MyValue3 v, Object o) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setF1(MyValue3 v, float f1) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setF2(MyValue3 v, double f2) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setF3(MyValue3 v, float f3) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setF4(MyValue3 v, double f4) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setF5(MyValue3 v, float f5) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setF6(MyValue3 v, double f6) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, f6, v.v1); - } - - @ForceInline - static MyValue3 setV1(MyValue3 v, MyValue3Inline v1) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v1); - } - - @ForceInline - public static MyValue3 createDefault() { - return MyValue3.default; - } - - @ForceInline - public static MyValue3 create() { - java.util.Random r = Utils.getRandomInstance(); - MyValue3 v = createDefault(); - v = setC(v, (char)r.nextInt()); - v = setBB(v, (byte)r.nextInt()); - v = setS(v, (short)r.nextInt()); - v = setI(v, r.nextInt()); - v = setL(v, r.nextLong()); - v = setO(v, new Object()); - v = setF1(v, r.nextFloat()); - v = setF2(v, r.nextDouble()); - v = setF3(v, r.nextFloat()); - v = setF4(v, r.nextDouble()); - v = setF5(v, r.nextFloat()); - v = setF6(v, r.nextDouble()); - v = setV1(v, MyValue3Inline.createWithFieldsInline(r.nextFloat(), r.nextDouble())); - return v; - } - - @DontInline - public static MyValue3 createDontInline() { - return create(); - } - - @ForceInline - public static MyValue3 copy(MyValue3 other) { - MyValue3 v = createDefault(); - v = setC(v, other.c); - v = setBB(v, other.bb); - v = setS(v, other.s); - v = setI(v, other.i); - v = setL(v, other.l); - v = setO(v, other.o); - v = setF1(v, other.f1); - v = setF2(v, other.f2); - v = setF3(v, other.f3); - v = setF4(v, other.f4); - v = setF5(v, other.f5); - v = setF6(v, other.f6); - v = setV1(v, other.v1); - return v; - } - - @DontInline - public void verify(MyValue3 other) { - Asserts.assertEQ(c, other.c); - Asserts.assertEQ(bb, other.bb); - Asserts.assertEQ(s, other.s); - Asserts.assertEQ(i, other.i); - Asserts.assertEQ(l, other.l); - Asserts.assertEQ(o, other.o); - Asserts.assertEQ(f1, other.f1); - Asserts.assertEQ(f2, other.f2); - Asserts.assertEQ(f3, other.f3); - Asserts.assertEQ(f4, other.f4); - Asserts.assertEQ(f5, other.f5); - Asserts.assertEQ(f6, other.f6); - Asserts.assertEQ(v1.f7, other.v1.f7); - Asserts.assertEQ(v1.f8, other.v1.f8); - } - - @ForceInline - public long hash() { - return c + - bb + - s + - i + - l + - o.hashCode() + - Float.hashCode(f1) + - Double.hashCode(f2) + - Float.hashCode(f3) + - Double.hashCode(f4) + - Float.hashCode(f5) + - Double.hashCode(f6) + - Float.hashCode(v1.f7) + - Double.hashCode(v1.f8); - } -} - diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue4.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue4.java deleted file mode 100644 index eb223519f07..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/MyValue4.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2017, 2021, 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.valhalla.testframework; - -import jdk.test.lib.hotspot.ir_framework.*; - -// Inline type definition with too many fields to return in registers -final primitive class MyValue4 extends MyAbstract { - final MyValue3 v1; - final MyValue3 v2; - - @ForceInline - public MyValue4(MyValue3 v1, MyValue3 v2) { - this.v1 = v1; - this.v2 = v2; - } - - @ForceInline - static MyValue4 setV1(MyValue4 v, MyValue3 v1) { - return new MyValue4(v1, v.v2); - } - - @ForceInline - static MyValue4 setV2(MyValue4 v, MyValue3 v2) { - return new MyValue4(v.v1, v2); - } - - @ForceInline - public static MyValue4 createDefault() { - return MyValue4.default; - } - - @ForceInline - public static MyValue4 create() { - MyValue4 v = createDefault(); - MyValue3 v1 = MyValue3.create(); - v = setV1(v, v1); - MyValue3 v2 = MyValue3.create(); - v = setV2(v, v2); - return v; - } - - public void verify(MyValue4 other) { - v1.verify(other.v1); - v2.verify(other.v2); - } - - @ForceInline - public long hash() { - return v1.hash() + v2.hash(); - } -} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/MyValueEmpty.java b/test/hotspot/jtreg/compiler/valhalla/testframework/MyValueEmpty.java deleted file mode 100644 index 5dd743a3c82..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/MyValueEmpty.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2020, 2021, 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.valhalla.testframework; - -public final primitive class MyValueEmpty extends MyAbstract { - public long hash() { return 0; } - - public MyValueEmpty copy(MyValueEmpty other) { return other; } -} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/NamedRectangle.java b/test/hotspot/jtreg/compiler/valhalla/testframework/NamedRectangle.java deleted file mode 100644 index 853edff5977..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/NamedRectangle.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2020, 2021, 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.valhalla.testframework; - -public class NamedRectangle { - Rectangle rect = new Rectangle(); - String name = ""; - - static int getP1X(NamedRectangle nr) { - return nr.rect - .p1 - .x; - } - - static Point getP1(NamedRectangle nr) { - return nr.rect - .p1; - } -} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/Point.java b/test/hotspot/jtreg/compiler/valhalla/testframework/Point.java deleted file mode 100644 index 31cd364437d..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/Point.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2020, 2021, 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.valhalla.testframework; - -public primitive class Point { - int x = 4; - int y = 7; -} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/Rectangle.java b/test/hotspot/jtreg/compiler/valhalla/testframework/Rectangle.java deleted file mode 100644 index 3ebe9f8f38e..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/Rectangle.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2020, 2021, 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.valhalla.testframework; - -public primitive class Rectangle { - Point p0 = new Point(); - Point p1 = new Point(); -} diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/SimpleInlineType.java b/test/hotspot/jtreg/compiler/valhalla/testframework/SimpleInlineType.java deleted file mode 100644 index decb480647f..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/SimpleInlineType.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2017, 2021, 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.valhalla.testframework; - -final primitive class SimpleInlineType { - final int x; - - private SimpleInlineType() { - x = 0; - } - - static SimpleInlineType create() { - return SimpleInlineType.default; - } -} - diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/examples/CheckExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckExample.java similarity index 97% rename from test/hotspot/jtreg/compiler/valhalla/testframework/examples/CheckExample.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckExample.java index 56c56a3aa6e..7ef1a653744 100644 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/examples/CheckExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckExample.java @@ -25,10 +25,10 @@ * @test * @summary Example test to use the new test framework. * @library /test/lib - * @run driver compiler.valhalla.testframework.examples.CheckExample + * @run driver jdk.test.lib.hotspot.ir_framework.examples.CheckExample */ -package compiler.valhalla.testframework.examples; +package jdk.test.lib.hotspot.ir_framework.examples; import jdk.test.lib.hotspot.ir_framework.*; diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/examples/RunExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/RunExample.java similarity index 97% rename from test/hotspot/jtreg/compiler/valhalla/testframework/examples/RunExample.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/examples/RunExample.java index ec6b2859de9..59fa60949d6 100644 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/examples/RunExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/RunExample.java @@ -25,10 +25,10 @@ * @test * @summary Example test to use the new test framework. * @library /test/lib - * @run driver compiler.valhalla.testframework.examples.RunExample + * @run driver jdk.test.lib.hotspot.ir_framework.examples.RunExample */ - -package compiler.valhalla.testframework.examples; + +package jdk.test.lib.hotspot.ir_framework.examples; import jdk.test.lib.hotspot.ir_framework.*; diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/examples/SimpleExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/SimpleExample.java similarity index 93% rename from test/hotspot/jtreg/compiler/valhalla/testframework/examples/SimpleExample.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/examples/SimpleExample.java index 446c38f80f3..94df2e068fc 100644 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/examples/SimpleExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/SimpleExample.java @@ -25,10 +25,10 @@ * @test * @summary Example test to use the new test framework. * @library /test/lib - * @run driver compiler.valhalla.testframework.examples.SimpleExample + * @run driver jdk.test.lib.hotspot.ir_framework.examples.SimpleExample */ - -package compiler.valhalla.testframework.examples; + +package jdk.test.lib.hotspot.ir_framework.examples; import jdk.test.lib.hotspot.ir_framework.*; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TEST.ROOT b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TEST.ROOT new file mode 100644 index 00000000000..13b866e68e3 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TEST.ROOT @@ -0,0 +1,3 @@ +# Minimal TEST.ROOT file to run the examples tests as if the examples would have been placed inside +# /test/hotspot/jtreg +external.lib.roots = ../../../../../../../.. diff --git a/test/hotspot/jtreg/compiler/valhalla/testframework/examples/TestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TestExample.java similarity index 95% rename from test/hotspot/jtreg/compiler/valhalla/testframework/examples/TestExample.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/examples/TestExample.java index 36bac2e5893..1e40a585c67 100644 --- a/test/hotspot/jtreg/compiler/valhalla/testframework/examples/TestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TestExample.java @@ -25,10 +25,10 @@ * @test * @summary Example test to use the new test framework. * @library /test/lib - * @run driver compiler.valhalla.testframework.examples.TestExample + * @run driver jdk.test.lib.hotspot.ir_framework.examples.TestExample */ - -package compiler.valhalla.testframework.examples; + +package jdk.test.lib.hotspot.ir_framework.examples; import jdk.test.lib.hotspot.ir_framework.*; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java index ec7144ff7be..4ac6121adee 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java @@ -52,13 +52,7 @@ public static void main(String[] args) { Asserts.assertTrue(e.getMessage().contains("noTestInHelper")); exceptionsCaught++; } - try { - TestFramework.runWithHelperClasses(BadHelperClasses.class, BadHelper.class); - } catch (Exception e) { - Asserts.assertTrue(e.getMessage().contains("Cannot use @Test annotation in helper class:")); - Asserts.assertTrue(e.getMessage().contains("noTestInHelper")); - exceptionsCaught++; - } + if (exceptionsCaught != 2) { throw new RuntimeException("Did not catch " + exceptionsCaught + " exceptions!"); } From c04904294eddfca835657343738a072f3492e48d Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 8 Mar 2021 11:45:23 +0100 Subject: [PATCH 041/131] small fixes and move remaining old tests to old_inlinetypes --- .../inlinetypes/ExampleTestNullableInlineTypes.java | 6 +++--- ...ld.java => ExampleTestUnloadedInlineTypeField.java} | 10 +++++----- .../TestNullableInlineTypes.java | 4 ++-- .../TestUnloadedInlineTypeField.java | 8 ++++---- .../jdk/test/lib/hotspot/ir_framework/Scenario.java | 6 ++++-- .../test/lib/hotspot/ir_framework/TestFramework.java | 7 ++++++- 6 files changed, 24 insertions(+), 17 deletions(-) rename test/hotspot/jtreg/compiler/valhalla/inlinetypes/{ExampleUnloadedInlineTypeField.java => ExampleTestUnloadedInlineTypeField.java} (92%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestNullableInlineTypes.java (99%) rename test/hotspot/jtreg/compiler/valhalla/{inlinetypes => old_inlinetypes}/TestUnloadedInlineTypeField.java (99%) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestNullableInlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestNullableInlineTypes.java index 1dc693a98b3..959ff95af88 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestNullableInlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestNullableInlineTypes.java @@ -42,9 +42,9 @@ public class ExampleTestNullableInlineTypes { public static void main(String[] args) { Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; - scenarios[3] = new Scenario(3, "-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"); - scenarios[4] = new Scenario(4, "-XX:-MonomorphicArrayCheck"); - TestFramework testFramework = new TestFramework(TestNullableInlineTypes.class); + scenarios[3].addFlags("-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"); + scenarios[4].addFlags("-XX:-MonomorphicArrayCheck"); + TestFramework testFramework = new TestFramework(ExampleTestNullableInlineTypes.class); testFramework.addScenarios(scenarios) .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class) .start(); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleUnloadedInlineTypeField.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestUnloadedInlineTypeField.java similarity index 92% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleUnloadedInlineTypeField.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestUnloadedInlineTypeField.java index 8fb9d386f81..1f33c2ecb5f 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleUnloadedInlineTypeField.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestUnloadedInlineTypeField.java @@ -26,10 +26,10 @@ * @key randomness * @summary Test the handling of fields of unloaded inline classes. * @library /test/lib - * @compile MyConstants.java - * @run driver compiler.valhalla.testframework.ExampleTestUnloadedInlineTypeField + * @compile InlineTypes.java + * @run driver compiler.valhalla.inlinetypes.ExampleTestUnloadedInlineTypeField */ -package compiler.valhalla.testframework; +package compiler.valhalla.inlinetypes; import jdk.test.lib.Asserts; import jdk.test.lib.hotspot.ir_framework.*; @@ -57,7 +57,7 @@ static final primitive class MyValue1 { final int foo; MyValue1() { - foo = MyConstants.rI; + foo = InlineTypes.rI; } } @@ -89,7 +89,7 @@ public void test1_verifier(TestInfo info) { test1(null); } else { MyValue1Holder holder = new MyValue1Holder(); - Asserts.assertEQ(test1(holder), MyConstants.rI); + Asserts.assertEQ(test1(holder), InlineTypes.rI); } } } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNullableInlineTypes.java similarity index 99% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNullableInlineTypes.java index a9d68961460..98ab9441294 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNullableInlineTypes.java @@ -46,8 +46,8 @@ public class TestNullableInlineTypes extends InlineTypeTest { @Override public String[] getExtraVMParameters(int scenario) { switch (scenario) { - case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"}; - case 4: return new String[] {"-XX:-MonomorphicArrayCheck"}; + case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"}; + case 4: return new String[] {"-XX:-MonomorphicArrayCheck"}; } return null; } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnloadedInlineTypeField.java similarity index 99% rename from test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java rename to test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnloadedInlineTypeField.java index a6043fcc1a7..d5f7e803ae5 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java +++ b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnloadedInlineTypeField.java @@ -51,10 +51,10 @@ public static void main(String[] args) throws Throwable { } static final String[][] scenarios = { - {}, - {"-XX:InlineFieldMaxFlatSize=0"}, - {"-XX:+PatchALot"}, - {"-XX:InlineFieldMaxFlatSize=0", "-XX:+PatchALot"} + {}, + {"-XX:InlineFieldMaxFlatSize=0"}, + {"-XX:+PatchALot"}, + {"-XX:InlineFieldMaxFlatSize=0", "-XX:+PatchALot"} }; @Override diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java index 90534d81ada..7b692128a52 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java @@ -59,8 +59,10 @@ public Scenario(int index, String... flags) { } } - public void addFlag(String flag) { - flags.add(flag); + public void addFlags(String... flags) { + if (flags != null) { + this.flags.addAll(Arrays.asList(flags)); + } } public List getFlags() { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index f3f077a2e76..c75f53c3d34 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -257,9 +257,15 @@ private void start(Scenario scenario) { return; } + if (scenario != null) { + System.out.println("Scenario #" + scenario.getIndex() + " - [" + String.join(",", scenario.getFlags()) + "]"); + } + System.out.println("Run Flag VM:"); String flagVMOutput = runFlagVM(); List testVMFlags = getTestVMFlags(flagVMOutput); + System.out.println("Run Test VM:"); runTestVM(scenario, testVMFlags); + System.out.println(); } private String runFlagVM() { @@ -359,7 +365,6 @@ private List prepareTestVMFlags(Scenario scenario, List testVMfl cmds.addAll(Arrays.asList(jtregVMFlags)); } if (scenario != null) { - System.out.println("Running Scenario #" + scenario.getIndex() + " - [" + String.join(",", scenario.getFlags()) + "]"); cmds.addAll(scenario.getFlags()); } cmds.addAll(testVMflags); From 5b2401ca52c8d5c9d21f003acd5052e8267f3287 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 9 Mar 2021 08:44:40 +0100 Subject: [PATCH 042/131] Add new ClassFileInstaller --- .../jdk/test/lib/util/ClassFileInstaller.java | 290 ++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 test/lib/jdk/test/lib/util/ClassFileInstaller.java diff --git a/test/lib/jdk/test/lib/util/ClassFileInstaller.java b/test/lib/jdk/test/lib/util/ClassFileInstaller.java new file mode 100644 index 00000000000..96f0db0989a --- /dev/null +++ b/test/lib/jdk/test/lib/util/ClassFileInstaller.java @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2016, 2021, 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 jdk.test.lib.util; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * Dump a class file for a class on the class path in the current directory, or + * in the specified JAR file. This class is usually used when you build a class + * from a test library, but want to use this class in a sub-process. + * + * For example, to build the following library class: + * test/lib/sun/hotspot/WhiteBox.java + * + * You would use the following tags: + * + * @library /test/lib + * @build sun.hotspot.WhiteBox + * + * JTREG would build the class file under + * ${JTWork}/classes/test/lib/sun/hotspot/WhiteBox.class + * + * With you run your main test class using "@run main MyMainClass", JTREG would setup the + * -classpath to include "${JTWork}/classes/test/lib/", so MyMainClass would be able to + * load the WhiteBox class. + * + * However, if you run a sub process, and do not wish to use the exact same -classpath, + * You can use ClassFileInstaller to ensure that WhiteBox is available in the current + * directory of your test: + * + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * + * Or, you can use the -jar option to store the class in the specified JAR file. If a relative + * path name is given, the JAR file would be relative to the current directory of + * + * @run driver ClassFileInstaller -jar myjar.jar sun.hotspot.WhiteBox + */ +public class ClassFileInstaller { + /** + * You can enable debug tracing of ClassFileInstaller by running JTREG with + * jtreg -DClassFileInstaller.debug=true ... + */ + public static boolean DEBUG = Boolean.getBoolean("ClassFileInstaller.debug"); + + /** + * @param args The names of the classes to dump + * @throws Exception + */ + public static void main(String... args) throws Exception { + if (args.length > 1 && args[0].equals("-jar")) { + if (args.length < 2) { + throw new RuntimeException("Usage: ClassFileInstaller \n" + + "where possible options include:\n" + + " -jar Write to the JAR file "); + } + String jarFile = args[1]; + String[] classes = addInnerClasses(args, 2); + writeJar_impl(jarFile, null, classes); + } else { + if (DEBUG) { + System.out.println("ClassFileInstaller: Writing to " + System.getProperty("user.dir")); + } + String[] classes = addInnerClasses(args, 0); + for (String cls : classes) { + writeClassToDisk(cls); + } + } + } + + // Add commonly used inner classes that are often omitted by mistake. Currently + // we support only sun.hotspot.WhiteBox$WhiteBoxPermission. See JDK-8199290 + private static String[] addInnerClasses(String[] classes, int startIdx) { + boolean seenWB = false; + boolean seenWBInner = false; + final String wb = "sun.hotspot.WhiteBox"; + final String wbInner = "sun.hotspot.WhiteBox$WhiteBoxPermission"; + + ArrayList list = new ArrayList<>(); + + for (int i = startIdx; i < classes.length; i++) { + String cls = classes[i]; + list.add(cls); + switch (cls) { + case wb: seenWB = true; break; + case wbInner: seenWBInner = true; break; + } + } + if (seenWB && !seenWBInner) { + list.add(wbInner); + } + + String[] array = new String[list.size()]; + list.toArray(array); + return array; + } + + public static class Manifest { + private InputStream in; + + private Manifest(InputStream in) { + this.in = in; + } + + static Manifest fromSourceFile(String fileName) throws Exception { + String pathName = System.getProperty("test.src") + File.separator + fileName; + return new Manifest(new FileInputStream(pathName)); + } + + // Example: + // String manifest = "Premain-Class: RedefineClassHelper\n" + + // "Can-Redefine-Classes: true\n"; + // ClassFileInstaller.writeJar("redefineagent.jar", + // ClassFileInstaller.Manifest.fromString(manifest), + // "RedefineClassHelper"); + static Manifest fromString(String manifest) throws Exception { + return new Manifest(new ByteArrayInputStream(manifest.getBytes())); + } + + public InputStream getInputStream() { + return in; + } + } + + private static void writeJar_impl(String jarFile, Manifest manifest, String classes[]) throws Exception { + if (DEBUG) { + System.out.println("ClassFileInstaller: Writing to " + getJarPath(jarFile)); + } + + (new File(jarFile)).delete(); + FileOutputStream fos = new FileOutputStream(jarFile); + ZipOutputStream zos = new ZipOutputStream(fos); + + // The manifest must be the first or second entry. See comments in JarInputStream + // constructor and JDK-5046178. + if (manifest != null) { + writeToDisk(zos, "META-INF/MANIFEST.MF", manifest.getInputStream()); + } + + for (String cls : classes) { + writeClassToDisk(zos, cls); + } + + zos.close(); + fos.close(); + } + + /* + * You can call ClassFileInstaller.writeJar() from your main test class instead of + * using "@run ClassFileInstaller -jar ...". E.g., + * + * String jarPath = ClassFileInstaller.getJarPath("myjar.jar", "sun.hotspot.WhiteBox") + * + * If you call this API, make sure you build ClassFileInstaller with the following tags: + * + * @library testlibrary + * @build ClassFileInstaller + */ + public static String writeJar(String jarFile, String... classes) throws Exception { + classes = addInnerClasses(classes, 0); + writeJar_impl(jarFile, null, classes); + return getJarPath(jarFile); + } + + public static String writeJar(String jarFile, Manifest manifest, String... classes) throws Exception { + classes = addInnerClasses(classes, 0); + writeJar_impl(jarFile, manifest, classes); + return getJarPath(jarFile); + } + + /** + * This returns the absolute path to the file specified in "@ClassFileInstaller -jar myjar.jar", + * In your test program, instead of using the JAR file name directly: + * + * String jarPath = "myjar.jar"; + * + * you should call this function, like: + * + * String jarPath = ClassFileInstaller.getJarPath("myjar.jar") + * + * The reasons are: + * (1) Using absolute path makes it easy to cut-and-paste from the JTR file and rerun your + * test in any directory. + * (2) In the future, we may make the JAR file name unique to avoid clobbering + * during parallel JTREG execution. + * + */ + public static String getJarPath(String jarFileName) { + return new File(jarFileName).getAbsolutePath(); + } + + public static void writeClassToDisk(String className) throws Exception { + writeClassToDisk((ZipOutputStream)null, className); + } + private static void writeClassToDisk(ZipOutputStream zos, String className) throws Exception { + writeClassToDisk(zos, className, ""); + } + + public static void writeClassToDisk(String className, String prependPath) throws Exception { + writeClassToDisk(null, className, prependPath); + } + private static void writeClassToDisk(ZipOutputStream zos, String className, String prependPath) throws Exception { + ClassLoader cl = ClassFileInstaller.class.getClassLoader(); + + // Convert dotted class name to a path to a class file + String pathName = className.replace('.', '/').concat(".class"); + InputStream is = cl.getResourceAsStream(pathName); + if (is == null) { + throw new RuntimeException("Failed to find " + pathName); + } + if (prependPath.length() > 0) { + pathName = prependPath + "/" + pathName; + } + writeToDisk(zos, pathName, is); + } + + public static void writeClassToDisk(String className, byte[] bytecode) throws Exception { + writeClassToDisk(null, className, bytecode); + } + private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode) throws Exception { + writeClassToDisk(zos, className, bytecode, ""); + } + + public static void writeClassToDisk(String className, byte[] bytecode, String prependPath) throws Exception { + writeClassToDisk(null, className, bytecode, prependPath); + } + private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode, String prependPath) throws Exception { + // Convert dotted class name to a path to a class file + String pathName = className.replace('.', '/').concat(".class"); + if (prependPath.length() > 0) { + pathName = prependPath + "/" + pathName; + } + writeToDisk(zos, pathName, new ByteArrayInputStream(bytecode)); + } + + private static void writeToDisk(ZipOutputStream zos, String pathName, InputStream is) throws Exception { + if (DEBUG) { + System.out.println("ClassFileInstaller: Writing " + pathName); + } + if (zos != null) { + ZipEntry ze = new ZipEntry(pathName); + zos.putNextEntry(ze); + byte[] buf = new byte[1024]; + int len; + while ((len = is.read(buf))>0){ + zos.write(buf, 0, len); + } + } else { + // Create the class file's package directory + Path p = Paths.get(pathName); + if (pathName.contains("/")) { + Files.createDirectories(p.getParent()); + } + // Create the class file + Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING); + } + is.close(); + } +} From db7c4093e01801aa0a8637c796e95e2be640999e Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 9 Mar 2021 17:42:10 +0100 Subject: [PATCH 043/131] Change encoding passing from flag and test VM to driver VM from using stdout to using a dedicated socket, added runWithFlags to interface, show compilation on IR failure --- .../ir_framework/IREncodingPrinter.java | 2 +- .../lib/hotspot/ir_framework/IRMatcher.java | 49 ++-- .../hotspot/ir_framework/TestFramework.java | 252 +++++++++++++----- .../ir_framework/TestFrameworkExecution.java | 22 +- .../TestFrameworkPrepareFlags.java | 11 +- .../ir_framework/tests/TestBadFormat.java | 2 +- .../ir_framework/tests/TestIRMatching.java | 43 ++- .../ir_framework/tests/TestSanity.java | 18 +- 8 files changed, 284 insertions(+), 115 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java index e71d2ae0cad..3678d1feac7 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java @@ -278,7 +278,7 @@ private String failAt() { public void emit() { output.append(END); - System.out.println(output.toString()); + TestFrameworkSocket.write(output.toString(), "IR rule application encoding"); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java index 8fa9ae6f7c7..4a5a1095bc8 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java @@ -29,45 +29,48 @@ import java.util.regex.Pattern; class IRMatcher { - private static final boolean PRINT_GRAPH = true; + private static final boolean PRINT_IR_ENCODING = Boolean.parseBoolean(System.getProperty("PrintIREncoding", "false")); private final Map irRulesMap; - private final Map compilations; + private final Map compilations; private final Class testClass; private final Map> fails; private Method method; // Current method to which rules are applied private IR irAnno; // Current IR annotation that is processed. private int irRuleIndex; // Current IR rule index; - public IRMatcher(String output, Class testClass) { + public IRMatcher(String output, String irEncoding, Class testClass) { this.irRulesMap = new HashMap<>(); this.compilations = new LinkedHashMap<>(); this.fails = new HashMap<>(); this.testClass = testClass; - parseIREncoding(output); + parseIREncoding(irEncoding); + if (TestFramework.VERBOSE || PRINT_IR_ENCODING) { + System.out.println("Read IR encoding from test VM:"); + System.out.println(irEncoding); + } splitCompilations(output, testClass); } - private void parseIREncoding(String output) { + private void parseIREncoding(String irEncoding) { String patternString = "(?<=" + IREncodingPrinter.START + "\\R)[\\s\\S]*(?=" + IREncodingPrinter.END + ")"; Pattern pattern = Pattern.compile(patternString); - Matcher matcher = pattern.matcher(output); + Matcher matcher = pattern.matcher(irEncoding); - while (matcher.find()) { - String[] lines = matcher.group(0).split("\\R"); - // Skip first line containing information about the format only - for (int i = 1; i < lines.length; i++) { - String line = lines[i].trim(); - String[] splitComma = line.split(","); - if (splitComma.length < 2) { - throw new TestFrameworkException("Invalid IR match rule encoding"); - } - String testName = splitComma[0]; - Integer[] irRulesIdx = new Integer[splitComma.length - 1]; - for (int j = 1; j < splitComma.length; j++) { - irRulesIdx[j - 1] = Integer.valueOf(splitComma[j]); - } - irRulesMap.put(testName, irRulesIdx); + TestFramework.check(matcher.find(), "Did not find IR encoding"); + String[] lines = matcher.group(0).split("\\R"); + // Skip first line containing information about the format only + for (int i = 1; i < lines.length; i++) { + String line = lines[i].trim(); + String[] splitComma = line.split(","); + if (splitComma.length < 2) { + throw new TestFrameworkException("Invalid IR match rule encoding"); + } + String testName = splitComma[0]; + Integer[] irRulesIdx = new Integer[splitComma.length - 1]; + for (int j = 1; j < splitComma.length; j++) { + irRulesIdx[j - 1] = Integer.valueOf(splitComma[j]); } + irRulesMap.put(testName, irRulesIdx); } } @@ -99,7 +102,7 @@ private void splitCompilations(String output, Class testClass) { String shortMethodName = methodName.split("::")[1]; if (irRulesMap.containsKey(methodName.split("::")[1])) { String testOutput = output.substring(prev); - if (PRINT_GRAPH) { + if (TestFramework.VERBOSE) { System.out.println("\nGraph for " + methodName + "\n" + testOutput); } compilations.put(shortMethodName, testOutput); @@ -135,6 +138,8 @@ private void reportFailuresIfAny() { int failures = 0; for (Map.Entry> entry : fails.entrySet()) { Method method = entry.getKey(); + System.out.println("\n>>> Compilation of " + method + ":"); + System.out.println(compilations.get(method.getName())); List list = entry.getValue(); builder.append("- Method \"").append(method).append("\":\n"); failures += list.size(); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index c75f53c3d34..8cc49f3bb6f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -29,10 +29,12 @@ import jdk.test.lib.util.ClassFileInstaller; import sun.hotspot.WhiteBox; -import java.io.PrintWriter; -import java.io.StringWriter; +import java.io.*; import java.lang.reflect.Method; +import java.net.ServerSocket; +import java.net.Socket; import java.util.*; +import java.util.concurrent.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -56,8 +58,10 @@ public class TestFramework { private List> helperClasses = null; private List scenarios = null; + private List flags = new ArrayList<>(); private final Class testClass; private static String lastVMOutput; + private TestFrameworkSocket socket; public TestFramework(Class testClass) { TestRun.check(testClass != null, "Test class cannot be null"); @@ -78,6 +82,17 @@ public static void run(Class testClass) { framework.start(); } + public static void runWithFlags(String... flags) { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + runWithFlags(walker.getCallerClass(), flags); + } + + public static void runWithFlags(Class testClass, String... flags) { + TestFramework framework = new TestFramework(testClass); + framework.addFlags(flags); + framework.start(); + } + public static void runWithHelperClasses(Class testClass, Class... helperClasses) { TestFramework framework = new TestFramework(testClass); framework.addHelperClasses(helperClasses); @@ -95,6 +110,12 @@ public static void runWithScenarios(Class testClass, Scenario... scenarios) { framework.start(); } + public TestFramework addFlags(String... flags) { + TestRun.check(flags != null && Arrays.stream(flags).noneMatch(Objects::isNull), "A flag cannot be null"); + this.flags.addAll(Arrays.asList(flags)); + return this; + } + public TestFramework addHelperClasses(Class... helperClasses) { TestRun.check(helperClasses != null && Arrays.stream(helperClasses).noneMatch(Objects::isNull), "A Helper class cannot be null"); if (this.helperClasses == null) { @@ -119,24 +140,22 @@ public TestFramework addScenarios(Scenario... scenarios) { } public void clear() { - clearHelperClasses(); - clearScenarios(); - } - - public void clearHelperClasses() { - this.helperClasses = null; - } - - public void clearScenarios() { - this.scenarios = null; + flags.clear(); + helperClasses = null; + scenarios = null; } public void start() { installWhiteBox(); - if (scenarios == null) { - start(null); - } else { - startWithScenarios(); + socket = new TestFrameworkSocket(); + try { + if (scenarios == null) { + start(null); + } else { + startWithScenarios(); + } + } finally { + socket.close(); } } @@ -226,7 +245,7 @@ private void startWithScenarios() { if (!exceptionMap.isEmpty()) { StringBuilder builder = new StringBuilder("The following scenarios have failed: #"); builder.append(String.join(", #", exceptionMap.keySet())).append("\n\n"); - for (Map.Entry entry: exceptionMap.entrySet()) { + for (Map.Entry entry : exceptionMap.entrySet()) { String title = "Stacktrace for Scenario #" + entry.getKey(); builder.append(title).append("\n").append("=".repeat(title.length())).append("\n"); Exception e = entry.getValue(); @@ -246,30 +265,39 @@ private void startWithScenarios() { } /** - * Execute a separate "flag" VM with White Box access to determine all test VM flags. The flag VM emits an encoding - * of all required flags for the test VM to the standard output. Once the flag VM exits, this driver VM parses the + * Execute a separate "flag" VM with White Box access to determine all test VM flags. The flag VM sends an encoding of + * all required flags for the test VM to the driver VM over a socket. Once the flag VM exits, this driver VM parses the * test VM flags, which also determine if IR matching should be done, and then starts the test VM to execute all tests. */ private void start(Scenario scenario) { if (scenario != null && !scenario.isEnabled()) { - System.out.println("Disabled scenario #" + scenario.getIndex() + "! This scenario is not present in set flag -DScenarios " + - "and is therefore not executed."); + System.out.println("Disabled scenario #" + scenario.getIndex() + "! This scenario is not present in set flag " + + "-DScenarios and is therefore not executed."); return; } + // Use TestFramework flags and scenario flags for new VMs. + List additionalFlags = new ArrayList<>(flags); if (scenario != null) { - System.out.println("Scenario #" + scenario.getIndex() + " - [" + String.join(",", scenario.getFlags()) + "]"); + List scenarioFlags = scenario.getFlags(); + String scenarioFlagsString = scenarioFlags.isEmpty() ? "" : " - [" + String.join(", ", scenarioFlags) + "]"; + System.out.println("Scenario #" + scenario.getIndex() + scenarioFlagsString + ":"); + additionalFlags.addAll(scenarioFlags); } System.out.println("Run Flag VM:"); - String flagVMOutput = runFlagVM(); - List testVMFlags = getTestVMFlags(flagVMOutput); - System.out.println("Run Test VM:"); - runTestVM(scenario, testVMFlags); + runFlagVM(additionalFlags); + String flagsString = additionalFlags.isEmpty() ? "" : " - [" + String.join(", ", additionalFlags) + "]"; + System.out.println("Run Test VM" + flagsString + ":"); + runTestVM(additionalFlags); + if (scenario != null) { + scenario.setVMOutput(lastVMOutput); + } System.out.println(); } - private String runFlagVM() { - ArrayList cmds = prepareFlagVMFlags(); + private void runFlagVM(List additionalFlags) { + ArrayList cmds = prepareFlagVMFlags(additionalFlags); + socket.start(); OutputAnalyzer oa; try { // Run "flag" VM with White Box access to determine the test VM flags and if IR verification should be done. @@ -278,14 +306,13 @@ private String runFlagVM() { throw new TestRunException("Failed to execute TestFramework flag VM", e); } checkFlagVMExitCode(oa); - return oa.getOutput(); } /** - * The "flag" VM needs White Box access to prepare all test VM flags. It emits these as encoding to the standard output. - * This driver VM then parses the flags and adds them to the test VM. + * The "flag" VM needs White Box access to prepare all test VM flags. It sends these as encoding over a socket to the + * driver VM which afterwards parses the flags and adds them to the test VM. */ - private ArrayList prepareFlagVMFlags() { + private ArrayList prepareFlagVMFlags(List additionalFlags) { ArrayList cmds = new ArrayList<>(); cmds.add("-Dtest.jdk=" + Utils.TEST_JDK); cmds.add("-cp"); @@ -293,6 +320,8 @@ private ArrayList prepareFlagVMFlags() { cmds.add("-Xbootclasspath/a:."); cmds.add("-XX:+UnlockDiagnosticVMOptions"); cmds.add("-XX:+WhiteBoxAPI"); + // TestFramework and scenario flags might have an influence on the later used test VM flags. Add them as well. + cmds.addAll(additionalFlags); cmds.add(TestFrameworkPrepareFlags.class.getCanonicalName()); cmds.add(testClass.getCanonicalName()); return cmds; @@ -307,30 +336,18 @@ private void checkFlagVMExitCode(OutputAnalyzer oa) { } if (exitCode != 0) { - System.out.println("--- OUTPUT TestFramework flag VM ---"); + System.err.println("--- OUTPUT TestFramework flag VM ---"); System.err.println(flagVMOutput); throw new RuntimeException("\nTestFramework flag VM exited with " + exitCode); } } - /** - * Parse the test VM flags as prepared by the flag VM. Additionally check the property flag DPrintValidIRRules to determine - * if IR matching should be done or not. - */ - private List getTestVMFlags(String flagVMOutput) { - String patternString = "(?<=" + TestFramework.TEST_VM_FLAGS_START + "\\R)" - + "(.*DPrintValidIRRules=(true|false).*)\\R" + "(?=" + IREncodingPrinter.END + ")"; - Pattern pattern = Pattern.compile(patternString); - Matcher matcher = pattern.matcher(flagVMOutput); - if (!matcher.find()) { - throw new TestFrameworkException("Invalid flag encoding emitted by flag VM"); + private void runTestVM(List additionalFlags) { + List cmds = prepareTestVMFlags(additionalFlags); + if (VERIFY_IR) { + // We only need the socket if we are doing IR verification. + socket.start(); } - VERIFY_IR = Boolean.parseBoolean(matcher.group(2)); - return new ArrayList<>(Arrays.asList(matcher.group(1).split(TEST_VM_FLAGS_DELIMITER))); - } - - private void runTestVM(Scenario scenario, List testVMflags) { - List cmds = prepareTestVMFlags(scenario, testVMflags); OutputAnalyzer oa; try { // Calls 'main' of TestFrameworkExecution to run all specified tests with commands 'cmds'. @@ -338,21 +355,19 @@ private void runTestVM(Scenario scenario, List testVMflags) { // Java options in prepareTestVMFlags(). oa = ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder(cmds)); } catch (Exception e) { - throw new TestFrameworkException("Error while executing Test VM", e); + fail("Error while executing Test VM", e); + return; } lastVMOutput = oa.getOutput(); checkTestVMExitCode(oa); - if (scenario != null) { - scenario.setVMOutput(lastVMOutput); - } if (VERIFY_IR) { - IRMatcher irMatcher = new IRMatcher(lastVMOutput, testClass); + IRMatcher irMatcher = new IRMatcher(lastVMOutput, socket.getOutput(), testClass); irMatcher.applyRules(); } } - private List prepareTestVMFlags(Scenario scenario, List testVMflags) { + private List prepareTestVMFlags(List additionalFlags) { ArrayList cmds = new ArrayList<>(); // Need White Box access in test VM. @@ -364,10 +379,8 @@ private List prepareTestVMFlags(Scenario scenario, List testVMfl if (!PREFER_COMMAND_LINE_FLAGS) { cmds.addAll(Arrays.asList(jtregVMFlags)); } - if (scenario != null) { - cmds.addAll(scenario.getFlags()); - } - cmds.addAll(testVMflags); + cmds.addAll(additionalFlags); + cmds.addAll(getTestVMFlags()); if (PREFER_COMMAND_LINE_FLAGS) { // Prefer flags set via the command line over the ones set by scenarios. @@ -382,6 +395,24 @@ private List prepareTestVMFlags(Scenario scenario, List testVMfl return cmds; } + /** + * Parse the test VM flags as prepared by the flag VM. Additionally check the property flag DPrintValidIRRules to determine + * if IR matching should be done or not. + */ + private List getTestVMFlags() { + String patternString = "(?<=" + TestFramework.TEST_VM_FLAGS_START + "\\R)" + "(.*DPrintValidIRRules=(true|false).*)\\R" + "(?=" + IREncodingPrinter.END + ")"; + Pattern pattern = Pattern.compile(patternString); + String flags = socket.getOutput(); + if (VERBOSE) { + System.out.println("Read sent data from flag VM from socket:"); + System.out.println(flags); + } + Matcher matcher = pattern.matcher(flags); + check(matcher.find(), "Invalid flag encoding emitted by flag VM"); + VERIFY_IR = Boolean.parseBoolean(matcher.group(2)); + return new ArrayList<>(Arrays.asList(matcher.group(1).split(TEST_VM_FLAGS_DELIMITER))); + } + private static void checkTestVMExitCode(OutputAnalyzer oa) { final int exitCode = oa.getExitValue(); if (VERBOSE && exitCode == 0) { @@ -402,13 +433,110 @@ private static void throwTestException(OutputAnalyzer oa, int exitCode) { TestFramework.check(matcher.find(), "Must find violation matches"); throw new TestFormatException("\n\n" + matcher.group()); } else { - throw new TestRunException("\nTestFramework runner VM exited with " + exitCode + "\n\nError Output:\n" + stdErr); + System.err.println("--- Standard Output TestFramework test VM ---"); + System.err.println(oa.getStdout()); + throw new TestRunException("\nTestFramework test VM exited with " + exitCode + "\n\nError Output:\n" + stdErr); } } static void check(boolean test, String failureMessage) { if (!test) { - throw new TestFrameworkException("Internal TestFrameworkExecution exception - please file a bug:\n" + failureMessage); + fail(failureMessage); + } + } + + static void fail(String failureMessage) { + throw new TestFrameworkException("Internal Test Framework exception - please file a bug:\n" + failureMessage); + } + + static void fail(String failureMessage, Exception e) { + throw new TestFrameworkException("Internal Test Framework exception - please file a bug:\n" + failureMessage, e); + } +} + +/** + * Dedicated socket to send data from flag and test VM back to the driver VM. + */ +class TestFrameworkSocket { + private static final int SOCKET_PORT = 6672; + private static final String HOSTNAME = "localhost"; + + private FutureTask socketTask; + private Thread socketThread; + private ServerSocket serverSocket; + + TestFrameworkSocket() { + try { + serverSocket = new ServerSocket(SOCKET_PORT); + } catch (IOException e) { + TestFramework.fail("Server socket error", e); + } + } + + public void start() { + socketTask = initSocketTask(); + socketThread = new Thread(socketTask); + socketThread.start(); + } + + private FutureTask initSocketTask() { + return new FutureTask<>(() -> { + try (Socket clientSocket = serverSocket.accept(); + BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())) + ) { + StringBuilder builder = new StringBuilder(); + String next; + while ((next = in.readLine()) != null) { + builder.append(next).append("\n"); + } + return builder.toString(); + } catch (IOException e) { + TestFramework.fail("Server socket error", e); + return null; + } + }); + } + + public void close() { + try { + serverSocket.close(); + } catch (IOException e) { + TestFramework.fail("Could not close socket", e); + } + } + + public void checkTerminated() { + try { + socketThread.join(5000); + if (socketThread.isAlive()) { + serverSocket.close(); + TestFramework.fail("Socket thread was not terminated"); + } + } catch (InterruptedException | IOException e) { + TestFramework.fail("Socket thread was not closed", e); + } + } + + public static void write(String msg, String type) { + try (Socket socket = new Socket(HOSTNAME, SOCKET_PORT); + PrintWriter out = new PrintWriter(socket.getOutputStream(), true) + ) { + out.print(msg); + } catch (Exception e) { + TestFramework.fail("Failed to write to socket", e); + } + if (TestFramework.VERBOSE) { + System.out.println("Written " + type + " to socket:"); + System.out.println(msg); + } + } + + public String getOutput() { + try { + return socketTask.get(); + } catch (Exception e) { + TestFramework.fail("Could not read from socket task", e); + return null; } } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index edb52291e94..b19898e10c7 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -66,6 +66,7 @@ public class TestFrameworkExecution { private static final boolean DUMP_REPLAY = Boolean.parseBoolean(System.getProperty("DumpReplay", "false")); private static final boolean GC_AFTER = Boolean.parseBoolean(System.getProperty("GCAfter", "false")); private static final boolean SHUFFLE_TESTS = Boolean.parseBoolean(System.getProperty("ShuffleTests", "true")); + // Use separate flag as VERIFY_IR could have been set by user but due to other flags it was disabled by flag VM. private static final boolean PRINT_VALID_IR_RULES = Boolean.parseBoolean(System.getProperty("PrintValidIRRules", "false")); protected static final long PerMethodTrapLimit = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); protected static final boolean ProfileInterpreter = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); @@ -157,14 +158,23 @@ private static Class[] getHelperClasses(String[] args) { return helperClasses; } - // Only called by tests testing the framework itself. Accessed by reflection. Do not expose this to normal users. + // Only called by internal tests testing the framework itself. Accessed by reflection. Not exposed to normal users. private static void runTestsOnSameVM(Class testClass) { - if (testClass == null) { - StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - testClass = walker.getCallerClass(); + TestFrameworkSocket dummy = new TestFrameworkSocket(); + try { + if (PRINT_VALID_IR_RULES) { + // Need dummy socket to write to as we are not calling this method from TestFramework. + dummy.start(); + } + if (testClass == null) { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + testClass = walker.getCallerClass(); + } + TestFrameworkExecution framework = new TestFrameworkExecution(testClass); + framework.start(); + } finally { + dummy.close(); } - TestFrameworkExecution framework = new TestFrameworkExecution(testClass); - framework.start(); } private void start() { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java index b67dd378a82..71266333c35 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java @@ -26,7 +26,8 @@ import jdk.test.lib.Platform; import sun.hotspot.WhiteBox; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; class TestFrameworkPrepareFlags { @@ -76,7 +77,9 @@ private static String[] getVerifyFlags() { public static void main(String[] args) { String testClassName = args[0]; - System.out.println("Framework main(), about to run tests in class " + testClassName); + if (VERBOSE) { + System.out.println("TestFrameworkPrepareFlags main() called. Prepare test VM flags to run class " + testClassName); + } Class testClass; try { testClass = Class.forName(testClassName); @@ -90,9 +93,9 @@ public static void main(String[] args) { * Emit test VM flags to standard output to parse them from the TestFramework "driver" VM again which adds them to the test VM. */ private static void emitTestVMFlags(ArrayList flags) { - String info = TestFramework.TEST_VM_FLAGS_START + "\n" + String.join(TestFramework.TEST_VM_FLAGS_DELIMITER, flags) + String encoding = TestFramework.TEST_VM_FLAGS_START + "\n" + String.join(TestFramework.TEST_VM_FLAGS_DELIMITER, flags) + "\n" + TestFramework.TEST_VM_FLAGS_END; - System.out.println(info); + TestFrameworkSocket.write(encoding, "flag encoding"); } private static ArrayList prepareTestVmFlags(Class testClass) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java index e561039b74a..131698db4e2 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java @@ -379,7 +379,7 @@ public void negativeWarmup2() {} public void someTest3() {} @FailCount(2) // Negative warmup and invoke once - @Run(test = "someTest2", mode = RunMode.STANDALONE) + @Run(test = "someTest3", mode = RunMode.STANDALONE) @Warmup(-1) public void noWarmupAtInvokeOnce() {} } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java index 08755ab66df..cdf7cf581e3 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java @@ -26,12 +26,15 @@ import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +// Run with -DPrintIREncoding=true public class TestIRMatching { public static void main(String[] args) { @@ -43,18 +46,6 @@ public static void main(String[] args) { runWithArguments(GoodCount.class, "-XX:SuspendRetryCount=50"); runWithArguments(MultipleFailOnGood.class, "-XX:SuspendRetryCount=50"); - runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=50"); - findIrIds(TestFramework.getLastVMOutput(), "testMatchAllIf50", 0, 21); - findIrIds(TestFramework.getLastVMOutput(), "testMatchNoneIf50", -1, -1); - - runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=49"); - findIrIds(TestFramework.getLastVMOutput(), "testMatchAllIf50", 4, 6, 13, 18); - findIrIds(TestFramework.getLastVMOutput(), "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); - - runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=51"); - findIrIds(TestFramework.getLastVMOutput(), "testMatchAllIf50", 7, 12, 19, 21); - findIrIds(TestFramework.getLastVMOutput(), "testMatchNoneIf50", 4, 7, 11, 16, 20, 22); - String[] allocMatches = { "MyClass", "call,static wrapper for: _new_instance_Java" }; runCheck(BadFailOnConstraint.create(MultipleFailOnBad.class, "fail1()", 1, 1, "Store"), BadFailOnConstraint.create(MultipleFailOnBad.class, "fail1()", 1, 3, "Store"), @@ -181,6 +172,33 @@ public static void main(String[] args) { GoodFailOnConstraint.create(CheckCastArray.class, "array()", 3), BadFailOnConstraint.create(CheckCastArray.class, "arrayCopy(java.lang.Object[],java.lang.Class)", 1, "checkcast_arraycopy") ); + + // Redirect stdout to stream and then check if we find required IR encoding read from socket. + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos); + PrintStream old = System.out; + System.setOut(ps); + runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=50"); + System.out.flush(); + String output = baos.toString(); + baos.reset(); + findIrIds(output, "testMatchAllIf50", 0, 21); + findIrIds(output, "testMatchNoneIf50", -1, -1); + + runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=49"); + System.out.flush(); + output = baos.toString(); + baos.reset(); + findIrIds(output, "testMatchAllIf50", 4, 6, 13, 18); + findIrIds(output, "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); + + runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=51"); + System.out.flush(); + output = baos.toString(); + baos.reset(); + findIrIds(output, "testMatchAllIf50", 7, 12, 19, 21); + findIrIds(output, "testMatchNoneIf50", 4, 7, 11, 16, 20, 22); + System.setOut(old); } private static void runWithArguments(Class clazz, String... args) { @@ -230,7 +248,6 @@ private static void runFailOnTestsArgs(Constraint constraint, String... args) { TestFramework.runWithScenarios(constraint.getKlass(), scenario); // All constraints have the same class. shouldNotReach(); } catch (TestRunException e) { - System.out.println(e.getMessage()); constraint.checkConstraint(e); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java index e4adfa75b6f..f621d5b4f4d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java @@ -32,6 +32,8 @@ public class TestSanity { public static void main(String[] args) { TestFramework.run(); TestFramework.run(TestSanity.class); + TestFramework.runWithFlags("-XX:+TieredCompilation"); + TestFramework.runWithFlags(TestSanity.class, "-XX:SuspendRetryCount=51", "-XX:+UseTLAB"); TestFramework.runWithHelperClasses(TestSanity.class, HelperA.class); TestFramework.runWithHelperClasses(TestSanity.class, HelperA.class, HelperB.class); Scenario sDefault = new Scenario(0); @@ -46,16 +48,20 @@ public static void main(String[] args) { TestFramework.runWithScenarios(TestSanity.class, sDefault, s1, s2); TestFramework testFramework = new TestFramework(TestSanity.class); testFramework.start(); + testFramework.addFlags("-XX:SuspendRetryCount=54").start(); + testFramework.clear(); + testFramework.addFlags("-XX:SuspendRetryCount=55").addFlags("-XX:+UseTLAB").start(); + testFramework.clear(); testFramework.addHelperClasses(HelperA.class, HelperB.class).start(); - testFramework.clearHelperClasses(); + testFramework.clear(); testFramework.addHelperClasses(HelperA.class, HelperB.class).addHelperClasses(HelperC.class).start(); - testFramework.clearHelperClasses(); + testFramework.clear(); testFramework.addScenarios(sDefault).addScenarios(s1, s2).start(); - testFramework.clearScenarios(); - testFramework.addHelperClasses(HelperA.class).addScenarios(sDefault).start(); testFramework.clear(); - testFramework.addHelperClasses(HelperA.class).addScenarios(sDefault).addHelperClasses(HelperB.class, HelperC.class) - .addScenarios(s1, s2).start(); + testFramework.addHelperClasses(HelperA.class).addScenarios(sDefault).addFlags("-XX:+UseSuperWord").start(); + testFramework.clear(); + testFramework.addHelperClasses(HelperA.class).addFlags("-XX:+UseSuperWord", "-XX:+UseCompiler").addScenarios(sDefault) + .addHelperClasses(HelperB.class, HelperC.class).addScenarios(s1, s2).addFlags("-XX:+TieredCompilation").start(); } @Test From c833e85e88e055f730445fd3a308f76ba2b73aa3 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 10 Mar 2021 15:45:20 +0100 Subject: [PATCH 044/131] Add more Javadocs --- .../lib/hotspot/ir_framework/Scenario.java | 10 +- .../test/lib/hotspot/ir_framework/Test.java | 44 +++++ .../hotspot/ir_framework/TestFramework.java | 184 ++++++++++++++++-- .../ir_framework/TestFrameworkExecution.java | 4 +- .../ir_framework/tests/TestCompLevels.java | 2 +- .../ir_framework/tests/TestIRMatching.java | 2 +- .../ir_framework/tests/TestSanity.java | 1 + .../tests/TestWithHelperClasses.java | 6 +- 8 files changed, 226 insertions(+), 27 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java index 7b692128a52..071f4df0d20 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java @@ -35,7 +35,7 @@ public class Scenario { private final List flags; private final int index; boolean enabled; - private String vmOutput; + private String testVMOutput; static { if (!SCENARIOS.isEmpty()) { @@ -77,11 +77,11 @@ public boolean isEnabled() { return enabled; } - public void setVMOutput(String vmOutput) { - this.vmOutput = vmOutput; + public void setTestVMOutput(String testVMOutput) { + this.testVMOutput = testVMOutput; } - public String getVMOutput() { - return vmOutput; + public String getTestVMOutput() { + return testVMOutput; } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java index c8330bf5c3f..42fbab782fd 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java @@ -26,7 +26,51 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +/** + * Annotate all methods in your test class which the framework should test with {@code @Test}. + *

+ * Let {@code m} be a test method specifying the {@code @Test} annotation. If {@code m} is not part of a custom run test + * (an additional method specifying {@link Run} with (@code @Run(test = "m"))), then the framework invokes {@code m} in + * the following way: + *

    + *
  1. The framework warms {@code m} up for a predefined number of iterations (default is 2000) or any number + * specified by an additional {@link Warmup} iteration (could also be 0 which skips the warm-up completely). More + * information about the warm-up can be found in {@link Warmup}

  2. + *
  3. After the warm-up, the framework compiles {@code m} at the specified compilation level set by + * {@link Test#compLevel()} (default {@link CompLevel#C2}).

  4. + *
  5. The framework invokes {@code m} one more time to ensure that the compilation works.

  6. + *
  7. The framework checks any specified {@link IR} constraints. More information about IR matching can be + * found in {@link IR}.

  8. + *
+ * + *

+ * {@code m} has the following properties: + *

    + *
  • If {@code m} specifies no parameters, the framework can directly invoke it.

  • + *
  • If {@code m} specifies parameters, the framework needs to know how to call {@code m}. Use {@link Arguments} + * with {@link Argument} properties for each parameter to use some well-defined parameters. If the method requires + * a more specific argument value, use a custom run test (see {@link Run}).

  • + *
  • {@code m} is not inlined by the framework.

  • + *
  • Verification of the return value of {@code m} can only TODO

  • + *
+ * + *

+ * The following constraints must be met for a test method {@code m} specifying {@code @Test}: + *

    + *
  • {@code m} must be part of the test class. Using {@code @Test} in other classes is not allowed.

  • + *
  • {@code m} cannot have the same name as another {@code @Test} method. Method overloading is only allowed + * with other non-{@code @Test} methods.

  • + *
  • {@code m} cannot specify any compile command annotations ({@link ForceCompile}, {@link DontCompile}, {@link ForceInline}, {@link DontInline}).

  • + *
+ */ @Retention(RetentionPolicy.RUNTIME) public @interface Test { + /** + * Specify at which compilation level the framework should eventually compile the test method after an optional + * warmup period. + * + *

+ * Default if not specified in annotation: {@link CompLevel#C2}. + */ CompLevel compLevel() default CompLevel.C2; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 8cc49f3bb6f..53c3dfb807f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -39,13 +39,9 @@ import java.util.regex.Pattern; /** - * Call the driver with jtreg: + * Use this framework by using the following JTreg setup in your "some.package.Test" * @library /test/lib - * @run driver TestFrameworkDriver some.package.Test - * - * package some.package; - * - * public class Test { ... } + * @run driver some.package.Test */ public class TestFramework { public static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); @@ -60,62 +56,192 @@ public class TestFramework { private List scenarios = null; private List flags = new ArrayList<>(); private final Class testClass; - private static String lastVMOutput; + private static String lastTestVMOutput; private TestFrameworkSocket socket; + /* + * Public interface methods + */ + + /** + * Creates an instance of TestFramework to test the class from which this constructor was invoked from. + * Use this constructor if you want to use multiple run options (flags, helper classes, scenarios). + * Use the associated add methods ({@link TestFramework#addFlags(String...)}, + * {@link TestFramework#addScenarios(Scenario...)}, {@link TestFramework#addHelperClasses(Class...)}) + * to set up everything and then start the testing by invoking {@link TestFramework#start()}. + */ + public TestFramework() { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + this.testClass = walker.getCallerClass(); + System.out.println(testClass); + } + + /** + * Creates an instance of TestFramework to test {@code testClass}. + * Use this constructor if you want to use multiple run options (flags, helper classes, scenarios). + * Use the associated add methods ({@link TestFramework#addFlags(String...)}, + * {@link TestFramework#addScenarios(Scenario...)}, {@link TestFramework#addHelperClasses(Class...)}) + * to set up everything and then start the testing by invoking {@link TestFramework#start()}. + * + * @param testClass the class to be tested by the framework. + * @see TestFramework#TestFramework() + */ public TestFramework(Class testClass) { TestRun.check(testClass != null, "Test class cannot be null"); this.testClass = testClass; } - /* - * Public interface methods + /** + * Tests the class from which this method was invoked from. */ - public static void run() { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); run(walker.getCallerClass()); } + /** + * Tests {@code testClass}. + * + * @param testClass the class to be tested by the framework. + * @see TestFramework#run() + */ public static void run(Class testClass) { TestFramework framework = new TestFramework(testClass); framework.start(); } + /** + * Tests the class from which this method was invoked from. The test VM is called with the specified {@code flags}. + *

    + *
  • The {@code flags} override any set Java or VM options by JTreg by default.

    + * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the {@code flags}.

  • + *
  • If you want to run your JTreg test with additional flags, use this method.

  • + *
  • If you want to run your JTreg test with multiple flag combinations, + * use {@link TestFramework#runWithScenarios(Scenario...)}

  • + *
+ * + * @param flags VM flags to be used for the test VM. + */ public static void runWithFlags(String... flags) { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); runWithFlags(walker.getCallerClass(), flags); } + /** + * Tests {@code testClass}. The test VM is called with the specified {@code flags}. + *
    + *
  • The {@code flags} override any set Java or VM options by JTreg by default.

    + * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the {@code flags}.

  • + *
  • If you want to run your JTreg test with additional flags, use this method.

  • + *
  • If you want to run your JTreg test with multiple flag combinations, + * use {@link TestFramework#runWithScenarios(Class, Scenario...)}

  • + *
+ * + * @param testClass the class to be tested by the framework. + * @param flags VM flags to be used for the test VM. + * + * @see TestFramework#runWithFlags(String...) + */ public static void runWithFlags(Class testClass, String... flags) { TestFramework framework = new TestFramework(testClass); framework.addFlags(flags); framework.start(); } + /** + * Tests {@code testClass} which uses {@code helperClasses} that can specify additional compile command annotations + * ({@link ForceCompile}, {@link DontCompile}, {@link ForceInline}, {@link DontInline}) to be applied while testing + * {@code testClass} (also see description of {@link TestFramework}). + *
    + *
  • If a helper class is not in the same file as the test class, make sure that JTreg compiles it by using + * {@literal @}compile in the JTreg header comment block.

  • + *
  • If a helper class does not specify any compile command annotations, you do not need to include it. If + * no helper class specifies any compile commands, consider using {@link TestFramework#run()} or + * {@link TestFramework#run(Class)}.

  • + *
+ * + * @param testClass the class to be tested by the framework. + * @param helperClasses helper classes containing compile command annotations ({@link ForceCompile}, + * {@link DontCompile}, {@link ForceInline}, {@link DontInline}) to be applied + * while testing {@code testClass} (also see description of {@link TestFramework}). + */ public static void runWithHelperClasses(Class testClass, Class... helperClasses) { TestFramework framework = new TestFramework(testClass); framework.addHelperClasses(helperClasses); framework.start(); } + /** + * Tests the class from which this method was invoked from. A test VM is called for each scenario in {@code scenarios} + * by using the specified flags in the scenario. + *
    + *
  • If there is only one scenario, consider using {@link TestFramework#runWithFlags(String...)}.

  • + *
  • The scenario flags override any Java or VM options set by JTreg by default.

    + * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the scenario flags.

  • + *
+ * + * @param scenarios scenarios which specify specific flags for the test VM. + */ public static void runWithScenarios(Scenario... scenarios) { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); runWithScenarios(walker.getCallerClass(), scenarios); } + /** + * Tests {@code testClass} A test VM is called for each scenario in {@code scenarios} by using the specified flags + * in the scenario. + *
    + *
  • If there is only one scenario, consider using {@link TestFramework#runWithFlags(String...)}.

  • + *
  • The scenario flags override any Java or VM options set by JTreg by default.

    + * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the scenario flags.

  • + *
+ * + * @param testClass the class to be tested by the framework. + * @param scenarios scenarios which specify specific flags for the test VM. + * + * @see TestFramework#runWithScenarios(Scenario...) + */ public static void runWithScenarios(Class testClass, Scenario... scenarios) { TestFramework framework = new TestFramework(testClass); framework.addScenarios(scenarios); framework.start(); } + /** + * Add VM flags to be used for the test VM. These flags override any Java or VM options set by JTreg by default.

+ * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the scenario flags. + * + *

+ * The testing can be started by invoking {@link TestFramework#start()} + * + * @param flags VM options to be applied to the test VM. + * @return the same framework instance. + */ public TestFramework addFlags(String... flags) { TestRun.check(flags != null && Arrays.stream(flags).noneMatch(Objects::isNull), "A flag cannot be null"); this.flags.addAll(Arrays.asList(flags)); return this; } + /** + * Add helper classes that can specify additional compile command annotations ({@link ForceCompile}, {@link DontCompile}, + * {@link ForceInline}, {@link DontInline}) to be applied while testing{@code testClass} (also see description of + * {@link TestFramework}). + *

    + *
  • If a helper class is not in the same file as the test class, make sure that JTreg compiles it by using + * {@literal @}compile in the JTreg header comment block.

  • + *
  • If a helper class does not specify any compile command annotations, you do not need to include it. If + * no helper class specifies any compile commands, you do not need to use this method

  • + *
+ * + *

+ * The testing can be started by invoking {@link TestFramework#start()} + * + * @param helperClasses helper classes containing compile command annotations ({@link ForceCompile}, + * {@link DontCompile}, {@link ForceInline}, {@link DontInline}) to be applied + * while testing {@code testClass} (also see description of {@link TestFramework}). + * @return the same framework instance. + */ public TestFramework addHelperClasses(Class... helperClasses) { TestRun.check(helperClasses != null && Arrays.stream(helperClasses).noneMatch(Objects::isNull), "A Helper class cannot be null"); if (this.helperClasses == null) { @@ -129,6 +255,18 @@ public TestFramework addHelperClasses(Class... helperClasses) { return this; } + /** + * Add scenarios to be used for the test VM. A test VM is called for each scenario in {@code scenarios} by using the + * specified flags in the scenario. The scenario flags override any flags set by {@link TestFramework#addFlags(String...)} + * and thus also override any Java or VM options set by JTreg by default.

+ * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the scenario flags. + * + *

+ * The testing can be started by invoking {@link TestFramework#start()} + * + * @param scenarios scenarios which specify specific flags for the test VM. + * @return the same framework instance. + */ public TestFramework addScenarios(Scenario... scenarios) { TestRun.check(scenarios != null && Arrays.stream(scenarios).noneMatch(Objects::isNull), "A scenario cannot be null"); if (this.scenarios == null) { @@ -139,12 +277,20 @@ public TestFramework addScenarios(Scenario... scenarios) { return this; } + /** + * Clear all settings set by {@link TestFramework#addFlags(String...)}, {@link TestFramework#addHelperClasses(Class[])} + * and/or {@link TestFramework#runWithScenarios(Scenario...)}. + */ public void clear() { flags.clear(); helperClasses = null; scenarios = null; } + /** + * Start the testing of the implicitely set test class by {@link TestFramework#TestFramework()} + * or explicitly set by {@link TestFramework#TestFramework(Class)}. + */ public void start() { installWhiteBox(); socket = new TestFrameworkSocket(); @@ -159,8 +305,14 @@ public void start() { } } - public static String getLastVMOutput() { - return lastVMOutput; + /** + * Get the VM output of the test VM. Use {@link -DVerbose=true} to enable more debug information. If scenarios + * were run, use {@link Scenario#getTestVMOutput()}. + * + * @return the last test VM output + */ + public static String getLastTestVMOutput() { + return lastTestVMOutput; } /** @@ -290,7 +442,7 @@ private void start(Scenario scenario) { System.out.println("Run Test VM" + flagsString + ":"); runTestVM(additionalFlags); if (scenario != null) { - scenario.setVMOutput(lastVMOutput); + scenario.setTestVMOutput(lastTestVMOutput); } System.out.println(); } @@ -359,10 +511,10 @@ private void runTestVM(List additionalFlags) { return; } - lastVMOutput = oa.getOutput(); + lastTestVMOutput = oa.getOutput(); checkTestVMExitCode(oa); if (VERIFY_IR) { - IRMatcher irMatcher = new IRMatcher(lastVMOutput, socket.getOutput(), testClass); + IRMatcher irMatcher = new IRMatcher(lastTestVMOutput, socket.getOutput(), testClass); irMatcher.applyRules(); } } @@ -416,7 +568,7 @@ private List getTestVMFlags() { private static void checkTestVMExitCode(OutputAnalyzer oa) { final int exitCode = oa.getExitValue(); if (VERBOSE && exitCode == 0) { - System.out.println("--- OUTPUT TestFramework runner VM ---"); + System.out.println("--- OUTPUT TestFramework test VM ---"); System.out.println(oa.getOutput()); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index b19898e10c7..7b38ce9a00c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -925,7 +925,9 @@ private void compileTest() { final Method testMethod = test.getTestMethod(); long started = System.currentTimeMillis(); long elapsed = 0; - Asserts.assertTrue(WHITE_BOX.isMethodCompilable(testMethod, test.getCompLevel().getValue(), false)); + TestRun.check(WHITE_BOX.isMethodCompilable(testMethod, test.getCompLevel().getValue(), false), + "Method" + testMethod + " not compilable at level " + test.getCompLevel() + + ". Did you use compileonly without including all @Test methods?"); enqueueMethodForCompilation(); do { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java index 6f988a333d0..f93959e5ee0 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java @@ -48,7 +48,7 @@ public static void main(String[] args) throws Exception { TestFramework.runWithScenarios(TestNoTiered.class, s); s = new Scenario(2, "-XX:TieredStopAtLevel=1"); TestFramework.runWithScenarios(TestStopAtLevel1.class, s); - Asserts.assertTrue(s.getVMOutput().contains("TestStopAtLevel1=34")); + Asserts.assertTrue(s.getTestVMOutput().contains("TestStopAtLevel1=34")); } @Test(compLevel = CompLevel.C1) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java index cdf7cf581e3..7ed7cfc3530 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java @@ -235,7 +235,7 @@ private static void checkConstraints(RuntimeException e, Constraint[] constraint constraint.checkConstraint(e); } } catch (Exception e1) { - System.out.println(TestFramework.getLastVMOutput()); + System.out.println(TestFramework.getLastTestVMOutput()); System.out.println(message); throw e1; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java index f621d5b4f4d..c24266708da 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java @@ -54,6 +54,7 @@ public static void main(String[] args) { testFramework.clear(); testFramework.addHelperClasses(HelperA.class, HelperB.class).start(); testFramework.clear(); + testFramework = new TestFramework(); testFramework.addHelperClasses(HelperA.class, HelperB.class).addHelperClasses(HelperC.class).start(); testFramework.clear(); testFramework.addScenarios(sDefault).addScenarios(s1, s2).start(); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java index 4ac6121adee..36075ddabbb 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java @@ -38,10 +38,10 @@ public static void main(String[] args) { TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class); } catch (Exception e) { Asserts.assertFalse(e.getMessage().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper1.foo() should have been C2 compiled")); - Asserts.assertFalse(TestFramework.getLastVMOutput().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper1.foo() should have been C2 compiled")); - Asserts.assertTrue(TestFramework.getLastVMOutput().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper2.foo() should have been C2 compiled")); + Asserts.assertFalse(TestFramework.getLastTestVMOutput().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper1.foo() should have been C2 compiled")); + Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper2.foo() should have been C2 compiled")); Asserts.assertTrue(e.getMessage().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper2.foo() should have been C2 compiled")); - Asserts.assertFalse(TestFramework.getLastVMOutput().contains("Should not be executed")); + Asserts.assertFalse(TestFramework.getLastTestVMOutput().contains("Should not be executed")); Asserts.assertFalse(e.getMessage().contains("Should not be executed")); exceptionsCaught++; } From c37d30bc854c9072a2cd96010a4e8aa91ef7b898 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 11 Mar 2021 11:34:08 +0100 Subject: [PATCH 045/131] Add more Javadocs --- .../test/lib/hotspot/ir_framework/Argument.java | 7 +++++++ .../jdk/test/lib/hotspot/ir_framework/Check.java | 5 +++++ .../test/lib/hotspot/ir_framework/CheckAt.java | 16 +++++++++++++++- .../test/lib/hotspot/ir_framework/CompLevel.java | 7 +++++++ .../ir_framework/IRViolationException.java | 5 +++++ .../jdk/test/lib/hotspot/ir_framework/IRs.java | 5 ++++- .../jdk/test/lib/hotspot/ir_framework/Run.java | 9 +++++++++ .../lib/hotspot/ir_framework/TestFormat.java | 2 +- .../ir_framework/TestFormatException.java | 3 +++ .../lib/hotspot/ir_framework/TestFramework.java | 9 ++++----- .../ir_framework/TestFrameworkException.java | 6 ++++-- .../hotspot/ir_framework/TestRunException.java | 4 ++++ .../test/lib/hotspot/ir_framework/Warmup.java | 11 ++++++++++- 13 files changed, 78 insertions(+), 11 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java index d8fc982aabb..efeca6d5ca7 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java @@ -23,6 +23,13 @@ package jdk.test.lib.hotspot.ir_framework; +/** + * Well-defined argument values that can be used in the {@link Arguments} annotation at a {@link Test} method for a + * base or a checked test. + * @see Arguments + * @see Test + * @see Check + */ public enum Argument { /** * Provides the default value for any kind of primitive type and objects type if the class provides a default constructor. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java index 17106ed64db..5f60806eaf2 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java @@ -28,6 +28,11 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Check { + /** + * The associated {@link Test} method for this {@code Check} annotated check method. The framework will directly + * invoke the check method after each invoking or only after the compilation of the associated {@code Test} method + * by the framework (depends on the value set with {@link Check#when()}). + */ String test(); CheckAt when() default CheckAt.EACH_INVOCATION; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java index b1c9c9e856d..08dd3865346 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java @@ -23,6 +23,20 @@ package jdk.test.lib.hotspot.ir_framework; +/** + * Enum used at in the {@link Check} annotation of a checked test. It specifies when the framework will invoke the + * check method after invoking the associated {@link Test} method. + * @see Check + * @see Test + */ public enum CheckAt { - EACH_INVOCATION, COMPILED + /** + * Invoke the {@link Check} method each time after invoking the associated {@link Test} method. + */ + EACH_INVOCATION, + /** + * Invoke the {@link Check} method only once after the warmup of the associated {@link Test} method completed has + * completed and test framework has compiled the test method. + */ + COMPILED } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java index 60167daa5ab..7d023637936 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java @@ -26,6 +26,13 @@ import java.util.HashMap; import java.util.Map; +/** + * Compilation levels used by the framework. The compilation levels map to the used levels in HotSpot (apart from the + * framework specific value {@link CompLevel#SKIP} that cannot be found in HotSpot). + * + *

+ * The compilation levels can be specified in the {@link Test}, {@link ForceCompile} and {@link DontCompile} annotation. + */ public enum CompLevel { /** * Skip a {@link Test @Test} when set as {@link Test#compLevel()}. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java index a051292bdf0..cd810e64114 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java @@ -23,6 +23,11 @@ package jdk.test.lib.hotspot.ir_framework; +/** + * Exception that is thrown if an {@link IR} constraint failed. The exception message contains a detailed list of + * all failures, including failing method, {@code IR} rule (the first {@code IR} constraint is rule 1) and the + * specific regex that could not be matched. + */ public class IRViolationException extends RuntimeException { public IRViolationException(String message) { super(message); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRs.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRs.java index 8b6335e8268..8875d7c83ff 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRs.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRs.java @@ -25,8 +25,11 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -@Retention(RetentionPolicy.RUNTIME) +/** + * Annotation to allow to specify multiple {@link IR} annotations at a {@link Test} method. + */ +@Retention(RetentionPolicy.RUNTIME) public @interface IRs { IR[] value(); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java index dc62e5074cc..de98c177145 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java @@ -28,6 +28,15 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Run { + /** + * The associated {@link Test} method for for this {@code Run} annotated run method. The framework directly invokes + * the run method instead of the associated {@code Test} method. + */ String test(); + + /** + * The mode of this custom run test. + * @see RunMode + */ RunMode mode() default RunMode.NORMAL; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java index 33464dabc31..2c7c613ad77 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java @@ -26,7 +26,7 @@ import java.util.ArrayList; import java.util.List; -public class TestFormat { +class TestFormat { private static final List FAILURES = new ArrayList<>(); public static void check(boolean test, String failureMessage) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java index d472eaa8986..c57790db78c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java @@ -23,6 +23,9 @@ package jdk.test.lib.hotspot.ir_framework; +/** + * Exception that is thrown if a JTreg test violates the supported format by the framework. + */ public class TestFormatException extends RuntimeException { public TestFormatException(String message) { super(message); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 53c3dfb807f..46959a3f28f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -40,12 +40,11 @@ /** * Use this framework by using the following JTreg setup in your "some.package.Test" - * @library /test/lib - * @run driver some.package.Test + * {@literal @}library /test/lib + * {@literal @}run driver some.package.Test */ public class TestFramework { - public static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); - + static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); static final String TEST_VM_FLAGS_START = "##### TestFrameworkPrepareFlags - used by TestFramework #####"; static final String TEST_VM_FLAGS_DELIMITER = " "; static final String TEST_VM_FLAGS_END = "----- END -----"; @@ -306,7 +305,7 @@ public void start() { } /** - * Get the VM output of the test VM. Use {@link -DVerbose=true} to enable more debug information. If scenarios + * Get the VM output of the test VM. Use {@code -DVerbose=true} to enable more debug information. If scenarios * were run, use {@link Scenario#getTestVMOutput()}. * * @return the last test VM output diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java index cbfb0a714e6..2307189e3dc 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java @@ -23,8 +23,10 @@ package jdk.test.lib.hotspot.ir_framework; -// Errors in the framework -class TestFrameworkException extends RuntimeException { +/** + * Exception that is thrown if there is an internal error in the framework. This is most likely a bug in the framework. + */ +public class TestFrameworkException extends RuntimeException { public TestFrameworkException(String message) { super(message); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java index 0753d05b194..69b5ccc7ab7 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java @@ -23,6 +23,10 @@ package jdk.test.lib.hotspot.ir_framework; +/** + * Exception that is thrown if the JTreg test throws an exception during the execution of individual tests of the + * test class. + */ public class TestRunException extends RuntimeException { public TestRunException(String message) { super(message); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java index 52043d0091a..1da49eb7332 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java @@ -26,7 +26,16 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -// Number of warmup iterations +/** + * This annotation overrides the default number (2000) of times the framework should warm up a test. + *

    + *
  • Any positive value or zero is permitted. A warm-up of zero allows a simulation of {@code -Xcomp}.

  • + *
  • Custom run tests (see {@link Run}) must specify a {@code @Warmup} annotation at the run method.

  • + *
  • Base and checked tests (see {@link Test}, {@link Check}) must specify a {@code @Warmup} annotation at + * the test method.

  • + *
+ * + */ @Retention(RetentionPolicy.RUNTIME) public @interface Warmup { int value(); From fc13fb8e6642e25533383e866e6c8b9d994676cc Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 11 Mar 2021 15:37:06 +0100 Subject: [PATCH 046/131] Fix port and host name for framework socket, fix tests accordingly, report scenario flags for failed scenarios --- .../hotspot/ir_framework/TestFramework.java | 96 ++++++++++++------- .../ir_framework/TestFrameworkExecution.java | 21 ++-- .../TestFrameworkPrepareFlags.java | 6 +- .../ir_framework/tests/TestBadFormat.java | 24 ++--- .../ir_framework/tests/TestIRMatching.java | 1 - .../ir_framework/tests/TestScenarios.java | 6 +- 6 files changed, 84 insertions(+), 70 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 46959a3f28f..826524f48aa 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -37,6 +37,7 @@ import java.util.concurrent.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; /** * Use this framework by using the following JTreg setup in your "some.package.Test" @@ -53,7 +54,7 @@ public class TestFramework { private List> helperClasses = null; private List scenarios = null; - private List flags = new ArrayList<>(); + private final List flags = new ArrayList<>(); private final Class testClass; private static String lastTestVMOutput; private TestFrameworkSocket socket; @@ -377,42 +378,49 @@ private void installWhiteBox() { } private void startWithScenarios() { - Map exceptionMap = new HashMap<>(); - Set scenarioIndecies = new HashSet<>(); + Map exceptionMap = new TreeMap<>(Comparator.comparingInt(Scenario::getIndex)); + Set scenarioIndices = new HashSet<>(); for (Scenario scenario : scenarios) { int scenarioIndex = scenario.getIndex(); - TestFormat.check(!scenarioIndecies.contains(scenarioIndex), + TestFormat.check(!scenarioIndices.contains(scenarioIndex), "Cannot define two scenarios with the same index " + scenarioIndex); - scenarioIndecies.add(scenarioIndex); + scenarioIndices.add(scenarioIndex); try { start(scenario); } catch (TestFormatException e) { // Test format violation is wrong for all the scenarios. Only report once. throw new TestFormatException(e.getMessage()); } catch (Exception e) { - exceptionMap.put(String.valueOf(scenarioIndex), e); + exceptionMap.put(scenario, e); } } if (!exceptionMap.isEmpty()) { - StringBuilder builder = new StringBuilder("The following scenarios have failed: #"); - builder.append(String.join(", #", exceptionMap.keySet())).append("\n\n"); - for (Map.Entry entry : exceptionMap.entrySet()) { - String title = "Stacktrace for Scenario #" + entry.getKey(); - builder.append(title).append("\n").append("=".repeat(title.length())).append("\n"); - Exception e = entry.getValue(); - if (e instanceof IRViolationException) { - // For IR violations, only show the actual message and not the (uninteresting) stack trace. - builder.append(e.getMessage()); - } else { - // Print stack trace if it was not a format violation or test run exception - StringWriter errors = new StringWriter(); - entry.getValue().printStackTrace(new PrintWriter(errors)); - builder.append(errors.toString()); - } - builder.append("\n"); + reportScenarioFailures(exceptionMap); + } + } + + private void reportScenarioFailures(Map exceptionMap) { + StringBuilder builder = new StringBuilder("The following scenarios have failed: #"); + builder.append(exceptionMap.keySet().stream().map(s -> String.valueOf(s.getIndex())). + collect(Collectors.joining(", #"))).append("\n\n"); + for (Map.Entry entry : exceptionMap.entrySet()) { + Scenario scenario = entry.getKey(); + String title = "Stacktrace for Scenario #" + scenario.getIndex(); + builder.append(title).append("\n").append("=".repeat(title.length())).append("\n"); + builder.append("Scenario flags: [").append(String.join(", ", scenario.getFlags())).append("]\n\n"); + Exception e = entry.getValue(); + if (e instanceof IRViolationException) { + // For IR violations, only show the actual message and not the (uninteresting) stack trace. + builder.append(e.getMessage()); + } else { + // Print stack trace if it was not a format violation or test run exception + StringWriter errors = new StringWriter(); + entry.getValue().printStackTrace(new PrintWriter(errors)); + builder.append(errors.toString()); } - TestRun.fail(builder.toString()); + builder.append("\n"); } + TestRun.fail(builder.toString()); } /** @@ -471,6 +479,7 @@ private ArrayList prepareFlagVMFlags(List additionalFlags) { cmds.add("-Xbootclasspath/a:."); cmds.add("-XX:+UnlockDiagnosticVMOptions"); cmds.add("-XX:+WhiteBoxAPI"); + cmds.add(socket.getPortPropertyFlag()); // TestFramework and scenario flags might have an influence on the later used test VM flags. Add them as well. cmds.addAll(additionalFlags); cmds.add(TestFrameworkPrepareFlags.class.getCanonicalName()); @@ -499,6 +508,7 @@ private void runTestVM(List additionalFlags) { // We only need the socket if we are doing IR verification. socket.start(); } + OutputAnalyzer oa; try { // Calls 'main' of TestFrameworkExecution to run all specified tests with commands 'cmds'. @@ -525,7 +535,6 @@ private List prepareTestVMFlags(List additionalFlags) { cmds.add("-Xbootclasspath/a:."); cmds.add("-XX:+UnlockDiagnosticVMOptions"); cmds.add("-XX:+WhiteBoxAPI"); - String[] jtregVMFlags = Utils.getTestJavaOpts(); if (!PREFER_COMMAND_LINE_FLAGS) { cmds.addAll(Arrays.asList(jtregVMFlags)); @@ -538,6 +547,11 @@ private List prepareTestVMFlags(List additionalFlags) { cmds.addAll(Arrays.asList(jtregVMFlags)); } + if (VERIFY_IR) { + // Add server property flag that enables test VM to print encoding for IR verification last. + cmds.add(socket.getPortPropertyFlag()); + } + cmds.add(TestFrameworkExecution.class.getCanonicalName()); cmds.add(testClass.getCanonicalName()); if (helperClasses != null) { @@ -547,11 +561,11 @@ private List prepareTestVMFlags(List additionalFlags) { } /** - * Parse the test VM flags as prepared by the flag VM. Additionally check the property flag DPrintValidIRRules to determine - * if IR matching should be done or not. + * Parse the test VM flags as prepared by the flag VM. Additionally check the property flag DShouldDoIRVerification + * to determine if IR matching should be done or not. */ private List getTestVMFlags() { - String patternString = "(?<=" + TestFramework.TEST_VM_FLAGS_START + "\\R)" + "(.*DPrintValidIRRules=(true|false).*)\\R" + "(?=" + IREncodingPrinter.END + ")"; + String patternString = "(?<=" + TestFramework.TEST_VM_FLAGS_START + "\\R)" + "(.*DShouldDoIRVerification=(true|false).*)\\R" + "(?=" + IREncodingPrinter.END + ")"; Pattern pattern = Pattern.compile(patternString); String flags = socket.getOutput(); if (VERBOSE) { @@ -609,19 +623,32 @@ static void fail(String failureMessage, Exception e) { * Dedicated socket to send data from flag and test VM back to the driver VM. */ class TestFrameworkSocket { - private static final int SOCKET_PORT = 6672; - private static final String HOSTNAME = "localhost"; + static final String SERVER_PORT_PROPERTY = "ir.framework.server.port"; + + // Static fields used by flag and test VM only. + private static final int SERVER_PORT = Integer.getInteger(SERVER_PORT_PROPERTY, -1); + private static final String HOSTNAME = null; + private final String serverPortPropertyFlag; private FutureTask socketTask; private Thread socketThread; private ServerSocket serverSocket; TestFrameworkSocket() { try { - serverSocket = new ServerSocket(SOCKET_PORT); + serverSocket = new ServerSocket(0); } catch (IOException e) { - TestFramework.fail("Server socket error", e); + TestFramework.fail("Failed to create TestFramework server socket", e); + } + int port = serverSocket.getLocalPort(); + if (TestFramework.VERBOSE) { + System.out.println("TestFramework server socket uses port " + port); } + serverPortPropertyFlag = "-D" + SERVER_PORT_PROPERTY + "=" + port; + } + + public String getPortPropertyFlag() { + return serverPortPropertyFlag; } public void start() { @@ -668,8 +695,13 @@ public void checkTerminated() { } } + /** + * Only called by flag and test VM to write to server socket. + */ public static void write(String msg, String type) { - try (Socket socket = new Socket(HOSTNAME, SOCKET_PORT); + TestFramework.check(SERVER_PORT != -1, "Server port was not set correctly for flag and/or test VM " + + "or method not called from flag or test VM"); + try (Socket socket = new Socket(HOSTNAME, SERVER_PORT); PrintWriter out = new PrintWriter(socket.getOutputStream(), true) ) { out.print(msg); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 7b38ce9a00c..37194b6b21c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -67,7 +67,7 @@ public class TestFrameworkExecution { private static final boolean GC_AFTER = Boolean.parseBoolean(System.getProperty("GCAfter", "false")); private static final boolean SHUFFLE_TESTS = Boolean.parseBoolean(System.getProperty("ShuffleTests", "true")); // Use separate flag as VERIFY_IR could have been set by user but due to other flags it was disabled by flag VM. - private static final boolean PRINT_VALID_IR_RULES = Boolean.parseBoolean(System.getProperty("PrintValidIRRules", "false")); + private static final boolean PRINT_VALID_IR_RULES = Integer.getInteger(TestFrameworkSocket.SERVER_PORT_PROPERTY, -1) != -1; protected static final long PerMethodTrapLimit = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); protected static final boolean ProfileInterpreter = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); private static final boolean FLIP_C1_C2 = Boolean.parseBoolean(System.getProperty("FlipC1C2", "false")); @@ -160,21 +160,12 @@ private static Class[] getHelperClasses(String[] args) { // Only called by internal tests testing the framework itself. Accessed by reflection. Not exposed to normal users. private static void runTestsOnSameVM(Class testClass) { - TestFrameworkSocket dummy = new TestFrameworkSocket(); - try { - if (PRINT_VALID_IR_RULES) { - // Need dummy socket to write to as we are not calling this method from TestFramework. - dummy.start(); - } - if (testClass == null) { - StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - testClass = walker.getCallerClass(); - } - TestFrameworkExecution framework = new TestFrameworkExecution(testClass); - framework.start(); - } finally { - dummy.close(); + if (testClass == null) { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + testClass = walker.getCallerClass(); } + TestFrameworkExecution framework = new TestFrameworkExecution(testClass); + framework.start(); } private void start() { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java index 71266333c35..de390140f3f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java @@ -100,7 +100,6 @@ private static void emitTestVMFlags(ArrayList flags) { private static ArrayList prepareTestVmFlags(Class testClass) { ArrayList cmds = new ArrayList<>(); - setupIrVerificationFlags(testClass, cmds); if (VERIFY_VM) { cmds.addAll(Arrays.asList(getVerifyFlags())); @@ -110,6 +109,7 @@ private static ArrayList prepareTestVmFlags(Class testClass) { if (COMPILE_COMMANDS) { cmds.addAll(Arrays.asList(getCompileCommandFlags())); } + setupIrVerificationFlags(testClass, cmds); // // TODO: Only for debugging // if (cmds.get(0).startsWith("-agentlib")) { @@ -139,9 +139,9 @@ private static void setupIrVerificationFlags(Class testClass, ArrayList clazz) { try { - runTestsOnSameVM.invoke(null, clazz); + TestFramework.run(clazz); } catch (Exception e) { - Throwable cause = e.getCause(); - if (cause != null) { - System.out.println(cause.getMessage()); - } - if (!(cause instanceof TestFormatException)) { + if (!(e instanceof TestFormatException)) { e.printStackTrace(); - Asserts.fail("Unexpected exception: " + cause); + Asserts.fail("Unexpected exception", e); } - String msg = cause.getMessage(); + String msg = e.getMessage(); Violations violations = getViolations(clazz); - violations.getFailedMethods().forEach(f -> Asserts.assertTrue(msg.contains(f), "Could not find " + f + " in violations")); + violations.getFailedMethods().forEach(f -> Asserts.assertTrue(msg.contains(f), "Could not find " + f + " in violations\n" + msg)); Pattern pattern = Pattern.compile("Violations \\((\\d+)\\)"); Matcher matcher = pattern.matcher(msg); - Asserts.assertTrue(matcher.find(), "Could not find violations"); + Asserts.assertTrue(matcher.find(), "Could not find violations in\n" + msg); int violationCount = Integer.parseInt(matcher.group(1)); - Asserts.assertEQ(violationCount, violations.getViolationCount()); + Asserts.assertEQ(violationCount, violations.getViolationCount(), msg); return; } throw new RuntimeException("Should catch an exception"); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java index 7ed7cfc3530..7cf9dad3303 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java @@ -34,7 +34,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -// Run with -DPrintIREncoding=true public class TestIRMatching { public static void main(String[] args) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java index b4d90a69661..2c4c329d62b 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java @@ -37,13 +37,13 @@ public static void main(String[] args) { TestFramework.runWithScenarios(sDefault, s1, s2, s3); Asserts.fail("Should not reach"); } catch (TestRunException e) { - Asserts.assertTrue(e.getMessage().contains("The following scenarios have failed: #0, #1, #3")); + Asserts.assertTrue(e.getMessage().contains("The following scenarios have failed: #0, #1, #3"), e.getMessage()); } try { TestFramework.runWithScenarios(s1, s2, s3); Asserts.fail("Should not reach"); } catch (TestRunException e) { - Asserts.assertTrue(e.getMessage().contains("The following scenarios have failed: #1, #3")); + Asserts.assertTrue(e.getMessage().contains("The following scenarios have failed: #1, #3"), e.getMessage()); } TestFramework.runWithScenarios(ScenarioTest.class, s1, s2, s3); @@ -51,7 +51,7 @@ public static void main(String[] args) { TestFramework.runWithScenarios(s1, s3dup, s2, s3); Asserts.fail("Should not reach"); } catch (RuntimeException e) { - Asserts.assertTrue(e.getMessage().contains("Cannot define two scenarios with the same index 3")); + Asserts.assertTrue(e.getMessage().contains("Cannot define two scenarios with the same index 3"), e.getMessage()); } } From 25d53c4f06dfcff9ce82900b4dc6a8dfefb745da Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 11 Mar 2021 18:08:59 +0100 Subject: [PATCH 047/131] Fix access modifier bug for checked and custom run test --- .../ir_framework/TestFrameworkExecution.java | 48 +- .../tests/TestAccessModifiers.java | 420 ++++++++++++++++++ .../tests/TestPackagePrivate.java | 46 -- 3 files changed, 449 insertions(+), 65 deletions(-) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestAccessModifiers.java delete mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestPackagePrivate.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 37194b6b21c..dbfcd013c20 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -788,7 +788,7 @@ class BaseTest { protected final DeclaredTest test; protected final Method testMethod; protected final TestInfo testInfo; - protected final Object invocationTarget; + private final Object invocationTarget; private final boolean shouldCompile; protected int warmupIterations; @@ -797,26 +797,32 @@ public BaseTest(DeclaredTest test) { this.testMethod = test.getTestMethod(); this.testInfo = new TestInfo(testMethod); this.warmupIterations = test.getWarmupIterations(); - Class clazz = testMethod.getDeclaringClass(); - if (Modifier.isStatic(testMethod.getModifiers())) { - this.invocationTarget = null; + this.invocationTarget = getInvocationTarget(testMethod); + if (!TestFrameworkExecution.USE_COMPILER) { + this.shouldCompile = false; + } else if (TestFrameworkExecution.STRESS_CC) { + this.shouldCompile = !TestFrameworkExecution.excludeCompilationRandomly(testMethod); + } else { + this.shouldCompile = true; + } + } + + protected Object getInvocationTarget(Method method) { + Class clazz = method.getDeclaringClass(); + Object invocationTarget; + if (Modifier.isStatic(method.getModifiers())) { + invocationTarget = null; } else { try { Constructor constructor = clazz.getDeclaredConstructor(); constructor.setAccessible(true); - this.invocationTarget = constructor.newInstance(); + invocationTarget = constructor.newInstance(); } catch (Exception e) { throw new TestRunException("Could not create instance of " + clazz - + ". Make sure there is a constructor without arguments.", e); + + ". Make sure there is a constructor without arguments.", e); } } - if (!TestFrameworkExecution.USE_COMPILER) { - this.shouldCompile = false; - } else if (TestFrameworkExecution.STRESS_CC) { - this.shouldCompile = !TestFrameworkExecution.excludeCompilationRandomly(testMethod); - } else { - this.shouldCompile = true; - } + return invocationTarget; } public String getTestName() { @@ -967,6 +973,7 @@ class CheckedTest extends BaseTest { private final Method checkMethod; private final CheckAt checkAt; private final Parameter parameter; + private final Object checkInvocationTarget; enum Parameter { NONE, RETURN_ONLY, TEST_INFO_ONLY, BOTH @@ -979,6 +986,7 @@ public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecificati this.checkMethod = checkMethod; this.checkAt = checkSpecification.when(); this.parameter = parameter; + this.checkInvocationTarget = getInvocationTarget(checkMethod); } @Override @@ -994,10 +1002,10 @@ public void verify(Object result) { if (shouldVerify) { try { switch (parameter) { - case NONE -> checkMethod.invoke(invocationTarget); - case RETURN_ONLY -> checkMethod.invoke(invocationTarget, result); - case TEST_INFO_ONLY -> checkMethod.invoke(invocationTarget, testInfo); - case BOTH -> checkMethod.invoke(invocationTarget, result, testInfo); + case NONE -> checkMethod.invoke(checkInvocationTarget); + case RETURN_ONLY -> checkMethod.invoke(checkInvocationTarget, result); + case TEST_INFO_ONLY -> checkMethod.invoke(checkInvocationTarget, testInfo); + case BOTH -> checkMethod.invoke(checkInvocationTarget, result, testInfo); } } catch (Exception e) { throw new TestRunException("There was an error while invoking @Check method " + checkMethod, e); @@ -1009,12 +1017,14 @@ public void verify(Object result) { class CustomRunTest extends BaseTest { private final Method runMethod; private final RunMode mode; + private final Object runInvocationTarget; public CustomRunTest(DeclaredTest test, Method runMethod, Warmup warmUpAnno, Run runSpecification) { super(test); // Make sure we can also call non-public or public methods in package private classes runMethod.setAccessible(true); this.runMethod = runMethod; + this.runInvocationTarget = getInvocationTarget(runMethod); this.mode = runSpecification.mode(); this.warmupIterations = warmUpAnno != null ? warmUpAnno.value() : test.getWarmupIterations(); TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + runMethod); @@ -1038,9 +1048,9 @@ public void run() { protected void runMethod() { try { if (runMethod.getParameterCount() == 1) { - runMethod.invoke(invocationTarget, testInfo); + runMethod.invoke(runInvocationTarget, testInfo); } else { - runMethod.invoke(invocationTarget); + runMethod.invoke(runInvocationTarget); } } catch (Exception e) { throw new TestRunException("There was an error while invoking @Run method " + runMethod, e); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestAccessModifiers.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestAccessModifiers.java new file mode 100644 index 00000000000..43f54becbdd --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestAccessModifiers.java @@ -0,0 +1,420 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework.tests; + +import jdk.test.lib.hotspot.ir_framework.*; +import jdk.test.lib.hotspot.ir_framework.examples.Sandbox; + +public class TestAccessModifiers { + public static void main(String[] args) { + TestFramework.run(PackagePrivate.class); + } +} + +class PackagePrivate { + @Test + public void test() { + } + + @Test + @Arguments(Argument.DEFAULT) + public void test2(int x) { + } + + @Test + public static int staticPublicPrivate() { + return 42; + } + + @Check(test = "staticPublicPrivate") + private void staticPublicPrivateCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + protected static int staticProtectedPrivate() { + return 42; + } + + @Check(test = "staticProtectedPrivate") + private void staticProtectedPrivateCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + static int staticDefaultPrivate() { + return 42; + } + + @Check(test = "staticDefaultPrivate") + private void staticDefaultPrivateCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + private static int staticPrivatePrivate() { + return 42; + } + + @Check(test = "staticPrivatePrivate") + private void staticPrivatePrivateCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + public static int staticPublicDefault() { + return 42; + } + + @Check(test = "staticPublicDefault") + void staticPublicDefaultCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + protected static int staticProtectedDefault() { + return 42; + } + + @Check(test = "staticProtectedDefault") + void staticProtectedDefaultCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + static int staticDefaultDefault() { + return 42; + } + + @Check(test = "staticDefaultDefault") + void staticDefaultDefaultCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + private static int staticPrivateDefault() { + return 42; + } + + @Check(test = "staticPrivateDefault") + void staticPrivateDefaultCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + public static int staticPublicProtected() { + return 42; + } + + @Check(test = "staticPublicProtected") + protected void staticPublicProtectedCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + protected static int staticProtectedProtected() { + return 42; + } + + @Check(test = "staticProtectedProtected") + protected void staticProtectedProtectedCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + static int staticDefaultProtected() { + return 42; + } + + @Check(test = "staticDefaultProtected") + protected void staticDefaultProtectedCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + private static int staticPrivateProtected() { + return 42; + } + + @Check(test = "staticPrivateProtected") + protected void staticPrivateProtectedCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + public static int staticPublicPublic() { + return 42; + } + + @Check(test = "staticPublicPublic") + public void staticPublicPublicCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + protected static int staticProtectedPublic() { + return 42; + } + + @Check(test = "staticProtectedPublic") + public void staticProtectedPublicCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + static int staticDefaultPublic() { + return 42; + } + + @Check(test = "staticDefaultPublic") + public void staticDefaultPublicCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + private static int staticPrivatePublic() { + return 42; + } + + @Check(test = "staticPrivatePublic") + public void staticPrivatePublicCheck(int retValue) { + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + static int staticDefaultPrivate2() { + return 42; + } + + @Run(test = "staticDefaultPrivate2") + private void staticDefaultPrivateRun() { + int retValue = staticDefaultPrivate2(); + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + private static int staticPrivatePrivate2() { + return 42; + } + + @Run(test = "staticPrivatePrivate2") + private void staticPrivatePrivateRun() { + int retValue = staticPrivatePrivate2(); + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + public static int staticPublicDefault2() { + return 42; + } + + @Run(test = "staticPublicDefault2") + void staticPublicDefaultRun() { + int retValue = staticPublicDefault2(); + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + protected static int staticProtectedDefault2() { + return 42; + } + + @Run(test = "staticProtectedDefault2") + void staticProtectedDefaultRun() { + int retValue = staticProtectedDefault2(); + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + static int staticDefaultDefault2() { + return 42; + } + + @Run(test = "staticDefaultDefault2") + void staticDefaultDefaultRun() { + int retValue = staticDefaultDefault2(); + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + private static int staticPrivateDefault2() { + return 42; + } + + @Run(test = "staticPrivateDefault2") + void staticPrivateDefaultRun() { + int retValue = staticPrivateDefault2(); + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + public static int staticPublicProtected2() { + return 42; + } + + @Run(test = "staticPublicProtected2") + protected void staticPublicProtectedRun() { + int retValue = staticPublicProtected2(); + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + protected static int staticProtectedProtected2() { + return 42; + } + + @Run(test = "staticProtectedProtected2") + protected void staticProtectedProtectedRun() { + int retValue = staticProtectedProtected2(); + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + static int staticDefaultProtected2() { + return 42; + } + + @Run(test = "staticDefaultProtected2") + protected void staticDefaultProtectedRun() { + int retValue = staticDefaultProtected2(); + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + private static int staticPrivateProtected2() { + return 42; + } + + @Run(test = "staticPrivateProtected2") + protected void staticPrivateProtectedRun() { + int retValue = staticPrivateProtected2(); + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + public static int staticPublicPublic2() { + return 42; + } + + @Run(test = "staticPublicPublic2") + public void staticPublicPublicRun() { + int retValue = staticPublicPublic2(); + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + protected static int staticProtectedPublic2() { + return 42; + } + + @Run(test = "staticProtectedPublic2") + public void staticProtectedPublicRun() { + int retValue = staticProtectedPublic2(); + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + static int staticDefaultPublic2() { + return 42; + } + + @Run(test = "staticDefaultPublic2") + public void staticDefaultPublicRun() { + int retValue = staticDefaultPublic2(); + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + @Test + private static int staticPrivatePublic2() { + return 42; + } + + @Run(test = "staticPrivatePublic2") + public void staticPrivatePublicRun() { + int retValue = staticPrivatePublic2(); + if (retValue != 42) { + throw new RuntimeException("Needs to be 42"); + } + } + + +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestPackagePrivate.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestPackagePrivate.java deleted file mode 100644 index 0c579372ee1..00000000000 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestPackagePrivate.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework.tests; - -import jdk.test.lib.hotspot.ir_framework.Argument; -import jdk.test.lib.hotspot.ir_framework.Test; -import jdk.test.lib.hotspot.ir_framework.TestFramework; -import jdk.test.lib.hotspot.ir_framework.Arguments; - -public class TestPackagePrivate { - public static void main(String[] args) { - TestFramework.run(PackagePrivate.class); - } -} - -class PackagePrivate { - @Test - public void test() { - } - - @Test - @Arguments(Argument.DEFAULT) - public void test2(int x) { - } -} From bbdc9a5de668b9a4b0a4fe7adcf14edb24228ae3 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 16 Mar 2021 15:15:43 +0100 Subject: [PATCH 048/131] Deoptimize as interface method --- test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java | 4 ++++ .../test/lib/hotspot/ir_framework/TestFrameworkExecution.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 826524f48aa..94c965d856b 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -325,6 +325,10 @@ public static void compile(Method m, CompLevel compLevel) { TestFrameworkExecution.compile(m, compLevel); } + public static void deoptimize(Method m) { + TestFrameworkExecution.deoptimize(m); + } + public static boolean isC1Compiled(Method m) { return TestFrameworkExecution.isC1Compiled(m); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index dbfcd013c20..4e117af57f8 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -615,6 +615,10 @@ static void compile(Method m, CompLevel compLevel) { enqueueMethodForCompilation(m, compLevel); } + static void deoptimize(Method m) { + WHITE_BOX.deoptimizeMethod(m); + } + static boolean isC1Compiled(Method m) { return compiledByC1(m) == TriState.Yes; } From 9763c3bc58498a2aa39f097e302f5c506d3feb27 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 16 Mar 2021 16:46:14 +0100 Subject: [PATCH 049/131] Support multiple @Test methods in custom run test (includes refactorings of BaseTest and TestInfo, additional tests), handle IR matching for no compilation in STANDALONE mode correctly, replace @OSRCompileOnly by CompLevel.WAIT_FOR_COMPILATION and add tests for it --- .../ExampleTestUnloadedInlineTypeField.java | 2 +- .../hotspot/ir_framework/AbstractInfo.java | 84 +++ .../lib/hotspot/ir_framework/CompLevel.java | 9 +- .../lib/hotspot/ir_framework/IRMatcher.java | 11 +- .../hotspot/ir_framework/OSRCompileOnly.java | 32 -- .../test/lib/hotspot/ir_framework/Run.java | 6 +- .../lib/hotspot/ir_framework/RunInfo.java | 147 ++++++ .../test/lib/hotspot/ir_framework/Test.java | 8 +- .../ir_framework/TestFrameworkExecution.java | 499 ++++++++++++------ .../lib/hotspot/ir_framework/TestInfo.java | 56 +- .../ir_framework/examples/RunExample.java | 48 +- .../ir_framework/examples/TestExample.java | 5 +- .../ir_framework/tests/TestBadFormat.java | 66 ++- .../ir_framework/tests/TestBasics.java | 55 +- .../ir_framework/tests/TestControls.java | 6 +- .../ir_framework/tests/TestIRMatching.java | 55 ++ .../ir_framework/tests/TestRunTests.java | 195 +++++++ 17 files changed, 1000 insertions(+), 284 deletions(-) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java delete mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/OSRCompileOnly.java create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestUnloadedInlineTypeField.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestUnloadedInlineTypeField.java index 1f33c2ecb5f..448fbc47f85 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestUnloadedInlineTypeField.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestUnloadedInlineTypeField.java @@ -84,7 +84,7 @@ public int test1(Object holder) { } @Run(test = "test1") - public void test1_verifier(TestInfo info) { + public void test1_verifier(RunInfo info) { if (info.isWarmUp() && info.isC1Test()) { test1(null); } else { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java new file mode 100644 index 00000000000..40e5bd32b45 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Random; +import java.util.stream.Collectors; + +abstract public class AbstractInfo { + private static final Random random = new Random(); + + protected final Class testClass; + private boolean toggleBool = false; + private boolean onWarmUp = true; + + AbstractInfo(Class testClass) { + this.testClass = testClass; + } + + public boolean toggleBoolean() { + toggleBool = !toggleBool; + return toggleBool; + } + + public static int getRandomInt() { + return random.nextInt() % 1000; + } + + public static long getRandomLong() { + return random.nextLong() % 1000; + } + + public static double getRandomDouble() { + return random.nextDouble() % 1000; + } + + public boolean isWarmUp() { + return onWarmUp; + } + + void setWarmUpFinished() { + onWarmUp = false; + } + + public Method getMethod(Class c, String name, Class... args) { + try { + return c.getMethod(name, args); + } catch (NoSuchMethodException e) { + String parameters = args == null || args.length == 0 ? "" : + " with arguments [" + Arrays.stream(args).map(Class::getName).collect(Collectors.joining(",")) + "]"; + throw new TestRunException("Could not find method " + name + " in " + c + parameters); + } + } + + public Method getTestClassMethod(String name, Class... args) { + return getMethod(testClass, name, args); + } + + public boolean isC1Test() { + return TestFrameworkExecution.TEST_C1; + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java index 7d023637936..9f249b5eeae 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java @@ -35,7 +35,14 @@ */ public enum CompLevel { /** - * Skip a {@link Test @Test} when set as {@link Test#compLevel()}. + * Can only be used at {@link Test#compLevel()}. After the warm-up, the framework keeps invoking the test over a span + * of 10s (configurable by setting the property flag {@code -DWaitForCompilationTimeout}) until HotSpot compiles the + * {@link Test} method. If the method was not compiled after 10s, an exception is thrown. The framework does not wait + * for the compilation if the test VM is run with {@code -Xcomp}, {@code -XX:-UseCompiler} or {@code -DStressCC=true}. + */ + WAIT_FOR_COMPILATION(-4), + /** + * Can only be used at {@link Test#compLevel()}. Skip a {@link Test @Test} completely. */ SKIP(-3), /** diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java index 4a5a1095bc8..3a97e25a03e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java @@ -85,7 +85,7 @@ private void splitCompilations(String output, Class testClass) { if (methodName.startsWith(keyMatchPrefix)) { String shortMethodName = methodName.split("::")[1]; if (irRulesMap.containsKey(methodName.split("::")[1])) { - compilations.put(shortMethodName, output.substring(prev, m.start() + 1)); + compilations.put(shortMethodName, output.substring(prev, m.start() + 1).trim()); } } @@ -105,7 +105,7 @@ private void splitCompilations(String output, Class testClass) { if (TestFramework.VERBOSE) { System.out.println("\nGraph for " + methodName + "\n" + testOutput); } - compilations.put(shortMethodName, testOutput); + compilations.put(shortMethodName, testOutput.trim()); } } } @@ -155,6 +155,13 @@ private void reportFailuresIfAny() { private void applyRuleToMethod(IR[] irAnnos, Integer[] ids) { String testOutput = compilations.get(method.getName()); + if (testOutput == null || testOutput.isEmpty()) { + String msg = "Method was not compiled as part of a @Run method in STANDALONE mode. " + + "Make sure to always trigger a C2 compilation by invoking the test enough times."; + fails.computeIfAbsent(method, k -> new ArrayList<>()).add(msg); + return; + } + if (TestFramework.VERBOSE) { System.out.println(testOutput); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/OSRCompileOnly.java b/test/lib/jdk/test/lib/hotspot/ir_framework/OSRCompileOnly.java deleted file mode 100644 index 655c9468b4a..00000000000 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/OSRCompileOnly.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -// Do not enqueue the test method for compilation immediately after warmup loops have finished. Instead -// let the test method be compiled with on-stack-replacement. -@Retention(RetentionPolicy.RUNTIME) -public @interface OSRCompileOnly {} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java index de98c177145..3396e8e439e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java @@ -29,10 +29,10 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Run { /** - * The associated {@link Test} method for for this {@code Run} annotated run method. The framework directly invokes - * the run method instead of the associated {@code Test} method. + * The associated {@link Test} methods (one or more) for for this {@code Run} annotated run method. + * The framework directly invokes the run method instead of the associated {@code Test} methods. */ - String test(); + String[] test(); /** * The mode of this custom run test. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java new file mode 100644 index 00000000000..91fd2f48dfd --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class RunInfo extends AbstractInfo { + + private final Method testMethod; + private final Map testMethods; + + RunInfo(Method testMethod) { + super(testMethod.getDeclaringClass()); + this.testMethod = testMethod; + this.testMethods = null; + } + + RunInfo(List testMethods) { + super(testMethods.get(0).getDeclaringClass()); + this.testMethods = new HashMap<>(); + for (Method m : testMethods) { + this.testMethods.put(m.getName(), m); + } + this.testMethod = testMethods.get(0); + } + + public Method getTest() { + checkSingleTest("getTest"); + return testMethod; + } + + public Method getTest(String testName) { + return getMethod(testName); + } + + public boolean isTestC1Compiled() { + checkSingleTest("isTestC1Compiled"); + return TestFrameworkExecution.isC1Compiled(testMethod); + } + + public boolean isTestC1Compiled(String testName) { + return TestFrameworkExecution.isC1Compiled(getMethod(testName)); + } + + public boolean isTestC2Compiled() { + checkSingleTest("isTestC2Compiled"); + return TestFrameworkExecution.isC2Compiled(testMethod); + } + + public boolean isTestC2Compiled(String testName) { + return TestFrameworkExecution.isC2Compiled(getMethod(testName)); + } + + public boolean isTestCompiledAtLevel(CompLevel compLevel) { + checkSingleTest("isTestCompiledAtLevel"); + return TestFrameworkExecution.isCompiledAtLevel(testMethod, compLevel); + } + + public boolean isTestCompiledAtLevel(String testName, CompLevel compLevel) { + return TestFrameworkExecution.isCompiledAtLevel(getMethod(testName), compLevel); + } + + public void assertTestDeoptimizedByC1() { + checkSingleTest("assertTestDeoptimizedByC1"); + TestFrameworkExecution.assertDeoptimizedByC1(testMethod); + } + + public void assertTestDeoptimizedByC1(String testName) { + TestFrameworkExecution.assertDeoptimizedByC1(getMethod(testName)); + } + + public void assertTestCompiledByC1() { + checkSingleTest("assertTestCompiledByC1"); + TestFrameworkExecution.assertCompiledByC1(testMethod); + } + + public void assertTestCompiledByC1(String testName) { + TestFrameworkExecution.assertCompiledByC1(getMethod(testName)); + } + + public void assertTestDeoptimizedByC2() { + checkSingleTest("assertTestDeoptimizedByC2"); + TestFrameworkExecution.assertDeoptimizedByC2(testMethod); + } + + public void assertTestDeoptimizedByC2(String testName) { + TestFrameworkExecution.assertDeoptimizedByC2(getMethod(testName)); + } + + public void assertTestCompiledByC2() { + checkSingleTest("assertTestCompiledByC2"); + TestFrameworkExecution.assertCompiledByC2(testMethod); + } + + public void assertTestCompiledByC2(String testName) { + TestFrameworkExecution.assertCompiledByC2(getMethod(testName)); + } + + public void assertTestCompiledAtLevel(CompLevel level) { + checkSingleTest("assertTestCompiledAtLevel"); + TestFrameworkExecution.assertCompiledAtLevel(testMethod, level); + } + + public void assertTestCompiledAtLevel(String testName, CompLevel level) { + TestFrameworkExecution.assertCompiledAtLevel(getMethod(testName), level); + } + + private void checkSingleTest(String calledMethod) { + if (testMethod == null) { + throw new TestRunException("Use " + calledMethod + " with testName String argument in @Run method when running " + + "more than one @Test method."); + } + } + + private Method getMethod(String testName) { + Method m = testMethods.get(testName); + if (m == null) { + throw new RuntimeException("Could not find @Test \"" + testName + "\" in " + testClass + " being associated with" + + " corresponding @Run method."); + } + return m; + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java index 42fbab782fd..af58dfbfe5b 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java @@ -67,10 +67,8 @@ public @interface Test { /** * Specify at which compilation level the framework should eventually compile the test method after an optional - * warmup period. - * - *

- * Default if not specified in annotation: {@link CompLevel#C2}. + * warmup period. The default {@link CompLevel#ANY} will let the framework compile the method at the highest + * available level which is usually {@link CompLevel#C2}. */ - CompLevel compLevel() default CompLevel.C2; + CompLevel compLevel() default CompLevel.ANY; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 4e117af57f8..2f0b98362ad 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -23,7 +23,6 @@ package jdk.test.lib.hotspot.ir_framework; -import jdk.test.lib.Asserts; import jdk.test.lib.Platform; import jdk.test.lib.Utils; import sun.hotspot.WhiteBox; @@ -33,6 +32,10 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import java.util.stream.Stream; @@ -73,10 +76,10 @@ public class TestFrameworkExecution { private static final boolean FLIP_C1_C2 = Boolean.parseBoolean(System.getProperty("FlipC1C2", "false")); private final HashMap declaredTests = new HashMap<>(); - private final LinkedHashMap allTests = new LinkedHashMap<>(); // Keep order + private final LinkedHashMap allTests = new LinkedHashMap<>(); // Keep order private final HashMap testMethodMap = new HashMap<>(); private final List excludeList; - private final List includeList; + private final List testList; private List> helperClasses = null; private final IREncodingPrinter irMatchRulePrinter; private final Class testClass; @@ -84,7 +87,7 @@ public class TestFrameworkExecution { private TestFrameworkExecution(Class testClass) { TestRun.check(testClass != null, "Test class cannot be null"); this.testClass = testClass; - this.includeList = createTestFilterList(TESTLIST, testClass); + this.testList = createTestFilterList(TESTLIST, testClass); this.excludeList = createTestFilterList(EXCLUDELIST, testClass); if (PRINT_VALID_IR_RULES) { @@ -345,8 +348,9 @@ private void dontCompileMethodAtLevel(Method m, CompLevel compLevel) { private void applyForceCompileCommand(Method m) { ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); if (forceCompileAnno != null) { - TestFormat.check(forceCompileAnno.value() != CompLevel.SKIP, - "Cannot define compilation level SKIP in @ForceCompile at " + m); + CompLevel level = forceCompileAnno.value(); + TestFormat.check(level != CompLevel.SKIP && level != CompLevel.WAIT_FOR_COMPILATION, + "Cannot define compilation level SKIP or WAIT_FOR_COMPILATION in @ForceCompile at " + m); enqueueMethodForCompilation(m, forceCompileAnno.value()); } } @@ -360,16 +364,20 @@ static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { } private void setupTests() { - boolean hasIncludeList = includeList != null; + boolean hasTestList = testList != null; boolean hasExcludeList = excludeList != null; for (Method m : testClass.getDeclaredMethods()) { Test testAnno = getAnnotation(m, Test.class); try { if (testAnno != null) { - if (hasIncludeList && includeList.contains(m.getName()) && (!hasExcludeList || !excludeList.contains(m.getName()))) { - addTest(m); - } else if (hasExcludeList && !excludeList.contains(m.getName())) { - addTest(m); + if (hasTestList) { + if (testList.contains(m.getName()) && (!hasExcludeList || !excludeList.contains(m.getName()))) { + addTest(m); + } + } else if (hasExcludeList) { + if (!excludeList.contains(m.getName())) { + addTest(m); + } } else { addTest(m); } @@ -397,8 +405,6 @@ private void addTest(Method m) { TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + m); } - boolean osrOnly = getAnnotation(m, OSRCompileOnly.class) != null; - if (PRINT_VALID_IR_RULES) { irMatchRulePrinter.emitRuleEncoding(m); } @@ -411,7 +417,7 @@ private void addTest(Method m) { if (FLIP_C1_C2) { compLevel = flipCompLevel(compLevel); } - DeclaredTest test = new DeclaredTest(m, ArgumentValue.getArguments(m), compLevel, warmupIterations, osrOnly); + DeclaredTest test = new DeclaredTest(m, ArgumentValue.getArguments(m), compLevel, warmupIterations); declaredTests.put(m, test); testMethodMap.put(m.getName(), m); } @@ -529,36 +535,56 @@ private CheckedTest.Parameter getCheckedTestParameter(Method m, Method testMetho } private void addCustomRunTest(Method m, Run runAnno) { - Method testMethod = testMethodMap.get(runAnno.test()); - DeclaredTest test = declaredTests.get(testMethod); - checkCustomRunTest(m, runAnno, testMethod, test); - test.setAttachedMethod(m); + checkRunMethod(m, runAnno); + List tests = new ArrayList<>(); + for (String testName : runAnno.test()) { + try { + Method testMethod = testMethodMap.get(testName); + DeclaredTest test = declaredTests.get(testMethod); + checkCustomRunTest(m, testName, testMethod, test, runAnno.mode()); + test.setAttachedMethod(m); + tests.add(test); + } catch (TestFormatException e) { + // Logged, continue. + } + } + if (tests.isEmpty()) { + return; // There was a format violation. Return. + } dontCompileMethod(m); // Don't inline run methods WHITE_BOX.testSetDontInlineMethod(m, true); - CustomRunTest customRunTest = new CustomRunTest(test, m, getAnnotation(m, Warmup.class), runAnno); + CustomRunTest customRunTest = new CustomRunTest(m, getAnnotation(m, Warmup.class), runAnno, tests); allTests.put(m, customRunTest); } - private void checkCustomRunTest(Method m, Run runAnno, Method testMethod, DeclaredTest test) { + private void checkCustomRunTest(Method m, String testName, Method testMethod, DeclaredTest test, RunMode runMode) { TestFormat.check(testMethod != null, "Did not find associated @Test method \"" + m.getDeclaringClass().getName() - + "." + runAnno.test() + "\" specified in @Run at " + m); - TestFormat.check(test != null, "Missing @Test annotation for associated test method " + runAnno.test() + " for @Run at " + m); + + "." + testName + "\" specified in @Run at " + m); + TestFormat.check(test != null, + "Missing @Test annotation for associated test method " + testName + " for @Run at " + m); Method attachedMethod = test.getAttachedMethod(); TestFormat.check(attachedMethod == null, - "Cannot use @Test " + testMethod + " for more than one @Run/@Check method. Found: " + m + ", " + attachedMethod); - TestFormat.check(!test.hasArguments(), "Cannot use @Arguments at test method " + testMethod + " in combination with @Run method " + m); - TestFormat.checkNoThrow(m.getParameterCount() == 0 || (m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(TestInfo.class)), - "@Run method " + m + " must specify either no parameter or exactly one of " + TestInfo.class); + "Cannot use @Test " + testMethod + " for more than one @Run/@Check method. Found: " + + m + ", " + attachedMethod); + TestFormat.check(!test.hasArguments(), + "Cannot use @Arguments at test method " + testMethod + " in combination with @Run method " + m); Warmup warmupAnno = getAnnotation(testMethod, Warmup.class); TestFormat.checkNoThrow(warmupAnno == null, - "Cannot set @Warmup at @Test method " + testMethod + " when used with its @Run method " + m + ". Use @Warmup at @Run method instead."); - warmupAnno = getAnnotation(m, Warmup.class); + "Cannot set @Warmup at @Test method " + testMethod + " when used with its @Run method " + + m + ". Use @Warmup at @Run method instead."); + TestFormat.checkNoThrow(runMode != RunMode.STANDALONE || test.getCompLevel() == CompLevel.C2, + "Setting explicit compilation level for @Test method " + testMethod + " has no effect " + + "when used with STANDALONE @Run method " + m); + } + + private void checkRunMethod(Method m, Run runAnno) { + TestFormat.check(runAnno.test().length > 0, "@Run method " + m + " must specify at least one test method"); + TestFormat.checkNoThrow(m.getParameterCount() == 0 || (m.getParameterCount() == 1 && m.getParameterTypes()[0].equals(RunInfo.class)), + "@Run method " + m + " must specify either no parameter or exactly one " + RunInfo.class + " parameter."); + Warmup warmupAnno = getAnnotation(m, Warmup.class); TestFormat.checkNoThrow(warmupAnno == null || runAnno.mode() != RunMode.STANDALONE, - "Cannot set @Warmup at @Run method " + m + " when used with RunMode.STANDALONE. The @Run method is only invoked once."); - OSRCompileOnly osrAnno = getAnnotation(testMethod, OSRCompileOnly.class); - TestFormat.checkNoThrow(osrAnno == null || runAnno.mode() != RunMode.STANDALONE, - "Cannot set @OSRCompileOnly at @Run method " + m + " when used with RunMode.STANDALONE. The @Run method is responsible for triggering compilation."); + "Cannot set @Warmup at @Run method " + m + " when used with RunMode.STANDALONE. The @Run method is only invoked once."); } private static T getAnnotation(Method m, Class c) { @@ -570,21 +596,21 @@ private static T getAnnotation(Method m, Class c) { private void runTests() { TreeMap durations = (PRINT_TIMES || VERBOSE) ? new TreeMap<>() : null; long startTime = System.nanoTime(); - Collection testCollection = allTests.values(); + Collection testCollection = allTests.values(); if (SHUFFLE_TESTS) { // Execute tests in random order (execution sequence affects profiling) - ArrayList shuffledList = new ArrayList<>(allTests.values()); + ArrayList shuffledList = new ArrayList<>(allTests.values()); Collections.shuffle(shuffledList); testCollection = shuffledList; } - for (BaseTest test : testCollection) { + for (AbstractTest test : testCollection) { test.run(); if (PRINT_TIMES || VERBOSE) { long endTime = System.nanoTime(); long duration = (endTime - startTime); - durations.put(duration, test.getTestName()); + durations.put(duration, test.getName()); if (VERBOSE) { - System.out.println("Done " + test.getTestName() + ": " + duration + " ns = " + (duration / 1000000) + " ms"); + System.out.println("Done " + test.getName() + ": " + duration + " ns = " + (duration / 1000000) + " ms"); } } if (GC_AFTER) { @@ -691,22 +717,21 @@ private static TriState compiledAtLevel(Method m, CompLevel level) { } } + class DeclaredTest { private final Method testMethod; private final ArgumentValue[] arguments; private final int warmupIterations; private final CompLevel compLevel; - private final boolean osrOnly; private Method attachedMethod; - public DeclaredTest(Method testMethod, ArgumentValue[] arguments, CompLevel compLevel, int warmupIterations, boolean osrOnly) { + public DeclaredTest(Method testMethod, ArgumentValue[] arguments, CompLevel compLevel, int warmupIterations) { // Make sure we can also call non-public or public methods in package private classes testMethod.setAccessible(true); this.testMethod = testMethod; this.compLevel = compLevel; this.arguments = arguments; this.warmupIterations = warmupIterations; - this.osrOnly = osrOnly; this.attachedMethod = null; } @@ -722,10 +747,6 @@ public int getWarmupIterations() { return warmupIterations; } - public boolean isOSROnly() { - return osrOnly; - } - public boolean hasArguments() { return arguments != null; } @@ -783,35 +804,36 @@ public Object invoke(Object obj, Object... args) { } } -class BaseTest { - private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); - private static final int OSR_TEST_TIMEOUT = Integer.parseInt(System.getProperty("OSRTestTimeOut", "5000")); - private static final int TEST_COMPILATION_TIMEOUT = Integer.parseInt(System.getProperty("TestCompilationTimeout", "5000")); - private static final boolean VERIFY_OOPS = (Boolean)WHITE_BOX.getVMFlag("VerifyOops"); - protected final DeclaredTest test; - protected final Method testMethod; - protected final TestInfo testInfo; - private final Object invocationTarget; - private final boolean shouldCompile; - protected int warmupIterations; +abstract class AbstractTest { + protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + protected static final int TEST_COMPILATION_TIMEOUT = Integer.parseInt(System.getProperty("TestCompilationTimeout", "10000")); + protected static final int WAIT_FOR_COMPILATION_TIMEOUT = Integer.parseInt(System.getProperty("WaitForCompilationTimeout", "10000")); + protected static final boolean VERIFY_OOPS = (Boolean)WHITE_BOX.getVMFlag("VerifyOops"); - public BaseTest(DeclaredTest test) { - this.test = test; - this.testMethod = test.getTestMethod(); - this.testInfo = new TestInfo(testMethod); - this.warmupIterations = test.getWarmupIterations(); - this.invocationTarget = getInvocationTarget(testMethod); + protected final int warmupIterations; + + AbstractTest(int warmupIterations) { + this.warmupIterations = warmupIterations; + } + + abstract String getName(); + + final protected boolean shouldCompile(Method testMethod) { if (!TestFrameworkExecution.USE_COMPILER) { - this.shouldCompile = false; + return false; } else if (TestFrameworkExecution.STRESS_CC) { - this.shouldCompile = !TestFrameworkExecution.excludeCompilationRandomly(testMethod); + return !TestFrameworkExecution.excludeCompilationRandomly(testMethod); } else { - this.shouldCompile = true; + return true; } } - protected Object getInvocationTarget(Method method) { + final protected boolean isWaitForCompilation(DeclaredTest test) { + return test.getCompLevel() == CompLevel.WAIT_FOR_COMPILATION; + } + + final protected Object getInvocationTarget(Method method) { Class clazz = method.getDeclaringClass(); Object invocationTarget; if (Modifier.isStatic(method.getModifiers())) { @@ -829,58 +851,88 @@ protected Object getInvocationTarget(Method method) { return invocationTarget; } - public String getTestName() { - return testMethod.getName(); - } - - public Method getAttachedMethod() { return null; } - /** * Run the associated test */ public void run() { - if (test.getCompLevel() == CompLevel.SKIP) { - // Exclude test if compilation level is SKIP either set through test or by not matching the current VM flags. + if (!onRunStart()) { + // Skip this test if set fails. return; } - if (TestFrameworkExecution.VERBOSE) { - System.out.println("Starting " + testMethod); - } - test.printFixedRandomArguments(); for (int i = 0; i < warmupIterations; i++) { - runMethod(); + invokeTest(); } - testInfo.setWarmUpFinished(); - if (test.isOSROnly()) { - compileOSRAndRun(); // TODO: Keep this? - } else { - if (shouldCompile) { - compileTest(); - } - // Always run method. - runMethod(); + onWarmupFinished(); + compileTest(); + // Always run method. + invokeTest(); + } + + abstract boolean onRunStart(); + + abstract void invokeTest(); + + protected void onWarmupFinished() { } + + abstract void compileTest(); + + final protected void compileMethod(DeclaredTest test) { + final Method testMethod = test.getTestMethod(); + TestRun.check(WHITE_BOX.isMethodCompilable(testMethod, test.getCompLevel().getValue(), false), + "Method" + testMethod + " not compilable at level " + test.getCompLevel() + + ". Did you use compileonly without including all @Test methods?"); + TestRun.check(WHITE_BOX.isMethodCompilable(testMethod), + "Method" + testMethod + " not compilable at level " + test.getCompLevel() + + ". Did you use compileonly without including all @Test methods?"); + if (TestFramework.VERBOSE) { + System.out.println("Compile method " + testMethod + " after warm-up..."); } + + final boolean maybeCodeBufferOverflow = (TestFrameworkExecution.TEST_C1 && VERIFY_OOPS); + final long started = System.currentTimeMillis(); + long elapsed = 0; + enqueueMethodForCompilation(test); + + do { + if (!WHITE_BOX.isMethodQueuedForCompilation(testMethod)) { + if (elapsed > 0) { + if (TestFrameworkExecution.VERBOSE) { + System.out.println(testMethod + " is not in queue anymore due to compiling it simultaneously on a different level. Enqueue again."); + } + enqueueMethodForCompilation(test); + } + } + if (maybeCodeBufferOverflow && elapsed > 1000 && !WHITE_BOX.isMethodCompiled(testMethod, false)) { + // Let's disable VerifyOops temporarily and retry. + WHITE_BOX.setBooleanVMFlag("VerifyOops", false); + WHITE_BOX.clearMethodState(testMethod); + enqueueMethodForCompilation(test); + WHITE_BOX.setBooleanVMFlag("VerifyOops", true); + } + + if (WHITE_BOX.getMethodCompilationLevel(testMethod, false) == test.getCompLevel().getValue()) { + break; + } + elapsed = System.currentTimeMillis() - started; + } while (elapsed < TEST_COMPILATION_TIMEOUT); + TestRun.check(elapsed < TEST_COMPILATION_TIMEOUT, + "Could not compile " + testMethod + " after " + TEST_COMPILATION_TIMEOUT/1000 + "s"); + checkCompilationLevel(test); } - protected void runMethod() { - verify(invokeTestMethod()); + private void enqueueMethodForCompilation(DeclaredTest test) { + TestFrameworkExecution.enqueueMethodForCompilation(test.getTestMethod(), test.getCompLevel()); } - private Object invokeTestMethod() { - try { - if (test.hasArguments()) { - return testMethod.invoke(invocationTarget, test.getArguments()); - } else { - return testMethod.invoke(invocationTarget); - } - } catch (Exception e) { - throw new TestRunException("There was an error while invoking @Test method " + testMethod - + ". Used arguments: " + test.getArgumentsString(), e); - } + protected void checkCompilationLevel(DeclaredTest test) { + CompLevel level = CompLevel.forValue(WHITE_BOX.getMethodCompilationLevel(test.getTestMethod())); + TestRun.check(level == test.getCompLevel(), "Compilation level should be " + test.getCompLevel().name() + + " (requested) but was " + level.name() + " for " + test.getTestMethod()); } - private void compileOSRAndRun() { + final protected void waitForCompilation(DeclaredTest test) { + final Method testMethod = test.getTestMethod(); final boolean maybeCodeBufferOverflow = (TestFrameworkExecution.TEST_C1 && VERIFY_OOPS); final long started = System.currentTimeMillis(); boolean stateCleared = false; @@ -888,83 +940,110 @@ private void compileOSRAndRun() { long elapsed = System.currentTimeMillis() - started; int level = WHITE_BOX.getMethodCompilationLevel(testMethod); if (maybeCodeBufferOverflow && elapsed > 5000 - && (!WHITE_BOX.isMethodCompiled(testMethod, false) || level != test.getCompLevel().getValue())) { - retryDisabledVerifyOops(stateCleared); + && (!WHITE_BOX.isMethodCompiled(testMethod, false) || level != test.getCompLevel().getValue())) { + retryDisabledVerifyOops(testMethod, stateCleared); stateCleared = true; } else { - runMethod(); + invokeTest(); } - boolean b = WHITE_BOX.isMethodCompiled(testMethod, false); + boolean isCompiled = WHITE_BOX.isMethodCompiled(testMethod, false); if (TestFrameworkExecution.VERBOSE) { - System.out.println("Is " + testMethod + " compiled? " + b); + System.out.println("Is " + testMethod + " compiled? " + isCompiled); } - if (b || TestFrameworkExecution.XCOMP || TestFrameworkExecution.STRESS_CC || !TestFrameworkExecution.USE_COMPILER) { - // Don't control compilation if -Xcomp is enabled, or if compiler is disabled + if (isCompiled || TestFrameworkExecution.XCOMP) { + // Don't wait for compilation if -Xcomp is enabled. break; } - Asserts.assertTrue(OSR_TEST_TIMEOUT < 0 || elapsed < OSR_TEST_TIMEOUT, testMethod + " not compiled after " + OSR_TEST_TIMEOUT + " ms"); + TestRun.check(WAIT_FOR_COMPILATION_TIMEOUT < 0 || elapsed < WAIT_FOR_COMPILATION_TIMEOUT, + testMethod + " not compiled after waiting for " + WAIT_FOR_COMPILATION_TIMEOUT/1000 + " s"); } } - private void retryDisabledVerifyOops(boolean stateCleared) { + private void retryDisabledVerifyOops(Method testMethod, boolean stateCleared) { System.out.println("Temporarily disabling VerifyOops"); try { WHITE_BOX.setBooleanVMFlag("VerifyOops", false); if (!stateCleared) { WHITE_BOX.clearMethodState(testMethod); } - runMethod(); + invokeTest(); } finally { WHITE_BOX.setBooleanVMFlag("VerifyOops", true); System.out.println("Re-enabled VerifyOops"); } } +} - private void compileTest() { - final boolean maybeCodeBufferOverflow = (TestFrameworkExecution.TEST_C1 && VERIFY_OOPS); - final Method testMethod = test.getTestMethod(); - long started = System.currentTimeMillis(); - long elapsed = 0; - TestRun.check(WHITE_BOX.isMethodCompilable(testMethod, test.getCompLevel().getValue(), false), - "Method" + testMethod + " not compilable at level " + test.getCompLevel() - + ". Did you use compileonly without including all @Test methods?"); - enqueueMethodForCompilation(); - do { - if (!WHITE_BOX.isMethodQueuedForCompilation(testMethod)) { - if (elapsed > 0) { - if (TestFrameworkExecution.VERBOSE) { - System.out.println(testMethod + " is not in queue anymore due to compiling it simultaneously on a different level. Enqueue again."); - } - enqueueMethodForCompilation(); - } - } - if (maybeCodeBufferOverflow && elapsed > 1000 && !WHITE_BOX.isMethodCompiled(testMethod, false)) { - // Let's disable VerifyOops temporarily and retry. - WHITE_BOX.setBooleanVMFlag("VerifyOops", false); - WHITE_BOX.clearMethodState(testMethod); - enqueueMethodForCompilation(); - WHITE_BOX.setBooleanVMFlag("VerifyOops", true); - } +class BaseTest extends AbstractTest { + private final DeclaredTest test; + protected final Method testMethod; + protected final TestInfo testInfo; + private final Object invocationTarget; + private final boolean shouldCompile; + private final boolean waitForCompilation; - if (WHITE_BOX.getMethodCompilationLevel(testMethod, false) == test.getCompLevel().getValue()) { - break; - } - elapsed = System.currentTimeMillis() - started; - } while (elapsed < TEST_COMPILATION_TIMEOUT); - TestRun.check(elapsed < TEST_COMPILATION_TIMEOUT, "Could not compile" + testMethod + " after " + TEST_COMPILATION_TIMEOUT/1000 + "s"); - checkCompilationLevel(); + public BaseTest(DeclaredTest test) { + super(test.getWarmupIterations()); + this.test = test; + this.testMethod = test.getTestMethod(); + this.testInfo = new TestInfo(testMethod); + this.invocationTarget = getInvocationTarget(testMethod); + this.shouldCompile = shouldCompile(testMethod); + this.waitForCompilation = isWaitForCompilation(test); } - private void enqueueMethodForCompilation() { - TestFrameworkExecution.enqueueMethodForCompilation(test.getTestMethod(), test.getCompLevel()); + @Override + public String getName() { + return testMethod.getName(); + } + + @Override + protected boolean onRunStart() { + if (test.getCompLevel() == CompLevel.SKIP) { + // Exclude test if compilation level is SKIP either set through test or by not matching the current VM flags. + return false; + } + if (TestFrameworkExecution.VERBOSE) { + System.out.println("Starting " + getName()); + } + test.printFixedRandomArguments(); + return true; + } + + @Override + public void onWarmupFinished() { + testInfo.setWarmUpFinished(); + } + + @Override + protected void invokeTest() { + verify(invokeTestMethod()); + } + + private Object invokeTestMethod() { + try { + if (test.hasArguments()) { + return testMethod.invoke(invocationTarget, test.getArguments()); + } else { + return testMethod.invoke(invocationTarget); + } + } catch (Exception e) { + throw new TestRunException("There was an error while invoking @Test method " + testMethod + + ". Used arguments: " + test.getArgumentsString(), e); + } } - protected void checkCompilationLevel() { - CompLevel level = CompLevel.forValue(WHITE_BOX.getMethodCompilationLevel(testMethod)); - TestRun.check(level == test.getCompLevel(), - "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod); + @Override + protected void compileTest() { + if (shouldCompile) { + if (waitForCompilation) { + waitForCompilation(test); + } else { + compileMethod(test); + } + } } /** @@ -973,6 +1052,7 @@ protected void checkCompilationLevel() { public void verify(Object result) { /* no verification in BaseTests */ } } + class CheckedTest extends BaseTest { private final Method checkMethod; private final CheckAt checkAt; @@ -994,7 +1074,9 @@ public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecificati } @Override - public Method getAttachedMethod() { return checkMethod; } + public String getName() { + return checkMethod.getName(); + } @Override public void verify(Object result) { @@ -1018,41 +1100,128 @@ public void verify(Object result) { } } -class CustomRunTest extends BaseTest { + +class CustomRunTest extends AbstractTest { private final Method runMethod; private final RunMode mode; private final Object runInvocationTarget; + private final List tests; + private final RunInfo runInfo; - public CustomRunTest(DeclaredTest test, Method runMethod, Warmup warmUpAnno, Run runSpecification) { - super(test); + public CustomRunTest(Method runMethod, Warmup warmUpAnno, Run runSpecification, List tests) { // Make sure we can also call non-public or public methods in package private classes + super(warmUpAnno != null ? warmUpAnno.value() : TestFrameworkExecution.WARMUP_ITERATIONS); + TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + runMethod); runMethod.setAccessible(true); this.runMethod = runMethod; this.runInvocationTarget = getInvocationTarget(runMethod); this.mode = runSpecification.mode(); - this.warmupIterations = warmUpAnno != null ? warmUpAnno.value() : test.getWarmupIterations(); - TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + runMethod); + this.tests = tests; + if (tests.size() == 1) { + this.runInfo = new RunInfo(tests.get(0).getTestMethod()); + } else { + this.runInfo = new RunInfo(tests.stream().map(DeclaredTest::getTestMethod).collect(Collectors.toList())); + } } @Override - public Method getAttachedMethod() { return runMethod; } + protected boolean onRunStart() { + if (tests.stream().anyMatch(t -> t.getCompLevel() == CompLevel.SKIP)) { + // Exclude test if any compilation level is SKIP either set through test or by not matching the current VM flags. + return false; + } + + if (TestFrameworkExecution.VERBOSE) { + System.out.println("Starting " + getName()); + } + return true; + } + + @Override + String getName() { + return runMethod.getName(); + } @Override public void run() { + if (!onRunStart()) { + // Skip this test if set fails. + return; + } + switch (mode) { - case STANDALONE -> runMethod(); + case STANDALONE -> { + runInfo.setWarmUpFinished(); + invokeTest(); + }// Invoke once but do not apply anything else. case NORMAL -> super.run(); } } + @Override + public void onWarmupFinished() { + runInfo.setWarmUpFinished(); + } + + @Override + protected void compileTest() { + if (tests.size() == 1) { + compileSingleTest(); + } else { + compileMultipleTests(); + } + } + + private void compileSingleTest() { + DeclaredTest test = tests.get(0); + if (shouldCompile(test.getTestMethod())) { + if (isWaitForCompilation(test)) { + waitForCompilation(test); + } else { + compileMethod(test); + } + } + } + + private void compileMultipleTests() { + boolean anyWaitForCompilation = false; + boolean anyCompileMethod = false; + ExecutorService executor = Executors.newFixedThreadPool(tests.size()); + for (DeclaredTest test : tests) { + if (shouldCompile(test.getTestMethod())) { + if (isWaitForCompilation(test)) { + anyWaitForCompilation = true; + executor.execute(() -> waitForCompilation(test)); + } else { + anyCompileMethod = true; + executor.execute(() -> compileMethod(test)); + } + } + } + executor.shutdown(); + int timeout; + if (anyCompileMethod && anyWaitForCompilation) { + timeout = Math.max(WAIT_FOR_COMPILATION_TIMEOUT, TEST_COMPILATION_TIMEOUT) + 5000; + } else if (anyWaitForCompilation) { + timeout = WAIT_FOR_COMPILATION_TIMEOUT + 5000; + } else { + timeout = TEST_COMPILATION_TIMEOUT + 5000; + } + try { + executor.awaitTermination(timeout, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + TestRun.fail("Some compilations did not complete after " + timeout + "ms for @Run method " + runMethod); + } + } + /** * Do not directly run the test but rather the run method that is responsible for invoking the actual test. */ @Override - protected void runMethod() { + protected void invokeTest() { try { if (runMethod.getParameterCount() == 1) { - runMethod.invoke(runInvocationTarget, testInfo); + runMethod.invoke(runInvocationTarget, runInfo); } else { runMethod.invoke(runInvocationTarget); } @@ -1062,13 +1231,15 @@ protected void runMethod() { } @Override - protected void checkCompilationLevel() { - CompLevel level = CompLevel.forValue(WhiteBox.getWhiteBox().getMethodCompilationLevel(testMethod)); + protected void checkCompilationLevel(DeclaredTest test) { + CompLevel level = CompLevel.forValue(WhiteBox.getWhiteBox().getMethodCompilationLevel(test.getTestMethod())); if (level != test.getCompLevel()) { - String message = "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " + level.name() + " for " + testMethod + "."; + String message = "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " + + level.name() + " for " + test.getTestMethod() + "."; switch (mode) { - case STANDALONE -> message = message + "\nCheck your @Run method (invoked once) " + runMethod + " to ensure that " + testMethod + " will be complied at the requested level."; - case NORMAL -> message = message + "\nCheck your @Run method " + runMethod + " to ensure that " + testMethod + " is called at least once in each iteration."; + case STANDALONE -> TestFramework.fail("Should not be called for STANDALONE method " + runMethod); + case NORMAL -> message = message + "\nCheck your @Run method " + runMethod + " to ensure that " + + test.getTestMethod() + " is called at least once in each iteration."; } TestRun.fail(message); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java index 0c17bd3a951..fec418e2aba 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java @@ -24,73 +24,25 @@ package jdk.test.lib.hotspot.ir_framework; import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Random; -import java.util.stream.Collectors; -public class TestInfo { - private static final Random random = new Random(); +public class TestInfo extends AbstractInfo { private final Method testMethod; - private boolean toggleBool = false; - private boolean onWarmUp = true; TestInfo(Method testMethod) { + super(testMethod.getDeclaringClass()); this.testMethod = testMethod; } - public boolean toggleBoolean() { - toggleBool = !toggleBool; - return toggleBool; - } - - public static int getRandomInt() { - return random.nextInt() % 1000; - } - - public static long getRandomLong() { - return random.nextLong() % 1000; - } - - public static double getRandomDouble() { - return random.nextDouble() % 1000; - } - - public boolean isWarmUp() { - return onWarmUp; - } - - void setWarmUpFinished() { - onWarmUp = false; - } - public Method getTest() { return testMethod; } - public Method getMethod(Class c, String name, Class... args) { - try { - return c.getMethod(name, args); - } catch (NoSuchMethodException e) { - String parameters = args == null || args.length == 0 ? "" : - " with arguments [" + Arrays.stream(args).map(Class::getName).collect(Collectors.joining(",")) + "]"; - throw new TestRunException("Could not find method " + name + " in " + c + parameters); - } - } - - public Method getTestClassMethod(String name, Class... args) { - return getMethod(testMethod.getDeclaringClass(), name, args); - } - - public boolean isC1Test() { - return TestFrameworkExecution.TEST_C1; - } - - public boolean isC1Compiled(Method m) { + public boolean isC1Compiled() { return TestFrameworkExecution.isC1Compiled(testMethod); } - public boolean isC2Compiled(Method m) { + public boolean isC2Compiled() { return TestFrameworkExecution.isC2Compiled(testMethod); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/RunExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/RunExample.java index 59fa60949d6..6909e6e1a16 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/RunExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/RunExample.java @@ -41,9 +41,9 @@ public static void main(String[] args) { /* * If there is no warm up specified the Test Framework will do the following: * - Invoke @Run method TestFrameworkExecution.WARMUP_ITERATIONS many times. Note that the @Run method is responsible - * to invoke the @Test method. This is not done by the framework. The @Run method can do any arbitrary argument setup + * to invoke the @Test methods. This is not done by the framework. The @Run method can do any arbitrary argument setup * and return value verification. - * - After the warmup, the @Test method is compiled. + * - After the warm-up, the @Test methods are compiled (there can be multiple @Test methods). * - Invoke @Run method once again. */ @@ -55,6 +55,7 @@ public static void main(String[] args) { * - No @Arguments, these are set by @Run method. * - At @Run method: * - @Warmup: Change warm-up iterations of @Run method (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS) + * - test: Specify any number of @Test methods. They cannot be shared with other @Check or @Run methods. * - mode: Choose between normal invocation as described above or STANDALONE. STANDALONE only invokes the @Run * method once without warmup or a compilation by the Test Framework. * - No @IR annotations @@ -76,13 +77,13 @@ public void basicRun() { } @Test - public int test2() { - return 42; + public int test2(int x) { + return x; } - // This version of @Run passes the TestInfo object as an argument. No other argument combinations are allowed. + // This version of @Run passes the RunInfo object as an argument. No other argument combinations are allowed. @Run(test = "test2") - public void runWithTestInfo(TestInfo info) { + public void runWithRunInfo(RunInfo info) { int returnValue = test(34); if (returnValue != 34) { throw new RuntimeException("Must match"); @@ -90,32 +91,55 @@ public void runWithTestInfo(TestInfo info) { } @Test - public int test3() { - return 42; + public int test3(int x) { + return x; } // This version of @Run uses a user defined @Warmup. @Run(test = "test3") @Warmup(100) public void runWithWarmUp() { - int returnValue = test(34); + int returnValue = test3(34); if (returnValue != 34) { throw new RuntimeException("Must match"); } } @Test - public int test4() { - return 42; + public int test4(int x) { + return x; } // This version of @Run is only invoked once by the Test Framework. There is no warm up and no compilation done // by the Test Framework @Run(test = "test4", mode = RunMode.STANDALONE) public void runOnlyOnce() { - int returnValue = test(34); + int returnValue = test4(34); + if (returnValue != 34) { + throw new RuntimeException("Must match"); + } + } + + @Test + public int test5(int x) { + return x; + } + + @Test + public int test6(int x) { + return x; + } + + // This version of @Run can run multiple test methods and get them IR checked as part of this custom run test. + @Run(test = {"test5", "test6"}) + public void runMultipleTests() { + int returnValue = test5(34); if (returnValue != 34) { throw new RuntimeException("Must match"); } + returnValue = test6(42); + if (returnValue != 42) { + throw new RuntimeException("Must match"); + } } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TestExample.java index 1e40a585c67..f1332ca4429 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TestExample.java @@ -43,12 +43,15 @@ public static void main(String[] args) { /* * If there is no warm up specified the Test Framework will do the following: * - Invoke @Test method TestFrameworkExecution.WARMUP_ITERATIONS many times. - * - Then do compilation of @Test method. + * - Then do compilation of @Test method. (**) * - Invoke @Test method once again */ /* * Configurable things for simple tests (no @Run or @Check) at @Test method: + * - compLevel: Specify at which compilation level the test should be compiled by the framework at step (**). + * If WAIT_FOR_COMPILATION is specified, the framework will continue to invoke the method until + * HotSpot compiles it. If it is not compiled after 10s, an exception is thrown. * - @Warmup: Change warm-up iterations of test (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS) * - @Arguments: If a @Test method specifies arguments, you need to provide arguments by using @Arguments such * that the framework knows how to call the method. If you need more complex values, use @Run. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java index c362bd40500..1775aeb3e18 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java @@ -313,6 +313,12 @@ public void invalidSkip1() {} @DontCompile(CompLevel.SKIP) public void invalidSkip2() {} + @ForceCompile(CompLevel.WAIT_FOR_COMPILATION) + public void invalidWaitForCompilation() {} + + @DontCompile(CompLevel.WAIT_FOR_COMPILATION) + public void invalidWaitForCompilation2() {} + @ForceCompile(CompLevel.C1) @DontCompile(CompLevel.C1) public void overlappingCompile1() {} @@ -373,7 +379,21 @@ public void someTest3() {} @FailCount(2) // Negative warmup and invoke once @Run(test = "someTest3", mode = RunMode.STANDALONE) @Warmup(-1) - public void noWarmupAtInvokeOnce() {} + public void noWarmupAtStandalone() {} + + @Test(compLevel = CompLevel.C1) + public void testNoCompLevelStandalone() {} + + @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) + public void testNoCompLevelStandalone2() {} + + @NoFail + @Test + public void someTest4() {} + + @FailCount(0) // Negative warmup and invoke once + @Run(test = {"someTest4", "testNoCompLevelStandalone", "testNoCompLevelStandalone2"}, mode = RunMode.STANDALONE) + public void runNoCompLevelStandalone() {} } class BadBaseTests { @@ -426,7 +446,7 @@ public void wrongParameters1(int x) {} public void test2() {} @Run(test = "test2") - public void wrongParameters(TestInfo info, int x) {} + public void wrongParameters(RunInfo info, int x) {} @Test public void invalidShare() {} @@ -456,7 +476,47 @@ public void testInvalidRunWithArgAnnotation() {} @Arguments(Argument.DEFAULT) @Run(test = "testInvalidRunWithArgAnnotation") - public void invalidRunWithArgAnnotation(TestInfo info) {} + public void invalidRunWithArgAnnotation(RunInfo info) {} + + @NoFail + @Test + public void testRunWithTestInfo() {} + + @Run(test = "testRunWithTestInfo") + public void invalidRunWithTestInfo(TestInfo info) {} + + @Run(test = {}) + public void invalidRunWithNoTest() {} + + @Run(test = "") + public void invalidRunWithEmptyTestName() {} + + @NoFail + @Test + public void someExistingTest() {} + + @FailCount(2) + @Run(test = {"unknown1", "someExistingTest", "unknown2"}) + public void invalidRunWithInvalidTests() {} + + @NoFail + @Test + public void testInvalidReuse() {} + + @Test + public void testInvalidReuse2() {} + + @NoFail + @Test + public void testInvalidReuse3() {} + + @FailCount(0) + @Run(test = {"testInvalidReuse", "testInvalidReuse2"}) + public void runInvalidReuse1() {} + + @FailCount(0) + @Run(test = {"testInvalidReuse2", "testInvalidReuse3"}) + public void runInvalidReuse2() {} } class BadCheckTest { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java index 661e846a605..a7822109b40 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java @@ -32,7 +32,7 @@ public class TestBasics { private static boolean wasExecuted = false; private boolean lastToggleBoolean = true; - private final static int[] executed = new int[96]; + private final static int[] executed = new int[100]; private final static int[] executedOnce = new int[5]; private long[] nonFloatingRandomNumbers = new long[10]; private double[] floatingRandomNumbers = new double[10]; @@ -961,7 +961,7 @@ public void sameName2() { // Allowed to overload test method if not test method itself @Run(test = "sameName2") - public void sameName2(TestInfo info) { + public void sameName2(RunInfo info) { executed[93]++; sameName2(); } @@ -974,7 +974,7 @@ public void testRun() { // Custom run test. This method is invoked each time instead of @Test method. This method responsible for calling // the @Test method. @Test method is compiled after warm up. This is similar to the verifiers in the old Valhalla framework. @Run(test = "testRun") - public void runTestRun(TestInfo info) { + public void runTestRun(RunInfo info) { testRun(); } @@ -1006,7 +1006,7 @@ public void testRunOnce() { // Custom run test that is only invoked once. There is no warm up and no compilation. This method is responsible // for triggering compilation. @Run(test = "testRunOnce", mode = RunMode.STANDALONE) - public void runTestRunOnce(TestInfo info) { + public void runTestRunOnce(RunInfo info) { testRunOnce(); } @@ -1016,11 +1016,56 @@ public void testRunOnce2() { } @Run(test = "testRunOnce2", mode = RunMode.STANDALONE) - public void runTestRunOnce2(TestInfo info) { + public void runTestRunOnce2(RunInfo info) { for (int i = 0; i < TestFrameworkExecution.WARMUP_ITERATIONS + 1; i++) { testRunOnce2(); } } + + @Test + public void testRunMultiple() { + executed[96]++; + } + + @Test + public void testRunMultiple2() { + executed[97]++; + } + + @Test + public void testRunMultipleNotExecuted() { + wasExecuted = true; + } + + @Run(test = {"testRunMultiple", "testRunMultiple2", "testRunMultipleNotExecuted"}) + public void runTestRunMultiple() { + testRunMultiple(); + testRunMultiple2(); + } + + + @Test + public void testRunMultiple3() { + executed[98]++; + } + + @Test + public void testRunMultiple4() { + executed[99]++; + } + + @Test + public void testRunMultipleNotExecuted2() { + wasExecuted = true; + } + + @Run(test = {"testRunMultiple3", "testRunMultiple4", "testRunMultipleNotExecuted2"}, mode = RunMode.STANDALONE) + public void runTestRunMultipl2(RunInfo info) { + for (int i = 0; i < TestFrameworkExecution.WARMUP_ITERATIONS + 1; i++) { + testRunMultiple3(); + testRunMultiple4(); + } + } } class DefaultObject { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java index 92a6b57d8c6..d78fd20e9e1 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java @@ -149,7 +149,7 @@ public static void dontCompile2() { @Run(test = "testCompileAtLevel1") @Warmup(5000) - public void runTestDontCompile2(TestInfo info) throws NoSuchMethodException { + public void runTestDontCompile2(RunInfo info) throws NoSuchMethodException { dontCompile2(); testCompileAtLevel1(); if (!info.isWarmUp()) { @@ -174,7 +174,7 @@ public void noWarmup2() { @Run(test = "noWarmup2") @Warmup(0) - public void runNoWarmup2(TestInfo info) { + public void runNoWarmup2(RunInfo info) { noWarmup2(); noWarmup2(); Asserts.assertTrue(!info.isWarmUp()); @@ -253,7 +253,7 @@ public void forceC2DontC1() { @Run(test = "testCompilation") @Warmup(0) - public void runTestCompilation(TestInfo info) { + public void runTestCompilation(RunInfo info) { for (int i = 0; i < 10000; i++) { dontCompileAny(); dontCompileC1(); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java index 7cf9dad3303..59f1d8af083 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java @@ -86,6 +86,15 @@ public static void main(String[] args) { BadFailOnConstraint.create(AllocArray.class, "allocArray()", 5, allocArrayMatches) ); + runCheck(GoodRuleConstraint.create(RunTests.class, "good1()", 1), + GoodRuleConstraint.create(RunTests.class, "good1()", 2), + GoodRuleConstraint.create(RunTests.class, "good2()", 1), + GoodRuleConstraint.create(RunTests.class, "good2()", 2), + GoodRuleConstraint.create(RunTests.class, "good3(int)", 1), + BadCountsConstraint.create(RunTests.class, "bad1(int)", 1, 0), + BadFailOnConstraint.create(RunTests.class, "bad1(int)", 2, "Load") + ); + runCheck(new String[] {"-XX:-UseCompressedClassPointers"}, BadFailOnConstraint.create(Loads.class, "load()", 1, 1, "Load"), BadFailOnConstraint.create(Loads.class, "load()", 1, 3, "LoadI"), @@ -706,6 +715,52 @@ public void bad3() { } +class RunTests { + public int iFld; + + @Test + @IR(counts = {IRNode.STORE, "1"}) + @IR(failOn = IRNode.LOAD) + public void good1() { + iFld = 42; + } + + @Test + @IR(counts = {IRNode.LOAD, "1"}) + @IR(failOn = IRNode.STORE) + public int good2() { + return iFld; + } + + @Run(test = {"good1", "good2"}) + public void runGood1() { + good1(); + good2(); + } + + + @Test + @IR(counts = {IRNode.STORE, "1"}) + @IR(failOn = IRNode.LOAD) + public void good3(int x) { + iFld = x; + } + + @Test + @IR(counts = {IRNode.STORE, "1"}) + @IR(failOn = IRNode.LOAD) + public int bad1(int x) { + return iFld + x; + } + + @Run(test = {"bad1", "good3"}) + public void run() { + bad1(2); + good3(4); + } +} + + class AllocArray { MyClass[] myClassArray; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java new file mode 100644 index 00000000000..909c6c7cb79 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework.tests; + +import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; + +import java.util.Arrays; + +public class TestRunTests { + + public static void main(String[] args) { + TestFramework.run(); + try { + TestFramework.run(BadStandalone.class); + throw new RuntimeException("Should not reach"); + } catch (IRViolationException e) { + String[] matches = { "test(int)", "test2(int)", "Failed IR Rules (2)"}; + Arrays.stream(matches).forEach(m -> Asserts.assertTrue(e.getMessage().contains(m))); + Asserts.assertEQ(e.getMessage().split("STANDALONE mode", -1).length - 1, 2); + } + } + public int iFld; + + @Test + @IR(counts = {IRNode.STORE_I, "1"}) + public int test1(int x) { + iFld = x; + return x; + } + + @Test + @IR(counts = {IRNode.STORE_I, "1"}) + public int test2(int y) { + iFld = y; + return y; + } + + @Run(test = {"test1", "test2"}) + public void run(RunInfo info) { + test1(23); + test2(42); + if (!info.isWarmUp()) { + info.assertTestCompiledByC2("test1"); + info.assertTestCompiledByC2("test2"); + } + } + + @Test + @IR(counts = {IRNode.STORE_I, "1"}) + public int test3(int x) { + iFld = x; + return x; + } + + @Run(test = "test3") + public void run2(RunInfo info) { + test3(42); + if (!info.isWarmUp()) { + info.assertTestCompiledByC2(); + } + } + + + @Test + @IR(counts = {IRNode.STORE_I, "1"}) + public int test4(int x) { + iFld = x; + return x; + } + + @Run(test = "test4", mode = RunMode.STANDALONE) + public void run3(RunInfo info) { + for (int i = 0; i < 2000; i++) { + test4(i); + } + } + + @Test + @IR(counts = {IRNode.STORE_I, "1"}) + public int test5(int x) { + iFld = x; + return x; + } + + @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) + @IR(counts = {IRNode.STORE_I, "1"}) + public int test6(int y) { + iFld = y; + return y; + } + + @Run(test = {"test5", "test6"}) + public void run4(RunInfo info) { + test5(23); + test6(42); + if (!info.isWarmUp()) { + info.assertTestCompiledByC2("test5"); + info.assertTestCompiledByC2("test6"); + } + } + + + @Test + @IR(counts = {IRNode.STORE_I, "1"}) + public int test7(int x) { + for (int i = 0; i < 100; i++); + iFld = x; + return x; + } + + + @Test + @IR(counts = {IRNode.STORE_I, "1"}) + public int test8(int x) { + for (int i = 0; i < 100; i++); + iFld = x; + return x; + } + + @Run(test = {"test7", "test8"}, mode = RunMode.STANDALONE) + public void run5() { + for (int i = 0; i < 10000; i++) { + test7(23); + test8(42); + } + } + + @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) + @Warmup(0) + public void test9() { + TestClass tmp = new TestClass(); + for (int i = 0; i < 100; ++i) { + tmp.test(); + } + } + + static class TestClass { + public int test() { + int res = 0; + for (int i = 1; i < 20_000; ++i) { + res -= i; + } + return res; + } + } +} + +class BadStandalone { + int iFld; + + @Test + @IR(counts = {IRNode.STORE_I, "1"}) + public int test(int x) { + iFld = x; + return x; + } + + @Run(test = "test", mode = RunMode.STANDALONE) + public void run(RunInfo info) { + test(42); + } + + @Test + @IR(counts = {IRNode.STORE_I, "1"}) + public int test2(int x) { + iFld = x; + return x; + } + + @Run(test = "test2", mode = RunMode.STANDALONE) + public void run2(RunInfo info) { + } +} From 40b6ce2448949d02fad3f75bb1b355441e072bcf Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 17 Mar 2021 16:00:06 +0100 Subject: [PATCH 050/131] Support helper annotations on constructors, add @ForceCompileClassInitializer with tests, add checks for @ForceCompile if compiled and add better restrictions, change compilation default to CompLevel.ANY, also print random character as int --- .../valhalla/inlinetypes/InlineTypes.java | 11 +- .../hotspot/ir_framework/ForceCompile.java | 7 +- .../ForceCompileClassInitializer.java | 50 +++++ .../hotspot/ir_framework/TestFramework.java | 4 +- .../ir_framework/TestFrameworkExecution.java | 207 +++++++++++------- .../TestFrameworkPrepareFlags.java | 14 +- .../ir_framework/tests/TestBadFormat.java | 68 +++++- .../ir_framework/tests/TestControls.java | 33 +++ 8 files changed, 295 insertions(+), 99 deletions(-) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompileClassInitializer.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java index 8686ad24944..f5d342c0518 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java @@ -2,10 +2,7 @@ import jdk.test.lib.Asserts; import jdk.test.lib.Utils; -import jdk.test.lib.hotspot.ir_framework.DontCompile; -import jdk.test.lib.hotspot.ir_framework.DontInline; -import jdk.test.lib.hotspot.ir_framework.ForceInline; -import jdk.test.lib.hotspot.ir_framework.Scenario; +import jdk.test.lib.hotspot.ir_framework.*; public class InlineTypes { public static final int rI = Utils.getRandomInstance().nextInt() % 1000; @@ -170,6 +167,7 @@ static SimpleInlineType create() { } } +@ForceCompileClassInitializer final primitive class MyValue1 implements MyInterface { static int s; static final long sf = InlineTypes.rL; @@ -302,6 +300,7 @@ static MyValue1 setV2(MyValue1 v, MyValue2 v2) { } } +@ForceCompileClassInitializer final primitive class MyValue2Inline { final double d; final long l; @@ -336,6 +335,7 @@ public static MyValue2Inline createWithFieldsInline(double d, long l) { } } +@ForceCompileClassInitializer final primitive class MyValue2 implements MyInterface { final int x; final byte y; @@ -411,6 +411,7 @@ static MyValue2 setV(MyValue2 v, MyValue2Inline vi) { } } +@ForceCompileClassInitializer final primitive class MyValue3Inline { final float f7; final double f8; @@ -447,6 +448,7 @@ public static MyValue3Inline createWithFieldsInline(float f7, double f8) { // Inline type definition to stress test return of an inline type in registers // (uses all registers of calling convention on x86_64) +@ForceCompileClassInitializer final primitive class MyValue3 extends MyAbstract { final char c; final byte bb; @@ -633,6 +635,7 @@ public long hash() { } // Inline type definition with too many fields to return in registers +@ForceCompileClassInitializer final primitive class MyValue4 implements MyInterface { final MyValue3 v1; final MyValue3 v2; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java index 9d32afedbce..18f95c08213 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java @@ -37,13 +37,14 @@ *

  • {@link CompLevel#C1_FULL_PROFILE}: Level 3: C1 compilation with full profile information: * Includes Invocation and backedge counters with MDO.

  • *
  • {@link CompLevel#C2}: Level 4: C2 compilation with full optimizations.

  • - *
  • {@link CompLevel#SKIP}: Does not apply to {@link ForceCompile @ForceCompile} and results in a + *

  • {@link CompLevel#SKIP}: Does not apply to {@code @ForceCompile} and results in a * {@link TestFormatException TestFormatException}.

  • - * + *
  • {@link CompLevel#WAIT_FOR_COMPILATION}: Does not apply to {@code @ForceCompile} and results in a + * {@link TestFormatException TestFormatException}.

  • * *

    * Using this annotation on non-helper methods results in a {@link TestFormatException TestFormatException}. */ @Retention(RetentionPolicy.RUNTIME) public @interface ForceCompile { - CompLevel value() default CompLevel.C2; + CompLevel value() default CompLevel.ANY; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompileClassInitializer.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompileClassInitializer.java new file mode 100644 index 00000000000..6c48d8a1575 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompileClassInitializer.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Force compilation of the annotated test or helper class immediately at the specified level: + *

      + *
    • {@link CompLevel#ANY} (default): Highest available compilation level which is usually C2.

    • + *
    • {@link CompLevel#C1}: Level 1: C1 compilation without any profile information.

    • + *
    • {@link CompLevel#C1_LIMITED_PROFILE}: Level 2: C1 compilation with limited profile information: + * Includes Invocation and backedge counters.

    • + *
    • {@link CompLevel#C1_FULL_PROFILE}: Level 3: C1 compilation with full profile information: + * Includes Invocation and backedge counters with MDO.

    • + *
    • {@link CompLevel#C2}: Level 4: C2 compilation with full optimizations.

    • + *
    • {@link CompLevel#SKIP}: Does not apply to {@code @ForceCompileClassInitializer} and results in a + * {@link TestFormatException TestFormatException}.

    • + *
    • {@link CompLevel#WAIT_FOR_COMPILATION}: Does not apply to {@code @ForceCompileClassInitializer} and results in a + * {@link TestFormatException TestFormatException}.

    • + *
    + *

    + * Using this annotation on non-classes results in a {@link TestFormatException TestFormatException}. + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface ForceCompileClassInitializer { + CompLevel value() default CompLevel.ANY; +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 94c965d856b..d33f7b7777f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -414,12 +414,12 @@ private void reportScenarioFailures(Map exceptionMap) { builder.append("Scenario flags: [").append(String.join(", ", scenario.getFlags())).append("]\n\n"); Exception e = entry.getValue(); if (e instanceof IRViolationException) { - // For IR violations, only show the actual message and not the (uninteresting) stack trace. + // For IR violations, only show the actual violations and not the (uninteresting) stack trace. builder.append(e.getMessage()); } else { // Print stack trace if it was not a format violation or test run exception StringWriter errors = new StringWriter(); - entry.getValue().printStackTrace(new PrintWriter(errors)); + e.printStackTrace(new PrintWriter(errors)); builder.append(errors.toString()); } builder.append("\n"); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 2f0b98362ad..0b68e0bfb9c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -28,9 +28,7 @@ import sun.hotspot.WhiteBox; import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; +import java.lang.reflect.*; import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -83,6 +81,7 @@ public class TestFrameworkExecution { private List> helperClasses = null; private final IREncodingPrinter irMatchRulePrinter; private final Class testClass; + private final Map forceCompileMap = new HashMap<>(); private TestFrameworkExecution(Class testClass) { TestRun.check(testClass != null, "Test class cannot be null"); @@ -97,7 +96,7 @@ private TestFrameworkExecution(Class testClass) { } } - private List createTestFilterList(String list, Class testClass) { + private static List createTestFilterList(String list, Class testClass) { List filterList = null; if (!list.isEmpty()) { String classPrefix = testClass.getSimpleName() + "."; @@ -176,10 +175,11 @@ private void start() { for (Class helperClass : helperClasses) { // Process the helper classes and apply the explicit compile commands checkHelperClass(helperClass); - processExplicitCompileCommands(helperClass); + processControlAnnotations(helperClass); } } parseTestClass(); + checkForcedCompilationsCompleted(); runTests(); } @@ -203,7 +203,7 @@ private void parseTestClass() { checkTestAnnotationInnerClass(clazz, "inner"); } addReplay(); - processExplicitCompileCommands(testClass); + processControlAnnotations(testClass); setupTests(); setupCheckAndRunMethods(); @@ -236,21 +236,24 @@ private void addReplay() { } } - private void processExplicitCompileCommands(Class clazz) { + private void processControlAnnotations(Class clazz) { if (!XCOMP) { // Don't control compilations if -Xcomp is enabled. // Also apply compile commands to all inner classes of 'clazz'. ArrayList> classes = new ArrayList<>(Arrays.asList(clazz.getDeclaredClasses())); classes.add(clazz); for (Class c : classes) { - Method[] methods = c.getDeclaredMethods(); - for (Method m : methods) { + applyClassAnnotations(c); + List executables = new ArrayList<>(Arrays.asList(c.getDeclaredMethods())); + Collections.addAll(executables, c.getDeclaredConstructors()); + for (Executable ex : executables) { + checkClassAnnotations(ex); try { - applyIndependentCompilationCommands(m); + applyIndependentCompilationCommands(ex); if (STRESS_CC) { - if (getAnnotation(m, Test.class) != null) { - excludeCompilationRandomly(m); + if (getAnnotation(ex, Test.class) != null) { + excludeCompilationRandomly(ex); } } } catch (TestFormatException e) { @@ -259,9 +262,9 @@ private void processExplicitCompileCommands(Class clazz) { } // Only force compilation now because above annotations affect inlining - for (Method m : methods) { + for (Executable ex : executables) { try { - applyForceCompileCommand(m); + applyForceCompileCommand(ex); } catch (TestFormatException e) { // Failure logged. Continue and report later. } @@ -270,61 +273,83 @@ private void processExplicitCompileCommands(Class clazz) { } } - static boolean excludeCompilationRandomly(Method m) { + private void applyClassAnnotations(Class c) { + ForceCompileClassInitializer anno = getAnnotation(c, ForceCompileClassInitializer.class); + if (anno != null) { + // Compile class initializer + CompLevel level = anno.value(); + if (level == CompLevel.SKIP || level == CompLevel.WAIT_FOR_COMPILATION) { + TestFormat.failNoThrow("Cannot define compilation level SKIP or WAIT_FOR_COMPILATION in " + + "@ForceCompileClassInitializer at " + c); + return; + } + level = restrictCompLevel(anno.value()); + if (level != CompLevel.SKIP) { + WHITE_BOX.enqueueInitializerForCompilation(c, level.getValue()); + } + } + } + + private void checkClassAnnotations(Executable ex) { + TestFormat.checkNoThrow(getAnnotation(ex, ForceCompileClassInitializer.class) == null, + "@ForceCompileClassInitializer only allowed at classes but not at method " + ex); + } + + static boolean excludeCompilationRandomly(Executable ex) { // Exclude some methods from compilation with C2 to stress test the calling convention boolean exclude = Utils.getRandomInstance().nextBoolean(); if (exclude) { - System.out.println("Excluding from C2 compilation: " + m); - WHITE_BOX.makeMethodNotCompilable(m, CompLevel.C2.getValue(), false); - WHITE_BOX.makeMethodNotCompilable(m, CompLevel.C2.getValue(), true); + System.out.println("Excluding from C2 compilation: " + ex); + WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.C2.getValue(), false); + WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.C2.getValue(), true); } return exclude; } - private void applyIndependentCompilationCommands(Method m) { - ForceInline forceInlineAnno = getAnnotation(m, ForceInline.class); - DontInline dontInlineAnno = getAnnotation(m, DontInline.class); - ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); - DontCompile dontCompileAnno = getAnnotation(m, DontCompile.class); - checkCompilationCommandAnnotations(m, forceInlineAnno, dontInlineAnno, forceCompileAnno, dontCompileAnno); + private void applyIndependentCompilationCommands(Executable ex) { + ForceInline forceInlineAnno = getAnnotation(ex, ForceInline.class); + DontInline dontInlineAnno = getAnnotation(ex, DontInline.class); + ForceCompile forceCompileAnno = getAnnotation(ex, ForceCompile.class); + DontCompile dontCompileAnno = getAnnotation(ex, DontCompile.class); + checkCompilationCommandAnnotations(ex, forceInlineAnno, dontInlineAnno, forceCompileAnno, dontCompileAnno); // First handle inline annotations if (dontInlineAnno != null) { - WHITE_BOX.testSetDontInlineMethod(m, true); + WHITE_BOX.testSetDontInlineMethod(ex, true); } else if (forceInlineAnno != null) { - WHITE_BOX.testSetForceInlineMethod(m, true); + WHITE_BOX.testSetForceInlineMethod(ex, true); } if (dontCompileAnno != null) { CompLevel compLevel = dontCompileAnno.value(); TestFormat.check(compLevel == CompLevel.C1 || compLevel == CompLevel.C2 || compLevel == CompLevel.ANY, "Can only specify compilation level C1 (no individual C1 levels), " + - "C2 or ANY (no compilation, same as specifying anything) in @DontCompile at " + m); - dontCompileMethodAtLevel(m, compLevel); + "C2 or ANY (no compilation, same as specifying anything) in @DontCompile at " + ex); + dontCompileAtLevel(ex, compLevel); } } - private void checkCompilationCommandAnnotations(Method m, ForceInline forceInlineAnno, DontInline dontInlineAnno, ForceCompile forceCompileAnno, DontCompile dontCompileAnno) { - Test testAnno = getAnnotation(m, Test.class); - Run runAnno = getAnnotation(m, Run.class); - Check checkAnno = getAnnotation(m, Check.class); + private void checkCompilationCommandAnnotations(Executable ex, ForceInline forceInlineAnno, DontInline dontInlineAnno, ForceCompile forceCompileAnno, DontCompile dontCompileAnno) { + Test testAnno = getAnnotation(ex, Test.class); + Run runAnno = getAnnotation(ex, Run.class); + Check checkAnno = getAnnotation(ex, Check.class); TestFormat.check((testAnno == null && runAnno == null && checkAnno == null) || Stream.of(forceCompileAnno, dontCompileAnno, forceInlineAnno, dontInlineAnno).noneMatch(Objects::nonNull), "Cannot use explicit compile command annotations (@ForceInline, @DontInline," + - "@ForceCompile or @DontCompile) together with @Test, @Check or @Run: " + m + ". Use compLevel in @Test for fine tuning."); + "@ForceCompile or @DontCompile) together with @Test, @Check or @Run: " + ex + ". Use compLevel in @Test for fine tuning."); if (Stream.of(forceInlineAnno, dontCompileAnno, dontInlineAnno).filter(Objects::nonNull).count() > 1) { // Failure TestFormat.check(dontCompileAnno == null || dontInlineAnno == null, - "@DontInline is implicitely done with @DontCompile annotation at " + m); - TestFormat.fail("Cannot mix @ForceInline, @DontInline and @DontCompile at the same time at " + m); + "@DontInline is implicitely done with @DontCompile annotation at " + ex); + TestFormat.fail("Cannot mix @ForceInline, @DontInline and @DontCompile at the same time at " + ex); } - TestFormat.check(forceInlineAnno == null || dontInlineAnno == null, "Cannot have @ForceInline and @DontInline at the same time at " + m); + TestFormat.check(forceInlineAnno == null || dontInlineAnno == null, "Cannot have @ForceInline and @DontInline at the same time at " + ex); if (forceCompileAnno != null && dontCompileAnno != null) { CompLevel forceCompile = forceCompileAnno.value(); CompLevel dontCompile = dontCompileAnno.value(); TestFormat.check(dontCompile != CompLevel.ANY, - "Cannot have @DontCompile(CompLevel.ANY) and @ForceCompile at the same time at " + m); + "Cannot have @DontCompile(CompLevel.ANY) and @ForceCompile at the same time at " + ex); TestFormat.check(forceCompile != CompLevel.ANY, - "Cannot have @ForceCompile(CompLevel.ANY) and @DontCompile at the same time at " + m); + "Cannot have @ForceCompile(CompLevel.ANY) and @DontCompile at the same time at " + ex); TestFormat.check(!CompLevel.overlapping(dontCompile, forceCompile), - "Overlapping compilation levels with @ForceCompile and @DontCompile at " + m); + "Overlapping compilation levels with @ForceCompile and @DontCompile at " + ex); } } @@ -334,33 +359,49 @@ private void dontCompileMethod(Method m) { WHITE_BOX.testSetDontInlineMethod(m, true); } - private void dontCompileMethodAtLevel(Method m, CompLevel compLevel) { + private void dontCompileAtLevel(Executable ex, CompLevel compLevel) { if (VERBOSE) { - System.out.println("dontCompileMethodAtLevel " + m + " , level = " + compLevel.name()); + System.out.println("dontCompileAtLevel " + ex + " , level = " + compLevel.name()); } - WHITE_BOX.makeMethodNotCompilable(m, compLevel.getValue(), true); - WHITE_BOX.makeMethodNotCompilable(m, compLevel.getValue(), false); + WHITE_BOX.makeMethodNotCompilable(ex, compLevel.getValue(), true); + WHITE_BOX.makeMethodNotCompilable(ex, compLevel.getValue(), false); if (compLevel == CompLevel.ANY) { - WHITE_BOX.testSetDontInlineMethod(m, true); + WHITE_BOX.testSetDontInlineMethod(ex, true); } } - private void applyForceCompileCommand(Method m) { - ForceCompile forceCompileAnno = getAnnotation(m, ForceCompile.class); + private void applyForceCompileCommand(Executable ex) { + ForceCompile forceCompileAnno = getAnnotation(ex, ForceCompile.class); if (forceCompileAnno != null) { CompLevel level = forceCompileAnno.value(); TestFormat.check(level != CompLevel.SKIP && level != CompLevel.WAIT_FOR_COMPILATION, - "Cannot define compilation level SKIP or WAIT_FOR_COMPILATION in @ForceCompile at " + m); - enqueueMethodForCompilation(m, forceCompileAnno.value()); + "Cannot define compilation level SKIP or WAIT_FOR_COMPILATION in @ForceCompile at " + ex); + if (shouldCompile(ex)) { + level = restrictCompLevel(forceCompileAnno.value()); + if (level != CompLevel.SKIP) { + enqueueForCompilation(ex, level); + forceCompileMap.put(ex, level); + } + } } } - static void enqueueMethodForCompilation(Method m, CompLevel compLevel) { + static void enqueueForCompilation(Executable ex, CompLevel compLevel) { if (TestFrameworkExecution.VERBOSE) { - System.out.println("enqueueMethodForCompilation " + m + ", level = " + compLevel); + System.out.println("enqueueForCompilation " + ex + ", level = " + compLevel); } compLevel = restrictCompLevel(compLevel); - WHITE_BOX.enqueueMethodForCompilation(m, compLevel.getValue()); + WHITE_BOX.enqueueMethodForCompilation(ex, compLevel.getValue()); + } + + static boolean shouldCompile(Executable ex) { + if (!TestFrameworkExecution.USE_COMPILER) { + return false; + } else if (TestFrameworkExecution.STRESS_CC) { + return !TestFrameworkExecution.excludeCompilationRandomly(ex); + } else { + return true; + } } private void setupTests() { @@ -390,6 +431,7 @@ private void setupTests() { // Failure logged. Continue and report later. } } + TestFormat.checkNoThrow(!declaredTests.isEmpty(), "Did not specify any @Test methods in " + testClass); if (PRINT_VALID_IR_RULES) { irMatchRulePrinter.emit(); } @@ -573,7 +615,8 @@ private void checkCustomRunTest(Method m, String testName, Method testMethod, De TestFormat.checkNoThrow(warmupAnno == null, "Cannot set @Warmup at @Test method " + testMethod + " when used with its @Run method " + m + ". Use @Warmup at @Run method instead."); - TestFormat.checkNoThrow(runMode != RunMode.STANDALONE || test.getCompLevel() == CompLevel.C2, + Test testAnno = getAnnotation(testMethod, Test.class); + TestFormat.checkNoThrow(runMode != RunMode.STANDALONE || testAnno.compLevel() == CompLevel.ANY, "Setting explicit compilation level for @Test method " + testMethod + " has no effect " + "when used with STANDALONE @Run method " + m); } @@ -587,12 +630,33 @@ private void checkRunMethod(Method m, Run runAnno) { "Cannot set @Warmup at @Run method " + m + " when used with RunMode.STANDALONE. The @Run method is only invoked once."); } - private static T getAnnotation(Method m, Class c) { - T[] annos = m.getAnnotationsByType(c); - TestFormat.check(annos.length < 2, m + " has duplicated annotations"); + private static T getAnnotation(AnnotatedElement element, Class c) { + T[] annos = element.getAnnotationsByType(c); + TestFormat.check(annos.length < 2, element + " has duplicated annotations"); return Arrays.stream(annos).findFirst().orElse(null); } + private void checkForcedCompilationsCompleted() { + if (forceCompileMap.isEmpty()) { + return; + } + final long started = System.currentTimeMillis(); + long elapsed; + do { + forceCompileMap.entrySet().removeIf(entry -> WHITE_BOX.getMethodCompilationLevel(entry.getKey()) == entry.getValue().getValue()); + if (forceCompileMap.isEmpty()) { + // All @ForceCompile methods are compiled at the requested level. + return; + } + // Retry again if not yet compiled. + forceCompileMap.forEach(TestFrameworkExecution::enqueueForCompilation); + elapsed = System.currentTimeMillis() - started; + } while (elapsed < 5000); + StringBuilder builder = new StringBuilder(); + forceCompileMap.forEach((key, value) -> builder.append("- ").append(key).append(" at CompLevel.").append(value).append("\n")); + TestRun.fail("Could not force compile the following @ForceCompile methods:\n" + builder.toString()); + } + private void runTests() { TreeMap durations = (PRINT_TIMES || VERBOSE) ? new TreeMap<>() : null; long startTime = System.nanoTime(); @@ -638,7 +702,7 @@ enum TriState { static void compile(Method m, CompLevel compLevel) { TestRun.check(getAnnotation(m, Test.class) == null, "Cannot call enqueueMethodForCompilation() for @Test annotated method " + m); - enqueueMethodForCompilation(m, compLevel); + enqueueForCompilation(m, compLevel); } static void deoptimize(Method m) { @@ -771,7 +835,12 @@ public void printFixedRandomArguments() { ArgumentValue argument = arguments[i]; if (argument.isFixedRandom()) { hasRandomArgs = true; - builder.append("arg ").append(i).append(": ").append(argument.getArgument()).append(", "); + Object argumentVal = argument.getArgument(); + String argumentValString = argumentVal.toString(); + if (argumentVal instanceof Character) { + argumentValString += " (" + (int)(Character)argumentVal + ")"; + } + builder.append("arg ").append(i).append(": ").append(argumentValString).append(", "); } } if (hasRandomArgs) { @@ -819,21 +888,11 @@ abstract class AbstractTest { abstract String getName(); - final protected boolean shouldCompile(Method testMethod) { - if (!TestFrameworkExecution.USE_COMPILER) { - return false; - } else if (TestFrameworkExecution.STRESS_CC) { - return !TestFrameworkExecution.excludeCompilationRandomly(testMethod); - } else { - return true; - } - } - - final protected boolean isWaitForCompilation(DeclaredTest test) { + protected static boolean isWaitForCompilation(DeclaredTest test) { return test.getCompLevel() == CompLevel.WAIT_FOR_COMPILATION; } - final protected Object getInvocationTarget(Method method) { + protected static Object getInvocationTarget(Method method) { Class clazz = method.getDeclaringClass(); Object invocationTarget; if (Modifier.isStatic(method.getModifiers())) { @@ -877,7 +936,7 @@ protected void onWarmupFinished() { } abstract void compileTest(); - final protected void compileMethod(DeclaredTest test) { + protected void compileMethod(DeclaredTest test) { final Method testMethod = test.getTestMethod(); TestRun.check(WHITE_BOX.isMethodCompilable(testMethod, test.getCompLevel().getValue(), false), "Method" + testMethod + " not compilable at level " + test.getCompLevel() @@ -922,7 +981,7 @@ final protected void compileMethod(DeclaredTest test) { } private void enqueueMethodForCompilation(DeclaredTest test) { - TestFrameworkExecution.enqueueMethodForCompilation(test.getTestMethod(), test.getCompLevel()); + TestFrameworkExecution.enqueueForCompilation(test.getTestMethod(), test.getCompLevel()); } protected void checkCompilationLevel(DeclaredTest test) { @@ -990,7 +1049,7 @@ public BaseTest(DeclaredTest test) { this.testMethod = test.getTestMethod(); this.testInfo = new TestInfo(testMethod); this.invocationTarget = getInvocationTarget(testMethod); - this.shouldCompile = shouldCompile(testMethod); + this.shouldCompile = TestFrameworkExecution.shouldCompile(testMethod); this.waitForCompilation = isWaitForCompilation(test); } @@ -1174,7 +1233,7 @@ protected void compileTest() { private void compileSingleTest() { DeclaredTest test = tests.get(0); - if (shouldCompile(test.getTestMethod())) { + if (TestFrameworkExecution.shouldCompile(test.getTestMethod())) { if (isWaitForCompilation(test)) { waitForCompilation(test); } else { @@ -1188,7 +1247,7 @@ private void compileMultipleTests() { boolean anyCompileMethod = false; ExecutorService executor = Executors.newFixedThreadPool(tests.size()); for (DeclaredTest test : tests) { - if (shouldCompile(test.getTestMethod())) { + if (TestFrameworkExecution.shouldCompile(test.getTestMethod())) { if (isWaitForCompilation(test)) { anyWaitForCompilation = true; executor.execute(() -> waitForCompilation(test)); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java index de390140f3f..a1690e6bbf5 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java @@ -49,20 +49,15 @@ class TestFrameworkPrepareFlags { static final boolean XCOMP = Platform.isComp(); static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); - private static final boolean COMPILE_COMMANDS = Boolean.parseBoolean(System.getProperty("CompileCommands", "true")) && !XCOMP; static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); static final boolean STRESS_CC = Boolean.parseBoolean(System.getProperty("StressCC", "false")); private static final boolean REQUESTED_VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); - private static boolean VERIFY_IR = REQUESTED_VERIFY_IR && USE_COMPILER && !XCOMP && !STRESS_CC && !TEST_C1 && COMPILE_COMMANDS + private static boolean VERIFY_IR = REQUESTED_VERIFY_IR && USE_COMPILER && !XCOMP && !STRESS_CC && !TEST_C1 && Platform.isDebugBuild() && !Platform.isInt(); private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false")) && Platform.isDebugBuild(); private static String[] getDefaultFlags() { - return new String[] {"-XX:-BackgroundCompilation"}; - } - - private static String[] getCompileCommandFlags() { - return new String[] {"-XX:CompileCommand=quiet"}; + return new String[] {"-XX:-BackgroundCompilation", "-XX:CompileCommand=quiet"}; } private static String[] getPrintFlags() { @@ -106,9 +101,6 @@ private static ArrayList prepareTestVmFlags(Class testClass) { } cmds.addAll(Arrays.asList(getDefaultFlags())); - if (COMPILE_COMMANDS) { - cmds.addAll(Arrays.asList(getCompileCommandFlags())); - } setupIrVerificationFlags(testClass, cmds); // // TODO: Only for debugging @@ -116,7 +108,7 @@ private static ArrayList prepareTestVmFlags(Class testClass) { // cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=n,server=y"); // } - + return cmds; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java index 1775aeb3e18..6acb37b8895 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java @@ -30,6 +30,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -37,6 +38,7 @@ public class TestBadFormat { public static void main(String[] args) { + expectTestFormatException(BadNoTests.class); expectTestFormatException(BadArgumentsAnnotation.class); expectTestFormatException(BadOverloadedMethod.class); expectTestFormatException(BadCompilerControl.class); @@ -46,18 +48,24 @@ public static void main(String[] args) { expectTestFormatException(BadCheckTest.class); expectTestFormatException(BadIRAnnotations.class); expectTestFormatException(BadInnerClassTest.class); + expectTestFormatException(BadCompileClassInitializer.class, BadCompileClassInitializerHelper1.class, + BadCompileClassInitializerHelper2.class); } - private static void expectTestFormatException(Class clazz) { + private static void expectTestFormatException(Class clazz, Class... helpers) { try { - TestFramework.run(clazz); + if (helpers == null) { + TestFramework.run(clazz); + } else { + TestFramework.runWithHelperClasses(clazz, helpers); + } } catch (Exception e) { if (!(e instanceof TestFormatException)) { e.printStackTrace(); Asserts.fail("Unexpected exception", e); } String msg = e.getMessage(); - Violations violations = getViolations(clazz); + Violations violations = getViolations(clazz, helpers); violations.getFailedMethods().forEach(f -> Asserts.assertTrue(msg.contains(f), "Could not find " + f + " in violations\n" + msg)); Pattern pattern = Pattern.compile("Violations \\((\\d+)\\)"); Matcher matcher = pattern.matcher(msg); @@ -69,16 +77,27 @@ private static void expectTestFormatException(Class clazz) { throw new RuntimeException("Should catch an exception"); } - private static Violations getViolations(Class clazz) { + private static Violations getViolations(Class clazz, Class... helpers) { Violations violations = new Violations(); + collectViolations(clazz, violations); + if (helpers != null) { + Arrays.stream(helpers).forEach(c -> collectViolations(c, violations)); + } + return violations; + } + + private static void collectViolations(Class clazz, Violations violations) { getViolationsOfClass(clazz, violations); for (Class c : clazz.getDeclaredClasses()) { getViolationsOfClass(c, violations); } - return violations; } private static void getViolationsOfClass(Class clazz, Violations violations) { + ClassFail classFail = clazz.getDeclaredAnnotation(ClassFail.class); + if (classFail != null) { + violations.addFail(clazz); + } for (Method m : clazz.getDeclaredMethods()) { NoFail noFail = m.getDeclaredAnnotation(NoFail.class); if (noFail == null) { @@ -97,6 +116,12 @@ private static void getViolationsOfClass(Class clazz, Violations violations) } +// Specify at least one @Test +@ClassFail +class BadNoTests { + +} + class BadArgumentsAnnotation { @Test @@ -849,6 +874,7 @@ public void wrongFlagValueDoubleFlag() {} public void anyValueForStringFlags() {} } +@ClassFail class BadInnerClassTest { class InnerClass { @@ -863,6 +889,28 @@ public void noTestInInnerClass() {} } } +@ForceCompileClassInitializer +class BadCompileClassInitializer { + @Test + @ForceCompileClassInitializer + public void test() {} + + @ForceCompileClassInitializer + public void helper() {} +} + +@ClassFail +@ForceCompileClassInitializer(CompLevel.SKIP) +class BadCompileClassInitializerHelper1 { + +} + +@ClassFail +@ForceCompileClassInitializer(CompLevel.WAIT_FOR_COMPILATION) +class BadCompileClassInitializerHelper2 { + +} + class ClassNoDefaultConstructor { private ClassNoDefaultConstructor(int i) { } @@ -880,6 +928,11 @@ private ClassNoDefaultConstructor(int i) { int value(); } +// Class specific annotation: +// All classes with such an annotation have exactly one violation with the clas name in it. +@Retention(RetentionPolicy.RUNTIME) +@interface ClassFail {} + class Violations { private final List failedMethods = new ArrayList<>(); private int violations; @@ -896,4 +949,9 @@ public void addFail(Method m, int count) { failedMethods.add(m.getName()); violations += count; } + + public void addFail(Class c) { + failedMethods.add(c.getName()); + violations += 1; + } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java index d78fd20e9e1..f174d8c7831 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java @@ -28,6 +28,8 @@ import sun.hotspot.WhiteBox; import java.lang.reflect.Method; +import java.util.regex.Matcher; +import java.util.regex.Pattern; // Run with -Xbatch public class TestControls { @@ -66,6 +68,16 @@ public static void main(String[] args) throws Exception { } TestFramework.assertCompiledAtLevel(TestControls.class.getDeclaredMethod("overload", double.class), CompLevel.C1_LIMITED_PROFILE); TestFramework.assertCompiledByC2(TestControls.class.getDeclaredMethod("overload", int.class)); + + TestFramework framework = new TestFramework(ClassInitializerTest.class); + framework.addFlags("-XX:+PrintCompilation").addHelperClasses(ClassInitializerHelper.class).start(); + String output = TestFramework.getLastTestVMOutput(); + Pattern p = Pattern.compile("4.*ClassInitializerTest::"); + Matcher m = p.matcher(output); + Asserts.assertTrue(m.find()); + p = Pattern.compile("2.*ClassInitializerHelper::"); + m = p.matcher(output); + Asserts.assertTrue(m.find()); } @Test @@ -276,3 +288,24 @@ public void runTestCompilation(RunInfo info) { executed[13]++; } } + +@ForceCompileClassInitializer +class ClassInitializerTest { + + static int i; + static Object o; + static { + i = 3; + o = new Object(); + } + @Test + public void test() {} +} + +@ForceCompileClassInitializer(CompLevel.C1_LIMITED_PROFILE) +class ClassInitializerHelper { + static int i; + static { + i = 3; + } +} From 5c264c3ec77b601187e259a9ae183cb0cdbf9e79 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 17 Mar 2021 17:03:50 +0100 Subject: [PATCH 051/131] Add some more Javadocs --- .../test/lib/hotspot/ir_framework/Check.java | 17 +++++++++-- .../jdk/test/lib/hotspot/ir_framework/IR.java | 1 + .../test/lib/hotspot/ir_framework/Run.java | 3 ++ .../test/lib/hotspot/ir_framework/Test.java | 30 +++++++++++-------- 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java index 5f60806eaf2..4774d84af8c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java @@ -26,13 +26,24 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +/** + * Annotation for a checked test. + */ @Retention(RetentionPolicy.RUNTIME) public @interface Check { /** - * The associated {@link Test} method for this {@code Check} annotated check method. The framework will directly - * invoke the check method after each invoking or only after the compilation of the associated {@code Test} method - * by the framework (depends on the value set with {@link Check#when()}). + * The associated {@link Test} method for this {@code @Check} annotated check method. The framework will directly + * invoke the {@code C@heck} method after each invocation or only after the compilation of the associated {@code @Test} + * method (depending on the value set with {@link Check#when()}). + * + * @see Test */ String test(); + /** + * When should the {@code @Check} method be invoked? By default, the check is done after each invocation which is + * encouraged if performance is not critical. + * + * @see CheckAt + */ CheckAt when() default CheckAt.EACH_INVOCATION; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java index a25c54bcc27..60f69510bcd 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java @@ -36,6 +36,7 @@ // Regular expressions used to match and count IR nodes. String[] counts() default {}; + String[] applyIf() default {}; String[] applyIfNot() default {}; String[] applyIfAnd() default {}; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java index 3396e8e439e..966577cfc39 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java @@ -26,6 +26,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +/** + * Annotation for a custom run test. + */ @Retention(RetentionPolicy.RUNTIME) public @interface Run { /** diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java index af58dfbfe5b..8507e5bc578 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java @@ -29,16 +29,18 @@ /** * Annotate all methods in your test class which the framework should test with {@code @Test}. *

    - * Let {@code m} be a test method specifying the {@code @Test} annotation. If {@code m} is not part of a custom run test - * (an additional method specifying {@link Run} with (@code @Run(test = "m"))), then the framework invokes {@code m} in - * the following way: + * Let {@code m} be a test method specifying the {@code @Test} annotation. If {@code m} is neither part of a + * checked test(an additiona method specifying {@link Check} with (@code @Run(test = "m") nor part of a + * custom run test (an additional method specifying {@link Run} with (@code @Run(test = "m"))), + * then {@code m} is a so-called base test and the the framework invokes {@code m} in the following way: *

      *
    1. The framework warms {@code m} up for a predefined number of iterations (default is 2000) or any number - * specified by an additional {@link Warmup} iteration (could also be 0 which skips the warm-up completely). More - * information about the warm-up can be found in {@link Warmup}

    2. + * specified by an additional {@link Warmup} iteration (could also be 0 which skips the warm-up completely which is + * similar to simulating {@code -Xcomp}). More information about the warm-up can be found in {@link Warmup} *
    3. After the warm-up, the framework compiles {@code m} at the specified compilation level set by - * {@link Test#compLevel()} (default {@link CompLevel#C2}).

    4. - *
    5. The framework invokes {@code m} one more time to ensure that the compilation works.

    6. + * {@link Test#compLevel()} (default {@link CompLevel#ANY} will pick the highest available level which is usually + * {@link CompLevel#C2}). + *
    7. The framework invokes {@code m} one more time to check the compilation.

    8. *
    9. The framework checks any specified {@link IR} constraints. More information about IR matching can be * found in {@link IR}.

    10. *
    @@ -51,17 +53,21 @@ * with {@link Argument} properties for each parameter to use some well-defined parameters. If the method requires * a more specific argument value, use a custom run test (see {@link Run}). *
  • {@code m} is not inlined by the framework.

  • - *
  • Verification of the return value of {@code m} can only TODO

  • + *
  • Verification of the return value of {@code m} can only be done in a checked test (see {@link Check}) or + * custom run test (see {@link Run}).

  • * * *

    - * The following constraints must be met for a test method {@code m} specifying {@code @Test}: + * The following constraints must be met for the test method {@code m} specifying {@code @Test}: *

      - *
    • {@code m} must be part of the test class. Using {@code @Test} in other classes is not allowed.

    • + *
    • {@code m} must be part of the test class. Using {@code @Test} in nested or other classes is not allowed.

    • *
    • {@code m} cannot have the same name as another {@code @Test} method. Method overloading is only allowed - * with other non-{@code @Test} methods.

    • - *
    • {@code m} cannot specify any compile command annotations ({@link ForceCompile}, {@link DontCompile}, {@link ForceInline}, {@link DontInline}).

    • + * (but not encouraged) with other non-{@code @Test} methods. + *
    • {@code m} cannot specify any helper-method specific compile command annotations ({@link ForceCompile}, + * {@link DontCompile}, {@link ForceInline}, {@link DontInline}).

    • *
    + * + * TODO: Add references to examples. */ @Retention(RetentionPolicy.RUNTIME) public @interface Test { From 924db853fe50ef8e3f9b240f46abe8a899c8361e Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Wed, 17 Mar 2021 09:54:06 -0700 Subject: [PATCH 052/131] Converted TestBasicFunctionality.java to use IR framework --- .../inlinetypes/TestBasicFunctionality.java | 1003 +++++++++++++++++ 1 file changed, 1003 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java new file mode 100644 index 00000000000..7683d0cc69b --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java @@ -0,0 +1,1003 @@ +/* + * Copyright (c) 2021, 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. + */ + +/* + * @test + * @key randomness + * @summary Test the basic inline type implementation in C2 + * + * @requires os.simpleArch == "x64" + * @library /test/lib + * @compile InlineTypes.java + * @run driver compiler.valhalla.inlinetypes.TestBasicFunctionality + */ + +package compiler.valhalla.inlinetypes; + +import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; +import java.lang.reflect.Method; + +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; + +public class TestBasicFunctionality { + + public static void main(String[] args) { + Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; + scenarios[2].addFlags("-DVerifyIR=false"); + scenarios[3].addFlags("-XX:FlatArrayElementMaxSize=0"); + + TestFramework testFramework = new TestFramework(TestBasicFunctionality.class); + testFramework.addScenarios(scenarios) + .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class, + MyValue3.class, MyValue3Inline.class) + .start(); + } + + // Helper methods + protected long hash() { + return hash(rI, rL); + } + + protected long hash(int x, long y) { + return MyValue1.createWithFieldsInline(x, y).hash(); + } + + + // Receive inline type through call to interpreter + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) + public long test1() { + MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); + return v.hash(); + } + + @Run(test = "test1") + public void test1_verifier() { + long result = test1(); + Asserts.assertEQ(result, hash()); + } + + + // Receive inline type from interpreter via parameter + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) + public long test2(MyValue1 v) { + return v.hash(); + } + + @Run(test = "test2") + public void test2_verifier() { + MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); + long result = test2(v); + Asserts.assertEQ(result, hash()); + } + + + // Return incoming inline type without accessing fields + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + counts = {ALLOC, "= 1", STORE, "= 14"}, + failOn = {LOAD, TRAP}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + failOn = {ALLOC, LOAD, STORE, TRAP}) + public MyValue1 test3(MyValue1 v) { + return v; + } + + + @Run(test = "test3") + public void test3_verifier() { + MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI, rL); + MyValue1 v2 = test3(v1); + Asserts.assertEQ(v1.x, v2.x); + Asserts.assertEQ(v1.y, v2.y); + } + + + // Create an inline type in compiled code and only use fields. + // Allocation should go away because inline type does not escape. + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) + public long test4() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + return v.hash(); + } + + @Run(test = "test4") + public void test4_verifier() { + long result = test4(); + Asserts.assertEQ(result, hash()); + } + + + // Create an inline type in compiled code and pass it to + // an inlined compiled method via a call. + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) + public long test5() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + return test5Inline(v); + } + + @ForceInline + public long test5Inline(MyValue1 v) { + return v.hash(); + } + + @Run(test = "test5") + public void test5_verifier() { + long result = test5(); + Asserts.assertEQ(result, hash()); + } + + + // Create an inline type in compiled code and pass it to + // the interpreter via a call. + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + failOn = {LOAD, TRAP, ALLOC}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + counts = {ALLOC, "= 1"}, + failOn = {LOAD, TRAP}) + public long test6() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + // Pass to interpreter + return v.hashInterpreted(); + } + + @Run(test = "test6") + public void test6_verifier() { + long result = test6(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type in compiled code and pass it to + // the interpreter by returning. + @Test + @IR(counts = {ALLOC, "= 1"}, + failOn = {LOAD, TRAP}) + public MyValue1 test7(int x, long y) { + return MyValue1.createWithFieldsInline(x, y); + } + + @Run(test = "test7") + public void test7_verifier() { + MyValue1 v = test7(rI, rL); + Asserts.assertEQ(v.hash(), hash()); + } + + + // Merge inline types created from two branches + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) + public long test8(boolean b) { + MyValue1 v; + if (b) { + v = MyValue1.createWithFieldsInline(rI, rL); + } else { + v = MyValue1.createWithFieldsDontInline(rI + 1, rL + 1); + } + return v.hash(); + } + + @Run(test = "test8") + public void test8_verifier() { + Asserts.assertEQ(test8(true), hash()); + Asserts.assertEQ(test8(false), hash(rI + 1, rL + 1)); + } + + // Merge inline types created from two branches + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + counts = {LOAD, "= 14"}, + failOn = {TRAP, ALLOC, STORE}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + counts = {ALLOC, "= 1", STORE, "= 13"}, + failOn = {LOAD, TRAP}) + public MyValue1 test9(boolean b, int localrI, long localrL) { + MyValue1 v; + if (b) { + // Inline type is not allocated + // Do not use rI/rL directly here as null values may cause + // some redundant null initializations to be optimized out + // and matching to fail. + v = MyValue1.createWithFieldsInline(localrI, localrL); + } else { + // Inline type is allocated by the callee + v = MyValue1.createWithFieldsDontInline(rI + 1, rL + 1); + } + // Need to allocate inline type if 'b' is true + long sum = v.hashInterpreted(); + if (b) { + v = MyValue1.createWithFieldsDontInline(rI, sum); + } else { + v = MyValue1.createWithFieldsDontInline(rI, sum + 1); + } + // Don't need to allocate inline type because both branches allocate + return v; + } + + @Run(test = "test9") + public void test9_verifier() { + MyValue1 v = test9(true, rI, rL); + Asserts.assertEQ(v.x, rI); + Asserts.assertEQ(v.y, hash()); + v = test9(false, rI, rL); + Asserts.assertEQ(v.x, rI); + Asserts.assertEQ(v.y, hash(rI + 1, rL + 1) + 1); + } + + // Merge inline types created in a loop (not inlined) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) + public long test10(int x, long y) { + MyValue1 v = MyValue1.createWithFieldsDontInline(x, y); + for (int i = 0; i < 10; ++i) { + v = MyValue1.createWithFieldsDontInline(v.x + 1, v.y + 1); + } + return v.hash(); + } + + @Run(test = "test10") + public void test10_verifier() { + long result = test10(rI, rL); + Asserts.assertEQ(result, hash(rI + 10, rL + 10)); + } + + // Merge inline types created in a loop (inlined) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) + public long test11(int x, long y) { + MyValue1 v = MyValue1.createWithFieldsInline(x, y); + for (int i = 0; i < 10; ++i) { + v = MyValue1.createWithFieldsInline(v.x + 1, v.y + 1); + } + return v.hash(); + } + + @Run(test = "test11") + public void test11_verifier() { + long result = test11(rI, rL); + Asserts.assertEQ(result, hash(rI + 10, rL + 10)); + } + + + // Test loop with uncommon trap referencing an inline type + @Test + @IR(counts = {SCOBJ, ">= 1"}, // at least 1 + failOn = {LOAD}) + public long test12(boolean b) { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + MyValue1[] va = new MyValue1[Math.abs(rI) % 10]; + for (int i = 0; i < va.length; ++i) { + va[i] = MyValue1.createWithFieldsInline(rI, rL); + } + long result = rL; + for (int i = 0; i < 1000; ++i) { + if (b) { + result += v.x; + } else { + // Uncommon trap referencing v. We delegate allocation to the + // interpreter by adding a SafePointScalarObjectNode. + result = v.hashInterpreted(); + for (int j = 0; j < va.length; ++j) { + result += va[j].hash(); + } + } + } + return result; + } + + @Run(test = "test12") + public void test12_verifier(RunInfo info) { + long result = test12(info.isWarmUp()); + Asserts.assertEQ(result, info.isWarmUp() ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); + } + + + // Test loop with uncommon trap referencing an inline type + @Test + public long test13(boolean b) { + MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); + MyValue1[] va = new MyValue1[Math.abs(rI) % 10]; + for (int i = 0; i < va.length; ++i) { + va[i] = MyValue1.createWithFieldsDontInline(rI, rL); + } + long result = rL; + for (int i = 0; i < 1000; ++i) { + if (b) { + result += v.x; + } else { + // Uncommon trap referencing v. Should not allocate + // but just pass the existing oop to the uncommon trap. + result = v.hashInterpreted(); + for (int j = 0; j < va.length; ++j) { + result += va[j].hashInterpreted(); + } + } + } + return result; + } + + @Run(test = "test13") + public void test13_verifier(RunInfo info) { + long result = test13(info.isWarmUp()); + Asserts.assertEQ(result, info.isWarmUp() ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); + } + + + // Create an inline type in a non-inlined method and then call a + // non-inlined method on that inline type. + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + failOn = {ALLOC, STORE, TRAP}, + counts = {LOAD, "= 14"}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + failOn = {ALLOC, LOAD, STORE, TRAP}) + public long test14() { + MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); + return v.hashInterpreted(); + } + + @Run(test = "test14") + public void test14_verifier() { + long result = test14(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type in an inlined method and then call a + // non-inlined method on that inline type. + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + failOn = {LOAD, TRAP, ALLOC}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + failOn = {LOAD, TRAP}, + counts = {ALLOC, "= 1"}) + public long test15() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + return v.hashInterpreted(); + } + + @Run(test = "test15") + public void test15_verifier() { + long result = test15(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type in a non-inlined method and then call an + // inlined method on that inline type. + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) + public long test16() { + MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); + return v.hash(); + } + + @Run(test = "test16") + public void test16_verifier() { + long result = test16(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type in an inlined method and then call an + // inlined method on that inline type. + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) + public long test17() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + return v.hash(); + } + + @Run(test = "test17") + public void test17_verifier() { + long result = test17(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type in compiled code and pass it to the + // interpreter via a call. The inline type is live at the first call so + // debug info should include a reference to all its fields. + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + failOn = {ALLOC, LOAD, TRAP}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + counts = {ALLOC, "= 1"}, + failOn = {LOAD, TRAP}) + public long test18() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + v.hashInterpreted(); + return v.hashInterpreted(); + } + + @Run(test = "test18") + public void test18_verifier() { + long result = test18(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type in compiled code and pass it to the + // interpreter via a call. The inline type is passed twice but + // should only be allocated once. + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + failOn = {ALLOC, LOAD, TRAP}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + counts = {ALLOC, "= 1"}, + failOn = {LOAD, TRAP}) + public long test19() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + return sumValue(v, v); + } + + @DontCompile + public long sumValue(MyValue1 v, MyValue1 dummy) { + return v.hash(); + } + + @Run(test = "test19") + public void test19_verifier() { + long result = test19(); + Asserts.assertEQ(result, hash()); + } + + + // Create an inline type (array) in compiled code and pass it to the + // interpreter via a call. The inline type is live at the uncommon + // trap: verify that deoptimization causes the inline type to be + // correctly allocated. + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + failOn = {LOAD, ALLOC, STORE}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + counts = {ALLOC, "= 1"}, + failOn = {LOAD}) + public long test20(boolean deopt) { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + MyValue2[] va = new MyValue2[3]; + if (deopt) { + // uncommon trap + try { + Method m = getClass().getDeclaredMethod("test20", boolean.class); + TestFramework.deoptimize(m); + } catch (NoSuchMethodException ex) { + System.out.println("ERROR: Failed to getDeclaredMethod test20"); + throw new TestRunException("Failed to getDeclaredMethod test20"); + } + } + + return v.hashInterpreted() + va[0].hashInterpreted() + + va[1].hashInterpreted() + va[2].hashInterpreted(); + } + + @Run(test = "test20") + public void test20_verifier(RunInfo info) { + MyValue2[] va = new MyValue2[42]; + long result = test20(!info.isWarmUp()); + Asserts.assertEQ(result, hash() + va[0].hash() + va[1].hash() + va[2].hash()); + } + + + // Inline type fields in regular object + MyValue1 val1; + MyValue2 val2; + final MyValue1 val3 = MyValue1.createWithFieldsInline(rI, rL); + static MyValue1 val4; + static final MyValue1 val5 = MyValue1.createWithFieldsInline(rI, rL); + + // Test inline type fields in objects + @Test + @IR(counts = {ALLOC, "= 1"}, + failOn = {TRAP}) + public long test21(int x, long y) { + // Compute hash of inline type fields + long result = val1.hash() + val2.hash() + val3.hash() + val4.hash() + val5.hash(); + // Update fields + val1 = MyValue1.createWithFieldsInline(x, y); + val2 = MyValue2.createWithFieldsInline(x, rD); + val4 = MyValue1.createWithFieldsInline(x, y); + return result; + } + + @Run(test = "test21") + public void test21_verifier() { + // Check if hash computed by test18 is correct + val1 = MyValue1.createWithFieldsInline(rI, rL); + val2 = val1.v2; + // val3 is initialized in the constructor + val4 = val1; + // val5 is initialized in the static initializer + long hash = val1.hash() + val2.hash() + val3.hash() + val4.hash() + val5.hash(); + long result = test21(rI + 1, rL + 1); + Asserts.assertEQ(result, hash); + // Check if inline type fields were updated + Asserts.assertEQ(val1.hash(), hash(rI + 1, rL + 1)); + Asserts.assertEQ(val2.hash(), MyValue2.createWithFieldsInline(rI + 1, rD).hash()); + Asserts.assertEQ(val4.hash(), hash(rI + 1, rL + 1)); + } + + // Test folding of constant inline type fields + @Test + @IR(failOn = {ALLOC, LOAD, STORE, LOOP, TRAP}) + public long test22() { + // This should be constant folded + return val5.hash() + val5.v3.hash(); + } + + @Run(test = "test22") + public void test22_verifier() { + long result = test22(); + Asserts.assertEQ(result, val5.hash() + val5.v3.hash()); + } + + // Test defaultvalue + @Test + @IR(failOn = {ALLOC, LOAD, STORE, LOOP, TRAP}) + public long test23() { + MyValue2 v = MyValue2.createDefaultInline(); + return v.hash(); + } + + @Run(test = "test23") + public void test23_verifier() { + long result = test23(); + Asserts.assertEQ(result, MyValue2.createDefaultInline().hash()); + } + + // Test defaultvalue + @Test + @IR(failOn = {ALLOC, STORE, LOOP, TRAP}) + public long test24() { + MyValue1 v1 = MyValue1.createDefaultInline(); + MyValue1 v2 = MyValue1.createDefaultDontInline(); + return v1.hashPrimitive() + v2.hashPrimitive(); + } + + @Run(test = "test24") + public void test24_verifier() { + long result = test24(); + Asserts.assertEQ(result, 2 * MyValue1.createDefaultInline().hashPrimitive()); + } + + // Test withfield + @Test + @IR(failOn = {ALLOC, LOAD, STORE, LOOP, TRAP}) + public long test25() { + MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); + return v.hash(); + } + + @Run(test = "test25") + public void test25_verifier() { + long result = test25(); + Asserts.assertEQ(result, MyValue2.createWithFieldsInline(rI, rD).hash()); + } + + // Test withfield + @Test + @IR(failOn = {ALLOC, STORE, LOOP, TRAP}) + public long test26() { + MyValue1 v1 = MyValue1.createWithFieldsInline(rI, rL); + MyValue1 v2 = MyValue1.createWithFieldsDontInline(rI, rL); + return v1.hash() + v2.hash(); + } + + @Run(test = "test26") + public void test26_verifier() { + long result = test26(); + Asserts.assertEQ(result, 2 * hash()); + } + + class TestClass27 { + public MyValue1 v; + } + + + + // Test allocation elimination of unused object with initialized inline type field + @Test + @IR(failOn = {ALLOC, LOAD, STORE, LOOP}) + public void test27(boolean deopt) { + TestClass27 unused = new TestClass27(); + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + unused.v = v; + if (deopt) { + // uncommon trap + try { + Method m = getClass().getDeclaredMethod("test27", boolean.class); + TestFramework.deoptimize(m); + } catch (NoSuchMethodException ex) { + System.out.println("ERROR: Failed to getDeclaredMethod test27"); + throw new TestRunException("Failed to getDeclaredMethod test27"); + } + } + } + + @Run(test = "test27") + public void test27_verifier(RunInfo info) { + test27(!info.isWarmUp()); + } + + + + static MyValue3 staticVal3; + static MyValue3 staticVal3_copy; + + // Check elimination of redundant inline type allocations + @Test + @IR(counts = {ALLOC, "= 1"}) + public MyValue3 test28(MyValue3[] va) { + // Create inline type and force allocation + MyValue3 vt = MyValue3.create(); + va[0] = vt; + staticVal3 = vt; + vt.verify(staticVal3); + + // Inline type is now allocated, make a copy and force allocation. + // Because copy is equal to vt, C2 should remove this redundant allocation. + MyValue3 copy = MyValue3.setC(vt, vt.c); + va[0] = copy; + staticVal3_copy = copy; + copy.verify(staticVal3_copy); + return copy; + } + + @Run(test = "test28") + public void test28_verifier() { + MyValue3[] va = new MyValue3[1]; + MyValue3 vt = test28(va); + staticVal3.verify(vt); + staticVal3.verify(va[0]); + staticVal3_copy.verify(vt); + staticVal3_copy.verify(va[0]); + } + + // Verify that only dominating allocations are re-used + @Test() + public MyValue3 test29(boolean warmup) { + MyValue3 vt = MyValue3.create(); + if (warmup) { + staticVal3 = vt; // Force allocation + } + // Force allocation to verify that above + // non-dominating allocation is not re-used + MyValue3 copy = MyValue3.setC(vt, vt.c); + staticVal3_copy = copy; + copy.verify(vt); + return copy; + } + + @Run(test = "test29") + public void test29_verifier(RunInfo info) { + MyValue3 vt = test29(info.isWarmUp()); + if (info.isWarmUp()) { + staticVal3.verify(vt); + } + } + + // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations + @Test + @IR(failOn = {ALLOC, ALLOCA, STORE}) + public MyValue3 test30(MyValue3[] va) { + // C2 can re-use the oop of staticVal3 because staticVal3 is equal to copy + MyValue3 copy = MyValue3.copy(staticVal3); + va[0] = copy; + staticVal3 = copy; + copy.verify(staticVal3); + return copy; + } + + @Run(test = "test30") + public void test30_verifier() { + staticVal3 = MyValue3.create(); + MyValue3[] va = new MyValue3[1]; + MyValue3 vt = test30(va); + staticVal3.verify(vt); + staticVal3.verify(va[0]); + } + + // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + failOn = {ALLOC, ALLOCA, STORE}) + public MyValue3 test31(MyValue3[] va) { + // C2 can re-use the oop returned by createDontInline() + // because the corresponding inline type is equal to 'copy'. + MyValue3 copy = MyValue3.copy(MyValue3.createDontInline()); + va[0] = copy; + staticVal3 = copy; + copy.verify(staticVal3); + return copy; + } + + @Run(test = "test31") + public void test31_verifier() { + MyValue3[] va = new MyValue3[1]; + MyValue3 vt = test31(va); + staticVal3.verify(vt); + staticVal3.verify(va[0]); + } + + // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + failOn = {ALLOC, ALLOCA, STORE}) + public MyValue3 test32(MyValue3 vt, MyValue3[] va) { + // C2 can re-use the oop of vt because vt is equal to 'copy'. + MyValue3 copy = MyValue3.copy(vt); + va[0] = copy; + staticVal3 = copy; + copy.verify(staticVal3); + return copy; + } + + @Run(test = "test32") + public void test32_verifier() { + MyValue3 vt = MyValue3.create(); + MyValue3[] va = new MyValue3[1]; + MyValue3 result = test32(vt, va); + staticVal3.verify(vt); + va[0].verify(vt); + result.verify(vt); + } + + // Test correct identification of inline type copies + @Test + public MyValue3 test33(MyValue3[] va) { + MyValue3 vt = MyValue3.copy(staticVal3); + vt = MyValue3.setI(vt, vt.c); + // vt is not equal to staticVal3, so C2 should not re-use the oop + va[0] = vt; + staticVal3 = vt; + vt.verify(staticVal3); + return vt; + } + + @Run(test = "test33") + public void test33_verifier() { + staticVal3 = MyValue3.create(); + MyValue3[] va = new MyValue3[1]; + MyValue3 vt = test33(va); + Asserts.assertEQ(staticVal3.i, (int)staticVal3.c); + Asserts.assertEQ(va[0].i, (int)staticVal3.c); + Asserts.assertEQ(vt.i, (int)staticVal3.c); + } + + // Verify that the default inline type is never allocated. + // C2 code should load and use the default oop from the java mirror. + @Test + @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE, LOOP, TRAP}) + public MyValue3 test34(MyValue3[] va) { + // Explicitly create default value + MyValue3 vt = MyValue3.createDefault(); + va[0] = vt; + staticVal3 = vt; + vt.verify(vt); + + // Load default value from uninitialized inline type array + MyValue3[] dva = new MyValue3[1]; + staticVal3_copy = dva[0]; + va[1] = dva[0]; + dva[0].verify(dva[0]); + return vt; + } + + @Run(test = "test34") + public void test34_verifier() { + MyValue3 vt = MyValue3.createDefault(); + MyValue3[] va = new MyValue3[2]; + va[0] = MyValue3.create(); + va[1] = MyValue3.create(); + MyValue3 res = test34(va); + res.verify(vt); + staticVal3.verify(vt); + staticVal3_copy.verify(vt); + va[0].verify(vt); + va[1].verify(vt); + } + + // Same as above but manually initialize inline type fields to default. + @Test + @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE, LOOP, TRAP}) + public MyValue3 test35(MyValue3 vt, MyValue3[] va) { + vt = MyValue3.setC(vt, (char)0); + vt = MyValue3.setBB(vt, (byte)0); + vt = MyValue3.setS(vt, (short)0); + vt = MyValue3.setI(vt, 0); + vt = MyValue3.setL(vt, 0); + vt = MyValue3.setO(vt, null); + vt = MyValue3.setF1(vt, 0); + vt = MyValue3.setF2(vt, 0); + vt = MyValue3.setF3(vt, 0); + vt = MyValue3.setF4(vt, 0); + vt = MyValue3.setF5(vt, 0); + vt = MyValue3.setF6(vt, 0); + vt = MyValue3.setV1(vt, MyValue3Inline.createDefault()); + va[0] = vt; + staticVal3 = vt; + vt.verify(vt); + return vt; + } + + @Run(test = "test35") + public void test35_verifier() { + MyValue3 vt = MyValue3.createDefault(); + MyValue3[] va = new MyValue3[1]; + va[0] = MyValue3.create(); + MyValue3 res = test35(va[0], va); + res.verify(vt); + staticVal3.verify(vt); + va[0].verify(vt); + } + + // Merge inline types created from two branches + + private Object test36_helper(Object v) { + return v; + } + + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) + public long test36(boolean b) { + Object o; + if (b) { + o = test36_helper(MyValue1.createWithFieldsInline(rI, rL)); + } else { + o = test36_helper(MyValue1.createWithFieldsDontInline(rI + 1, rL + 1)); + } + MyValue1 v = (MyValue1)o; + return v.hash(); + } + + @Run(test = "test36") + public void test36_verifier() { + Asserts.assertEQ(test36(true), hash()); + Asserts.assertEQ(test36(false), hash(rI + 1, rL + 1)); + } + + // Test correct loading of flattened fields + primitive class Test37Value2 { + final int x = 0; + final int y = 0; + } + + primitive class Test37Value1 { + final double d = 0; + final float f = 0; + final Test37Value2 v = new Test37Value2(); + } + + @Test + public Test37Value1 test37(Test37Value1 vt) { + return vt; + } + + @Run(test = "test37") + public void test37_verifier() { + Test37Value1 vt = new Test37Value1(); + Asserts.assertEQ(test37(vt), vt); + } + + // Test elimination of inline type allocations without a unique CheckCastPP + primitive class Test38Value { + public int i; + public Test38Value(int i) { this.i = i; } + } + + static Test38Value test38Field; + + @Test + public void test38() { + for (int i = 3; i < 100; ++i) { + int j = 1; + while (++j < 11) { + try { + test38Field = new Test38Value(i); + } catch (ArithmeticException ae) { } + } + } + } + + @Run(test = "test38") + public void test38_verifier() { + test38Field = Test38Value.default; + test38(); + Asserts.assertEQ(test38Field, new Test38Value(99)); + } + + // Tests split if with inline type Phi users + static primitive class Test39Value { + public int iFld1; + public int iFld2; + + public Test39Value(int i1, int i2) { iFld1 = i1; iFld2 = i2; } + } + + static int test39A1[][] = new int[400][400]; + static double test39A2[] = new double[400]; + static Test39Value test39Val = Test39Value.default; + + @DontInline + public int[] getArray() { + return new int[400]; + } + + @Test + public int test39() { + int result = 0; + for (int i = 0; i < 100; ++i) { + switch ((i >>> 1) % 3) { + case 0: + test39A1[i][i] = i; + break; + case 1: + for (int j = 0; j < 100; ++j) { + test39A1[i] = getArray(); + test39Val = new Test39Value(j, test39Val.iFld2); + } + break; + case 2: + for (float f = 142; f > i; f--) { + test39A2[i + 1] += 3; + } + result += test39Val.iFld1; + break; + } + double d1 = 1; + while (++d1 < 142) { + test39A1[(i >>> 1) % 400][i + 1] = result; + test39Val = new Test39Value(i, test39Val.iFld2); + } + } + return result; + } + + @Run(test = "test39") + @Warmup(10) + public void test39_verifier() { + int result = test39(); + Asserts.assertEQ(result, 1552); + } + + // Test scalar replacement of inline type array containing inline type with oop fields + @Test() + public long test40(boolean b) { + MyValue1[] va = {MyValue1.createWithFieldsInline(rI, rL)}; + long result = 0; + for (int i = 0; i < 1000; ++i) { + if (!b) { + result = va[0].hash(); + } + } + return result; + } + + @Run(test = "test40") + public void test40_verifier(RunInfo info) { + long result = test40(info.isWarmUp()); + Asserts.assertEQ(result, info.isWarmUp() ? 0 : hash()); + } +} From 03cbebf5ef8d348c2a9df8a588b8cc13282036d2 Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Wed, 17 Mar 2021 10:35:13 -0700 Subject: [PATCH 053/131] Fixed spaces in IR annotations --- .../inlinetypes/TestBasicFunctionality.java | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java index 7683d0cc69b..c3ef1ced853 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java @@ -100,10 +100,10 @@ public void test2_verifier() { // Return incoming inline type without accessing fields @Test @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - counts = {ALLOC, "= 1", STORE, "= 14"}, - failOn = {LOAD, TRAP}) + counts = {ALLOC, "= 1", STORE, "= 14"}, + failOn = {LOAD, TRAP}) @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - failOn = {ALLOC, LOAD, STORE, TRAP}) + failOn = {ALLOC, LOAD, STORE, TRAP}) public MyValue1 test3(MyValue1 v) { return v; } @@ -159,10 +159,10 @@ public void test5_verifier() { // the interpreter via a call. @Test @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - failOn = {LOAD, TRAP, ALLOC}) + failOn = {LOAD, TRAP, ALLOC}) @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - counts = {ALLOC, "= 1"}, - failOn = {LOAD, TRAP}) + counts = {ALLOC, "= 1"}, + failOn = {LOAD, TRAP}) public long test6() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); // Pass to interpreter @@ -179,7 +179,7 @@ public void test6_verifier() { // the interpreter by returning. @Test @IR(counts = {ALLOC, "= 1"}, - failOn = {LOAD, TRAP}) + failOn = {LOAD, TRAP}) public MyValue1 test7(int x, long y) { return MyValue1.createWithFieldsInline(x, y); } @@ -213,11 +213,11 @@ public void test8_verifier() { // Merge inline types created from two branches @Test @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - counts = {LOAD, "= 14"}, - failOn = {TRAP, ALLOC, STORE}) + counts = {LOAD, "= 14"}, + failOn = {TRAP, ALLOC, STORE}) @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - counts = {ALLOC, "= 1", STORE, "= 13"}, - failOn = {LOAD, TRAP}) + counts = {ALLOC, "= 1", STORE, "= 13"}, + failOn = {LOAD, TRAP}) public MyValue1 test9(boolean b, int localrI, long localrL) { MyValue1 v; if (b) { @@ -289,7 +289,7 @@ public void test11_verifier() { // Test loop with uncommon trap referencing an inline type @Test @IR(counts = {SCOBJ, ">= 1"}, // at least 1 - failOn = {LOAD}) + failOn = {LOAD}) public long test12(boolean b) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue1[] va = new MyValue1[Math.abs(rI) % 10]; @@ -354,10 +354,10 @@ public void test13_verifier(RunInfo info) { // non-inlined method on that inline type. @Test @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - failOn = {ALLOC, STORE, TRAP}, - counts = {LOAD, "= 14"}) + failOn = {ALLOC, STORE, TRAP}, + counts = {LOAD, "= 14"}) @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - failOn = {ALLOC, LOAD, STORE, TRAP}) + failOn = {ALLOC, LOAD, STORE, TRAP}) public long test14() { MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); return v.hashInterpreted(); @@ -373,10 +373,10 @@ public void test14_verifier() { // non-inlined method on that inline type. @Test @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - failOn = {LOAD, TRAP, ALLOC}) + failOn = {LOAD, TRAP, ALLOC}) @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - failOn = {LOAD, TRAP}, - counts = {ALLOC, "= 1"}) + failOn = {LOAD, TRAP}, + counts = {ALLOC, "= 1"}) public long test15() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); return v.hashInterpreted(); @@ -423,10 +423,10 @@ public void test17_verifier() { // debug info should include a reference to all its fields. @Test @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - failOn = {ALLOC, LOAD, TRAP}) + failOn = {ALLOC, LOAD, TRAP}) @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - counts = {ALLOC, "= 1"}, - failOn = {LOAD, TRAP}) + counts = {ALLOC, "= 1"}, + failOn = {LOAD, TRAP}) public long test18() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); v.hashInterpreted(); @@ -444,10 +444,10 @@ public void test18_verifier() { // should only be allocated once. @Test @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - failOn = {ALLOC, LOAD, TRAP}) + failOn = {ALLOC, LOAD, TRAP}) @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - counts = {ALLOC, "= 1"}, - failOn = {LOAD, TRAP}) + counts = {ALLOC, "= 1"}, + failOn = {LOAD, TRAP}) public long test19() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); return sumValue(v, v); @@ -471,10 +471,10 @@ public void test19_verifier() { // correctly allocated. @Test @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - failOn = {LOAD, ALLOC, STORE}) + failOn = {LOAD, ALLOC, STORE}) @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - counts = {ALLOC, "= 1"}, - failOn = {LOAD}) + counts = {ALLOC, "= 1"}, + failOn = {LOAD}) public long test20(boolean deopt) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue2[] va = new MyValue2[3]; @@ -511,7 +511,7 @@ public void test20_verifier(RunInfo info) { // Test inline type fields in objects @Test @IR(counts = {ALLOC, "= 1"}, - failOn = {TRAP}) + failOn = {TRAP}) public long test21(int x, long y) { // Compute hash of inline type fields long result = val1.hash() + val2.hash() + val3.hash() + val4.hash() + val5.hash(); @@ -722,7 +722,7 @@ public void test30_verifier() { // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations @Test @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - failOn = {ALLOC, ALLOCA, STORE}) + failOn = {ALLOC, ALLOCA, STORE}) public MyValue3 test31(MyValue3[] va) { // C2 can re-use the oop returned by createDontInline() // because the corresponding inline type is equal to 'copy'. @@ -744,7 +744,7 @@ public void test31_verifier() { // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations @Test @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - failOn = {ALLOC, ALLOCA, STORE}) + failOn = {ALLOC, ALLOCA, STORE}) public MyValue3 test32(MyValue3 vt, MyValue3[] va) { // C2 can re-use the oop of vt because vt is equal to 'copy'. MyValue3 copy = MyValue3.copy(vt); From 92e3962dd1e1e37c1360c55411afa00c8827168e Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 18 Mar 2021 14:41:34 +0100 Subject: [PATCH 054/131] Add setDefaultWarmup() and remove clear() as interface method, share invocation target between @Test and @Check method if possible --- .../valhalla/inlinetypes/InlineTypes.java | 5 ++ .../hotspot/ir_framework/TestFramework.java | 33 ++++++++----- .../ir_framework/TestFrameworkExecution.java | 16 +++++-- .../ir_framework/tests/TestControls.java | 46 +++++++++++++++++++ .../ir_framework/tests/TestSanity.java | 17 ++++--- 5 files changed, 94 insertions(+), 23 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java index f5d342c0518..158af6db8dd 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java @@ -71,6 +71,11 @@ public class InlineTypes { ) }; + public static TestFramework getFramework() { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + return new TestFramework(walker.getCallerClass()).setDefaultWarmup(251); + } + static class IRNode { // Regular expressions used to match nodes in the PrintIdeal output protected static final String START = "(\\d+ (.*"; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index d33f7b7777f..3f11f508395 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -49,6 +49,7 @@ public class TestFramework { static final String TEST_VM_FLAGS_START = "##### TestFrameworkPrepareFlags - used by TestFramework #####"; static final String TEST_VM_FLAGS_DELIMITER = " "; static final String TEST_VM_FLAGS_END = "----- END -----"; + private static final int WARMUP_ITERATIONS = Integer.getInteger("Warmup", -1); private static boolean VERIFY_IR = true; // Should we perform IR matching? private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); @@ -58,6 +59,7 @@ public class TestFramework { private final Class testClass; private static String lastTestVMOutput; private TestFrameworkSocket socket; + private int defaultWarmup = -1; /* * Public interface methods @@ -277,16 +279,6 @@ public TestFramework addScenarios(Scenario... scenarios) { return this; } - /** - * Clear all settings set by {@link TestFramework#addFlags(String...)}, {@link TestFramework#addHelperClasses(Class[])} - * and/or {@link TestFramework#runWithScenarios(Scenario...)}. - */ - public void clear() { - flags.clear(); - helperClasses = null; - scenarios = null; - } - /** * Start the testing of the implicitely set test class by {@link TestFramework#TestFramework()} * or explicitly set by {@link TestFramework#TestFramework(Class)}. @@ -305,6 +297,19 @@ public void start() { } } + /** + * Set a new default warm-up (overriding the framework default of 2000) to be applied for all tests that do + * not specify an explicit warm-up with {@link Warmup}. + * + * @param defaultWarmup a non-negative default warm-up + * @return the same framework instance. + */ + public TestFramework setDefaultWarmup(int defaultWarmup) { + TestFormat.check(defaultWarmup >= 0, "Cannot specify a negative default warm-up"); + this.defaultWarmup = defaultWarmup; + return this; + } + /** * Get the VM output of the test VM. Use {@code -DVerbose=true} to enable more debug information. If scenarios * were run, use {@link Scenario#getTestVMOutput()}. @@ -551,7 +556,13 @@ private List prepareTestVMFlags(List additionalFlags) { cmds.addAll(Arrays.asList(jtregVMFlags)); } - if (VERIFY_IR) { + if (WARMUP_ITERATIONS < 0 && defaultWarmup != -1) { + // Only use the set warmup for the framework if not overridden by a valid -DWarmup property set by a test. + cmds.add("-DWarmup=" + defaultWarmup); + } + + + if (VERIFY_IR) { // Add server property flag that enables test VM to print encoding for IR verification last. cmds.add(socket.getPortPropertyFlag()); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 0b68e0bfb9c..35509da5c20 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -892,7 +892,7 @@ protected static boolean isWaitForCompilation(DeclaredTest test) { return test.getCompLevel() == CompLevel.WAIT_FOR_COMPILATION; } - protected static Object getInvocationTarget(Method method) { + protected static Object createInvocationTarget(Method method) { Class clazz = method.getDeclaringClass(); Object invocationTarget; if (Modifier.isStatic(method.getModifiers())) { @@ -1039,7 +1039,7 @@ class BaseTest extends AbstractTest { private final DeclaredTest test; protected final Method testMethod; protected final TestInfo testInfo; - private final Object invocationTarget; + protected final Object invocationTarget; private final boolean shouldCompile; private final boolean waitForCompilation; @@ -1048,7 +1048,7 @@ public BaseTest(DeclaredTest test) { this.test = test; this.testMethod = test.getTestMethod(); this.testInfo = new TestInfo(testMethod); - this.invocationTarget = getInvocationTarget(testMethod); + this.invocationTarget = createInvocationTarget(testMethod); this.shouldCompile = TestFrameworkExecution.shouldCompile(testMethod); this.waitForCompilation = isWaitForCompilation(test); } @@ -1129,7 +1129,13 @@ public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecificati this.checkMethod = checkMethod; this.checkAt = checkSpecification.when(); this.parameter = parameter; - this.checkInvocationTarget = getInvocationTarget(checkMethod); + // Use the same invocation target + if (Modifier.isStatic(checkMethod.getModifiers())) { + this.checkInvocationTarget = null; + } else { + // Use the same invocation target as the test method if check method is non-static. + this.checkInvocationTarget = this.invocationTarget != null ? this.invocationTarget : createInvocationTarget(checkMethod); + } } @Override @@ -1173,7 +1179,7 @@ public CustomRunTest(Method runMethod, Warmup warmUpAnno, Run runSpecification, TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + runMethod); runMethod.setAccessible(true); this.runMethod = runMethod; - this.runInvocationTarget = getInvocationTarget(runMethod); + this.runInvocationTarget = createInvocationTarget(runMethod); this.mode = runSpecification.mode(); this.tests = tests; if (tests.size() == 1) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java index f174d8c7831..02d298eb8ac 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java @@ -78,6 +78,8 @@ public static void main(String[] args) throws Exception { p = Pattern.compile("2.*ClassInitializerHelper::"); m = p.matcher(output); Asserts.assertTrue(m.find()); + + new TestFramework(TestWarmup.class).setDefaultWarmup(500).start(); } @Test @@ -309,3 +311,47 @@ class ClassInitializerHelper { i = 3; } } + +class TestWarmup { + int iFld; + int iFld2; + int iFldCheck; + int iFldCheck2; + + @Test + @Warmup(200) + public void test() { + iFld++; + } + + @Test + public void test2() { + iFld2++; + } + + @Check(test = "test") + public void checkTest(TestInfo info) { + iFldCheck++; + if (iFldCheck != iFld) { + throw new RuntimeException(iFld + " must be equal " + iFldCheck); + } + if (!info.isWarmUp()) { + if (iFld != 201) { + throw new RuntimeException("Must be 201 but was " + iFld); + } + } + } + + @Check(test = "test2") + public void checkTest2(TestInfo info) { + iFldCheck2++; + if (iFldCheck2 != iFld2) { + throw new RuntimeException(iFld2 + " must be equal " + iFldCheck2); + } + if (!info.isWarmUp()) { + if (iFld2 != 501) { + throw new RuntimeException("Must be 501 but was " + iFld2); + } + } + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java index c24266708da..3898d16add1 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java @@ -46,23 +46,26 @@ public static void main(String[] args) { TestFramework.runWithScenarios(sDefault, s1, s2); TestFramework.runWithScenarios(TestSanity.class, sDefault, s1); TestFramework.runWithScenarios(TestSanity.class, sDefault, s1, s2); - TestFramework testFramework = new TestFramework(TestSanity.class); + TestFramework testFramework = new TestFramework(); testFramework.start(); testFramework.addFlags("-XX:SuspendRetryCount=54").start(); - testFramework.clear(); + testFramework = new TestFramework(); testFramework.addFlags("-XX:SuspendRetryCount=55").addFlags("-XX:+UseTLAB").start(); - testFramework.clear(); + testFramework = new TestFramework(); testFramework.addHelperClasses(HelperA.class, HelperB.class).start(); - testFramework.clear(); testFramework = new TestFramework(); testFramework.addHelperClasses(HelperA.class, HelperB.class).addHelperClasses(HelperC.class).start(); - testFramework.clear(); + testFramework = new TestFramework(); testFramework.addScenarios(sDefault).addScenarios(s1, s2).start(); - testFramework.clear(); + testFramework = new TestFramework(); testFramework.addHelperClasses(HelperA.class).addScenarios(sDefault).addFlags("-XX:+UseSuperWord").start(); - testFramework.clear(); + testFramework = new TestFramework(); testFramework.addHelperClasses(HelperA.class).addFlags("-XX:+UseSuperWord", "-XX:+UseCompiler").addScenarios(sDefault) .addHelperClasses(HelperB.class, HelperC.class).addScenarios(s1, s2).addFlags("-XX:+TieredCompilation").start(); + testFramework = new TestFramework(); + testFramework.addHelperClasses(HelperA.class).addFlags("-XX:+UseSuperWord", "-XX:+UseCompiler").addScenarios(sDefault) + .addHelperClasses(HelperB.class, HelperC.class).addScenarios(s1, s2).setDefaultWarmup(200) + .addFlags("-XX:+TieredCompilation").start(); } @Test From e8bffb9fc0bf43d8970d56c716728a68d4809bca Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 18 Mar 2021 17:26:05 +0100 Subject: [PATCH 055/131] Forbid use of AbstractInfo as parameter or return type in any @Test method, update @Test Javadocs and add Javadocs for @Check and @Run --- .../test/lib/hotspot/ir_framework/Check.java | 61 ++++++++++++++++++- .../test/lib/hotspot/ir_framework/Run.java | 56 ++++++++++++++++- .../test/lib/hotspot/ir_framework/Test.java | 18 +++--- .../ir_framework/TestFrameworkExecution.java | 10 +-- .../ir_framework/tests/TestBadFormat.java | 14 +++++ 5 files changed, 143 insertions(+), 16 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java index 4774d84af8c..a0a03601649 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java @@ -27,14 +27,69 @@ import java.lang.annotation.RetentionPolicy; /** - * Annotation for a checked test. + * Annotation for a check method of a checked test. + * + *

    + * Let {@code t} be a test method specifying the {@link Test} annotation and {@code c} be a check method specifying + * the {@code @Check(test = "t")} annotation. These two methods represent a so-called checked test. The only + * difference to a base test (see {@link Test}) is that the framework will invoke the check method {@code c} + * directly after the invocation of the test method {@code t} which allows to do some additional verification, + * including the return value of {@code t}. The framework does the following, similar as for base tests: + *

      + *
    1. The framework warms {@code t} up by invoking it for a predefined number of iterations (default: 2000) + * or any number specified by an additional {@link Warmup} annotation at {@code t} or by using + * {@link TestFramework#setDefaultWarmup(int)} (could also be 0 which skips the warm-up completely which is similar + * to simulating {@code -Xcomp}). After each invocation of {@code t}, the framework also invokes {@code c} if the + * {@code @Check} annotation specifies {@link CheckAt#EACH_INVOCATION} at {@link Check#when()}.

    2. + *
    3. After the warm-up, the framework compiles {@code t} at the specified compilation level set by + * {@link Test#compLevel()} (default {@link CompLevel#ANY} will pick the highest available level which is usually + * {@link CompLevel#C2}).

    4. + *
    5. The framework invokes {@code t} one more time to check the compilation and immediately afterwards + * always invokes {@code c}.

    6. + *
    7. The framework checks any specified {@link IR} constraints at the test method {@code t}. + * More information about IR matching can be found in {@link IR}.

    8. + *
    + * + *

    + * The test method {@code t} has the same properties and follows the same constraints as stated in {@link Test}. + *

    + * The following additional constraints must be met for the test method {@code t} and check method {@code c}: + *

      + *
    • {@code c} must specify the method name {@code t} as property in {@code @Check(test = "t")} + * (see {@link Check#test()}. Specifying a non-{@code Test} annotated method or a {@code @Test} method that + * has already been used by another {@code @Check} or {@link Run} method results in a {@link TestFormatException}. + *

    • {@code c} can specify the following method parameter combinations: + *

        + *
      • void

      • + *
      • 1st parameter: {@link TestInfo} which provides some methods to check various things, including + * information about {@code t}.

      • + *
      • 1st parameter specifies the exact same type as the return value of {@code t}. When {@code c} is + * invoked by the framework, this parameter contains the return value of {@code t}.

      • + *
      • 1st parameter: {@link TestInfo}; 2nd parameter: return type of {@code t} (see above)

      • + *
      • Any other combination will result in a {@link TestFormatException}. + *

      + *
    • {@code c} is not compiled nor inlined. + *

    • {@code c} must be part of the test class. Using {@code @Check} in nested or other classes is not allowed.

    • // TODO write test for it + *
    • {@code c} cannot specify any helper-method specific compile command annotations ({@link ForceCompile}, + * {@link DontCompile}, {@link ForceInline}, {@link DontInline}).

    • + *
    + * + *

    + * If no verification is required, use a base test (see {@link Test}). If {@code t} must be invoked with more + * complex or varying arguments and/or the {@code t} must be invoked differently in subsequent invocations, use a + * custom run test (see {@link Run}). + * + * TODO: Add references to examples */ @Retention(RetentionPolicy.RUNTIME) public @interface Check { /** - * The associated {@link Test} method for this {@code @Check} annotated check method. The framework will directly - * invoke the {@code C@heck} method after each invocation or only after the compilation of the associated {@code @Test} + * The unique associated {@link Test} method for this {@code @Check} annotated check method. The framework will directly + * invoke the {@code @Check} method after each invocation or only after the compilation of the associated {@code @Test} * method (depending on the value set with {@link Check#when()}). + *

    + * If a non-{@code Test} annotated method is used or a {@code @Test} method that has already been used by another + * {@code @Check} or {@link Run} method, then a {@link TestFormatException} is thrown. * * @see Test */ diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java index 966577cfc39..b05a96191a1 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java @@ -27,7 +27,61 @@ import java.lang.annotation.RetentionPolicy; /** - * Annotation for a custom run test. + * Annotation for a run method of a custom run test. + * + *

    + * Let {@code t} be a test method specifying the {@link Test} annotation and {@code r} be a run method specifying + * the {@code @Run(test = "t")} annotation. These two methods represent a so-called custom run test. The only + * difference to a base test (see {@link Test}) is that the framework will not invoke the test method {@code t} + * but instead the run method {@code r} which is then responsible to invoke {@code t} and do any additional verification, + * (e.g. of the return value). If {@code Run} does not specify {@link RunMode#STANDALONE} as {@link Run#mode()} + * property, the framework does the following, similar as for base tests: + *

      + *
    1. The framework warms {@code r} up by invoking it for a predefined number of iterations (default: 2000) + * or any number specified by an additional {@link Warmup} annotation at the run method {@code r} or by using + * {@link TestFramework#setDefaultWarmup(int)} (could also be 0 which skips the warm-up completely which is similar + * to simulating {@code -Xcomp}). More information about the warm-up in general can be found in {@link Warmup}

    2. + *
    3. After the warm-up, the framework compiles the test method {@code t} at the specified compilation level set by + * {@link Test#compLevel()} (default {@link CompLevel#ANY} will pick the highest available level which is usually + * {@link CompLevel#C2}).

    4. + *
    5. The framework invokes the run method {@code r} one more time to check the compilation.

    6. + *
    7. The framework checks any specified {@link IR} constraints at the test method {@code t}. + * More information about IR matching can be found in {@link IR}.

    8. + *
    + * + *

    + * If {@code Run} specifies {@link RunMode#STANDALONE} as {@link Run#mode()} property, the framework gives complete + * control to the run method {@code r}: + *

      + *
    1. The framework invokes the run method {@code r} only one time without any warm-up or compilation of + * {@code t} ({@link Warmup} is not allowed at {@code r} in this case).

    2. + *
    3. After this single invocation, the framework directly checks any specified {@link IR} constraints at the test + * method {@code t}. The run method {@code r} needs to make sure to reliably trigger a C2 compilation. Otherwise, + * IR matching will fail. More information about IR matching can be found in {@link IR}.

    4. + *
    * + * + *

    + * The test method {@code t} and run method {@code r} have the following properties: + *

      + *
    • {@code t} can specify any parameter or return type except {@link AbstractInfo} or any of its subclasses.

    • + *
    • {@code t} is not inlined. + *

    • {@code r} is not compiled nor inlined. + *

    • {@code r} is responsible to invoke {@code t} in any way (once, multiple times or even skipping on some + * invocations of {@code r}). + *

    • {@code r} can specify the following method parameter combinations: + *

        + *
      • void

      • + *
      • 1st parameter: {@link RunInfo} which provides some methods to check various things, including + * information about {@code t}.

      • + *
      • Any other combination will result in a {@link TestFormatException}. + *

      + *
    • {@code t} and {@code r} must be part of the test class. Using {@code @Run} and ({@code @Test})in nested or + * other classes is not allowed.

    • // TODO write test for it + *
    • {@code t} and {@code r} cannot specify any helper-method specific compile command annotations + * ({@link ForceCompile}, {@link DontCompile}, {@link ForceInline}, {@link DontInline}).

    • + *
    + * + * TODO: Add references to examples */ @Retention(RetentionPolicy.RUNTIME) public @interface Run { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java index 8507e5bc578..ebc72cd988f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java @@ -30,19 +30,20 @@ * Annotate all methods in your test class which the framework should test with {@code @Test}. *

    * Let {@code m} be a test method specifying the {@code @Test} annotation. If {@code m} is neither part of a - * checked test(an additiona method specifying {@link Check} with (@code @Run(test = "m") nor part of a - * custom run test (an additional method specifying {@link Run} with (@code @Run(test = "m"))), - * then {@code m} is a so-called base test and the the framework invokes {@code m} in the following way: + * checked test (an additiona method specifying {@link Check} with (@code @Run(test = "m") nor part of a + * custom run test (an additional method specifying {@link Run} with (@code @Run(test = "m"))), + * then {@code m} is a so-called base test and the the framework invokes {@code m} in the following way: *

      - *
    1. The framework warms {@code m} up for a predefined number of iterations (default is 2000) or any number - * specified by an additional {@link Warmup} iteration (could also be 0 which skips the warm-up completely which is - * similar to simulating {@code -Xcomp}). More information about the warm-up can be found in {@link Warmup}

    2. + *
    3. The framework warms {@code m} up by invoking it for a predefined number of iterations (default: 2000) + * or any number specified by an additional {@link Warmup} annotation at {@code m} or by using + * {@link TestFramework#setDefaultWarmup(int)} (could also be 0 which skips the warm-up completely which is similar + * to simulating {@code -Xcomp}). More information about the warm-up in general can be found in {@link Warmup}

    4. *
    5. After the warm-up, the framework compiles {@code m} at the specified compilation level set by * {@link Test#compLevel()} (default {@link CompLevel#ANY} will pick the highest available level which is usually * {@link CompLevel#C2}).

    6. *
    7. The framework invokes {@code m} one more time to check the compilation.

    8. - *
    9. The framework checks any specified {@link IR} constraints. More information about IR matching can be - * found in {@link IR}.

    10. + *
    11. The framework checks any specified {@link IR} constraints at {@code m}. More information about IR matching + * can be found in {@link IR}.

    12. *
    * *

    @@ -52,6 +53,7 @@ *

  • If {@code m} specifies parameters, the framework needs to know how to call {@code m}. Use {@link Arguments} * with {@link Argument} properties for each parameter to use some well-defined parameters. If the method requires * a more specific argument value, use a custom run test (see {@link Run}).

  • + * li>

    {@code m} cannot specify {@link AbstractInfo} or any of its subclasses as parameter or return type. *

  • {@code m} is not inlined by the framework.

  • *
  • Verification of the return value of {@code m} can only be done in a checked test (see {@link Check}) or * custom run test (see {@link Run}).

  • diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 35509da5c20..2b650a322bd 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -474,11 +474,13 @@ private void checkTestAnnotations(Method m, Test testAnno) { TestFormat.check(checkAnno == null && runAnno == null, m + " has invalid @Check or @Run annotation while @Test annotation is present."); - TestFormat.checkNoThrow(!Arrays.asList(m.getParameterTypes()).contains(TestInfo.class), - "Cannot use of " + TestInfo.class + " as parameter type at @Test method " + m); + TestFormat.checkNoThrow(Arrays.stream(m.getParameterTypes()).noneMatch(AbstractInfo.class::isAssignableFrom), + "Cannot " + AbstractInfo.class + " or any of its subclasses as parameter type at " + + "@Test method " + m); - TestFormat.checkNoThrow(!m.getReturnType().equals(TestInfo.class), - "Cannot use of " + TestInfo.class + " as return type at @Test method " + m); + TestFormat.checkNoThrow(!AbstractInfo.class.isAssignableFrom(m.getReturnType()), + "Cannot " + AbstractInfo.class + " or any of its subclasses as return type at " + + "@Test method " + m); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java index 6acb37b8895..cea5524726b 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java @@ -428,6 +428,20 @@ class BadBaseTests { public TestInfo cannotUseTestInfoAsParameterOrReturn(TestInfo info) { return null; } + + @Test + @Arguments(Argument.DEFAULT) + @FailCount(3) // No default constructor + parameter + return + public RunInfo cannotUseRunInfoAsParameterOrReturn(RunInfo info) { + return null; + } + + @Test + @Arguments(Argument.DEFAULT) + @FailCount(3) // No default constructor + parameter + return + public AbstractInfo cannotUseAbstractInfoAsParameterOrReturn(AbstractInfo info) { + return null; + } } class BadRunTests { From d92ae5630c0cffd420b39a8c04995cd3afb6dc7c Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Thu, 18 Mar 2021 16:28:56 -0700 Subject: [PATCH 056/131] Added getTestMethod returning a Method object for particular test --- .../hotspot/ir_framework/TestFramework.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 3f11f508395..82ee2e45623 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -61,6 +61,8 @@ public class TestFramework { private TestFrameworkSocket socket; private int defaultWarmup = -1; + private final HashMap testMethods = new HashMap<>(); + /* * Public interface methods */ @@ -75,6 +77,7 @@ public class TestFramework { public TestFramework() { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); this.testClass = walker.getCallerClass(); + initTestsMap(); System.out.println(testClass); } @@ -91,6 +94,29 @@ public TestFramework() { public TestFramework(Class testClass) { TestRun.check(testClass != null, "Test class cannot be null"); this.testClass = testClass; + initTestsMap(); + } + + /** + * Returns a Method object that matches the specified test method name. + * + * @param mName the name of the test method + * @return the Method object matching the specified name + */ + public Method getTestMethod(String mName) { + return testMethods.get(mName); + } + + /* + * Helper method that gathers all test methods and put them in Hashtable + */ + synchronized private void initTestsMap() { + for (Method m : testClass.getDeclaredMethods()) { + Test[] testAnnos = m.getAnnotationsByType(Test.class); + if (testAnnos.length != 0) { + testMethods.put(m.getName(), m); + } + } } /** @@ -334,6 +360,10 @@ public static void deoptimize(Method m) { TestFrameworkExecution.deoptimize(m); } + public void deoptimize(String mName) { + deoptimize(getTestMethod(mName)); + } + public static boolean isC1Compiled(Method m) { return TestFrameworkExecution.isC1Compiled(m); } From 7b525d636534725598db87ec253e010266c2f679 Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Thu, 18 Mar 2021 16:30:54 -0700 Subject: [PATCH 057/131] Addjusted to latest TestFramework changes --- .../inlinetypes/TestBasicFunctionality.java | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java index c3ef1ced853..f6682eb6324 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java @@ -45,12 +45,13 @@ public class TestBasicFunctionality { + static final TestFramework testFramework = InlineTypes.getFramework(); + public static void main(String[] args) { Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; scenarios[2].addFlags("-DVerifyIR=false"); scenarios[3].addFlags("-XX:FlatArrayElementMaxSize=0"); - TestFramework testFramework = new TestFramework(TestBasicFunctionality.class); testFramework.addScenarios(scenarios) .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class, MyValue3.class, MyValue3Inline.class) @@ -464,7 +465,6 @@ public void test19_verifier() { Asserts.assertEQ(result, hash()); } - // Create an inline type (array) in compiled code and pass it to the // interpreter via a call. The inline type is live at the uncommon // trap: verify that deoptimization causes the inline type to be @@ -480,13 +480,7 @@ public long test20(boolean deopt) { MyValue2[] va = new MyValue2[3]; if (deopt) { // uncommon trap - try { - Method m = getClass().getDeclaredMethod("test20", boolean.class); - TestFramework.deoptimize(m); - } catch (NoSuchMethodException ex) { - System.out.println("ERROR: Failed to getDeclaredMethod test20"); - throw new TestRunException("Failed to getDeclaredMethod test20"); - } + testFramework.deoptimize("test20"); } return v.hashInterpreted() + va[0].hashInterpreted() + @@ -626,13 +620,7 @@ public void test27(boolean deopt) { unused.v = v; if (deopt) { // uncommon trap - try { - Method m = getClass().getDeclaredMethod("test27", boolean.class); - TestFramework.deoptimize(m); - } catch (NoSuchMethodException ex) { - System.out.println("ERROR: Failed to getDeclaredMethod test27"); - throw new TestRunException("Failed to getDeclaredMethod test27"); - } + testFramework.deoptimize("test27"); } } @@ -1000,4 +988,5 @@ public void test40_verifier(RunInfo info) { long result = test40(info.isWarmUp()); Asserts.assertEQ(result, info.isWarmUp() ? 0 : hash()); } + } From 57af3538753dbe4b606048e5b4e10f388a3309cb Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 19 Mar 2021 15:09:39 +0100 Subject: [PATCH 058/131] Move TestBasicFunctionality.java 1/3 --- .../inlinetypes/TestBasicFunctionality.java | 992 ------------------ .../TestBasicFunctionality.java | 440 ++++---- 2 files changed, 261 insertions(+), 1171 deletions(-) delete mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java deleted file mode 100644 index f6682eb6324..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java +++ /dev/null @@ -1,992 +0,0 @@ -/* - * Copyright (c) 2021, 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. - */ - -/* - * @test - * @key randomness - * @summary Test the basic inline type implementation in C2 - * - * @requires os.simpleArch == "x64" - * @library /test/lib - * @compile InlineTypes.java - * @run driver compiler.valhalla.inlinetypes.TestBasicFunctionality - */ - -package compiler.valhalla.inlinetypes; - -import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; -import java.lang.reflect.Method; - -import static compiler.valhalla.inlinetypes.InlineTypes.rI; -import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; -import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; - -public class TestBasicFunctionality { - - static final TestFramework testFramework = InlineTypes.getFramework(); - - public static void main(String[] args) { - Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; - scenarios[2].addFlags("-DVerifyIR=false"); - scenarios[3].addFlags("-XX:FlatArrayElementMaxSize=0"); - - testFramework.addScenarios(scenarios) - .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class, - MyValue3.class, MyValue3Inline.class) - .start(); - } - - // Helper methods - protected long hash() { - return hash(rI, rL); - } - - protected long hash(int x, long y) { - return MyValue1.createWithFieldsInline(x, y).hash(); - } - - - // Receive inline type through call to interpreter - @Test - @IR(failOn = {ALLOC, STORE, TRAP}) - public long test1() { - MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); - return v.hash(); - } - - @Run(test = "test1") - public void test1_verifier() { - long result = test1(); - Asserts.assertEQ(result, hash()); - } - - - // Receive inline type from interpreter via parameter - @Test - @IR(failOn = {ALLOC, STORE, TRAP}) - public long test2(MyValue1 v) { - return v.hash(); - } - - @Run(test = "test2") - public void test2_verifier() { - MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); - long result = test2(v); - Asserts.assertEQ(result, hash()); - } - - - // Return incoming inline type without accessing fields - @Test - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - counts = {ALLOC, "= 1", STORE, "= 14"}, - failOn = {LOAD, TRAP}) - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - failOn = {ALLOC, LOAD, STORE, TRAP}) - public MyValue1 test3(MyValue1 v) { - return v; - } - - - @Run(test = "test3") - public void test3_verifier() { - MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI, rL); - MyValue1 v2 = test3(v1); - Asserts.assertEQ(v1.x, v2.x); - Asserts.assertEQ(v1.y, v2.y); - } - - - // Create an inline type in compiled code and only use fields. - // Allocation should go away because inline type does not escape. - @Test - @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) - public long test4() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - return v.hash(); - } - - @Run(test = "test4") - public void test4_verifier() { - long result = test4(); - Asserts.assertEQ(result, hash()); - } - - - // Create an inline type in compiled code and pass it to - // an inlined compiled method via a call. - @Test - @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) - public long test5() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - return test5Inline(v); - } - - @ForceInline - public long test5Inline(MyValue1 v) { - return v.hash(); - } - - @Run(test = "test5") - public void test5_verifier() { - long result = test5(); - Asserts.assertEQ(result, hash()); - } - - - // Create an inline type in compiled code and pass it to - // the interpreter via a call. - @Test - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - failOn = {LOAD, TRAP, ALLOC}) - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - counts = {ALLOC, "= 1"}, - failOn = {LOAD, TRAP}) - public long test6() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - // Pass to interpreter - return v.hashInterpreted(); - } - - @Run(test = "test6") - public void test6_verifier() { - long result = test6(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type in compiled code and pass it to - // the interpreter by returning. - @Test - @IR(counts = {ALLOC, "= 1"}, - failOn = {LOAD, TRAP}) - public MyValue1 test7(int x, long y) { - return MyValue1.createWithFieldsInline(x, y); - } - - @Run(test = "test7") - public void test7_verifier() { - MyValue1 v = test7(rI, rL); - Asserts.assertEQ(v.hash(), hash()); - } - - - // Merge inline types created from two branches - @Test - @IR(failOn = {ALLOC, STORE, TRAP}) - public long test8(boolean b) { - MyValue1 v; - if (b) { - v = MyValue1.createWithFieldsInline(rI, rL); - } else { - v = MyValue1.createWithFieldsDontInline(rI + 1, rL + 1); - } - return v.hash(); - } - - @Run(test = "test8") - public void test8_verifier() { - Asserts.assertEQ(test8(true), hash()); - Asserts.assertEQ(test8(false), hash(rI + 1, rL + 1)); - } - - // Merge inline types created from two branches - @Test - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - counts = {LOAD, "= 14"}, - failOn = {TRAP, ALLOC, STORE}) - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - counts = {ALLOC, "= 1", STORE, "= 13"}, - failOn = {LOAD, TRAP}) - public MyValue1 test9(boolean b, int localrI, long localrL) { - MyValue1 v; - if (b) { - // Inline type is not allocated - // Do not use rI/rL directly here as null values may cause - // some redundant null initializations to be optimized out - // and matching to fail. - v = MyValue1.createWithFieldsInline(localrI, localrL); - } else { - // Inline type is allocated by the callee - v = MyValue1.createWithFieldsDontInline(rI + 1, rL + 1); - } - // Need to allocate inline type if 'b' is true - long sum = v.hashInterpreted(); - if (b) { - v = MyValue1.createWithFieldsDontInline(rI, sum); - } else { - v = MyValue1.createWithFieldsDontInline(rI, sum + 1); - } - // Don't need to allocate inline type because both branches allocate - return v; - } - - @Run(test = "test9") - public void test9_verifier() { - MyValue1 v = test9(true, rI, rL); - Asserts.assertEQ(v.x, rI); - Asserts.assertEQ(v.y, hash()); - v = test9(false, rI, rL); - Asserts.assertEQ(v.x, rI); - Asserts.assertEQ(v.y, hash(rI + 1, rL + 1) + 1); - } - - // Merge inline types created in a loop (not inlined) - @Test - @IR(failOn = {ALLOC, STORE, TRAP}) - public long test10(int x, long y) { - MyValue1 v = MyValue1.createWithFieldsDontInline(x, y); - for (int i = 0; i < 10; ++i) { - v = MyValue1.createWithFieldsDontInline(v.x + 1, v.y + 1); - } - return v.hash(); - } - - @Run(test = "test10") - public void test10_verifier() { - long result = test10(rI, rL); - Asserts.assertEQ(result, hash(rI + 10, rL + 10)); - } - - // Merge inline types created in a loop (inlined) - @Test - @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) - public long test11(int x, long y) { - MyValue1 v = MyValue1.createWithFieldsInline(x, y); - for (int i = 0; i < 10; ++i) { - v = MyValue1.createWithFieldsInline(v.x + 1, v.y + 1); - } - return v.hash(); - } - - @Run(test = "test11") - public void test11_verifier() { - long result = test11(rI, rL); - Asserts.assertEQ(result, hash(rI + 10, rL + 10)); - } - - - // Test loop with uncommon trap referencing an inline type - @Test - @IR(counts = {SCOBJ, ">= 1"}, // at least 1 - failOn = {LOAD}) - public long test12(boolean b) { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - MyValue1[] va = new MyValue1[Math.abs(rI) % 10]; - for (int i = 0; i < va.length; ++i) { - va[i] = MyValue1.createWithFieldsInline(rI, rL); - } - long result = rL; - for (int i = 0; i < 1000; ++i) { - if (b) { - result += v.x; - } else { - // Uncommon trap referencing v. We delegate allocation to the - // interpreter by adding a SafePointScalarObjectNode. - result = v.hashInterpreted(); - for (int j = 0; j < va.length; ++j) { - result += va[j].hash(); - } - } - } - return result; - } - - @Run(test = "test12") - public void test12_verifier(RunInfo info) { - long result = test12(info.isWarmUp()); - Asserts.assertEQ(result, info.isWarmUp() ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); - } - - - // Test loop with uncommon trap referencing an inline type - @Test - public long test13(boolean b) { - MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); - MyValue1[] va = new MyValue1[Math.abs(rI) % 10]; - for (int i = 0; i < va.length; ++i) { - va[i] = MyValue1.createWithFieldsDontInline(rI, rL); - } - long result = rL; - for (int i = 0; i < 1000; ++i) { - if (b) { - result += v.x; - } else { - // Uncommon trap referencing v. Should not allocate - // but just pass the existing oop to the uncommon trap. - result = v.hashInterpreted(); - for (int j = 0; j < va.length; ++j) { - result += va[j].hashInterpreted(); - } - } - } - return result; - } - - @Run(test = "test13") - public void test13_verifier(RunInfo info) { - long result = test13(info.isWarmUp()); - Asserts.assertEQ(result, info.isWarmUp() ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); - } - - - // Create an inline type in a non-inlined method and then call a - // non-inlined method on that inline type. - @Test - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - failOn = {ALLOC, STORE, TRAP}, - counts = {LOAD, "= 14"}) - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - failOn = {ALLOC, LOAD, STORE, TRAP}) - public long test14() { - MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); - return v.hashInterpreted(); - } - - @Run(test = "test14") - public void test14_verifier() { - long result = test14(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type in an inlined method and then call a - // non-inlined method on that inline type. - @Test - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - failOn = {LOAD, TRAP, ALLOC}) - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - failOn = {LOAD, TRAP}, - counts = {ALLOC, "= 1"}) - public long test15() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - return v.hashInterpreted(); - } - - @Run(test = "test15") - public void test15_verifier() { - long result = test15(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type in a non-inlined method and then call an - // inlined method on that inline type. - @Test - @IR(failOn = {ALLOC, STORE, TRAP}) - public long test16() { - MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); - return v.hash(); - } - - @Run(test = "test16") - public void test16_verifier() { - long result = test16(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type in an inlined method and then call an - // inlined method on that inline type. - @Test - @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) - public long test17() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - return v.hash(); - } - - @Run(test = "test17") - public void test17_verifier() { - long result = test17(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type in compiled code and pass it to the - // interpreter via a call. The inline type is live at the first call so - // debug info should include a reference to all its fields. - @Test - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - failOn = {ALLOC, LOAD, TRAP}) - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - counts = {ALLOC, "= 1"}, - failOn = {LOAD, TRAP}) - public long test18() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - v.hashInterpreted(); - return v.hashInterpreted(); - } - - @Run(test = "test18") - public void test18_verifier() { - long result = test18(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type in compiled code and pass it to the - // interpreter via a call. The inline type is passed twice but - // should only be allocated once. - @Test - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - failOn = {ALLOC, LOAD, TRAP}) - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - counts = {ALLOC, "= 1"}, - failOn = {LOAD, TRAP}) - public long test19() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - return sumValue(v, v); - } - - @DontCompile - public long sumValue(MyValue1 v, MyValue1 dummy) { - return v.hash(); - } - - @Run(test = "test19") - public void test19_verifier() { - long result = test19(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type (array) in compiled code and pass it to the - // interpreter via a call. The inline type is live at the uncommon - // trap: verify that deoptimization causes the inline type to be - // correctly allocated. - @Test - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, - failOn = {LOAD, ALLOC, STORE}) - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - counts = {ALLOC, "= 1"}, - failOn = {LOAD}) - public long test20(boolean deopt) { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - MyValue2[] va = new MyValue2[3]; - if (deopt) { - // uncommon trap - testFramework.deoptimize("test20"); - } - - return v.hashInterpreted() + va[0].hashInterpreted() + - va[1].hashInterpreted() + va[2].hashInterpreted(); - } - - @Run(test = "test20") - public void test20_verifier(RunInfo info) { - MyValue2[] va = new MyValue2[42]; - long result = test20(!info.isWarmUp()); - Asserts.assertEQ(result, hash() + va[0].hash() + va[1].hash() + va[2].hash()); - } - - - // Inline type fields in regular object - MyValue1 val1; - MyValue2 val2; - final MyValue1 val3 = MyValue1.createWithFieldsInline(rI, rL); - static MyValue1 val4; - static final MyValue1 val5 = MyValue1.createWithFieldsInline(rI, rL); - - // Test inline type fields in objects - @Test - @IR(counts = {ALLOC, "= 1"}, - failOn = {TRAP}) - public long test21(int x, long y) { - // Compute hash of inline type fields - long result = val1.hash() + val2.hash() + val3.hash() + val4.hash() + val5.hash(); - // Update fields - val1 = MyValue1.createWithFieldsInline(x, y); - val2 = MyValue2.createWithFieldsInline(x, rD); - val4 = MyValue1.createWithFieldsInline(x, y); - return result; - } - - @Run(test = "test21") - public void test21_verifier() { - // Check if hash computed by test18 is correct - val1 = MyValue1.createWithFieldsInline(rI, rL); - val2 = val1.v2; - // val3 is initialized in the constructor - val4 = val1; - // val5 is initialized in the static initializer - long hash = val1.hash() + val2.hash() + val3.hash() + val4.hash() + val5.hash(); - long result = test21(rI + 1, rL + 1); - Asserts.assertEQ(result, hash); - // Check if inline type fields were updated - Asserts.assertEQ(val1.hash(), hash(rI + 1, rL + 1)); - Asserts.assertEQ(val2.hash(), MyValue2.createWithFieldsInline(rI + 1, rD).hash()); - Asserts.assertEQ(val4.hash(), hash(rI + 1, rL + 1)); - } - - // Test folding of constant inline type fields - @Test - @IR(failOn = {ALLOC, LOAD, STORE, LOOP, TRAP}) - public long test22() { - // This should be constant folded - return val5.hash() + val5.v3.hash(); - } - - @Run(test = "test22") - public void test22_verifier() { - long result = test22(); - Asserts.assertEQ(result, val5.hash() + val5.v3.hash()); - } - - // Test defaultvalue - @Test - @IR(failOn = {ALLOC, LOAD, STORE, LOOP, TRAP}) - public long test23() { - MyValue2 v = MyValue2.createDefaultInline(); - return v.hash(); - } - - @Run(test = "test23") - public void test23_verifier() { - long result = test23(); - Asserts.assertEQ(result, MyValue2.createDefaultInline().hash()); - } - - // Test defaultvalue - @Test - @IR(failOn = {ALLOC, STORE, LOOP, TRAP}) - public long test24() { - MyValue1 v1 = MyValue1.createDefaultInline(); - MyValue1 v2 = MyValue1.createDefaultDontInline(); - return v1.hashPrimitive() + v2.hashPrimitive(); - } - - @Run(test = "test24") - public void test24_verifier() { - long result = test24(); - Asserts.assertEQ(result, 2 * MyValue1.createDefaultInline().hashPrimitive()); - } - - // Test withfield - @Test - @IR(failOn = {ALLOC, LOAD, STORE, LOOP, TRAP}) - public long test25() { - MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); - return v.hash(); - } - - @Run(test = "test25") - public void test25_verifier() { - long result = test25(); - Asserts.assertEQ(result, MyValue2.createWithFieldsInline(rI, rD).hash()); - } - - // Test withfield - @Test - @IR(failOn = {ALLOC, STORE, LOOP, TRAP}) - public long test26() { - MyValue1 v1 = MyValue1.createWithFieldsInline(rI, rL); - MyValue1 v2 = MyValue1.createWithFieldsDontInline(rI, rL); - return v1.hash() + v2.hash(); - } - - @Run(test = "test26") - public void test26_verifier() { - long result = test26(); - Asserts.assertEQ(result, 2 * hash()); - } - - class TestClass27 { - public MyValue1 v; - } - - - - // Test allocation elimination of unused object with initialized inline type field - @Test - @IR(failOn = {ALLOC, LOAD, STORE, LOOP}) - public void test27(boolean deopt) { - TestClass27 unused = new TestClass27(); - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - unused.v = v; - if (deopt) { - // uncommon trap - testFramework.deoptimize("test27"); - } - } - - @Run(test = "test27") - public void test27_verifier(RunInfo info) { - test27(!info.isWarmUp()); - } - - - - static MyValue3 staticVal3; - static MyValue3 staticVal3_copy; - - // Check elimination of redundant inline type allocations - @Test - @IR(counts = {ALLOC, "= 1"}) - public MyValue3 test28(MyValue3[] va) { - // Create inline type and force allocation - MyValue3 vt = MyValue3.create(); - va[0] = vt; - staticVal3 = vt; - vt.verify(staticVal3); - - // Inline type is now allocated, make a copy and force allocation. - // Because copy is equal to vt, C2 should remove this redundant allocation. - MyValue3 copy = MyValue3.setC(vt, vt.c); - va[0] = copy; - staticVal3_copy = copy; - copy.verify(staticVal3_copy); - return copy; - } - - @Run(test = "test28") - public void test28_verifier() { - MyValue3[] va = new MyValue3[1]; - MyValue3 vt = test28(va); - staticVal3.verify(vt); - staticVal3.verify(va[0]); - staticVal3_copy.verify(vt); - staticVal3_copy.verify(va[0]); - } - - // Verify that only dominating allocations are re-used - @Test() - public MyValue3 test29(boolean warmup) { - MyValue3 vt = MyValue3.create(); - if (warmup) { - staticVal3 = vt; // Force allocation - } - // Force allocation to verify that above - // non-dominating allocation is not re-used - MyValue3 copy = MyValue3.setC(vt, vt.c); - staticVal3_copy = copy; - copy.verify(vt); - return copy; - } - - @Run(test = "test29") - public void test29_verifier(RunInfo info) { - MyValue3 vt = test29(info.isWarmUp()); - if (info.isWarmUp()) { - staticVal3.verify(vt); - } - } - - // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations - @Test - @IR(failOn = {ALLOC, ALLOCA, STORE}) - public MyValue3 test30(MyValue3[] va) { - // C2 can re-use the oop of staticVal3 because staticVal3 is equal to copy - MyValue3 copy = MyValue3.copy(staticVal3); - va[0] = copy; - staticVal3 = copy; - copy.verify(staticVal3); - return copy; - } - - @Run(test = "test30") - public void test30_verifier() { - staticVal3 = MyValue3.create(); - MyValue3[] va = new MyValue3[1]; - MyValue3 vt = test30(va); - staticVal3.verify(vt); - staticVal3.verify(va[0]); - } - - // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations - @Test - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - failOn = {ALLOC, ALLOCA, STORE}) - public MyValue3 test31(MyValue3[] va) { - // C2 can re-use the oop returned by createDontInline() - // because the corresponding inline type is equal to 'copy'. - MyValue3 copy = MyValue3.copy(MyValue3.createDontInline()); - va[0] = copy; - staticVal3 = copy; - copy.verify(staticVal3); - return copy; - } - - @Run(test = "test31") - public void test31_verifier() { - MyValue3[] va = new MyValue3[1]; - MyValue3 vt = test31(va); - staticVal3.verify(vt); - staticVal3.verify(va[0]); - } - - // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations - @Test - @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, - failOn = {ALLOC, ALLOCA, STORE}) - public MyValue3 test32(MyValue3 vt, MyValue3[] va) { - // C2 can re-use the oop of vt because vt is equal to 'copy'. - MyValue3 copy = MyValue3.copy(vt); - va[0] = copy; - staticVal3 = copy; - copy.verify(staticVal3); - return copy; - } - - @Run(test = "test32") - public void test32_verifier() { - MyValue3 vt = MyValue3.create(); - MyValue3[] va = new MyValue3[1]; - MyValue3 result = test32(vt, va); - staticVal3.verify(vt); - va[0].verify(vt); - result.verify(vt); - } - - // Test correct identification of inline type copies - @Test - public MyValue3 test33(MyValue3[] va) { - MyValue3 vt = MyValue3.copy(staticVal3); - vt = MyValue3.setI(vt, vt.c); - // vt is not equal to staticVal3, so C2 should not re-use the oop - va[0] = vt; - staticVal3 = vt; - vt.verify(staticVal3); - return vt; - } - - @Run(test = "test33") - public void test33_verifier() { - staticVal3 = MyValue3.create(); - MyValue3[] va = new MyValue3[1]; - MyValue3 vt = test33(va); - Asserts.assertEQ(staticVal3.i, (int)staticVal3.c); - Asserts.assertEQ(va[0].i, (int)staticVal3.c); - Asserts.assertEQ(vt.i, (int)staticVal3.c); - } - - // Verify that the default inline type is never allocated. - // C2 code should load and use the default oop from the java mirror. - @Test - @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE, LOOP, TRAP}) - public MyValue3 test34(MyValue3[] va) { - // Explicitly create default value - MyValue3 vt = MyValue3.createDefault(); - va[0] = vt; - staticVal3 = vt; - vt.verify(vt); - - // Load default value from uninitialized inline type array - MyValue3[] dva = new MyValue3[1]; - staticVal3_copy = dva[0]; - va[1] = dva[0]; - dva[0].verify(dva[0]); - return vt; - } - - @Run(test = "test34") - public void test34_verifier() { - MyValue3 vt = MyValue3.createDefault(); - MyValue3[] va = new MyValue3[2]; - va[0] = MyValue3.create(); - va[1] = MyValue3.create(); - MyValue3 res = test34(va); - res.verify(vt); - staticVal3.verify(vt); - staticVal3_copy.verify(vt); - va[0].verify(vt); - va[1].verify(vt); - } - - // Same as above but manually initialize inline type fields to default. - @Test - @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE, LOOP, TRAP}) - public MyValue3 test35(MyValue3 vt, MyValue3[] va) { - vt = MyValue3.setC(vt, (char)0); - vt = MyValue3.setBB(vt, (byte)0); - vt = MyValue3.setS(vt, (short)0); - vt = MyValue3.setI(vt, 0); - vt = MyValue3.setL(vt, 0); - vt = MyValue3.setO(vt, null); - vt = MyValue3.setF1(vt, 0); - vt = MyValue3.setF2(vt, 0); - vt = MyValue3.setF3(vt, 0); - vt = MyValue3.setF4(vt, 0); - vt = MyValue3.setF5(vt, 0); - vt = MyValue3.setF6(vt, 0); - vt = MyValue3.setV1(vt, MyValue3Inline.createDefault()); - va[0] = vt; - staticVal3 = vt; - vt.verify(vt); - return vt; - } - - @Run(test = "test35") - public void test35_verifier() { - MyValue3 vt = MyValue3.createDefault(); - MyValue3[] va = new MyValue3[1]; - va[0] = MyValue3.create(); - MyValue3 res = test35(va[0], va); - res.verify(vt); - staticVal3.verify(vt); - va[0].verify(vt); - } - - // Merge inline types created from two branches - - private Object test36_helper(Object v) { - return v; - } - - @Test - @IR(failOn = {ALLOC, STORE, TRAP}) - public long test36(boolean b) { - Object o; - if (b) { - o = test36_helper(MyValue1.createWithFieldsInline(rI, rL)); - } else { - o = test36_helper(MyValue1.createWithFieldsDontInline(rI + 1, rL + 1)); - } - MyValue1 v = (MyValue1)o; - return v.hash(); - } - - @Run(test = "test36") - public void test36_verifier() { - Asserts.assertEQ(test36(true), hash()); - Asserts.assertEQ(test36(false), hash(rI + 1, rL + 1)); - } - - // Test correct loading of flattened fields - primitive class Test37Value2 { - final int x = 0; - final int y = 0; - } - - primitive class Test37Value1 { - final double d = 0; - final float f = 0; - final Test37Value2 v = new Test37Value2(); - } - - @Test - public Test37Value1 test37(Test37Value1 vt) { - return vt; - } - - @Run(test = "test37") - public void test37_verifier() { - Test37Value1 vt = new Test37Value1(); - Asserts.assertEQ(test37(vt), vt); - } - - // Test elimination of inline type allocations without a unique CheckCastPP - primitive class Test38Value { - public int i; - public Test38Value(int i) { this.i = i; } - } - - static Test38Value test38Field; - - @Test - public void test38() { - for (int i = 3; i < 100; ++i) { - int j = 1; - while (++j < 11) { - try { - test38Field = new Test38Value(i); - } catch (ArithmeticException ae) { } - } - } - } - - @Run(test = "test38") - public void test38_verifier() { - test38Field = Test38Value.default; - test38(); - Asserts.assertEQ(test38Field, new Test38Value(99)); - } - - // Tests split if with inline type Phi users - static primitive class Test39Value { - public int iFld1; - public int iFld2; - - public Test39Value(int i1, int i2) { iFld1 = i1; iFld2 = i2; } - } - - static int test39A1[][] = new int[400][400]; - static double test39A2[] = new double[400]; - static Test39Value test39Val = Test39Value.default; - - @DontInline - public int[] getArray() { - return new int[400]; - } - - @Test - public int test39() { - int result = 0; - for (int i = 0; i < 100; ++i) { - switch ((i >>> 1) % 3) { - case 0: - test39A1[i][i] = i; - break; - case 1: - for (int j = 0; j < 100; ++j) { - test39A1[i] = getArray(); - test39Val = new Test39Value(j, test39Val.iFld2); - } - break; - case 2: - for (float f = 142; f > i; f--) { - test39A2[i + 1] += 3; - } - result += test39Val.iFld1; - break; - } - double d1 = 1; - while (++d1 < 142) { - test39A1[(i >>> 1) % 400][i + 1] = result; - test39Val = new Test39Value(i, test39Val.iFld2); - } - } - return result; - } - - @Run(test = "test39") - @Warmup(10) - public void test39_verifier() { - int result = test39(); - Asserts.assertEQ(result, 1552); - } - - // Test scalar replacement of inline type array containing inline type with oop fields - @Test() - public long test40(boolean b) { - MyValue1[] va = {MyValue1.createWithFieldsInline(rI, rL)}; - long result = 0; - for (int i = 0; i < 1000; ++i) { - if (!b) { - result = va[0].hash(); - } - } - return result; - } - - @Run(test = "test40") - public void test40_verifier(RunInfo info) { - long result = test40(info.isWarmUp()); - Asserts.assertEQ(result, info.isWarmUp() ? 0 : hash()); - } - -} diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java index da6ec98bdfd..7bd1fa83f5b 100644 --- a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java +++ b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -21,41 +21,44 @@ * questions. */ -package compiler.valhalla.inlinetypes; - -import jdk.test.lib.Asserts; - /* * @test * @key randomness * @summary Test the basic inline type implementation in C2 - * @library /testlibrary /test/lib /compiler/whitebox / + * * @requires os.simpleArch == "x64" - * @compile TestBasicFunctionality.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestBasicFunctionality + * @library /test/lib + * @compile InlineTypes.java + * @run driver compiler.valhalla.inlinetypes.TestBasicFunctionality */ -public class TestBasicFunctionality extends InlineTypeTest { - // Extra VM parameters for some test scenarios. See InlineTypeTest.getVMParameters() - @Override - public String[] getExtraVMParameters(int scenario) { - switch (scenario) { - case 2: return new String[] {"-DVerifyIR=false"}; - case 3: return new String[] {"-XX:FlatArrayElementMaxSize=0"}; - } - return null; - } - public static void main(String[] args) throws Throwable { - TestBasicFunctionality test = new TestBasicFunctionality(); - test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, MyValue3.class, MyValue3Inline.class); +package compiler.valhalla.inlinetypes; + +import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; +import java.lang.reflect.Method; + +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; + +public class TestBasicFunctionality { + + static final TestFramework testFramework = InlineTypes.getFramework(); + + public static void main(String[] args) { + Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; + scenarios[2].addFlags("-DVerifyIR=false"); + scenarios[3].addFlags("-XX:FlatArrayElementMaxSize=0"); + + testFramework.addScenarios(scenarios) + .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class, + MyValue3.class, MyValue3Inline.class) + .start(); } // Helper methods - protected long hash() { return hash(rI, rL); } @@ -64,64 +67,78 @@ protected long hash(int x, long y) { return MyValue1.createWithFieldsInline(x, y).hash(); } + // Receive inline type through call to interpreter - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test1() { MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); return v.hash(); } - @DontCompile - public void test1_verifier(boolean warmup) { + @Run(test = "test1") + public void test1_verifier() { long result = test1(); Asserts.assertEQ(result, hash()); } + // Receive inline type from interpreter via parameter - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test2(MyValue1 v) { return v.hash(); } - @DontCompile - public void test2_verifier(boolean warmup) { + @Run(test = "test2") + public void test2_verifier() { MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); long result = test2(v); Asserts.assertEQ(result, hash()); } + // Return incoming inline type without accessing fields - @Test(valid = InlineTypePassFieldsAsArgsOn, match = {ALLOC, STORE}, matchCount = {1, 14}, failOn = LOAD + TRAP) - @Test(valid = InlineTypePassFieldsAsArgsOff, failOn = ALLOC + LOAD + STORE + TRAP) + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + counts = {ALLOC, "= 1", STORE, "= 14"}, + failOn = {LOAD, TRAP}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + failOn = {ALLOC, LOAD, STORE, TRAP}) public MyValue1 test3(MyValue1 v) { return v; } - @DontCompile - public void test3_verifier(boolean warmup) { + + @Run(test = "test3") + public void test3_verifier() { MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI, rL); MyValue1 v2 = test3(v1); Asserts.assertEQ(v1.x, v2.x); Asserts.assertEQ(v1.y, v2.y); } + // Create an inline type in compiled code and only use fields. // Allocation should go away because inline type does not escape. - @Test(failOn = ALLOC + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) public long test4() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); return v.hash(); } - @DontCompile - public void test4_verifier(boolean warmup) { + @Run(test = "test4") + public void test4_verifier() { long result = test4(); Asserts.assertEQ(result, hash()); } + // Create an inline type in compiled code and pass it to // an inlined compiled method via a call. - @Test(failOn = ALLOC + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) public long test5() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); return test5Inline(v); @@ -132,43 +149,52 @@ public long test5Inline(MyValue1 v) { return v.hash(); } - @DontCompile - public void test5_verifier(boolean warmup) { + @Run(test = "test5") + public void test5_verifier() { long result = test5(); Asserts.assertEQ(result, hash()); } + // Create an inline type in compiled code and pass it to // the interpreter via a call. - @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = LOAD + TRAP + ALLOC) - @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP) + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + failOn = {LOAD, TRAP, ALLOC}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + counts = {ALLOC, "= 1"}, + failOn = {LOAD, TRAP}) public long test6() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); // Pass to interpreter return v.hashInterpreted(); } - @DontCompile - public void test6_verifier(boolean warmup) { + @Run(test = "test6") + public void test6_verifier() { long result = test6(); Asserts.assertEQ(result, hash()); } // Create an inline type in compiled code and pass it to // the interpreter by returning. - @Test(match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP) + @Test + @IR(counts = {ALLOC, "= 1"}, + failOn = {LOAD, TRAP}) public MyValue1 test7(int x, long y) { return MyValue1.createWithFieldsInline(x, y); } - @DontCompile - public void test7_verifier(boolean warmup) { + @Run(test = "test7") + public void test7_verifier() { MyValue1 v = test7(rI, rL); Asserts.assertEQ(v.hash(), hash()); } + // Merge inline types created from two branches - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test8(boolean b) { MyValue1 v; if (b) { @@ -179,15 +205,20 @@ public long test8(boolean b) { return v.hash(); } - @DontCompile - public void test8_verifier(boolean warmup) { + @Run(test = "test8") + public void test8_verifier() { Asserts.assertEQ(test8(true), hash()); Asserts.assertEQ(test8(false), hash(rI + 1, rL + 1)); } // Merge inline types created from two branches - @Test(valid = InlineTypePassFieldsAsArgsOn, match = {LOAD}, matchCount = {14}, failOn = TRAP + ALLOC + STORE) - @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC, STORE}, matchCount = {1, 13}, failOn = LOAD + TRAP) + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + counts = {LOAD, "= 14"}, + failOn = {TRAP, ALLOC, STORE}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + counts = {ALLOC, "= 1", STORE, "= 13"}, + failOn = {LOAD, TRAP}) public MyValue1 test9(boolean b, int localrI, long localrL) { MyValue1 v; if (b) { @@ -211,8 +242,8 @@ public MyValue1 test9(boolean b, int localrI, long localrL) { return v; } - @DontCompile - public void test9_verifier(boolean warmup) { + @Run(test = "test9") + public void test9_verifier() { MyValue1 v = test9(true, rI, rL); Asserts.assertEQ(v.x, rI); Asserts.assertEQ(v.y, hash()); @@ -222,7 +253,8 @@ public void test9_verifier(boolean warmup) { } // Merge inline types created in a loop (not inlined) - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test10(int x, long y) { MyValue1 v = MyValue1.createWithFieldsDontInline(x, y); for (int i = 0; i < 10; ++i) { @@ -231,14 +263,15 @@ public long test10(int x, long y) { return v.hash(); } - @DontCompile - public void test10_verifier(boolean warmup) { + @Run(test = "test10") + public void test10_verifier() { long result = test10(rI, rL); Asserts.assertEQ(result, hash(rI + 10, rL + 10)); } // Merge inline types created in a loop (inlined) - @Test(failOn = ALLOC + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) public long test11(int x, long y) { MyValue1 v = MyValue1.createWithFieldsInline(x, y); for (int i = 0; i < 10; ++i) { @@ -247,14 +280,17 @@ public long test11(int x, long y) { return v.hash(); } - @DontCompile - public void test11_verifier(boolean warmup) { + @Run(test = "test11") + public void test11_verifier() { long result = test11(rI, rL); Asserts.assertEQ(result, hash(rI + 10, rL + 10)); } + // Test loop with uncommon trap referencing an inline type - @Test(match = {SCOBJ}, matchCount = {-1 /* at least 1 */}, failOn = LOAD) + @Test + @IR(counts = {SCOBJ, ">= 1"}, // at least 1 + failOn = {LOAD}) public long test12(boolean b) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue1[] va = new MyValue1[Math.abs(rI) % 10]; @@ -277,12 +313,13 @@ public long test12(boolean b) { return result; } - @DontCompile - public void test12_verifier(boolean warmup) { - long result = test12(warmup); - Asserts.assertEQ(result, warmup ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); + @Run(test = "test12") + public void test12_verifier(RunInfo info) { + long result = test12(info.isWarmUp()); + Asserts.assertEQ(result, info.isWarmUp() ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); } + // Test loop with uncommon trap referencing an inline type @Test public long test13(boolean b) { @@ -307,66 +344,77 @@ public long test13(boolean b) { return result; } - @DontCompile - public void test13_verifier(boolean warmup) { - long result = test13(warmup); - Asserts.assertEQ(result, warmup ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); + @Run(test = "test13") + public void test13_verifier(RunInfo info) { + long result = test13(info.isWarmUp()); + Asserts.assertEQ(result, info.isWarmUp() ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); } + // Create an inline type in a non-inlined method and then call a // non-inlined method on that inline type. - @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = (ALLOC + STORE + TRAP), match = {LOAD}, matchCount = {14}) - @Test(valid = InlineTypePassFieldsAsArgsOff, failOn = (ALLOC + LOAD + STORE + TRAP)) + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + failOn = {ALLOC, STORE, TRAP}, + counts = {LOAD, "= 14"}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + failOn = {ALLOC, LOAD, STORE, TRAP}) public long test14() { MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); return v.hashInterpreted(); } - @DontCompile - public void test14_verifier(boolean b) { + @Run(test = "test14") + public void test14_verifier() { long result = test14(); Asserts.assertEQ(result, hash()); } // Create an inline type in an inlined method and then call a // non-inlined method on that inline type. - @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = (LOAD + TRAP + ALLOC)) - @Test(valid = InlineTypePassFieldsAsArgsOff, failOn = (LOAD + TRAP), match = {ALLOC}, matchCount = {1}) + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + failOn = {LOAD, TRAP, ALLOC}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + failOn = {LOAD, TRAP}, + counts = {ALLOC, "= 1"}) public long test15() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); return v.hashInterpreted(); } - @DontCompile - public void test15_verifier(boolean b) { + @Run(test = "test15") + public void test15_verifier() { long result = test15(); Asserts.assertEQ(result, hash()); } // Create an inline type in a non-inlined method and then call an // inlined method on that inline type. - @Test(failOn = (ALLOC + STORE + TRAP)) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test16() { MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); return v.hash(); } - @DontCompile - public void test16_verifier(boolean b) { + @Run(test = "test16") + public void test16_verifier() { long result = test16(); Asserts.assertEQ(result, hash()); } // Create an inline type in an inlined method and then call an // inlined method on that inline type. - @Test(failOn = (ALLOC + LOAD + STORE + TRAP)) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) public long test17() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); return v.hash(); } - @DontCompile - public void test17_verifier(boolean b) { + @Run(test = "test17") + public void test17_verifier() { long result = test17(); Asserts.assertEQ(result, hash()); } @@ -374,16 +422,20 @@ public void test17_verifier(boolean b) { // Create an inline type in compiled code and pass it to the // interpreter via a call. The inline type is live at the first call so // debug info should include a reference to all its fields. - @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = ALLOC + LOAD + TRAP) - @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP) + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + failOn = {ALLOC, LOAD, TRAP}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + counts = {ALLOC, "= 1"}, + failOn = {LOAD, TRAP}) public long test18() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); v.hashInterpreted(); return v.hashInterpreted(); } - @DontCompile - public void test18_verifier(boolean warmup) { + @Run(test = "test18") + public void test18_verifier() { long result = test18(); Asserts.assertEQ(result, hash()); } @@ -391,8 +443,12 @@ public void test18_verifier(boolean warmup) { // Create an inline type in compiled code and pass it to the // interpreter via a call. The inline type is passed twice but // should only be allocated once. - @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = ALLOC + LOAD + TRAP) - @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP) + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + failOn = {ALLOC, LOAD, TRAP}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + counts = {ALLOC, "= 1"}, + failOn = {LOAD, TRAP}) public long test19() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); return sumValue(v, v); @@ -403,8 +459,8 @@ public long sumValue(MyValue1 v, MyValue1 dummy) { return v.hash(); } - @DontCompile - public void test19_verifier(boolean warmup) { + @Run(test = "test19") + public void test19_verifier() { long result = test19(); Asserts.assertEQ(result, hash()); } @@ -413,26 +469,32 @@ public void test19_verifier(boolean warmup) { // interpreter via a call. The inline type is live at the uncommon // trap: verify that deoptimization causes the inline type to be // correctly allocated. - @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = LOAD + ALLOC + STORE) - @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {1}, failOn = LOAD) + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + failOn = {LOAD, ALLOC, STORE}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + counts = {ALLOC, "= 1"}, + failOn = {LOAD}) public long test20(boolean deopt) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue2[] va = new MyValue2[3]; if (deopt) { // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test20")); + testFramework.deoptimize("test20"); } + return v.hashInterpreted() + va[0].hashInterpreted() + - va[1].hashInterpreted() + va[2].hashInterpreted(); + va[1].hashInterpreted() + va[2].hashInterpreted(); } - @DontCompile - public void test20_verifier(boolean warmup) { + @Run(test = "test20") + public void test20_verifier(RunInfo info) { MyValue2[] va = new MyValue2[42]; - long result = test20(!warmup); + long result = test20(!info.isWarmUp()); Asserts.assertEQ(result, hash() + va[0].hash() + va[1].hash() + va[2].hash()); } + // Inline type fields in regular object MyValue1 val1; MyValue2 val2; @@ -441,7 +503,9 @@ public void test20_verifier(boolean warmup) { static final MyValue1 val5 = MyValue1.createWithFieldsInline(rI, rL); // Test inline type fields in objects - @Test(match = {ALLOC}, matchCount = {1}, failOn = (TRAP)) + @Test + @IR(counts = {ALLOC, "= 1"}, + failOn = {TRAP}) public long test21(int x, long y) { // Compute hash of inline type fields long result = val1.hash() + val2.hash() + val3.hash() + val4.hash() + val5.hash(); @@ -452,8 +516,8 @@ public long test21(int x, long y) { return result; } - @DontCompile - public void test21_verifier(boolean warmup) { + @Run(test = "test21") + public void test21_verifier() { // Check if hash computed by test18 is correct val1 = MyValue1.createWithFieldsInline(rI, rL); val2 = val1.v2; @@ -470,68 +534,73 @@ public void test21_verifier(boolean warmup) { } // Test folding of constant inline type fields - @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, LOOP, TRAP}) public long test22() { // This should be constant folded return val5.hash() + val5.v3.hash(); } - @DontCompile - public void test22_verifier(boolean warmup) { + @Run(test = "test22") + public void test22_verifier() { long result = test22(); Asserts.assertEQ(result, val5.hash() + val5.v3.hash()); } // Test defaultvalue - @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, LOOP, TRAP}) public long test23() { MyValue2 v = MyValue2.createDefaultInline(); return v.hash(); } - @DontCompile - public void test23_verifier(boolean warmup) { + @Run(test = "test23") + public void test23_verifier() { long result = test23(); Asserts.assertEQ(result, MyValue2.createDefaultInline().hash()); } // Test defaultvalue - @Test(failOn = ALLOC + STORE + LOOP + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, LOOP, TRAP}) public long test24() { MyValue1 v1 = MyValue1.createDefaultInline(); MyValue1 v2 = MyValue1.createDefaultDontInline(); return v1.hashPrimitive() + v2.hashPrimitive(); } - @DontCompile - public void test24_verifier(boolean warmup) { + @Run(test = "test24") + public void test24_verifier() { long result = test24(); Asserts.assertEQ(result, 2 * MyValue1.createDefaultInline().hashPrimitive()); } // Test withfield - @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, LOOP, TRAP}) public long test25() { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); return v.hash(); } - @DontCompile - public void test25_verifier(boolean warmup) { + @Run(test = "test25") + public void test25_verifier() { long result = test25(); Asserts.assertEQ(result, MyValue2.createWithFieldsInline(rI, rD).hash()); } // Test withfield - @Test(failOn = ALLOC + STORE + LOOP + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, LOOP, TRAP}) public long test26() { MyValue1 v1 = MyValue1.createWithFieldsInline(rI, rL); MyValue1 v2 = MyValue1.createWithFieldsDontInline(rI, rL); return v1.hash() + v2.hash(); } - @DontCompile - public void test26_verifier(boolean warmup) { + @Run(test = "test26") + public void test26_verifier() { long result = test26(); Asserts.assertEQ(result, 2 * hash()); } @@ -540,28 +609,34 @@ class TestClass27 { public MyValue1 v; } + + // Test allocation elimination of unused object with initialized inline type field - @Test(failOn = ALLOC + LOAD + STORE + LOOP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, LOOP}) public void test27(boolean deopt) { TestClass27 unused = new TestClass27(); MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); unused.v = v; if (deopt) { // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test27")); + testFramework.deoptimize("test27"); } } - @DontCompile - public void test27_verifier(boolean warmup) { - test27(!warmup); + @Run(test = "test27") + public void test27_verifier(RunInfo info) { + test27(!info.isWarmUp()); } + + static MyValue3 staticVal3; static MyValue3 staticVal3_copy; // Check elimination of redundant inline type allocations - @Test(match = {ALLOC}, matchCount = {1}) + @Test + @IR(counts = {ALLOC, "= 1"}) public MyValue3 test28(MyValue3[] va) { // Create inline type and force allocation MyValue3 vt = MyValue3.create(); @@ -578,8 +653,8 @@ public MyValue3 test28(MyValue3[] va) { return copy; } - @DontCompile - public void test28_verifier(boolean warmup) { + @Run(test = "test28") + public void test28_verifier() { MyValue3[] va = new MyValue3[1]; MyValue3 vt = test28(va); staticVal3.verify(vt); @@ -603,16 +678,17 @@ public MyValue3 test29(boolean warmup) { return copy; } - @DontCompile - public void test29_verifier(boolean warmup) { - MyValue3 vt = test29(warmup); - if (warmup) { + @Run(test = "test29") + public void test29_verifier(RunInfo info) { + MyValue3 vt = test29(info.isWarmUp()); + if (info.isWarmUp()) { staticVal3.verify(vt); } } // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations - @Test(failOn = ALLOC + ALLOCA + STORE) + @Test + @IR(failOn = {ALLOC, ALLOCA, STORE}) public MyValue3 test30(MyValue3[] va) { // C2 can re-use the oop of staticVal3 because staticVal3 is equal to copy MyValue3 copy = MyValue3.copy(staticVal3); @@ -622,8 +698,8 @@ public MyValue3 test30(MyValue3[] va) { return copy; } - @DontCompile - public void test30_verifier(boolean warmup) { + @Run(test = "test30") + public void test30_verifier() { staticVal3 = MyValue3.create(); MyValue3[] va = new MyValue3[1]; MyValue3 vt = test30(va); @@ -632,8 +708,9 @@ public void test30_verifier(boolean warmup) { } // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations - @Test(valid = InlineTypeReturnedAsFieldsOn) - @Test(valid = InlineTypeReturnedAsFieldsOff, failOn = ALLOC + ALLOCA + STORE) + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + failOn = {ALLOC, ALLOCA, STORE}) public MyValue3 test31(MyValue3[] va) { // C2 can re-use the oop returned by createDontInline() // because the corresponding inline type is equal to 'copy'. @@ -644,8 +721,8 @@ public MyValue3 test31(MyValue3[] va) { return copy; } - @DontCompile - public void test31_verifier(boolean warmup) { + @Run(test = "test31") + public void test31_verifier() { MyValue3[] va = new MyValue3[1]; MyValue3 vt = test31(va); staticVal3.verify(vt); @@ -653,8 +730,9 @@ public void test31_verifier(boolean warmup) { } // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations - @Test(valid = InlineTypePassFieldsAsArgsOn) - @Test(valid = InlineTypePassFieldsAsArgsOff, failOn = ALLOC + ALLOCA + STORE) + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + failOn = {ALLOC, ALLOCA, STORE}) public MyValue3 test32(MyValue3 vt, MyValue3[] va) { // C2 can re-use the oop of vt because vt is equal to 'copy'. MyValue3 copy = MyValue3.copy(vt); @@ -664,8 +742,8 @@ public MyValue3 test32(MyValue3 vt, MyValue3[] va) { return copy; } - @DontCompile - public void test32_verifier(boolean warmup) { + @Run(test = "test32") + public void test32_verifier() { MyValue3 vt = MyValue3.create(); MyValue3[] va = new MyValue3[1]; MyValue3 result = test32(vt, va); @@ -675,7 +753,7 @@ public void test32_verifier(boolean warmup) { } // Test correct identification of inline type copies - @Test() + @Test public MyValue3 test33(MyValue3[] va) { MyValue3 vt = MyValue3.copy(staticVal3); vt = MyValue3.setI(vt, vt.c); @@ -686,8 +764,8 @@ public MyValue3 test33(MyValue3[] va) { return vt; } - @DontCompile - public void test33_verifier(boolean warmup) { + @Run(test = "test33") + public void test33_verifier() { staticVal3 = MyValue3.create(); MyValue3[] va = new MyValue3[1]; MyValue3 vt = test33(va); @@ -698,7 +776,8 @@ public void test33_verifier(boolean warmup) { // Verify that the default inline type is never allocated. // C2 code should load and use the default oop from the java mirror. - @Test(failOn = ALLOC + ALLOCA + LOAD + STORE + LOOP + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE, LOOP, TRAP}) public MyValue3 test34(MyValue3[] va) { // Explicitly create default value MyValue3 vt = MyValue3.createDefault(); @@ -714,8 +793,8 @@ public MyValue3 test34(MyValue3[] va) { return vt; } - @DontCompile - public void test34_verifier(boolean warmup) { + @Run(test = "test34") + public void test34_verifier() { MyValue3 vt = MyValue3.createDefault(); MyValue3[] va = new MyValue3[2]; va[0] = MyValue3.create(); @@ -729,7 +808,8 @@ public void test34_verifier(boolean warmup) { } // Same as above but manually initialize inline type fields to default. - @Test(failOn = ALLOC + ALLOCA + LOAD + STORE + LOOP + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE, LOOP, TRAP}) public MyValue3 test35(MyValue3 vt, MyValue3[] va) { vt = MyValue3.setC(vt, (char)0); vt = MyValue3.setBB(vt, (byte)0); @@ -750,8 +830,8 @@ public MyValue3 test35(MyValue3 vt, MyValue3[] va) { return vt; } - @DontCompile - public void test35_verifier(boolean warmup) { + @Run(test = "test35") + public void test35_verifier() { MyValue3 vt = MyValue3.createDefault(); MyValue3[] va = new MyValue3[1]; va[0] = MyValue3.create(); @@ -767,7 +847,8 @@ private Object test36_helper(Object v) { return v; } - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test36(boolean b) { Object o; if (b) { @@ -779,8 +860,8 @@ public long test36(boolean b) { return v.hash(); } - @DontCompile - public void test36_verifier(boolean warmup) { + @Run(test = "test36") + public void test36_verifier() { Asserts.assertEQ(test36(true), hash()); Asserts.assertEQ(test36(false), hash(rI + 1, rL + 1)); } @@ -802,8 +883,8 @@ public Test37Value1 test37(Test37Value1 vt) { return vt; } - @DontCompile - public void test37_verifier(boolean warmup) { + @Run(test = "test37") + public void test37_verifier() { Test37Value1 vt = new Test37Value1(); Asserts.assertEQ(test37(vt), vt); } @@ -828,8 +909,8 @@ public void test38() { } } - @DontCompile - public void test38_verifier(boolean warmup) { + @Run(test = "test38") + public void test38_verifier() { test38Field = Test38Value.default; test38(); Asserts.assertEQ(test38Field, new Test38Value(99)); @@ -853,26 +934,25 @@ public int[] getArray() { } @Test - @Warmup(10) public int test39() { int result = 0; for (int i = 0; i < 100; ++i) { switch ((i >>> 1) % 3) { - case 0: - test39A1[i][i] = i; - break; - case 1: - for (int j = 0; j < 100; ++j) { - test39A1[i] = getArray(); - test39Val = new Test39Value(j, test39Val.iFld2); - } - break; - case 2: - for (float f = 142; f > i; f--) { - test39A2[i + 1] += 3; - } - result += test39Val.iFld1; - break; + case 0: + test39A1[i][i] = i; + break; + case 1: + for (int j = 0; j < 100; ++j) { + test39A1[i] = getArray(); + test39Val = new Test39Value(j, test39Val.iFld2); + } + break; + case 2: + for (float f = 142; f > i; f--) { + test39A2[i + 1] += 3; + } + result += test39Val.iFld1; + break; } double d1 = 1; while (++d1 < 142) { @@ -883,8 +963,9 @@ public int test39() { return result; } - @DontCompile - public void test39_verifier(boolean warmup) { + @Run(test = "test39") + @Warmup(10) + public void test39_verifier() { int result = test39(); Asserts.assertEQ(result, 1552); } @@ -902,9 +983,10 @@ public long test40(boolean b) { return result; } - @DontCompile - public void test40_verifier(boolean warmup) { - long result = test40(warmup); - Asserts.assertEQ(result, warmup ? 0 : hash()); + @Run(test = "test40") + public void test40_verifier(RunInfo info) { + long result = test40(info.isWarmUp()); + Asserts.assertEQ(result, info.isWarmUp() ? 0 : hash()); } + } From 0a18c9863bbb8f479d6424561b2fb00df083bb15 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 19 Mar 2021 15:10:25 +0100 Subject: [PATCH 059/131] Move TestBasicFunctionality.java 2/3 --- .../{old_inlinetypes => inlinetypes}/TestBasicFunctionality.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestBasicFunctionality.java (100%) diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java From 0ca740b77acf14ea1315d4829d4989f98df1ef10 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 19 Mar 2021 15:16:15 +0100 Subject: [PATCH 060/131] Move all tests back to inlinetypes --- .../valhalla/{old_inlinetypes => inlinetypes}/GetfieldChains.jcod | 0 .../valhalla/{old_inlinetypes => inlinetypes}/InlineTypeTest.java | 0 .../{old_inlinetypes => inlinetypes}/TestArrayAccessDeopt.java | 0 .../{old_inlinetypes => inlinetypes}/TestArrayCopyWithOops.java | 0 .../valhalla/{old_inlinetypes => inlinetypes}/TestArrays.java | 0 .../{old_inlinetypes => inlinetypes}/TestBimorphicInlining.java | 0 .../{old_inlinetypes => inlinetypes}/TestBufferTearing.java | 0 .../valhalla/{old_inlinetypes => inlinetypes}/TestC1.java | 0 .../valhalla/{old_inlinetypes => inlinetypes}/TestC2CCalls.java | 0 .../{old_inlinetypes => inlinetypes}/TestCallingConvention.java | 0 .../{old_inlinetypes => inlinetypes}/TestCallingConventionC1.java | 0 .../TestDeadAllocationRemoval.java | 0 .../TestDeoptimizationWhenBuffering.java | 0 .../TestFlatArrayAliasesCardMark.java | 0 .../{old_inlinetypes => inlinetypes}/TestFlatArrayThreshold.java | 0 .../valhalla/{old_inlinetypes => inlinetypes}/TestGenerated.java | 0 .../{old_inlinetypes => inlinetypes}/TestGetfieldChains.java | 0 .../valhalla/{old_inlinetypes => inlinetypes}/TestIntrinsics.java | 0 .../TestIsSubstitutableReresolution.java | 0 .../valhalla/{old_inlinetypes => inlinetypes}/TestJNICalls.java | 0 .../valhalla/{old_inlinetypes => inlinetypes}/TestLWorld.java | 0 .../{old_inlinetypes => inlinetypes}/TestLWorldProfiling.java | 0 .../{old_inlinetypes => inlinetypes}/TestMethodHandles.java | 0 .../{old_inlinetypes => inlinetypes}/TestNativeClone.java | 0 .../{old_inlinetypes => inlinetypes}/TestNestmateAccess.java | 0 .../valhalla/{old_inlinetypes => inlinetypes}/TestNewAcmp.java | 0 .../{old_inlinetypes => inlinetypes}/TestNullableArrays.java | 0 .../{old_inlinetypes => inlinetypes}/TestNullableInlineTypes.java | 0 .../{old_inlinetypes => inlinetypes}/TestOnStackReplacement.java | 0 .../{old_inlinetypes => inlinetypes}/TestOptimizeKlassCmp.java | 0 .../TestStressReturnBuffering.java | 0 .../TestUnloadedInlineTypeArray.java | 0 .../TestUnloadedInlineTypeField.java | 0 .../{old_inlinetypes => inlinetypes}/TestUnresolvedDefault.java | 0 .../TestUnresolvedInlineClass.java | 0 .../{old_inlinetypes => inlinetypes}/TestWithfieldC1.java | 0 .../valhalla/{old_inlinetypes => inlinetypes}/libTestJNICalls.c | 0 37 files changed, 0 insertions(+), 0 deletions(-) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/GetfieldChains.jcod (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/InlineTypeTest.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestArrayAccessDeopt.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestArrayCopyWithOops.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestArrays.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestBimorphicInlining.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestBufferTearing.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestC1.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestC2CCalls.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestCallingConvention.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestCallingConventionC1.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestDeadAllocationRemoval.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestDeoptimizationWhenBuffering.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestFlatArrayAliasesCardMark.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestFlatArrayThreshold.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestGenerated.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestGetfieldChains.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestIntrinsics.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestIsSubstitutableReresolution.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestJNICalls.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestLWorld.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestLWorldProfiling.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestMethodHandles.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestNativeClone.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestNestmateAccess.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestNewAcmp.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestNullableArrays.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestNullableInlineTypes.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestOnStackReplacement.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestOptimizeKlassCmp.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestStressReturnBuffering.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestUnloadedInlineTypeArray.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestUnloadedInlineTypeField.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestUnresolvedDefault.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestUnresolvedInlineClass.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/TestWithfieldC1.java (100%) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/libTestJNICalls.c (100%) diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/GetfieldChains.jcod b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/GetfieldChains.jcod similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/GetfieldChains.jcod rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/GetfieldChains.jcod diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/InlineTypeTest.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypeTest.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/InlineTypeTest.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypeTest.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestArrayAccessDeopt.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrayAccessDeopt.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestArrayAccessDeopt.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrayAccessDeopt.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestArrayCopyWithOops.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrayCopyWithOops.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestArrayCopyWithOops.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrayCopyWithOops.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestArrays.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBimorphicInlining.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBimorphicInlining.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBimorphicInlining.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBimorphicInlining.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBufferTearing.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBufferTearing.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBufferTearing.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBufferTearing.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestC1.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestC2CCalls.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC2CCalls.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestC2CCalls.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC2CCalls.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestCallingConvention.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestCallingConvention.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestCallingConventionC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestCallingConventionC1.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestDeadAllocationRemoval.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestDeadAllocationRemoval.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestDeadAllocationRemoval.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestDeadAllocationRemoval.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestDeoptimizationWhenBuffering.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestDeoptimizationWhenBuffering.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestDeoptimizationWhenBuffering.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestDeoptimizationWhenBuffering.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestFlatArrayAliasesCardMark.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestFlatArrayAliasesCardMark.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestFlatArrayAliasesCardMark.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestFlatArrayAliasesCardMark.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestFlatArrayThreshold.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestFlatArrayThreshold.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestFlatArrayThreshold.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestFlatArrayThreshold.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestGenerated.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGenerated.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestGenerated.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGenerated.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestGetfieldChains.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestGetfieldChains.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestIntrinsics.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestIntrinsics.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestIsSubstitutableReresolution.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIsSubstitutableReresolution.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestIsSubstitutableReresolution.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIsSubstitutableReresolution.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestJNICalls.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestJNICalls.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestLWorld.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestLWorld.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestLWorldProfiling.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestLWorldProfiling.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestMethodHandles.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestMethodHandles.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNativeClone.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNativeClone.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNativeClone.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNativeClone.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNestmateAccess.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNestmateAccess.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNestmateAccess.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNestmateAccess.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNewAcmp.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNewAcmp.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNewAcmp.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNewAcmp.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNullableArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNullableArrays.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNullableInlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestNullableInlineTypes.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestOnStackReplacement.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestOnStackReplacement.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestOptimizeKlassCmp.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOptimizeKlassCmp.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestOptimizeKlassCmp.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOptimizeKlassCmp.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestStressReturnBuffering.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestStressReturnBuffering.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestStressReturnBuffering.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestStressReturnBuffering.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnloadedInlineTypeArray.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeArray.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnloadedInlineTypeArray.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeArray.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnloadedInlineTypeField.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnloadedInlineTypeField.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnresolvedDefault.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnresolvedDefault.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnresolvedDefault.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnresolvedDefault.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnresolvedInlineClass.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnresolvedInlineClass.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestUnresolvedInlineClass.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnresolvedInlineClass.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestWithfieldC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestWithfieldC1.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/libTestJNICalls.c b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/libTestJNICalls.c similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/libTestJNICalls.c rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/libTestJNICalls.c From 6ccdcdbf3dd895fc9720d43ea1342e1354d338cc Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 19 Mar 2021 15:16:42 +0100 Subject: [PATCH 061/131] Move TestBasicFunctionality.java 3/3 --- .../TestBasicFunctionality.java | 910 ++++++++++++++++++ 1 file changed, 910 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java new file mode 100644 index 00000000000..8eb4b8e7848 --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java @@ -0,0 +1,910 @@ +/* + * Copyright (c) 2017, 2020, 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.valhalla.inlinetypes; + +import jdk.test.lib.Asserts; + +/* + * @test + * @key randomness + * @summary Test the basic inline type implementation in C2 + * @library /testlibrary /test/lib /compiler/whitebox / + * @requires os.simpleArch == "x64" + * @compile TestBasicFunctionality.java + * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform + * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions + * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI + * compiler.valhalla.inlinetypes.InlineTypeTest + * compiler.valhalla.inlinetypes.TestBasicFunctionality + */ +public class TestBasicFunctionality extends InlineTypeTest { + // Extra VM parameters for some test scenarios. See InlineTypeTest.getVMParameters() + @Override + public String[] getExtraVMParameters(int scenario) { + switch (scenario) { + case 2: return new String[] {"-DVerifyIR=false"}; + case 3: return new String[] {"-XX:FlatArrayElementMaxSize=0"}; + } + return null; + } + + public static void main(String[] args) throws Throwable { + TestBasicFunctionality test = new TestBasicFunctionality(); + test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, MyValue3.class, MyValue3Inline.class); + } + + // Helper methods + + protected long hash() { + return hash(rI, rL); + } + + protected long hash(int x, long y) { + return MyValue1.createWithFieldsInline(x, y).hash(); + } + + // Receive inline type through call to interpreter + @Test(failOn = ALLOC + STORE + TRAP) + public long test1() { + MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); + return v.hash(); + } + + @DontCompile + public void test1_verifier(boolean warmup) { + long result = test1(); + Asserts.assertEQ(result, hash()); + } + + // Receive inline type from interpreter via parameter + @Test(failOn = ALLOC + STORE + TRAP) + public long test2(MyValue1 v) { + return v.hash(); + } + + @DontCompile + public void test2_verifier(boolean warmup) { + MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); + long result = test2(v); + Asserts.assertEQ(result, hash()); + } + + // Return incoming inline type without accessing fields + @Test(valid = InlineTypePassFieldsAsArgsOn, match = {ALLOC, STORE}, matchCount = {1, 14}, failOn = LOAD + TRAP) + @Test(valid = InlineTypePassFieldsAsArgsOff, failOn = ALLOC + LOAD + STORE + TRAP) + public MyValue1 test3(MyValue1 v) { + return v; + } + + @DontCompile + public void test3_verifier(boolean warmup) { + MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI, rL); + MyValue1 v2 = test3(v1); + Asserts.assertEQ(v1.x, v2.x); + Asserts.assertEQ(v1.y, v2.y); + } + + // Create an inline type in compiled code and only use fields. + // Allocation should go away because inline type does not escape. + @Test(failOn = ALLOC + LOAD + STORE + TRAP) + public long test4() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + return v.hash(); + } + + @DontCompile + public void test4_verifier(boolean warmup) { + long result = test4(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type in compiled code and pass it to + // an inlined compiled method via a call. + @Test(failOn = ALLOC + LOAD + STORE + TRAP) + public long test5() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + return test5Inline(v); + } + + @ForceInline + public long test5Inline(MyValue1 v) { + return v.hash(); + } + + @DontCompile + public void test5_verifier(boolean warmup) { + long result = test5(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type in compiled code and pass it to + // the interpreter via a call. + @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = LOAD + TRAP + ALLOC) + @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP) + public long test6() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + // Pass to interpreter + return v.hashInterpreted(); + } + + @DontCompile + public void test6_verifier(boolean warmup) { + long result = test6(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type in compiled code and pass it to + // the interpreter by returning. + @Test(match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP) + public MyValue1 test7(int x, long y) { + return MyValue1.createWithFieldsInline(x, y); + } + + @DontCompile + public void test7_verifier(boolean warmup) { + MyValue1 v = test7(rI, rL); + Asserts.assertEQ(v.hash(), hash()); + } + + // Merge inline types created from two branches + @Test(failOn = ALLOC + STORE + TRAP) + public long test8(boolean b) { + MyValue1 v; + if (b) { + v = MyValue1.createWithFieldsInline(rI, rL); + } else { + v = MyValue1.createWithFieldsDontInline(rI + 1, rL + 1); + } + return v.hash(); + } + + @DontCompile + public void test8_verifier(boolean warmup) { + Asserts.assertEQ(test8(true), hash()); + Asserts.assertEQ(test8(false), hash(rI + 1, rL + 1)); + } + + // Merge inline types created from two branches + @Test(valid = InlineTypePassFieldsAsArgsOn, match = {LOAD}, matchCount = {14}, failOn = TRAP + ALLOC + STORE) + @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC, STORE}, matchCount = {1, 13}, failOn = LOAD + TRAP) + public MyValue1 test9(boolean b, int localrI, long localrL) { + MyValue1 v; + if (b) { + // Inline type is not allocated + // Do not use rI/rL directly here as null values may cause + // some redundant null initializations to be optimized out + // and matching to fail. + v = MyValue1.createWithFieldsInline(localrI, localrL); + } else { + // Inline type is allocated by the callee + v = MyValue1.createWithFieldsDontInline(rI + 1, rL + 1); + } + // Need to allocate inline type if 'b' is true + long sum = v.hashInterpreted(); + if (b) { + v = MyValue1.createWithFieldsDontInline(rI, sum); + } else { + v = MyValue1.createWithFieldsDontInline(rI, sum + 1); + } + // Don't need to allocate inline type because both branches allocate + return v; + } + + @DontCompile + public void test9_verifier(boolean warmup) { + MyValue1 v = test9(true, rI, rL); + Asserts.assertEQ(v.x, rI); + Asserts.assertEQ(v.y, hash()); + v = test9(false, rI, rL); + Asserts.assertEQ(v.x, rI); + Asserts.assertEQ(v.y, hash(rI + 1, rL + 1) + 1); + } + + // Merge inline types created in a loop (not inlined) + @Test(failOn = ALLOC + STORE + TRAP) + public long test10(int x, long y) { + MyValue1 v = MyValue1.createWithFieldsDontInline(x, y); + for (int i = 0; i < 10; ++i) { + v = MyValue1.createWithFieldsDontInline(v.x + 1, v.y + 1); + } + return v.hash(); + } + + @DontCompile + public void test10_verifier(boolean warmup) { + long result = test10(rI, rL); + Asserts.assertEQ(result, hash(rI + 10, rL + 10)); + } + + // Merge inline types created in a loop (inlined) + @Test(failOn = ALLOC + LOAD + STORE + TRAP) + public long test11(int x, long y) { + MyValue1 v = MyValue1.createWithFieldsInline(x, y); + for (int i = 0; i < 10; ++i) { + v = MyValue1.createWithFieldsInline(v.x + 1, v.y + 1); + } + return v.hash(); + } + + @DontCompile + public void test11_verifier(boolean warmup) { + long result = test11(rI, rL); + Asserts.assertEQ(result, hash(rI + 10, rL + 10)); + } + + // Test loop with uncommon trap referencing an inline type + @Test(match = {SCOBJ}, matchCount = {-1 /* at least 1 */}, failOn = LOAD) + public long test12(boolean b) { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + MyValue1[] va = new MyValue1[Math.abs(rI) % 10]; + for (int i = 0; i < va.length; ++i) { + va[i] = MyValue1.createWithFieldsInline(rI, rL); + } + long result = rL; + for (int i = 0; i < 1000; ++i) { + if (b) { + result += v.x; + } else { + // Uncommon trap referencing v. We delegate allocation to the + // interpreter by adding a SafePointScalarObjectNode. + result = v.hashInterpreted(); + for (int j = 0; j < va.length; ++j) { + result += va[j].hash(); + } + } + } + return result; + } + + @DontCompile + public void test12_verifier(boolean warmup) { + long result = test12(warmup); + Asserts.assertEQ(result, warmup ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); + } + + // Test loop with uncommon trap referencing an inline type + @Test + public long test13(boolean b) { + MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); + MyValue1[] va = new MyValue1[Math.abs(rI) % 10]; + for (int i = 0; i < va.length; ++i) { + va[i] = MyValue1.createWithFieldsDontInline(rI, rL); + } + long result = rL; + for (int i = 0; i < 1000; ++i) { + if (b) { + result += v.x; + } else { + // Uncommon trap referencing v. Should not allocate + // but just pass the existing oop to the uncommon trap. + result = v.hashInterpreted(); + for (int j = 0; j < va.length; ++j) { + result += va[j].hashInterpreted(); + } + } + } + return result; + } + + @DontCompile + public void test13_verifier(boolean warmup) { + long result = test13(warmup); + Asserts.assertEQ(result, warmup ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); + } + + // Create an inline type in a non-inlined method and then call a + // non-inlined method on that inline type. + @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = (ALLOC + STORE + TRAP), match = {LOAD}, matchCount = {14}) + @Test(valid = InlineTypePassFieldsAsArgsOff, failOn = (ALLOC + LOAD + STORE + TRAP)) + public long test14() { + MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); + return v.hashInterpreted(); + } + + @DontCompile + public void test14_verifier(boolean b) { + long result = test14(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type in an inlined method and then call a + // non-inlined method on that inline type. + @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = (LOAD + TRAP + ALLOC)) + @Test(valid = InlineTypePassFieldsAsArgsOff, failOn = (LOAD + TRAP), match = {ALLOC}, matchCount = {1}) + public long test15() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + return v.hashInterpreted(); + } + + @DontCompile + public void test15_verifier(boolean b) { + long result = test15(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type in a non-inlined method and then call an + // inlined method on that inline type. + @Test(failOn = (ALLOC + STORE + TRAP)) + public long test16() { + MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); + return v.hash(); + } + + @DontCompile + public void test16_verifier(boolean b) { + long result = test16(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type in an inlined method and then call an + // inlined method on that inline type. + @Test(failOn = (ALLOC + LOAD + STORE + TRAP)) + public long test17() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + return v.hash(); + } + + @DontCompile + public void test17_verifier(boolean b) { + long result = test17(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type in compiled code and pass it to the + // interpreter via a call. The inline type is live at the first call so + // debug info should include a reference to all its fields. + @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = ALLOC + LOAD + TRAP) + @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP) + public long test18() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + v.hashInterpreted(); + return v.hashInterpreted(); + } + + @DontCompile + public void test18_verifier(boolean warmup) { + long result = test18(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type in compiled code and pass it to the + // interpreter via a call. The inline type is passed twice but + // should only be allocated once. + @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = ALLOC + LOAD + TRAP) + @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP) + public long test19() { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + return sumValue(v, v); + } + + @DontCompile + public long sumValue(MyValue1 v, MyValue1 dummy) { + return v.hash(); + } + + @DontCompile + public void test19_verifier(boolean warmup) { + long result = test19(); + Asserts.assertEQ(result, hash()); + } + + // Create an inline type (array) in compiled code and pass it to the + // interpreter via a call. The inline type is live at the uncommon + // trap: verify that deoptimization causes the inline type to be + // correctly allocated. + @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = LOAD + ALLOC + STORE) + @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {1}, failOn = LOAD) + public long test20(boolean deopt) { + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + MyValue2[] va = new MyValue2[3]; + if (deopt) { + // uncommon trap + WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test20")); + } + return v.hashInterpreted() + va[0].hashInterpreted() + + va[1].hashInterpreted() + va[2].hashInterpreted(); + } + + @DontCompile + public void test20_verifier(boolean warmup) { + MyValue2[] va = new MyValue2[42]; + long result = test20(!warmup); + Asserts.assertEQ(result, hash() + va[0].hash() + va[1].hash() + va[2].hash()); + } + + // Inline type fields in regular object + MyValue1 val1; + MyValue2 val2; + final MyValue1 val3 = MyValue1.createWithFieldsInline(rI, rL); + static MyValue1 val4; + static final MyValue1 val5 = MyValue1.createWithFieldsInline(rI, rL); + + // Test inline type fields in objects + @Test(match = {ALLOC}, matchCount = {1}, failOn = (TRAP)) + public long test21(int x, long y) { + // Compute hash of inline type fields + long result = val1.hash() + val2.hash() + val3.hash() + val4.hash() + val5.hash(); + // Update fields + val1 = MyValue1.createWithFieldsInline(x, y); + val2 = MyValue2.createWithFieldsInline(x, rD); + val4 = MyValue1.createWithFieldsInline(x, y); + return result; + } + + @DontCompile + public void test21_verifier(boolean warmup) { + // Check if hash computed by test18 is correct + val1 = MyValue1.createWithFieldsInline(rI, rL); + val2 = val1.v2; + // val3 is initialized in the constructor + val4 = val1; + // val5 is initialized in the static initializer + long hash = val1.hash() + val2.hash() + val3.hash() + val4.hash() + val5.hash(); + long result = test21(rI + 1, rL + 1); + Asserts.assertEQ(result, hash); + // Check if inline type fields were updated + Asserts.assertEQ(val1.hash(), hash(rI + 1, rL + 1)); + Asserts.assertEQ(val2.hash(), MyValue2.createWithFieldsInline(rI + 1, rD).hash()); + Asserts.assertEQ(val4.hash(), hash(rI + 1, rL + 1)); + } + + // Test folding of constant inline type fields + @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) + public long test22() { + // This should be constant folded + return val5.hash() + val5.v3.hash(); + } + + @DontCompile + public void test22_verifier(boolean warmup) { + long result = test22(); + Asserts.assertEQ(result, val5.hash() + val5.v3.hash()); + } + + // Test defaultvalue + @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) + public long test23() { + MyValue2 v = MyValue2.createDefaultInline(); + return v.hash(); + } + + @DontCompile + public void test23_verifier(boolean warmup) { + long result = test23(); + Asserts.assertEQ(result, MyValue2.createDefaultInline().hash()); + } + + // Test defaultvalue + @Test(failOn = ALLOC + STORE + LOOP + TRAP) + public long test24() { + MyValue1 v1 = MyValue1.createDefaultInline(); + MyValue1 v2 = MyValue1.createDefaultDontInline(); + return v1.hashPrimitive() + v2.hashPrimitive(); + } + + @DontCompile + public void test24_verifier(boolean warmup) { + long result = test24(); + Asserts.assertEQ(result, 2 * MyValue1.createDefaultInline().hashPrimitive()); + } + + // Test withfield + @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) + public long test25() { + MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); + return v.hash(); + } + + @DontCompile + public void test25_verifier(boolean warmup) { + long result = test25(); + Asserts.assertEQ(result, MyValue2.createWithFieldsInline(rI, rD).hash()); + } + + // Test withfield + @Test(failOn = ALLOC + STORE + LOOP + TRAP) + public long test26() { + MyValue1 v1 = MyValue1.createWithFieldsInline(rI, rL); + MyValue1 v2 = MyValue1.createWithFieldsDontInline(rI, rL); + return v1.hash() + v2.hash(); + } + + @DontCompile + public void test26_verifier(boolean warmup) { + long result = test26(); + Asserts.assertEQ(result, 2 * hash()); + } + + class TestClass27 { + public MyValue1 v; + } + + // Test allocation elimination of unused object with initialized inline type field + @Test(failOn = ALLOC + LOAD + STORE + LOOP) + public void test27(boolean deopt) { + TestClass27 unused = new TestClass27(); + MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); + unused.v = v; + if (deopt) { + // uncommon trap + WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test27")); + } + } + + @DontCompile + public void test27_verifier(boolean warmup) { + test27(!warmup); + } + + static MyValue3 staticVal3; + static MyValue3 staticVal3_copy; + + // Check elimination of redundant inline type allocations + @Test(match = {ALLOC}, matchCount = {1}) + public MyValue3 test28(MyValue3[] va) { + // Create inline type and force allocation + MyValue3 vt = MyValue3.create(); + va[0] = vt; + staticVal3 = vt; + vt.verify(staticVal3); + + // Inline type is now allocated, make a copy and force allocation. + // Because copy is equal to vt, C2 should remove this redundant allocation. + MyValue3 copy = MyValue3.setC(vt, vt.c); + va[0] = copy; + staticVal3_copy = copy; + copy.verify(staticVal3_copy); + return copy; + } + + @DontCompile + public void test28_verifier(boolean warmup) { + MyValue3[] va = new MyValue3[1]; + MyValue3 vt = test28(va); + staticVal3.verify(vt); + staticVal3.verify(va[0]); + staticVal3_copy.verify(vt); + staticVal3_copy.verify(va[0]); + } + + // Verify that only dominating allocations are re-used + @Test() + public MyValue3 test29(boolean warmup) { + MyValue3 vt = MyValue3.create(); + if (warmup) { + staticVal3 = vt; // Force allocation + } + // Force allocation to verify that above + // non-dominating allocation is not re-used + MyValue3 copy = MyValue3.setC(vt, vt.c); + staticVal3_copy = copy; + copy.verify(vt); + return copy; + } + + @DontCompile + public void test29_verifier(boolean warmup) { + MyValue3 vt = test29(warmup); + if (warmup) { + staticVal3.verify(vt); + } + } + + // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations + @Test(failOn = ALLOC + ALLOCA + STORE) + public MyValue3 test30(MyValue3[] va) { + // C2 can re-use the oop of staticVal3 because staticVal3 is equal to copy + MyValue3 copy = MyValue3.copy(staticVal3); + va[0] = copy; + staticVal3 = copy; + copy.verify(staticVal3); + return copy; + } + + @DontCompile + public void test30_verifier(boolean warmup) { + staticVal3 = MyValue3.create(); + MyValue3[] va = new MyValue3[1]; + MyValue3 vt = test30(va); + staticVal3.verify(vt); + staticVal3.verify(va[0]); + } + + // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations + @Test(valid = InlineTypeReturnedAsFieldsOn) + @Test(valid = InlineTypeReturnedAsFieldsOff, failOn = ALLOC + ALLOCA + STORE) + public MyValue3 test31(MyValue3[] va) { + // C2 can re-use the oop returned by createDontInline() + // because the corresponding inline type is equal to 'copy'. + MyValue3 copy = MyValue3.copy(MyValue3.createDontInline()); + va[0] = copy; + staticVal3 = copy; + copy.verify(staticVal3); + return copy; + } + + @DontCompile + public void test31_verifier(boolean warmup) { + MyValue3[] va = new MyValue3[1]; + MyValue3 vt = test31(va); + staticVal3.verify(vt); + staticVal3.verify(va[0]); + } + + // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations + @Test(valid = InlineTypePassFieldsAsArgsOn) + @Test(valid = InlineTypePassFieldsAsArgsOff, failOn = ALLOC + ALLOCA + STORE) + public MyValue3 test32(MyValue3 vt, MyValue3[] va) { + // C2 can re-use the oop of vt because vt is equal to 'copy'. + MyValue3 copy = MyValue3.copy(vt); + va[0] = copy; + staticVal3 = copy; + copy.verify(staticVal3); + return copy; + } + + @DontCompile + public void test32_verifier(boolean warmup) { + MyValue3 vt = MyValue3.create(); + MyValue3[] va = new MyValue3[1]; + MyValue3 result = test32(vt, va); + staticVal3.verify(vt); + va[0].verify(vt); + result.verify(vt); + } + + // Test correct identification of inline type copies + @Test() + public MyValue3 test33(MyValue3[] va) { + MyValue3 vt = MyValue3.copy(staticVal3); + vt = MyValue3.setI(vt, vt.c); + // vt is not equal to staticVal3, so C2 should not re-use the oop + va[0] = vt; + staticVal3 = vt; + vt.verify(staticVal3); + return vt; + } + + @DontCompile + public void test33_verifier(boolean warmup) { + staticVal3 = MyValue3.create(); + MyValue3[] va = new MyValue3[1]; + MyValue3 vt = test33(va); + Asserts.assertEQ(staticVal3.i, (int)staticVal3.c); + Asserts.assertEQ(va[0].i, (int)staticVal3.c); + Asserts.assertEQ(vt.i, (int)staticVal3.c); + } + + // Verify that the default inline type is never allocated. + // C2 code should load and use the default oop from the java mirror. + @Test(failOn = ALLOC + ALLOCA + LOAD + STORE + LOOP + TRAP) + public MyValue3 test34(MyValue3[] va) { + // Explicitly create default value + MyValue3 vt = MyValue3.createDefault(); + va[0] = vt; + staticVal3 = vt; + vt.verify(vt); + + // Load default value from uninitialized inline type array + MyValue3[] dva = new MyValue3[1]; + staticVal3_copy = dva[0]; + va[1] = dva[0]; + dva[0].verify(dva[0]); + return vt; + } + + @DontCompile + public void test34_verifier(boolean warmup) { + MyValue3 vt = MyValue3.createDefault(); + MyValue3[] va = new MyValue3[2]; + va[0] = MyValue3.create(); + va[1] = MyValue3.create(); + MyValue3 res = test34(va); + res.verify(vt); + staticVal3.verify(vt); + staticVal3_copy.verify(vt); + va[0].verify(vt); + va[1].verify(vt); + } + + // Same as above but manually initialize inline type fields to default. + @Test(failOn = ALLOC + ALLOCA + LOAD + STORE + LOOP + TRAP) + public MyValue3 test35(MyValue3 vt, MyValue3[] va) { + vt = MyValue3.setC(vt, (char)0); + vt = MyValue3.setBB(vt, (byte)0); + vt = MyValue3.setS(vt, (short)0); + vt = MyValue3.setI(vt, 0); + vt = MyValue3.setL(vt, 0); + vt = MyValue3.setO(vt, null); + vt = MyValue3.setF1(vt, 0); + vt = MyValue3.setF2(vt, 0); + vt = MyValue3.setF3(vt, 0); + vt = MyValue3.setF4(vt, 0); + vt = MyValue3.setF5(vt, 0); + vt = MyValue3.setF6(vt, 0); + vt = MyValue3.setV1(vt, MyValue3Inline.createDefault()); + va[0] = vt; + staticVal3 = vt; + vt.verify(vt); + return vt; + } + + @DontCompile + public void test35_verifier(boolean warmup) { + MyValue3 vt = MyValue3.createDefault(); + MyValue3[] va = new MyValue3[1]; + va[0] = MyValue3.create(); + MyValue3 res = test35(va[0], va); + res.verify(vt); + staticVal3.verify(vt); + va[0].verify(vt); + } + + // Merge inline types created from two branches + + private Object test36_helper(Object v) { + return v; + } + + @Test(failOn = ALLOC + STORE + TRAP) + public long test36(boolean b) { + Object o; + if (b) { + o = test36_helper(MyValue1.createWithFieldsInline(rI, rL)); + } else { + o = test36_helper(MyValue1.createWithFieldsDontInline(rI + 1, rL + 1)); + } + MyValue1 v = (MyValue1)o; + return v.hash(); + } + + @DontCompile + public void test36_verifier(boolean warmup) { + Asserts.assertEQ(test36(true), hash()); + Asserts.assertEQ(test36(false), hash(rI + 1, rL + 1)); + } + + // Test correct loading of flattened fields + primitive class Test37Value2 { + final int x = 0; + final int y = 0; + } + + primitive class Test37Value1 { + final double d = 0; + final float f = 0; + final Test37Value2 v = new Test37Value2(); + } + + @Test + public Test37Value1 test37(Test37Value1 vt) { + return vt; + } + + @DontCompile + public void test37_verifier(boolean warmup) { + Test37Value1 vt = new Test37Value1(); + Asserts.assertEQ(test37(vt), vt); + } + + // Test elimination of inline type allocations without a unique CheckCastPP + primitive class Test38Value { + public int i; + public Test38Value(int i) { this.i = i; } + } + + static Test38Value test38Field; + + @Test + public void test38() { + for (int i = 3; i < 100; ++i) { + int j = 1; + while (++j < 11) { + try { + test38Field = new Test38Value(i); + } catch (ArithmeticException ae) { } + } + } + } + + @DontCompile + public void test38_verifier(boolean warmup) { + test38Field = Test38Value.default; + test38(); + Asserts.assertEQ(test38Field, new Test38Value(99)); + } + + // Tests split if with inline type Phi users + static primitive class Test39Value { + public int iFld1; + public int iFld2; + + public Test39Value(int i1, int i2) { iFld1 = i1; iFld2 = i2; } + } + + static int test39A1[][] = new int[400][400]; + static double test39A2[] = new double[400]; + static Test39Value test39Val = Test39Value.default; + + @DontInline + public int[] getArray() { + return new int[400]; + } + + @Test + @Warmup(10) + public int test39() { + int result = 0; + for (int i = 0; i < 100; ++i) { + switch ((i >>> 1) % 3) { + case 0: + test39A1[i][i] = i; + break; + case 1: + for (int j = 0; j < 100; ++j) { + test39A1[i] = getArray(); + test39Val = new Test39Value(j, test39Val.iFld2); + } + break; + case 2: + for (float f = 142; f > i; f--) { + test39A2[i + 1] += 3; + } + result += test39Val.iFld1; + break; + } + double d1 = 1; + while (++d1 < 142) { + test39A1[(i >>> 1) % 400][i + 1] = result; + test39Val = new Test39Value(i, test39Val.iFld2); + } + } + return result; + } + + @DontCompile + public void test39_verifier(boolean warmup) { + int result = test39(); + Asserts.assertEQ(result, 1552); + } + + // Test scalar replacement of inline type array containing inline type with oop fields + @Test() + public long test40(boolean b) { + MyValue1[] va = {MyValue1.createWithFieldsInline(rI, rL)}; + long result = 0; + for (int i = 0; i < 1000; ++i) { + if (!b) { + result = va[0].hash(); + } + } + return result; + } + + @DontCompile + public void test40_verifier(boolean warmup) { + long result = test40(warmup); + Asserts.assertEQ(result, warmup ? 0 : hash()); + } +} From 16e2a158d4c3608cdb4306a58eb434e41af66525 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 19 Mar 2021 15:43:12 +0100 Subject: [PATCH 062/131] Remove old_inlinetypes and only keep the converted versions --- ...etUnresolvedInlineFieldWrongSignature.java | 0 .../TestBasicFunctionality.java | 910 ------------------ 2 files changed, 910 deletions(-) rename test/hotspot/jtreg/compiler/valhalla/{old_inlinetypes => inlinetypes}/hack/GetUnresolvedInlineFieldWrongSignature.java (100%) delete mode 100644 test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/hack/GetUnresolvedInlineFieldWrongSignature.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/hack/GetUnresolvedInlineFieldWrongSignature.java similarity index 100% rename from test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/hack/GetUnresolvedInlineFieldWrongSignature.java rename to test/hotspot/jtreg/compiler/valhalla/inlinetypes/hack/GetUnresolvedInlineFieldWrongSignature.java diff --git a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java deleted file mode 100644 index 8eb4b8e7848..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/old_inlinetypes/TestBasicFunctionality.java +++ /dev/null @@ -1,910 +0,0 @@ -/* - * Copyright (c) 2017, 2020, 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.valhalla.inlinetypes; - -import jdk.test.lib.Asserts; - -/* - * @test - * @key randomness - * @summary Test the basic inline type implementation in C2 - * @library /testlibrary /test/lib /compiler/whitebox / - * @requires os.simpleArch == "x64" - * @compile TestBasicFunctionality.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestBasicFunctionality - */ -public class TestBasicFunctionality extends InlineTypeTest { - // Extra VM parameters for some test scenarios. See InlineTypeTest.getVMParameters() - @Override - public String[] getExtraVMParameters(int scenario) { - switch (scenario) { - case 2: return new String[] {"-DVerifyIR=false"}; - case 3: return new String[] {"-XX:FlatArrayElementMaxSize=0"}; - } - return null; - } - - public static void main(String[] args) throws Throwable { - TestBasicFunctionality test = new TestBasicFunctionality(); - test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, MyValue3.class, MyValue3Inline.class); - } - - // Helper methods - - protected long hash() { - return hash(rI, rL); - } - - protected long hash(int x, long y) { - return MyValue1.createWithFieldsInline(x, y).hash(); - } - - // Receive inline type through call to interpreter - @Test(failOn = ALLOC + STORE + TRAP) - public long test1() { - MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); - return v.hash(); - } - - @DontCompile - public void test1_verifier(boolean warmup) { - long result = test1(); - Asserts.assertEQ(result, hash()); - } - - // Receive inline type from interpreter via parameter - @Test(failOn = ALLOC + STORE + TRAP) - public long test2(MyValue1 v) { - return v.hash(); - } - - @DontCompile - public void test2_verifier(boolean warmup) { - MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); - long result = test2(v); - Asserts.assertEQ(result, hash()); - } - - // Return incoming inline type without accessing fields - @Test(valid = InlineTypePassFieldsAsArgsOn, match = {ALLOC, STORE}, matchCount = {1, 14}, failOn = LOAD + TRAP) - @Test(valid = InlineTypePassFieldsAsArgsOff, failOn = ALLOC + LOAD + STORE + TRAP) - public MyValue1 test3(MyValue1 v) { - return v; - } - - @DontCompile - public void test3_verifier(boolean warmup) { - MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI, rL); - MyValue1 v2 = test3(v1); - Asserts.assertEQ(v1.x, v2.x); - Asserts.assertEQ(v1.y, v2.y); - } - - // Create an inline type in compiled code and only use fields. - // Allocation should go away because inline type does not escape. - @Test(failOn = ALLOC + LOAD + STORE + TRAP) - public long test4() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - return v.hash(); - } - - @DontCompile - public void test4_verifier(boolean warmup) { - long result = test4(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type in compiled code and pass it to - // an inlined compiled method via a call. - @Test(failOn = ALLOC + LOAD + STORE + TRAP) - public long test5() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - return test5Inline(v); - } - - @ForceInline - public long test5Inline(MyValue1 v) { - return v.hash(); - } - - @DontCompile - public void test5_verifier(boolean warmup) { - long result = test5(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type in compiled code and pass it to - // the interpreter via a call. - @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = LOAD + TRAP + ALLOC) - @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP) - public long test6() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - // Pass to interpreter - return v.hashInterpreted(); - } - - @DontCompile - public void test6_verifier(boolean warmup) { - long result = test6(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type in compiled code and pass it to - // the interpreter by returning. - @Test(match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP) - public MyValue1 test7(int x, long y) { - return MyValue1.createWithFieldsInline(x, y); - } - - @DontCompile - public void test7_verifier(boolean warmup) { - MyValue1 v = test7(rI, rL); - Asserts.assertEQ(v.hash(), hash()); - } - - // Merge inline types created from two branches - @Test(failOn = ALLOC + STORE + TRAP) - public long test8(boolean b) { - MyValue1 v; - if (b) { - v = MyValue1.createWithFieldsInline(rI, rL); - } else { - v = MyValue1.createWithFieldsDontInline(rI + 1, rL + 1); - } - return v.hash(); - } - - @DontCompile - public void test8_verifier(boolean warmup) { - Asserts.assertEQ(test8(true), hash()); - Asserts.assertEQ(test8(false), hash(rI + 1, rL + 1)); - } - - // Merge inline types created from two branches - @Test(valid = InlineTypePassFieldsAsArgsOn, match = {LOAD}, matchCount = {14}, failOn = TRAP + ALLOC + STORE) - @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC, STORE}, matchCount = {1, 13}, failOn = LOAD + TRAP) - public MyValue1 test9(boolean b, int localrI, long localrL) { - MyValue1 v; - if (b) { - // Inline type is not allocated - // Do not use rI/rL directly here as null values may cause - // some redundant null initializations to be optimized out - // and matching to fail. - v = MyValue1.createWithFieldsInline(localrI, localrL); - } else { - // Inline type is allocated by the callee - v = MyValue1.createWithFieldsDontInline(rI + 1, rL + 1); - } - // Need to allocate inline type if 'b' is true - long sum = v.hashInterpreted(); - if (b) { - v = MyValue1.createWithFieldsDontInline(rI, sum); - } else { - v = MyValue1.createWithFieldsDontInline(rI, sum + 1); - } - // Don't need to allocate inline type because both branches allocate - return v; - } - - @DontCompile - public void test9_verifier(boolean warmup) { - MyValue1 v = test9(true, rI, rL); - Asserts.assertEQ(v.x, rI); - Asserts.assertEQ(v.y, hash()); - v = test9(false, rI, rL); - Asserts.assertEQ(v.x, rI); - Asserts.assertEQ(v.y, hash(rI + 1, rL + 1) + 1); - } - - // Merge inline types created in a loop (not inlined) - @Test(failOn = ALLOC + STORE + TRAP) - public long test10(int x, long y) { - MyValue1 v = MyValue1.createWithFieldsDontInline(x, y); - for (int i = 0; i < 10; ++i) { - v = MyValue1.createWithFieldsDontInline(v.x + 1, v.y + 1); - } - return v.hash(); - } - - @DontCompile - public void test10_verifier(boolean warmup) { - long result = test10(rI, rL); - Asserts.assertEQ(result, hash(rI + 10, rL + 10)); - } - - // Merge inline types created in a loop (inlined) - @Test(failOn = ALLOC + LOAD + STORE + TRAP) - public long test11(int x, long y) { - MyValue1 v = MyValue1.createWithFieldsInline(x, y); - for (int i = 0; i < 10; ++i) { - v = MyValue1.createWithFieldsInline(v.x + 1, v.y + 1); - } - return v.hash(); - } - - @DontCompile - public void test11_verifier(boolean warmup) { - long result = test11(rI, rL); - Asserts.assertEQ(result, hash(rI + 10, rL + 10)); - } - - // Test loop with uncommon trap referencing an inline type - @Test(match = {SCOBJ}, matchCount = {-1 /* at least 1 */}, failOn = LOAD) - public long test12(boolean b) { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - MyValue1[] va = new MyValue1[Math.abs(rI) % 10]; - for (int i = 0; i < va.length; ++i) { - va[i] = MyValue1.createWithFieldsInline(rI, rL); - } - long result = rL; - for (int i = 0; i < 1000; ++i) { - if (b) { - result += v.x; - } else { - // Uncommon trap referencing v. We delegate allocation to the - // interpreter by adding a SafePointScalarObjectNode. - result = v.hashInterpreted(); - for (int j = 0; j < va.length; ++j) { - result += va[j].hash(); - } - } - } - return result; - } - - @DontCompile - public void test12_verifier(boolean warmup) { - long result = test12(warmup); - Asserts.assertEQ(result, warmup ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); - } - - // Test loop with uncommon trap referencing an inline type - @Test - public long test13(boolean b) { - MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); - MyValue1[] va = new MyValue1[Math.abs(rI) % 10]; - for (int i = 0; i < va.length; ++i) { - va[i] = MyValue1.createWithFieldsDontInline(rI, rL); - } - long result = rL; - for (int i = 0; i < 1000; ++i) { - if (b) { - result += v.x; - } else { - // Uncommon trap referencing v. Should not allocate - // but just pass the existing oop to the uncommon trap. - result = v.hashInterpreted(); - for (int j = 0; j < va.length; ++j) { - result += va[j].hashInterpreted(); - } - } - } - return result; - } - - @DontCompile - public void test13_verifier(boolean warmup) { - long result = test13(warmup); - Asserts.assertEQ(result, warmup ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); - } - - // Create an inline type in a non-inlined method and then call a - // non-inlined method on that inline type. - @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = (ALLOC + STORE + TRAP), match = {LOAD}, matchCount = {14}) - @Test(valid = InlineTypePassFieldsAsArgsOff, failOn = (ALLOC + LOAD + STORE + TRAP)) - public long test14() { - MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); - return v.hashInterpreted(); - } - - @DontCompile - public void test14_verifier(boolean b) { - long result = test14(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type in an inlined method and then call a - // non-inlined method on that inline type. - @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = (LOAD + TRAP + ALLOC)) - @Test(valid = InlineTypePassFieldsAsArgsOff, failOn = (LOAD + TRAP), match = {ALLOC}, matchCount = {1}) - public long test15() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - return v.hashInterpreted(); - } - - @DontCompile - public void test15_verifier(boolean b) { - long result = test15(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type in a non-inlined method and then call an - // inlined method on that inline type. - @Test(failOn = (ALLOC + STORE + TRAP)) - public long test16() { - MyValue1 v = MyValue1.createWithFieldsDontInline(rI, rL); - return v.hash(); - } - - @DontCompile - public void test16_verifier(boolean b) { - long result = test16(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type in an inlined method and then call an - // inlined method on that inline type. - @Test(failOn = (ALLOC + LOAD + STORE + TRAP)) - public long test17() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - return v.hash(); - } - - @DontCompile - public void test17_verifier(boolean b) { - long result = test17(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type in compiled code and pass it to the - // interpreter via a call. The inline type is live at the first call so - // debug info should include a reference to all its fields. - @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = ALLOC + LOAD + TRAP) - @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP) - public long test18() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - v.hashInterpreted(); - return v.hashInterpreted(); - } - - @DontCompile - public void test18_verifier(boolean warmup) { - long result = test18(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type in compiled code and pass it to the - // interpreter via a call. The inline type is passed twice but - // should only be allocated once. - @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = ALLOC + LOAD + TRAP) - @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {1}, failOn = LOAD + TRAP) - public long test19() { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - return sumValue(v, v); - } - - @DontCompile - public long sumValue(MyValue1 v, MyValue1 dummy) { - return v.hash(); - } - - @DontCompile - public void test19_verifier(boolean warmup) { - long result = test19(); - Asserts.assertEQ(result, hash()); - } - - // Create an inline type (array) in compiled code and pass it to the - // interpreter via a call. The inline type is live at the uncommon - // trap: verify that deoptimization causes the inline type to be - // correctly allocated. - @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = LOAD + ALLOC + STORE) - @Test(valid = InlineTypePassFieldsAsArgsOff, match = {ALLOC}, matchCount = {1}, failOn = LOAD) - public long test20(boolean deopt) { - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - MyValue2[] va = new MyValue2[3]; - if (deopt) { - // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test20")); - } - return v.hashInterpreted() + va[0].hashInterpreted() + - va[1].hashInterpreted() + va[2].hashInterpreted(); - } - - @DontCompile - public void test20_verifier(boolean warmup) { - MyValue2[] va = new MyValue2[42]; - long result = test20(!warmup); - Asserts.assertEQ(result, hash() + va[0].hash() + va[1].hash() + va[2].hash()); - } - - // Inline type fields in regular object - MyValue1 val1; - MyValue2 val2; - final MyValue1 val3 = MyValue1.createWithFieldsInline(rI, rL); - static MyValue1 val4; - static final MyValue1 val5 = MyValue1.createWithFieldsInline(rI, rL); - - // Test inline type fields in objects - @Test(match = {ALLOC}, matchCount = {1}, failOn = (TRAP)) - public long test21(int x, long y) { - // Compute hash of inline type fields - long result = val1.hash() + val2.hash() + val3.hash() + val4.hash() + val5.hash(); - // Update fields - val1 = MyValue1.createWithFieldsInline(x, y); - val2 = MyValue2.createWithFieldsInline(x, rD); - val4 = MyValue1.createWithFieldsInline(x, y); - return result; - } - - @DontCompile - public void test21_verifier(boolean warmup) { - // Check if hash computed by test18 is correct - val1 = MyValue1.createWithFieldsInline(rI, rL); - val2 = val1.v2; - // val3 is initialized in the constructor - val4 = val1; - // val5 is initialized in the static initializer - long hash = val1.hash() + val2.hash() + val3.hash() + val4.hash() + val5.hash(); - long result = test21(rI + 1, rL + 1); - Asserts.assertEQ(result, hash); - // Check if inline type fields were updated - Asserts.assertEQ(val1.hash(), hash(rI + 1, rL + 1)); - Asserts.assertEQ(val2.hash(), MyValue2.createWithFieldsInline(rI + 1, rD).hash()); - Asserts.assertEQ(val4.hash(), hash(rI + 1, rL + 1)); - } - - // Test folding of constant inline type fields - @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) - public long test22() { - // This should be constant folded - return val5.hash() + val5.v3.hash(); - } - - @DontCompile - public void test22_verifier(boolean warmup) { - long result = test22(); - Asserts.assertEQ(result, val5.hash() + val5.v3.hash()); - } - - // Test defaultvalue - @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) - public long test23() { - MyValue2 v = MyValue2.createDefaultInline(); - return v.hash(); - } - - @DontCompile - public void test23_verifier(boolean warmup) { - long result = test23(); - Asserts.assertEQ(result, MyValue2.createDefaultInline().hash()); - } - - // Test defaultvalue - @Test(failOn = ALLOC + STORE + LOOP + TRAP) - public long test24() { - MyValue1 v1 = MyValue1.createDefaultInline(); - MyValue1 v2 = MyValue1.createDefaultDontInline(); - return v1.hashPrimitive() + v2.hashPrimitive(); - } - - @DontCompile - public void test24_verifier(boolean warmup) { - long result = test24(); - Asserts.assertEQ(result, 2 * MyValue1.createDefaultInline().hashPrimitive()); - } - - // Test withfield - @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) - public long test25() { - MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); - return v.hash(); - } - - @DontCompile - public void test25_verifier(boolean warmup) { - long result = test25(); - Asserts.assertEQ(result, MyValue2.createWithFieldsInline(rI, rD).hash()); - } - - // Test withfield - @Test(failOn = ALLOC + STORE + LOOP + TRAP) - public long test26() { - MyValue1 v1 = MyValue1.createWithFieldsInline(rI, rL); - MyValue1 v2 = MyValue1.createWithFieldsDontInline(rI, rL); - return v1.hash() + v2.hash(); - } - - @DontCompile - public void test26_verifier(boolean warmup) { - long result = test26(); - Asserts.assertEQ(result, 2 * hash()); - } - - class TestClass27 { - public MyValue1 v; - } - - // Test allocation elimination of unused object with initialized inline type field - @Test(failOn = ALLOC + LOAD + STORE + LOOP) - public void test27(boolean deopt) { - TestClass27 unused = new TestClass27(); - MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); - unused.v = v; - if (deopt) { - // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test27")); - } - } - - @DontCompile - public void test27_verifier(boolean warmup) { - test27(!warmup); - } - - static MyValue3 staticVal3; - static MyValue3 staticVal3_copy; - - // Check elimination of redundant inline type allocations - @Test(match = {ALLOC}, matchCount = {1}) - public MyValue3 test28(MyValue3[] va) { - // Create inline type and force allocation - MyValue3 vt = MyValue3.create(); - va[0] = vt; - staticVal3 = vt; - vt.verify(staticVal3); - - // Inline type is now allocated, make a copy and force allocation. - // Because copy is equal to vt, C2 should remove this redundant allocation. - MyValue3 copy = MyValue3.setC(vt, vt.c); - va[0] = copy; - staticVal3_copy = copy; - copy.verify(staticVal3_copy); - return copy; - } - - @DontCompile - public void test28_verifier(boolean warmup) { - MyValue3[] va = new MyValue3[1]; - MyValue3 vt = test28(va); - staticVal3.verify(vt); - staticVal3.verify(va[0]); - staticVal3_copy.verify(vt); - staticVal3_copy.verify(va[0]); - } - - // Verify that only dominating allocations are re-used - @Test() - public MyValue3 test29(boolean warmup) { - MyValue3 vt = MyValue3.create(); - if (warmup) { - staticVal3 = vt; // Force allocation - } - // Force allocation to verify that above - // non-dominating allocation is not re-used - MyValue3 copy = MyValue3.setC(vt, vt.c); - staticVal3_copy = copy; - copy.verify(vt); - return copy; - } - - @DontCompile - public void test29_verifier(boolean warmup) { - MyValue3 vt = test29(warmup); - if (warmup) { - staticVal3.verify(vt); - } - } - - // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations - @Test(failOn = ALLOC + ALLOCA + STORE) - public MyValue3 test30(MyValue3[] va) { - // C2 can re-use the oop of staticVal3 because staticVal3 is equal to copy - MyValue3 copy = MyValue3.copy(staticVal3); - va[0] = copy; - staticVal3 = copy; - copy.verify(staticVal3); - return copy; - } - - @DontCompile - public void test30_verifier(boolean warmup) { - staticVal3 = MyValue3.create(); - MyValue3[] va = new MyValue3[1]; - MyValue3 vt = test30(va); - staticVal3.verify(vt); - staticVal3.verify(va[0]); - } - - // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations - @Test(valid = InlineTypeReturnedAsFieldsOn) - @Test(valid = InlineTypeReturnedAsFieldsOff, failOn = ALLOC + ALLOCA + STORE) - public MyValue3 test31(MyValue3[] va) { - // C2 can re-use the oop returned by createDontInline() - // because the corresponding inline type is equal to 'copy'. - MyValue3 copy = MyValue3.copy(MyValue3.createDontInline()); - va[0] = copy; - staticVal3 = copy; - copy.verify(staticVal3); - return copy; - } - - @DontCompile - public void test31_verifier(boolean warmup) { - MyValue3[] va = new MyValue3[1]; - MyValue3 vt = test31(va); - staticVal3.verify(vt); - staticVal3.verify(va[0]); - } - - // Verify that C2 recognizes inline type loads and re-uses the oop to avoid allocations - @Test(valid = InlineTypePassFieldsAsArgsOn) - @Test(valid = InlineTypePassFieldsAsArgsOff, failOn = ALLOC + ALLOCA + STORE) - public MyValue3 test32(MyValue3 vt, MyValue3[] va) { - // C2 can re-use the oop of vt because vt is equal to 'copy'. - MyValue3 copy = MyValue3.copy(vt); - va[0] = copy; - staticVal3 = copy; - copy.verify(staticVal3); - return copy; - } - - @DontCompile - public void test32_verifier(boolean warmup) { - MyValue3 vt = MyValue3.create(); - MyValue3[] va = new MyValue3[1]; - MyValue3 result = test32(vt, va); - staticVal3.verify(vt); - va[0].verify(vt); - result.verify(vt); - } - - // Test correct identification of inline type copies - @Test() - public MyValue3 test33(MyValue3[] va) { - MyValue3 vt = MyValue3.copy(staticVal3); - vt = MyValue3.setI(vt, vt.c); - // vt is not equal to staticVal3, so C2 should not re-use the oop - va[0] = vt; - staticVal3 = vt; - vt.verify(staticVal3); - return vt; - } - - @DontCompile - public void test33_verifier(boolean warmup) { - staticVal3 = MyValue3.create(); - MyValue3[] va = new MyValue3[1]; - MyValue3 vt = test33(va); - Asserts.assertEQ(staticVal3.i, (int)staticVal3.c); - Asserts.assertEQ(va[0].i, (int)staticVal3.c); - Asserts.assertEQ(vt.i, (int)staticVal3.c); - } - - // Verify that the default inline type is never allocated. - // C2 code should load and use the default oop from the java mirror. - @Test(failOn = ALLOC + ALLOCA + LOAD + STORE + LOOP + TRAP) - public MyValue3 test34(MyValue3[] va) { - // Explicitly create default value - MyValue3 vt = MyValue3.createDefault(); - va[0] = vt; - staticVal3 = vt; - vt.verify(vt); - - // Load default value from uninitialized inline type array - MyValue3[] dva = new MyValue3[1]; - staticVal3_copy = dva[0]; - va[1] = dva[0]; - dva[0].verify(dva[0]); - return vt; - } - - @DontCompile - public void test34_verifier(boolean warmup) { - MyValue3 vt = MyValue3.createDefault(); - MyValue3[] va = new MyValue3[2]; - va[0] = MyValue3.create(); - va[1] = MyValue3.create(); - MyValue3 res = test34(va); - res.verify(vt); - staticVal3.verify(vt); - staticVal3_copy.verify(vt); - va[0].verify(vt); - va[1].verify(vt); - } - - // Same as above but manually initialize inline type fields to default. - @Test(failOn = ALLOC + ALLOCA + LOAD + STORE + LOOP + TRAP) - public MyValue3 test35(MyValue3 vt, MyValue3[] va) { - vt = MyValue3.setC(vt, (char)0); - vt = MyValue3.setBB(vt, (byte)0); - vt = MyValue3.setS(vt, (short)0); - vt = MyValue3.setI(vt, 0); - vt = MyValue3.setL(vt, 0); - vt = MyValue3.setO(vt, null); - vt = MyValue3.setF1(vt, 0); - vt = MyValue3.setF2(vt, 0); - vt = MyValue3.setF3(vt, 0); - vt = MyValue3.setF4(vt, 0); - vt = MyValue3.setF5(vt, 0); - vt = MyValue3.setF6(vt, 0); - vt = MyValue3.setV1(vt, MyValue3Inline.createDefault()); - va[0] = vt; - staticVal3 = vt; - vt.verify(vt); - return vt; - } - - @DontCompile - public void test35_verifier(boolean warmup) { - MyValue3 vt = MyValue3.createDefault(); - MyValue3[] va = new MyValue3[1]; - va[0] = MyValue3.create(); - MyValue3 res = test35(va[0], va); - res.verify(vt); - staticVal3.verify(vt); - va[0].verify(vt); - } - - // Merge inline types created from two branches - - private Object test36_helper(Object v) { - return v; - } - - @Test(failOn = ALLOC + STORE + TRAP) - public long test36(boolean b) { - Object o; - if (b) { - o = test36_helper(MyValue1.createWithFieldsInline(rI, rL)); - } else { - o = test36_helper(MyValue1.createWithFieldsDontInline(rI + 1, rL + 1)); - } - MyValue1 v = (MyValue1)o; - return v.hash(); - } - - @DontCompile - public void test36_verifier(boolean warmup) { - Asserts.assertEQ(test36(true), hash()); - Asserts.assertEQ(test36(false), hash(rI + 1, rL + 1)); - } - - // Test correct loading of flattened fields - primitive class Test37Value2 { - final int x = 0; - final int y = 0; - } - - primitive class Test37Value1 { - final double d = 0; - final float f = 0; - final Test37Value2 v = new Test37Value2(); - } - - @Test - public Test37Value1 test37(Test37Value1 vt) { - return vt; - } - - @DontCompile - public void test37_verifier(boolean warmup) { - Test37Value1 vt = new Test37Value1(); - Asserts.assertEQ(test37(vt), vt); - } - - // Test elimination of inline type allocations without a unique CheckCastPP - primitive class Test38Value { - public int i; - public Test38Value(int i) { this.i = i; } - } - - static Test38Value test38Field; - - @Test - public void test38() { - for (int i = 3; i < 100; ++i) { - int j = 1; - while (++j < 11) { - try { - test38Field = new Test38Value(i); - } catch (ArithmeticException ae) { } - } - } - } - - @DontCompile - public void test38_verifier(boolean warmup) { - test38Field = Test38Value.default; - test38(); - Asserts.assertEQ(test38Field, new Test38Value(99)); - } - - // Tests split if with inline type Phi users - static primitive class Test39Value { - public int iFld1; - public int iFld2; - - public Test39Value(int i1, int i2) { iFld1 = i1; iFld2 = i2; } - } - - static int test39A1[][] = new int[400][400]; - static double test39A2[] = new double[400]; - static Test39Value test39Val = Test39Value.default; - - @DontInline - public int[] getArray() { - return new int[400]; - } - - @Test - @Warmup(10) - public int test39() { - int result = 0; - for (int i = 0; i < 100; ++i) { - switch ((i >>> 1) % 3) { - case 0: - test39A1[i][i] = i; - break; - case 1: - for (int j = 0; j < 100; ++j) { - test39A1[i] = getArray(); - test39Val = new Test39Value(j, test39Val.iFld2); - } - break; - case 2: - for (float f = 142; f > i; f--) { - test39A2[i + 1] += 3; - } - result += test39Val.iFld1; - break; - } - double d1 = 1; - while (++d1 < 142) { - test39A1[(i >>> 1) % 400][i + 1] = result; - test39Val = new Test39Value(i, test39Val.iFld2); - } - } - return result; - } - - @DontCompile - public void test39_verifier(boolean warmup) { - int result = test39(); - Asserts.assertEQ(result, 1552); - } - - // Test scalar replacement of inline type array containing inline type with oop fields - @Test() - public long test40(boolean b) { - MyValue1[] va = {MyValue1.createWithFieldsInline(rI, rL)}; - long result = 0; - for (int i = 0; i < 1000; ++i) { - if (!b) { - result = va[0].hash(); - } - } - return result; - } - - @DontCompile - public void test40_verifier(boolean warmup) { - long result = test40(warmup); - Asserts.assertEQ(result, warmup ? 0 : hash()); - } -} From 004192ee0a2ccc33937e019c385eae91af862b6e Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 19 Mar 2021 18:44:44 +0100 Subject: [PATCH 063/131] Add isCompiled() and fix isCompiledAtLevel() to handle ANY --- .../hotspot/ir_framework/TestFramework.java | 4 ++ .../ir_framework/TestFrameworkExecution.java | 39 ++++++++++++++----- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 82ee2e45623..36e504b5f08 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -364,6 +364,10 @@ public void deoptimize(String mName) { deoptimize(getTestMethod(mName)); } + public static boolean isCompiled(Method m) { + return TestFrameworkExecution.isCompiled(m); + } + public static boolean isC1Compiled(Method m) { return TestFrameworkExecution.isC1Compiled(m); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 2b650a322bd..5c11ace3685 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -386,12 +386,16 @@ private void applyForceCompileCommand(Executable ex) { } } - static void enqueueForCompilation(Executable ex, CompLevel compLevel) { + static void enqueueForCompilation(Executable ex, CompLevel requestedCompLevel) { if (TestFrameworkExecution.VERBOSE) { - System.out.println("enqueueForCompilation " + ex + ", level = " + compLevel); + System.out.println("enqueueForCompilation " + ex + ", level = " + requestedCompLevel); + } + CompLevel compLevel = restrictCompLevel(requestedCompLevel); + if (compLevel != CompLevel.SKIP) { + WHITE_BOX.enqueueMethodForCompilation(ex, compLevel.getValue()); + } else { + System.out.println("Skipped compilation on level " + requestedCompLevel + " due to VM flags not allowing it."); } - compLevel = restrictCompLevel(compLevel); - WHITE_BOX.enqueueMethodForCompilation(ex, compLevel.getValue()); } static boolean shouldCompile(Executable ex) { @@ -704,6 +708,8 @@ enum TriState { static void compile(Method m, CompLevel compLevel) { TestRun.check(getAnnotation(m, Test.class) == null, "Cannot call enqueueMethodForCompilation() for @Test annotated method " + m); + TestRun.check(compLevel != CompLevel.SKIP && compLevel != CompLevel.WAIT_FOR_COMPILATION, + "Invalid compilation request with level " + compLevel); enqueueForCompilation(m, compLevel); } @@ -711,6 +717,10 @@ static void deoptimize(Method m) { WHITE_BOX.deoptimizeMethod(m); } + static boolean isCompiled(Method m) { + return compiledAtLevel(m, CompLevel.ANY) == TriState.Yes; + } + static boolean isC1Compiled(Method m) { return compiledByC1(m) == TriState.Yes; } @@ -771,13 +781,24 @@ private static TriState compiledByC2(Method m) { } private static TriState compiledAtLevel(Method m, CompLevel level) { - if (!TestFrameworkExecution.USE_COMPILER || TestFrameworkExecution.XCOMP || TestFrameworkExecution.TEST_C1 || - (TestFrameworkExecution.STRESS_CC && !WHITE_BOX.isMethodCompilable(m, level.getValue(), false))) { + if (!USE_COMPILER || XCOMP || TEST_C1 || + (STRESS_CC && !WHITE_BOX.isMethodCompilable(m, level.getValue(), false))) { return TriState.Maybe; } - if (WHITE_BOX.isMethodCompiled(m, false) - && WHITE_BOX.getMethodCompilationLevel(m, false) == level.getValue()) { - return TriState.Yes; + if (WHITE_BOX.isMethodCompiled(m, false)) { + switch (level) { + case C1, C1_LIMITED_PROFILE, C1_FULL_PROFILE, C2 -> { + if (WHITE_BOX.getMethodCompilationLevel(m, false) == level.getValue()) { + return TriState.Yes; + } else { + return TriState.No; + } + } + case ANY -> { + return TriState.Yes; + } + default -> TestRun.fail("compiledAtLevel() should not be called with " + level); + } } return TriState.No; } From e7e9ab30e318167e3c30a2dc21bc23d73c1111f3 Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Mon, 22 Mar 2021 10:25:45 -0700 Subject: [PATCH 064/131] Converted the test to IT framework --- .../valhalla/inlinetypes/TestArrays.java | 1188 +++++++++-------- 1 file changed, 638 insertions(+), 550 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java index 616393d2074..1e5ce95107b 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -28,38 +28,38 @@ import java.lang.reflect.Method; import java.util.Arrays; +import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; + /* * @test * @key randomness * @summary Test inline type arrays - * @library /testlibrary /test/lib /compiler/whitebox / + * @library /test/lib * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile TestArrays.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestArrays + * @compile InlineTypes.java + * @run driver compiler.valhalla.inlinetypes.TestArrays */ -public class TestArrays extends InlineTypeTest { - // Extra VM parameters for some test scenarios. See InlineTypeTest.getVMParameters() - @Override - public String[] getExtraVMParameters(int scenario) { - switch (scenario) { - case 2: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode"}; - case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1", "-XX:-UncommonNullCast"}; - case 4: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast"}; - case 5: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode"}; - } - return null; - } +public class TestArrays { + + static final TestFramework testFramework = InlineTypes.getFramework(); - public static void main(String[] args) throws Throwable { - TestArrays test = new TestArrays(); - test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class); + public static void main(String[] args) { + Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; + scenarios[2].addFlags("-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode"); + scenarios[3].addFlags("-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1", "-XX:-UncommonNullCast"); + scenarios[4].addFlags("-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast"); + scenarios[5].addFlags("-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode"); + + testFramework.addScenarios(scenarios) + .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class) + .start(); } - // Helper methods + // Helper methods and classes protected long hash() { return hash(rI, rL); @@ -69,9 +69,68 @@ protected long hash(int x, long y) { return MyValue1.createWithFieldsInline(x, y).hash(); } + static void verify(Object[] src, Object[] dst) { + if (src instanceof MyInterface[] && dst instanceof MyInterface[]) { + for (int i = 0; i < src.length; ++i) { + Asserts.assertEQ(((MyInterface)src[i]).hash(), ((MyInterface)dst[i]).hash()); + } + } else { + for (int i = 0; i < src.length; ++i) { + Asserts.assertEQ(src[i], dst[i]); + } + } + } + + static void verify(MyValue1[] src, MyValue1[] dst) { + for (int i = 0; i < src.length; ++i) { + Asserts.assertEQ(src[i].hash(), dst[i].hash()); + } + } + + static void verify(MyValue1[] src, Object[] dst) { + for (int i = 0; i < src.length; ++i) { + Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); + } + } + + static void verify(MyValue2[] src, MyValue2[] dst) { + for (int i = 0; i < src.length; ++i) { + Asserts.assertEQ(src[i].hash(), dst[i].hash()); + } + } + + static void verify(MyValue2[] src, Object[] dst) { + for (int i = 0; i < src.length; ++i) { + Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); + } + } + + static boolean compile_and_run_again_if_deoptimized(boolean warmup, String test) { + if (!warmup) { + Method m = testFramework.getTestMethod(test); + if (testFramework.isCompiled(m)) { + testFramework.compile(m, CompLevel.C2); + } + } + return false; + } + + primitive static class NotFlattenable { + private final Object o1 = null; + private final Object o2 = null; + private final Object o3 = null; + private final Object o4 = null; + private final Object o5 = null; + private final Object o6 = null; + } + // Test inline type array creation and initialization - @Test(valid = InlineTypeArrayFlattenOn, match = { ALLOCA }, matchCount = { 1 }) - @Test(valid = InlineTypeArrayFlattenOff, match = { ALLOCA }, matchCount = { 1 }, failOn = LOAD) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + counts = {ALLOCA, "= 1"}) + @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, + counts = {ALLOCA, "= 1"}, + failOn = {LOAD}) public MyValue1[] test1(int len) { MyValue1[] va = new MyValue1[len]; for (int i = 0; i < len; ++i) { @@ -80,8 +139,8 @@ public MyValue1[] test1(int len) { return va; } - @DontCompile - public void test1_verifier(boolean warmup) { + @Run(test = "test1") + public void test1_verifier() { int len = Math.abs(rI % 10); MyValue1[] va = test1(len); for (int i = 0; i < len; ++i) { @@ -89,23 +148,26 @@ public void test1_verifier(boolean warmup) { } } + // Test creation of an inline type array and element access - @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) public long test2() { MyValue1[] va = new MyValue1[1]; va[0] = MyValue1.createWithFieldsInline(rI, rL); return va[0].hash(); } - @DontCompile - public void test2_verifier(boolean warmup) { + @Run(test = "test2") + public void test2_verifier() { long result = test2(); Asserts.assertEQ(result, hash()); } // Test receiving an inline type array from the interpreter, // updating its elements in a loop and computing a hash. - @Test(failOn = ALLOCA) + @Test + @IR(failOn = {ALLOCA}) public long test3(MyValue1[] va) { long result = 0; for (int i = 0; i < 10; ++i) { @@ -115,8 +177,8 @@ public long test3(MyValue1[] va) { return result; } - @DontCompile - public void test3_verifier(boolean warmup) { + @Run(test = "test3") + public void test3_verifier() { MyValue1[] va = new MyValue1[10]; long expected = 0; for (int i = 0; i < 10; ++i) { @@ -133,13 +195,14 @@ public void test3_verifier(boolean warmup) { } // Test returning an inline type array received from the interpreter - @Test(failOn = ALLOC + ALLOCA + LOAD + STORE + LOOP + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE, LOOP, TRAP}) public MyValue1[] test4(MyValue1[] va) { return va; } - @DontCompile - public void test4_verifier(boolean warmup) { + @Run(test = "test4") + public void test4_verifier() { MyValue1[] va = new MyValue1[10]; for (int i = 0; i < 10; ++i) { va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i); @@ -174,8 +237,8 @@ public MyValue1[] test5(boolean b) { return va; } - @DontCompile - public void test5_verifier(boolean warmup) { + @Run(test = "test5") + public void test5_verifier() { MyValue1[] va = test5(true); Asserts.assertEQ(va.length, 5); Asserts.assertEQ(va[0].hash(), hash(rI, hash())); @@ -191,27 +254,29 @@ public void test5_verifier(boolean warmup) { } // Test creation of inline type array with single element - @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) public MyValue1 test6() { MyValue1[] va = new MyValue1[1]; return va[0]; } - @DontCompile - public void test6_verifier(boolean warmup) { + @Run(test = "test6") + public void test6_verifier() { MyValue1[] va = new MyValue1[1]; MyValue1 v = test6(); Asserts.assertEQ(v.hashPrimitive(), va[0].hashPrimitive()); } // Test default initialization of inline type arrays - @Test(failOn = LOAD) + @Test + @IR(failOn = {LOAD}) public MyValue1[] test7(int len) { return new MyValue1[len]; } - @DontCompile - public void test7_verifier(boolean warmup) { + @Run(test = "test7") + public void test7_verifier() { int len = Math.abs(rI % 10); MyValue1[] va = new MyValue1[len]; MyValue1[] var = test7(len); @@ -221,13 +286,14 @@ public void test7_verifier(boolean warmup) { } // Test creation of inline type array with zero length - @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, LOOP, TRAP}) public MyValue1[] test8() { return new MyValue1[0]; } - @DontCompile - public void test8_verifier(boolean warmup) { + @Run(test = "test8") + public void test8_verifier() { MyValue1[] va = test8(); Asserts.assertEQ(va.length, 0); } @@ -235,13 +301,14 @@ public void test8_verifier(boolean warmup) { static MyValue1[] test9_va; // Test that inline type array loaded from field has correct type - @Test(failOn = LOOP) + @Test + @IR(failOn = {LOOP}) public long test9() { return test9_va[0].hash(); } - @DontCompile - public void test9_verifier(boolean warmup) { + @Run(test = "test9") + public void test9_verifier() { test9_va = new MyValue1[1]; test9_va[0] = MyValue1.createWithFieldsInline(rI, rL); long result = test9(); @@ -262,8 +329,8 @@ public MyValue1[][][] test10(int len1, int len2, int len3) { return arr; } - @DontCompile - public void test10_verifier(boolean warmup) { + @Run(test = "test10") + public void test10_verifier() { MyValue1[][][] arr = test10(2, 3, 4); for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { @@ -274,6 +341,7 @@ public void test10_verifier(boolean warmup) { } } + @Test public void test11(MyValue1[][][] arr, long[] res) { int l = 0; @@ -287,8 +355,8 @@ public void test11(MyValue1[][][] arr, long[] res) { } } - @DontCompile - public void test11_verifier(boolean warmup) { + @Run(test = "test11") + public void test11_verifier() { MyValue1[][][] arr = new MyValue1[2][3][4]; long[] res = new long[2*3*4]; long[] verif = new long[2*3*4]; @@ -325,8 +393,8 @@ public int test12() { } } - @DontCompile - public void test12_verifier(boolean warmup) { + @Run(test = "test12") + public void test12_verifier() { Asserts.assertEQ(test12(), rI); } @@ -347,8 +415,8 @@ public int test13() { } } - @DontCompile - public void test13_verifier(boolean warmup) { + @Run(test = "test13") + public void test13_verifier() { Asserts.assertEQ(test13(), rI); } @@ -358,8 +426,8 @@ public int test14(MyValue1[] va, int index) { return va[index].x; } - @DontCompile - public void test14_verifier(boolean warmup) { + @Run(test = "test14") + public void test14_verifier() { int arraySize = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[arraySize]; @@ -394,8 +462,8 @@ public int test15() { } } - @DontCompile - public void test15_verifier(boolean warmup) { + @Run(test = "test15") + public void test15_verifier() { Asserts.assertEQ(test15(), rI); } @@ -415,8 +483,8 @@ public int test16() { } } - @DontCompile - public void test16_verifier(boolean warmup) { + @Run(test = "test16") + public void test16_verifier() { Asserts.assertEQ(test16(), rI); } @@ -427,8 +495,8 @@ public int test17(MyValue1[] va, int index, MyValue1 vt) { return va[index].x; } - @DontCompile - public void test17_verifier(boolean warmup) { + @Run(test = "test17") + public void test17_verifier() { int arraySize = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[arraySize]; @@ -458,8 +526,8 @@ public MyValue1[] test18(MyValue1[] va) { return va.clone(); } - @DontCompile - public void test18_verifier(boolean warmup) { + @Run(test = "test18") + public void test18_verifier() { int len = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[len]; for (int i = 0; i < len; ++i) { @@ -485,22 +553,23 @@ public MyValue1[] test19() { return va.clone(); } - @DontCompile - public void test19_verifier(boolean warmup) { + @Run(test = "test19") + public void test19_verifier() { MyValue1[] result = test19(); for (int i = 0; i < test19_orig.length; ++i) { Asserts.assertEQ(result[i].hash(), test19_orig[i].hash()); } } + // arraycopy() of inline type array with oop fields @Test public void test20(MyValue1[] src, MyValue1[] dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test20_verifier(boolean warmup) { + @Run(test = "test20") + public void test20_verifier() { int len = Math.abs(rI) % 10; MyValue1[] src = new MyValue1[len]; MyValue1[] dst = new MyValue1[len]; @@ -519,8 +588,8 @@ public void test21(MyValue2[] src, MyValue2[] dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test21_verifier(boolean warmup) { + @Run(test = "test21") + public void test21_verifier() { int len = Math.abs(rI) % 10; MyValue2[] src = new MyValue2[len]; MyValue2[] dst = new MyValue2[len]; @@ -542,8 +611,8 @@ public MyValue1[] test22(MyValue1[] src) { return dst; } - @DontCompile - public void test22_verifier(boolean warmup) { + @Run(test = "test22") + public void test22_verifier() { int len = Math.abs(rI) % 10; MyValue1[] src = new MyValue1[len]; for (int i = 0; i < len; ++i) { @@ -564,8 +633,8 @@ public MyValue1[] test23(MyValue1[] src) { return dst; } - @DontCompile - public void test23_verifier(boolean warmup) { + @Run(test = "test23") + public void test23_verifier() { int len = Math.abs(rI) % 10; MyValue1[] src = new MyValue1[len]; for (int i = 0; i < len; ++i) { @@ -583,8 +652,8 @@ public void test24(MyValue1[] src, Object dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test24_verifier(boolean warmup) { + @Run(test = "test24") + public void test24_verifier() { int len = Math.abs(rI) % 10; MyValue1[] src = new MyValue1[len]; MyValue1[] dst1 = new MyValue1[len]; @@ -608,8 +677,8 @@ public void test25(MyValue2[] src, MyValue2[] dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test25_verifier(boolean warmup) { + @Run(test = "test25") + public void test25_verifier() { MyValue2[] src = new MyValue2[8]; MyValue2[] dst = new MyValue2[8]; for (int i = 0; i < 8; ++i) { @@ -627,8 +696,8 @@ public void test26(MyValue1[] src, MyValue1[] dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test26_verifier(boolean warmup) { + @Run(test = "test26") + public void test26_verifier() { MyValue1[] src = new MyValue1[8]; MyValue1[] dst = new MyValue1[8]; for (int i = 0; i < 8; ++i) { @@ -646,8 +715,8 @@ public void test27(MyValue1[] src, MyValue1[] dst) { System.arraycopy(src, 1, dst, 2, 6); } - @DontCompile - public void test27_verifier(boolean warmup) { + @Run(test = "test27") + public void test27_verifier() { MyValue1[] src = new MyValue1[8]; MyValue1[] dst = new MyValue1[8]; for (int i = 0; i < 8; ++i) { @@ -659,10 +728,12 @@ public void test27_verifier(boolean warmup) { } } + // non escaping allocations // TODO 8252027: Make sure this is optimized with ZGC - @Test(valid = ZGCOff, failOn = ALLOCA + LOOP + LOAD + TRAP) - @Test(valid = ZGCOn) + @Test + @IR(applyIf = {"UseZGC", "false"}, + failOn = {ALLOCA, LOOP, LOAD, TRAP}) public MyValue2 test28() { MyValue2[] src = new MyValue2[10]; src[0] = MyValue2.createWithFieldsInline(rI, rD); @@ -670,26 +741,30 @@ public MyValue2 test28() { return dst[0]; } - @DontCompile - public void test28_verifier(boolean warmup) { + @Run(test = "test28") + public void test28_verifier() { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); MyValue2 result = test28(); Asserts.assertEQ(result.hash(), v.hash()); } + // non escaping allocations // TODO 8227588: shouldn't this have the same IR matching rules as test6? // @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) - @Test(valid = InlineTypeArrayFlattenOn, failOn = ALLOCA + LOOP + LOAD + TRAP) - @Test(valid = InlineTypeArrayFlattenOff, failOn = ALLOCA + LOOP + TRAP) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + failOn = {ALLOCA, LOOP, LOAD, TRAP}) + @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, + failOn = {ALLOCA, LOOP, TRAP}) public MyValue2 test29(MyValue2[] src) { MyValue2[] dst = new MyValue2[10]; System.arraycopy(src, 0, dst, 0, 10); return dst[0]; } - @DontCompile - public void test29_verifier(boolean warmup) { + @Run(test = "test29") + public void test29_verifier() { MyValue2[] src = new MyValue2[10]; for (int i = 0; i < 10; ++i) { src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); @@ -698,10 +773,10 @@ public void test29_verifier(boolean warmup) { Asserts.assertEQ(src[0].hash(), v.hash()); } + // non escaping allocation with uncommon trap that needs // eliminated inline type array element as debug info @Test - @Warmup(10000) public MyValue2 test30(MyValue2[] src, boolean flag) { MyValue2[] dst = new MyValue2[10]; System.arraycopy(src, 0, dst, 0, 10); @@ -709,18 +784,21 @@ public MyValue2 test30(MyValue2[] src, boolean flag) { return dst[0]; } - @DontCompile - public void test30_verifier(boolean warmup) { + @Run(test = "test30") + @Warmup(10000) + public void test30_verifier(RunInfo info) { MyValue2[] src = new MyValue2[10]; for (int i = 0; i < 10; ++i) { src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); } - MyValue2 v = test30(src, !warmup); + MyValue2 v = test30(src, !info.isWarmUp()); Asserts.assertEQ(src[0].hash(), v.hash()); } + // non escaping allocation with memory phi - @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) public long test31(boolean b, boolean deopt) { MyValue2[] src = new MyValue2[1]; if (b) { @@ -730,21 +808,23 @@ public long test31(boolean b, boolean deopt) { } if (deopt) { // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test31")); + Method m = testFramework.getTestMethod("test31"); + testFramework.deoptimize(m); } return src[0].hash(); } - @DontCompile - public void test31_verifier(boolean warmup) { + @Run(test = "test31") + public void test31_verifier(RunInfo info) { MyValue2 v1 = MyValue2.createWithFieldsInline(rI, rD); - long result1 = test31(true, !warmup); + long result1 = test31(true, !info.isWarmUp()); Asserts.assertEQ(result1, v1.hash()); - MyValue2 v2 = MyValue2.createWithFieldsInline(rI+1, rD+1); - long result2 = test31(false, !warmup); + MyValue2 v2 = MyValue2.createWithFieldsInline(rI + 1, rD + 1); + long result2 = test31(false, !info.isWarmUp()); Asserts.assertEQ(result2, v2.hash()); } + // Tests with Object arrays and clone/arraycopy // clone() as stub call @Test @@ -752,8 +832,8 @@ public Object[] test32(Object[] va) { return va.clone(); } - @DontCompile - public void test32_verifier(boolean warmup) { + @Run(test = "test32") + public void test32_verifier() { int len = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[len]; for (int i = 0; i < len; ++i) { @@ -770,8 +850,8 @@ public Object[] test33(Object[] va) { return va.clone(); } - @DontCompile - public void test33_verifier(boolean warmup) { + @Run(test = "test33") + public void test33_verifier() { int len = Math.abs(rI) % 10; Object[] va = new Object[len]; for (int i = 0; i < len; ++i) { @@ -809,8 +889,8 @@ public Object[] test34(boolean flag) { return va.clone(); } - @DontCompile - public void test34_verifier(boolean warmup) { + @Run(test = "test34") + public void test34_verifier(RunInfo info) { test34(false); for (int i = 0; i < 10; i++) { // make sure we do deopt Object[] result = test34(true); @@ -823,7 +903,7 @@ public void test34_verifier(boolean warmup) { // Expected } } - if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test34")) { + if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test34")) { Object[] result = test34(true); verify(test34_orig, result); // Check that array has correct properties (null-free) @@ -836,64 +916,14 @@ public void test34_verifier(boolean warmup) { } } - static void verify(Object[] src, Object[] dst) { - if (src instanceof MyInterface[] && dst instanceof MyInterface[]) { - for (int i = 0; i < src.length; ++i) { - Asserts.assertEQ(((MyInterface)src[i]).hash(), ((MyInterface)dst[i]).hash()); - } - } else { - for (int i = 0; i < src.length; ++i) { - Asserts.assertEQ(src[i], dst[i]); - } - } - } - - static void verify(MyValue1[] src, MyValue1[] dst) { - for (int i = 0; i < src.length; ++i) { - Asserts.assertEQ(src[i].hash(), dst[i].hash()); - } - } - - static void verify(MyValue1[] src, Object[] dst) { - for (int i = 0; i < src.length; ++i) { - Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); - } - } - - static void verify(MyValue2[] src, MyValue2[] dst) { - for (int i = 0; i < src.length; ++i) { - Asserts.assertEQ(src[i].hash(), dst[i].hash()); - } - } - - static void verify(MyValue2[] src, Object[] dst) { - for (int i = 0; i < src.length; ++i) { - Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); - } - } - - static boolean compile_and_run_again_if_deoptimized(boolean warmup, String test) { - if (!warmup) { - Method m = tests.get(test); - if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false)) { - if (!InlineTypeArrayFlatten && !XCOMP && !STRESS_CC) { - throw new RuntimeException("Unexpected deoptimization"); - } - enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); - return true; - } - } - return false; - } - // arraycopy() of inline type array of unknown size @Test public void test35(Object src, Object dst, int len) { System.arraycopy(src, 0, dst, 0, len); } - @DontCompile - public void test35_verifier(boolean warmup) { + @Run(test = "test35") + public void test35_verifier(RunInfo info) { int len = Math.abs(rI) % 10; MyValue1[] src = new MyValue1[len]; MyValue1[] dst1 = new MyValue1[len]; @@ -905,7 +935,7 @@ public void test35_verifier(boolean warmup) { verify(src, dst1); test35(src, dst2, src.length); verify(src, dst2); - if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test35")) { + if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test35")) { test35(src, dst1, src.length); verify(src, dst1); } @@ -916,8 +946,8 @@ public void test36(Object src, MyValue2[] dst) { System.arraycopy(src, 0, dst, 0, dst.length); } - @DontCompile - public void test36_verifier(boolean warmup) { + @Run(test = "test36") + public void test36_verifier(RunInfo info) { int len = Math.abs(rI) % 10; MyValue2[] src = new MyValue2[len]; MyValue2[] dst = new MyValue2[len]; @@ -926,7 +956,7 @@ public void test36_verifier(boolean warmup) { } test36(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test36")) { + if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test36")) { test36(src, dst); verify(src, dst); } @@ -937,8 +967,8 @@ public void test37(MyValue2[] src, Object dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test37_verifier(boolean warmup) { + @Run(test = "test37") + public void test37_verifier(RunInfo info) { int len = Math.abs(rI) % 10; MyValue2[] src = new MyValue2[len]; MyValue2[] dst = new MyValue2[len]; @@ -947,20 +977,21 @@ public void test37_verifier(boolean warmup) { } test37(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test37")) { + if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test37")) { test37(src, dst); verify(src, dst); } } + @Test - @Warmup(1) // Avoid early compilation public void test38(Object src, MyValue2[] dst) { System.arraycopy(src, 0, dst, 0, dst.length); } - @DontCompile - public void test38_verifier(boolean warmup) { + @Run(test = "test38") + @Warmup(1) // Avoid early compilation + public void test38_verifier(RunInfo info) { int len = Math.abs(rI) % 10; Object[] src = new Object[len]; MyValue2[] dst = new MyValue2[len]; @@ -969,25 +1000,24 @@ public void test38_verifier(boolean warmup) { } test38(src, dst); verify(dst, src); - if (!warmup) { - Method m = tests.get("TestArrays::test38"); - assertDeoptimizedByC2(m); - enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); + if (!info.isWarmUp()) { + Method m = testFramework.getTestMethod("test38"); + testFramework.assertDeoptimizedByC2(m); + testFramework.compile(m, CompLevel.C2); test38(src, dst); verify(dst, src); - if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP && !STRESS_CC) { - throw new RuntimeException("unexpected deoptimization"); - } + testFramework.assertCompiledByC2(m); } } + @Test public void test39(MyValue2[] src, Object dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test39_verifier(boolean warmup) { + @Run(test = "test39") + public void test39_verifier(RunInfo info) { int len = Math.abs(rI) % 10; MyValue2[] src = new MyValue2[len]; Object[] dst = new Object[len]; @@ -996,20 +1026,20 @@ public void test39_verifier(boolean warmup) { } test39(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test39")) { + if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test39")) { test39(src, dst); verify(src, dst); } } @Test - @Warmup(1) // Avoid early compilation public void test40(Object[] src, Object dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test40_verifier(boolean warmup) { + @Run(test = "test40") + @Warmup(1) // Avoid early compilation + public void test40_verifier(RunInfo info) { int len = Math.abs(rI) % 10; Object[] src = new Object[len]; MyValue2[] dst = new MyValue2[len]; @@ -1018,15 +1048,13 @@ public void test40_verifier(boolean warmup) { } test40(src, dst); verify(dst, src); - if (!warmup) { - Method m = tests.get("TestArrays::test40"); - assertDeoptimizedByC2(m); - enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); + if (!info.isWarmUp()) { + Method m = testFramework.getTestMethod("test40"); + testFramework.assertDeoptimizedByC2(m); + testFramework.compile(m, CompLevel.C2); test40(src, dst); verify(dst, src); - if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP && !STRESS_CC) { - throw new RuntimeException("unexpected deoptimization"); - } + testFramework.assertCompiledByC2(m); } } @@ -1035,8 +1063,8 @@ public void test41(Object src, Object[] dst) { System.arraycopy(src, 0, dst, 0, dst.length); } - @DontCompile - public void test41_verifier(boolean warmup) { + @Run(test = "test41") + public void test41_verifier(RunInfo info) { int len = Math.abs(rI) % 10; MyValue2[] src = new MyValue2[len]; Object[] dst = new Object[len]; @@ -1045,7 +1073,7 @@ public void test41_verifier(boolean warmup) { } test41(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test41")) { + if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test41")) { test41(src, dst); verify(src, dst); } @@ -1056,8 +1084,8 @@ public void test42(Object[] src, Object[] dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test42_verifier(boolean warmup) { + @Run(test = "test42") + public void test42_verifier(RunInfo info) { int len = Math.abs(rI) % 10; Object[] src = new Object[len]; Object[] dst = new Object[len]; @@ -1066,11 +1094,9 @@ public void test42_verifier(boolean warmup) { } test42(src, dst); verify(src, dst); - if (!warmup) { - Method m = tests.get("TestArrays::test42"); - if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP && !STRESS_CC) { - throw new RuntimeException("unexpected deoptimization"); - } + if (!info.isWarmUp()) { + Method m = testFramework.getTestMethod("test42"); + testFramework.assertCompiledByC2(m); } } @@ -1080,8 +1106,8 @@ public void test43(Object src, Object dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test43_verifier(boolean warmup) { + @Run(test = "test43") + public void test43_verifier(RunInfo info) { MyValue1[] src = new MyValue1[8]; MyValue1[] dst = new MyValue1[8]; for (int i = 0; i < 8; ++i) { @@ -1089,7 +1115,7 @@ public void test43_verifier(boolean warmup) { } test43(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test43")) { + if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test43")) { test43(src, dst); verify(src, dst); } @@ -1100,8 +1126,8 @@ public void test44(Object src, MyValue2[] dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test44_verifier(boolean warmup) { + @Run(test = "test44") + public void test44_verifier(RunInfo info) { MyValue2[] src = new MyValue2[8]; MyValue2[] dst = new MyValue2[8]; for (int i = 0; i < 8; ++i) { @@ -1109,7 +1135,7 @@ public void test44_verifier(boolean warmup) { } test44(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test44")) { + if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test44")) { test44(src, dst); verify(src, dst); } @@ -1120,8 +1146,8 @@ public void test45(MyValue2[] src, Object dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test45_verifier(boolean warmup) { + @Run(test = "test45") + public void test45_verifier(RunInfo info) { MyValue2[] src = new MyValue2[8]; MyValue2[] dst = new MyValue2[8]; for (int i = 0; i < 8; ++i) { @@ -1129,20 +1155,20 @@ public void test45_verifier(boolean warmup) { } test45(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test45")) { + if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test45")) { test45(src, dst); verify(src, dst); } } @Test - @Warmup(1) // Avoid early compilation public void test46(Object[] src, MyValue2[] dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test46_verifier(boolean warmup) { + @Run(test = "test46") + @Warmup(1) // Avoid early compilation + public void test46_verifier(RunInfo info) { Object[] src = new Object[8]; MyValue2[] dst = new MyValue2[8]; for (int i = 0; i < 8; ++i) { @@ -1150,15 +1176,13 @@ public void test46_verifier(boolean warmup) { } test46(src, dst); verify(dst, src); - if (!warmup) { - Method m = tests.get("TestArrays::test46"); - assertDeoptimizedByC2(m); - enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); + if (!info.isWarmUp()) { + Method m = testFramework.getTestMethod("test46"); + testFramework.assertDeoptimizedByC2(m); + testFramework.compile(m, CompLevel.C2); test46(src, dst); verify(dst, src); - if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP && !STRESS_CC) { - throw new RuntimeException("unexpected deoptimization"); - } + testFramework.assertCompiledByC2(m); } } @@ -1167,8 +1191,8 @@ public void test47(MyValue2[] src, Object[] dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test47_verifier(boolean warmup) { + @Run(test = "test47") + public void test47_verifier(RunInfo info) { MyValue2[] src = new MyValue2[8]; Object[] dst = new Object[8]; for (int i = 0; i < 8; ++i) { @@ -1176,20 +1200,20 @@ public void test47_verifier(boolean warmup) { } test47(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test47")) { + if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test47")) { test47(src, dst); verify(src, dst); } } @Test - @Warmup(1) // Avoid early compilation public void test48(Object[] src, Object dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test48_verifier(boolean warmup) { + @Run(test = "test48") + @Warmup(1) // Avoid early compilation + public void test48_verifier(RunInfo info) { Object[] src = new Object[8]; MyValue2[] dst = new MyValue2[8]; for (int i = 0; i < 8; ++i) { @@ -1197,15 +1221,13 @@ public void test48_verifier(boolean warmup) { } test48(src, dst); verify(dst, src); - if (!warmup) { - Method m = tests.get("TestArrays::test48"); - assertDeoptimizedByC2(m); - enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); + if (!info.isWarmUp()) { + Method m = testFramework.getTestMethod("test48"); + testFramework.assertDeoptimizedByC2(m); + testFramework.compile(m, CompLevel.C2); test48(src, dst); verify(dst, src); - if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP && !STRESS_CC) { - throw new RuntimeException("unexpected deoptimization"); - } + testFramework.assertCompiledByC2(m); } } @@ -1214,8 +1236,8 @@ public void test49(Object src, Object[] dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test49_verifier(boolean warmup) { + @Run(test = "test49") + public void test49_verifier(RunInfo info) { MyValue2[] src = new MyValue2[8]; Object[] dst = new Object[8]; for (int i = 0; i < 8; ++i) { @@ -1223,7 +1245,7 @@ public void test49_verifier(boolean warmup) { } test49(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test49")) { + if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test49")) { test49(src, dst); verify(src, dst); } @@ -1234,8 +1256,8 @@ public void test50(Object[] src, Object[] dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test50_verifier(boolean warmup) { + @Run(test = "test50") + public void test50_verifier(RunInfo info) { Object[] src = new Object[8]; Object[] dst = new Object[8]; for (int i = 0; i < 8; ++i) { @@ -1243,11 +1265,9 @@ public void test50_verifier(boolean warmup) { } test50(src, dst); verify(src, dst); - if (!warmup) { - Method m = tests.get("TestArrays::test50"); - if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP && !STRESS_CC) { - throw new RuntimeException("unexpected deoptimization"); - } + if (!info.isWarmUp()) { + Method m = testFramework.getTestMethod("test50"); + testFramework.assertCompiledByC2(m); } } @@ -1258,8 +1278,8 @@ public MyValue1[] test51(MyValue1[] va) { return (MyValue1[]) res; } - @DontCompile - public void test51_verifier(boolean warmup) { + @Run(test = "test51") + public void test51_verifier() { int len = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[len]; for (int i = 0; i < len; ++i) { @@ -1278,8 +1298,8 @@ public MyValue1[] test52() { return (MyValue1[]) res; } - @DontCompile - public void test52_verifier(boolean warmup) { + @Run(test = "test52") + public void test52_verifier() { for (int i = 0; i < 8; ++i) { test52_va[i] = MyValue1.createWithFieldsInline(rI, rL); } @@ -1294,8 +1314,8 @@ public MyValue1[] test53(Object[] va) { return (MyValue1[]) res; } - @DontCompile - public void test53_verifier(boolean warmup) { + @Run(test = "test53") + public void test53_verifier() { int len = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[len]; for (int i = 0; i < len; ++i) { @@ -1310,8 +1330,8 @@ public Object[] test54(MyValue1[] va) { return Arrays.copyOf(va, va.length, Object[].class); } - @DontCompile - public void test54_verifier(boolean warmup) { + @Run(test = "test54") + public void test54_verifier() { int len = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[len]; for (int i = 0; i < len; ++i) { @@ -1326,8 +1346,8 @@ public Object[] test55(Object[] va) { return Arrays.copyOf(va, va.length, Object[].class); } - @DontCompile - public void test55_verifier(boolean warmup) { + @Run(test = "test55") + public void test55_verifier() { int len = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[len]; for (int i = 0; i < len; ++i) { @@ -1344,8 +1364,8 @@ public MyValue1[] test56(Object[] va) { return (MyValue1[]) res; } - @DontCompile - public void test56_verifier(boolean warmup) { + @Run(test = "test56") + public void test56_verifier() { int len = Math.abs(rI) % 10; Object[] va = new Object[len]; for (int i = 0; i < len; ++i) { @@ -1355,13 +1375,13 @@ public void test56_verifier(boolean warmup) { verify(result, va); } - @Test + @Test public Object[] test57(Object[] va, Class klass) { return Arrays.copyOf(va, va.length, klass); } - @DontCompile - public void test57_verifier(boolean warmup) { + @Run(test = "test57") + public void test57_verifier() { int len = Math.abs(rI) % 10; Object[] va = new MyValue1[len]; for (int i = 0; i < len; ++i) { @@ -1376,8 +1396,8 @@ public Object[] test58(MyValue1[] va, Class klass) { return Arrays.copyOf(va, va.length, klass); } - @DontCompile - public void test58_verifier(boolean warmup) { + @Run(test = "test58") + public void test58_verifier(RunInfo info) { int len = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[len]; for (int i = 0; i < len; ++i) { @@ -1387,7 +1407,7 @@ public void test58_verifier(boolean warmup) { Object[] result = test58(va, MyValue1[].class); verify(va, result); } - if (compile_and_run_again_if_deoptimized(warmup, "TestArrays::test58")) { + if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test58")) { Object[] result = test58(va, MyValue1[].class); verify(va, result); } @@ -1398,8 +1418,8 @@ public Object[] test59(MyValue1[] va) { return Arrays.copyOf(va, va.length+1, MyValue1[].class); } - @DontCompile - public void test59_verifier(boolean warmup) { + @Run(test = "test59") + public void test59_verifier() { int len = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[len]; MyValue1[] verif = new MyValue1[len+1]; @@ -1416,8 +1436,8 @@ public Object[] test60(Object[] va, Class klass) { return Arrays.copyOf(va, va.length+1, klass); } - @DontCompile - public void test60_verifier(boolean warmup) { + @Run(test = "test60") + public void test60_verifier() { int len = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[len]; MyValue1[] verif = new MyValue1[len+1]; @@ -1434,8 +1454,8 @@ public Object[] test61(Object[] va, Class klass) { return Arrays.copyOf(va, va.length+1, klass); } - @DontCompile - public void test61_verifier(boolean warmup) { + @Run(test = "test61") + public void test61_verifier() { int len = Math.abs(rI) % 10; Object[] va = new Integer[len]; for (int i = 0; i < len; ++i) { @@ -1468,8 +1488,8 @@ public Object[] test62(MyValue1[] va, Integer[] oa) { return Arrays.copyOf(arr, arr.length+1, arr.getClass()); } - @DontCompile - public void test62_verifier(boolean warmup) { + @Run(test = "test62") + public void test62_verifier() { int len = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[len]; Integer[] oa = new Integer[len]; @@ -1504,8 +1524,8 @@ public Object[] test63(MyValue1[] va, Integer[] oa) { return Arrays.copyOf(arr, arr.length+1, arr.getClass()); } - @DontCompile - public void test63_verifier(boolean warmup) { + @Run(test = "test63") + public void test63_verifier() { int len = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[len]; MyValue1[] verif = new MyValue1[len+1]; @@ -1525,8 +1545,8 @@ public MyValue1[] test64() { return new MyValue1[8]; } - @DontCompile - public void test64_verifier(boolean warmup) { + @Run(test = "test64") + public void test64_verifier() { MyValue1[] va = new MyValue1[8]; MyValue1[] var = test64(); for (int i = 0; i < 8; ++i) { @@ -1540,8 +1560,8 @@ public MyValue1[] test65() { return new MyValue1[32]; } - @DontCompile - public void test65_verifier(boolean warmup) { + @Run(test = "test65") + public void test65_verifier() { MyValue1[] va = new MyValue1[32]; MyValue1[] var = test65(); for (int i = 0; i < 32; ++i) { @@ -1550,15 +1570,16 @@ public void test65_verifier(boolean warmup) { } // Check init store elimination - @Test(match = { ALLOCA }, matchCount = { 1 }) + @Test + @IR(counts = {ALLOCA, "= 1"}) public MyValue1[] test66(MyValue1 vt) { MyValue1[] va = new MyValue1[1]; va[0] = vt; return va; } - @DontCompile - public void test66_verifier(boolean warmup) { + @Run(test = "test66") + public void test66_verifier() { MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL); MyValue1[] va = test66(vt); Asserts.assertEQ(va[0].hashPrimitive(), vt.hashPrimitive()); @@ -1572,8 +1593,8 @@ public MyValue1[] test67(MyValue1[] src) { return dst; } - @DontCompile - public void test67_verifier(boolean warmup) { + @Run(test = "test67") + public void test67_verifier() { MyValue1[] va = new MyValue1[16]; MyValue1[] var = test67(va); for (int i = 0; i < 16; ++i) { @@ -1589,8 +1610,8 @@ public MyValue1[] test68() { return va; } - @DontCompile - public void test68_verifier(boolean warmup) { + @Run(test = "test68") + public void test68_verifier() { MyValue1[] va = new MyValue1[2]; MyValue1[] var = test68(); for (int i = 0; i < 2; ++i) { @@ -1607,8 +1628,8 @@ public MyValue1[] test69(MyValue1 vt) { return va; } - @DontCompile - public void test69_verifier(boolean warmup) { + @Run(test = "test69") + public void test69_verifier() { MyValue1 vt = MyValue1.createWithFieldsDontInline(rI, rL); MyValue1[] va = new MyValue1[4]; va[0] = vt; @@ -1630,8 +1651,8 @@ public MyValue1[] test70(MyValue1[] other) { return va; } - @DontCompile - public void test70_verifier(boolean warmup) { + @Run(test = "test70") + public void test70_verifier() { MyValue1[] va = new MyValue1[2]; MyValue1[] var = test70(va); for (int i = 0; i < 2; ++i) { @@ -1654,8 +1675,8 @@ public void test71() { } } - @DontCompile - public void test71_verifier(boolean warmup) { + @Run(test = "test71") + public void test71_verifier() { test71(); } @@ -1671,8 +1692,8 @@ public void test72(Object[] o, boolean b, Object element) { arr2[0] = element; } - @DontCompile - public void test72_verifier(boolean warmup) { + @Run(test = "test72") + public void test72_verifier() { Object[] arr = new Object[1]; Object elem = new Object(); test72(arr, true, elem); @@ -1690,8 +1711,8 @@ public void test73(Object[] oa, MyValue1 v, Object o) { oa[0] = oa; // The stored value is known to be not flattenable (an Object[]) } - @DontCompile - public void test73_verifier(boolean warmup) { + @Run(test = "test73") + public void test73_verifier() { MyValue1 v0 = MyValue1.createWithFieldsDontInline(rI, rL); MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1); MyValue1[] arr = new MyValue1[3]; @@ -1710,13 +1731,13 @@ public static void test74Callee(MyValue1[] va) { } // Tests invoking unloaded method with inline type array in signature @Test - @Warmup(0) public void test74(MethodHandle m, MyValue1[] va) throws Throwable { m.invoke(va); } - @DontCompile - public void test74_verifier(boolean warmup) throws Throwable { + @Run(test = "test74") + @Warmup(0) + public void test74_verifier() throws Throwable { MethodHandle m = MethodHandles.lookup().findStatic(TestArrays.class, "test74Callee", MethodType.methodType(void.class, MyValue1[].class)); MyValue1[] va = new MyValue1[0]; test74(m, va); @@ -1743,8 +1764,8 @@ public Object[] test75(MyValue1[] va, Integer[] oa) { return arr.clone(); } - @DontCompile - public void test75_verifier(boolean warmup) { + @Run(test = "test75") + public void test75_verifier() { int len = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[len]; Integer[] oa = new Integer[len]; @@ -1781,8 +1802,8 @@ public Object[] test76(MyValue1[] va, Integer[] oa) { return arr.clone(); } - @DontCompile - public void test76_verifier(boolean warmup) { + @Run(test = "test76") + public void test76_verifier() { int len = Math.abs(rI) % 10; MyValue1[] va = new MyValue1[len]; MyValue1[] verif = new MyValue1[len]; @@ -1821,8 +1842,8 @@ public void test77() { } - @DontCompile - public void test77_verifier(boolean warmup) { + @Run(test = "test77") + public void test77_verifier() { test77(); } @@ -1841,23 +1862,26 @@ public long test78(MyValue1 v, int n) { return x; } - @DontCompile - public void test78_verifier(boolean warmup) { + @Run(test = "test78") + public void test78_verifier() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); Asserts.assertEQ(test78(v, 1), v.hash()); } // Verify that casting an array element to a non-flattenable type marks the array as not-flat - @Test(valid = InlineTypeArrayFlattenOn, match = { ALLOC_G, LOAD_UNKNOWN_INLINE }, matchCount = { 1, 1 }) - @Test(valid = InlineTypeArrayFlattenOff, failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_INLINE) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + counts = {ALLOC_G, "= 1", LOAD_UNKNOWN_INLINE, "= 1"}) + @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, + failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE}) public Object test79(Object[] array, int i) { Integer i1 = (Integer)array[0]; Object o = array[1]; return array[i]; } - @DontCompile - public void test79_verifier(boolean warmup) { + @Run(test = "test79") + public void test79_verifier() { Integer i = Integer.valueOf(rI); Integer[] array = new Integer[2]; array[1] = i; @@ -1865,26 +1889,20 @@ public void test79_verifier(boolean warmup) { Asserts.assertEquals(result, i); } - primitive static class NotFlattenable { - private final Object o1 = null; - private final Object o2 = null; - private final Object o3 = null; - private final Object o4 = null; - private final Object o5 = null; - private final Object o6 = null; - } - // Same as test79 but with not-flattenable inline type - @Test(valid = InlineTypeArrayFlattenOn, match = { ALLOC_G, LOAD_UNKNOWN_INLINE }, matchCount = { 1, 1 }) - @Test(valid = InlineTypeArrayFlattenOff, failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_INLINE) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + counts = {ALLOC_G, "= 1", LOAD_UNKNOWN_INLINE, "= 1"}) + @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, + failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE}) public Object test80(Object[] array, int i) { NotFlattenable vt = (NotFlattenable)array[0]; Object o = array[1]; return array[i]; } - @DontCompile - public void test80_verifier(boolean warmup) { + @Run(test = "test80") + public void test80_verifier() { NotFlattenable vt = new NotFlattenable(); NotFlattenable[] array = new NotFlattenable[2]; array[1] = vt; @@ -1893,7 +1911,8 @@ public void test80_verifier(boolean warmup) { } // Verify that writing an object of a non-inline, non-null type to an array marks the array as not-null-free and not-flat - @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD) + @Test + @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) public Object test81(Object[] array, Integer v, Object o, int i) { if (v == null) { return null; @@ -1904,8 +1923,8 @@ public Object test81(Object[] array, Integer v, Object o, int i) { return array[i]; } - @DontCompile - public void test81_verifier(boolean warmup) { + @Run(test = "test81") + public void test81_verifier() { Integer i = Integer.valueOf(rI); Integer[] array1 = new Integer[3]; Object[] array2 = new Object[3]; @@ -1922,8 +1941,11 @@ public void test81_verifier(boolean warmup) { } // Verify that writing an object of a non-flattenable inline type to an array marks the array as not-flat - @Test(valid = InlineTypePassFieldsAsArgsOn, failOn = ALLOCA_G + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE) - @Test(valid = InlineTypePassFieldsAsArgsOff, failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE) + @Test + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"}, + failOn = {ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE}) + @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, + failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE}) public Object test82(Object[] array, NotFlattenable vt, Object o, int i) { array[0] = vt; array[1] = array[0]; @@ -1931,8 +1953,8 @@ public Object test82(Object[] array, NotFlattenable vt, Object o, int i) { return array[i]; } - @DontCompile - public void test82_verifier(boolean warmup) { + @Run(test = "test82") + public void test82_verifier() { NotFlattenable vt = new NotFlattenable(); NotFlattenable[] array1 = new NotFlattenable[3]; Object[] array2 = new Object[3]; @@ -1949,15 +1971,19 @@ public void test82_verifier(boolean warmup) { } // Verify that casting an array element to a non-inline type type marks the array as not-null-free and not-flat - @Test(valid = InlineTypeArrayFlattenOn, match = { ALLOC_G, LOAD_UNKNOWN_INLINE }, matchCount = { 1, 1 }, failOn = ALLOCA_G + STORE_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD) - @Test(valid = InlineTypeArrayFlattenOff, failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + counts = {ALLOC_G, "= 1", LOAD_UNKNOWN_INLINE, "= 1"}, + failOn = {ALLOCA_G, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) + @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, + failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) public void test83(Object[] array, Object o) { Integer i = (Integer)array[0]; array[1] = o; } - @DontCompile - public void test83_verifier(boolean warmup) { + @Run(test = "test83") + public void test83_verifier() { Integer i = Integer.valueOf(rI); Integer[] array1 = new Integer[2]; Object[] array2 = new Object[2]; @@ -1968,15 +1994,17 @@ public void test83_verifier(boolean warmup) { } // Verify that writing constant null into an array marks the array as not-null-free and not-flat - @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE, match = { INLINE_ARRAY_NULL_GUARD }, matchCount = { 1 }) + @Test + @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE}, + counts = {INLINE_ARRAY_NULL_GUARD, "= 1"}) public Object test84(Object[] array, int i) { array[0] = null; array[1] = null; return array[i]; } - @DontCompile - public void test84_verifier(boolean warmup) { + @Run(test = "test84") + public void test84_verifier(RunInfo info) { NotFlattenable.ref[] array1 = new NotFlattenable.ref[2]; Object[] array2 = new Object[2]; Object result = test84(array1, 0); @@ -1985,7 +2013,7 @@ public void test84_verifier(boolean warmup) { result = test84(array2, 1); Asserts.assertEquals(array2[0], null); Asserts.assertEquals(result, null); - if (!warmup) { + if (!info.isWarmUp()) { NotFlattenable[] array3 = new NotFlattenable[2]; try { test84(array3, 1); @@ -1997,7 +2025,9 @@ public void test84_verifier(boolean warmup) { } // Same as test84 but with branches - @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE, match = { INLINE_ARRAY_NULL_GUARD }, matchCount = { 2 }) + @Test + @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE}, + counts = {INLINE_ARRAY_NULL_GUARD, "= 2"}) public void test85(Object[] array, Object o, boolean b) { if (b) { array[0] = null; @@ -2007,8 +2037,8 @@ public void test85(Object[] array, Object o, boolean b) { array[1] = o; } - @DontCompile - public void test85_verifier(boolean warmup) { + @Run(test = "test85") + public void test85_verifier(RunInfo info) { Integer i = Integer.valueOf(rI); Integer[] array1 = new Integer[2]; Object[] array2 = new Object[2]; @@ -2020,7 +2050,7 @@ public void test85_verifier(boolean warmup) { Asserts.assertEquals(array2[1], i); test85(array2, null, false); Asserts.assertEquals(array2[1], null); - if (!warmup) { + if (!info.isWarmUp()) { NotFlattenable[] array3 = new NotFlattenable[2]; try { test85(array3, null, true); @@ -2032,7 +2062,9 @@ public void test85_verifier(boolean warmup) { } // Same as test85 but with not-flattenable inline type array - @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE, match = { INLINE_ARRAY_NULL_GUARD }, matchCount = { 2 }) + @Test + @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE}, + counts = {INLINE_ARRAY_NULL_GUARD, "= 2"}) public void test86(NotFlattenable.ref[] array, NotFlattenable.ref o, boolean b) { if (b) { array[0] = null; @@ -2042,15 +2074,15 @@ public void test86(NotFlattenable.ref[] array, NotFlattenable.ref o, boolean b) array[1] = o; } - @DontCompile - public void test86_verifier(boolean warmup) { + @Run(test = "test86") + public void test86_verifier(RunInfo info) { NotFlattenable vt = new NotFlattenable(); NotFlattenable.ref[] array1 = new NotFlattenable.ref[2]; test86(array1, vt, true); Asserts.assertEquals(array1[1], vt); test86(array1, null, false); Asserts.assertEquals(array1[1], null); - if (!warmup) { + if (!info.isWarmUp()) { NotFlattenable[] array2 = new NotFlattenable[2]; try { test86(array2, null, true); @@ -2062,7 +2094,9 @@ public void test86_verifier(boolean warmup) { } // Same as test85 but with inline type array - @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE, match = { INLINE_ARRAY_NULL_GUARD }, matchCount = { 2 }) + @Test + @IR(failOn = {ALLOC_G, ALLOCA_G, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE}, + counts = {INLINE_ARRAY_NULL_GUARD, "= 2"}) public void test87(MyValue1.ref[] array, MyValue1.ref o, boolean b) { if (b) { array[0] = null; @@ -2072,15 +2106,15 @@ public void test87(MyValue1.ref[] array, MyValue1.ref o, boolean b) { array[1] = o; } - @DontCompile - public void test87_verifier(boolean warmup) { + @Run(test = "test87") + public void test87_verifier(RunInfo info) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); MyValue1.ref[] array1 = new MyValue1.ref[2]; test87(array1, vt, true); Asserts.assertEquals(array1[1], vt); test87(array1, null, false); Asserts.assertEquals(array1[1], null); - if (!warmup) { + if (!info.isWarmUp()) { MyValue1[] array2 = new MyValue1[2]; try { test87(array2, null, true); @@ -2097,15 +2131,15 @@ public void test88(Object[] array, Integer v) { array[0] = v; } - @DontCompile - public void test88_verifier(boolean warmup) { + @Run(test = "test88") + public void test88_verifier(RunInfo info) { Integer[] array1 = new Integer[1]; Object[] array2 = new Object[1]; test88(array1, null); Asserts.assertEquals(array1[0], null); test88(array2, null); Asserts.assertEquals(array2[0], null); - if (!warmup) { + if (!info.isWarmUp()) { MyValue1[] array3 = new MyValue1[1]; try { test88(array3, null); @@ -2122,12 +2156,12 @@ public void test89(MyValue1.ref[] array, Integer v) { array[0] = (MyValue1.ref)o; } - @DontCompile - public void test89_verifier(boolean warmup) { + @Run(test = "test89") + public void test89_verifier(RunInfo info) { MyValue1.ref[] array1 = new MyValue1.ref[1]; test89(array1, null); Asserts.assertEquals(array1[0], null); - if (!warmup) { + if (!info.isWarmUp()) { MyValue1[] array2 = new MyValue1[1]; try { test89(array2, null); @@ -2157,8 +2191,8 @@ public boolean test90() { return b; } - @DontCompile - public void test90_verifier(boolean warmup) { + @Run(test = "test90") + public void test90_verifier() { Asserts.assertEQ(test90(), true); } @@ -2188,7 +2222,6 @@ public void verify() { // Test anti-dependencies between loads and stores from flattened array @Test - @Warmup(0) public int test91(Test91Value[] array, int lo, int val) { int i = 3; while (lo < i) { @@ -2199,8 +2232,9 @@ public int test91(Test91Value[] array, int lo, int val) { return val; } - @DontCompile - public void test91_verifier(boolean warmup) { + @Run(test = "test91") + @Warmup(0) + public void test91_verifier() { Test91Value[] array = new Test91Value[5]; for (int i = 0; i < 5; ++i) { array[i] = new Test91Value(i); @@ -2217,8 +2251,8 @@ public void test92(Object[] src, Object[] dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test92_verifier(boolean warmup) { + @Run(test = "test92") + public void test92_verifier() { MyValue1[] a = new MyValue1[1]; MyValue1[] b = new MyValue1[1]; try { @@ -2238,7 +2272,6 @@ public void test92_verifier(boolean warmup) { // Same as test30 but accessing all elements of the non-escaping array @Test - @Warmup(10000) public long test93(MyValue2[] src, boolean flag) { MyValue2[] dst = new MyValue2[10]; System.arraycopy(src, 0, dst, 0, 10); @@ -2247,13 +2280,14 @@ public long test93(MyValue2[] src, boolean flag) { dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash(); } - @DontCompile - public void test93_verifier(boolean warmup) { + @Run(test = "test93") + @Warmup(10000) + public void test93_verifier(RunInfo info) { MyValue2[] src = new MyValue2[10]; for (int i = 0; i < 10; ++i) { src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); } - long res = test93(src, !warmup); + long res = test93(src, !info.isWarmUp()); long expected = 0; for (int i = 0; i < 10; ++i) { expected += src[i].hash(); @@ -2263,7 +2297,6 @@ public void test93_verifier(boolean warmup) { // Same as test93 but with variable source array offset @Test - @Warmup(10000) public long test94(MyValue2[] src, int i, boolean flag) { MyValue2[] dst = new MyValue2[10]; System.arraycopy(src, i, dst, 0, 1); @@ -2272,21 +2305,23 @@ public long test94(MyValue2[] src, int i, boolean flag) { dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash(); } - @DontCompile - public void test94_verifier(boolean warmup) { + @Run(test = "test94") + @Warmup(10000) + public void test94_verifier(RunInfo info) { MyValue2[] src = new MyValue2[10]; for (int i = 0; i < 10; ++i) { src[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); } for (int i = 0; i < 10; ++i) { - long res = test94(src, i, !warmup); + long res = test94(src, i, !info.isWarmUp()); long expected = src[i].hash() + 9*MyValue2.default.hash(); Asserts.assertEQ(res, expected); } } // Test propagation of not null-free/flat information - @Test(failOn = CHECKCAST_ARRAY) + @Test + @IR(failOn = {CHECKCAST_ARRAY}) public MyValue1[] test95(Object[] array) { array[0] = null; // Always throws a ClassCastException because we just successfully @@ -2294,8 +2329,8 @@ public MyValue1[] test95(Object[] array) { return (MyValue1[])array; } - @DontCompile - public void test95_verifier(boolean warmup) { + @Run(test = "test95") + public void test95_verifier() { MyValue1[] array1 = new MyValue1[1]; Integer[] array2 = new Integer[1]; try { @@ -2313,7 +2348,8 @@ public void test95_verifier(boolean warmup) { } // Same as test95 but with cmp user of cast result - @Test(failOn = CHECKCAST_ARRAY) + @Test + @IR(failOn = {CHECKCAST_ARRAY}) public boolean test96(Object[] array) { array[0] = null; // Always throws a ClassCastException because we just successfully @@ -2322,8 +2358,8 @@ public boolean test96(Object[] array) { return casted != null; } - @DontCompile - public void test96_verifier(boolean warmup) { + @Run(test = "test96") + public void test96_verifier() { MyValue1[] array1 = new MyValue1[1]; Integer[] array2 = new Integer[1]; try { @@ -2341,7 +2377,8 @@ public void test96_verifier(boolean warmup) { } // Same as test95 but with instanceof instead of cast - @Test(failOn = CHECKCAST_ARRAY) + @Test + @IR(failOn = {CHECKCAST_ARRAY}) public boolean test97(Object[] array) { array[0] = 42; // Always throws a ClassCastException because we just successfully stored @@ -2349,8 +2386,8 @@ public boolean test97(Object[] array) { return array instanceof MyValue1[]; } - @DontCompile - public void test97_verifier(boolean warmup) { + @Run(test = "test97") + public void test97_verifier() { MyValue1[] array1 = new MyValue1[1]; Integer[] array2 = new Integer[1]; try { @@ -2364,8 +2401,9 @@ public void test97_verifier(boolean warmup) { } // Same as test95 but with non-flattenable store - @Test(valid = InlineTypeArrayFlattenOn, failOn = CHECKCAST_ARRAY) - @Test(valid = InlineTypeArrayFlattenOff) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + failOn = {CHECKCAST_ARRAY}) public MyValue1[] test98(Object[] array) { array[0] = NotFlattenable.default; // Always throws a ClassCastException because we just successfully stored a @@ -2373,8 +2411,8 @@ public MyValue1[] test98(Object[] array) { return (MyValue1[])array; } - @DontCompile - public void test98_verifier(boolean warmup) { + @Run(test = "test98") + public void test98_verifier() { MyValue1[] array1 = new MyValue1[1]; NotFlattenable[] array2 = new NotFlattenable[1]; try { @@ -2392,8 +2430,9 @@ public void test98_verifier(boolean warmup) { } // Same as test98 but with cmp user of cast result - @Test(valid = InlineTypeArrayFlattenOn, failOn = CHECKCAST_ARRAY) - @Test(valid = InlineTypeArrayFlattenOff) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + failOn = {CHECKCAST_ARRAY}) public boolean test99(Object[] array) { array[0] = NotFlattenable.default; // Always throws a ClassCastException because we just successfully stored a @@ -2402,8 +2441,8 @@ public boolean test99(Object[] array) { return casted != null; } - @DontCompile - public void test99_verifier(boolean warmup) { + @Run(test = "test99") + public void test99_verifier() { MyValue1[] array1 = new MyValue1[1]; NotFlattenable[] array2 = new NotFlattenable[1]; try { @@ -2421,8 +2460,9 @@ public void test99_verifier(boolean warmup) { } // Same as test98 but with instanceof instead of cast - @Test(valid = InlineTypeArrayFlattenOn, failOn = CHECKCAST_ARRAY) - @Test(valid = InlineTypeArrayFlattenOff) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + failOn = {CHECKCAST_ARRAY}) public boolean test100(Object[] array) { array[0] = NotFlattenable.default; // Always throws a ClassCastException because we just successfully stored a @@ -2430,8 +2470,8 @@ public boolean test100(Object[] array) { return array instanceof MyValue1[]; } - @DontCompile - public void test100_verifier(boolean warmup) { + @Run(test = "test100") + public void test100_verifier() { MyValue1[] array1 = new MyValue1[1]; NotFlattenable[] array2 = new NotFlattenable[1]; try { @@ -2445,13 +2485,14 @@ public void test100_verifier(boolean warmup) { } // Test that CHECKCAST_ARRAY matching works as expected - @Test(match = { CHECKCAST_ARRAY }, matchCount = { 1 }) + @Test + @IR(counts = { CHECKCAST_ARRAY, "= 1" }) public boolean test101(Object[] array) { return array instanceof MyValue1[]; } - @DontCompile - public void test101_verifier(boolean warmup) { + @Run(test = "test101") + public void test101_verifier() { MyValue1[] array1 = new MyValue1[1]; NotFlattenable[] array2 = new NotFlattenable[1]; Asserts.assertTrue(test101(array1)); @@ -2483,62 +2524,69 @@ public void test101_verifier(boolean warmup) { } // Arraycopy with constant source and destination arrays - @Test(valid = InlineTypeArrayFlattenOn, match = { INTRINSIC_SLOW_PATH }, matchCount = { 1 }) - @Test(valid = InlineTypeArrayFlattenOff, failOn = INTRINSIC_SLOW_PATH) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + counts = {INTRINSIC_SLOW_PATH, "= 1"}) + @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, + failOn = {INTRINSIC_SLOW_PATH}) public void test102() { System.arraycopy(val_src, 0, obj_dst, 0, 8); } - @DontCompile - public void test102_verifier(boolean warmup) { + @Run(test = "test102") + public void test102_verifier() { test102(); verify(val_src, obj_dst); } // Same as test102 but with MyValue2[] dst - @Test(failOn = INTRINSIC_SLOW_PATH) + @Test + @IR(failOn = INTRINSIC_SLOW_PATH) public void test103() { System.arraycopy(val_src, 0, val_dst, 0, 8); } - @DontCompile - public void test103_verifier(boolean warmup) { + @Run(test = "test103") + public void test103_verifier() { test103(); verify(val_src, val_dst); } // Same as test102 but with Object[] src - @Test(failOn = INTRINSIC_SLOW_PATH) + @Test + @IR(failOn = INTRINSIC_SLOW_PATH) public void test104() { System.arraycopy(obj_src, 0, obj_dst, 0, 8); } - @DontCompile - public void test104_verifier(boolean warmup) { + @Run(test = "test104") + public void test104_verifier() { test104(); verify(obj_src, obj_dst); } // Same as test103 but with Object[] src - @Test(match = { INTRINSIC_SLOW_PATH }, matchCount = { 1 }) + @Test + @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"}) public void test105() { System.arraycopy(obj_src, 0, val_dst, 0, 8); } - @DontCompile - public void test105_verifier(boolean warmup) { + @Run(test = "test105") + public void test105_verifier() { test105(); verify(obj_src, val_dst); } // Same as test103 but with Object[] src containing null - @Test(match = { INTRINSIC_SLOW_PATH }, matchCount = { 1 }) + @Test + @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"}) public void test105_null() { System.arraycopy(obj_null_src, 0, val_dst, 0, 8); } - @DontCompile - public void test105_null_verifier(boolean warmup) { + @Run(test = "test105_null") + public void test105_null_verifier() { try { test105_null(); throw new RuntimeException("NullPointerException expected"); @@ -2549,62 +2597,68 @@ public void test105_null_verifier(boolean warmup) { // Below tests are equal to test102-test105 but hide the src/dst types until // after the arraycopy intrinsic is emitted (with incremental inlining). - - @Test(valid = InlineTypeArrayFlattenOn, match = { INTRINSIC_SLOW_PATH }, matchCount = { 1 }) - @Test(valid = InlineTypeArrayFlattenOff, failOn = INTRINSIC_SLOW_PATH) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + counts = {INTRINSIC_SLOW_PATH, "= 1"}) + @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, + failOn = {INTRINSIC_SLOW_PATH}) public void test106() { System.arraycopy(get_val_src(), 0, get_obj_dst(), 0, 8); } - @DontCompile - public void test106_verifier(boolean warmup) { + @Run(test = "test106") + public void test106_verifier() { test106(); verify(val_src, obj_dst); } // TODO 8251971: Should be optimized but we are bailing out because // at parse time it looks as if src could be flat and dst could be not flat. - @Test(valid = InlineTypeArrayFlattenOn) - @Test(valid = InlineTypeArrayFlattenOff, failOn = INTRINSIC_SLOW_PATH) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, + failOn = {INTRINSIC_SLOW_PATH}) public void test107() { System.arraycopy(get_val_src(), 0, get_val_dst(), 0, 8); } - @DontCompile - public void test107_verifier(boolean warmup) { + @Run(test = "test107") + public void test107_verifier() { test107(); verify(val_src, val_dst); } - @Test(failOn = INTRINSIC_SLOW_PATH) + @Test + @IR(failOn = {INTRINSIC_SLOW_PATH}) public void test108() { System.arraycopy(get_obj_src(), 0, get_obj_dst(), 0, 8); } - @DontCompile - public void test108_verifier(boolean warmup) { + @Run(test = "test108") + public void test108_verifier() { test108(); verify(obj_src, obj_dst); } - @Test(match = { INTRINSIC_SLOW_PATH }, matchCount = { 1 }) + @Test + @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"}) public void test109() { System.arraycopy(get_obj_src(), 0, get_val_dst(), 0, 8); } - @DontCompile - public void test109_verifier(boolean warmup) { + @Run(test = "test109") + public void test109_verifier() { test109(); verify(obj_src, val_dst); } - @Test(match = { INTRINSIC_SLOW_PATH }, matchCount = { 1 }) + @Test + @IR(counts = {INTRINSIC_SLOW_PATH, "= 1"}) public void test109_null() { System.arraycopy(get_obj_null_src(), 0, get_val_dst(), 0, 8); } - @DontCompile - public void test109_null_verifier(boolean warmup) { + @Run(test = "test109_null") + public void test109_null_verifier() { try { test109_null(); throw new RuntimeException("NullPointerException expected"); @@ -2614,62 +2668,69 @@ public void test109_null_verifier(boolean warmup) { } // Arrays.copyOf with constant source and destination arrays - @Test(valid = InlineTypeArrayFlattenOn, match = { INTRINSIC_SLOW_PATH }, matchCount = { 1 }) - @Test(valid = InlineTypeArrayFlattenOff, failOn = INTRINSIC_SLOW_PATH + CLASS_CHECK_TRAP) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + counts = {INTRINSIC_SLOW_PATH, "= 1"}) + @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, + failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP}) public Object[] test110() { return Arrays.copyOf(val_src, 8, Object[].class); } - @DontCompile - public void test110_verifier(boolean warmup) { + @Run(test = "test110") + public void test110_verifier() { Object[] res = test110(); verify(val_src, res); } // Same as test110 but with MyValue2[] dst - @Test(failOn = INTRINSIC_SLOW_PATH + CLASS_CHECK_TRAP) + @Test + @IR(failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP}) public Object[] test111() { return Arrays.copyOf(val_src, 8, MyValue2[].class); } - @DontCompile - public void test111_verifier(boolean warmup) { + @Run(test = "test111") + public void test111_verifier() { Object[] res = test111(); verify(val_src, res); } // Same as test110 but with Object[] src - @Test(failOn = INTRINSIC_SLOW_PATH + CLASS_CHECK_TRAP) + @Test + @IR(failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP}) public Object[] test112() { return Arrays.copyOf(obj_src, 8, Object[].class); } - @DontCompile - public void test112_verifier(boolean warmup) { + @Run(test = "test112") + public void test112_verifier() { Object[] res = test112(); verify(obj_src, res); } // Same as test111 but with Object[] src - @Test(match = { INTRINSIC_SLOW_PATH + CLASS_CHECK_TRAP }, matchCount = { 1 }) + @Test + @IR(counts = {INTRINSIC_SLOW_PATH + "|" + CLASS_CHECK_TRAP, " = 1"}) public Object[] test113() { return Arrays.copyOf(obj_src, 8, MyValue2[].class); } - @DontCompile - public void test113_verifier(boolean warmup) { + @Run(test = "test113") + public void test113_verifier() { Object[] res = test113(); verify(obj_src, res); } // Same as test111 but with Object[] src containing null - @Test(match = { INTRINSIC_SLOW_PATH + CLASS_CHECK_TRAP }, matchCount = { 1 }) + @Test + @IR(counts = {INTRINSIC_SLOW_PATH + "|" + CLASS_CHECK_TRAP, " = 1"}) public Object[] test113_null() { return Arrays.copyOf(obj_null_src, 8, MyValue2[].class); } - @DontCompile - public void test113_null_verifier(boolean warmup) { + @Run(test = "test113_null") + public void test113_null_verifier() { try { test113_null(); throw new RuntimeException("NullPointerException expected"); @@ -2681,61 +2742,68 @@ public void test113_null_verifier(boolean warmup) { // Below tests are equal to test110-test113 but hide the src/dst types until // after the arraycopy intrinsic is emitted (with incremental inlining). - @Test(valid = InlineTypeArrayFlattenOn, match = { INTRINSIC_SLOW_PATH }, matchCount = { 1 }) - @Test(valid = InlineTypeArrayFlattenOff, failOn = INTRINSIC_SLOW_PATH + CLASS_CHECK_TRAP) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + counts = {INTRINSIC_SLOW_PATH, "= 1"}) + @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, + failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP}) public Object[] test114() { return Arrays.copyOf((Object[])get_val_src(), 8, get_obj_class()); } - @DontCompile - public void test114_verifier(boolean warmup) { + @Run(test = "test114") + public void test114_verifier() { Object[] res = test114(); verify(val_src, res); } // TODO 8251971: Should be optimized but we are bailing out because // at parse time it looks as if src could be flat and dst could be not flat - @Test(valid = InlineTypeArrayFlattenOn) - @Test(valid = InlineTypeArrayFlattenOff, failOn = INTRINSIC_SLOW_PATH + CLASS_CHECK_TRAP) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, + failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP}) public Object[] test115() { return Arrays.copyOf((Object[])get_val_src(), 8, get_val_class()); } - @DontCompile - public void test115_verifier(boolean warmup) { + @Run(test = "test115") + public void test115_verifier() { Object[] res = test115(); verify(val_src, res); } - @Test(failOn = INTRINSIC_SLOW_PATH + CLASS_CHECK_TRAP) + @Test + @IR(failOn = {INTRINSIC_SLOW_PATH, CLASS_CHECK_TRAP}) public Object[] test116() { return Arrays.copyOf((Object[])get_obj_src(), 8, get_obj_class()); } - @DontCompile - public void test116_verifier(boolean warmup) { + @Run(test = "test116") + public void test116_verifier() { Object[] res = test116(); verify(obj_src, res); } - @Test(match = { INTRINSIC_SLOW_PATH + CLASS_CHECK_TRAP }, matchCount = { 1 }) + @Test + @IR(counts = {INTRINSIC_SLOW_PATH + "|" + CLASS_CHECK_TRAP, " = 1"}) public Object[] test117() { return Arrays.copyOf((Object[])get_obj_src(), 8, get_val_class()); } - @DontCompile - public void test117_verifier(boolean warmup) { + @Run(test = "test117") + public void test117_verifier() { Object[] res = test117(); verify(obj_src, res); } - @Test(match = { INTRINSIC_SLOW_PATH + CLASS_CHECK_TRAP }, matchCount = { 1 }) + @Test + @IR(counts = {INTRINSIC_SLOW_PATH + "|" + CLASS_CHECK_TRAP, " = 1"}) public Object[] test117_null() { return Arrays.copyOf((Object[])get_obj_null_src(), 8, get_val_class()); } - @DontCompile - public void test117_null_verifier(boolean warmup) { + @Run(test = "test117_null") + public void test117_null_verifier() { try { test117_null(); throw new RuntimeException("NullPointerException expected"); @@ -2746,13 +2814,15 @@ public void test117_null_verifier(boolean warmup) { // Some more Arrays.copyOf tests with only constant class - @Test(match = { CLASS_CHECK_TRAP }, matchCount = { 1 }, failOn = INTRINSIC_SLOW_PATH) + @Test + @IR(counts = {CLASS_CHECK_TRAP, "= 1"}, + failOn = INTRINSIC_SLOW_PATH) public Object[] test118(Object[] src) { return Arrays.copyOf(src, 8, MyValue2[].class); } - @DontCompile - public void test118_verifier(boolean warmup) { + @Run(test = "test118") + public void test118_verifier() { Object[] res = test118(obj_src); verify(obj_src, res); res = test118(val_src); @@ -2770,21 +2840,23 @@ public Object[] test119(Object[] src) { return Arrays.copyOf(src, 8, Object[].class); } - @DontCompile - public void test119_verifier(boolean warmup) { + @Run(test = "test119") + public void test119_verifier() { Object[] res = test119(obj_src); verify(obj_src, res); res = test119(val_src); verify(val_src, res); } - @Test(match = { CLASS_CHECK_TRAP }, matchCount = { 1 }, failOn = INTRINSIC_SLOW_PATH) + @Test + @IR(counts = {CLASS_CHECK_TRAP, "= 1"}, + failOn = INTRINSIC_SLOW_PATH) public Object[] test120(Object[] src) { return Arrays.copyOf(src, 8, Integer[].class); } - @DontCompile - public void test120_verifier(boolean warmup) { + @Run(test = "test120") + public void test120_verifier() { Integer[] arr = new Integer[8]; for (int i = 0; i < 8; ++i) { arr[i] = rI + i; @@ -2800,13 +2872,13 @@ public void test120_verifier(boolean warmup) { } @Test - @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check public Object[] test121(Object[] src) { return Arrays.copyOf(src, 8, MyValue2[].class); } - @DontCompile - public void test121_verifier(boolean warmup) { + @Run(test = "test121") + @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check + public void test121_verifier() { Object[] res = test121(obj_src); verify(obj_src, res); res = test121(val_src); @@ -2820,13 +2892,13 @@ public void test121_verifier(boolean warmup) { } @Test - @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check public Object[] test122(Object[] src) { return Arrays.copyOf(src, 8, get_val_class()); } - @DontCompile - public void test122_verifier(boolean warmup) { + @Run(test = "test122") + @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check + public void test122_verifier() { Object[] res = test122(obj_src); verify(obj_src, res); res = test122(val_src); @@ -2840,13 +2912,13 @@ public void test122_verifier(boolean warmup) { } @Test - @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check public Object[] test123(Object[] src) { return Arrays.copyOf(src, 8, Integer[].class); } - @DontCompile - public void test123_verifier(boolean warmup) { + @Run(test = "test123") + @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check + public void test123_verifier() { Integer[] arr = new Integer[8]; for (int i = 0; i < 8; ++i) { arr[i] = rI + i; @@ -2862,13 +2934,13 @@ public void test123_verifier(boolean warmup) { } @Test - @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check public Object[] test124(Object[] src) { return Arrays.copyOf(src, 8, get_int_class()); } - @DontCompile - public void test124_verifier(boolean warmup) { + @Run(test = "test124") + @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check + public void test124_verifier() { Integer[] arr = new Integer[8]; for (int i = 0; i < 8; ++i) { arr[i] = rI + i; @@ -2884,13 +2956,13 @@ public void test124_verifier(boolean warmup) { } @Test - @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check public Object[] test125(Object[] src, Class klass) { return Arrays.copyOf(src, 8, klass); } - @DontCompile - public void test125_verifier(boolean warmup) { + @Run(test = "test125") + @Warmup(10000) // Make sure we hit too_many_traps for the src <: dst check + public void test125_verifier() { Integer[] arr = new Integer[8]; for (int i = 0; i < 8; ++i) { arr[i] = rI + i; @@ -2921,15 +2993,20 @@ public void test125_verifier(boolean warmup) { } } + // Verify that clone from (flat) inline type array not containing oops is always optimized. - @Test(valid = InlineTypeArrayFlattenOn, match = { JLONG_ARRAYCOPY }, matchCount = { 1 }, failOn = CHECKCAST_ARRAYCOPY + CLONE_INTRINSIC_SLOW_PATH) - @Test(valid = InlineTypeArrayFlattenOff, failOn = CLONE_INTRINSIC_SLOW_PATH) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + counts = {JLONG_ARRAYCOPY, "= 1"}, + failOn = {CHECKCAST_ARRAYCOPY, CLONE_INTRINSIC_SLOW_PATH}) + @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, + failOn = {CLONE_INTRINSIC_SLOW_PATH}) public Object[] test126(MyValue2[] src) { return src.clone(); } - @DontCompile - public void test126_verifier(boolean warmup) { + @Run(test = "test126") + public void test126_verifier() { Object[] res = test126(val_src); verify(val_src, res); } @@ -2940,8 +3017,8 @@ public void test127(Object src, Object dst, int len) { System.arraycopy(src, 0, dst, 0, len); } - @DontCompile - public void test127_verifier(boolean warmup) { + @Run(test = "test127") + public void test127_verifier() { test127(val_src, obj_dst, 8); verify(val_src, obj_dst); test127(val_src, val_dst, 8); @@ -2957,14 +3034,16 @@ public void test127_verifier(boolean warmup) { } // Verify that copyOf with known source and unknown destination class is optimized - @Test(valid = InlineTypeArrayFlattenOn, match = { JLONG_ARRAYCOPY }, matchCount = { 1 }, failOn = CHECKCAST_ARRAYCOPY) - @Test(valid = InlineTypeArrayFlattenOff) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + counts = {JLONG_ARRAYCOPY, "= 1"}, + failOn = {CHECKCAST_ARRAYCOPY}) public Object[] test128(MyValue2[] src, Class klass) { return Arrays.copyOf(src, 8, klass); } - @DontCompile - public void test128_verifier(boolean warmup) { + @Run(test = "test128") + public void test128_verifier() { Object[] res = test128(val_src, MyValue2[].class); verify(val_src, res); res = test128(val_src, Object[].class); @@ -2983,8 +3062,8 @@ public void test129(Object src, Object dst, int len) { System.arraycopy(src, 0, dst, 0, len); } - @DontCompile - public void test129_verifier(boolean warmup) { + @Run(test = "test129") + public void test129_verifier() { try { test129(new Object(), new Object[0], 0); throw new RuntimeException("ArrayStoreException expected"); @@ -3000,14 +3079,15 @@ public void test129_verifier(boolean warmup) { } // Empty inline type array access - @Test(failOn = ALLOC + ALLOCA + LOAD + STORE) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE}) public MyValueEmpty test130(MyValueEmpty[] array) { array[0] = new MyValueEmpty(); return array[1]; } - @DontCompile - public void test130_verifier(boolean warmup) { + @Run(test = "test130") + public void test130_verifier() { MyValueEmpty[] array = new MyValueEmpty[2]; MyValueEmpty empty = test130(array); Asserts.assertEquals(array[0], MyValueEmpty.default); @@ -3019,14 +3099,15 @@ static primitive class EmptyContainer { } // Empty inline type container array access - @Test(failOn = ALLOC + ALLOCA + LOAD + STORE) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE}) public MyValueEmpty test131(EmptyContainer[] array) { array[0] = new EmptyContainer(); return array[1].empty; } - @DontCompile - public void test131_verifier(boolean warmup) { + @Run(test = "test131") + public void test131_verifier() { EmptyContainer[] array = new EmptyContainer[2]; MyValueEmpty empty = test131(array); Asserts.assertEquals(array[0], EmptyContainer.default); @@ -3040,8 +3121,8 @@ public Object test132(Object[] array) { return array[1]; } - @DontCompile - public void test132_verifier(boolean warmup) { + @Run(test = "test132") + public void test132_verifier() { Object[] array = new MyValueEmpty[2]; Object empty = test132(array); Asserts.assertEquals(array[0], MyValueEmpty.default); @@ -3059,8 +3140,8 @@ public Object test133(Object[] array) { return array[1]; } - @DontCompile - public void test133_verifier(boolean warmup) { + @Run(test = "test133") + public void test133_verifier() { Object[] array = new EmptyContainer[2]; Object empty = test133(array); Asserts.assertEquals(array[0], EmptyContainer.default); @@ -3072,15 +3153,16 @@ public void test133_verifier(boolean warmup) { } // Non-escaping empty inline type array access - @Test(failOn = ALLOC + ALLOCA + LOAD + STORE) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE}) public static MyValueEmpty test134(MyValueEmpty val) { MyValueEmpty[] array = new MyValueEmpty[1]; array[0] = val; return array[0]; } - @DontCompile - public void test134_verifier(boolean warmup) { + @Run(test = "test134") + public void test134_verifier() { MyValueEmpty empty = test134(MyValueEmpty.default); Asserts.assertEquals(empty, MyValueEmpty.default); } @@ -3092,8 +3174,8 @@ public Object test135(Object[] array, Object val) { return array[1]; } - @DontCompile - public void test135_verifier(boolean warmup) { + @Run(test = "test135") + public void test135_verifier() { MyValue1[] array1 = new MyValue1[2]; array1[1] = MyValue1.createWithFieldsInline(rI, rL); synchronized (array1) { @@ -3121,8 +3203,8 @@ public Object test136(Object[] array, Object val) { return res; } - @DontCompile - public void test136_verifier(boolean warmup) { + @Run(test = "test136") + public void test136_verifier() { MyValue1[] array1 = new MyValue1[2]; array1[1] = MyValue1.createWithFieldsInline(rI, rL); Object res = test136(array1, array1[1]); @@ -3146,8 +3228,8 @@ public void test137(Object[] array1, Object[] array2) { } } - @DontCompile - public void test137_verifier(boolean warmup) { + @Run(test = "test137") + public void test137_verifier() { MyValue1[] array1 = new MyValue1[100]; Arrays.fill(array1, MyValue1.createWithFieldsInline(rI, rL)); Integer[] array2 = new Integer[100]; @@ -3189,8 +3271,8 @@ public void test138(Object[] array1, Object[] array2) { } } - @DontCompile - public void test138_verifier(boolean warmup) { + @Run(test = "test138") + public void test138_verifier() { MyValue1[] array1 = new MyValue1[100]; Arrays.fill(array1, MyValue1.createWithFieldsInline(rI, rL)); Integer[] array2 = new Integer[100]; @@ -3211,7 +3293,9 @@ public void test138_verifier(boolean warmup) { } // Test load from array that is only known to be non-inline after parsing - @Test(failOn = ALLOC + ALLOCA + ALLOC_G + ALLOCA_G + LOOP + LOAD + STORE + TRAP + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD) + @Test + @IR(failOn = {ALLOC, ALLOCA, ALLOC_G, ALLOCA_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, + STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) public Object test139() { Object[] array = null; Object[] iarray = new Integer[1]; @@ -3223,14 +3307,16 @@ public Object test139() { return array[0]; } - @DontCompile - public void test139_verifier(boolean warmup) { + @Run(test = "test139") + public void test139_verifier() { Object res = test139(); Asserts.assertEquals(res, null); } // Test store to array that is only known to be non-inline after parsing - @Test(failOn = ALLOC + ALLOCA + ALLOC_G + LOOP + LOAD + STORE + TRAP + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD) + @Test + @IR(failOn = {ALLOC, ALLOCA, ALLOC_G, LOOP, LOAD, STORE, TRAP, + LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) public Object[] test140(Object val) { Object[] array = null; Object[] iarray = new Integer[1]; @@ -3243,8 +3329,8 @@ public Object[] test140(Object val) { return array; } - @DontCompile - public void test140_verifier(boolean warmup) { + @Run(test = "test140") + public void test140_verifier() { Object[] res = test140(rI); Asserts.assertEquals(res[0], rI); res = test140(null); @@ -3253,7 +3339,7 @@ public void test140_verifier(boolean warmup) { // Test load from array that is only known to be inline after parsing // TODO 8255938 - // @Test(failOn = ALLOC + ALLOCA + ALLOC_G + ALLOCA_G + LOOP + LOAD + STORE + TRAP + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD) + // @Test(failOn = {ALLOC, ALLOCA, ALLOC_G, ALLOCA_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) @Test public Object test141() { Object[] array = null; @@ -3266,15 +3352,15 @@ public Object test141() { return array[0]; } - @DontCompile - public void test141_verifier(boolean warmup) { + @Run(test = "test141") + public void test141_verifier() { Object res = test141(); Asserts.assertEquals(res, MyValue1.default); } // Test store to array that is only known to be inline after parsing // TODO 8255938 - // @Test(failOn = ALLOC + ALLOCA + ALLOC_G + LOOP + LOAD + STORE + TRAP + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD) + // @Test(failOn = {ALLOC, ALLOCA, ALLOC_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) @Test public Object[] test142(Object val) { Object[] array = null; @@ -3288,11 +3374,11 @@ public Object[] test142(Object val) { return array; } - @DontCompile - public void test142_verifier(boolean warmup) { + @Run(test = "test142") + public void test142_verifier(RunInfo info) { Object[] res = test142(MyValue1.default); Asserts.assertEquals(res[0], MyValue1.default); - if (!warmup) { + if (!info.isWarmUp()) { try { test142(null); throw new RuntimeException("Should throw NullPointerException"); @@ -3317,7 +3403,6 @@ static class MyObject143 implements MyInterface143 { // Test that triggers an anti dependency failure when array mark word is loaded from immutable memory @Test - @Warmup(0) public void test143() { MyInterface143[] arr = array143; int tmp = arr.length; @@ -3328,14 +3413,14 @@ public void test143() { } } - @DontCompile - public void test143_verifier(boolean warmup) { + @Run(test = "test143") + @Warmup(0) + public void test143_verifier() { test143(); } // Same as test143 but with two flat array checks that are unswitched @Test - @Warmup(0) public void test144() { MyInterface143[] arr1 = array143; MyInterface143[] arr2 = array143; @@ -3348,8 +3433,9 @@ public void test144() { } } - @DontCompile - public void test144_verifier(boolean warmup) { + @Run(test = "test144") + @Warmup(0) + public void test144_verifier() { test144(); } @@ -3359,16 +3445,16 @@ public Object test145(Object[] array) { return array[0]; } - @DontCompile - public void test145_verifier(boolean warmup) { + @Run(test = "test145") + public void test145_verifier() { Object[] array = new EmptyContainer[1]; EmptyContainer empty = (EmptyContainer)test145(array); Asserts.assertEquals(empty, EmptyContainer.default); } // Test that non-flattened array does not block inline type scalarization - @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE) - @Warmup(50000) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE}) public void test146(boolean b) { MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD); MyValue2[] array = { vt }; @@ -3381,14 +3467,15 @@ public void test146(boolean b) { } } - @DontCompile - public void test146_verifier(boolean warmup) { + @Run(test = "test146") + @Warmup(50000) + public void test146_verifier() { test146(true); } // Test that non-flattened array does not block inline type scalarization - @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE) - @Warmup(50000) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE}) public int test147(boolean deopt) { // Both vt and array should be scalarized MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD); @@ -3412,9 +3499,10 @@ public int test147(boolean deopt) { return array[0].x; } - @DontCompile - public void test147_verifier(boolean warmup) { - int res = test147(!warmup); - Asserts.assertEquals(res, MyValue2.createWithFieldsInline(rI, rD).x + (warmup ? 0 : 42)); + @Run(test = "test147") + @Warmup(50000) + public void test147_verifier(RunInfo info) { + int res = test147(!info.isWarmUp()); + Asserts.assertEquals(res, MyValue2.createWithFieldsInline(rI, rD).x + (info.isWarmUp() ? 0 : 42)); } } From 90af9b016ac77f29b98ea2005cb14f129160a23b Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Mon, 22 Mar 2021 10:37:43 -0700 Subject: [PATCH 065/131] Commented the check whether the method to be compiled is @Test annotated --- .../test/lib/hotspot/ir_framework/TestFrameworkExecution.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 5c11ace3685..ca39dd9b8b7 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -706,8 +706,8 @@ enum TriState { // Can be called from tests for non-@Test methods static void compile(Method m, CompLevel compLevel) { - TestRun.check(getAnnotation(m, Test.class) == null, - "Cannot call enqueueMethodForCompilation() for @Test annotated method " + m); +// TestRun.check(getAnnotation(m, Test.class) == null, +// "Cannot call enqueueMethodForCompilation() for @Test annotated method " + m); TestRun.check(compLevel != CompLevel.SKIP && compLevel != CompLevel.WAIT_FOR_COMPILATION, "Invalid compilation request with level " + compLevel); enqueueForCompilation(m, compLevel); From 01d04a1515faf9ae0d53852c5044adefa1848801 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 23 Mar 2021 11:06:51 +0100 Subject: [PATCH 066/131] Fix hanging socket connections blocking the framework, fix nested helper classes not found, correctly prevent IR matching when CompileThreshold is set --- .../hotspot/ir_framework/TestFramework.java | 84 ++++++++++++------- .../ir_framework/TestFrameworkExecution.java | 3 - .../TestFrameworkPrepareFlags.java | 6 +- .../ir_framework/tests/TestScenarios.java | 23 +++++ 4 files changed, 80 insertions(+), 36 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 36e504b5f08..ba986b2a0dd 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -311,15 +311,10 @@ public TestFramework addScenarios(Scenario... scenarios) { */ public void start() { installWhiteBox(); - socket = new TestFrameworkSocket(); - try { - if (scenarios == null) { - start(null); - } else { - startWithScenarios(); - } - } finally { - socket.close(); + if (scenarios == null) { + start(null); + } else { + startWithScenarios(); } } @@ -351,7 +346,14 @@ public static String getLastTestVMOutput() { * Calling these methods from main() results in a linking exception (Whitebox not yet loaded and enabled). */ - // Can be called from tests for non-@Test methods + /** + * Compile {@code m} at compilation level {@code compLevel}. {@code m} is first enqueued and might not be compiled + * yet upon returning from this method. + * + * @param m the method to be compiled + * @param compLevel the (valid) compilation level at which the method should be compiled. + * @throws TestRunException if compilation level is {@link CompLevel#SKIP} or {@link CompLevel#WAIT_FOR_COMPILATION} + */ public static void compile(Method m, CompLevel compLevel) { TestFrameworkExecution.compile(m, compLevel); } @@ -477,24 +479,25 @@ private void start(Scenario scenario) { "-DScenarios and is therefore not executed."); return; } - - // Use TestFramework flags and scenario flags for new VMs. - List additionalFlags = new ArrayList<>(flags); - if (scenario != null) { - List scenarioFlags = scenario.getFlags(); - String scenarioFlagsString = scenarioFlags.isEmpty() ? "" : " - [" + String.join(", ", scenarioFlags) + "]"; - System.out.println("Scenario #" + scenario.getIndex() + scenarioFlagsString + ":"); - additionalFlags.addAll(scenarioFlags); - } - System.out.println("Run Flag VM:"); - runFlagVM(additionalFlags); - String flagsString = additionalFlags.isEmpty() ? "" : " - [" + String.join(", ", additionalFlags) + "]"; - System.out.println("Run Test VM" + flagsString + ":"); - runTestVM(additionalFlags); - if (scenario != null) { - scenario.setTestVMOutput(lastTestVMOutput); + socket = TestFrameworkSocket.getSocket(); + try { + // Use TestFramework flags and scenario flags for new VMs. + List additionalFlags = new ArrayList<>(flags); + if (scenario != null) { + List scenarioFlags = scenario.getFlags(); + String scenarioFlagsString = scenarioFlags.isEmpty() ? "" : " - [" + String.join(", ", scenarioFlags) + "]"; + System.out.println("Scenario #" + scenario.getIndex() + scenarioFlagsString + ":"); + additionalFlags.addAll(scenarioFlags); + } + System.out.println("Run Flag VM:"); + runFlagVM(additionalFlags); + String flagsString = additionalFlags.isEmpty() ? "" : " - [" + String.join(", ", additionalFlags) + "]"; + System.out.println("Run Test VM" + flagsString + ":"); + runTestVM(additionalFlags, scenario); + System.out.println(); + } finally { + socket.close(); } - System.out.println(); } private void runFlagVM(List additionalFlags) { @@ -545,7 +548,7 @@ private void checkFlagVMExitCode(OutputAnalyzer oa) { } } - private void runTestVM(List additionalFlags) { + private void runTestVM(List additionalFlags, Scenario scenario) { List cmds = prepareTestVMFlags(additionalFlags); if (VERIFY_IR) { // We only need the socket if we are doing IR verification. @@ -564,10 +567,17 @@ private void runTestVM(List additionalFlags) { } lastTestVMOutput = oa.getOutput(); + if (scenario != null) { + scenario.setTestVMOutput(lastTestVMOutput); + } checkTestVMExitCode(oa); if (VERIFY_IR) { IRMatcher irMatcher = new IRMatcher(lastTestVMOutput, socket.getOutput(), testClass); irMatcher.applyRules(); + } else { + System.out.println("IR Verification disabled either through explicitly setting -DVerify=false or due to " + + "not running a debug build, running with -Xint, or other VM flags that make the verification " + + "inaccurate or impossible (e.g. using -XX:CompileThreshold, running with C1 only etc.)."); } } @@ -601,10 +611,10 @@ private List prepareTestVMFlags(List additionalFlags) { cmds.add(socket.getPortPropertyFlag()); } - cmds.add(TestFrameworkExecution.class.getCanonicalName()); - cmds.add(testClass.getCanonicalName()); + cmds.add(TestFrameworkExecution.class.getName()); + cmds.add(testClass.getName()); if (helperClasses != null) { - helperClasses.forEach(c -> cmds.add(c.getCanonicalName())); + helperClasses.forEach(c -> cmds.add(c.getName())); } return cmds; } @@ -683,7 +693,9 @@ class TestFrameworkSocket { private Thread socketThread; private ServerSocket serverSocket; - TestFrameworkSocket() { + private static TestFrameworkSocket singleton = null; + + private TestFrameworkSocket() { try { serverSocket = new ServerSocket(0); } catch (IOException e) { @@ -696,6 +708,14 @@ class TestFrameworkSocket { serverPortPropertyFlag = "-D" + SERVER_PORT_PROPERTY + "=" + port; } + public static TestFrameworkSocket getSocket() { + if (singleton == null || singleton.serverSocket.isClosed()) { + singleton = new TestFrameworkSocket(); + return singleton; + } + return singleton; + } + public String getPortPropertyFlag() { return serverPortPropertyFlag; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index ca39dd9b8b7..b6335bcda00 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -704,10 +704,7 @@ enum TriState { No } - // Can be called from tests for non-@Test methods static void compile(Method m, CompLevel compLevel) { -// TestRun.check(getAnnotation(m, Test.class) == null, -// "Cannot call enqueueMethodForCompilation() for @Test annotated method " + m); TestRun.check(compLevel != CompLevel.SKIP && compLevel != CompLevel.WAIT_FOR_COMPILATION, "Invalid compilation request with level " + compLevel); enqueueForCompilation(m, compLevel); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java index a1690e6bbf5..2779853c8a1 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java @@ -24,10 +24,12 @@ package jdk.test.lib.hotspot.ir_framework; import jdk.test.lib.Platform; +import jdk.test.lib.management.InputArguments; import sun.hotspot.WhiteBox; import java.util.ArrayList; import java.util.Arrays; +import java.util.function.Predicate; class TestFrameworkPrepareFlags { @@ -113,7 +115,9 @@ private static ArrayList prepareTestVmFlags(Class testClass) { } private static void setupIrVerificationFlags(Class testClass, ArrayList cmds) { - if (VERIFY_IR && cmds.stream().anyMatch(flag -> flag.startsWith("-XX:CompileThreshold"))) { + Predicate matchCompileThreshold = flag -> flag.startsWith("-XX:CompileThreshold"); + if (VERIFY_IR && (cmds.stream().anyMatch(matchCompileThreshold) + || Arrays.stream(InputArguments.getVmInputArgs()).anyMatch(matchCompileThreshold))) { // Disable IR verification if non-default CompileThreshold is set if (VERBOSE) { System.out.println("Disabled IR verification due to CompileThreshold flag"); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java index 2c4c329d62b..92821376fd8 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java @@ -53,6 +53,17 @@ public static void main(String[] args) { } catch (RuntimeException e) { Asserts.assertTrue(e.getMessage().contains("Cannot define two scenarios with the same index 3"), e.getMessage()); } + try { + TestFramework.runWithScenarios(MyExceptionTest.class, s1, s2, s3); + Asserts.fail("Should not reach"); + } catch (TestRunException e) { + Asserts.assertTrue(s1.getTestVMOutput().contains("Caused by: jdk.test.lib.hotspot.ir_framework.tests.MyScenarioException")); + Asserts.assertTrue(s2.getTestVMOutput().contains("Caused by: jdk.test.lib.hotspot.ir_framework.tests.MyScenarioException")); + Asserts.assertTrue(s3.getTestVMOutput().contains("Caused by: jdk.test.lib.hotspot.ir_framework.tests.MyScenarioException")); + } catch (Exception e) { + Asserts.fail("Should not catch other exceptions"); + } + } @Test @@ -73,3 +84,15 @@ class ScenarioTest { public void doesNotFail() { } } + +class MyExceptionTest { + int iFld; + @Test + @IR(failOn = IRNode.STORE) // Not evaluated due to MyScenarioException + public void test() { + iFld = 42; + throw new MyScenarioException(); + } +} + +class MyScenarioException extends RuntimeException {} From 48488c9842d53d194e8c8ed66e54bf2e43432742 Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Tue, 23 Mar 2021 10:54:22 -0700 Subject: [PATCH 067/131] Added @ForceCompileClassInitializer for helper classes to match old framework behavior. --- .../jtreg/compiler/valhalla/inlinetypes/TestArrays.java | 4 ++++ .../valhalla/inlinetypes/TestBasicFunctionality.java | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java index 1e5ce95107b..755a5e524cc 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java @@ -115,6 +115,7 @@ static boolean compile_and_run_again_if_deoptimized(boolean warmup, String test) return false; } + @ForceCompileClassInitializer primitive static class NotFlattenable { private final Object o1 = null; private final Object o2 = null; @@ -2196,6 +2197,7 @@ public void test90_verifier() { Asserts.assertEQ(test90(), true); } + @ForceCompileClassInitializer primitive static final class Test91Value { public final int f0; public final int f1; @@ -3094,6 +3096,7 @@ public void test130_verifier() { Asserts.assertEquals(empty, MyValueEmpty.default); } + @ForceCompileClassInitializer static primitive class EmptyContainer { MyValueEmpty empty = MyValueEmpty.default; } @@ -3392,6 +3395,7 @@ static interface MyInterface143 { public int hash(); } + @ForceCompileClassInitializer static class MyObject143 implements MyInterface143 { public int hash() { return 42; } } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java index 7bd1fa83f5b..84036865309 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java @@ -605,6 +605,7 @@ public void test26_verifier() { Asserts.assertEQ(result, 2 * hash()); } + @ForceCompileClassInitializer class TestClass27 { public MyValue1 v; } @@ -867,11 +868,13 @@ public void test36_verifier() { } // Test correct loading of flattened fields + @ForceCompileClassInitializer primitive class Test37Value2 { final int x = 0; final int y = 0; } + @ForceCompileClassInitializer primitive class Test37Value1 { final double d = 0; final float f = 0; @@ -890,6 +893,7 @@ public void test37_verifier() { } // Test elimination of inline type allocations without a unique CheckCastPP + @ForceCompileClassInitializer primitive class Test38Value { public int i; public Test38Value(int i) { this.i = i; } @@ -917,6 +921,7 @@ public void test38_verifier() { } // Tests split if with inline type Phi users + @ForceCompileClassInitializer static primitive class Test39Value { public int iFld1; public int iFld2; From e510d975aa77cc9a704dedb72f3ea6937eb5147c Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Tue, 23 Mar 2021 13:01:16 -0700 Subject: [PATCH 068/131] Converted tests to new IR framework. --- .../compiler/valhalla/inlinetypes/TestC1.java | 155 +++-- .../inlinetypes/TestCallingConvention.java | 551 ++++++++++-------- 2 files changed, 371 insertions(+), 335 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java index 7b15092d82b..fbe8bd9654c 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, 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 @@ -24,71 +24,53 @@ package compiler.valhalla.inlinetypes; -import java.lang.invoke.*; -import java.lang.reflect.Method; import java.util.Arrays; import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; /* * @test * @key randomness * @summary Various tests that are specific for C1. - * @library /testlibrary /test/lib /compiler/whitebox / + * @library /test/lib * @requires os.simpleArch == "x64" + * @compile InlineTypes.java * @compile -XDallowWithFieldOperator TestC1.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestC1 + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestC1 */ -public class TestC1 extends InlineTypeTest { - public static final int C1 = COMP_LEVEL_SIMPLE; - public static final int C2 = COMP_LEVEL_FULL_OPTIMIZATION; - - public static void main(String[] args) throws Throwable { - TestC1 test = new TestC1(); - test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, MyValue3.class, MyValue3Inline.class); - } - - @Override - public int getNumScenarios() { - return 5; - } - - @Override - public String[] getVMParameters(int scenario) { - switch (scenario) { - case 0: return new String[] { // C1 only - "-XX:TieredStopAtLevel=1", - "-XX:+TieredCompilation", - }; - case 1: return new String[] { // C2 only. (Make sure the tests are correctly written) - "-XX:TieredStopAtLevel=4", - "-XX:-TieredCompilation", - }; - case 2: return new String[] { // interpreter only - "-Xint", - }; - case 3: return new String[] { +public class TestC1 { + public static void main(String[] args) { + final Scenario[] scenarios = { + // C1 only + new Scenario(0, + "-XX:TieredStopAtLevel=1", "-XX:+TieredCompilation"), + // C2 only. (Make sure the tests are correctly written) + new Scenario(1, + "-XX:TieredStopAtLevel=4", "-XX:-TieredCompilation"), + // interpreter only + new Scenario(2, + "-Xint"), // Xcomp Only C1. - "-XX:TieredStopAtLevel=1", - "-XX:+TieredCompilation", - "-Xcomp", - }; - case 4: return new String[] { + new Scenario(3, + "-XX:TieredStopAtLevel=1", "-XX:+TieredCompilation", "-Xcomp"), // Xcomp Only C2. - "-XX:TieredStopAtLevel=4", - "-XX:-TieredCompilation", - "-Xcomp", - }; - } - return null; + new Scenario(4, + "-XX:TieredStopAtLevel=4", "-XX:-TieredCompilation", "-Xcomp") + }; + + TestFramework testFramework = InlineTypes.getFramework(); + testFramework.addScenarios(scenarios) + .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class, + MyValue3.class, MyValue3Inline.class) + .start(); } // JDK-8229799 - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public long test1(Object a, Object b, long n) { long r; n += (a == b) ? 0x5678123456781234L : 0x1234567812345678L; @@ -96,8 +78,8 @@ public long test1(Object a, Object b, long n) { return n; } - @DontCompile - public void test1_verifier(boolean warmup) { + @Run(test = "test1") + public void test1_verifier() { MyValue1 v1 = MyValue1.createWithFieldsInline(rI, rL); MyValue1 v2 = MyValue1.createWithFieldsInline(rI, rL+1); long r1 = test1(v1, v1, 1); @@ -106,6 +88,7 @@ public void test1_verifier(boolean warmup) { Asserts.assertEQ(r2, 0x1234567812345678L); } + @ForceCompileClassInitializer static primitive class SimpleValue2 { final int value; SimpleValue2(int value) { @@ -116,13 +99,13 @@ static primitive class SimpleValue2 { // JDK-8231961 // Test that the value numbering optimization does not remove // the second load from the buffered array element. - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public int test2(SimpleValue2[] array) { return array[0].value + array[0].value; } - @DontCompile - public void test2_verifier(boolean warmup) { + @Run(test = "test2") + public void test2_verifier() { SimpleValue2[] array = new SimpleValue2[1]; array[0] = new SimpleValue2(rI); int result = test2(array); @@ -134,13 +117,13 @@ public void test2_verifier(boolean warmup) { // sub-elements of a flattened array without copying the element first // Test access to a null array - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public int test3(MyValue2[] array, int index) { return array[index].x; } - @DontCompile - public void test3_verifier(boolean warmup) { + @Run(test = "test3") + public void test3_verifier() { NullPointerException npe = null; try { test3(null, 0); @@ -151,13 +134,13 @@ public void test3_verifier(boolean warmup) { } // Test out of bound accesses - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public int test4(MyValue2[] array, int index) { return array[index].x; } - @DontCompile - public void test4_verifier(boolean warmup) { + @Run(test = "test4") + public void test4_verifier() { MyValue2[] array = new MyValue2[2]; ArrayIndexOutOfBoundsException aioob = null; try { @@ -176,13 +159,13 @@ public void test4_verifier(boolean warmup) { } // Test 1st level sub-element access to primitive field - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public int test5(MyValue2[] array, int index) { return array[index].x; } - @DontCompile - public void test5_verifier(boolean warmup) { + @Run(test = "test5") + public void test5_verifier() { MyValue2[] array = new MyValue2[2]; MyValue2 v = new MyValue2(1,(byte)2, new MyValue2Inline(5.0d, 345L)); array[1] = v; @@ -191,13 +174,13 @@ public void test5_verifier(boolean warmup) { } // Test 1st level sub-element access to flattened field - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public MyValue2Inline test6(MyValue2[] array, int index) { return array[index].v; } - @DontCompile - public void test6_verifier(boolean warmup) { + @Run(test = "test6") + public void test6_verifier() { MyValue2[] array = new MyValue2[2]; MyValue2Inline vi = new MyValue2Inline(3.5d, 678L); MyValue2 v = new MyValue2(1,(byte)2, vi); @@ -207,6 +190,7 @@ public void test6_verifier(boolean warmup) { } // Test 1st level sub-element access to non-flattened field + @ForceCompileClassInitializer static primitive class Big { long l0,l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12,l13,l14,l15,l16,l17,l18,l19 ; @@ -240,6 +224,7 @@ void check(long n, int i) { } } + @ForceCompileClassInitializer static primitive class TestValue { int i; Big big; @@ -250,13 +235,13 @@ static primitive class TestValue { } } - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public Big test7(TestValue[] array, int index) { return array[index].big; } - @DontCompile - public void test7_verifier(boolean warmup) { + @Run(test = "test7") + public void test7_verifier() { TestValue[] array = new TestValue[7]; Big b0 = test7(array, 3); b0.check(0, 0); @@ -267,13 +252,13 @@ public void test7_verifier(boolean warmup) { } // Test 2nd level sub-element access to primitive field - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public byte test8(MyValue1[] array, int index) { return array[index].v2.y; } - @DontCompile - public void test8_verifier(boolean warmup) { + @Run(test = "test8") + public void test8_verifier() { MyValue1[] array = new MyValue1[23]; MyValue2 mv2a = MyValue2.createWithFieldsInline(7, 63L, 8.9d); MyValue2 mv2b = MyValue2.createWithFieldsInline(11, 69L, 17.3d); @@ -290,37 +275,37 @@ public void test8_verifier(boolean warmup) { // (OOB, null pointer) static primitive class EmptyType {} - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public EmptyType test9() { EmptyType[] array = new EmptyType[10]; return array[4]; } - @DontCompile - public void test9_verifier(boolean warmup) { + @Run(test = "test9") + public void test9_verifier() { EmptyType et = test9(); Asserts.assertEQ(et, EmptyType.default); } - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public EmptyType test10(EmptyType[] array) { return array[0]; } - @DontCompile - public void test10_verifier(boolean warmup) { + @Run(test = "test10") + public void test10_verifier() { EmptyType[] array = new EmptyType[16]; EmptyType et = test10(array); Asserts.assertEQ(et, EmptyType.default); } - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public EmptyType test11(EmptyType[] array, int index) { return array[index]; } - @DontCompile - public void test11_verifier(boolean warmup) { + @Run(test = "test11") + public void test11_verifier() { Exception e = null; EmptyType[] array = new EmptyType[10]; try { @@ -345,13 +330,13 @@ public void test11_verifier(boolean warmup) { Asserts.assertNotNull(e); } - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public void test12(EmptyType[] array, int index, EmptyType value) { array[index] = value; } - @DontCompile - public void test12_verifier(boolean warmup) { + @Run(test = "test12") + public void test12_verifier() { EmptyType[] array = new EmptyType[16]; test12(array, 2, EmptyType.default); Exception e = null; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java index 6b8d8088a69..58eb5628442 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -28,30 +28,24 @@ import java.lang.invoke.*; import java.lang.reflect.Method; +import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; + /* * @test * @key randomness * @summary Test inline type calling convention optimizations - * @library /testlibrary /test/lib /compiler/whitebox / + * @library /test/lib * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile TestCallingConvention.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestCallingConvention + * @compile InlineTypes.java + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestCallingConvention */ -public class TestCallingConvention extends InlineTypeTest { - // Extra VM parameters for some test scenarios. See InlineTypeTest.getVMParameters() - @Override - public String[] getExtraVMParameters(int scenario) { - switch (scenario) { - case 0: return new String[] {"-Dsun.reflect.inflationThreshold=10000"}; // Don't generate bytecodes but call through runtime for reflective calls - case 1: return new String[] {"-Dsun.reflect.inflationThreshold=10000"}; - case 3: return new String[] {"-XX:FlatArrayElementMaxSize=0"}; - } - return null; - } +public class TestCallingConvention { + + static MethodHandle test32_mh, test33_mh, test37_mh; static { try { @@ -72,80 +66,188 @@ public String[] getExtraVMParameters(int scenario) { } } - public static void main(String[] args) throws Throwable { - TestCallingConvention test = new TestCallingConvention(); - test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, MyValue3.class, MyValue3Inline.class, MyValue4.class, - Test27Value1.class, Test27Value2.class, Test27Value3.class, Test37Value.class, EmptyContainer.class, MixedContainer.class); + static final TestFramework testFramework = InlineTypes.getFramework(); + + public static void main(String[] args) { + + Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; + // Don't generate bytecodes but call through runtime for reflective calls + scenarios[0].addFlags("-Dsun.reflect.inflationThreshold=10000"); + scenarios[1].addFlags("-Dsun.reflect.inflationThreshold=10000"); + scenarios[3].addFlags("-XX:FlatArrayElementMaxSize=0"); + + testFramework.addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class, + MyValue3.class, + MyValue3Inline.class, + MyValue4.class) + .start(); + } + + // Helper methods and classes + + // Test calling convention with deep hierarchy of flattened fields + @ForceCompileClassInitializer + final primitive class Test27Value1 { + final Test27Value2 valueField; + + private Test27Value1(Test27Value2 val2) { + valueField = val2; + } + + @DontInline + public int test(Test27Value1 val1) { + return valueField.test(valueField) + val1.valueField.test(valueField); + } + } + + @ForceCompileClassInitializer + final primitive class Test27Value2 { + final Test27Value3 valueField; + + private Test27Value2(Test27Value3 val3) { + valueField = val3; + } + + @DontInline + public int test(Test27Value2 val2) { + return valueField.test(valueField) + val2.valueField.test(valueField); + } + } + + @ForceCompileClassInitializer + final primitive class Test27Value3 { + final int x; + + private Test27Value3(int x) { + this.x = x; + } + + @DontInline + public int test(Test27Value3 val3) { + return x + val3.x; + } + } + + @ForceCompileClassInitializer + primitive class Test37Value { + int x = rI; + + @DontInline + public int test() { + return x; + } + } + + @ForceCompileClassInitializer + primitive class EmptyContainer { + private MyValueEmpty empty; + + EmptyContainer(MyValueEmpty empty) { + this.empty = empty; + } + + @ForceInline + MyValueEmpty getInline() { return empty; } + + @DontInline + MyValueEmpty getNoInline() { return empty; } + } + + @ForceCompileClassInitializer + primitive class MixedContainer { + public int val; + private EmptyContainer empty; + + MixedContainer(int val, EmptyContainer empty) { + this.val = val; + this.empty = empty; + } + + @ForceInline + EmptyContainer getInline() { return empty; } + + @DontInline + EmptyContainer getNoInline() { return empty; } } + // Test interpreter to compiled code with various signatures - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test1(MyValue2 v) { return v.hash(); } - @DontCompile - public void test1_verifier(boolean warmup) { + @Run(test = "test1") + public void test1_verifier(RunInfo info) { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test1(v); Asserts.assertEQ(result, v.hashInterpreted()); } - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test2(int i1, MyValue2 v, int i2) { return v.hash() + i1 - i2; } - @DontCompile - public void test2_verifier(boolean warmup) { + @Run(test = "test2") + public void test2_verifier(RunInfo info) { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test2(rI, v, 2*rI); Asserts.assertEQ(result, v.hashInterpreted() - rI); } - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test3(long l1, MyValue2 v, long l2) { return v.hash() + l1 - l2; } - @DontCompile - public void test3_verifier(boolean warmup) { + @Run(test = "test3") + public void test3_verifier(RunInfo info) { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test3(rL, v, 2*rL); Asserts.assertEQ(result, v.hashInterpreted() - rL); } - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test4(int i, MyValue2 v, long l) { return v.hash() + i + l; } - @DontCompile - public void test4_verifier(boolean warmup) { + @Run(test = "test4") + public void test4_verifier(RunInfo info) { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test4(rI, v, rL); Asserts.assertEQ(result, v.hashInterpreted() + rL + rI); } - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test5(long l, MyValue2 v, int i) { return v.hash() + i + l; } - @DontCompile - public void test5_verifier(boolean warmup) { + @Run(test = "test5") + public void test5_verifier(RunInfo info) { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test5(rL, v, rI); Asserts.assertEQ(result, v.hashInterpreted() + rL + rI); } - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test6(long l, MyValue1 v1, int i, MyValue2 v2) { return v1.hash() + i + l + v2.hash(); } - @DontCompile - public void test6_verifier(boolean warmup) { + @Run(test = "test6") + public void test6_verifier(RunInfo info) { MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI, rL); MyValue2 v2 = MyValue2.createWithFieldsInline(rI, rD); long result = test6(rL, v1, rI, v2); @@ -158,13 +260,14 @@ public long test7_interp(MyValue2 v) { return v.hash(); } - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test7(MyValue2 v) { return test7_interp(v); } - @DontCompile - public void test7_verifier(boolean warmup) { + @Run(test = "test7") + public void test7_verifier(RunInfo info) { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test7(v); Asserts.assertEQ(result, v.hashInterpreted()); @@ -175,13 +278,14 @@ public long test8_interp(int i1, MyValue2 v, int i2) { return v.hash() + i1 - i2; } - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test8(int i1, MyValue2 v, int i2) { return test8_interp(i1, v, i2); } - @DontCompile - public void test8_verifier(boolean warmup) { + @Run(test = "test8") + public void test8_verifier(RunInfo info) { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test8(rI, v, 2*rI); Asserts.assertEQ(result, v.hashInterpreted() - rI); @@ -192,13 +296,14 @@ public long test9_interp(long l1, MyValue2 v, long l2) { return v.hash() + l1 - l2; } - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test9(long l1, MyValue2 v, long l2) { return test9_interp(l1, v, l2); } - @DontCompile - public void test9_verifier(boolean warmup) { + @Run(test = "test9") + public void test9_verifier(RunInfo info) { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test9(rL, v, 2*rL); Asserts.assertEQ(result, v.hashInterpreted() - rL); @@ -209,30 +314,33 @@ public long test10_interp(int i, MyValue2 v, long l) { return v.hash() + i + l; } - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test10(int i, MyValue2 v, long l) { return test10_interp(i, v, l); } - @DontCompile - public void test10_verifier(boolean warmup) { + @Run(test = "test10") + public void test10_verifier(RunInfo info) { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test10(rI, v, rL); Asserts.assertEQ(result, v.hashInterpreted() + rL + rI); } + @DontCompile public long test11_interp(long l, MyValue2 v, int i) { return v.hash() + i + l; } - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test11(long l, MyValue2 v, int i) { return test11_interp(l, v, i); } - @DontCompile - public void test11_verifier(boolean warmup) { + @Run(test = "test11") + public void test11_verifier(RunInfo info) { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test11(rL, v, rI); Asserts.assertEQ(result, v.hashInterpreted() + rL + rI); @@ -243,13 +351,14 @@ public long test12_interp(long l, MyValue1 v1, int i, MyValue2 v2) { return v1.hash() + i + l + v2.hash(); } - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test12(long l, MyValue1 v1, int i, MyValue2 v2) { return test12_interp(l, v1, i, v2); } - @DontCompile - public void test12_verifier(boolean warmup) { + @Run(test = "test12") + public void test12_verifier(RunInfo info) { MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI, rL); MyValue2 v2 = MyValue2.createWithFieldsInline(rI, rD); long result = test12(rL, v1, rI, v2); @@ -261,23 +370,25 @@ public void test12_verifier(boolean warmup) { public long test13_interp(MyValue2 v, MyValue1[] va, boolean deopt) { if (deopt) { // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test13")); + Method m = testFramework.getTestMethod("test13"); + testFramework.deoptimize(m); } return v.hash() + va[0].hash() + va[1].hash(); } - @Test(failOn = ALLOC + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, STORE, TRAP}) public long test13(MyValue2 v, MyValue1[] va, boolean flag, long l) { return test13_interp(v, va, flag) + l; } - @DontCompile - public void test13_verifier(boolean warmup) { + @Run(test = "test13") + public void test13_verifier(RunInfo info) { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); MyValue1[] va = new MyValue1[2]; va[0] = MyValue1.createWithFieldsDontInline(rI, rL); va[1] = MyValue1.createWithFieldsDontInline(rI, rL); - long result = test13(v, va, !warmup, rL); + long result = test13(v, va, !info.isWarmUp(), rL); Asserts.assertEQ(result, v.hashInterpreted() + va[0].hash() + va[1].hash() + rL); } @@ -286,19 +397,20 @@ public void test13_verifier(boolean warmup) { public MyValue2 test14_interp(boolean deopt) { if (deopt) { // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test14")); + Method m = testFramework.getTestMethod("test14"); + testFramework.deoptimize(m); } return MyValue2.createWithFieldsInline(rI, rD); } - @Test() + @Test public MyValue2 test14(boolean flag) { return test14_interp(flag); } - @DontCompile - public void test14_verifier(boolean warmup) { - MyValue2 result = test14(!warmup); + @Run(test = "test14") + public void test14_verifier(RunInfo info) { + MyValue2 result = test14(!info.isWarmUp()); MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); Asserts.assertEQ(result.hash(), v.hash()); } @@ -311,32 +423,35 @@ public MyValue3 test15_interp() { } MyValue3 test15_vt2; - @Test(valid = InlineTypeReturnedAsFieldsOn, failOn = ALLOC + LOAD + TRAP) - @Test(valid = InlineTypeReturnedAsFieldsOff) + @Test + @IR(applyIf = {"InlineTypeReturnedAsFields", "true"}, + failOn = {ALLOC, LOAD, TRAP}) public void test15() { test15_vt2 = test15_interp(); } - @DontCompile - public void test15_verifier(boolean warmup) { + @Run(test = "test15") + public void test15_verifier(RunInfo info) { test15(); test15_vt.verify(test15_vt2); } // Return inline types in registers from compiled -> interpreter final MyValue3 test16_vt = MyValue3.create(); - @Test(valid = InlineTypeReturnedAsFieldsOn, failOn = ALLOC + STORE + TRAP) - @Test(valid = InlineTypeReturnedAsFieldsOff) + @Test + @IR(applyIf = {"InlineTypeReturnedAsFields", "true"}, + failOn = {ALLOC, STORE, TRAP}) public MyValue3 test16() { return test16_vt; } - @DontCompile - public void test16_verifier(boolean warmup) { + @Run(test = "test16") + public void test16_verifier(RunInfo info) { MyValue3 vt = test16(); test16_vt.verify(vt); } + // Return inline types in registers from compiled -> compiled final MyValue3 test17_vt = MyValue3.create(); @DontInline @@ -345,19 +460,21 @@ public MyValue3 test17_comp() { } MyValue3 test17_vt2; - @Test(valid = InlineTypeReturnedAsFieldsOn, failOn = ALLOC + LOAD + TRAP) - @Test(valid = InlineTypeReturnedAsFieldsOff) + @Test + @IR(applyIf = {"InlineTypeReturnedAsFields", "true"}, + failOn = {ALLOC, LOAD, TRAP}) public void test17() { test17_vt2 = test17_comp(); } - @DontCompile - public void test17_verifier(boolean warmup) throws Exception { + @Run(test = "test17") + public void test17_verifier(RunInfo info) throws Exception { Method helper_m = getClass().getDeclaredMethod("test17_comp"); - if (!warmup && USE_COMPILER && !WHITE_BOX.isMethodCompiled(helper_m, false)) { - enqueueMethodForCompilation(helper_m, COMP_LEVEL_FULL_OPTIMIZATION); - Asserts.assertTrue(WHITE_BOX.isMethodCompiled(helper_m, false), "test17_comp not compiled"); + if (!info.isWarmUp() && testFramework.isCompiled(helper_m)) { + testFramework.compile(helper_m, CompLevel.C2); + testFramework.assertCompiledByC2(helper_m); } + test17(); test17_vt.verify(test17_vt2); } @@ -377,8 +494,8 @@ public void test18() { test18_vt2 = test18_interp(); } - @DontCompile - public void test18_verifier(boolean warmup) { + @Run(test = "test18") + public void test18_verifier(RunInfo info) { test18(); test18_vt.verify(test18_vt2); } @@ -390,8 +507,8 @@ public MyValue4 test19() { return test19_vt; } - @DontCompile - public void test19_verifier(boolean warmup) { + @Run(test = "test19") + public void test19_verifier(RunInfo info) { MyValue4 vt = test19(); test19_vt.verify(vt); } @@ -409,17 +526,18 @@ public void test20() { test20_vt2 = test20_comp(); } - @DontCompile - public void test20_verifier(boolean warmup) throws Exception { + @Run(test = "test20") + public void test20_verifier(RunInfo info) throws Exception { Method helper_m = getClass().getDeclaredMethod("test20_comp"); - if (!warmup && USE_COMPILER && !WHITE_BOX.isMethodCompiled(helper_m, false)) { - enqueueMethodForCompilation(helper_m, COMP_LEVEL_FULL_OPTIMIZATION); - Asserts.assertTrue(WHITE_BOX.isMethodCompiled(helper_m, false), "test20_comp not compiled"); + if (!info.isWarmUp() && testFramework.isCompiled(helper_m)) { + testFramework.compile(helper_m, CompLevel.C2); + testFramework.assertCompiledByC2(helper_m); } test20(); test20_vt.verify(test20_vt2); } + // Test no result from inlined method for incremental inlining final MyValue3 test21_vt = MyValue3.create(); public MyValue3 test21_inlined() { @@ -435,8 +553,8 @@ public MyValue3 test21() { } } - @DontCompile - public void test21_verifier(boolean warmup) { + @Run(test = "test21") + public void test21_verifier(RunInfo info) { MyValue3 vt = test21(); test21_vt.verify(vt); } @@ -449,13 +567,14 @@ public MyValue3 test22() { return (MyValue3) test22_vt; } - @DontCompile - public void test22_verifier(boolean warmup) { + @Run(test = "test22") + public void test22_verifier(RunInfo info) { MyValue3 vt = test22(); test22_vt.verify(vt); } // Test calling a method that has circular register/stack dependencies when unpacking inline type arguments + @ForceCompileClassInitializer primitive class TestValue23 { final double f1; TestValue23(double val) { @@ -478,8 +597,8 @@ public double test23(int i1, int i2, int i3, int i4, int i5, int i6, d1, d2, d3, d4, d5, d6, d7, d8); } - @DontCompile - public void test23_verifier(boolean warmup) { + @Run(test = "test23") + public void test23_verifier(RunInfo info) { TestValue23 vt = new TestValue23(rI); double res1 = test23(rI, rI, rI, rI, rI, rI, vt, vt, vt, vt, vt, vt, vt, vt, @@ -498,8 +617,8 @@ public MyValue2.ref test24() { return null; } - @DontCompile - public void test24_verifier(boolean warmup) { + @Run(test = "test24") + public void test24_verifier(RunInfo info) { MyValue2.ref vt = test24(); Asserts.assertEQ(vt, null); } @@ -519,61 +638,21 @@ public MyValue2.ref test26(boolean b) { return test26_callee(b); } - @DontCompile - public void test26_verifier(boolean warmup) { + @Run(test = "test26") + public void test26_verifier(RunInfo info) { MyValue2.ref vt = test26(true); Asserts.assertEQ(vt, null); vt = test26(false); Asserts.assertEQ(vt.hash(), MyValue2.createWithFieldsInline(rI, rD).hash()); } - // Test calling convention with deep hierarchy of flattened fields - final primitive class Test27Value1 { - final Test27Value2 valueField; - - private Test27Value1(Test27Value2 val2) { - valueField = val2; - } - - @DontInline - public int test(Test27Value1 val1) { - return valueField.test(valueField) + val1.valueField.test(valueField); - } - } - - final primitive class Test27Value2 { - final Test27Value3 valueField; - - private Test27Value2(Test27Value3 val3) { - valueField = val3; - } - - @DontInline - public int test(Test27Value2 val2) { - return valueField.test(valueField) + val2.valueField.test(valueField); - } - } - - final primitive class Test27Value3 { - final int x; - - private Test27Value3(int x) { - this.x = x; - } - - @DontInline - public int test(Test27Value3 val3) { - return x + val3.x; - } - } - @Test public int test27(Test27Value1 val) { return val.test(val); } - @DontCompile - public void test27_verifier(boolean warmup) { + @Run(test = "test27") + public void test27_verifier(RunInfo info) { Test27Value3 val3 = new Test27Value3(rI); Test27Value2 val2 = new Test27Value2(val3); Test27Value1 val1 = new Test27Value1(val2); @@ -584,13 +663,13 @@ public void test27_verifier(boolean warmup) { static final MyValue1.ref test28Val = MyValue1.createWithFieldsDontInline(rI, rL); @Test - @Warmup(0) public String test28() { return test28Val.toString(); } - @DontCompile - public void test28_verifier(boolean warmup) { + @Run(test = "test28") + @Warmup(0) + public void test28_verifier(RunInfo info) { String result = test28(); } @@ -602,8 +681,8 @@ public MyValue3 test29() { return test29_vt; } - @DontCompile - public void test29_verifier(boolean warmup) throws Exception { + @Run(test = "test29") + public void test29_verifier(RunInfo info) throws Exception { MyValue3 vt = (MyValue3)TestCallingConvention.class.getDeclaredMethod("test29").invoke(this); test29_vt.verify(vt); } @@ -615,8 +694,8 @@ public MyValue3 test30(MyValue3[] array) { return result; } - @DontCompile - public void test30_verifier(boolean warmup) throws Exception { + @Run(test = "test30") + public void test30_verifier(RunInfo info) throws Exception { MyValue3[] array = new MyValue3[1]; MyValue3 vt = (MyValue3)TestCallingConvention.class.getDeclaredMethod("test30", MyValue3[].class).invoke(this, (Object)array); array[0].verify(vt); @@ -631,21 +710,21 @@ public MyValue3 test31() { return result; } - @DontCompile - public void test31_verifier(boolean warmup) throws Exception { + @Run(test = "test31") + public void test31_verifier(RunInfo info) throws Exception { MyValue3 vt = (MyValue3)TestCallingConvention.class.getDeclaredMethod("test31").invoke(this); test31_vt.verify(vt); } // Test deoptimization at call return with inline type returned in registers. // Same as test14, except the interpreted method is called via a MethodHandle. - static MethodHandle test32_mh; @DontCompile public MyValue2 test32_interp(boolean deopt) { if (deopt) { // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test32")); + Method m = testFramework.getTestMethod("test32"); + testFramework.deoptimize(m); } return MyValue2.createWithFieldsInline(rI+32, rD); } @@ -655,21 +734,21 @@ public MyValue2 test32(boolean flag) throws Throwable { return (MyValue2)test32_mh.invokeExact(this, flag); } - @DontCompile - public void test32_verifier(boolean warmup) throws Throwable { - MyValue2 result = test32(!warmup); + @Run(test = "test32") + public void test32_verifier(RunInfo info) throws Throwable { + MyValue2 result = test32(!info.isWarmUp()); MyValue2 v = MyValue2.createWithFieldsInline(rI+32, rD); Asserts.assertEQ(result.hash(), v.hash()); } // Same as test32, except the return type is not flattenable. - static MethodHandle test33_mh; @DontCompile public Object test33_interp(boolean deopt) { if (deopt) { // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test33")); + Method m = testFramework.getTestMethod("test33"); + testFramework.deoptimize(m); } return MyValue2.createWithFieldsInline(rI+33, rD); } @@ -680,9 +759,9 @@ public MyValue2 test33(boolean flag) throws Throwable { return (MyValue2)o; } - @DontCompile - public void test33_verifier(boolean warmup) throws Throwable { - MyValue2 result = test33(!warmup); + @Run(test = "test33") + public void test33_verifier(RunInfo info) throws Throwable { + MyValue2 result = test33(!info.isWarmUp()); MyValue2 v = MyValue2.createWithFieldsInline(rI+33, rD); Asserts.assertEQ(result.hash(), v.hash()); } @@ -709,17 +788,17 @@ public static long test34_callee(MyValue2 vt, int i1, int i2, int i3, int i4) { } @Test() - @Warmup(10000) // Make sure test34_callee is compiled public static long test34(MyValue2 vt, int i1, int i2, int i3, int i4) { return test34_callee(vt, i1, i2, i3, i4); } - @DontCompile - public void test34_verifier(boolean warmup) { + @Run(test = "test34") + @Warmup(10000) // Make sure test34_callee is compiled + public void test34_verifier(RunInfo info) { MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD); long result = test34(vt, rI, rI, rI, rI); Asserts.assertEQ(result, vt.hash()+4*rI); - if (!warmup) { + if (!info.isWarmUp()) { test34_deopt = true; for (int i = 0; i < 100; ++i) { result = test34(vt, rI, rI, rI, rI); @@ -739,8 +818,8 @@ public static long test35(MyValue2 vt, int i1, int i2, int i3, int i4) { return vt.hash() + i1 + i2 + i3 + i4 + result; } - @DontCompile - public void test35_verifier(boolean warmup) { + @Run(test = "test35") + public void test35_verifier(RunInfo info) { MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD); long result = test35(vt, rI, rI, rI, rI); Asserts.assertEQ(result, vt.hash()+10004*rI); @@ -758,50 +837,41 @@ public MyValue3 test36() { return result; } - @DontCompile - public void test36_verifier(boolean warmup) throws Exception { + @Run(test = "test36") + public void test36_verifier(RunInfo info) throws Exception { MyValue3 vt = (MyValue3)TestCallingConvention.class.getDeclaredMethod("test36").invoke(this); test36_vt.verify(vt); } // Test method resolution with scalarized inline type receiver at invokespecial - static final MethodHandle test37_mh; - - primitive class Test37Value { - int x = rI; - - @DontInline - public int test() { - return x; - } - } - @Test public int test37(Test37Value vt) throws Throwable { // Generates invokespecial call of Test37Value::test return (int)test37_mh.invokeExact(vt); } - @DontCompile - public void test37_verifier(boolean warmup) throws Throwable { + @Run(test = "test37") + public void test37_verifier(RunInfo info) throws Throwable { Test37Value vt = new Test37Value(); int res = test37(vt); Asserts.assertEQ(res, rI); } // Test passing/returning an empty inline type - @Test(failOn = ALLOC + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) public MyValueEmpty test38(MyValueEmpty vt) { return vt.copy(vt); } - @DontCompile - public void test38_verifier(boolean warmup) { + @Run(test = "test38") + public void test38_verifier(RunInfo info) { MyValueEmpty vt = new MyValueEmpty(); MyValueEmpty res = test38(vt); Asserts.assertEQ(res, vt); } + @ForceCompileClassInitializer static primitive class LargeValueWithOops { // Use all 6 int registers + 50/2 on stack = 29 Object o1 = null; @@ -835,6 +905,7 @@ static primitive class LargeValueWithOops { Object o29 = null; } + @ForceCompileClassInitializer static primitive class LargeValueWithoutOops { // Use all 6 int registers + 50/2 on stack = 29 int i1 = 0; @@ -883,8 +954,8 @@ public static LargeValueWithOops test39(LargeValueWithOops vt) { return vt; } - @DontCompile - public void test39_verifier(boolean warmup) { + @Run(test = "test39") + public void test39_verifier(RunInfo info) { LargeValueWithOops vt = new LargeValueWithOops(); LargeValueWithOops res = test39(vt); Asserts.assertEQ(res, vt); @@ -896,142 +967,122 @@ public static LargeValueWithoutOops test40(LargeValueWithoutOops vt) { return vt; } - @DontCompile - public void test40_verifier(boolean warmup) { + @Run(test = "test40") + public void test40_verifier(RunInfo info) { LargeValueWithoutOops vt = new LargeValueWithoutOops(); LargeValueWithoutOops res = test40(vt); Asserts.assertEQ(res, vt); } + // Test passing/returning an empty inline type together with non-empty // inline types such that only some inline type arguments are scalarized. - @Test(failOn = ALLOC + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) public MyValueEmpty test41(MyValue1 vt1, MyValueEmpty vt2, MyValue1 vt3) { return vt2.copy(vt2); } - @DontCompile - public void test41_verifier(boolean warmup) { + @Run(test = "test41") + public void test41_verifier(RunInfo info) { MyValueEmpty res = test41(MyValue1.default, MyValueEmpty.default, MyValue1.default); Asserts.assertEQ(res, MyValueEmpty.default); } // More empty inline type tests with containers - static primitive class EmptyContainer { - private MyValueEmpty empty; - - EmptyContainer(MyValueEmpty empty) { - this.empty = empty; - } - - @ForceInline - MyValueEmpty getInline() { return empty; } - - @DontInline - MyValueEmpty getNoInline() { return empty; } - } - - static primitive class MixedContainer { - public int val; - private EmptyContainer empty; - - MixedContainer(int val, EmptyContainer empty) { - this.val = val; - this.empty = empty; - } - - @ForceInline - EmptyContainer getInline() { return empty; } - - @DontInline - EmptyContainer getNoInline() { return empty; } - } - // Empty inline type return - @Test(failOn = ALLOC + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) public MyValueEmpty test42() { EmptyContainer c = new EmptyContainer(MyValueEmpty.default); return c.getInline(); } - @DontCompile - public void test42_verifier(boolean warmup) { + @Run(test = "test42") + public void test42_verifier(RunInfo info) { MyValueEmpty empty = test42(); Asserts.assertEquals(empty, MyValueEmpty.default); } // Empty inline type container return - @Test(failOn = ALLOC + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) public EmptyContainer test43(EmptyContainer c) { return c; } - @DontCompile - public void test43_verifier(boolean warmup) { + @Run(test = "test43") + public void test43_verifier(RunInfo info) { EmptyContainer c = test43(EmptyContainer. default); Asserts.assertEquals(c, EmptyContainer.default); } // Empty inline type container (mixed) return - @Test(failOn = ALLOC + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) public MixedContainer test44() { MixedContainer c = new MixedContainer(rI, EmptyContainer.default); c = new MixedContainer(rI, c.getInline()); return c; } - @DontCompile - public void test44_verifier(boolean warmup) { + @Run(test = "test44") + public void test44_verifier(RunInfo info) { MixedContainer c = test44(); Asserts.assertEquals(c, new MixedContainer(rI, EmptyContainer.default)); } + // Empty inline type container argument - @Test(failOn = ALLOC + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) public EmptyContainer test45(EmptyContainer c) { return new EmptyContainer(c.getInline()); } - @DontCompile - public void test45_verifier(boolean warmup) { + @Run(test = "test45") + public void test45_verifier(RunInfo info) { EmptyContainer empty = test45(EmptyContainer.default); Asserts.assertEquals(empty, EmptyContainer.default); } // Empty inline type container and mixed container arguments - @Test(failOn = ALLOC + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) public MyValueEmpty test46(EmptyContainer c1, MixedContainer c2, MyValueEmpty empty) { c2 = new MixedContainer(c2.val, c1); return c2.getNoInline().getNoInline(); } - @DontCompile - public void test46_verifier(boolean warmup) { + @Run(test = "test46") + public void test46_verifier(RunInfo info) { MyValueEmpty empty = test46(EmptyContainer.default, MixedContainer.default, MyValueEmpty.default); Asserts.assertEquals(empty, MyValueEmpty.default); } // No receiver and only empty argument - @Test(failOn = ALLOC + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) public static MyValueEmpty test47(MyValueEmpty empty) { return empty; } - @DontCompile - public void test47_verifier(boolean warmup) { + @Run(test = "test47") + public void test47_verifier(RunInfo info) { MyValueEmpty empty = test47(MyValueEmpty.default); Asserts.assertEquals(empty, MyValueEmpty.default); } // No receiver and only empty container argument - @Test(failOn = ALLOC + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) public static MyValueEmpty test48(EmptyContainer empty) { return empty.getNoInline(); } - @DontCompile - public void test48_verifier(boolean warmup) { + @Run(test = "test48") + public void test48_verifier(RunInfo info) { MyValueEmpty empty = test48(EmptyContainer.default); Asserts.assertEquals(empty, MyValueEmpty.default); } @@ -1054,8 +1105,8 @@ public void test49(boolean b) { test49_inlined2(b); } - @DontCompile - public void test49_verifier(boolean warmup) { + @Run(test = "test49") + public void test49_verifier(RunInfo info) { test49(true); test49(false); } @@ -1082,8 +1133,8 @@ public void test50(boolean b) { test50_vt.verify(vt); } - @DontCompile - public void test50_verifier(boolean warmup) { + @Run(test = "test50") + public void test50_verifier(RunInfo info) { test50(true); test50(false); } From eacf1aa779ecd02be45c00cdcb8a86937f0296e5 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 24 Mar 2021 16:56:17 +0100 Subject: [PATCH 069/131] Improve error reporting and exception structure, add -DReproduce to reproduce a test VM crash and add hints to stderr, exclude IR matching if @Test(SKIP), add helper class check --- .../ir_framework/IREncodingPrinter.java | 20 +-- .../hotspot/ir_framework/TestFramework.java | 130 +++++++++++++----- .../ir_framework/TestFrameworkExecution.java | 24 +++- .../hotspot/ir_framework/TestVMException.java | 58 ++++++++ .../ir_framework/tests/TestControls.java | 19 +++ .../ir_framework/tests/TestIRMatching.java | 18 +-- .../tests/TestWithHelperClasses.java | 41 ++++-- 7 files changed, 231 insertions(+), 79 deletions(-) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/TestVMException.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java index 3678d1feac7..9518525d7da 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java @@ -56,21 +56,23 @@ public IREncodingPrinter() { * - indices of all @IR rules that should be applied, separated by a comma * - "-1" if no @IR rule should not be applied */ - public void emitRuleEncoding(Method m) { + public void emitRuleEncoding(Method m, CompLevel compLevel) { method = m; int i = 0; ArrayList validRules = new ArrayList<>(); IR[] irAnnos = m.getAnnotationsByType(IR.class); - for (IR irAnno : irAnnos) { - ruleIndex = i + 1; - try { - if (shouldApplyIrRule(irAnno)) { - validRules.add(i); + if (compLevel != CompLevel.SKIP) { + for (IR irAnno : irAnnos) { + ruleIndex = i + 1; + try { + if (shouldApplyIrRule(irAnno)) { + validRules.add(i); + } + } catch (TestFormatException e) { + // Catch logged failure and continue to check other IR annotations. } - } catch (TestFormatException e) { - // Catch logged failure and continue to check other IR annotations. + i++; } - i++; } if (irAnnos.length != 0) { output.append(m.getName()); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index ba986b2a0dd..c66a0820a87 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -312,7 +312,12 @@ public TestFramework addScenarios(Scenario... scenarios) { public void start() { installWhiteBox(); if (scenarios == null) { - start(null); + try { + start(null); + } catch (TestVMException e) { + System.err.println("\n" + e.getExceptionInfo()); + throw e; + } } else { startWithScenarios(); } @@ -445,27 +450,42 @@ private void startWithScenarios() { } private void reportScenarioFailures(Map exceptionMap) { - StringBuilder builder = new StringBuilder("The following scenarios have failed: #"); - builder.append(exceptionMap.keySet().stream().map(s -> String.valueOf(s.getIndex())). - collect(Collectors.joining(", #"))).append("\n\n"); + String failedScenarios = "The following scenarios have failed: #" + + exceptionMap.keySet().stream() + .map(s -> String.valueOf(s.getIndex())) + .collect(Collectors.joining(", #")); + StringBuilder builder = new StringBuilder(failedScenarios); + builder.append("\n\n"); for (Map.Entry entry : exceptionMap.entrySet()) { - Scenario scenario = entry.getKey(); - String title = "Stacktrace for Scenario #" + scenario.getIndex(); - builder.append(title).append("\n").append("=".repeat(title.length())).append("\n"); - builder.append("Scenario flags: [").append(String.join(", ", scenario.getFlags())).append("]\n\n"); Exception e = entry.getValue(); + Scenario scenario = entry.getKey(); + String errorMsg = ""; + if (scenario != null) { + errorMsg = getScenarioTitleAndFlags(scenario); + } if (e instanceof IRViolationException) { // For IR violations, only show the actual violations and not the (uninteresting) stack trace. builder.append(e.getMessage()); + } else if (e instanceof TestVMException) { + builder.append(errorMsg).append(((TestVMException) e).getExceptionInfo()); } else { - // Print stack trace if it was not a format violation or test run exception + // Print stack trace otherwise StringWriter errors = new StringWriter(); e.printStackTrace(new PrintWriter(errors)); builder.append(errors.toString()); } builder.append("\n"); } - TestRun.fail(builder.toString()); + System.err.println(builder.toString()); + TestRun.fail(failedScenarios + ". Please check stderr for more information."); + } + + private static String getScenarioTitleAndFlags(Scenario scenario) { + StringBuilder builder = new StringBuilder(); + String title = "Scenario #" + scenario.getIndex(); + builder.append(title).append("\n").append("=".repeat(title.length())).append("\n"); + builder.append("Scenario flags: [").append(String.join(", ", scenario.getFlags())).append("]\n\n"); + return builder.toString(); } /** @@ -491,6 +511,7 @@ private void start(Scenario scenario) { } System.out.println("Run Flag VM:"); runFlagVM(additionalFlags); + String flagsString = additionalFlags.isEmpty() ? "" : " - [" + String.join(", ", additionalFlags) + "]"; System.out.println("Run Test VM" + flagsString + ":"); runTestVM(additionalFlags, scenario); @@ -556,21 +577,22 @@ private void runTestVM(List additionalFlags, Scenario scenario) { } OutputAnalyzer oa; + ProcessBuilder process = ProcessTools.createJavaProcessBuilder(cmds); try { // Calls 'main' of TestFrameworkExecution to run all specified tests with commands 'cmds'. // Use executeProcess instead of executeTestJvm as we have already added the JTreg VM and // Java options in prepareTestVMFlags(). - oa = ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder(cmds)); + oa = ProcessTools.executeProcess(process); } catch (Exception e) { fail("Error while executing Test VM", e); return; } - + JVMOutput output = new JVMOutput(oa, scenario, process); lastTestVMOutput = oa.getOutput(); if (scenario != null) { scenario.setTestVMOutput(lastTestVMOutput); } - checkTestVMExitCode(oa); + checkTestVMExitCode(output); if (VERIFY_IR) { IRMatcher irMatcher = new IRMatcher(lastTestVMOutput, socket.getOutput(), testClass); irMatcher.applyRules(); @@ -637,29 +659,27 @@ private List getTestVMFlags() { return new ArrayList<>(Arrays.asList(matcher.group(1).split(TEST_VM_FLAGS_DELIMITER))); } - private static void checkTestVMExitCode(OutputAnalyzer oa) { - final int exitCode = oa.getExitValue(); + private static void checkTestVMExitCode(JVMOutput vmOutput) { + final int exitCode = vmOutput.getExitCode(); if (VERBOSE && exitCode == 0) { System.out.println("--- OUTPUT TestFramework test VM ---"); - System.out.println(oa.getOutput()); + System.out.println(vmOutput.getOutput()); } if (exitCode != 0) { - throwTestException(oa, exitCode); + throwTestVMException(vmOutput); } } - private static void throwTestException(OutputAnalyzer oa, int exitCode) { - String stdErr = oa.getStderr(); + private static void throwTestVMException(JVMOutput vmOutput) { + String stdErr = vmOutput.getStderr(); if (stdErr.contains("TestFormat.reportIfAnyFailures")) { Pattern pattern = Pattern.compile("Violations \\(\\d+\\)[\\s\\S]*(?=/============/)"); Matcher matcher = pattern.matcher(stdErr); TestFramework.check(matcher.find(), "Must find violation matches"); throw new TestFormatException("\n\n" + matcher.group()); } else { - System.err.println("--- Standard Output TestFramework test VM ---"); - System.err.println(oa.getStdout()); - throw new TestRunException("\nTestFramework test VM exited with " + exitCode + "\n\nError Output:\n" + stdErr); + throw new TestVMException(vmOutput); } } @@ -678,6 +698,42 @@ static void fail(String failureMessage, Exception e) { } } +class JVMOutput { + private final Scenario scenario; + private final OutputAnalyzer oa; + private final ProcessBuilder process; + + JVMOutput(OutputAnalyzer oa, Scenario scenario, ProcessBuilder process) { + this.oa = oa; + this.scenario = scenario; + this.process = process; + } + + public Scenario getScenario() { + return scenario; + } + + public String getCommandLine() { + return String.join(" ", process.command()); + } + + public int getExitCode() { + return oa.getExitValue(); + } + + public String getOutput() { + return oa.getOutput(); + } + + public String getStdout() { + return oa.getStdout(); + } + + public String getStderr() { + return oa.getStderr(); + } +} + /** * Dedicated socket to send data from flag and test VM back to the driver VM. */ @@ -686,11 +742,11 @@ class TestFrameworkSocket { // Static fields used by flag and test VM only. private static final int SERVER_PORT = Integer.getInteger(SERVER_PORT_PROPERTY, -1); + private static final boolean REPRODUCE = Boolean.getBoolean("Reproduce"); private static final String HOSTNAME = null; private final String serverPortPropertyFlag; private FutureTask socketTask; - private Thread socketThread; private ServerSocket serverSocket; private static TestFrameworkSocket singleton = null; @@ -722,7 +778,7 @@ public String getPortPropertyFlag() { public void start() { socketTask = initSocketTask(); - socketThread = new Thread(socketTask); + Thread socketThread = new Thread(socketTask); socketThread.start(); } @@ -752,22 +808,14 @@ public void close() { } } - public void checkTerminated() { - try { - socketThread.join(5000); - if (socketThread.isAlive()) { - serverSocket.close(); - TestFramework.fail("Socket thread was not terminated"); - } - } catch (InterruptedException | IOException e) { - TestFramework.fail("Socket thread was not closed", e); - } - } - /** * Only called by flag and test VM to write to server socket. */ public static void write(String msg, String type) { + if (REPRODUCE) { + System.out.println("Debugging Test VM: Skip writing due to -DReproduce"); + return; + } TestFramework.check(SERVER_PORT != -1, "Server port was not set correctly for flag and/or test VM " + "or method not called from flag or test VM"); try (Socket socket = new Socket(HOSTNAME, SERVER_PORT); @@ -775,7 +823,15 @@ public static void write(String msg, String type) { ) { out.print(msg); } catch (Exception e) { - TestFramework.fail("Failed to write to socket", e); + String failMsg = """ + + ########################################################### + Did you directly run the test VM (TestFrameworkExecution) + to reproduce a bug? + => Append the flag -DReproduce=true and try again! + ########################################################### + """; + TestRun.fail(failMsg, e); } if (TestFramework.VERBOSE) { System.out.println("Written " + type + " to socket:"); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index b6335bcda00..497bf530883 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -44,8 +44,18 @@ public class TestFrameworkExecution { try { WHITE_BOX = WhiteBox.getWhiteBox(); } catch (UnsatisfiedLinkError e) { - System.err.println("Did you call a test-related interface method from TestFramework in main() of your test? " + - "Make sure to only call setup/run methods and no checks/assertions from main() of your test!"); + System.err.println(""" + ########################################################## + - Did you call a test-related interface method from + TestFramework in main() of your test? Make sure to + only call setup/run methods and no checks or + assertions from main() of your test! + - Are you rerunning the test VM (TestFrameworkExecution) + directly after a JTreg run? Make sure to start it + from within JTwork/scratch and with the flag + -DReproduce=true! + ########################################################## + """); throw e; } } @@ -78,7 +88,7 @@ public class TestFrameworkExecution { private final HashMap testMethodMap = new HashMap<>(); private final List excludeList; private final List testList; - private List> helperClasses = null; + private Set> helperClasses = null; private final IREncodingPrinter irMatchRulePrinter; private final Class testClass; private final Map forceCompileMap = new HashMap<>(); @@ -135,7 +145,7 @@ private void addHelperClasses(String[] args) { Class[] helperClasses = getHelperClasses(args); if (helperClasses != null) { TestRun.check(Arrays.stream(helperClasses).noneMatch(Objects::isNull), "A Helper class cannot be null"); - this.helperClasses = new ArrayList<>(); + this.helperClasses = new HashSet<>(); for (Class helperClass : helperClasses) { TestRun.check(!this.helperClasses.contains(helperClass), "Cannot add the same class twice: " + helperClass); @@ -174,6 +184,8 @@ private void start() { if (helperClasses != null) { for (Class helperClass : helperClasses) { // Process the helper classes and apply the explicit compile commands + TestFormat.checkNoThrow(helperClass != testClass, + "Cannot specify test " + testClass + " as helper class, too."); checkHelperClass(helperClass); processControlAnnotations(helperClass); } @@ -194,7 +206,7 @@ private void checkTestAnnotationInnerClass(Class c, String clazzType) { Method[] methods = c.getDeclaredMethods(); for (Method m : methods) { TestFormat.checkNoThrow(getAnnotation(m, Test.class) == null, - "Cannot use @Test annotation in " + clazzType + " class: " + m); + "Cannot use @Test annotation in " + clazzType + " " + c + " at " + m); } } @@ -452,7 +464,7 @@ private void addTest(Method m) { } if (PRINT_VALID_IR_RULES) { - irMatchRulePrinter.emitRuleEncoding(m); + irMatchRulePrinter.emitRuleEncoding(m, testAnno.compLevel()); } if (!XCOMP) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMException.java new file mode 100644 index 00000000000..ac4e8df4983 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMException.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +public class TestVMException extends RuntimeException { + static final boolean REPORT_STDOUT = Boolean.parseBoolean(System.getProperty("ReportStdout", "false")); + + private final JVMOutput vmOutput; + + TestVMException(JVMOutput vmOutput) { + super("There were one or multiple errors. Please check stderr for more information."); + this.vmOutput = vmOutput; + } + + public String getExceptionInfo() { + String errorMsg = "Command Line:\n" + vmOutput.getCommandLine() + "\n\n"; + int exitCode = vmOutput.getExitCode(); + String stdErr = vmOutput.getStderr(); + Scenario scenario = vmOutput.getScenario(); + String hintStdout = ""; + String stdOut = ""; + if (REPORT_STDOUT || TestFramework.VERBOSE || exitCode == 134) { + stdOut = "\n\nStandard Output\n---------------\n" + vmOutput.getOutput(); + } else { + hintStdout = """ + ########################################################### + To also get the standard output of the test VM run with\s + -DReportStdout=true or for even more fine-grained logging + use -DVerbose=true. + ########################################################### + + """; + } + return errorMsg + "TestFramework test VM exited with code " + exitCode + + stdOut + "\n\nError Output\n------------\n" + stdErr + "\n\n" + hintStdout; + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java index 02d298eb8ac..169ec684a12 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java @@ -80,6 +80,7 @@ public static void main(String[] args) throws Exception { Asserts.assertTrue(m.find()); new TestFramework(TestWarmup.class).setDefaultWarmup(500).start(); + TestFramework.run(ExplicitSkip.class); } @Test @@ -355,3 +356,21 @@ public void checkTest2(TestInfo info) { } } } + + +class ExplicitSkip { + int iFld; + + // Test skipped and thus also no IR verification should be done. + @Test(compLevel = CompLevel.SKIP) + @IR(counts = {IRNode.STORE_I, "1"}) + public int test(int x) { + iFld = x; + return x; + } + + @Run(test = "test") + public void run(RunInfo info) { + test(34); + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java index 59f1d8af083..9bf6beeeae5 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java @@ -210,17 +210,14 @@ public static void main(String[] args) { } private static void runWithArguments(Class clazz, String... args) { - TestFramework.runWithScenarios(clazz, new Scenario(0, args)); + TestFramework.runWithFlags(clazz, args); } private static void runCheck(String[] args , Constraint... constraints) { try { - Scenario s = new Scenario(0, args); - TestFramework.runWithScenarios(constraints[0].getKlass(), s); // All constraints have the same class. + TestFramework.runWithFlags(constraints[0].getKlass(), args); // All constraints have the same class. shouldNotReach(); - } catch (ShouldNotReachException e) { - throw e; - } catch (RuntimeException e) { + } catch (IRViolationException e) { checkConstraints(e, constraints); } } @@ -229,9 +226,7 @@ private static void runCheck(Constraint... constraints) { try { TestFramework.run(constraints[0].getKlass()); // All constraints have the same class. shouldNotReach(); - } catch (ShouldNotReachException e) { - throw e; - } catch (RuntimeException e) { + } catch (IRViolationException e) { checkConstraints(e, constraints); } } @@ -252,10 +247,9 @@ private static void checkConstraints(RuntimeException e, Constraint[] constraint // Single constraint private static void runFailOnTestsArgs(Constraint constraint, String... args) { try { - Scenario scenario = new Scenario(0, args); - TestFramework.runWithScenarios(constraint.getKlass(), scenario); // All constraints have the same class. + TestFramework.runWithFlags(constraint.getKlass(), args); // All constraints have the same class. shouldNotReach(); - } catch (TestRunException e) { + } catch (IRViolationException e) { constraint.checkConstraint(e); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java index 36075ddabbb..0db15f4c119 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java @@ -23,41 +23,46 @@ package jdk.test.lib.hotspot.ir_framework.tests; -import jdk.test.lib.hotspot.ir_framework.CompLevel; -import jdk.test.lib.hotspot.ir_framework.ForceCompile; -import jdk.test.lib.hotspot.ir_framework.Test; -import jdk.test.lib.hotspot.ir_framework.TestFramework; +import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; public class TestWithHelperClasses { public static void main(String[] args) { - int exceptionsCaught = 0; TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class, Helper2.class); try { TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class); - } catch (Exception e) { - Asserts.assertFalse(e.getMessage().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper1.foo() should have been C2 compiled")); + shouldNotReach(); + } catch (TestVMException e) { + Asserts.assertFalse(e.getExceptionInfo().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper1.foo() should have been C2 compiled")); Asserts.assertFalse(TestFramework.getLastTestVMOutput().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper1.foo() should have been C2 compiled")); Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper2.foo() should have been C2 compiled")); - Asserts.assertTrue(e.getMessage().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper2.foo() should have been C2 compiled")); + Asserts.assertTrue(e.getExceptionInfo().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper2.foo() should have been C2 compiled")); Asserts.assertFalse(TestFramework.getLastTestVMOutput().contains("Should not be executed")); - Asserts.assertFalse(e.getMessage().contains("Should not be executed")); - exceptionsCaught++; + Asserts.assertFalse(e.getExceptionInfo().contains("Should not be executed")); } + try { TestFramework.runWithHelperClasses(BadHelperClasses.class, BadHelper.class); - } catch (Exception e) { - Asserts.assertTrue(e.getMessage().contains("Cannot use @Test annotation in helper class:")); + shouldNotReach(); + } catch (TestFormatException e) { + Asserts.assertTrue(e.getMessage().contains("Cannot use @Test annotation in helper class")); Asserts.assertTrue(e.getMessage().contains("noTestInHelper")); - exceptionsCaught++; } - if (exceptionsCaught != 2) { - throw new RuntimeException("Did not catch " + exceptionsCaught + " exceptions!"); + try { + TestFramework.runWithHelperClasses(TestAsHelper.class, TestAsHelper.class); + shouldNotReach(); + } catch (TestFormatException e) { + Asserts.assertTrue(e.getMessage().contains("Cannot specify test class jdk.test.lib.hotspot.ir_framework." + + "tests.TestAsHelper as helper class, too")); } } + public static void shouldNotReach() { + throw new RuntimeException("should not reach"); + } + @Test public void test() throws NoSuchMethodException { TestFramework.assertCompiledByC2(Helper1.class.getMethod("foo")); @@ -82,6 +87,12 @@ public void foo() { } } +class TestAsHelper { + + @Test + public void foo() {} +} + class Helper1 { @ForceCompile(CompLevel.C2) From 605aba65f336c01db083f1b1f640a10cd4f9fa9b Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 24 Mar 2021 17:25:12 +0100 Subject: [PATCH 070/131] Throw FormatViolation for nested helper inside test class (implicit helper) --- .../lib/hotspot/ir_framework/TestFrameworkExecution.java | 6 ++++++ .../hotspot/ir_framework/tests/TestWithHelperClasses.java | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 497bf530883..6f461e01d91 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -148,6 +148,12 @@ private void addHelperClasses(String[] args) { this.helperClasses = new HashSet<>(); for (Class helperClass : helperClasses) { + if (Arrays.stream(testClass.getDeclaredClasses()).anyMatch(c -> c == helperClass)) { + // Nested class of test class is automatically treated as helper class + TestFormat.failNoThrow("Nested " + helperClass + " inside test " + testClass + " is implicitly" + + " treated as helper class and does not need to be specified as such."); + continue; + } TestRun.check(!this.helperClasses.contains(helperClass), "Cannot add the same class twice: " + helperClass); this.helperClasses.add(helperClass); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java index 0db15f4c119..a07ca9862b2 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java @@ -57,6 +57,14 @@ public static void main(String[] args) { Asserts.assertTrue(e.getMessage().contains("Cannot specify test class jdk.test.lib.hotspot.ir_framework." + "tests.TestAsHelper as helper class, too")); } + + try { + TestFramework.runWithHelperClasses(TestWithHelperClasses.class, NestedHelper.class); + shouldNotReach(); + } catch (TestFormatException e) { + Asserts.assertTrue(e.getMessage().contains("Nested class")); + Asserts.assertTrue(e.getMessage().contains("TestWithHelperClasses$NestedHelper inside test class")); + } } public static void shouldNotReach() { From ef992a1f8cb1af544894f736a4a6c2564259e766 Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Wed, 24 Mar 2021 22:19:13 -0700 Subject: [PATCH 071/131] Synced scenarios with the ones in the test from master valhalla ws --- .../compiler/valhalla/inlinetypes/TestCallingConvention.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java index 58eb5628442..f452a927f3c 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java @@ -75,6 +75,7 @@ public static void main(String[] args) { scenarios[0].addFlags("-Dsun.reflect.inflationThreshold=10000"); scenarios[1].addFlags("-Dsun.reflect.inflationThreshold=10000"); scenarios[3].addFlags("-XX:FlatArrayElementMaxSize=0"); + scenarios[4].addFlags("-XX:-UseTLAB"); testFramework.addScenarios(scenarios) .addHelperClasses(MyValue1.class, From f1914449ee8e5a76e68bbc481848ec8f19a58e18 Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Wed, 24 Mar 2021 22:52:04 -0700 Subject: [PATCH 072/131] Converted tests to new IR framework --- .../valhalla/inlinetypes/InlineTypes.java | 65 +++- .../inlinetypes/TestGetfieldChains.java | 138 ++++--- .../valhalla/inlinetypes/TestIntrinsics.java | 350 ++++++++++-------- 3 files changed, 297 insertions(+), 256 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java index 158af6db8dd..01191d2c2d0 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java @@ -1,9 +1,50 @@ +/* + * Copyright (c) 2021, 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.valhalla.inlinetypes; import jdk.test.lib.Asserts; import jdk.test.lib.Utils; import jdk.test.lib.hotspot.ir_framework.*; +// This class should not be moved. +// TestGetfieldChains has hard codded line numbers for NamedRectangle methods +class NamedRectangle { + Rectangle rect = new Rectangle(); + String name = ""; + + static int getP1X(NamedRectangle nr) { + return nr.rect + .p1 + .x; + } + + static Point getP1(NamedRectangle nr) { + return nr.rect + .p1; + } +} + public class InlineTypes { public static final int rI = Utils.getRandomInstance().nextInt() % 1000; public static final long rL = Utils.getRandomInstance().nextLong() % 1000; @@ -128,28 +169,12 @@ abstract class MyAbstract implements MyInterface { } -final primitive class MyValueEmpty implements MyInterface { +final primitive class MyValueEmpty extends MyAbstract { public long hash() { return 0; } public MyValueEmpty copy(MyValueEmpty other) { return other; } } -class NamedRectangle { - Rectangle rect = new Rectangle(); - String name = ""; - - static int getP1X(NamedRectangle nr) { - return nr.rect - .p1 - .x; - } - - static Point getP1(NamedRectangle nr) { - return nr.rect - .p1; - } -} - primitive class Point { int x = 4; int y = 7; @@ -173,7 +198,7 @@ static SimpleInlineType create() { } @ForceCompileClassInitializer -final primitive class MyValue1 implements MyInterface { +final primitive class MyValue1 extends MyAbstract { static int s; static final long sf = InlineTypes.rL; final int x; @@ -341,7 +366,7 @@ public static MyValue2Inline createWithFieldsInline(double d, long l) { } @ForceCompileClassInitializer -final primitive class MyValue2 implements MyInterface { +final primitive class MyValue2 extends MyAbstract { final int x; final byte y; final MyValue2Inline v; @@ -641,7 +666,7 @@ public long hash() { // Inline type definition with too many fields to return in registers @ForceCompileClassInitializer -final primitive class MyValue4 implements MyInterface { +final primitive class MyValue4 extends MyAbstract { final MyValue3 v1; final MyValue3 v2; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java index bb984e3d5ae..4a1fa7df4f2 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, 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 @@ -30,94 +30,82 @@ import java.util.Arrays; import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; + /* * @test * @key randomness * @summary Verify that chains of getfields on flattened fields are correctly optimized - * @library /testlibrary /test/lib /compiler/whitebox / + * @library /test/lib * @requires os.simpleArch == "x64" - * @compile TestGetfieldChains.java NamedRectangle.java Rectangle.java Point.java GetfieldChains.jcod - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestGetfieldChains + * @compile InlineTypes.java GetfieldChains.jcod + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestGetfieldChains */ - -public class TestGetfieldChains extends InlineTypeTest { - public static final int C1 = COMP_LEVEL_SIMPLE; - public static final int C2 = COMP_LEVEL_FULL_OPTIMIZATION; - - public static void main(String[] args) throws Throwable { - TestGetfieldChains test = new TestGetfieldChains(); - test.run(args, TestGetfieldChains.class); - } - - @Override - public int getNumScenarios() { - return 5; - } - - @Override - public String[] getVMParameters(int scenario) { - switch (scenario) { - case 0: return new String[] { // C1 only - "-XX:TieredStopAtLevel=1", - "-XX:+TieredCompilation", - }; - case 1: return new String[] { // C2 only. (Make sure the tests are correctly written) - "-XX:TieredStopAtLevel=4", - "-XX:-TieredCompilation", - "-XX:-OmitStackTraceInFastThrow", - }; - case 2: return new String[] { // interpreter only - "-Xint", - }; - case 3: return new String[] { - // Xcomp Only C1. - "-XX:TieredStopAtLevel=1", - "-XX:+TieredCompilation", - "-Xcomp", - }; - case 4: return new String[] { - // Xcomp Only C2. - "-XX:TieredStopAtLevel=4", - "-XX:-TieredCompilation", - "-XX:-OmitStackTraceInFastThrow", - "-Xcomp", - }; - } - return null; +public class TestGetfieldChains { + + public static void main(String[] args) { + + final Scenario[] scenarios = { + new Scenario(0, + // C1 only + "-XX:TieredStopAtLevel=1", + "-XX:+TieredCompilation"), + new Scenario(1, + // C2 only. (Make sure the tests are correctly written) + "-XX:TieredStopAtLevel=4", + "-XX:-TieredCompilation", + "-XX:-OmitStackTraceInFastThrow"), + new Scenario(2, + // interpreter only + "-Xint"), + new Scenario(3, + // Xcomp Only C1. + "-XX:TieredStopAtLevel=1", + "-XX:+TieredCompilation", + "-Xcomp"), + new Scenario(4, + // Xcomp Only C2. + "-XX:TieredStopAtLevel=4", + "-XX:-TieredCompilation", + "-XX:-OmitStackTraceInFastThrow", + "-Xcomp") + }; + + + TestFramework testFramework = new TestFramework(TestGetfieldChains.class); + testFramework.addScenarios(scenarios) + .start(); } + // Simple chain of getfields ending with primitive field - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public int test1() { return NamedRectangle.getP1X(new NamedRectangle()); } - @DontCompile - public void test1_verifier(boolean warmup) { + @Run(test = "test1") + public void test1_verifier(RunInfo info) { int res = test1(); Asserts.assertEQ(res, 4); } // Simple chain of getfields ending with a flattened field - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public Point test2() { return NamedRectangle.getP1(new NamedRectangle()); } - @DontCompile - public void test2_verifier(boolean warmup) { + @Run(test = "test2") + public void test2_verifier(RunInfo info) { Point p = test2(); Asserts.assertEQ(p.x, 4); Asserts.assertEQ(p.y, 7); } // Chain of getfields but the initial receiver is null - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public NullPointerException test3() { NullPointerException npe = null; try { @@ -128,17 +116,17 @@ public NullPointerException test3() { return npe; } - @DontCompile - public void test3_verifier(boolean warmup) { + @Run(test = "test3") + public void test3_verifier(RunInfo info) { NullPointerException npe = test3(); Asserts.assertNE(npe, null); StackTraceElement st = npe.getStackTrace()[0]; Asserts.assertEQ(st.getMethodName(), "getP1X"); - Asserts.assertEQ(st.getLineNumber(), 31); // line number depends on file NamedRectangle.java + Asserts.assertEQ(st.getLineNumber(), 37); // line number depends on file NamedRectangle.java } // Chain of getfields but one getfield in the middle of the chain trigger an illegal access - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public IllegalAccessError test4() { IllegalAccessError iae = null; try { @@ -149,8 +137,8 @@ public IllegalAccessError test4() { return iae; } - @DontCompile - public void test4_verifier(boolean warmup) { + @Run(test = "test4") + public void test4_verifier(RunInfo info) { IllegalAccessError iae = test4(); Asserts.assertNE(iae, null); StackTraceElement st = iae.getStackTrace()[0]; @@ -160,7 +148,7 @@ public void test4_verifier(boolean warmup) { } // Chain of getfields but the last getfield trigger a NoSuchFieldError - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public NoSuchFieldError test5() { NoSuchFieldError nsfe = null; try { @@ -171,8 +159,8 @@ public NoSuchFieldError test5() { return nsfe; } - @DontCompile - public void test5_verifier(boolean warmup) { + @Run(test = "test5") + public void test5_verifier(RunInfo info) { NoSuchFieldError nsfe = test5(); Asserts.assertNE(nsfe, null); StackTraceElement st = nsfe.getStackTrace()[0]; @@ -191,26 +179,26 @@ static primitive class Container { EmptyContainer container1 = new EmptyContainer(); } - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public EmptyType test6() { Container c = new Container(); return c.container1.et; } - @DontCompile - public void test6_verifier(boolean warmup) { + @Run(test = "test6") + public void test6_verifier(RunInfo info) { EmptyType et = test6(); Asserts.assertEQ(et, EmptyType.default); } - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public EmptyType test7() { Container[] ca = new Container[10]; return ca[3].container0.et; } - @DontCompile - public void test7_verifier(boolean warmup) { + @Run(test = "test7") + public void test7_verifier(RunInfo info) { EmptyType et = test7(); Asserts.assertEQ(et, EmptyType.default); } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java index 823a0156d31..01427403e63 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -31,34 +31,40 @@ import jdk.test.lib.Asserts; import jdk.internal.misc.Unsafe; +import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; + /* * @test * @key randomness * @summary Test intrinsic support for inline types - * @library /testlibrary /test/lib /compiler/whitebox / + * @library /test/lib * @modules java.base/jdk.internal.misc * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile TestIntrinsics.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestIntrinsics + * @compile InlineTypes.java + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestIntrinsics */ -public class TestIntrinsics extends InlineTypeTest { - // Extra VM parameters for some test scenarios. See InlineTypeTest.getVMParameters() - @Override - public String[] getExtraVMParameters(int scenario) { - switch (scenario) { - case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"}; - case 4: return new String[] {"-XX:-MonomorphicArrayCheck"}; + +public class TestIntrinsics { + + public static void main(String[] args) { + + Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; + for (Scenario scenario: scenarios) { + scenario.addFlags("--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"); } - return null; - } + scenarios[3].addFlags("-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"); + scenarios[4].addFlags("-XX:-MonomorphicArrayCheck"); - public static void main(String[] args) throws Throwable { - TestIntrinsics test = new TestIntrinsics(); - test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class); + TestFramework testFramework = new TestFramework(TestIntrinsics.class); + testFramework.addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class) + .start(); } // Test correctness of the Class::isAssignableFrom intrinsic @@ -67,8 +73,8 @@ public boolean test1(Class supercls, Class subcls) { return supercls.isAssignableFrom(subcls); } - @DontCompile - public void test1_verifier(boolean warmup) { + @Run(test = "test1") + public void test1_verifier(RunInfo info) { Asserts.assertTrue(test1(java.util.AbstractList.class, java.util.ArrayList.class), "test1_1 failed"); Asserts.assertTrue(test1(MyValue1.ref.class, MyValue1.ref.class), "test1_2 failed"); Asserts.assertTrue(test1(MyValue1.class, MyValue1.class), "test1_3 failed"); @@ -82,7 +88,8 @@ public void test1_verifier(boolean warmup) { } // Verify that Class::isAssignableFrom checks with statically known classes are folded - @Test(failOn = LOADK) + @Test + @IR(failOn = {LOADK}) public boolean test2() { boolean check1 = java.util.AbstractList.class.isAssignableFrom(java.util.ArrayList.class); boolean check2 = MyValue1.ref.class.isAssignableFrom(MyValue1.ref.class); @@ -97,8 +104,8 @@ public boolean test2() { return check1 && check2 && check3 && check4 && check5 && check6 && check7 && check8 && check9 && check10; } - @DontCompile - public void test2_verifier(boolean warmup) { + @Run(test = "test2") + public void test2_verifier(RunInfo info) { Asserts.assertTrue(test2(), "test2 failed"); } @@ -108,8 +115,8 @@ public Class test3(Class cls) { return cls.getSuperclass(); } - @DontCompile - public void test3_verifier(boolean warmup) { + @Run(test = "test3") + public void test3_verifier(RunInfo info) { Asserts.assertTrue(test3(Object.class) == null, "test3_1 failed"); Asserts.assertTrue(test3(MyValue1.ref.class) == MyAbstract.class, "test3_2 failed"); Asserts.assertTrue(test3(MyValue1.val.class) == MyValue1.ref.class, "test3_3 failed"); @@ -117,7 +124,8 @@ public void test3_verifier(boolean warmup) { } // Verify that Class::getSuperclass checks with statically known classes are folded - @Test(failOn = LOADK) + @Test + @IR(failOn = {LOADK}) public boolean test4() { boolean check1 = Object.class.getSuperclass() == null; // TODO 8244562: Remove cast as workaround once javac is fixed @@ -128,8 +136,8 @@ public boolean test4() { return check1 && check2 && check3 && check4; } - @DontCompile - public void test4_verifier(boolean warmup) { + @Run(test = "test4") + public void test4_verifier(RunInfo info) { Asserts.assertTrue(test4(), "test4 failed"); } @@ -139,8 +147,8 @@ public String test5(MyValue1 v) { return v.toString(); } - @DontCompile - public void test5_verifier(boolean warmup) { + @Run(test = "test5") + public void test5_verifier(RunInfo info) { MyValue1 v = MyValue1.createDefaultInline(); test5(v); } @@ -151,8 +159,8 @@ public int test6(MyValue1 v) { return v.hashCode(); } - @DontCompile - public void test6_verifier(boolean warmup) { + @Run(test = "test6") + public void test6_verifier(RunInfo info) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); int res = test6(v); Asserts.assertEQ(res, v.hashCode()); @@ -165,8 +173,8 @@ public Object[] test7(Class componentType, int len) { return va; } - @DontCompile - public void test7_verifier(boolean warmup) { + @Run(test = "test7") + public void test7_verifier(RunInfo info) { int len = Math.abs(rI) % 42; long hash = MyValue1.createDefaultDontInline().hashPrimitive(); Object[] va = test7(MyValue1.class, len); @@ -181,8 +189,8 @@ public boolean test8(Class c, MyValue1 vt) { return c.isInstance(vt); } - @DontCompile - public void test8_verifier(boolean warmup) { + @Run(test = "test8") + public void test8_verifier(RunInfo info) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); boolean result = test8(MyValue1.class, vt); Asserts.assertTrue(result); @@ -195,8 +203,8 @@ public boolean test9(Class c, MyValue1 vt) { return c.isInstance(vt); } - @DontCompile - public void test9_verifier(boolean warmup) { + @Run(test = "test9") + public void test9_verifier(RunInfo info) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); boolean result = test9(MyValue2.class, vt); Asserts.assertFalse(result); @@ -210,8 +218,8 @@ public Object test10(Class c, MyValue1 vt) { return c.cast(vt); } - @DontCompile - public void test10_verifier(boolean warmup) { + @Run(test = "test10") + public void test10_verifier(RunInfo info) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); Object result = test10(MyValue1.class, vt); Asserts.assertEQ(((MyValue1)result).hash(), vt.hash()); @@ -222,8 +230,8 @@ public Object test11(Class c, MyValue1 vt) { return c.cast(vt); } - @DontCompile - public void test11_verifier(boolean warmup) { + @Run(test = "test11") + public void test11_verifier(RunInfo info) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); try { test11(MyValue2.class, vt); @@ -237,8 +245,8 @@ public Object test12(MyValue1 vt) { return MyValue1.class.cast(vt); } - @DontCompile - public void test12_verifier(boolean warmup) { + @Run(test = "test12") + public void test12_verifier(RunInfo info) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); Object result = test12(vt); Asserts.assertEQ(((MyValue1)result).hash(), vt.hash()); @@ -249,8 +257,8 @@ public Object test13(MyValue1 vt) { return MyValue2.class.cast(vt); } - @DontCompile - public void test13_verifier(boolean warmup) { + @Run(test = "test13") + public void test13_verifier(RunInfo info) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); try { test13(vt); @@ -268,8 +276,8 @@ public void test14(int len, long hash) { } } - @DontCompile - public void test14_verifier(boolean warmup) { + @Run(test = "test14") + public void test14_verifier(RunInfo info) { int len = Math.abs(rI) % 42; long hash = MyValue1.createDefaultDontInline().hashPrimitive(); test14(len, hash); @@ -281,8 +289,8 @@ public int test15(Object v) { return v.hashCode(); } - @DontCompile - public void test15_verifier(boolean warmup) { + @Run(test = "test15") + public void test15_verifier(RunInfo info) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); int res = test15(v); Asserts.assertEQ(res, v.hashCode()); @@ -293,8 +301,8 @@ public int test16(Object v) { return System.identityHashCode(v); } - @DontCompile - public void test16_verifier(boolean warmup) { + @Run(test = "test16") + public void test16_verifier(RunInfo info) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); int res = test16(v); Asserts.assertEQ(res, System.identityHashCode((Object)v)); @@ -305,8 +313,8 @@ public int test17(Object v) { return System.identityHashCode(v); } - @DontCompile - public void test17_verifier(boolean warmup) { + @Run(test = "test17") + public void test17_verifier(RunInfo info) { Integer v = Integer.valueOf(rI); int res = test17(v); Asserts.assertEQ(res, System.identityHashCode(v)); @@ -317,8 +325,8 @@ public int test18(Object v) { return System.identityHashCode(v); } - @DontCompile - public void test18_verifier(boolean warmup) { + @Run(test = "test18") + public void test18_verifier(RunInfo info) { Object v = null; int res = test18(v); Asserts.assertEQ(res, System.identityHashCode(v)); @@ -331,8 +339,8 @@ public int test19(MyValue1 vt1, MyValue1 vt2, boolean b) { return res.hashCode(); } - @DontCompile - public void test19_verifier(boolean warmup) { + @Run(test = "test19") + public void test19_verifier(RunInfo info) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); int res = test19(vt, vt, true); Asserts.assertEQ(res, vt.hashCode()); @@ -346,8 +354,8 @@ public String test20(MyValue1 vt1, MyValue1 vt2, boolean b) { return res.toString(); } - @DontCompile - public void test20_verifier(boolean warmup) { + @Run(test = "test20") + public void test20_verifier(RunInfo info) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); String res = test20(vt, vt, true); Asserts.assertEQ(res, vt.toString()); @@ -376,20 +384,22 @@ public void test20_verifier(boolean warmup) { protected static final String CALL_Unsafe = START + "CallStaticJava" + MID + "# Static jdk.internal.misc.Unsafe::" + END; - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public int test21(MyValue1 v) { return U.getInt(v, X_OFFSET); } - @DontCompile - public void test21_verifier(boolean warmup) { + @Run(test = "test21") + public void test21_verifier(RunInfo info) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); int res = test21(v); Asserts.assertEQ(res, v.x); } MyValue1 test22_vt; - @Test(failOn=CALL_Unsafe + ALLOC) + @Test + @IR(failOn = {CALL_Unsafe, ALLOC}) public void test22(MyValue1 v) { v = U.makePrivateBuffer(v); U.putInt(v, X_OFFSET, rI); @@ -397,20 +407,21 @@ public void test22(MyValue1 v) { test22_vt = v; } - @DontCompile - public void test22_verifier(boolean warmup) { + @Run(test = "test22") + public void test22_verifier(RunInfo info) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); test22(v.setX(v, 0)); Asserts.assertEQ(test22_vt.hash(), v.hash()); } - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public int test23(MyValue1 v, long offset) { return U.getInt(v, offset); } - @DontCompile - public void test23_verifier(boolean warmup) { + @Run(test = "test23") + public void test23_verifier(RunInfo info) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); int res = test23(v, X_OFFSET); Asserts.assertEQ(res, v.x); @@ -418,13 +429,14 @@ public void test23_verifier(boolean warmup) { MyValue1 test24_vt = MyValue1.createWithFieldsInline(rI, rL); - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public int test24(long offset) { return U.getInt(test24_vt, offset); } - @DontCompile - public void test24_verifier(boolean warmup) { + @Run(test = "test24") + public void test24_verifier(RunInfo info) { int res = test24(X_OFFSET); Asserts.assertEQ(res, test24_vt.x); } @@ -446,8 +458,8 @@ public Test25Value[] test25(Test25Value element) { return (Test25Value[]) newArray; } - @DontCompile - public void test25_verifier(boolean warmup) { + @Run(test = "test25") + public void test25_verifier(RunInfo info) { Test25Value vt = new Test25Value(); test25(vt); } @@ -462,8 +474,8 @@ public Object test26() { return Array.newInstance(ca[0], 1); } - @DontCompile - public void test26_verifier(boolean warmup) { + @Run(test = "test26") + public void test26_verifier(RunInfo info) { Object[] res = (Object[])test26(); Asserts.assertEQ(((MyValue1)res[0]).hashPrimitive(), MyValue1.createDefaultInline().hashPrimitive()); } @@ -480,25 +492,27 @@ public void test26_verifier(boolean warmup) { } } - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public MyValue1 test27() { return (MyValue1)U.getReference(this, TEST27_OFFSET); } - @DontCompile - public void test27_verifier(boolean warmup) { + @Run(test = "test27") + public void test27_verifier(RunInfo info) { MyValue1 res = test27(); Asserts.assertEQ(res.hash(), test24_vt.hash()); } // Mismatched type - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public int test28(MyValue1 v) { return U.getByte(v, X_OFFSET); } - @DontCompile - public void test28_verifier(boolean warmup) { + @Run(test = "test28") + public void test28_verifier(RunInfo info) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); int res = test28(v); if (java.nio.ByteOrder.nativeOrder() == java.nio.ByteOrder.LITTLE_ENDIAN) { @@ -509,7 +523,8 @@ public void test28_verifier(boolean warmup) { } // Wrong alignment - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public long test29(MyValue1 v) { // Read the field that's guaranteed to not be last in the // inline type so we don't read out of bounds. @@ -519,8 +534,8 @@ public long test29(MyValue1 v) { return U.getLong(v, Y_OFFSET+1); } - @DontCompile - public void test29_verifier(boolean warmup) { + @Run(test = "test29") + public void test29_verifier(RunInfo info) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); long res = test29(v); if (java.nio.ByteOrder.nativeOrder() == java.nio.ByteOrder.LITTLE_ENDIAN) { @@ -538,8 +553,10 @@ public void test29_verifier(boolean warmup) { } } + // getValue to retrieve flattened field from inline type - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public MyValue2 test30(MyValue1 v) { if (V1_FLATTENED) { return U.getValue(v, V1_OFFSET, MyValue2.val.class); @@ -547,8 +564,8 @@ public MyValue2 test30(MyValue1 v) { return (MyValue2)U.getReference(v, V1_OFFSET); } - @DontCompile - public void test30_verifier(boolean warmup) { + @Run(test = "test30") + public void test30_verifier(RunInfo info) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue2 res = test30(v); Asserts.assertEQ(res.hash(), v.v1.hash()); @@ -568,7 +585,8 @@ public void test30_verifier(boolean warmup) { } // getValue to retrieve flattened field from object - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public MyValue1 test31() { if (TEST31_VT_FLATTENED) { return U.getValue(this, TEST31_VT_OFFSET, MyValue1.val.class); @@ -576,15 +594,16 @@ public MyValue1 test31() { return (MyValue1)U.getReference(this, TEST31_VT_OFFSET); } - @DontCompile - public void test31_verifier(boolean warmup) { + @Run(test = "test31") + public void test31_verifier(RunInfo info) { test31_vt = MyValue1.createWithFieldsInline(rI, rL); MyValue1 res = test31(); Asserts.assertEQ(res.hash(), test31_vt.hash()); } // putValue to set flattened field in object - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public void test32(MyValue1 vt) { if (TEST31_VT_FLATTENED) { U.putValue(this, TEST31_VT_OFFSET, MyValue1.val.class, vt); @@ -593,8 +612,8 @@ public void test32(MyValue1 vt) { } } - @DontCompile - public void test32_verifier(boolean warmup) { + @Run(test = "test32") + public void test32_verifier(RunInfo info) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); test31_vt = MyValue1.createDefaultInline(); test32(vt); @@ -614,7 +633,8 @@ public void test32_verifier(boolean warmup) { } } // getValue to retrieve flattened field from array - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public MyValue1 test33(MyValue1[] arr) { if (TEST33_FLATTENED_ARRAY) { return U.getValue(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE, MyValue1.val.class); @@ -622,8 +642,8 @@ public MyValue1 test33(MyValue1[] arr) { return (MyValue1)U.getReference(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE); } - @DontCompile - public void test33_verifier(boolean warmup) { + @Run(test = "test33") + public void test33_verifier(RunInfo info) { MyValue1[] arr = new MyValue1[2]; MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); arr[1] = vt; @@ -632,7 +652,8 @@ public void test33_verifier(boolean warmup) { } // putValue to set flattened field in array - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public void test34(MyValue1[] arr, MyValue1 vt) { if (TEST33_FLATTENED_ARRAY) { U.putValue(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE, MyValue1.val.class, vt); @@ -641,8 +662,8 @@ public void test34(MyValue1[] arr, MyValue1 vt) { } } - @DontCompile - public void test34_verifier(boolean warmup) { + @Run(test = "test34") + public void test34_verifier(RunInfo info) { MyValue1[] arr = new MyValue1[2]; MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); test34(arr, vt); @@ -651,7 +672,8 @@ public void test34_verifier(boolean warmup) { // getValue to retrieve flattened field from object with unknown // container type - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public MyValue1 test35(Object o) { if (TEST31_VT_FLATTENED) { return U.getValue(o, TEST31_VT_OFFSET, MyValue1.val.class); @@ -659,8 +681,8 @@ public MyValue1 test35(Object o) { return (MyValue1)U.getReference(o, TEST31_VT_OFFSET); } - @DontCompile - public void test35_verifier(boolean warmup) { + @Run(test = "test35") + public void test35_verifier(RunInfo info) { test31_vt = MyValue1.createWithFieldsInline(rI, rL); MyValue1 res = test35(this); Asserts.assertEQ(res.hash(), test31_vt.hash()); @@ -668,7 +690,8 @@ public void test35_verifier(boolean warmup) { // getValue to retrieve flattened field from object at unknown // offset - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public MyValue1 test36(long offset) { if (TEST31_VT_FLATTENED) { return U.getValue(this, offset, MyValue1.val.class); @@ -676,8 +699,8 @@ public MyValue1 test36(long offset) { return (MyValue1)U.getReference(this, offset); } - @DontCompile - public void test36_verifier(boolean warmup) { + @Run(test = "test36") + public void test36_verifier(RunInfo info) { test31_vt = MyValue1.createWithFieldsInline(rI, rL); MyValue1 res = test36(TEST31_VT_OFFSET); Asserts.assertEQ(res.hash(), test31_vt.hash()); @@ -685,7 +708,8 @@ public void test36_verifier(boolean warmup) { // putValue to set flattened field in object with unknown // container - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public void test37(Object o, MyValue1 vt) { if (TEST31_VT_FLATTENED) { U.putValue(o, TEST31_VT_OFFSET, MyValue1.val.class, vt); @@ -694,8 +718,8 @@ public void test37(Object o, MyValue1 vt) { } } - @DontCompile - public void test37_verifier(boolean warmup) { + @Run(test = "test37") + public void test37_verifier(RunInfo info) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); test31_vt = MyValue1.createDefaultInline(); test37(this, vt); @@ -704,7 +728,8 @@ public void test37_verifier(boolean warmup) { // putValue to set flattened field in object, non inline argument // to store - @Test(match = { CALL_Unsafe }, matchCount = { 1 }) + @Test + @IR(counts = {CALL_Unsafe, "= 1"}) public void test38(Object o) { if (TEST31_VT_FLATTENED) { U.putValue(this, TEST31_VT_OFFSET, MyValue1.val.class, o); @@ -713,15 +738,16 @@ public void test38(Object o) { } } - @DontCompile - public void test38_verifier(boolean warmup) { + @Run(test = "test38") + public void test38_verifier(RunInfo info) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); test31_vt = MyValue1.createDefaultInline(); test38(vt); Asserts.assertEQ(vt.hash(), test31_vt.hash()); } - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public MyValue1 test39(MyValue1 v) { v = U.makePrivateBuffer(v); U.putInt(v, X_OFFSET, rI); @@ -729,8 +755,8 @@ public MyValue1 test39(MyValue1 v) { return v; } - @DontCompile - public void test39_verifier(boolean warmup) { + @Run(test = "test39") + public void test39_verifier(RunInfo info) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue1 res = test39(v.setX(v, 0)); Asserts.assertEQ(res.hash(), v.hash()); @@ -743,8 +769,8 @@ public Object[] test40(Class componentType, int len) { return va; } - @DontCompile - public void test40_verifier(boolean warmup) { + @Run(test = "test40") + public void test40_verifier(RunInfo info) { int len = Math.abs(rI) % 42; Object[] va = test40(MyValue1.ref.class, len); for (int i = 0; i < len; ++i) { @@ -758,8 +784,8 @@ public boolean test41(Class c, MyValue1.ref vt) { return c.isInstance(vt); } - @DontCompile - public void test41_verifier(boolean warmup) { + @Run(test = "test41") + public void test41_verifier(RunInfo info) { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); boolean result = test41(MyValue1.ref.class, vt); Asserts.assertTrue(result); @@ -772,8 +798,8 @@ public boolean test42(Class c, MyValue1.ref vt) { return c.isInstance(vt); } - @DontCompile - public void test42_verifier(boolean warmup) { + @Run(test = "test42") + public void test42_verifier(RunInfo info) { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); boolean result = test42(MyValue2.ref.class, vt); Asserts.assertFalse(result); @@ -787,8 +813,8 @@ public Object test43(Class c, MyValue1.ref vt) { return c.cast(vt); } - @DontCompile - public void test43_verifier(boolean warmup) { + @Run(test = "test43") + public void test43_verifier(RunInfo info) { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); Object result = test43(MyValue1.ref.class, vt); Asserts.assertEQ(((MyValue1)result).hash(), vt.hash()); @@ -801,8 +827,8 @@ public Object test44(Class c, MyValue1.ref vt) { return c.cast(vt); } - @DontCompile - public void test44_verifier(boolean warmup) { + @Run(test = "test44") + public void test44_verifier(RunInfo info) { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); try { test44(MyValue2.ref.class, vt); @@ -816,8 +842,8 @@ public Object test45(MyValue1.ref vt) { return MyValue1.ref.class.cast(vt); } - @DontCompile - public void test45_verifier(boolean warmup) { + @Run(test = "test45") + public void test45_verifier(RunInfo info) { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); Object result = test45(vt); Asserts.assertEQ(((MyValue1)result).hash(), vt.hash()); @@ -830,8 +856,8 @@ public Object test46(MyValue1.ref vt) { return MyValue2.ref.class.cast(vt); } - @DontCompile - public void test46_verifier(boolean warmup) { + @Run(test = "test46") + public void test46_verifier(RunInfo info) { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); test46(null); try { @@ -846,8 +872,8 @@ public Object test47(MyValue1.ref vt) { return MyValue1.val.class.cast(vt); } - @DontCompile - public void test47_verifier(boolean warmup) { + @Run(test = "test47") + public void test47_verifier(RunInfo info) { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); Object result = test47(vt); Asserts.assertEQ(((MyValue1)result).hash(), vt.hash()); @@ -863,8 +889,8 @@ public Object test48(Class c, MyValue1.ref vt) { return c.cast(vt); } - @DontCompile - public void test48_verifier(boolean warmup) { + @Run(test = "test48") + public void test48_verifier(RunInfo info) { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); Object result = test48(MyValue1.class, vt); Asserts.assertEQ(((MyValue1)result).hash(), vt.hash()); @@ -880,20 +906,21 @@ public Object test49(MyValue1 vt) { return MyValue1.ref.class.cast(vt); } - @DontCompile - public void test49_verifier(boolean warmup) { + @Run(test = "test49") + public void test49_verifier(RunInfo info) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); Object result = test49(vt); Asserts.assertEQ(((MyValue1)result).hash(), vt.hash()); } + @Test() public Object test50(Class c, Object obj) { return c.cast(obj); } - @DontCompile - public void test50_verifier(boolean warmup) { + @Run(test = "test50") + public void test50_verifier(RunInfo info) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); MyValue1[] va = new MyValue1[42]; MyValue1.ref[] vba = new MyValue1.ref[42]; @@ -928,8 +955,8 @@ public void test51(int len) { } } - @DontCompile - public void test51_verifier(boolean warmup) { + @Run(test = "test51") + public void test51_verifier(RunInfo info) { int len = Math.abs(rI) % 42; test51(len); } @@ -956,8 +983,8 @@ public Object[][] test52(int len, int val) { return result; } - @DontCompile - public void test52_verifier(boolean warmup) { + @Run(test = "test52") + public void test52_verifier(RunInfo info) { test52(1, 1); test52(1, 2); } @@ -1000,8 +1027,8 @@ public Object[][] test53(Class c1, Class c2, int len, int val) { return result; } - @DontCompile - public void test53_verifier(boolean warmup) { + @Run(test = "test53") + public void test53_verifier(RunInfo info) { int len = Math.abs(rI) % 42; test53(MyValue1[].class, MyValue1.ref[].class, len, 1); test53(MyValue1[].class, MyValue1.ref[].class, len, 2); @@ -1016,7 +1043,6 @@ public void test54_callee(MyValue1.ref v) { // Use .ref here to make sure the ar } @Test() - @Warmup(10000) // Fill up the TLAB to trigger slow path allocation public MyValue1 test54(MyValue1 v) { v = U.makePrivateBuffer(v); test54_callee(v); @@ -1024,8 +1050,9 @@ public MyValue1 test54(MyValue1 v) { return v; } - @DontCompile - public void test54_verifier(boolean warmup) { + @Run(test = "test54") + @Warmup(10000) // Fill up the TLAB to trigger slow path allocation + public void test54_verifier(RunInfo info) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue1 res = test54(v.setX(v, 0)); Asserts.assertEQ(res.hash(), v.hash()); @@ -1034,7 +1061,8 @@ public void test54_verifier(boolean warmup) { static final MyValue1 test55_vt = MyValue1.createWithFieldsInline(rI, rL); // Same as test30 but with constant field holder - @Test(failOn=CALL_Unsafe) + @Test + @IR(failOn = {CALL_Unsafe}) public MyValue2 test55() { if (V1_FLATTENED) { return U.getValue(test55_vt, V1_OFFSET, MyValue2.val.class); @@ -1042,8 +1070,8 @@ public MyValue2 test55() { return (MyValue2)U.getReference(test55_vt, V1_OFFSET); } - @DontCompile - public void test55_verifier(boolean warmup) { + @Run(test = "test55") + public void test55_verifier(RunInfo info) { MyValue2 res = test55(); Asserts.assertEQ(res.hash(), test55_vt.v1.hash()); } @@ -1057,8 +1085,8 @@ public void test56(int idx) { } } - @DontCompile - public void test56_verifier(boolean warmup) { + @Run(test = "test56") + public void test56_verifier(RunInfo info) { test56(0); } @@ -1071,8 +1099,8 @@ public void test57() { } } - @DontCompile - public void test57_verifier(boolean warmup) { + @Run(test = "test57") + public void test57_verifier(RunInfo info) { test57(); } @@ -1084,8 +1112,8 @@ public boolean test58(Class c1, Class c2) throws Exception { return obj1 == obj2; } - @DontCompile - public void test58_verifier(boolean warmup) throws Exception { + @Run(test = "test58") + public void test58_verifier(RunInfo info) throws Exception { boolean res = test58(MyValue1.class, MyValue1.class); Asserts.assertTrue(res); res = test58(Object.class, MyValue1.class); @@ -1103,8 +1131,8 @@ public void test59(Class c) throws Exception { } } - @DontCompile - public void test59_verifier(boolean warmup) throws Exception { + @Run(test = "test59") + public void test59_verifier(RunInfo info) throws Exception { test59(Integer.class); try { test59(MyValue1.class); @@ -1122,8 +1150,8 @@ public boolean test60(Class c1, Class c2, boolean b1, boolean b2) throws E return obj1 == obj2; } - @DontCompile - public void test60_verifier(boolean warmup) throws Exception { + @Run(test = "test60") + public void test60_verifier(RunInfo info) throws Exception { Asserts.assertTrue(test60(MyValue1.class, MyValue1.class, false, false)); Asserts.assertFalse(test60(MyValue1.class, MyValue2.class, false, false)); Asserts.assertFalse(test60(MyValue1.class, MyValue1.class, false, true)); From d8535e2be3ce4bf7c2164e9f8ad805cbd0a32a82 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 25 Mar 2021 13:55:39 +0100 Subject: [PATCH 073/131] Update some code style cleanups for converted tests --- .../valhalla/inlinetypes/TestArrays.java | 119 ++++++------- .../inlinetypes/TestBasicFunctionality.java | 19 +- .../compiler/valhalla/inlinetypes/TestC1.java | 11 +- .../inlinetypes/TestCallingConvention.java | 115 ++++++------ .../inlinetypes/TestGetfieldChains.java | 21 ++- .../valhalla/inlinetypes/TestIntrinsics.java | 167 +++++++++--------- .../tests/TestWithHelperClasses.java | 2 +- 7 files changed, 213 insertions(+), 241 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java index 755a5e524cc..1b5fc1d3f27 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java @@ -105,11 +105,11 @@ static void verify(MyValue2[] src, Object[] dst) { } } - static boolean compile_and_run_again_if_deoptimized(boolean warmup, String test) { - if (!warmup) { - Method m = testFramework.getTestMethod(test); - if (testFramework.isCompiled(m)) { - testFramework.compile(m, CompLevel.C2); + static boolean compile_and_run_again_if_deoptimized(RunInfo info) { + if (!info.isWarmUp()) { + Method m = info.getTest(); + if (TestFramework.isCompiled(m)) { + TestFramework.compile(m, CompLevel.C2); } } return false; @@ -131,7 +131,7 @@ primitive static class NotFlattenable { counts = {ALLOCA, "= 1"}) @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, counts = {ALLOCA, "= 1"}, - failOn = {LOAD}) + failOn = LOAD) public MyValue1[] test1(int len) { MyValue1[] va = new MyValue1[len]; for (int i = 0; i < len; ++i) { @@ -149,7 +149,6 @@ public void test1_verifier() { } } - // Test creation of an inline type array and element access @Test @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) @@ -168,7 +167,7 @@ public void test2_verifier() { // Test receiving an inline type array from the interpreter, // updating its elements in a loop and computing a hash. @Test - @IR(failOn = {ALLOCA}) + @IR(failOn = ALLOCA) public long test3(MyValue1[] va) { long result = 0; for (int i = 0; i < 10; ++i) { @@ -271,7 +270,7 @@ public void test6_verifier() { // Test default initialization of inline type arrays @Test - @IR(failOn = {LOAD}) + @IR(failOn = LOAD) public MyValue1[] test7(int len) { return new MyValue1[len]; } @@ -303,7 +302,7 @@ public void test8_verifier() { // Test that inline type array loaded from field has correct type @Test - @IR(failOn = {LOOP}) + @IR(failOn = LOOP) public long test9() { return test9_va[0].hash(); } @@ -342,7 +341,6 @@ public void test10_verifier() { } } - @Test public void test11(MyValue1[][][] arr, long[] res) { int l = 0; @@ -562,7 +560,6 @@ public void test19_verifier() { } } - // arraycopy() of inline type array with oop fields @Test public void test20(MyValue1[] src, MyValue1[] dst) { @@ -729,7 +726,6 @@ public void test27_verifier() { } } - // non escaping allocations // TODO 8252027: Make sure this is optimized with ZGC @Test @@ -749,7 +745,6 @@ public void test28_verifier() { Asserts.assertEQ(result.hash(), v.hash()); } - // non escaping allocations // TODO 8227588: shouldn't this have the same IR matching rules as test6? // @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) @@ -774,7 +769,6 @@ public void test29_verifier() { Asserts.assertEQ(src[0].hash(), v.hash()); } - // non escaping allocation with uncommon trap that needs // eliminated inline type array element as debug info @Test @@ -810,7 +804,7 @@ public long test31(boolean b, boolean deopt) { if (deopt) { // uncommon trap Method m = testFramework.getTestMethod("test31"); - testFramework.deoptimize(m); + TestFramework.deoptimize(m); } return src[0].hash(); } @@ -825,7 +819,6 @@ public void test31_verifier(RunInfo info) { Asserts.assertEQ(result2, v2.hash()); } - // Tests with Object arrays and clone/arraycopy // clone() as stub call @Test @@ -904,7 +897,7 @@ public void test34_verifier(RunInfo info) { // Expected } } - if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test34")) { + if (compile_and_run_again_if_deoptimized(info)) { Object[] result = test34(true); verify(test34_orig, result); // Check that array has correct properties (null-free) @@ -936,7 +929,7 @@ public void test35_verifier(RunInfo info) { verify(src, dst1); test35(src, dst2, src.length); verify(src, dst2); - if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test35")) { + if (compile_and_run_again_if_deoptimized(info)) { test35(src, dst1, src.length); verify(src, dst1); } @@ -957,7 +950,7 @@ public void test36_verifier(RunInfo info) { } test36(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test36")) { + if (compile_and_run_again_if_deoptimized(info)) { test36(src, dst); verify(src, dst); } @@ -978,7 +971,7 @@ public void test37_verifier(RunInfo info) { } test37(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test37")) { + if (compile_and_run_again_if_deoptimized(info)) { test37(src, dst); verify(src, dst); } @@ -1002,16 +995,15 @@ public void test38_verifier(RunInfo info) { test38(src, dst); verify(dst, src); if (!info.isWarmUp()) { - Method m = testFramework.getTestMethod("test38"); - testFramework.assertDeoptimizedByC2(m); - testFramework.compile(m, CompLevel.C2); + Method m = info.getTest(); + TestFramework.assertDeoptimizedByC2(m); + TestFramework.compile(m, CompLevel.C2); test38(src, dst); verify(dst, src); - testFramework.assertCompiledByC2(m); + TestFramework.assertCompiledByC2(m); } } - @Test public void test39(MyValue2[] src, Object dst) { System.arraycopy(src, 0, dst, 0, src.length); @@ -1027,7 +1019,7 @@ public void test39_verifier(RunInfo info) { } test39(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test39")) { + if (compile_and_run_again_if_deoptimized(info)) { test39(src, dst); verify(src, dst); } @@ -1050,12 +1042,12 @@ public void test40_verifier(RunInfo info) { test40(src, dst); verify(dst, src); if (!info.isWarmUp()) { - Method m = testFramework.getTestMethod("test40"); - testFramework.assertDeoptimizedByC2(m); - testFramework.compile(m, CompLevel.C2); + Method m = info.getTest(); + TestFramework.assertDeoptimizedByC2(m); + TestFramework.compile(m, CompLevel.C2); test40(src, dst); verify(dst, src); - testFramework.assertCompiledByC2(m); + TestFramework.assertCompiledByC2(m); } } @@ -1074,7 +1066,7 @@ public void test41_verifier(RunInfo info) { } test41(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test41")) { + if (compile_and_run_again_if_deoptimized(info)) { test41(src, dst); verify(src, dst); } @@ -1096,8 +1088,7 @@ public void test42_verifier(RunInfo info) { test42(src, dst); verify(src, dst); if (!info.isWarmUp()) { - Method m = testFramework.getTestMethod("test42"); - testFramework.assertCompiledByC2(m); + TestFramework.assertCompiledByC2(info.getTest()); } } @@ -1116,7 +1107,7 @@ public void test43_verifier(RunInfo info) { } test43(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test43")) { + if (compile_and_run_again_if_deoptimized(info)) { test43(src, dst); verify(src, dst); } @@ -1136,7 +1127,7 @@ public void test44_verifier(RunInfo info) { } test44(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test44")) { + if (compile_and_run_again_if_deoptimized(info)) { test44(src, dst); verify(src, dst); } @@ -1156,7 +1147,7 @@ public void test45_verifier(RunInfo info) { } test45(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test45")) { + if (compile_and_run_again_if_deoptimized(info)) { test45(src, dst); verify(src, dst); } @@ -1178,12 +1169,12 @@ public void test46_verifier(RunInfo info) { test46(src, dst); verify(dst, src); if (!info.isWarmUp()) { - Method m = testFramework.getTestMethod("test46"); - testFramework.assertDeoptimizedByC2(m); - testFramework.compile(m, CompLevel.C2); + Method m = info.getTest(); + TestFramework.assertDeoptimizedByC2(m); + TestFramework.compile(m, CompLevel.C2); test46(src, dst); verify(dst, src); - testFramework.assertCompiledByC2(m); + TestFramework.assertCompiledByC2(m); } } @@ -1201,7 +1192,7 @@ public void test47_verifier(RunInfo info) { } test47(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test47")) { + if (compile_and_run_again_if_deoptimized(info)) { test47(src, dst); verify(src, dst); } @@ -1223,12 +1214,12 @@ public void test48_verifier(RunInfo info) { test48(src, dst); verify(dst, src); if (!info.isWarmUp()) { - Method m = testFramework.getTestMethod("test48"); - testFramework.assertDeoptimizedByC2(m); - testFramework.compile(m, CompLevel.C2); + Method m = info.getTest(); + TestFramework.assertDeoptimizedByC2(m); + TestFramework.compile(m, CompLevel.C2); test48(src, dst); verify(dst, src); - testFramework.assertCompiledByC2(m); + TestFramework.assertCompiledByC2(m); } } @@ -1246,7 +1237,7 @@ public void test49_verifier(RunInfo info) { } test49(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test49")) { + if (compile_and_run_again_if_deoptimized(info)) { test49(src, dst); verify(src, dst); } @@ -1267,8 +1258,8 @@ public void test50_verifier(RunInfo info) { test50(src, dst); verify(src, dst); if (!info.isWarmUp()) { - Method m = testFramework.getTestMethod("test50"); - testFramework.assertCompiledByC2(m); + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); } } @@ -1408,7 +1399,7 @@ public void test58_verifier(RunInfo info) { Object[] result = test58(va, MyValue1[].class); verify(va, result); } - if (compile_and_run_again_if_deoptimized(info.isWarmUp(), "test58")) { + if (compile_and_run_again_if_deoptimized(info)) { Object[] result = test58(va, MyValue1[].class); verify(va, result); } @@ -2323,7 +2314,7 @@ public void test94_verifier(RunInfo info) { // Test propagation of not null-free/flat information @Test - @IR(failOn = {CHECKCAST_ARRAY}) + @IR(failOn = CHECKCAST_ARRAY) public MyValue1[] test95(Object[] array) { array[0] = null; // Always throws a ClassCastException because we just successfully @@ -2351,7 +2342,7 @@ public void test95_verifier() { // Same as test95 but with cmp user of cast result @Test - @IR(failOn = {CHECKCAST_ARRAY}) + @IR(failOn = CHECKCAST_ARRAY) public boolean test96(Object[] array) { array[0] = null; // Always throws a ClassCastException because we just successfully @@ -2380,7 +2371,7 @@ public void test96_verifier() { // Same as test95 but with instanceof instead of cast @Test - @IR(failOn = {CHECKCAST_ARRAY}) + @IR(failOn = CHECKCAST_ARRAY) public boolean test97(Object[] array) { array[0] = 42; // Always throws a ClassCastException because we just successfully stored @@ -2405,7 +2396,7 @@ public void test97_verifier() { // Same as test95 but with non-flattenable store @Test @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, - failOn = {CHECKCAST_ARRAY}) + failOn = CHECKCAST_ARRAY) public MyValue1[] test98(Object[] array) { array[0] = NotFlattenable.default; // Always throws a ClassCastException because we just successfully stored a @@ -2434,7 +2425,7 @@ public void test98_verifier() { // Same as test98 but with cmp user of cast result @Test @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, - failOn = {CHECKCAST_ARRAY}) + failOn = CHECKCAST_ARRAY) public boolean test99(Object[] array) { array[0] = NotFlattenable.default; // Always throws a ClassCastException because we just successfully stored a @@ -2464,7 +2455,7 @@ public void test99_verifier() { // Same as test98 but with instanceof instead of cast @Test @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, - failOn = {CHECKCAST_ARRAY}) + failOn = CHECKCAST_ARRAY) public boolean test100(Object[] array) { array[0] = NotFlattenable.default; // Always throws a ClassCastException because we just successfully stored a @@ -2530,7 +2521,7 @@ public void test101_verifier() { @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, counts = {INTRINSIC_SLOW_PATH, "= 1"}) @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, - failOn = {INTRINSIC_SLOW_PATH}) + failOn = INTRINSIC_SLOW_PATH) public void test102() { System.arraycopy(val_src, 0, obj_dst, 0, 8); } @@ -2603,7 +2594,7 @@ public void test105_null_verifier() { @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, counts = {INTRINSIC_SLOW_PATH, "= 1"}) @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, - failOn = {INTRINSIC_SLOW_PATH}) + failOn = INTRINSIC_SLOW_PATH) public void test106() { System.arraycopy(get_val_src(), 0, get_obj_dst(), 0, 8); } @@ -2618,7 +2609,7 @@ public void test106_verifier() { // at parse time it looks as if src could be flat and dst could be not flat. @Test @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, - failOn = {INTRINSIC_SLOW_PATH}) + failOn = INTRINSIC_SLOW_PATH) public void test107() { System.arraycopy(get_val_src(), 0, get_val_dst(), 0, 8); } @@ -2630,7 +2621,7 @@ public void test107_verifier() { } @Test - @IR(failOn = {INTRINSIC_SLOW_PATH}) + @IR(failOn = INTRINSIC_SLOW_PATH) public void test108() { System.arraycopy(get_obj_src(), 0, get_obj_dst(), 0, 8); } @@ -3002,7 +2993,7 @@ public void test125_verifier() { counts = {JLONG_ARRAYCOPY, "= 1"}, failOn = {CHECKCAST_ARRAYCOPY, CLONE_INTRINSIC_SLOW_PATH}) @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, - failOn = {CLONE_INTRINSIC_SLOW_PATH}) + failOn = CLONE_INTRINSIC_SLOW_PATH) public Object[] test126(MyValue2[] src) { return src.clone(); } @@ -3039,7 +3030,7 @@ public void test127_verifier() { @Test @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, counts = {JLONG_ARRAYCOPY, "= 1"}, - failOn = {CHECKCAST_ARRAYCOPY}) + failOn = CHECKCAST_ARRAYCOPY) public Object[] test128(MyValue2[] src, Class klass) { return Arrays.copyOf(src, 8, klass); } @@ -3342,8 +3333,8 @@ public void test140_verifier() { // Test load from array that is only known to be inline after parsing // TODO 8255938 - // @Test(failOn = {ALLOC, ALLOCA, ALLOC_G, ALLOCA_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) @Test + // @IR(failOn = {ALLOC, ALLOCA, ALLOC_G, ALLOCA_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) public Object test141() { Object[] array = null; Object[] iarray = new Integer[1]; @@ -3363,8 +3354,8 @@ public void test141_verifier() { // Test store to array that is only known to be inline after parsing // TODO 8255938 - // @Test(failOn = {ALLOC, ALLOCA, ALLOC_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) @Test + // @IR(failOn = {ALLOC, ALLOCA, ALLOC_G, LOOP, LOAD, STORE, TRAP, LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) public Object[] test142(Object val) { Object[] array = null; Object[] iarray = new Integer[1]; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java index 84036865309..110daee7dc8 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java @@ -109,7 +109,6 @@ public MyValue1 test3(MyValue1 v) { return v; } - @Run(test = "test3") public void test3_verifier() { MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI, rL); @@ -118,7 +117,6 @@ public void test3_verifier() { Asserts.assertEQ(v1.y, v2.y); } - // Create an inline type in compiled code and only use fields. // Allocation should go away because inline type does not escape. @Test @@ -134,7 +132,6 @@ public void test4_verifier() { Asserts.assertEQ(result, hash()); } - // Create an inline type in compiled code and pass it to // an inlined compiled method via a call. @Test @@ -155,7 +152,6 @@ public void test5_verifier() { Asserts.assertEQ(result, hash()); } - // Create an inline type in compiled code and pass it to // the interpreter via a call. @Test @@ -191,7 +187,6 @@ public void test7_verifier() { Asserts.assertEQ(v.hash(), hash()); } - // Merge inline types created from two branches @Test @IR(failOn = {ALLOC, STORE, TRAP}) @@ -286,11 +281,10 @@ public void test11_verifier() { Asserts.assertEQ(result, hash(rI + 10, rL + 10)); } - // Test loop with uncommon trap referencing an inline type @Test @IR(counts = {SCOBJ, ">= 1"}, // at least 1 - failOn = {LOAD}) + failOn = LOAD) public long test12(boolean b) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue1[] va = new MyValue1[Math.abs(rI) % 10]; @@ -319,7 +313,6 @@ public void test12_verifier(RunInfo info) { Asserts.assertEQ(result, info.isWarmUp() ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); } - // Test loop with uncommon trap referencing an inline type @Test public long test13(boolean b) { @@ -350,7 +343,6 @@ public void test13_verifier(RunInfo info) { Asserts.assertEQ(result, info.isWarmUp() ? rL + (1000 * rI) : ((Math.abs(rI) % 10) + 1) * hash()); } - // Create an inline type in a non-inlined method and then call a // non-inlined method on that inline type. @Test @@ -474,7 +466,7 @@ public void test19_verifier() { failOn = {LOAD, ALLOC, STORE}) @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, counts = {ALLOC, "= 1"}, - failOn = {LOAD}) + failOn = LOAD) public long test20(boolean deopt) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue2[] va = new MyValue2[3]; @@ -494,7 +486,6 @@ public void test20_verifier(RunInfo info) { Asserts.assertEQ(result, hash() + va[0].hash() + va[1].hash() + va[2].hash()); } - // Inline type fields in regular object MyValue1 val1; MyValue2 val2; @@ -505,7 +496,7 @@ public void test20_verifier(RunInfo info) { // Test inline type fields in objects @Test @IR(counts = {ALLOC, "= 1"}, - failOn = {TRAP}) + failOn = TRAP) public long test21(int x, long y) { // Compute hash of inline type fields long result = val1.hash() + val2.hash() + val3.hash() + val4.hash() + val5.hash(); @@ -610,8 +601,6 @@ class TestClass27 { public MyValue1 v; } - - // Test allocation elimination of unused object with initialized inline type field @Test @IR(failOn = {ALLOC, LOAD, STORE, LOOP}) @@ -630,8 +619,6 @@ public void test27_verifier(RunInfo info) { test27(!info.isWarmUp()); } - - static MyValue3 staticVal3; static MyValue3 staticVal3_copy; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java index fbe8bd9654c..e6b763a6062 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java @@ -62,11 +62,11 @@ public static void main(String[] args) { "-XX:TieredStopAtLevel=4", "-XX:-TieredCompilation", "-Xcomp") }; - TestFramework testFramework = InlineTypes.getFramework(); - testFramework.addScenarios(scenarios) - .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class, - MyValue3.class, MyValue3Inline.class) - .start(); + InlineTypes.getFramework() + .addScenarios(scenarios) + .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class, + MyValue3.class, MyValue3Inline.class) + .start(); } // JDK-8229799 @@ -361,5 +361,4 @@ public void test12_verifier() { } Asserts.assertNotNull(e); } - } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java index f452a927f3c..c91ed0e4281 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java @@ -78,13 +78,13 @@ public static void main(String[] args) { scenarios[4].addFlags("-XX:-UseTLAB"); testFramework.addScenarios(scenarios) - .addHelperClasses(MyValue1.class, - MyValue2.class, - MyValue2Inline.class, - MyValue3.class, - MyValue3Inline.class, - MyValue4.class) - .start(); + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class, + MyValue3.class, + MyValue3Inline.class, + MyValue4.class) + .start(); } // Helper methods and classes @@ -183,7 +183,7 @@ public long test1(MyValue2 v) { } @Run(test = "test1") - public void test1_verifier(RunInfo info) { + public void test1_verifier() { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test1(v); Asserts.assertEQ(result, v.hashInterpreted()); @@ -209,7 +209,7 @@ public long test3(long l1, MyValue2 v, long l2) { } @Run(test = "test3") - public void test3_verifier(RunInfo info) { + public void test3_verifier() { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test3(rL, v, 2*rL); Asserts.assertEQ(result, v.hashInterpreted() - rL); @@ -222,7 +222,7 @@ public long test4(int i, MyValue2 v, long l) { } @Run(test = "test4") - public void test4_verifier(RunInfo info) { + public void test4_verifier() { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test4(rI, v, rL); Asserts.assertEQ(result, v.hashInterpreted() + rL + rI); @@ -235,7 +235,7 @@ public long test5(long l, MyValue2 v, int i) { } @Run(test = "test5") - public void test5_verifier(RunInfo info) { + public void test5_verifier() { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test5(rL, v, rI); Asserts.assertEQ(result, v.hashInterpreted() + rL + rI); @@ -248,7 +248,7 @@ public long test6(long l, MyValue1 v1, int i, MyValue2 v2) { } @Run(test = "test6") - public void test6_verifier(RunInfo info) { + public void test6_verifier() { MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI, rL); MyValue2 v2 = MyValue2.createWithFieldsInline(rI, rD); long result = test6(rL, v1, rI, v2); @@ -268,7 +268,7 @@ public long test7(MyValue2 v) { } @Run(test = "test7") - public void test7_verifier(RunInfo info) { + public void test7_verifier() { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test7(v); Asserts.assertEQ(result, v.hashInterpreted()); @@ -286,7 +286,7 @@ public long test8(int i1, MyValue2 v, int i2) { } @Run(test = "test8") - public void test8_verifier(RunInfo info) { + public void test8_verifier() { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test8(rI, v, 2*rI); Asserts.assertEQ(result, v.hashInterpreted() - rI); @@ -304,7 +304,7 @@ public long test9(long l1, MyValue2 v, long l2) { } @Run(test = "test9") - public void test9_verifier(RunInfo info) { + public void test9_verifier() { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test9(rL, v, 2*rL); Asserts.assertEQ(result, v.hashInterpreted() - rL); @@ -322,13 +322,12 @@ public long test10(int i, MyValue2 v, long l) { } @Run(test = "test10") - public void test10_verifier(RunInfo info) { + public void test10_verifier() { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test10(rI, v, rL); Asserts.assertEQ(result, v.hashInterpreted() + rL + rI); } - @DontCompile public long test11_interp(long l, MyValue2 v, int i) { return v.hash() + i + l; @@ -341,7 +340,7 @@ public long test11(long l, MyValue2 v, int i) { } @Run(test = "test11") - public void test11_verifier(RunInfo info) { + public void test11_verifier() { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); long result = test11(rL, v, rI); Asserts.assertEQ(result, v.hashInterpreted() + rL + rI); @@ -359,7 +358,7 @@ public long test12(long l, MyValue1 v1, int i, MyValue2 v2) { } @Run(test = "test12") - public void test12_verifier(RunInfo info) { + public void test12_verifier() { MyValue1 v1 = MyValue1.createWithFieldsDontInline(rI, rL); MyValue2 v2 = MyValue2.createWithFieldsInline(rI, rD); long result = test12(rL, v1, rI, v2); @@ -372,7 +371,7 @@ public long test13_interp(MyValue2 v, MyValue1[] va, boolean deopt) { if (deopt) { // uncommon trap Method m = testFramework.getTestMethod("test13"); - testFramework.deoptimize(m); + TestFramework.deoptimize(m); } return v.hash() + va[0].hash() + va[1].hash(); } @@ -399,7 +398,7 @@ public MyValue2 test14_interp(boolean deopt) { if (deopt) { // uncommon trap Method m = testFramework.getTestMethod("test14"); - testFramework.deoptimize(m); + TestFramework.deoptimize(m); } return MyValue2.createWithFieldsInline(rI, rD); } @@ -432,7 +431,7 @@ public void test15() { } @Run(test = "test15") - public void test15_verifier(RunInfo info) { + public void test15_verifier() { test15(); test15_vt.verify(test15_vt2); } @@ -447,7 +446,7 @@ public MyValue3 test16() { } @Run(test = "test16") - public void test16_verifier(RunInfo info) { + public void test16_verifier() { MyValue3 vt = test16(); test16_vt.verify(vt); } @@ -471,9 +470,9 @@ public void test17() { @Run(test = "test17") public void test17_verifier(RunInfo info) throws Exception { Method helper_m = getClass().getDeclaredMethod("test17_comp"); - if (!info.isWarmUp() && testFramework.isCompiled(helper_m)) { - testFramework.compile(helper_m, CompLevel.C2); - testFramework.assertCompiledByC2(helper_m); + if (!info.isWarmUp() && TestFramework.isCompiled(helper_m)) { + TestFramework.compile(helper_m, CompLevel.C2); + TestFramework.assertCompiledByC2(helper_m); } test17(); @@ -496,7 +495,7 @@ public void test18() { } @Run(test = "test18") - public void test18_verifier(RunInfo info) { + public void test18_verifier() { test18(); test18_vt.verify(test18_vt2); } @@ -509,7 +508,7 @@ public MyValue4 test19() { } @Run(test = "test19") - public void test19_verifier(RunInfo info) { + public void test19_verifier() { MyValue4 vt = test19(); test19_vt.verify(vt); } @@ -530,15 +529,14 @@ public void test20() { @Run(test = "test20") public void test20_verifier(RunInfo info) throws Exception { Method helper_m = getClass().getDeclaredMethod("test20_comp"); - if (!info.isWarmUp() && testFramework.isCompiled(helper_m)) { - testFramework.compile(helper_m, CompLevel.C2); - testFramework.assertCompiledByC2(helper_m); + if (!info.isWarmUp() && TestFramework.isCompiled(helper_m)) { + TestFramework.compile(helper_m, CompLevel.C2); + TestFramework.assertCompiledByC2(helper_m); } test20(); test20_vt.verify(test20_vt2); } - // Test no result from inlined method for incremental inlining final MyValue3 test21_vt = MyValue3.create(); public MyValue3 test21_inlined() { @@ -555,7 +553,7 @@ public MyValue3 test21() { } @Run(test = "test21") - public void test21_verifier(RunInfo info) { + public void test21_verifier() { MyValue3 vt = test21(); test21_vt.verify(vt); } @@ -569,7 +567,7 @@ public MyValue3 test22() { } @Run(test = "test22") - public void test22_verifier(RunInfo info) { + public void test22_verifier() { MyValue3 vt = test22(); test22_vt.verify(vt); } @@ -640,7 +638,7 @@ public MyValue2.ref test26(boolean b) { } @Run(test = "test26") - public void test26_verifier(RunInfo info) { + public void test26_verifier() { MyValue2.ref vt = test26(true); Asserts.assertEQ(vt, null); vt = test26(false); @@ -653,7 +651,7 @@ public int test27(Test27Value1 val) { } @Run(test = "test27") - public void test27_verifier(RunInfo info) { + public void test27_verifier() { Test27Value3 val3 = new Test27Value3(rI); Test27Value2 val2 = new Test27Value2(val3); Test27Value1 val1 = new Test27Value1(val2); @@ -670,7 +668,7 @@ public String test28() { @Run(test = "test28") @Warmup(0) - public void test28_verifier(RunInfo info) { + public void test28_verifier() { String result = test28(); } @@ -683,7 +681,7 @@ public MyValue3 test29() { } @Run(test = "test29") - public void test29_verifier(RunInfo info) throws Exception { + public void test29_verifier() throws Exception { MyValue3 vt = (MyValue3)TestCallingConvention.class.getDeclaredMethod("test29").invoke(this); test29_vt.verify(vt); } @@ -696,7 +694,7 @@ public MyValue3 test30(MyValue3[] array) { } @Run(test = "test30") - public void test30_verifier(RunInfo info) throws Exception { + public void test30_verifier() throws Exception { MyValue3[] array = new MyValue3[1]; MyValue3 vt = (MyValue3)TestCallingConvention.class.getDeclaredMethod("test30", MyValue3[].class).invoke(this, (Object)array); array[0].verify(vt); @@ -712,7 +710,7 @@ public MyValue3 test31() { } @Run(test = "test31") - public void test31_verifier(RunInfo info) throws Exception { + public void test31_verifier() throws Exception { MyValue3 vt = (MyValue3)TestCallingConvention.class.getDeclaredMethod("test31").invoke(this); test31_vt.verify(vt); } @@ -725,7 +723,7 @@ public MyValue2 test32_interp(boolean deopt) { if (deopt) { // uncommon trap Method m = testFramework.getTestMethod("test32"); - testFramework.deoptimize(m); + TestFramework.deoptimize(m); } return MyValue2.createWithFieldsInline(rI+32, rD); } @@ -749,7 +747,7 @@ public Object test33_interp(boolean deopt) { if (deopt) { // uncommon trap Method m = testFramework.getTestMethod("test33"); - testFramework.deoptimize(m); + TestFramework.deoptimize(m); } return MyValue2.createWithFieldsInline(rI+33, rD); } @@ -820,7 +818,7 @@ public static long test35(MyValue2 vt, int i1, int i2, int i3, int i4) { } @Run(test = "test35") - public void test35_verifier(RunInfo info) { + public void test35_verifier() { MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD); long result = test35(vt, rI, rI, rI, rI); Asserts.assertEQ(result, vt.hash()+10004*rI); @@ -839,7 +837,7 @@ public MyValue3 test36() { } @Run(test = "test36") - public void test36_verifier(RunInfo info) throws Exception { + public void test36_verifier() throws Exception { MyValue3 vt = (MyValue3)TestCallingConvention.class.getDeclaredMethod("test36").invoke(this); test36_vt.verify(vt); } @@ -852,7 +850,7 @@ public int test37(Test37Value vt) throws Throwable { } @Run(test = "test37") - public void test37_verifier(RunInfo info) throws Throwable { + public void test37_verifier() throws Throwable { Test37Value vt = new Test37Value(); int res = test37(vt); Asserts.assertEQ(res, rI); @@ -866,7 +864,7 @@ public MyValueEmpty test38(MyValueEmpty vt) { } @Run(test = "test38") - public void test38_verifier(RunInfo info) { + public void test38_verifier() { MyValueEmpty vt = new MyValueEmpty(); MyValueEmpty res = test38(vt); Asserts.assertEQ(res, vt); @@ -956,7 +954,7 @@ public static LargeValueWithOops test39(LargeValueWithOops vt) { } @Run(test = "test39") - public void test39_verifier(RunInfo info) { + public void test39_verifier() { LargeValueWithOops vt = new LargeValueWithOops(); LargeValueWithOops res = test39(vt); Asserts.assertEQ(res, vt); @@ -969,13 +967,12 @@ public static LargeValueWithoutOops test40(LargeValueWithoutOops vt) { } @Run(test = "test40") - public void test40_verifier(RunInfo info) { + public void test40_verifier() { LargeValueWithoutOops vt = new LargeValueWithoutOops(); LargeValueWithoutOops res = test40(vt); Asserts.assertEQ(res, vt); } - // Test passing/returning an empty inline type together with non-empty // inline types such that only some inline type arguments are scalarized. @Test @@ -985,7 +982,7 @@ public MyValueEmpty test41(MyValue1 vt1, MyValueEmpty vt2, MyValue1 vt3) { } @Run(test = "test41") - public void test41_verifier(RunInfo info) { + public void test41_verifier() { MyValueEmpty res = test41(MyValue1.default, MyValueEmpty.default, MyValue1.default); Asserts.assertEQ(res, MyValueEmpty.default); } @@ -1001,7 +998,7 @@ public MyValueEmpty test42() { } @Run(test = "test42") - public void test42_verifier(RunInfo info) { + public void test42_verifier() { MyValueEmpty empty = test42(); Asserts.assertEquals(empty, MyValueEmpty.default); } @@ -1014,7 +1011,7 @@ public EmptyContainer test43(EmptyContainer c) { } @Run(test = "test43") - public void test43_verifier(RunInfo info) { + public void test43_verifier() { EmptyContainer c = test43(EmptyContainer. default); Asserts.assertEquals(c, EmptyContainer.default); } @@ -1029,7 +1026,7 @@ public MixedContainer test44() { } @Run(test = "test44") - public void test44_verifier(RunInfo info) { + public void test44_verifier() { MixedContainer c = test44(); Asserts.assertEquals(c, new MixedContainer(rI, EmptyContainer.default)); } @@ -1043,7 +1040,7 @@ public EmptyContainer test45(EmptyContainer c) { } @Run(test = "test45") - public void test45_verifier(RunInfo info) { + public void test45_verifier() { EmptyContainer empty = test45(EmptyContainer.default); Asserts.assertEquals(empty, EmptyContainer.default); } @@ -1057,7 +1054,7 @@ public MyValueEmpty test46(EmptyContainer c1, MixedContainer c2, MyValueEmpty em } @Run(test = "test46") - public void test46_verifier(RunInfo info) { + public void test46_verifier() { MyValueEmpty empty = test46(EmptyContainer.default, MixedContainer.default, MyValueEmpty.default); Asserts.assertEquals(empty, MyValueEmpty.default); } @@ -1070,7 +1067,7 @@ public static MyValueEmpty test47(MyValueEmpty empty) { } @Run(test = "test47") - public void test47_verifier(RunInfo info) { + public void test47_verifier() { MyValueEmpty empty = test47(MyValueEmpty.default); Asserts.assertEquals(empty, MyValueEmpty.default); } @@ -1083,7 +1080,7 @@ public static MyValueEmpty test48(EmptyContainer empty) { } @Run(test = "test48") - public void test48_verifier(RunInfo info) { + public void test48_verifier() { MyValueEmpty empty = test48(EmptyContainer.default); Asserts.assertEquals(empty, MyValueEmpty.default); } @@ -1107,7 +1104,7 @@ public void test49(boolean b) { } @Run(test = "test49") - public void test49_verifier(RunInfo info) { + public void test49_verifier() { test49(true); test49(false); } @@ -1135,7 +1132,7 @@ public void test50(boolean b) { } @Run(test = "test50") - public void test50_verifier(RunInfo info) { + public void test50_verifier() { test50(true); test50(false); } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java index 4a1fa7df4f2..44ffc373cb4 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java @@ -72,10 +72,9 @@ public static void main(String[] args) { "-Xcomp") }; - - TestFramework testFramework = new TestFramework(TestGetfieldChains.class); - testFramework.addScenarios(scenarios) - .start(); + InlineTypes.getFramework() + .addScenarios(scenarios) + .start(); } @@ -86,7 +85,7 @@ public int test1() { } @Run(test = "test1") - public void test1_verifier(RunInfo info) { + public void test1_verifier() { int res = test1(); Asserts.assertEQ(res, 4); } @@ -98,7 +97,7 @@ public Point test2() { } @Run(test = "test2") - public void test2_verifier(RunInfo info) { + public void test2_verifier() { Point p = test2(); Asserts.assertEQ(p.x, 4); Asserts.assertEQ(p.y, 7); @@ -117,7 +116,7 @@ public NullPointerException test3() { } @Run(test = "test3") - public void test3_verifier(RunInfo info) { + public void test3_verifier() { NullPointerException npe = test3(); Asserts.assertNE(npe, null); StackTraceElement st = npe.getStackTrace()[0]; @@ -138,7 +137,7 @@ public IllegalAccessError test4() { } @Run(test = "test4") - public void test4_verifier(RunInfo info) { + public void test4_verifier() { IllegalAccessError iae = test4(); Asserts.assertNE(iae, null); StackTraceElement st = iae.getStackTrace()[0]; @@ -160,7 +159,7 @@ public NoSuchFieldError test5() { } @Run(test = "test5") - public void test5_verifier(RunInfo info) { + public void test5_verifier() { NoSuchFieldError nsfe = test5(); Asserts.assertNE(nsfe, null); StackTraceElement st = nsfe.getStackTrace()[0]; @@ -186,7 +185,7 @@ public EmptyType test6() { } @Run(test = "test6") - public void test6_verifier(RunInfo info) { + public void test6_verifier() { EmptyType et = test6(); Asserts.assertEQ(et, EmptyType.default); } @@ -198,7 +197,7 @@ public EmptyType test7() { } @Run(test = "test7") - public void test7_verifier(RunInfo info) { + public void test7_verifier() { EmptyType et = test7(); Asserts.assertEQ(et, EmptyType.default); } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java index 01427403e63..d42822fbe05 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java @@ -59,12 +59,12 @@ public static void main(String[] args) { scenarios[3].addFlags("-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"); scenarios[4].addFlags("-XX:-MonomorphicArrayCheck"); - TestFramework testFramework = new TestFramework(TestIntrinsics.class); - testFramework.addScenarios(scenarios) - .addHelperClasses(MyValue1.class, - MyValue2.class, - MyValue2Inline.class) - .start(); + InlineTypes.getFramework() + .addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class) + .start(); } // Test correctness of the Class::isAssignableFrom intrinsic @@ -74,7 +74,7 @@ public boolean test1(Class supercls, Class subcls) { } @Run(test = "test1") - public void test1_verifier(RunInfo info) { + public void test1_verifier() { Asserts.assertTrue(test1(java.util.AbstractList.class, java.util.ArrayList.class), "test1_1 failed"); Asserts.assertTrue(test1(MyValue1.ref.class, MyValue1.ref.class), "test1_2 failed"); Asserts.assertTrue(test1(MyValue1.class, MyValue1.class), "test1_3 failed"); @@ -105,7 +105,7 @@ public boolean test2() { } @Run(test = "test2") - public void test2_verifier(RunInfo info) { + public void test2_verifier() { Asserts.assertTrue(test2(), "test2 failed"); } @@ -116,7 +116,7 @@ public Class test3(Class cls) { } @Run(test = "test3") - public void test3_verifier(RunInfo info) { + public void test3_verifier() { Asserts.assertTrue(test3(Object.class) == null, "test3_1 failed"); Asserts.assertTrue(test3(MyValue1.ref.class) == MyAbstract.class, "test3_2 failed"); Asserts.assertTrue(test3(MyValue1.val.class) == MyValue1.ref.class, "test3_3 failed"); @@ -125,7 +125,7 @@ public void test3_verifier(RunInfo info) { // Verify that Class::getSuperclass checks with statically known classes are folded @Test - @IR(failOn = {LOADK}) + @IR(failOn = LOADK) public boolean test4() { boolean check1 = Object.class.getSuperclass() == null; // TODO 8244562: Remove cast as workaround once javac is fixed @@ -137,7 +137,7 @@ public boolean test4() { } @Run(test = "test4") - public void test4_verifier(RunInfo info) { + public void test4_verifier() { Asserts.assertTrue(test4(), "test4 failed"); } @@ -148,7 +148,7 @@ public String test5(MyValue1 v) { } @Run(test = "test5") - public void test5_verifier(RunInfo info) { + public void test5_verifier() { MyValue1 v = MyValue1.createDefaultInline(); test5(v); } @@ -160,7 +160,7 @@ public int test6(MyValue1 v) { } @Run(test = "test6") - public void test6_verifier(RunInfo info) { + public void test6_verifier() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); int res = test6(v); Asserts.assertEQ(res, v.hashCode()); @@ -174,7 +174,7 @@ public Object[] test7(Class componentType, int len) { } @Run(test = "test7") - public void test7_verifier(RunInfo info) { + public void test7_verifier() { int len = Math.abs(rI) % 42; long hash = MyValue1.createDefaultDontInline().hashPrimitive(); Object[] va = test7(MyValue1.class, len); @@ -190,7 +190,7 @@ public boolean test8(Class c, MyValue1 vt) { } @Run(test = "test8") - public void test8_verifier(RunInfo info) { + public void test8_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); boolean result = test8(MyValue1.class, vt); Asserts.assertTrue(result); @@ -204,7 +204,7 @@ public boolean test9(Class c, MyValue1 vt) { } @Run(test = "test9") - public void test9_verifier(RunInfo info) { + public void test9_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); boolean result = test9(MyValue2.class, vt); Asserts.assertFalse(result); @@ -219,7 +219,7 @@ public Object test10(Class c, MyValue1 vt) { } @Run(test = "test10") - public void test10_verifier(RunInfo info) { + public void test10_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); Object result = test10(MyValue1.class, vt); Asserts.assertEQ(((MyValue1)result).hash(), vt.hash()); @@ -231,7 +231,7 @@ public Object test11(Class c, MyValue1 vt) { } @Run(test = "test11") - public void test11_verifier(RunInfo info) { + public void test11_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); try { test11(MyValue2.class, vt); @@ -246,7 +246,7 @@ public Object test12(MyValue1 vt) { } @Run(test = "test12") - public void test12_verifier(RunInfo info) { + public void test12_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); Object result = test12(vt); Asserts.assertEQ(((MyValue1)result).hash(), vt.hash()); @@ -258,7 +258,7 @@ public Object test13(MyValue1 vt) { } @Run(test = "test13") - public void test13_verifier(RunInfo info) { + public void test13_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); try { test13(vt); @@ -277,7 +277,7 @@ public void test14(int len, long hash) { } @Run(test = "test14") - public void test14_verifier(RunInfo info) { + public void test14_verifier() { int len = Math.abs(rI) % 42; long hash = MyValue1.createDefaultDontInline().hashPrimitive(); test14(len, hash); @@ -290,7 +290,7 @@ public int test15(Object v) { } @Run(test = "test15") - public void test15_verifier(RunInfo info) { + public void test15_verifier() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); int res = test15(v); Asserts.assertEQ(res, v.hashCode()); @@ -302,7 +302,7 @@ public int test16(Object v) { } @Run(test = "test16") - public void test16_verifier(RunInfo info) { + public void test16_verifier() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); int res = test16(v); Asserts.assertEQ(res, System.identityHashCode((Object)v)); @@ -314,7 +314,7 @@ public int test17(Object v) { } @Run(test = "test17") - public void test17_verifier(RunInfo info) { + public void test17_verifier() { Integer v = Integer.valueOf(rI); int res = test17(v); Asserts.assertEQ(res, System.identityHashCode(v)); @@ -326,7 +326,7 @@ public int test18(Object v) { } @Run(test = "test18") - public void test18_verifier(RunInfo info) { + public void test18_verifier() { Object v = null; int res = test18(v); Asserts.assertEQ(res, System.identityHashCode(v)); @@ -340,7 +340,7 @@ public int test19(MyValue1 vt1, MyValue1 vt2, boolean b) { } @Run(test = "test19") - public void test19_verifier(RunInfo info) { + public void test19_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); int res = test19(vt, vt, true); Asserts.assertEQ(res, vt.hashCode()); @@ -355,7 +355,7 @@ public String test20(MyValue1 vt1, MyValue1 vt2, boolean b) { } @Run(test = "test20") - public void test20_verifier(RunInfo info) { + public void test20_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); String res = test20(vt, vt, true); Asserts.assertEQ(res, vt.toString()); @@ -385,13 +385,13 @@ public void test20_verifier(RunInfo info) { protected static final String CALL_Unsafe = START + "CallStaticJava" + MID + "# Static jdk.internal.misc.Unsafe::" + END; @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public int test21(MyValue1 v) { return U.getInt(v, X_OFFSET); } @Run(test = "test21") - public void test21_verifier(RunInfo info) { + public void test21_verifier() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); int res = test21(v); Asserts.assertEQ(res, v.x); @@ -408,20 +408,20 @@ public void test22(MyValue1 v) { } @Run(test = "test22") - public void test22_verifier(RunInfo info) { + public void test22_verifier() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); test22(v.setX(v, 0)); Asserts.assertEQ(test22_vt.hash(), v.hash()); } @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public int test23(MyValue1 v, long offset) { return U.getInt(v, offset); } @Run(test = "test23") - public void test23_verifier(RunInfo info) { + public void test23_verifier() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); int res = test23(v, X_OFFSET); Asserts.assertEQ(res, v.x); @@ -430,13 +430,13 @@ public void test23_verifier(RunInfo info) { MyValue1 test24_vt = MyValue1.createWithFieldsInline(rI, rL); @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public int test24(long offset) { return U.getInt(test24_vt, offset); } @Run(test = "test24") - public void test24_verifier(RunInfo info) { + public void test24_verifier() { int res = test24(X_OFFSET); Asserts.assertEQ(res, test24_vt.x); } @@ -459,7 +459,7 @@ public Test25Value[] test25(Test25Value element) { } @Run(test = "test25") - public void test25_verifier(RunInfo info) { + public void test25_verifier() { Test25Value vt = new Test25Value(); test25(vt); } @@ -475,7 +475,7 @@ public Object test26() { } @Run(test = "test26") - public void test26_verifier(RunInfo info) { + public void test26_verifier() { Object[] res = (Object[])test26(); Asserts.assertEQ(((MyValue1)res[0]).hashPrimitive(), MyValue1.createDefaultInline().hashPrimitive()); } @@ -493,26 +493,26 @@ public void test26_verifier(RunInfo info) { } @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public MyValue1 test27() { return (MyValue1)U.getReference(this, TEST27_OFFSET); } @Run(test = "test27") - public void test27_verifier(RunInfo info) { + public void test27_verifier() { MyValue1 res = test27(); Asserts.assertEQ(res.hash(), test24_vt.hash()); } // Mismatched type @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public int test28(MyValue1 v) { return U.getByte(v, X_OFFSET); } @Run(test = "test28") - public void test28_verifier(RunInfo info) { + public void test28_verifier() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); int res = test28(v); if (java.nio.ByteOrder.nativeOrder() == java.nio.ByteOrder.LITTLE_ENDIAN) { @@ -524,7 +524,7 @@ public void test28_verifier(RunInfo info) { // Wrong alignment @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public long test29(MyValue1 v) { // Read the field that's guaranteed to not be last in the // inline type so we don't read out of bounds. @@ -535,7 +535,7 @@ public long test29(MyValue1 v) { } @Run(test = "test29") - public void test29_verifier(RunInfo info) { + public void test29_verifier() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); long res = test29(v); if (java.nio.ByteOrder.nativeOrder() == java.nio.ByteOrder.LITTLE_ENDIAN) { @@ -556,7 +556,7 @@ public void test29_verifier(RunInfo info) { // getValue to retrieve flattened field from inline type @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public MyValue2 test30(MyValue1 v) { if (V1_FLATTENED) { return U.getValue(v, V1_OFFSET, MyValue2.val.class); @@ -565,7 +565,7 @@ public MyValue2 test30(MyValue1 v) { } @Run(test = "test30") - public void test30_verifier(RunInfo info) { + public void test30_verifier() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue2 res = test30(v); Asserts.assertEQ(res.hash(), v.v1.hash()); @@ -586,7 +586,7 @@ public void test30_verifier(RunInfo info) { // getValue to retrieve flattened field from object @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public MyValue1 test31() { if (TEST31_VT_FLATTENED) { return U.getValue(this, TEST31_VT_OFFSET, MyValue1.val.class); @@ -595,7 +595,7 @@ public MyValue1 test31() { } @Run(test = "test31") - public void test31_verifier(RunInfo info) { + public void test31_verifier() { test31_vt = MyValue1.createWithFieldsInline(rI, rL); MyValue1 res = test31(); Asserts.assertEQ(res.hash(), test31_vt.hash()); @@ -603,7 +603,7 @@ public void test31_verifier(RunInfo info) { // putValue to set flattened field in object @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public void test32(MyValue1 vt) { if (TEST31_VT_FLATTENED) { U.putValue(this, TEST31_VT_OFFSET, MyValue1.val.class, vt); @@ -613,7 +613,7 @@ public void test32(MyValue1 vt) { } @Run(test = "test32") - public void test32_verifier(RunInfo info) { + public void test32_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); test31_vt = MyValue1.createDefaultInline(); test32(vt); @@ -634,7 +634,7 @@ public void test32_verifier(RunInfo info) { } // getValue to retrieve flattened field from array @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public MyValue1 test33(MyValue1[] arr) { if (TEST33_FLATTENED_ARRAY) { return U.getValue(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE, MyValue1.val.class); @@ -643,7 +643,7 @@ public MyValue1 test33(MyValue1[] arr) { } @Run(test = "test33") - public void test33_verifier(RunInfo info) { + public void test33_verifier() { MyValue1[] arr = new MyValue1[2]; MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); arr[1] = vt; @@ -653,7 +653,7 @@ public void test33_verifier(RunInfo info) { // putValue to set flattened field in array @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public void test34(MyValue1[] arr, MyValue1 vt) { if (TEST33_FLATTENED_ARRAY) { U.putValue(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE, MyValue1.val.class, vt); @@ -663,7 +663,7 @@ public void test34(MyValue1[] arr, MyValue1 vt) { } @Run(test = "test34") - public void test34_verifier(RunInfo info) { + public void test34_verifier() { MyValue1[] arr = new MyValue1[2]; MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); test34(arr, vt); @@ -673,7 +673,7 @@ public void test34_verifier(RunInfo info) { // getValue to retrieve flattened field from object with unknown // container type @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public MyValue1 test35(Object o) { if (TEST31_VT_FLATTENED) { return U.getValue(o, TEST31_VT_OFFSET, MyValue1.val.class); @@ -682,7 +682,7 @@ public MyValue1 test35(Object o) { } @Run(test = "test35") - public void test35_verifier(RunInfo info) { + public void test35_verifier() { test31_vt = MyValue1.createWithFieldsInline(rI, rL); MyValue1 res = test35(this); Asserts.assertEQ(res.hash(), test31_vt.hash()); @@ -691,7 +691,7 @@ public void test35_verifier(RunInfo info) { // getValue to retrieve flattened field from object at unknown // offset @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public MyValue1 test36(long offset) { if (TEST31_VT_FLATTENED) { return U.getValue(this, offset, MyValue1.val.class); @@ -700,7 +700,7 @@ public MyValue1 test36(long offset) { } @Run(test = "test36") - public void test36_verifier(RunInfo info) { + public void test36_verifier() { test31_vt = MyValue1.createWithFieldsInline(rI, rL); MyValue1 res = test36(TEST31_VT_OFFSET); Asserts.assertEQ(res.hash(), test31_vt.hash()); @@ -709,7 +709,7 @@ public void test36_verifier(RunInfo info) { // putValue to set flattened field in object with unknown // container @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public void test37(Object o, MyValue1 vt) { if (TEST31_VT_FLATTENED) { U.putValue(o, TEST31_VT_OFFSET, MyValue1.val.class, vt); @@ -719,7 +719,7 @@ public void test37(Object o, MyValue1 vt) { } @Run(test = "test37") - public void test37_verifier(RunInfo info) { + public void test37_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); test31_vt = MyValue1.createDefaultInline(); test37(this, vt); @@ -739,7 +739,7 @@ public void test38(Object o) { } @Run(test = "test38") - public void test38_verifier(RunInfo info) { + public void test38_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); test31_vt = MyValue1.createDefaultInline(); test38(vt); @@ -747,7 +747,7 @@ public void test38_verifier(RunInfo info) { } @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public MyValue1 test39(MyValue1 v) { v = U.makePrivateBuffer(v); U.putInt(v, X_OFFSET, rI); @@ -756,7 +756,7 @@ public MyValue1 test39(MyValue1 v) { } @Run(test = "test39") - public void test39_verifier(RunInfo info) { + public void test39_verifier() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue1 res = test39(v.setX(v, 0)); Asserts.assertEQ(res.hash(), v.hash()); @@ -770,7 +770,7 @@ public Object[] test40(Class componentType, int len) { } @Run(test = "test40") - public void test40_verifier(RunInfo info) { + public void test40_verifier() { int len = Math.abs(rI) % 42; Object[] va = test40(MyValue1.ref.class, len); for (int i = 0; i < len; ++i) { @@ -785,7 +785,7 @@ public boolean test41(Class c, MyValue1.ref vt) { } @Run(test = "test41") - public void test41_verifier(RunInfo info) { + public void test41_verifier() { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); boolean result = test41(MyValue1.ref.class, vt); Asserts.assertTrue(result); @@ -799,7 +799,7 @@ public boolean test42(Class c, MyValue1.ref vt) { } @Run(test = "test42") - public void test42_verifier(RunInfo info) { + public void test42_verifier() { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); boolean result = test42(MyValue2.ref.class, vt); Asserts.assertFalse(result); @@ -814,7 +814,7 @@ public Object test43(Class c, MyValue1.ref vt) { } @Run(test = "test43") - public void test43_verifier(RunInfo info) { + public void test43_verifier() { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); Object result = test43(MyValue1.ref.class, vt); Asserts.assertEQ(((MyValue1)result).hash(), vt.hash()); @@ -828,7 +828,7 @@ public Object test44(Class c, MyValue1.ref vt) { } @Run(test = "test44") - public void test44_verifier(RunInfo info) { + public void test44_verifier() { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); try { test44(MyValue2.ref.class, vt); @@ -843,7 +843,7 @@ public Object test45(MyValue1.ref vt) { } @Run(test = "test45") - public void test45_verifier(RunInfo info) { + public void test45_verifier() { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); Object result = test45(vt); Asserts.assertEQ(((MyValue1)result).hash(), vt.hash()); @@ -857,7 +857,7 @@ public Object test46(MyValue1.ref vt) { } @Run(test = "test46") - public void test46_verifier(RunInfo info) { + public void test46_verifier() { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); test46(null); try { @@ -873,7 +873,7 @@ public Object test47(MyValue1.ref vt) { } @Run(test = "test47") - public void test47_verifier(RunInfo info) { + public void test47_verifier() { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); Object result = test47(vt); Asserts.assertEQ(((MyValue1)result).hash(), vt.hash()); @@ -890,7 +890,7 @@ public Object test48(Class c, MyValue1.ref vt) { } @Run(test = "test48") - public void test48_verifier(RunInfo info) { + public void test48_verifier() { MyValue1.ref vt = MyValue1.createWithFieldsInline(rI, rL); Object result = test48(MyValue1.class, vt); Asserts.assertEQ(((MyValue1)result).hash(), vt.hash()); @@ -907,20 +907,19 @@ public Object test49(MyValue1 vt) { } @Run(test = "test49") - public void test49_verifier(RunInfo info) { + public void test49_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); Object result = test49(vt); Asserts.assertEQ(((MyValue1)result).hash(), vt.hash()); } - @Test() public Object test50(Class c, Object obj) { return c.cast(obj); } @Run(test = "test50") - public void test50_verifier(RunInfo info) { + public void test50_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); MyValue1[] va = new MyValue1[42]; MyValue1.ref[] vba = new MyValue1.ref[42]; @@ -956,7 +955,7 @@ public void test51(int len) { } @Run(test = "test51") - public void test51_verifier(RunInfo info) { + public void test51_verifier() { int len = Math.abs(rI) % 42; test51(len); } @@ -984,7 +983,7 @@ public Object[][] test52(int len, int val) { } @Run(test = "test52") - public void test52_verifier(RunInfo info) { + public void test52_verifier() { test52(1, 1); test52(1, 2); } @@ -1028,7 +1027,7 @@ public Object[][] test53(Class c1, Class c2, int len, int val) { } @Run(test = "test53") - public void test53_verifier(RunInfo info) { + public void test53_verifier() { int len = Math.abs(rI) % 42; test53(MyValue1[].class, MyValue1.ref[].class, len, 1); test53(MyValue1[].class, MyValue1.ref[].class, len, 2); @@ -1052,7 +1051,7 @@ public MyValue1 test54(MyValue1 v) { @Run(test = "test54") @Warmup(10000) // Fill up the TLAB to trigger slow path allocation - public void test54_verifier(RunInfo info) { + public void test54_verifier() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue1 res = test54(v.setX(v, 0)); Asserts.assertEQ(res.hash(), v.hash()); @@ -1062,7 +1061,7 @@ public void test54_verifier(RunInfo info) { // Same as test30 but with constant field holder @Test - @IR(failOn = {CALL_Unsafe}) + @IR(failOn = CALL_Unsafe) public MyValue2 test55() { if (V1_FLATTENED) { return U.getValue(test55_vt, V1_OFFSET, MyValue2.val.class); @@ -1071,7 +1070,7 @@ public MyValue2 test55() { } @Run(test = "test55") - public void test55_verifier(RunInfo info) { + public void test55_verifier() { MyValue2 res = test55(); Asserts.assertEQ(res.hash(), test55_vt.v1.hash()); } @@ -1086,7 +1085,7 @@ public void test56(int idx) { } @Run(test = "test56") - public void test56_verifier(RunInfo info) { + public void test56_verifier() { test56(0); } @@ -1100,7 +1099,7 @@ public void test57() { } @Run(test = "test57") - public void test57_verifier(RunInfo info) { + public void test57_verifier() { test57(); } @@ -1113,7 +1112,7 @@ public boolean test58(Class c1, Class c2) throws Exception { } @Run(test = "test58") - public void test58_verifier(RunInfo info) throws Exception { + public void test58_verifier() throws Exception { boolean res = test58(MyValue1.class, MyValue1.class); Asserts.assertTrue(res); res = test58(Object.class, MyValue1.class); @@ -1132,7 +1131,7 @@ public void test59(Class c) throws Exception { } @Run(test = "test59") - public void test59_verifier(RunInfo info) throws Exception { + public void test59_verifier() throws Exception { test59(Integer.class); try { test59(MyValue1.class); @@ -1151,7 +1150,7 @@ public boolean test60(Class c1, Class c2, boolean b1, boolean b2) throws E } @Run(test = "test60") - public void test60_verifier(RunInfo info) throws Exception { + public void test60_verifier() throws Exception { Asserts.assertTrue(test60(MyValue1.class, MyValue1.class, false, false)); Asserts.assertFalse(test60(MyValue1.class, MyValue2.class, false, false)); Asserts.assertFalse(test60(MyValue1.class, MyValue1.class, false, true)); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java index a07ca9862b2..be00b2b13ca 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java @@ -67,7 +67,7 @@ public static void main(String[] args) { } } - public static void shouldNotReach() { + public static void shouldNotReach() { throw new RuntimeException("should not reach"); } From 4513a0f5800d50eac4af87a38b7e836b8eee6f5b Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Thu, 25 Mar 2021 10:53:39 -0700 Subject: [PATCH 074/131] Converted the test to new IR framework --- .../inlinetypes/TestCallingConventionC1.java | 1160 ++++++++--------- 1 file changed, 577 insertions(+), 583 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java index a7358a54851..8bf3b5725cd 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, 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 @@ -23,94 +23,64 @@ package compiler.valhalla.inlinetypes; -import sun.hotspot.WhiteBox; import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; + +import sun.hotspot.WhiteBox; /* * @test * @key randomness - * @summary Test calls from {C1} to {C2, Interpreter}, and vice versa. - * @library /testlibrary /test/lib /compiler/whitebox / + * @summary Test calls from {CompLevel.C1} to {CompLevel.C2, Interpreter}, and vice versa. + * @library /test/lib * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile TestCallingConventionC1.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestCallingConventionC1 + * @compile InlineTypes.java + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestCallingConventionC1 */ -public class TestCallingConventionC1 extends InlineTypeTest { - public static final int C1 = COMP_LEVEL_SIMPLE; - public static final int C2 = COMP_LEVEL_FULL_OPTIMIZATION; - - @Override - public int getNumScenarios() { - return 5; - } - - @Override - public String[] getVMParameters(int scenario) { - switch (scenario) { - case 0: return new String[] { - // Default: both C1 and C2 are enabled, tiered compilation enabled - "-XX:CICompilerCount=2", - "-XX:TieredStopAtLevel=4", - "-XX:+TieredCompilation", - }; - case 1: return new String[] { - // Default: both C1 and C2 are enabled, tiered compilation enabled - "-XX:CICompilerCount=2", - "-XX:TieredStopAtLevel=4", - "-XX:+TieredCompilation", - "-XX:+StressInlineTypeReturnedAsFields" - }; - case 2: return new String[] { - // Same as above, but flip all the compLevel=C1 and compLevel=C2, so we test +public class TestCallingConventionC1 { + public static void main(String[] args) { + final Scenario[] scenarios = { + // Default: both CompLevel.C1 and CompLevel.C2 are enabled, tiered compilation enabled + new Scenario(0, + "-XX:CICompilerCount=2", + "-XX:TieredStopAtLevel=4", + "-XX:+TieredCompilation"), + // Default: both CompLevel.C1 and CompLevel.C2 are enabled, tiered compilation enabled + new Scenario(1, + "-XX:CICompilerCount=2", + "-XX:TieredStopAtLevel=4", + "-XX:+TieredCompilation", + "-XX:+StressInlineTypeReturnedAsFields"), + // Same as above, but flip all the compLevel=CompLevel.C1 and compLevel=CompLevel.C2, so we test // the compliment of the above scenario. - "-XX:CICompilerCount=2", - "-XX:TieredStopAtLevel=4", - "-XX:+TieredCompilation", - "-DFlipC1C2=true" - }; - case 3: return new String[] { - // Only C1. Tiered compilation disabled. - "-XX:TieredStopAtLevel=1", - "-XX:+TieredCompilation", - }; - case 4: return new String[] { - // Only C2. - "-XX:TieredStopAtLevel=4", - "-XX:-TieredCompilation", - }; - } - return null; - } - - public static void main(String[] args) throws Throwable { - System.gc(); // Resolve this call, to avoid C1 code patching in the test cases. - TestCallingConventionC1 test = new TestCallingConventionC1(); - test.run(args, - Point.class, - Functor.class, - Functor1.class, - Functor2.class, - Functor3.class, - Functor4.class, - MyImplPojo0.class, - MyImplPojo1.class, - MyImplPojo2.class, - MyImplPojo3.class, - MyImplVal1.class, - MyImplVal2.class, - MyImplVal1X.class, - MyImplVal2X.class, - FixedPoints.class, - FloatPoint.class, - RefPoint.class, - RefPoint_Access_Impl1.class, - RefPoint_Access_Impl2.class); - } - + new Scenario(2, + "-XX:CICompilerCount=2", + "-XX:TieredStopAtLevel=4", + "-XX:+TieredCompilation", + "-DFlipCompLevel.C1CompLevel.C2=true"), + // Only CompLevel.C1. Tiered compilation disabled. + new Scenario(3, + "-XX:TieredStopAtLevel=1", + "-XX:+TieredCompilation"), + // Only CompLevel.C2. + new Scenario(4, + "-XX:TieredStopAtLevel=4", + "-XX:-TieredCompilation") + }; + + System.gc(); // Resolve this call, to avoid CompLevel.C1 code patching in the test cases. + + TestFramework testFramework = new TestFramework(TestCallingConventionC1.class); + testFramework.addScenarios(scenarios) + .start(); + } + + // Helper methods and classes + + @ForceCompileClassInitializer static primitive class Point { final int x; final int y; @@ -120,13 +90,11 @@ public Point(int x, int y) { } @DontCompile - @DontInline public int func() { return x + y; } - @ForceCompile(compLevel = C1) - @DontInline + @ForceCompile(CompLevel.C1) public int func_c1(Point p) { return x + y + p.x + p.y; } @@ -136,37 +104,41 @@ static interface FunctorInterface { public int apply_interp(Point p); } + @ForceCompileClassInitializer static class Functor implements FunctorInterface { @DontCompile - @DontInline public int apply_interp(Point p) { return p.func() + 0; } } + + @ForceCompileClassInitializer static class Functor1 extends Functor { @DontCompile - @DontInline public int apply_interp(Point p) { return p.func() + 10000; } } + + @ForceCompileClassInitializer static class Functor2 extends Functor { @DontCompile - @DontInline public int apply_interp(Point p) { return p.func() + 20000; } } + + @ForceCompileClassInitializer static class Functor3 extends Functor { @DontCompile - @DontInline public int apply_interp(Point p) { return p.func() + 30000; } } + + @ForceCompileClassInitializer static class Functor4 extends Functor { @DontCompile - @DontInline public int apply_interp(Point p) { return p.func() + 40000; } @@ -194,32 +166,36 @@ static interface Intf { public int func2(int a, int b, Point p); } + @ForceCompileClassInitializer static class MyImplPojo0 implements Intf { int field = 0; - @DontInline @DontCompile + @DontCompile public int func1(int a, int b) { return field + a + b + 1; } - @DontInline @DontCompile + @DontCompile public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 1; } } + @ForceCompileClassInitializer static class MyImplPojo1 implements Intf { int field = 1000; - @DontInline @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) public int func1(int a, int b) { return field + a + b + 20; } - @DontInline @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 20; } } + @ForceCompileClassInitializer static class MyImplPojo2 implements Intf { int field = 2000; - @DontInline @ForceCompile(compLevel = C2) + @ForceCompile(CompLevel.C2) public int func1(int a, int b) { return field + a + b + 20; } - @DontInline @ForceCompile(compLevel = C2) + @ForceCompile(CompLevel.C2) public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 20; } } + @ForceCompileClassInitializer static class MyImplPojo3 implements Intf { int field = 0; @DontInline // will be compiled with counters @@ -228,45 +204,50 @@ static class MyImplPojo3 implements Intf { public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 1; } } + @ForceCompileClassInitializer static primitive class MyImplVal1 implements Intf { final int field; MyImplVal1() { field = 11000; } - @DontInline @ForceCompile(compLevel = C1) - public int func1(int a, int b) { return field + a + b + 300; } + @DontInline + @ForceCompile(CompLevel.C1) + public int func1(int a, int b) { return field + a + b + 300; } - @DontInline @ForceCompile(compLevel = C1) + @DontInline @ForceCompile(CompLevel.C1) public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 300; } } + @ForceCompileClassInitializer static primitive class MyImplVal2 implements Intf { final int field; MyImplVal2() { field = 12000; } - @DontInline @ForceCompile(compLevel = C2) + @DontInline @ForceCompile(CompLevel.C2) public int func1(int a, int b) { return field + a + b + 300; } - @DontInline @ForceCompile(compLevel = C2) + @DontInline @ForceCompile(CompLevel.C2) public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 300; } } + @ForceCompileClassInitializer static primitive class MyImplVal1X implements Intf { final int field; MyImplVal1X() { field = 11000; } - @DontInline @DontCompile + @DontCompile public int func1(int a, int b) { return field + a + b + 300; } - @DontInline @DontCompile + @DontCompile public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 300; } } + @ForceCompileClassInitializer static primitive class MyImplVal2X implements Intf { final int field; MyImplVal2X() { @@ -282,10 +263,10 @@ static primitive class MyImplVal2X implements Intf { static Intf intfs[] = { new MyImplPojo0(), // methods not compiled - new MyImplPojo1(), // methods compiled by C1 - new MyImplPojo2(), // methods compiled by C2 - new MyImplVal1(), // methods compiled by C1 - new MyImplVal2() // methods compiled by C2 + new MyImplPojo1(), // methods compiled by CompLevel.C1 + new MyImplPojo2(), // methods compiled by CompLevel.C2 + new MyImplVal1(), // methods compiled by CompLevel.C1 + new MyImplVal2() // methods compiled by CompLevel.C2 }; static Intf getIntf(int i) { int n = i % intfs.length; @@ -303,6 +284,7 @@ static primitive class FixedPoints { } static FixedPoints fixedPointsField = new FixedPoints(); + @ForceCompileClassInitializer static primitive class FloatPoint { final float x; final float y; @@ -311,6 +293,8 @@ public FloatPoint(float x, float y) { this.y = y; } } + + @ForceCompileClassInitializer static primitive class DoublePoint { final double x; final double y; @@ -322,6 +306,7 @@ public DoublePoint(double x, double y) { static FloatPoint floatPointField = new FloatPoint(123.456f, 789.012f); static DoublePoint doublePointField = new DoublePoint(123.456, 789.012); + @ForceCompileClassInitializer static primitive class EightFloats { float f1, f2, f3, f4, f5, f6, f7, f8; public EightFloats() { @@ -337,6 +322,7 @@ public EightFloats() { } static EightFloats eightFloatsField = new EightFloats(); + @ForceCompileClassInitializer static class Number { int n; Number(int v) { @@ -352,6 +338,7 @@ static interface RefPoint_Access { public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2); } + @ForceCompileClassInitializer static primitive class RefPoint implements RefPoint_Access { final Number x; final Number y; @@ -365,19 +352,19 @@ public RefPoint(Number x, Number y) { } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) public final int final_func(RefPoint rp2) { // opt_virtual_call return this.x.n + this.y.n + rp2.x.n + rp2.y.n; } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) public int func1(RefPoint rp2) { return this.x.n + this.y.n + rp2.x.n + rp2.y.n; } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return x.n + y.n + rp1.x.n + rp1.y.n + @@ -389,13 +376,14 @@ public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint r } } + @ForceCompileClassInitializer static class RefPoint_Access_Impl1 implements RefPoint_Access { - @DontInline @DontCompile + @DontCompile public int func1(RefPoint rp2) { return rp2.x.n + rp2.y.n + 1111111; } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return 111111 + rp1.x.n + rp1.y.n + @@ -406,13 +394,15 @@ public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint r n2.n; } } + + @ForceCompileClassInitializer static class RefPoint_Access_Impl2 implements RefPoint_Access { - @DontInline @DontCompile + @DontCompile public int func1(RefPoint rp2) { return rp2.x.n + rp2.y.n + 2222222; } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return 222222 + rp1.x.n + rp1.y.n + @@ -441,6 +431,7 @@ static RefPoint_Access get_RefPoint_Access() { // This inline class has too many fields to fit in registers on x64 for // InlineTypeReturnedAsFields. + @ForceCompileClassInitializer static primitive class TooBigToReturnAsFields { int a0 = 0; int a1 = 1; @@ -457,132 +448,128 @@ static primitive class TooBigToReturnAsFields { static TooBigToReturnAsFields tooBig = new TooBigToReturnAsFields(); //********************************************************************** - // PART 1 - C1 calls interpreted code + // PART 1 - CompLevel.C1 calls interpreted code //********************************************************************** - - //** C1 passes inline type to interpreter (static) - @Test(compLevel = C1) + //** CompLevel.C1 passes inline type to interpreter (static) + @Test(compLevel = CompLevel.C1) public int test1() { return test1_helper(pointField); } - @DontInline @DontCompile private static int test1_helper(Point p) { return p.func(); } - @DontCompile - public void test1_verifier(boolean warmup) { - int count = warmup ? 1 : 10; + @Run(test = "test1") + public void test1_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 10; for (int i=0; iC1 invokestatic, single inline arg - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, single inline arg + @Test(compLevel = CompLevel.C2) public int test30() { return test30_helper(pointField); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test30_helper(Point p) { return p.x + p.y; } - @DontCompile - public void test30_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test30") + public void test30_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokestatic, two single inline args - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, two single inline args + @Test(compLevel = CompLevel.C2) public int test31() { return test31_helper(pointField1, pointField2); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test31_helper(Point p1, Point p2) { return p1.x + p2.y; } - @DontCompile - public void test31_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test31") + public void test31_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokestatic, two single inline args and interleaving ints (all passed in registers on x64) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, two single inline args and interleaving ints (all passed in registers on x64) + @Test(compLevel = CompLevel.C2) public int test32() { return test32_helper(0, pointField1, 1, pointField2); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test32_helper(int x, Point p1, int y, Point p2) { return p1.x + p2.y + x + y; } - @DontCompile - public void test32_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test32") + public void test32_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokeinterface -- no verified_ro_entry (no inline args except for receiver) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokeinterface -- no verified_ro_entry (no inline args except for receiver) + @Test(compLevel = CompLevel.C2) public int test33(Intf intf, int a, int b) { return intf.func1(a, b); } - @DontCompile - public void test33_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test33") + public void test33_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC1 invokeinterface -- use verified_ro_entry (has inline args other than receiver) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokeinterface -- use verified_ro_entry (has inline args other than receiver) + @Test(compLevel = CompLevel.C2) public int test34(Intf intf, int a, int b) { return intf.func2(a, b, pointField); } - @DontCompile - public void test34_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test34") + public void test34_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC1 invokestatic, Point.y is on stack (x64) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, Point.y is on stack (x64) + @Test(compLevel = CompLevel.C2) public int test35() { return test35_helper(1, 2, 3, 4, 5, pointField); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test35_helper(int a1, int a2, int a3, int a4, int a5, Point p) { return a1 + a2 + a3 + a4 + a5 + p.x + p.y; } - @DontCompile - public void test35_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test35") + public void test35_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokestatic, shuffling arguments that are passed on stack - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, shuffling arguments that are passed on stack + @Test(compLevel = CompLevel.C2) public int test36() { return test36_helper(pointField, 1, 2, 3, 4, 5, 6, 7, 8); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test36_helper(Point p, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { return a6 + a8; } - @DontCompile - public void test36_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test36") + public void test36_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokestatic, shuffling long arguments - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, shuffling long arguments + @Test(compLevel = CompLevel.C2) public int test37() { return test37_helper(pointField, 1, 2, 3, 4, 5, 6, 7, 8); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test37_helper(Point p, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return (int)(a6 + a8); } - @DontCompile - public void test37_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test37") + public void test37_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokestatic, shuffling boolean, byte, char, short, int, long arguments - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, shuffling boolean, byte, char, short, int, long arguments + @Test(compLevel = CompLevel.C2) public int test38() { return test38_helper(pointField, true, (byte)1, (char)2, (short)3, 4, 5, (byte)6, (short)7, 8); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test38_helper(Point p, boolean a0, byte a1, char a2, short a3, int a4, long a5, byte a6, short a7, int a8) { if (a0) { return (int)(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8); @@ -773,9 +760,9 @@ private static int test38_helper(Point p, boolean a0, byte a1, char a2, short a3 } } - @DontCompile - public void test38_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test38") + public void test38_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokestatic, packing an inline type with all types of fixed point primitive fields. - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, packing an inline type with all types of fixed point primitive fields. + @Test(compLevel = CompLevel.C2) public long test39() { return test39_helper(1, fixedPointsField, 2, fixedPointsField); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static long test39_helper(int a1, FixedPoints f1, int a2, FixedPoints f2) { if (f1.Z0 == false && f1.Z1 == true && f2.Z0 == false && f2.Z1 == true) { return f1.B + f2.C + f1.S + f2.I + f1.J; @@ -799,9 +786,9 @@ private static long test39_helper(int a1, FixedPoints f1, int a2, FixedPoints f2 } } - @DontCompile - public void test39_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test39") + public void test39_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokestatic, shuffling floating point args - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, shuffling floating point args + @Test(compLevel = CompLevel.C2) public double test40() { return test40_helper(1.1f, 1.2, floatPointField, doublePointField, 1.3f, 1.4, 1.5f, 1.7, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static double test40_helper(float a1, double a2, FloatPoint fp, DoublePoint dp, float a3, double a4, float a5, double a6, double a7, double a8, double a9, double a10, double a11, double a12) { return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + fp.x + fp.y - dp.x - dp.y; } - @DontCompile - public void test40_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test40") + public void test40_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokestatic, mixing floats and ints - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, mixing floats and ints + @Test(compLevel = CompLevel.C2) public double test41() { return test41_helper(1, 1.2, pointField, floatPointField, doublePointField, 1.3f, 4, 1.5f, 1.7, 1.7, 1.8, 9, 1.10, 1.11, 1.12); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static double test41_helper(int a1, double a2, Point p, FloatPoint fp, DoublePoint dp, float a3, int a4, float a5, double a6, double a7, double a8, long a9, double a10, double a11, double a12) { return a1 + a2 + fp.x + fp.y - dp.x - dp.y + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12; } - @DontCompile - public void test41_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test41") + public void test41_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokestatic, circular dependency (between rdi and first stack slot on x64) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, circular dependency (between rdi and first stack slot on x64) + @Test(compLevel = CompLevel.C2) public float test42() { return test42_helper(eightFloatsField, pointField, 3, 4, 5, floatPointField, 7); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static float test42_helper(EightFloats ep1, // (xmm0 ... xmm7) -> rsi Point p2, // (rsi, rdx) -> rdx int i3, // rcx -> rcx @@ -873,9 +860,9 @@ private static float test42_helper(EightFloats ep1, // (xmm0 ... xmm7) -> rsi p2.x + p2.y + i3 + i4 + i5 + fp6.x + fp6.y + i7; } - @DontCompile - public void test42_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test42") + public void test42_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokestatic, packing causes stack growth (1 extra stack word) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, packing causes stack growth (1 extra stack word) + @Test(compLevel = CompLevel.C2) public float test43() { return test43_helper(floatPointField, 1, 2, 3, 4, 5, 6); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static float test43_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) { // On x64: // Scalarized entry -- all parameters are passed in registers @@ -898,9 +885,9 @@ private static float test43_helper(FloatPoint fp, int a1, int a2, int a3, int a4 return fp.x + fp.y + a1 + a2 + a3 + a4 + a5 + a6; } - @DontCompile - public void test43_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test43") + public void test43_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokestatic, packing causes stack growth (2 extra stack words) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, packing causes stack growth (2 extra stack words) + @Test(compLevel = CompLevel.C2) public float test44() { return test44_helper(floatPointField, floatPointField, 1, 2, 3, 4, 5, 6); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static float test44_helper(FloatPoint fp1, FloatPoint fp2, int a1, int a2, int a3, int a4, int a5, int a6) { // On x64: // Scalarized entry -- all parameters are passed in registers @@ -926,9 +913,9 @@ private static float test44_helper(FloatPoint fp1, FloatPoint fp2, int a1, int a a1 + a2 + a3 + a4 + a5 + a6; } - @DontCompile - public void test44_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test44") + public void test44_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokestatic, packing causes stack growth (5 extra stack words) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, packing causes stack growth (5 extra stack words) + @Test(compLevel = CompLevel.C2) public float test45() { return test45_helper(floatPointField, floatPointField, floatPointField, floatPointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static float test45_helper(FloatPoint fp1, FloatPoint fp2, FloatPoint fp3, FloatPoint fp4, FloatPoint fp5, int a1, int a2, int a3, int a4, int a5, int a6, int a7) { return fp1.x + fp1.y + fp2.x + fp2.y + @@ -953,9 +940,9 @@ private static float test45_helper(FloatPoint fp1, FloatPoint fp2, FloatPoint fp a1 + a2 + a3 + a4 + a5 + a6 + a7; } - @DontCompile - public void test45_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test45") + public void test45_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokestatic, packing causes stack growth (1 extra stack word -- mixing Point and FloatPoint) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, packing causes stack growth (1 extra stack word -- mixing Point and FloatPoint) + @Test(compLevel = CompLevel.C2) public float test46() { return test46_helper(floatPointField, floatPointField, pointField, floatPointField, floatPointField, pointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static float test46_helper(FloatPoint fp1, FloatPoint fp2, Point p1, FloatPoint fp3, FloatPoint fp4, Point p2, FloatPoint fp5, int a1, int a2, int a3, int a4, int a5, int a6, int a7) { return p1.x + p1.y + p2.x + p2.y + @@ -982,9 +969,9 @@ private static float test46_helper(FloatPoint fp1, FloatPoint fp2, Point p1, Flo a1 + a2 + a3 + a4 + a5 + a6 + a7; } - @DontCompile - public void test46_verifier(boolean warmup) { - int count = warmup ? 1 : 2; + @Run(test = "test46") + public void test46_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 2; for (int i=0; iC1 invokestatic, make sure stack walking works (with static variable) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, make sure stack walking works (with static variable) + @Test(compLevel = CompLevel.C2) public void test47(int n) { try { test47_helper(floatPointField, 1, 2, 3, 4, 5); @@ -1024,13 +1012,13 @@ public void test47(int n) { } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static float test47_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5) { test47_thrower(); return 0.0f; } - @DontInline @DontCompile + @DontCompile private static void test47_thrower() { MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); checkStackTrace(e, "test47_thrower", "test47_helper", "test47", "test47_verifier"); @@ -1039,9 +1027,9 @@ private static void test47_thrower() { static int test47_value = 999; - @DontCompile - public void test47_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test47") + public void test47_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iC1 invokestatic, make sure stack walking works (with returned inline type) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, make sure stack walking works (with returned inline type) + @Test(compLevel = CompLevel.C2) public int test48(int n) { try { test48_helper(floatPointField, 1, 2, 3, 4, 5); @@ -1062,32 +1050,32 @@ public int test48(int n) { } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static float test48_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5) { test48_thrower(); return 0.0f; } - @DontInline @DontCompile + @DontCompile private static void test48_thrower() { MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); checkStackTrace(e, "test48_thrower", "test48_helper", "test48", "test48_verifier"); throw e; } - @DontCompile - public void test48_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test48") + public void test48_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iinterpreter invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair) + // CompLevel.C2->interpreter invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair) // (this is the baseline for test50 -- - // the only difference is: test49_helper is interpreted but test50_helper is compiled by C1). - @Test(compLevel = C2) + // the only difference is: test49_helper is interpreted but test50_helper is compiled by CompLevel.C1). + @Test(compLevel = CompLevel.C2) public int test49(int n) { try { test49_helper(floatPointField, 1, 2, 3, 4, 5, 6); @@ -1098,30 +1086,30 @@ public int test49(int n) { return n; } - @DontInline @DontCompile + @DontCompile private static float test49_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) { test49_thrower(); return 0.0f; } - @DontInline @DontCompile + @DontCompile private static void test49_thrower() { MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); checkStackTrace(e, "test49_thrower", "test49_helper", "test49", "test49_verifier"); throw e; } - @DontCompile - public void test49_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test49") + public void test49_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iC1 invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair) + @Test(compLevel = CompLevel.C2) public int test50(int n) { try { test50_helper(floatPointField, 1, 2, 3, 4, 5, 6); @@ -1133,22 +1121,22 @@ public int test50(int n) { } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static float test50_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) { test50_thrower(); return 0.0f; } - @DontInline @DontCompile + @DontCompile private static void test50_thrower() { MyRuntimeException e = new MyRuntimeException("This exception should have been caught!"); checkStackTrace(e, "test50_thrower", "test50_helper", "test50", "test50_verifier"); throw e; } - @DontCompile - public void test50_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test50") + public void test50_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iC1 invokestatic, inline class with ref fields (RefPoint) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, inline class with ref fields (RefPoint) + @Test(compLevel = CompLevel.C2) public int test51() { return test51_helper(refPointField1); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test51_helper(RefPoint rp1) { return rp1.x.n + rp1.y.n; } - @DontCompile - public void test51_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test51") + public void test51_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iC1 invokestatic, inline class with ref fields (Point, RefPoint) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, inline class with ref fields (Point, RefPoint) + @Test(compLevel = CompLevel.C2) public int test52() { return test52_helper(pointField, refPointField1); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test52_helper(Point p1, RefPoint rp1) { return p1.x + p1.y + rp1.x.n + rp1.y.n; } - @DontCompile - public void test52_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test52") + public void test52_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iC1 invokestatic, inline class with ref fields (RefPoint, RefPoint, RefPoint, RefPoint) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, inline class with ref fields (RefPoint, RefPoint, RefPoint, RefPoint) + @Test(compLevel = CompLevel.C2) public int test53() { return test53_helper(refPointField1, refPointField2, refPointField1, refPointField2); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test53_helper(RefPoint rp1, RefPoint rp2, RefPoint rp3, RefPoint rp4) { return rp1.x.n + rp1.y.n + rp2.x.n + rp2.y.n + @@ -1215,9 +1203,9 @@ private static int test53_helper(RefPoint rp1, RefPoint rp2, RefPoint rp3, RefPo rp4.x.n + rp4.y.n; } - @DontCompile - public void test53_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test53") + public void test53_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iC1 invokestatic, inline class with ref fields (RefPoint, RefPoint, float, int, RefPoint, RefPoint) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, inline class with ref fields (RefPoint, RefPoint, float, int, RefPoint, RefPoint) + @Test(compLevel = CompLevel.C2) public int test54() { return test54_helper(refPointField1, refPointField2, 1.0f, 2, refPointField1, refPointField2); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test54_helper(RefPoint rp1, RefPoint rp2, float f, int i, RefPoint rp3, RefPoint rp4) { return rp1.x.n + rp1.y.n + rp2.x.n + rp2.y.n + @@ -1241,9 +1229,9 @@ private static int test54_helper(RefPoint rp1, RefPoint rp2, float f, int i, Ref rp4.x.n + rp4.y.n; } - @DontCompile - public void test54_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test54") + public void test54_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iC1 invokestatic, force GC for every allocation when entering a C1 VEP (Point) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, force GC for every allocation when entering a CompLevel.C1 VEP (Point) + @Test(compLevel = CompLevel.C2) public int test55(Point p1) { return test55_helper(p1); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test55_helper(Point p1) { return p1.x + p1.y; } - @DontCompile - public void test55_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test55") + public void test55_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iC1 invokestatic, force GC for every allocation when entering a C1 VEP (RefPoint) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, force GC for every allocation when entering a CompLevel.C1 VEP (RefPoint) + @Test(compLevel = CompLevel.C2) public int test56(RefPoint rp1) { return test56_helper(rp1); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test56_helper(RefPoint rp1) { return rp1.x.n + rp1.y.n; } - @DontCompile - public void test56_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test56") + public void test56_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iInterpreter (same as test56, but test c2i entry instead of C1) - @Test(compLevel = C2) + // CompLevel.C2->Interpreter (same as test56, but test CompLevel.C2i entry instead of CompLevel.C1) + @Test(compLevel = CompLevel.C2) public int test57(RefPoint rp1) { return test57_helper(rp1); } - @DontInline @DontCompile + @DontCompile private static int test57_helper(RefPoint rp1) { return rp1.x.n + rp1.y.n; } - @DontCompile - public void test57_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test57") + public void test57_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iC1 invokestatic, force GC for every allocation when entering a C1 VEP (a bunch of RefPoints and Numbers); - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, force GC for every allocation when entering a CompLevel.C1 VEP (a bunch of RefPoints and Numbers); + @Test(compLevel = CompLevel.C2) public int test58(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return test58_helper(rp1, rp2, n1, rp3, rp4, n2); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test58_helper(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return rp1.x.n + rp1.y.n + rp2.x.n + rp2.y.n + @@ -1371,9 +1356,9 @@ private static int test58_helper(RefPoint rp1, RefPoint rp2, Number n1, RefPoint n2.n; } - @DontCompile - public void test58_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test58") + public void test58_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iC1 invokestatic, GC inside main body of C1-compiled method (caller's args should not be GC'ed). - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic, GC inside main body of CompLevel.C1-compiled method (caller's args should not be GC'ed). + @Test(compLevel = CompLevel.C2) public int test59(RefPoint rp1, boolean doGC) { return test59_helper(rp1, 11, 222, 3333, 4444, doGC); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test59_helper(RefPoint rp1, int a1, int a2, int a3, int a4, boolean doGC) { if (doGC) { System.gc(); @@ -1405,10 +1390,10 @@ private static int test59_helper(RefPoint rp1, int a1, int a2, int a3, int a4, b return rp1.x.n + rp1.y.n + a1 + a2 + a3 + a4; } - @DontCompile - public void test59_verifier(boolean warmup) { - int count = warmup ? 1 : 5; - boolean doGC = !warmup; + @Run(test = "test59") + public void test59_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; + boolean doGC = !info.isWarmUp(); for (int i=0; iC1 invokestatic, GC inside main body of C1-compiled method (caller's args should not be GC'ed). + // CompLevel.C2->CompLevel.C1 invokestatic, GC inside main body of CompLevel.C1-compiled method (caller's args should not be GC'ed). // same as test59, but the incoming (scalarized) oops are passed in both registers and stack. - @Test(compLevel = C2) + @Test(compLevel = CompLevel.C2) public int test60(RefPoint rp1, RefPoint rp2, boolean doGC) { return test60_helper(555, 6666, 77777, rp1, rp2, 11, 222, 3333, 4444, doGC); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static int test60_helper(int x0, int x1, int x2, RefPoint rp1, RefPoint rp2,int a1, int a2, int a3, int a4, boolean doGC) { - // On x64, C2 passes: reg0=x1, reg1=x1, reg2=x2, reg3=rp1.x, reg4=rp1.y, reg5=rp2.x stack0=rp2.y .... - // C1 expects: reg0=x1, reg1=x1, reg2=x2, reg3=rp1, reg4=rp2, reg5=a1 stack0=a2 ... + // On x64, CompLevel.C2 passes: reg0=x1, reg1=x1, reg2=x2, reg3=rp1.x, reg4=rp1.y, reg5=rp2.x stack0=rp2.y .... + // CompLevel.C1 expects: reg0=x1, reg1=x1, reg2=x2, reg3=rp1, reg4=rp2, reg5=a1 stack0=a2 ... // When GC happens, make sure it does not treat reg5 and stack0 as oops! if (doGC) { System.gc(); @@ -1436,10 +1421,10 @@ private static int test60_helper(int x0, int x1, int x2, RefPoint rp1, RefPoint return x0 + x1 + x2 + rp1.x.n + rp1.y.n + rp2.x.n + rp2.y.n + a1 + a2 + a3 + a4; } - @DontCompile - public void test60_verifier(boolean warmup) { - int count = warmup ? 1 : 5; - boolean doGC = !warmup; + @Run(test = "test60") + public void test60_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; + boolean doGC = !info.isWarmUp(); for (int i=0; iC1 invokeinterface via VVEP(RO) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokeinterface via VVEP(RO) + @Test(compLevel = CompLevel.C2) public int test61(RefPoint_Access rpa, RefPoint rp2) { return rpa.func1(rp2); } - @DontCompile - public void test61_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test61") + public void test61_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a C1 VVEP(RO) (RefPoint) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a CompLevel.C1 VVEP(RO) (RefPoint) + @Test(compLevel = CompLevel.C2) public int test62(RefPoint_Access rpa, RefPoint rp2) { return rpa.func1(rp2); } - @DontCompile - public void test62_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test62") + public void test62_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a C1 VVEP(RO) (a bunch of RefPoints and Numbers) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a CompLevel.C1 VVEP(RO) (a bunch of RefPoints and Numbers) + @Test(compLevel = CompLevel.C2) public int test63(RefPoint_Access rpa, RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return rpa.func2(rp1, rp2, n1, rp3, rp4, n2); } - @DontCompile - public void test63_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test63") + public void test63_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC1 invokestatic (same as test63, but use invokestatic instead) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic (same as test63, but use invokestatic instead) + @Test(compLevel = CompLevel.C2) public int test64(RefPoint_Access rpa, RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return test64_helper(rpa, rp1, rp2, n1, rp3, rp4, n2); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) public static int test64_helper(RefPoint_Access rpa, RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return rp3.y.n; } - @DontCompile - public void test64_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test64") + public void test64_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC1 invokevirtual via VVEP(RO) (opt_virtual_call) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokevirtual via VVEP(RO) (opt_virtual_call) + @Test(compLevel = CompLevel.C2) public int test76(RefPoint rp1, RefPoint rp2) { return rp1.final_func(rp2); } - @DontCompile - public void test76_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test76") + public void test76_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iC1 invokevirtual, force GC for every allocation when entering a C1 VEP (RefPoint) + // CompLevel.C2->CompLevel.C1 invokevirtual, force GC for every allocation when entering a CompLevel.C1 VEP (RefPoint) // Same as test56, except we call the VVEP(RO) instead of VEP. - @Test(compLevel = C2) + @Test(compLevel = CompLevel.C2) public int test77(RefPoint rp1, RefPoint rp2) { return rp1.final_func(rp2); } - @DontCompile - public void test77_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test77") + public void test77_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iC1 invokestatic with InlineTypeReturnedAsFields (Point) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic with InlineTypeReturnedAsFields (Point) + @Test(compLevel = CompLevel.C2) public int test78(Point p) { Point np = test78_helper(p); return np.x + np.y; } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static Point test78_helper(Point p) { return p; } - @DontCompile - public void test78_verifier(boolean warmup) { + @Run(test = "test78") + public void test78_verifier(RunInfo info) { int result = test78(pointField1); int n = pointField1.x + pointField1.y; Asserts.assertEQ(result, n); } - // C2->C1 invokestatic with InlineTypeReturnedAsFields (RefPoint) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic with InlineTypeReturnedAsFields (RefPoint) + @Test(compLevel = CompLevel.C2) public int test79(RefPoint p) { RefPoint np = test79_helper(p); return np.x.n + np.y.n; } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static RefPoint test79_helper(RefPoint p) { return p; } - @DontCompile - public void test79_verifier(boolean warmup) { + @Run(test = "test79") + public void test79_verifier(RunInfo info) { int result = test79(refPointField1); int n = refPointField1.x.n + refPointField1.y.n; Asserts.assertEQ(result, n); } - // C1->C2 invokestatic with InlineTypeReturnedAsFields (RefPoint) - @Test(compLevel = C1) + // CompLevel.C1->CompLevel.C2 invokestatic with InlineTypeReturnedAsFields (RefPoint) + @Test(compLevel = CompLevel.C1) public int test80(RefPoint p) { RefPoint np = test80_helper(p); return np.x.n + np.y.n; } @DontInline - @ForceCompile(compLevel = C2) + @ForceCompile(CompLevel.C2) private static RefPoint test80_helper(RefPoint p) { return p; } - @DontCompile - public void test80_verifier(boolean warmup) { + @Run(test = "test80") + public void test80_verifier(RunInfo info) { int result = test80(refPointField1); int n = refPointField1.x.n + refPointField1.y.n; Asserts.assertEQ(result, n); } - // Interpreter->C1 invokestatic with InlineTypeReturnedAsFields (Point) - @Test(compLevel = C1) + // Interpreter->CompLevel.C1 invokestatic with InlineTypeReturnedAsFields (Point) + @Test(compLevel = CompLevel.C1) public Point test81(Point p) { return p; } - @DontCompile - public void test81_verifier(boolean warmup) { + @Run(test = "test81") + public void test81_verifier(RunInfo info) { Point p = test81(pointField1); Asserts.assertEQ(p.x, pointField1.x); Asserts.assertEQ(p.y, pointField1.y); @@ -1665,20 +1650,20 @@ public void test81_verifier(boolean warmup) { Asserts.assertEQ(p.y, pointField2.y); } - // C1->Interpreter invokestatic with InlineTypeReturnedAsFields (RefPoint) - @Test(compLevel = C1) + // CompLevel.C1->Interpreter invokestatic with InlineTypeReturnedAsFields (RefPoint) + @Test(compLevel = CompLevel.C1) public int test82(RefPoint p) { RefPoint np = test82_helper(p); return np.x.n + np.y.n; } - @DontInline @DontCompile + @DontCompile private static RefPoint test82_helper(RefPoint p) { return p; } - @DontCompile - public void test82_verifier(boolean warmup) { + @Run(test = "test82") + public void test82_verifier(RunInfo info) { int result = test82(refPointField1); int n = refPointField1.x.n + refPointField1.y.n; Asserts.assertEQ(result, n); @@ -1688,148 +1673,148 @@ public void test82_verifier(boolean warmup) { // Tests for InlineTypeReturnedAsFields vs the inline class TooBigToReturnAsFields //------------------------------------------------------------------------------- - // C2->C1 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) + @Test(compLevel = CompLevel.C2) public int test83(TooBigToReturnAsFields p) { TooBigToReturnAsFields np = test83_helper(p); return p.a0 + p.a5; } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static TooBigToReturnAsFields test83_helper(TooBigToReturnAsFields p) { return p; } - @DontCompile - public void test83_verifier(boolean warmup) { + @Run(test = "test83") + public void test83_verifier(RunInfo info) { int result = test83(tooBig); int n = tooBig.a0 + tooBig.a5; Asserts.assertEQ(result, n); } - // C1->C2 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) - @Test(compLevel = C1) + // CompLevel.C1->CompLevel.C2 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) + @Test(compLevel = CompLevel.C1) public int test84(TooBigToReturnAsFields p) { TooBigToReturnAsFields np = test84_helper(p); return p.a0 + p.a5; } @DontInline - @ForceCompile(compLevel = C2) + @ForceCompile(CompLevel.C2) private static TooBigToReturnAsFields test84_helper(TooBigToReturnAsFields p) { return p; } - @DontCompile - public void test84_verifier(boolean warmup) { + @Run(test = "test84") + public void test84_verifier(RunInfo info) { int result = test84(tooBig); int n = tooBig.a0 + tooBig.a5; Asserts.assertEQ(result, n); } - // Interpreter->C1 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) - @Test(compLevel = C1) + // Interpreter->CompLevel.C1 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) + @Test(compLevel = CompLevel.C1) public TooBigToReturnAsFields test85(TooBigToReturnAsFields p) { return p; } - @DontCompile - public void test85_verifier(boolean warmup) { + @Run(test = "test85") + public void test85_verifier(RunInfo info) { TooBigToReturnAsFields p = test85(tooBig); Asserts.assertEQ(p.a0, tooBig.a0); Asserts.assertEQ(p.a2, tooBig.a2); } - // C1->Interpreter invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) - @Test(compLevel = C1) + // CompLevel.C1->Interpreter invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) + @Test(compLevel = CompLevel.C1) public int test86(TooBigToReturnAsFields p) { TooBigToReturnAsFields np = test86_helper(p); return p.a0 + p.a5; } - @DontInline @DontCompile + @DontCompile private static TooBigToReturnAsFields test86_helper(TooBigToReturnAsFields p) { return p; } - @DontCompile - public void test86_verifier(boolean warmup) { + @Run(test = "test86") + public void test86_verifier(RunInfo info) { int result = test86(tooBig); int n = tooBig.a0 + tooBig.a5; Asserts.assertEQ(result, n); } //------------------------------------------------------------------------------- - // Tests for how C1 handles InlineTypeReturnedAsFields in both calls and returns (RefPoint?) + // Tests for how CompLevel.C1 handles InlineTypeReturnedAsFields in both calls and returns (RefPoint?) //------------------------------------------------------------------------------- - // C2->C1 invokestatic with InlineTypeReturnedAsFields (RefPoint.ref) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic with InlineTypeReturnedAsFields (RefPoint.ref) + @Test(compLevel = CompLevel.C2) public RefPoint.ref test87(RefPoint.ref p) { return test87_helper(p); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static RefPoint.ref test87_helper(RefPoint.ref p) { return p; } - @DontCompile - public void test87_verifier(boolean warmup) { + @Run(test = "test87") + public void test87_verifier(RunInfo info) { Object result = test87(null); Asserts.assertEQ(result, null); } - // C2->C1 invokestatic with InlineTypeReturnedAsFields (RefPoint.ref with constant null) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokestatic with InlineTypeReturnedAsFields (RefPoint.ref with constant null) + @Test(compLevel = CompLevel.C2) public RefPoint.ref test88() { return test88_helper(); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static RefPoint.ref test88_helper() { return null; } - @DontCompile - public void test88_verifier(boolean warmup) { + @Run(test = "test88") + public void test88_verifier(RunInfo info) { Object result = test88(); Asserts.assertEQ(result, null); } - // C1->C2 invokestatic with InlineTypeReturnedAsFields (RefPoint.ref) - @Test(compLevel = C1) + // CompLevel.C1->CompLevel.C2 invokestatic with InlineTypeReturnedAsFields (RefPoint.ref) + @Test(compLevel = CompLevel.C1) public RefPoint.ref test89(RefPoint.ref p) { return test89_helper(p); } @DontInline - @ForceCompile(compLevel = C2) + @ForceCompile(CompLevel.C2) private static RefPoint.ref test89_helper(RefPoint.ref p) { return p; } - @DontCompile - public void test89_verifier(boolean warmup) { + @Run(test = "test89") + public void test89_verifier(RunInfo info) { Object result = test89(null); Asserts.assertEQ(result, null); } //---------------------------------------------------------------------------------- // Tests for unverified entries: there are 6 cases: - // C1 -> Unverified Value Entry compiled by C1 - // C1 -> Unverified Value Entry compiled by C2 - // C2 -> Unverified Entry compiled by C1 (target is NOT an inline type) - // C2 -> Unverified Entry compiled by C2 (target is NOT an inline type) - // C2 -> Unverified Entry compiled by C1 (target IS an inline type, i.e., has VVEP_RO) - // C2 -> Unverified Entry compiled by C2 (target IS an inline type, i.e., has VVEP_RO) + // CompLevel.C1 -> Unverified Value Entry compiled by CompLevel.C1 + // CompLevel.C1 -> Unverified Value Entry compiled by CompLevel.C2 + // CompLevel.C2 -> Unverified Entry compiled by CompLevel.C1 (target is NOT an inline type) + // CompLevel.C2 -> Unverified Entry compiled by CompLevel.C2 (target is NOT an inline type) + // CompLevel.C2 -> Unverified Entry compiled by CompLevel.C1 (target IS an inline type, i.e., has VVEP_RO) + // CompLevel.C2 -> Unverified Entry compiled by CompLevel.C2 (target IS an inline type, i.e., has VVEP_RO) //---------------------------------------------------------------------------------- - // C1->C1 invokeinterface -- call Unverified Value Entry of MyImplPojo1.func2 (compiled by C1) - @Test(compLevel = C1) + // CompLevel.C1->CompLevel.C1 invokeinterface -- call Unverified Value Entry of MyImplPojo1.func2 (compiled by CompLevel.C1) + @Test(compLevel = CompLevel.C1) public int test90(Intf intf, int a, int b) { return intf.func2(a, b, pointField); } @@ -1839,9 +1824,9 @@ public int test90(Intf intf, int a, int b) { new MyImplPojo2(), }; - @DontCompile - public void test90_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test90") + public void test90_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC2 invokeinterface -- call Unverified Value Entry of MyImplPojo2.func2 (compiled by C2) - @Test(compLevel = C1) + // CompLevel.C1->CompLevel.C2 invokeinterface -- call Unverified Value Entry of MyImplPojo2.func2 (compiled by CompLevel.C2) + @Test(compLevel = CompLevel.C1) public int test91(Intf intf, int a, int b) { return intf.func2(a, b, pointField); } @@ -1860,9 +1845,9 @@ public int test91(Intf intf, int a, int b) { new MyImplPojo1(), }; - @DontCompile - public void test91_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test91") + public void test91_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC1 invokeinterface -- call Unverified Entry of MyImplPojo1.func2 (compiled by C1) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokeinterface -- call Unverified Entry of MyImplPojo1.func2 (compiled by CompLevel.C1) + @Test(compLevel = CompLevel.C2) public int test92(Intf intf, int a, int b) { return intf.func2(a, b, pointField); } @@ -1881,9 +1866,9 @@ public int test92(Intf intf, int a, int b) { new MyImplPojo2(), }; - @DontCompile - public void test92_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test92") + public void test92_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC2 invokeinterface -- call Unverified Entry of MyImplPojo2.func2 (compiled by C2) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C2 invokeinterface -- call Unverified Entry of MyImplPojo2.func2 (compiled by CompLevel.C2) + @Test(compLevel = CompLevel.C2) public int test93(Intf intf, int a, int b) { return intf.func2(a, b, pointField); } @@ -1902,9 +1887,9 @@ public int test93(Intf intf, int a, int b) { new MyImplPojo1(), }; - @DontCompile - public void test93_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test93") + public void test93_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC1 invokeinterface -- call Unverified Entry of MyImplVal1.func2 (compiled by C1 - has VVEP_RO) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C1 invokeinterface -- call Unverified Entry of MyImplVal1.func2 (compiled by CompLevel.C1 - has VVEP_RO) + @Test(compLevel = CompLevel.C2) public int test94(Intf intf, int a, int b) { return intf.func2(a, b, pointField); } @@ -1923,9 +1908,9 @@ public int test94(Intf intf, int a, int b) { new MyImplVal2(), }; - @DontCompile - public void test94_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test94") + public void test94_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC2 invokeinterface -- call Unverified Entry of MyImplVal2.func2 (compiled by C2 - has VVEP_RO) - @Test(compLevel = C2) + // CompLevel.C2->CompLevel.C2 invokeinterface -- call Unverified Entry of MyImplVal2.func2 (compiled by CompLevel.C2 - has VVEP_RO) + @Test(compLevel = CompLevel.C2) public int test95(Intf intf, int a, int b) { return intf.func2(a, b, pointField); } @@ -1944,9 +1929,9 @@ public int test95(Intf intf, int a, int b) { new MyImplVal1(), }; - @DontCompile - public void test95_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test95") + public void test95_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC2 GC handling in StubRoutines::store_inline_type_fields_to_buf() - @Test(compLevel = C1) + // CompLevel.C1->CompLevel.C2 GC handling in StubRoutines::store_inline_type_fields_to_buf() + @Test(compLevel = CompLevel.C1) public RefPoint test96(RefPoint rp, boolean b) { RefPoint p = test96_helper(rp); if (b) { @@ -1964,19 +1949,20 @@ public RefPoint test96(RefPoint rp, boolean b) { return p; } - @DontInline @ForceCompile(compLevel = C2) + @DontInline + @ForceCompile(CompLevel.C2) public RefPoint test96_helper(RefPoint rp) { return rp; } - @DontCompile - public void test96_verifier(boolean warmup) { - int count = warmup ? 1 : 20000; // Do enough iteration to cause GC inside StubRoutines::store_inline_type_fields_to_buf + @Run(test = "test96") + public void test96_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20000; // Do enough iteration to cause GC inside StubRoutines::store_inline_type_fields_to_buf Number x = new Number(10); // old object for (int i=0; iC1 - caller is compiled first. It invokes callee(test97) a few times while the + // CompLevel.C1->CompLevel.C1 - caller is compiled first. It invokes callee(test97) a few times while the // callee is executed by the interpreter. Then, callee is compiled // and SharedRuntime::fixup_callers_callsite is called to fix up the // callsite from test97_verifier->test97. - @Test(compLevel = C1) + @Test(compLevel = CompLevel.C1) public int test97(Point p1, Point p2) { return test97_helper(p1, p2); } - @DontInline @DontCompile + @DontInline + @ForceCompile(CompLevel.C1) public int test97_helper(Point p1, Point p2) { return p1.x + p1.y + p2.x + p2.y; } - @ForceCompile(compLevel = C1) - public void test97_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test97") + public void test97_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC2 - same as test97, except the callee is compiled by c2. - @Test(compLevel = C2) + // CompLevel.C1->CompLevel.C2 - same as test97, except the callee is compiled by CompLevel.C2. + @Test(compLevel = CompLevel.C2) public int test98(Point p1, Point p2) { return test98_helper(p1, p2); } - @DontInline @DontCompile + @DontInline + @ForceCompile(CompLevel.C1) public int test98_helper(Point p1, Point p2) { return p1.x + p1.y + p2.x + p2.y; } - @ForceCompile(compLevel = C1) - public void test98_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test98") + public void test98_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC2 - same as test97, except the callee is a static method. - @Test(compLevel = C1) + // CompLevel.C1->CompLevel.C2 - same as test97, except the callee is a static method. + @Test(compLevel = CompLevel.C1) public static int test99(Point p1, Point p2) { return test99_helper(p1, p2); } - @DontInline @DontCompile + @DontInline + @ForceCompile(CompLevel.C1) public static int test99_helper(Point p1, Point p2) { return p1.x + p1.y + p2.x + p2.y; } - @ForceCompile(compLevel = C1) - public void test99_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test99") + public void test99_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC1 invokestatic, packing causes stack growth (1 extra stack word). + // CompLevel.C2->CompLevel.C1 invokestatic, packing causes stack growth (1 extra stack word). // Make sure stack frame is set up properly for GC. - @Test(compLevel = C2) + @Test(compLevel = CompLevel.C2) public float test100(FloatPoint fp1, FloatPoint fp2, RefPoint rp, int a1, int a2, int a3, int a4) { return test100_helper(fp1, fp2, rp, a1, a2, a3, a4); } @DontInline - @ForceCompile(compLevel = C1) + @ForceCompile(CompLevel.C1) private static float test100_helper(FloatPoint fp1, FloatPoint fp2, RefPoint rp, int a1, int a2, int a3, int a4) { // On x64: // Scalarized entry -- all parameters are passed in registers @@ -2084,15 +2073,15 @@ private static float test100_helper(FloatPoint fp1, FloatPoint fp2, RefPoint rp, return fp1.x + fp1.y + fp2.x + fp2.y + rp.x.n + rp.y.n + a1 + a2 + a3 + a4; } - @DontCompile - public void test100_verifier(boolean warmup) { - int count = warmup ? 1 : 4; + @Run(test = "test100") + public void test100_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 4; for (int i=0; iC2 force GC for every allocation when storing the returned + // CompLevel.C1->CompLevel.C2 force GC for every allocation when storing the returned // fields back into a buffered object. - @Test(compLevel = C1) + @Test(compLevel = CompLevel.C1) public RefPoint test101(RefPoint rp) { return test101_helper(rp); } - @ForceCompile(compLevel = C2) @DontInline + @DontInline + @ForceCompile(CompLevel.C2) public RefPoint test101_helper(RefPoint rp) { return rp; } - @DontCompile - public void test101_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test101") + public void test101_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; iC2 instead. - @Test(compLevel = C1) + // Same as test101, except we have Interpreter->CompLevel.C2 instead. + @Test(compLevel = CompLevel.C1) public RefPoint test102(RefPoint rp) { return test102_interp(rp); } - @DontCompile @DontInline + @DontInline public RefPoint test102_interp(RefPoint rp) { return test102_helper(rp); } - @ForceCompile(compLevel = C2) @DontInline + @DontInline + @ForceCompile(CompLevel.C2) public RefPoint test102_helper(RefPoint rp) { return rp; } - @DontCompile - public void test102_verifier(boolean warmup) { - int count = warmup ? 1 : 5; + @Run(test = "test102") + public void test102_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 5; for (int i=0; i()QTest103Value;" } @@ -2176,9 +2167,9 @@ static primitive class Test103Value { static Object test103_v; - @DontCompile - public void test103_verifier(boolean warmup) { - if (warmup) { + @Run(test = "test103") + public void test103_verifier(RunInfo info) { + if (info.isWarmUp()) { // Make sure test103() is compiled before Test103Value is loaded return; } @@ -2189,9 +2180,9 @@ public void test103_verifier(boolean warmup) { // Same as test103, but with an inline class that's too big to return as fields. - @Test(compLevel = C1) + @Test(compLevel = CompLevel.C1) public void test104() { - // when this method is compiled by C1, the Test104Value class is not yet loaded. + // when this method is compiled by CompLevel.C1, the Test104Value class is not yet loaded. test104_v = new Test104Value(); // invokestatic "Test104Value.()QTest104Value;" } @@ -2216,9 +2207,9 @@ static primitive class Test104Value { static Object test104_v; - @DontCompile - public void test104_verifier(boolean warmup) { - if (warmup) { + @Run(test = "test104") + public void test104_verifier(RunInfo info) { + if (info.isWarmUp()) { // Make sure test104() is compiled before Test104Value is loaded return; } @@ -2227,9 +2218,9 @@ public void test104_verifier(boolean warmup) { Asserts.assertEQ(v.x0, rL); } - // C2->C1 invokeinterface -- call Unverified Entry of MyImplVal1.func1 (compiled by C1 - has VVEP_RO) + // CompLevel.C2->CompLevel.C1 invokeinterface -- call Unverified Entry of MyImplVal1.func1 (compiled by CompLevel.C1 - has VVEP_RO) /// (same as test94, except we are calling func1, which shares VVEP and VVEP_RO - @Test(compLevel = C2) + @Test(compLevel = CompLevel.C2) public int test105(Intf intf, int a, int b) { return intf.func1(a, b); } @@ -2239,9 +2230,9 @@ public int test105(Intf intf, int a, int b) { new MyImplVal2(), }; - @DontCompile - public void test105_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test105") + public void test105_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC2 invokeinterface -- call Unverified Entry of MyImplVal2.func1 (compiled by C2 - has VVEP_RO) + // CompLevel.C2->CompLevel.C2 invokeinterface -- call Unverified Entry of MyImplVal2.func1 (compiled by CompLevel.C2 - has VVEP_RO) /// (same as test95, except we are calling func1, which shares VVEP and VVEP_RO - @Test(compLevel = C2) + @Test(compLevel = CompLevel.C2) public int test106(Intf intf, int a, int b) { return intf.func1(a, b); } @@ -2261,9 +2252,9 @@ public int test106(Intf intf, int a, int b) { new MyImplVal1(), }; - @DontCompile - public void test106_verifier(boolean warmup) { - int count = warmup ? 1 : 20; + @Run(test = "test106") + public void test106_verifier(RunInfo info) { + int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC1 invokeinterface -- C2 calls call Unverified Entry of MyImplVal2X.func1 (compiled by - // C1, with VVEP_RO==VVEP) + // CompLevel.C2->CompLevel.C1 invokeinterface -- CompLevel.C2 calls call Unverified Entry of MyImplVal2X.func1 (compiled by + // CompLevel.C1, with VVEP_RO==VVEP) // This test is developed to validate JDK-8230325. - @Test() @Warmup(0) @OSRCompileOnly + @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public int test107(Intf intf, int a, int b) { return intf.func1(a, b); } - @ForceCompile - public void test107_verifier(boolean warmup) { + @Run(test = "test107") + @Warmup(0) + public void test107_verifier(RunInfo info) { Intf intf1 = new MyImplVal1X(); Intf intf2 = new MyImplVal2X(); @@ -2288,28 +2280,29 @@ public void test107_verifier(boolean warmup) { test107(intf1, 123, 456); } for (int i=0; i<500_000; i++) { - // Run enough loops so that test107 will be compiled by C2. + // Run enough loops so that test107 will be compiled by CompLevel.C2. if (i % 30 == 0) { // This will indirectly call MyImplVal2X.func1, but the call frequency is low, so - // test107 will be compiled by C2, but MyImplVal2X.func1 will compiled by C1 only. + // test107 will be compiled by CompLevel.C2, but MyImplVal2X.func1 will compiled by CompLevel.C1 only. int result = test107(intf2, 123, 456) + i; Asserts.assertEQ(result, intf2.func1(123, 456) + i); } else { - // Call test107 with a mix of intf1 and intf2, so C2 will use a virtual call (not an optimized call) + // Call test107 with a mix of intf1 and intf2, so CompLevel.C2 will use a virtual call (not an optimized call) // for the invokeinterface bytecode in test107. test107(intf1, 123, 456); } } } - // Same as test107, except we call MyImplVal2X.func2 (compiled by C1, VVEP_RO != VVEP) - @Test() @Warmup(0) @OSRCompileOnly + // Same as test107, except we call MyImplVal2X.func2 (compiled by CompLevel.C1, VVEP_RO != VVEP) + @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public int test108(Intf intf, int a, int b) { return intf.func2(a, b, pointField); } - @ForceCompile - public void test108_verifier(boolean warmup) { + @Run(test = "test108") + @Warmup(0) + public void test108_verifier(RunInfo info) { Intf intf1 = new MyImplVal1X(); Intf intf2 = new MyImplVal2X(); @@ -2317,28 +2310,29 @@ public void test108_verifier(boolean warmup) { test108(intf1, 123, 456); } for (int i=0; i<500_000; i++) { - // Run enough loops so that test108 will be compiled by C2. + // Run enough loops so that test108 will be compiled by CompLevel.C2. if (i % 30 == 0) { // This will indirectly call MyImplVal2X.func2, but the call frequency is low, so - // test108 will be compiled by C2, but MyImplVal2X.func2 will compiled by C1 only. + // test108 will be compiled by CompLevel.C2, but MyImplVal2X.func2 will compiled by CompLevel.C1 only. int result = test108(intf2, 123, 456) + i; Asserts.assertEQ(result, intf2.func2(123, 456, pointField) + i); } else { - // Call test108 with a mix of intf1 and intf2, so C2 will use a virtual call (not an optimized call) + // Call test108 with a mix of intf1 and intf2, so CompLevel.C2 will use a virtual call (not an optimized call) // for the invokeinterface bytecode in test108. test108(intf1, 123, 456); } } } - // Same as test107, except we call MyImplPojo3.func2 (compiled by C1, VVEP_RO == VEP) - @Test() @Warmup(0) @OSRCompileOnly + // Same as test107, except we call MyImplPojo3.func2 (compiled by CompLevel.C1, VVEP_RO == VEP) + @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public int test109(Intf intf, int a, int b) { return intf.func2(a, b, pointField); } - @ForceCompile - public void test109_verifier(boolean warmup) { + @Run(test = "test109") + @Warmup(0) + public void test109_verifier(RunInfo info) { Intf intf1 = new MyImplPojo0(); Intf intf2 = new MyImplPojo3(); @@ -2346,14 +2340,14 @@ public void test109_verifier(boolean warmup) { test109(intf1, 123, 456); } for (int i=0; i<500_000; i++) { - // Run enough loops so that test109 will be compiled by C2. + // Run enough loops so that test109 will be compiled by CompLevel.C2. if (i % 30 == 0) { // This will indirectly call MyImplPojo3.func2, but the call frequency is low, so - // test109 will be compiled by C2, but MyImplPojo3.func2 will compiled by C1 only. + // test109 will be compiled by CompLevel.C2, but MyImplPojo3.func2 will compiled by CompLevel.C1 only. int result = test109(intf2, 123, 456) + i; Asserts.assertEQ(result, intf2.func2(123, 456, pointField) + i); } else { - // Call test109 with a mix of intf1 and intf2, so C2 will use a virtual call (not an optimized call) + // Call test109 with a mix of intf1 and intf2, so CompLevel.C2 will use a virtual call (not an optimized call) // for the invokeinterface bytecode in test109. test109(intf1, 123, 456); } From 91f7b33eb6ac6c627a348a39d668e5359233dceb Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Thu, 25 Mar 2021 11:56:27 -0700 Subject: [PATCH 075/131] Forgot to commit tests 97-99, 107-109 --- .../inlinetypes/TestCallingConventionC1.java | 59 ++++++++++++++----- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java index 8bf3b5725cd..c849c226376 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java @@ -40,6 +40,7 @@ * @compile InlineTypes.java * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestCallingConventionC1 */ + public class TestCallingConventionC1 { public static void main(String[] args) { final Scenario[] scenarios = { @@ -1979,13 +1980,12 @@ public int test97(Point p1, Point p2) { return test97_helper(p1, p2); } - @DontInline - @ForceCompile(CompLevel.C1) + @DontCompile public int test97_helper(Point p1, Point p2) { return p1.x + p1.y + p2.x + p2.y; } - @Run(test = "test97") + @ForceCompile(CompLevel.C1) public void test97_verifier(RunInfo info) { int count = info.isWarmUp() ? 1 : 20; for (int i=0; iCompLevel.C2 - same as test97, except the callee is compiled by CompLevel.C2. @Test(compLevel = CompLevel.C2) public int test98(Point p1, Point p2) { return test98_helper(p1, p2); } - @DontInline - @ForceCompile(CompLevel.C1) + @DontCompile public int test98_helper(Point p1, Point p2) { return p1.x + p1.y + p2.x + p2.y; } - @Run(test = "test98") + @ForceCompile(CompLevel.C1) public void test98_verifier(RunInfo info) { int count = info.isWarmUp() ? 1 : 20; for (int i=0; iCompLevel.C2 - same as test97, except the callee is a static method. @Test(compLevel = CompLevel.C1) public static int test99(Point p1, Point p2) { return test99_helper(p1, p2); } - @DontInline - @ForceCompile(CompLevel.C1) + @DontCompile public static int test99_helper(Point p1, Point p2) { return p1.x + p1.y + p2.x + p2.y; } - @Run(test = "test99") + @ForceCompile(CompLevel.C1) public void test99_verifier(RunInfo info) { int count = info.isWarmUp() ? 1 : 20; for (int i=0; iCompLevel.C1 invokestatic, packing causes stack growth (1 extra stack word). // Make sure stack frame is set up properly for GC. @@ -2270,8 +2282,7 @@ public int test107(Intf intf, int a, int b) { return intf.func1(a, b); } - @Run(test = "test107") - @Warmup(0) + @ForceCompile public void test107_verifier(RunInfo info) { Intf intf1 = new MyImplVal1X(); Intf intf2 = new MyImplVal2X(); @@ -2294,14 +2305,19 @@ public void test107_verifier(RunInfo info) { } } + @Run(test = "test107") + @Warmup(0) + public void run_test107_verifier(RunInfo info) { + test107_verifier(info); + } + // Same as test107, except we call MyImplVal2X.func2 (compiled by CompLevel.C1, VVEP_RO != VVEP) @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public int test108(Intf intf, int a, int b) { return intf.func2(a, b, pointField); } - @Run(test = "test108") - @Warmup(0) + @ForceCompile public void test108_verifier(RunInfo info) { Intf intf1 = new MyImplVal1X(); Intf intf2 = new MyImplVal2X(); @@ -2324,14 +2340,20 @@ public void test108_verifier(RunInfo info) { } } + @Run(test = "test108") + @Warmup(0) + public void run_test108_verifier(RunInfo info) { + test108_verifier(info); + } + + /* // Same as test107, except we call MyImplPojo3.func2 (compiled by CompLevel.C1, VVEP_RO == VEP) @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public int test109(Intf intf, int a, int b) { return intf.func2(a, b, pointField); } - @Run(test = "test109") - @Warmup(0) + @ForceCompile public void test109_verifier(RunInfo info) { Intf intf1 = new MyImplPojo0(); Intf intf2 = new MyImplPojo3(); @@ -2353,4 +2375,11 @@ public void test109_verifier(RunInfo info) { } } } + + @Run(test = "test109") + @Warmup(0) + public void run_test109_verifier(RunInfo info) { + test109_verifier(info); + } + */ } From ff584019d5a05d3ec95b2ebd414fc533f9d286ee Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Thu, 25 Mar 2021 21:16:32 -0700 Subject: [PATCH 076/131] Converted TestJNICalls.java to new IR framework --- .../valhalla/inlinetypes/TestJNICalls.java | 52 +++++++++---------- .../hotspot/ir_framework/TestFramework.java | 5 +- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java index f7f65558eec..6477254d614 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, 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 @@ -24,6 +24,10 @@ package compiler.valhalla.inlinetypes; import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; import java.lang.reflect.Method; @@ -31,25 +35,21 @@ * @test * @key randomness * @summary Test calling native methods with inline type arguments from compiled code. - * @library /testlibrary /test/lib /compiler/whitebox / + * @library /test/lib * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile TestJNICalls.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestJNICalls + * @compile InlineTypes.java + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestJNICalls */ -public class TestJNICalls extends InlineTypeTest { - // Extra VM parameters for some test scenarios. See InlineTypeTest.getVMParameters() - @Override - public String[] getExtraVMParameters(int scenario) { - return null; - } - public static void main(String[] args) throws Throwable { - TestJNICalls test = new TestJNICalls(); - test.run(args, MyValue1.class); +public class TestJNICalls { + + public static void main(String[] args) { + Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; + + InlineTypes.getFramework() + .addScenarios(scenarios) + .addHelperClasses(MyValue1.class) + .start(); } static { @@ -61,7 +61,6 @@ public static void main(String[] args) throws Throwable { // Pass an inline type to a native method that calls back into Java code and returns an inline type @Test - @Warmup(10000) // Make sure native method is compiled public MyValue1 test1(MyValue1 vt, boolean callback) { if (!callback) { return (MyValue1)testMethod1(vt); @@ -70,8 +69,9 @@ public MyValue1 test1(MyValue1 vt, boolean callback) { } } - @DontCompile - public void test1_verifier(boolean warmup) { + @Run(test = "test1") + @Warmup(10000) // Make sure native method is compiled + public void test1_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); MyValue1 result = test1(vt, false); Asserts.assertEQ(result.hash(), vt.hash()); @@ -81,13 +81,13 @@ public void test1_verifier(boolean warmup) { // Pass an inline type to a native method that calls the hash method and returns the result @Test - @Warmup(10000) // Make sure native method is compiled public long test2(MyValue1 vt) { return testMethod2(vt); } - @DontCompile - public void test2_verifier(boolean warmup) { + @Run(test = "test2") + @Warmup(10000) // Make sure native method is compiled + public void test2_verifier() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); long result = test2(vt); Asserts.assertEQ(result, vt.hash()); @@ -105,13 +105,13 @@ private MyValueWithNative(int x) { // Call a native method with an inline type receiver @Test - @Warmup(10000) // Make sure native method is compiled public int test3(MyValueWithNative vt) { return vt.testMethod3(); } - @DontCompile - public void test3_verifier(boolean warmup) { + @Run(test = "test3") + @Warmup(10000) // Make sure native method is compiled + public void test3_verifier() { MyValueWithNative vt = new MyValueWithNative(rI); int result = test3(vt); Asserts.assertEQ(result, rI); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index c66a0820a87..dabf3f25751 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -541,6 +541,8 @@ private void runFlagVM(List additionalFlags) { private ArrayList prepareFlagVMFlags(List additionalFlags) { ArrayList cmds = new ArrayList<>(); cmds.add("-Dtest.jdk=" + Utils.TEST_JDK); + // Set java.library.path so JNI tests which rely on jtreg nativepath setting work + cmds.add("-Djava.library.path=" + Utils.TEST_NATIVE_PATH); cmds.add("-cp"); cmds.add(Utils.TEST_CLASS_PATH); cmds.add("-Xbootclasspath/a:."); @@ -605,7 +607,8 @@ private void runTestVM(List additionalFlags, Scenario scenario) { private List prepareTestVMFlags(List additionalFlags) { ArrayList cmds = new ArrayList<>(); - + // Set java.library.path so JNI tests which rely on jtreg nativepath setting work + cmds.add("-Djava.library.path=" + Utils.TEST_NATIVE_PATH); // Need White Box access in test VM. cmds.add("-Xbootclasspath/a:."); cmds.add("-XX:+UnlockDiagnosticVMOptions"); From d448689c31354fdb6b5e8f3f084b26b50ead6aad Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Thu, 25 Mar 2021 22:25:24 -0700 Subject: [PATCH 077/131] Converted tests to new IR framework --- .../inlinetypes/TestOnStackReplacement.java | 99 +++++++------ .../valhalla/inlinetypes/TestWithfieldC1.java | 137 ++++++++---------- 2 files changed, 118 insertions(+), 118 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java index 10cf2d53abc..88b8a20f065 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -24,34 +24,38 @@ package compiler.valhalla.inlinetypes; import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; + import java.lang.reflect.Method; /* * @test * @key randomness * @summary Test on stack replacement (OSR) with inline types - * @library /testlibrary /test/lib /compiler/whitebox / + * @library /test/lib * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile TestOnStackReplacement.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestOnStackReplacement + * @compile InlineTypes.java + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestOnStackReplacement */ -public class TestOnStackReplacement extends InlineTypeTest { - // Extra VM parameters for some test scenarios. See InlineTypeTest.getVMParameters() - @Override - public String[] getExtraVMParameters(int scenario) { - switch (scenario) { - case 3: return new String[] {"-XX:FlatArrayElementMaxSize=0"}; - } - return null; - } + +public class TestOnStackReplacement { public static void main(String[] args) throws Throwable { - TestOnStackReplacement test = new TestOnStackReplacement(); - test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, MyValue3.class, MyValue3Inline.class); + Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; + scenarios[3].addFlags("-XX:FlatArrayElementMaxSize=0"); + + InlineTypes.getFramework() + .addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class, + MyValue3.class, + MyValue3Inline.class) + .start(); } // Helper methods @@ -65,7 +69,7 @@ protected long hash(int x, long y) { } // Test OSR compilation - @Test() @Warmup(0) @OSRCompileOnly + @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public long test1() { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue1[] va = new MyValue1[Math.abs(rI) % 3]; @@ -84,14 +88,16 @@ public long test1() { return result; } - @DontCompile - public void test1_verifier(boolean warmup) { + @Run(test = "test1") + @Warmup(0) + public void test1_verifier() { long result = test1(); Asserts.assertEQ(result, ((Math.abs(rI) % 3) + 1) * hash()); } // Test loop peeling - @Test(failOn = ALLOC + LOAD + STORE) @Warmup(0) @OSRCompileOnly + @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) + @IR(failOn = {ALLOC, LOAD, STORE}) public void test2() { MyValue1 v = MyValue1.createWithFieldsInline(0, 1); // Trigger OSR compilation and loop peeling @@ -104,13 +110,14 @@ public void test2() { } } - @DontCompile - public void test2_verifier(boolean warmup) { + @Run(test = "test2") + @Warmup(0) + public void test2_verifier() { test2(); } // Test loop peeling and unrolling - @Test() @Warmup(0) @OSRCompileOnly + @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public void test3() { MyValue1 v1 = MyValue1.createWithFieldsInline(0, 0); MyValue1 v2 = MyValue1.createWithFieldsInline(1, 1); @@ -125,8 +132,9 @@ public void test3() { } } - @DontCompile - public void test3_verifier(boolean warmup) { + @Run(test = "test3") + @Warmup(0) + public void test3_verifier() { test3(); } @@ -141,7 +149,7 @@ public Object test4_body() { return MyValue1.createWithFieldsInline(rI, rL); } - @Test() @Warmup(0) @OSRCompileOnly + @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public Object test4() { Object vt = test4_init(); for (int i = 0; i < 50_000; i++) { @@ -152,8 +160,9 @@ public Object test4() { return vt; } - @DontCompile - public void test4_verifier(boolean warmup) { + @Run(test = "test4") + @Warmup(0) + public void test4_verifier() { test4(); } @@ -161,7 +170,7 @@ public void test4_verifier(boolean warmup) { MyValue1.ref nullField; - @Test() @Warmup(0) @OSRCompileOnly + @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public void test5() { MyValue1.ref vt = nullField; for (int i = 0; i < 50_000; i++) { @@ -171,8 +180,9 @@ public void test5() { } } - @DontCompile - public void test5_verifier(boolean warmup) { + @Run(test = "test5") + @Warmup(0) + public void test5_verifier() { test5(); } @@ -189,7 +199,7 @@ public int test() { } } - @Test() @Warmup(0) @OSRCompileOnly + @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public void test6() { Test6Value tmp = new Test6Value(); for (int i = 0; i < 100; ++i) { @@ -197,8 +207,9 @@ public void test6() { } } - @DontCompile - public void test6_verifier(boolean warmup) { + @Run(test = "test6") + @Warmup(0) + public void test6_verifier() { test6(); } @@ -246,7 +257,7 @@ public int test(String[] args) { } } - @Test() @Warmup(0) @OSRCompileOnly + @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public void test7() { Test7Value2 tmp = new Test7Value2(); for (int i = 0; i < 10; ++i) { @@ -254,8 +265,9 @@ public void test7() { } } - @DontCompile - public void test7_verifier(boolean warmup) { + @Run(test = "test7") + @Warmup(0) + public void test7_verifier() { test7(); } @@ -273,7 +285,7 @@ public MyValue3 test8_callee(int len) { return test8_vt; } - @Test() @Warmup(2) + @Test() public int test8(int start) { MyValue3 vt = test8_callee(start); test8_vt.verify(vt); @@ -284,8 +296,9 @@ public int test8(int start) { return result; } - @DontCompile - public void test8_verifier(boolean warmup) { + @Run(test = "test8") + @Warmup(2) + public void test8_verifier() { test8(1); test8(50_000); } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java index e8f0a5b4506..a6a9b4a256f 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, 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 @@ -29,62 +29,48 @@ import java.util.Arrays; import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; + /* * @test * @key randomness * @summary Verify that C1 performs escape analysis before optimizing withfield bytecode to putfield. - * @library /testlibrary /test/lib /compiler/whitebox / + * @library /test/lib * @requires os.simpleArch == "x64" + * @compile InlineTypes.java * @compile -XDallowWithFieldOperator TestWithfieldC1.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestWithfieldC1 + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestWithfieldC1 */ -public class TestWithfieldC1 extends InlineTypeTest { - public static final int C1 = COMP_LEVEL_SIMPLE; - public static final int C2 = COMP_LEVEL_FULL_OPTIMIZATION; - - public static void main(String[] args) throws Throwable { - TestWithfieldC1 test = new TestWithfieldC1(); - test.run(args, FooValue.class); - } - @Override - public int getNumScenarios() { - return 5; - } - - @Override - public String[] getVMParameters(int scenario) { - switch (scenario) { - case 0: return new String[] { // C1 only - "-XX:TieredStopAtLevel=1", - "-XX:+TieredCompilation", - }; - case 1: return new String[] { // C2 only. (Make sure the tests are correctly written) - "-XX:TieredStopAtLevel=4", - "-XX:-TieredCompilation", - }; - case 2: return new String[] { // interpreter only - "-Xint", - }; - case 3: return new String[] { - // Xcomp Only C1. - "-XX:TieredStopAtLevel=1", - "-XX:+TieredCompilation", - "-Xcomp", - }; - case 4: return new String[] { - // Xcomp Only C2. - "-XX:TieredStopAtLevel=4", - "-XX:-TieredCompilation", - "-Xcomp", - }; - } - return null; +public class TestWithfieldC1 { + + public static void main(String[] args) { + final Scenario[] scenarios = { + new Scenario(0, // C1 only + "-XX:TieredStopAtLevel=1", + "-XX:+TieredCompilation"), + new Scenario(1, // C2 only. (Make sure the tests are correctly written) + "-XX:TieredStopAtLevel=4", + "-XX:-TieredCompilation"), + new Scenario(2, // interpreter only + "-Xint"), + new Scenario(3, // Xcomp Only C1. + "-XX:TieredStopAtLevel=1", + "-XX:+TieredCompilation", + "-Xcomp"), + new Scenario(4, // Xcomp Only C2. + "-XX:TieredStopAtLevel=4", + "-XX:-TieredCompilation", + "-Xcomp") + }; + + InlineTypes.getFramework() + .addScenarios(scenarios) + .start(); } static FooValue.ref foo_static; @@ -98,6 +84,7 @@ static void set_foo_static_if_null(FooValue v) { } } + @ForceCompileClassInitializer static primitive class FooValue { public int x = 0, y = 0; @@ -214,19 +201,19 @@ static void validate_foo_static_and(FooValue v) { } // escape with putstatic - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public FooValue test1() { return FooValue.test1(); } - @DontCompile - public void test1_verifier(boolean warmup) { + @Run(test = "test1") + public void test1_verifier() { FooValue v = test1(); validate_foo_static_and(v); } // escape with putfield - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public FooValue test2() { FooValue v = FooValue.default; @@ -239,8 +226,8 @@ public FooValue test2() { return v; } - @DontCompile - public void test2_verifier(boolean warmup) { + @Run(test = "test2") + public void test2_verifier() { foo_instance = null; FooValue v = test2(); Asserts.assertEQ(foo_instance.x, 1); @@ -250,52 +237,52 @@ public void test2_verifier(boolean warmup) { } // escape with function call - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public FooValue test3() { return FooValue.test3(); } - @DontCompile - public void test3_verifier(boolean warmup) { + @Run(test = "test3") + public void test3_verifier() { foo_static = null; FooValue v = test3(); validate_foo_static_and(v); } // escape and then branch backwards - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public FooValue test4() { return FooValue.test4(); } - @DontCompile - public void test4_verifier(boolean warmup) { + @Run(test = "test4") + public void test4_verifier() { foo_static = null; FooValue v = test4(); validate_foo_static_and(v); } // escape using a different local variable - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public FooValue test5() { return FooValue.test5(); } - @DontCompile - public void test5_verifier(boolean warmup) { + @Run(test = "test5") + public void test5_verifier() { foo_static = null; FooValue v = test5(); validate_foo_static_and(v); } // escape using aastore - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public FooValue test6() { return FooValue.test6(); } - @DontCompile - public void test6_verifier(boolean warmup) { + @Run(test = "test6") + public void test6_verifier() { foo_static_arr[0] = null; FooValue v = test6(); Asserts.assertEQ(foo_static_arr[0].x, 1); @@ -305,33 +292,33 @@ public void test6_verifier(boolean warmup) { } // Copying a value into different local slots -- disable withfield optimization - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public FooValue test7() { return FooValue.test7(); } - @DontCompile - public void test7_verifier(boolean warmup) { + @Run(test = "test7") + public void test7_verifier() { FooValue v = test7(); Asserts.assertEQ(v.x, 1); Asserts.assertEQ(v.y, 1); } // escape by invoking non-static method - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public FooValue test8() { return FooValue.test8(); } - @DontCompile - public void test8_verifier(boolean warmup) { + @Run(test = "test8") + public void test8_verifier() { foo_static = null; FooValue v = test8(); validate_foo_static_and(v); } // duplicate reference with local variables - @Test(compLevel=C1) + @Test(compLevel = CompLevel.C1) public FooValue test9() { FooValue v = FooValue.default; @@ -350,8 +337,8 @@ public FooValue test9() { return v; } - @DontCompile - public void test9_verifier(boolean warmup) { + @Run(test = "test9") + public void test9_verifier() { foo_instance = null; FooValue v = test9(); Asserts.assertEQ(foo_instance.x, 3); From 5c9de77149e80279e950299d321f823bfe7f3dfe Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 26 Mar 2021 11:54:17 +0100 Subject: [PATCH 078/131] Clean up some things in converted tests --- .../inlinetypes/TestBasicFunctionality.java | 7 +- .../inlinetypes/TestCallingConventionC1.java | 255 +++++++++--------- .../inlinetypes/TestOnStackReplacement.java | 2 +- 3 files changed, 130 insertions(+), 134 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java index 110daee7dc8..d9c5b3f1f48 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java @@ -29,19 +29,16 @@ * @requires os.simpleArch == "x64" * @library /test/lib * @compile InlineTypes.java - * @run driver compiler.valhalla.inlinetypes.TestBasicFunctionality + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestBasicFunctionality */ package compiler.valhalla.inlinetypes; import jdk.test.lib.Asserts; import jdk.test.lib.hotspot.ir_framework.*; -import java.lang.reflect.Method; -import static compiler.valhalla.inlinetypes.InlineTypes.rI; -import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; +import static compiler.valhalla.inlinetypes.InlineTypes.*; public class TestBasicFunctionality { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java index c849c226376..8a471e142f4 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java @@ -25,16 +25,15 @@ import jdk.test.lib.Asserts; import jdk.test.lib.hotspot.ir_framework.*; +import sun.hotspot.WhiteBox; + import static compiler.valhalla.inlinetypes.InlineTypes.rI; import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; - -import sun.hotspot.WhiteBox; /* * @test * @key randomness - * @summary Test calls from {CompLevel.C1} to {CompLevel.C2, Interpreter}, and vice versa. + * @summary Test calls from {C1} to {C2, Interpreter}, and vice versa. * @library /test/lib * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") * @compile InlineTypes.java @@ -44,12 +43,12 @@ public class TestCallingConventionC1 { public static void main(String[] args) { final Scenario[] scenarios = { - // Default: both CompLevel.C1 and CompLevel.C2 are enabled, tiered compilation enabled + // Default: both C1 and C2 are enabled, tiered compilation enabled new Scenario(0, "-XX:CICompilerCount=2", "-XX:TieredStopAtLevel=4", "-XX:+TieredCompilation"), - // Default: both CompLevel.C1 and CompLevel.C2 are enabled, tiered compilation enabled + // Default: both C1 and C2 are enabled, tiered compilation enabled new Scenario(1, "-XX:CICompilerCount=2", "-XX:TieredStopAtLevel=4", @@ -61,18 +60,18 @@ public static void main(String[] args) { "-XX:CICompilerCount=2", "-XX:TieredStopAtLevel=4", "-XX:+TieredCompilation", - "-DFlipCompLevel.C1CompLevel.C2=true"), - // Only CompLevel.C1. Tiered compilation disabled. + "-DFlipC1C2=true"), + // Only C1. Tiered compilation disabled. new Scenario(3, "-XX:TieredStopAtLevel=1", "-XX:+TieredCompilation"), - // Only CompLevel.C2. + // Only C2. new Scenario(4, "-XX:TieredStopAtLevel=4", "-XX:-TieredCompilation") }; - System.gc(); // Resolve this call, to avoid CompLevel.C1 code patching in the test cases. + System.gc(); // Resolve this call, to avoid C1 code patching in the test cases. TestFramework testFramework = new TestFramework(TestCallingConventionC1.class); testFramework.addScenarios(scenarios) @@ -264,10 +263,10 @@ static primitive class MyImplVal2X implements Intf { static Intf intfs[] = { new MyImplPojo0(), // methods not compiled - new MyImplPojo1(), // methods compiled by CompLevel.C1 - new MyImplPojo2(), // methods compiled by CompLevel.C2 - new MyImplVal1(), // methods compiled by CompLevel.C1 - new MyImplVal2() // methods compiled by CompLevel.C2 + new MyImplPojo1(), // methods compiled by C1 + new MyImplPojo2(), // methods compiled by C2 + new MyImplVal1(), // methods compiled by C1 + new MyImplVal2() // methods compiled by C2 }; static Intf getIntf(int i) { int n = i % intfs.length; @@ -449,10 +448,10 @@ static primitive class TooBigToReturnAsFields { static TooBigToReturnAsFields tooBig = new TooBigToReturnAsFields(); //********************************************************************** - // PART 1 - CompLevel.C1 calls interpreted code + // PART 1 - C1 calls interpreted code //********************************************************************** - //** CompLevel.C1 passes inline type to interpreter (static) + //** C1 passes inline type to interpreter (static) @Test(compLevel = CompLevel.C1) public int test1() { return test1_helper(pointField); @@ -472,7 +471,7 @@ public void test1_verifier(RunInfo info) { } } - //** CompLevel.C1 passes inline type to interpreter (monomorphic) + //** C1 passes inline type to interpreter (monomorphic) @Test(compLevel = CompLevel.C1) public int test2() { return test2_helper(pointField); @@ -492,7 +491,7 @@ public void test2_verifier(RunInfo info) { } } - // CompLevel.C1 passes inline type to interpreter (megamorphic: vtable) + // C1 passes inline type to interpreter (megamorphic: vtable) @Test(compLevel = CompLevel.C1) public int test3(Functor functor) { return functor.apply_interp(pointField); @@ -508,7 +507,7 @@ public void test3_verifier(RunInfo info) { } } - // Same as test3, but compiled with CompLevel.C2. Test the hastable of VtableStubs + // Same as test3, but compiled with C2. Test the hastable of VtableStubs @Test(compLevel = CompLevel.C2) public int test3b(Functor functor) { return functor.apply_interp(pointField); @@ -525,7 +524,7 @@ public void test3b_verifier(RunInfo info) { } - // CompLevel.C1 passes inline type to interpreter (megamorphic: itable) + // C1 passes inline type to interpreter (megamorphic: itable) @Test(compLevel = CompLevel.C1) public int test4(FunctorInterface fi) { return fi.apply_interp(pointField); @@ -542,23 +541,23 @@ public void test4_verifier(RunInfo info) { } //********************************************************************** - // PART 2 - interpreter calls CompLevel.C1 + // PART 2 - interpreter calls C1 //********************************************************************** - // Interpreter passes inline type to CompLevel.C1 (static) + // Interpreter passes inline type to C1 (static) @Test(compLevel = CompLevel.C1) static public int test20(Point p1, long l, Point p2) { return p1.x + p2.y; } @Run(test = "test20") - public void test20_verifier(RunInfo info) { + public void test20_verifier() { int result = test20(pointField1, 0, pointField2); int n = pointField1.x + pointField2.y; Asserts.assertEQ(result, n); } - // Interpreter passes inline type to CompLevel.C1 (instance method in inline class) + // Interpreter passes inline type to C1 (instance method in inline class) @Test public int test21(Point p) { return test21_helper(p); @@ -570,7 +569,7 @@ int test21_helper(Point p) { } @Run(test = "test21") - public void test21_verifier(RunInfo info) { + public void test21_verifier() { int result = test21(pointField); int n = 2 * (pointField.x + pointField.y); Asserts.assertEQ(result, n); @@ -578,10 +577,10 @@ public void test21_verifier(RunInfo info) { //********************************************************************** - // PART 3 - CompLevel.C2 calls CompLevel.C1 + // PART 3 - C2 calls C1 //********************************************************************** - // CompLevel.C2->CompLevel.C1 invokestatic, single inline arg + // C2->C1 invokestatic, single inline arg @Test(compLevel = CompLevel.C2) public int test30() { return test30_helper(pointField); @@ -603,7 +602,7 @@ public void test30_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, two single inline args + // C2->C1 invokestatic, two single inline args @Test(compLevel = CompLevel.C2) public int test31() { return test31_helper(pointField1, pointField2); @@ -625,7 +624,7 @@ public void test31_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, two single inline args and interleaving ints (all passed in registers on x64) + // C2->C1 invokestatic, two single inline args and interleaving ints (all passed in registers on x64) @Test(compLevel = CompLevel.C2) public int test32() { return test32_helper(0, pointField1, 1, pointField2); @@ -647,7 +646,7 @@ public void test32_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokeinterface -- no verified_ro_entry (no inline args except for receiver) + // C2->C1 invokeinterface -- no verified_ro_entry (no inline args except for receiver) @Test(compLevel = CompLevel.C2) public int test33(Intf intf, int a, int b) { return intf.func1(a, b); @@ -663,7 +662,7 @@ public void test33_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokeinterface -- use verified_ro_entry (has inline args other than receiver) + // C2->C1 invokeinterface -- use verified_ro_entry (has inline args other than receiver) @Test(compLevel = CompLevel.C2) public int test34(Intf intf, int a, int b) { return intf.func2(a, b, pointField); @@ -679,7 +678,7 @@ public void test34_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, Point.y is on stack (x64) + // C2->C1 invokestatic, Point.y is on stack (x64) @Test(compLevel = CompLevel.C2) public int test35() { return test35_helper(1, 2, 3, 4, 5, pointField); @@ -701,7 +700,7 @@ public void test35_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, shuffling arguments that are passed on stack + // C2->C1 invokestatic, shuffling arguments that are passed on stack @Test(compLevel = CompLevel.C2) public int test36() { return test36_helper(pointField, 1, 2, 3, 4, 5, 6, 7, 8); @@ -723,7 +722,7 @@ public void test36_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, shuffling long arguments + // C2->C1 invokestatic, shuffling long arguments @Test(compLevel = CompLevel.C2) public int test37() { return test37_helper(pointField, 1, 2, 3, 4, 5, 6, 7, 8); @@ -745,7 +744,7 @@ public void test37_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, shuffling boolean, byte, char, short, int, long arguments + // C2->C1 invokestatic, shuffling boolean, byte, char, short, int, long arguments @Test(compLevel = CompLevel.C2) public int test38() { return test38_helper(pointField, true, (byte)1, (char)2, (short)3, 4, 5, (byte)6, (short)7, 8); @@ -771,7 +770,7 @@ public void test38_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, packing an inline type with all types of fixed point primitive fields. + // C2->C1 invokestatic, packing an inline type with all types of fixed point primitive fields. @Test(compLevel = CompLevel.C2) public long test39() { return test39_helper(1, fixedPointsField, 2, fixedPointsField); @@ -797,7 +796,7 @@ public void test39_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, shuffling floating point args + // C2->C1 invokestatic, shuffling floating point args @Test(compLevel = CompLevel.C2) public double test40() { return test40_helper(1.1f, 1.2, floatPointField, doublePointField, 1.3f, 1.4, 1.5f, 1.7, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12); @@ -819,7 +818,7 @@ public void test40_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, mixing floats and ints + // C2->C1 invokestatic, mixing floats and ints @Test(compLevel = CompLevel.C2) public double test41() { return test41_helper(1, 1.2, pointField, floatPointField, doublePointField, 1.3f, 4, 1.5f, 1.7, 1.7, 1.8, 9, 1.10, 1.11, 1.12); @@ -841,7 +840,7 @@ public void test41_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, circular dependency (between rdi and first stack slot on x64) + // C2->C1 invokestatic, circular dependency (between rdi and first stack slot on x64) @Test(compLevel = CompLevel.C2) public float test42() { return test42_helper(eightFloatsField, pointField, 3, 4, 5, floatPointField, 7); @@ -871,7 +870,7 @@ public void test42_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, packing causes stack growth (1 extra stack word) + // C2->C1 invokestatic, packing causes stack growth (1 extra stack word) @Test(compLevel = CompLevel.C2) public float test43() { return test43_helper(floatPointField, 1, 2, 3, 4, 5, 6); @@ -896,7 +895,7 @@ public void test43_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, packing causes stack growth (2 extra stack words) + // C2->C1 invokestatic, packing causes stack growth (2 extra stack words) @Test(compLevel = CompLevel.C2) public float test44() { return test44_helper(floatPointField, floatPointField, 1, 2, 3, 4, 5, 6); @@ -924,7 +923,7 @@ public void test44_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, packing causes stack growth (5 extra stack words) + // C2->C1 invokestatic, packing causes stack growth (5 extra stack words) @Test(compLevel = CompLevel.C2) public float test45() { return test45_helper(floatPointField, floatPointField, floatPointField, floatPointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); @@ -951,7 +950,7 @@ public void test45_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, packing causes stack growth (1 extra stack word -- mixing Point and FloatPoint) + // C2->C1 invokestatic, packing causes stack growth (1 extra stack word -- mixing Point and FloatPoint) @Test(compLevel = CompLevel.C2) public float test46() { return test46_helper(floatPointField, floatPointField, pointField, floatPointField, floatPointField, pointField, floatPointField, 1, 2, 3, 4, 5, 6, 7); @@ -1000,7 +999,7 @@ static void checkStackTrace(Throwable t, String... methodNames) { } //* - // CompLevel.C2->CompLevel.C1 invokestatic, make sure stack walking works (with static variable) + // C2->C1 invokestatic, make sure stack walking works (with static variable) @Test(compLevel = CompLevel.C2) public void test47(int n) { try { @@ -1038,7 +1037,7 @@ public void test47_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, make sure stack walking works (with returned inline type) + // C2->C1 invokestatic, make sure stack walking works (with returned inline type) @Test(compLevel = CompLevel.C2) public int test48(int n) { try { @@ -1073,9 +1072,9 @@ public void test48_verifier(RunInfo info) { } } - // CompLevel.C2->interpreter invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair) + // C2->interpreter invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair) // (this is the baseline for test50 -- - // the only difference is: test49_helper is interpreted but test50_helper is compiled by CompLevel.C1). + // the only difference is: test49_helper is interpreted but test50_helper is compiled by C1). @Test(compLevel = CompLevel.C2) public int test49(int n) { try { @@ -1109,7 +1108,7 @@ public void test49_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair) + // C2->C1 invokestatic, make sure stack walking works (same as test 48, but with stack extension/repair) @Test(compLevel = CompLevel.C2) public int test50(int n) { try { @@ -1145,7 +1144,7 @@ public void test50_verifier(RunInfo info) { } - // CompLevel.C2->CompLevel.C1 invokestatic, inline class with ref fields (RefPoint) + // C2->C1 invokestatic, inline class with ref fields (RefPoint) @Test(compLevel = CompLevel.C2) public int test51() { return test51_helper(refPointField1); @@ -1167,7 +1166,7 @@ public void test51_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, inline class with ref fields (Point, RefPoint) + // C2->C1 invokestatic, inline class with ref fields (Point, RefPoint) @Test(compLevel = CompLevel.C2) public int test52() { return test52_helper(pointField, refPointField1); @@ -1189,7 +1188,7 @@ public void test52_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, inline class with ref fields (RefPoint, RefPoint, RefPoint, RefPoint) + // C2->C1 invokestatic, inline class with ref fields (RefPoint, RefPoint, RefPoint, RefPoint) @Test(compLevel = CompLevel.C2) public int test53() { return test53_helper(refPointField1, refPointField2, refPointField1, refPointField2); @@ -1214,7 +1213,7 @@ public void test53_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, inline class with ref fields (RefPoint, RefPoint, float, int, RefPoint, RefPoint) + // C2->C1 invokestatic, inline class with ref fields (RefPoint, RefPoint, float, int, RefPoint, RefPoint) @Test(compLevel = CompLevel.C2) public int test54() { return test54_helper(refPointField1, refPointField2, 1.0f, 2, refPointField1, refPointField2); @@ -1263,7 +1262,7 @@ static ForceGCMarker mark(boolean warmup) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, force GC for every allocation when entering a CompLevel.C1 VEP (Point) + // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (Point) @Test(compLevel = CompLevel.C2) public int test55(Point p1) { return test55_helper(p1); @@ -1289,7 +1288,7 @@ public void test55_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, force GC for every allocation when entering a CompLevel.C1 VEP (RefPoint) + // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (RefPoint) @Test(compLevel = CompLevel.C2) public int test56(RefPoint rp1) { return test56_helper(rp1); @@ -1315,7 +1314,7 @@ public void test56_verifier(RunInfo info) { } } - // CompLevel.C2->Interpreter (same as test56, but test CompLevel.C2i entry instead of CompLevel.C1) + // C2->Interpreter (same as test56, but test C2i entry instead of C1) @Test(compLevel = CompLevel.C2) public int test57(RefPoint rp1) { return test57_helper(rp1); @@ -1340,7 +1339,7 @@ public void test57_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, force GC for every allocation when entering a CompLevel.C1 VEP (a bunch of RefPoints and Numbers); + // C2->C1 invokestatic, force GC for every allocation when entering a C1 VEP (a bunch of RefPoints and Numbers); @Test(compLevel = CompLevel.C2) public int test58(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return test58_helper(rp1, rp2, n1, rp3, rp4, n2); @@ -1376,7 +1375,7 @@ public void test58_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, GC inside main body of CompLevel.C1-compiled method (caller's args should not be GC'ed). + // C2->C1 invokestatic, GC inside main body of C1-compiled method (caller's args should not be GC'ed). @Test(compLevel = CompLevel.C2) public int test59(RefPoint rp1, boolean doGC) { return test59_helper(rp1, 11, 222, 3333, 4444, doGC); @@ -1403,7 +1402,7 @@ public void test59_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic, GC inside main body of CompLevel.C1-compiled method (caller's args should not be GC'ed). + // C2->C1 invokestatic, GC inside main body of C1-compiled method (caller's args should not be GC'ed). // same as test59, but the incoming (scalarized) oops are passed in both registers and stack. @Test(compLevel = CompLevel.C2) public int test60(RefPoint rp1, RefPoint rp2, boolean doGC) { @@ -1413,8 +1412,8 @@ public int test60(RefPoint rp1, RefPoint rp2, boolean doGC) { @DontInline @ForceCompile(CompLevel.C1) private static int test60_helper(int x0, int x1, int x2, RefPoint rp1, RefPoint rp2,int a1, int a2, int a3, int a4, boolean doGC) { - // On x64, CompLevel.C2 passes: reg0=x1, reg1=x1, reg2=x2, reg3=rp1.x, reg4=rp1.y, reg5=rp2.x stack0=rp2.y .... - // CompLevel.C1 expects: reg0=x1, reg1=x1, reg2=x2, reg3=rp1, reg4=rp2, reg5=a1 stack0=a2 ... + // On x64, C2 passes: reg0=x1, reg1=x1, reg2=x2, reg3=rp1.x, reg4=rp1.y, reg5=rp2.x stack0=rp2.y .... + // C1 expects: reg0=x1, reg1=x1, reg2=x2, reg3=rp1, reg4=rp2, reg5=a1 stack0=a2 ... // When GC happens, make sure it does not treat reg5 and stack0 as oops! if (doGC) { System.gc(); @@ -1435,7 +1434,7 @@ public void test60_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokeinterface via VVEP(RO) + // C2->C1 invokeinterface via VVEP(RO) @Test(compLevel = CompLevel.C2) public int test61(RefPoint_Access rpa, RefPoint rp2) { return rpa.func1(rp2); @@ -1453,7 +1452,7 @@ public void test61_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a CompLevel.C1 VVEP(RO) (RefPoint) + // C2->C1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a C1 VVEP(RO) (RefPoint) @Test(compLevel = CompLevel.C2) public int test62(RefPoint_Access rpa, RefPoint rp2) { return rpa.func1(rp2); @@ -1474,7 +1473,7 @@ public void test62_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a CompLevel.C1 VVEP(RO) (a bunch of RefPoints and Numbers) + // C2->C1 invokeinterface via VVEP(RO) -- force GC for every allocation when entering a C1 VVEP(RO) (a bunch of RefPoints and Numbers) @Test(compLevel = CompLevel.C2) public int test63(RefPoint_Access rpa, RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return rpa.func2(rp1, rp2, n1, rp3, rp4, n2); @@ -1500,7 +1499,7 @@ public void test63_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokestatic (same as test63, but use invokestatic instead) + // C2->C1 invokestatic (same as test63, but use invokestatic instead) @Test(compLevel = CompLevel.C2) public int test64(RefPoint_Access rpa, RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return test64_helper(rpa, rp1, rp2, n1, rp3, rp4, n2); @@ -1532,7 +1531,7 @@ public void test64_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokevirtual via VVEP(RO) (opt_virtual_call) + // C2->C1 invokevirtual via VVEP(RO) (opt_virtual_call) @Test(compLevel = CompLevel.C2) public int test76(RefPoint rp1, RefPoint rp2) { return rp1.final_func(rp2); @@ -1550,7 +1549,7 @@ public void test76_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokevirtual, force GC for every allocation when entering a CompLevel.C1 VEP (RefPoint) + // C2->C1 invokevirtual, force GC for every allocation when entering a C1 VEP (RefPoint) // Same as test56, except we call the VVEP(RO) instead of VEP. @Test(compLevel = CompLevel.C2) public int test77(RefPoint rp1, RefPoint rp2) { @@ -1573,9 +1572,9 @@ public void test77_verifier(RunInfo info) { } //------------------------------------------------------------------------------- - // Tests for how CompLevel.C1 handles InlineTypeReturnedAsFields in both calls and returns + // Tests for how C1 handles InlineTypeReturnedAsFields in both calls and returns //------------------------------------------------------------------------------- - // CompLevel.C2->CompLevel.C1 invokestatic with InlineTypeReturnedAsFields (Point) + // C2->C1 invokestatic with InlineTypeReturnedAsFields (Point) @Test(compLevel = CompLevel.C2) public int test78(Point p) { Point np = test78_helper(p); @@ -1589,13 +1588,13 @@ private static Point test78_helper(Point p) { } @Run(test = "test78") - public void test78_verifier(RunInfo info) { + public void test78_verifier() { int result = test78(pointField1); int n = pointField1.x + pointField1.y; Asserts.assertEQ(result, n); } - // CompLevel.C2->CompLevel.C1 invokestatic with InlineTypeReturnedAsFields (RefPoint) + // C2->C1 invokestatic with InlineTypeReturnedAsFields (RefPoint) @Test(compLevel = CompLevel.C2) public int test79(RefPoint p) { RefPoint np = test79_helper(p); @@ -1609,13 +1608,13 @@ private static RefPoint test79_helper(RefPoint p) { } @Run(test = "test79") - public void test79_verifier(RunInfo info) { + public void test79_verifier() { int result = test79(refPointField1); int n = refPointField1.x.n + refPointField1.y.n; Asserts.assertEQ(result, n); } - // CompLevel.C1->CompLevel.C2 invokestatic with InlineTypeReturnedAsFields (RefPoint) + // C1->C2 invokestatic with InlineTypeReturnedAsFields (RefPoint) @Test(compLevel = CompLevel.C1) public int test80(RefPoint p) { RefPoint np = test80_helper(p); @@ -1629,20 +1628,20 @@ private static RefPoint test80_helper(RefPoint p) { } @Run(test = "test80") - public void test80_verifier(RunInfo info) { + public void test80_verifier() { int result = test80(refPointField1); int n = refPointField1.x.n + refPointField1.y.n; Asserts.assertEQ(result, n); } - // Interpreter->CompLevel.C1 invokestatic with InlineTypeReturnedAsFields (Point) + // Interpreter->C1 invokestatic with InlineTypeReturnedAsFields (Point) @Test(compLevel = CompLevel.C1) public Point test81(Point p) { return p; } @Run(test = "test81") - public void test81_verifier(RunInfo info) { + public void test81_verifier() { Point p = test81(pointField1); Asserts.assertEQ(p.x, pointField1.x); Asserts.assertEQ(p.y, pointField1.y); @@ -1651,7 +1650,7 @@ public void test81_verifier(RunInfo info) { Asserts.assertEQ(p.y, pointField2.y); } - // CompLevel.C1->Interpreter invokestatic with InlineTypeReturnedAsFields (RefPoint) + // C1->Interpreter invokestatic with InlineTypeReturnedAsFields (RefPoint) @Test(compLevel = CompLevel.C1) public int test82(RefPoint p) { RefPoint np = test82_helper(p); @@ -1664,7 +1663,7 @@ private static RefPoint test82_helper(RefPoint p) { } @Run(test = "test82") - public void test82_verifier(RunInfo info) { + public void test82_verifier() { int result = test82(refPointField1); int n = refPointField1.x.n + refPointField1.y.n; Asserts.assertEQ(result, n); @@ -1674,7 +1673,7 @@ public void test82_verifier(RunInfo info) { // Tests for InlineTypeReturnedAsFields vs the inline class TooBigToReturnAsFields //------------------------------------------------------------------------------- - // CompLevel.C2->CompLevel.C1 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) + // C2->C1 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) @Test(compLevel = CompLevel.C2) public int test83(TooBigToReturnAsFields p) { TooBigToReturnAsFields np = test83_helper(p); @@ -1688,13 +1687,13 @@ private static TooBigToReturnAsFields test83_helper(TooBigToReturnAsFields p) { } @Run(test = "test83") - public void test83_verifier(RunInfo info) { + public void test83_verifier() { int result = test83(tooBig); int n = tooBig.a0 + tooBig.a5; Asserts.assertEQ(result, n); } - // CompLevel.C1->CompLevel.C2 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) + // C1->C2 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) @Test(compLevel = CompLevel.C1) public int test84(TooBigToReturnAsFields p) { TooBigToReturnAsFields np = test84_helper(p); @@ -1708,26 +1707,26 @@ private static TooBigToReturnAsFields test84_helper(TooBigToReturnAsFields p) { } @Run(test = "test84") - public void test84_verifier(RunInfo info) { + public void test84_verifier() { int result = test84(tooBig); int n = tooBig.a0 + tooBig.a5; Asserts.assertEQ(result, n); } - // Interpreter->CompLevel.C1 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) + // Interpreter->C1 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) @Test(compLevel = CompLevel.C1) public TooBigToReturnAsFields test85(TooBigToReturnAsFields p) { return p; } @Run(test = "test85") - public void test85_verifier(RunInfo info) { + public void test85_verifier() { TooBigToReturnAsFields p = test85(tooBig); Asserts.assertEQ(p.a0, tooBig.a0); Asserts.assertEQ(p.a2, tooBig.a2); } - // CompLevel.C1->Interpreter invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) + // C1->Interpreter invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) @Test(compLevel = CompLevel.C1) public int test86(TooBigToReturnAsFields p) { TooBigToReturnAsFields np = test86_helper(p); @@ -1740,17 +1739,17 @@ private static TooBigToReturnAsFields test86_helper(TooBigToReturnAsFields p) { } @Run(test = "test86") - public void test86_verifier(RunInfo info) { + public void test86_verifier() { int result = test86(tooBig); int n = tooBig.a0 + tooBig.a5; Asserts.assertEQ(result, n); } //------------------------------------------------------------------------------- - // Tests for how CompLevel.C1 handles InlineTypeReturnedAsFields in both calls and returns (RefPoint?) + // Tests for how C1 handles InlineTypeReturnedAsFields in both calls and returns (RefPoint?) //------------------------------------------------------------------------------- - // CompLevel.C2->CompLevel.C1 invokestatic with InlineTypeReturnedAsFields (RefPoint.ref) + // C2->C1 invokestatic with InlineTypeReturnedAsFields (RefPoint.ref) @Test(compLevel = CompLevel.C2) public RefPoint.ref test87(RefPoint.ref p) { return test87_helper(p); @@ -1763,12 +1762,12 @@ private static RefPoint.ref test87_helper(RefPoint.ref p) { } @Run(test = "test87") - public void test87_verifier(RunInfo info) { + public void test87_verifier() { Object result = test87(null); Asserts.assertEQ(result, null); } - // CompLevel.C2->CompLevel.C1 invokestatic with InlineTypeReturnedAsFields (RefPoint.ref with constant null) + // C2->C1 invokestatic with InlineTypeReturnedAsFields (RefPoint.ref with constant null) @Test(compLevel = CompLevel.C2) public RefPoint.ref test88() { return test88_helper(); @@ -1781,12 +1780,12 @@ private static RefPoint.ref test88_helper() { } @Run(test = "test88") - public void test88_verifier(RunInfo info) { + public void test88_verifier() { Object result = test88(); Asserts.assertEQ(result, null); } - // CompLevel.C1->CompLevel.C2 invokestatic with InlineTypeReturnedAsFields (RefPoint.ref) + // C1->C2 invokestatic with InlineTypeReturnedAsFields (RefPoint.ref) @Test(compLevel = CompLevel.C1) public RefPoint.ref test89(RefPoint.ref p) { return test89_helper(p); @@ -1799,22 +1798,22 @@ private static RefPoint.ref test89_helper(RefPoint.ref p) { } @Run(test = "test89") - public void test89_verifier(RunInfo info) { + public void test89_verifier() { Object result = test89(null); Asserts.assertEQ(result, null); } //---------------------------------------------------------------------------------- // Tests for unverified entries: there are 6 cases: - // CompLevel.C1 -> Unverified Value Entry compiled by CompLevel.C1 - // CompLevel.C1 -> Unverified Value Entry compiled by CompLevel.C2 - // CompLevel.C2 -> Unverified Entry compiled by CompLevel.C1 (target is NOT an inline type) - // CompLevel.C2 -> Unverified Entry compiled by CompLevel.C2 (target is NOT an inline type) - // CompLevel.C2 -> Unverified Entry compiled by CompLevel.C1 (target IS an inline type, i.e., has VVEP_RO) - // CompLevel.C2 -> Unverified Entry compiled by CompLevel.C2 (target IS an inline type, i.e., has VVEP_RO) + // C1 -> Unverified Value Entry compiled by C1 + // C1 -> Unverified Value Entry compiled by C2 + // C2 -> Unverified Entry compiled by C1 (target is NOT an inline type) + // C2 -> Unverified Entry compiled by C2 (target is NOT an inline type) + // C2 -> Unverified Entry compiled by C1 (target IS an inline type, i.e., has VVEP_RO) + // C2 -> Unverified Entry compiled by C2 (target IS an inline type, i.e., has VVEP_RO) //---------------------------------------------------------------------------------- - // CompLevel.C1->CompLevel.C1 invokeinterface -- call Unverified Value Entry of MyImplPojo1.func2 (compiled by CompLevel.C1) + // C1->C1 invokeinterface -- call Unverified Value Entry of MyImplPojo1.func2 (compiled by C1) @Test(compLevel = CompLevel.C1) public int test90(Intf intf, int a, int b) { return intf.func2(a, b, pointField); @@ -1835,7 +1834,7 @@ public void test90_verifier(RunInfo info) { } } - // CompLevel.C1->CompLevel.C2 invokeinterface -- call Unverified Value Entry of MyImplPojo2.func2 (compiled by CompLevel.C2) + // C1->C2 invokeinterface -- call Unverified Value Entry of MyImplPojo2.func2 (compiled by C2) @Test(compLevel = CompLevel.C1) public int test91(Intf intf, int a, int b) { return intf.func2(a, b, pointField); @@ -1856,7 +1855,7 @@ public void test91_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokeinterface -- call Unverified Entry of MyImplPojo1.func2 (compiled by CompLevel.C1) + // C2->C1 invokeinterface -- call Unverified Entry of MyImplPojo1.func2 (compiled by C1) @Test(compLevel = CompLevel.C2) public int test92(Intf intf, int a, int b) { return intf.func2(a, b, pointField); @@ -1877,7 +1876,7 @@ public void test92_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C2 invokeinterface -- call Unverified Entry of MyImplPojo2.func2 (compiled by CompLevel.C2) + // C2->C2 invokeinterface -- call Unverified Entry of MyImplPojo2.func2 (compiled by C2) @Test(compLevel = CompLevel.C2) public int test93(Intf intf, int a, int b) { return intf.func2(a, b, pointField); @@ -1898,7 +1897,7 @@ public void test93_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokeinterface -- call Unverified Entry of MyImplVal1.func2 (compiled by CompLevel.C1 - has VVEP_RO) + // C2->C1 invokeinterface -- call Unverified Entry of MyImplVal1.func2 (compiled by C1 - has VVEP_RO) @Test(compLevel = CompLevel.C2) public int test94(Intf intf, int a, int b) { return intf.func2(a, b, pointField); @@ -1919,7 +1918,7 @@ public void test94_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C2 invokeinterface -- call Unverified Entry of MyImplVal2.func2 (compiled by CompLevel.C2 - has VVEP_RO) + // C2->C2 invokeinterface -- call Unverified Entry of MyImplVal2.func2 (compiled by C2 - has VVEP_RO) @Test(compLevel = CompLevel.C2) public int test95(Intf intf, int a, int b) { return intf.func2(a, b, pointField); @@ -1940,7 +1939,7 @@ public void test95_verifier(RunInfo info) { } } - // CompLevel.C1->CompLevel.C2 GC handling in StubRoutines::store_inline_type_fields_to_buf() + // C1->C2 GC handling in StubRoutines::store_inline_type_fields_to_buf() @Test(compLevel = CompLevel.C1) public RefPoint test96(RefPoint rp, boolean b) { RefPoint p = test96_helper(rp); @@ -1971,7 +1970,7 @@ public void test96_verifier(RunInfo info) { } } - // CompLevel.C1->CompLevel.C1 - caller is compiled first. It invokes callee(test97) a few times while the + // C1->C1 - caller is compiled first. It invokes callee(test97) a few times while the // callee is executed by the interpreter. Then, callee is compiled // and SharedRuntime::fixup_callers_callsite is called to fix up the // callsite from test97_verifier->test97. @@ -2000,7 +1999,7 @@ public void run_test97_verifier(RunInfo info) { test97_verifier(info); } - // CompLevel.C1->CompLevel.C2 - same as test97, except the callee is compiled by CompLevel.C2. + // C1->C2 - same as test97, except the callee is compiled by C2. @Test(compLevel = CompLevel.C2) public int test98(Point p1, Point p2) { return test98_helper(p1, p2); @@ -2026,7 +2025,7 @@ public void run_test98_verifier(RunInfo info) { test98_verifier(info); } - // CompLevel.C1->CompLevel.C2 - same as test97, except the callee is a static method. + // C1->C2 - same as test97, except the callee is a static method. @Test(compLevel = CompLevel.C1) public static int test99(Point p1, Point p2) { return test99_helper(p1, p2); @@ -2052,7 +2051,7 @@ public void run_test99_verifier(RunInfo info) { test99_verifier(info); } - // CompLevel.C2->CompLevel.C1 invokestatic, packing causes stack growth (1 extra stack word). + // C2->C1 invokestatic, packing causes stack growth (1 extra stack word). // Make sure stack frame is set up properly for GC. @Test(compLevel = CompLevel.C2) public float test100(FloatPoint fp1, FloatPoint fp2, RefPoint rp, int a1, int a2, int a3, int a4) { @@ -2101,7 +2100,7 @@ public void test100_verifier(RunInfo info) { } } - // CompLevel.C1->CompLevel.C2 force GC for every allocation when storing the returned + // C1->C2 force GC for every allocation when storing the returned // fields back into a buffered object. @Test(compLevel = CompLevel.C1) public RefPoint test101(RefPoint rp) { @@ -2132,7 +2131,7 @@ public void test101_verifier(RunInfo info) { } } - // Same as test101, except we have Interpreter->CompLevel.C2 instead. + // Same as test101, except we have Interpreter->C2 instead. @Test(compLevel = CompLevel.C1) public RefPoint test102(RefPoint rp) { return test102_interp(rp); @@ -2169,7 +2168,7 @@ public void test102_verifier(RunInfo info) { @Test(compLevel = CompLevel.C1) public void test103() { - // when this method is compiled by CompLevel.C1, the Test103Value class is not yet loaded. + // when this method is compiled by C1, the Test103Value class is not yet loaded. test103_v = new Test103Value(); // invokestatic "Test103Value.()QTest103Value;" } @@ -2194,7 +2193,7 @@ public void test103_verifier(RunInfo info) { // Same as test103, but with an inline class that's too big to return as fields. @Test(compLevel = CompLevel.C1) public void test104() { - // when this method is compiled by CompLevel.C1, the Test104Value class is not yet loaded. + // when this method is compiled by C1, the Test104Value class is not yet loaded. test104_v = new Test104Value(); // invokestatic "Test104Value.()QTest104Value;" } @@ -2230,7 +2229,7 @@ public void test104_verifier(RunInfo info) { Asserts.assertEQ(v.x0, rL); } - // CompLevel.C2->CompLevel.C1 invokeinterface -- call Unverified Entry of MyImplVal1.func1 (compiled by CompLevel.C1 - has VVEP_RO) + // C2->C1 invokeinterface -- call Unverified Entry of MyImplVal1.func1 (compiled by C1 - has VVEP_RO) /// (same as test94, except we are calling func1, which shares VVEP and VVEP_RO @Test(compLevel = CompLevel.C2) public int test105(Intf intf, int a, int b) { @@ -2252,7 +2251,7 @@ public void test105_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C2 invokeinterface -- call Unverified Entry of MyImplVal2.func1 (compiled by CompLevel.C2 - has VVEP_RO) + // C2->C2 invokeinterface -- call Unverified Entry of MyImplVal2.func1 (compiled by C2 - has VVEP_RO) /// (same as test95, except we are calling func1, which shares VVEP and VVEP_RO @Test(compLevel = CompLevel.C2) public int test106(Intf intf, int a, int b) { @@ -2274,8 +2273,8 @@ public void test106_verifier(RunInfo info) { } } - // CompLevel.C2->CompLevel.C1 invokeinterface -- CompLevel.C2 calls call Unverified Entry of MyImplVal2X.func1 (compiled by - // CompLevel.C1, with VVEP_RO==VVEP) + // C2->C1 invokeinterface -- C2 calls call Unverified Entry of MyImplVal2X.func1 (compiled by + // C1, with VVEP_RO==VVEP) // This test is developed to validate JDK-8230325. @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public int test107(Intf intf, int a, int b) { @@ -2291,14 +2290,14 @@ public void test107_verifier(RunInfo info) { test107(intf1, 123, 456); } for (int i=0; i<500_000; i++) { - // Run enough loops so that test107 will be compiled by CompLevel.C2. + // Run enough loops so that test107 will be compiled by C2. if (i % 30 == 0) { // This will indirectly call MyImplVal2X.func1, but the call frequency is low, so - // test107 will be compiled by CompLevel.C2, but MyImplVal2X.func1 will compiled by CompLevel.C1 only. + // test107 will be compiled by C2, but MyImplVal2X.func1 will compiled by C1 only. int result = test107(intf2, 123, 456) + i; Asserts.assertEQ(result, intf2.func1(123, 456) + i); } else { - // Call test107 with a mix of intf1 and intf2, so CompLevel.C2 will use a virtual call (not an optimized call) + // Call test107 with a mix of intf1 and intf2, so C2 will use a virtual call (not an optimized call) // for the invokeinterface bytecode in test107. test107(intf1, 123, 456); } @@ -2311,7 +2310,7 @@ public void run_test107_verifier(RunInfo info) { test107_verifier(info); } - // Same as test107, except we call MyImplVal2X.func2 (compiled by CompLevel.C1, VVEP_RO != VVEP) + // Same as test107, except we call MyImplVal2X.func2 (compiled by C1, VVEP_RO != VVEP) @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public int test108(Intf intf, int a, int b) { return intf.func2(a, b, pointField); @@ -2326,14 +2325,14 @@ public void test108_verifier(RunInfo info) { test108(intf1, 123, 456); } for (int i=0; i<500_000; i++) { - // Run enough loops so that test108 will be compiled by CompLevel.C2. + // Run enough loops so that test108 will be compiled by C2. if (i % 30 == 0) { // This will indirectly call MyImplVal2X.func2, but the call frequency is low, so - // test108 will be compiled by CompLevel.C2, but MyImplVal2X.func2 will compiled by CompLevel.C1 only. + // test108 will be compiled by C2, but MyImplVal2X.func2 will compiled by C1 only. int result = test108(intf2, 123, 456) + i; Asserts.assertEQ(result, intf2.func2(123, 456, pointField) + i); } else { - // Call test108 with a mix of intf1 and intf2, so CompLevel.C2 will use a virtual call (not an optimized call) + // Call test108 with a mix of intf1 and intf2, so C2 will use a virtual call (not an optimized call) // for the invokeinterface bytecode in test108. test108(intf1, 123, 456); } @@ -2347,7 +2346,7 @@ public void run_test108_verifier(RunInfo info) { } /* - // Same as test107, except we call MyImplPojo3.func2 (compiled by CompLevel.C1, VVEP_RO == VEP) + // Same as test107, except we call MyImplPojo3.func2 (compiled by C1, VVEP_RO == VEP) @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public int test109(Intf intf, int a, int b) { return intf.func2(a, b, pointField); @@ -2362,14 +2361,14 @@ public void test109_verifier(RunInfo info) { test109(intf1, 123, 456); } for (int i=0; i<500_000; i++) { - // Run enough loops so that test109 will be compiled by CompLevel.C2. + // Run enough loops so that test109 will be compiled by C2. if (i % 30 == 0) { // This will indirectly call MyImplPojo3.func2, but the call frequency is low, so - // test109 will be compiled by CompLevel.C2, but MyImplPojo3.func2 will compiled by CompLevel.C1 only. + // test109 will be compiled by C2, but MyImplPojo3.func2 will compiled by C1 only. int result = test109(intf2, 123, 456) + i; Asserts.assertEQ(result, intf2.func2(123, 456, pointField) + i); } else { - // Call test109 with a mix of intf1 and intf2, so CompLevel.C2 will use a virtual call (not an optimized call) + // Call test109 with a mix of intf1 and intf2, so C2 will use a virtual call (not an optimized call) // for the invokeinterface bytecode in test109. test109(intf1, 123, 456); } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java index 88b8a20f065..51ba7acb16b 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java @@ -285,7 +285,7 @@ public MyValue3 test8_callee(int len) { return test8_vt; } - @Test() + @Test public int test8(int start) { MyValue3 vt = test8_callee(start); test8_vt.verify(vt); From 0b761892d104440936c7f6520431c87c6468db07 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 26 Mar 2021 11:55:50 +0100 Subject: [PATCH 079/131] Fix bug where @ForceCompile methods could have inlined a @Test before it was processed and set to be not inlined --- .../inlinetypes/TestCallingConventionC1.java | 2 - .../ir_framework/TestFrameworkExecution.java | 41 +++++++++++-------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java index 8a471e142f4..0a7271f5402 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java @@ -2345,7 +2345,6 @@ public void run_test108_verifier(RunInfo info) { test108_verifier(info); } - /* // Same as test107, except we call MyImplPojo3.func2 (compiled by C1, VVEP_RO == VEP) @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) public int test109(Intf intf, int a, int b) { @@ -2380,5 +2379,4 @@ public void test109_verifier(RunInfo info) { public void run_test109_verifier(RunInfo info) { test109_verifier(info); } - */ } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 6f461e01d91..bf6fd9f70cd 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -187,16 +187,7 @@ private static void runTestsOnSameVM(Class testClass) { } private void start() { - if (helperClasses != null) { - for (Class helperClass : helperClasses) { - // Process the helper classes and apply the explicit compile commands - TestFormat.checkNoThrow(helperClass != testClass, - "Cannot specify test " + testClass + " as helper class, too."); - checkHelperClass(helperClass); - processControlAnnotations(helperClass); - } - } - parseTestClass(); + parseTests(); checkForcedCompilationsCompleted(); runTests(); } @@ -216,13 +207,15 @@ private void checkTestAnnotationInnerClass(Class c, String clazzType) { } } - private void parseTestClass() { + private void parseTests() { for (Class clazz : testClass.getDeclaredClasses()) { checkTestAnnotationInnerClass(clazz, "inner"); } addReplay(); - processControlAnnotations(testClass); + // Make sure to first parse tests and make them non-inlineable and only then process compile commands. setupTests(); + processControlAnnotations(testClass); + processHelperClasses(); setupCheckAndRunMethods(); // All remaining tests are simple base tests without check or specific way to run them. @@ -536,6 +529,18 @@ private static CompLevel flipCompLevel(CompLevel compLevel) { return compLevel; } + private void processHelperClasses() { + if (helperClasses != null) { + for (Class helperClass : helperClasses) { + // Process the helper classes and apply the explicit compile commands + TestFormat.checkNoThrow(helperClass != testClass, + "Cannot specify test " + testClass + " as helper class, too."); + checkHelperClass(helperClass); + processControlAnnotations(helperClass); + } + } + } + private void setupCheckAndRunMethods() { for (Method m : testClass.getDeclaredMethods()) { Check checkAnno = getAnnotation(m, Check.class); @@ -1033,8 +1038,9 @@ final protected void waitForCompilation(DeclaredTest test) { final boolean maybeCodeBufferOverflow = (TestFrameworkExecution.TEST_C1 && VERIFY_OOPS); final long started = System.currentTimeMillis(); boolean stateCleared = false; - while (true) { - long elapsed = System.currentTimeMillis() - started; + long elapsed = 0; + do { + elapsed = System.currentTimeMillis() - started; int level = WHITE_BOX.getMethodCompilationLevel(testMethod); if (maybeCodeBufferOverflow && elapsed > 5000 && (!WHITE_BOX.isMethodCompiled(testMethod, false) || level != test.getCompLevel().getValue())) { @@ -1050,11 +1056,10 @@ final protected void waitForCompilation(DeclaredTest test) { } if (isCompiled || TestFrameworkExecution.XCOMP) { // Don't wait for compilation if -Xcomp is enabled. - break; + return; } - TestRun.check(WAIT_FOR_COMPILATION_TIMEOUT < 0 || elapsed < WAIT_FOR_COMPILATION_TIMEOUT, - testMethod + " not compiled after waiting for " + WAIT_FOR_COMPILATION_TIMEOUT/1000 + " s"); - } + } while (elapsed < WAIT_FOR_COMPILATION_TIMEOUT); + TestRun.fail(testMethod + " not compiled after waiting for " + WAIT_FOR_COMPILATION_TIMEOUT/1000 + " s"); } private void retryDisabledVerifyOops(Method testMethod, boolean stateCleared) { From b8c49f1e1d31484fac2e61e243a9bd568ed8d0be Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Fri, 26 Mar 2021 10:04:07 -0700 Subject: [PATCH 080/131] Converted TestMethodHandles.java to new IR framework --- .../inlinetypes/TestCallingConventionC1.java | 3 +- .../inlinetypes/TestMethodHandles.java | 127 ++++++++++-------- .../inlinetypes/TestOnStackReplacement.java | 17 +-- 3 files changed, 81 insertions(+), 66 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java index 0a7271f5402..919803bda43 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java @@ -41,6 +41,8 @@ */ public class TestCallingConventionC1 { + static final TestFramework testFramework = InlineTypes.getFramework(); + public static void main(String[] args) { final Scenario[] scenarios = { // Default: both C1 and C2 are enabled, tiered compilation enabled @@ -73,7 +75,6 @@ public static void main(String[] args) { System.gc(); // Resolve this call, to avoid C1 code patching in the test cases. - TestFramework testFramework = new TestFramework(TestCallingConventionC1.class); testFramework.addScenarios(scenarios) .start(); } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java index 84a63b0014e..3d87451ebf7 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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,33 +25,27 @@ import java.lang.invoke.*; import java.lang.reflect.Method; +import sun.hotspot.WhiteBox; import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; /* * @test * @key randomness * @summary Test method handle support for inline types - * @library /testlibrary /test/lib /compiler/whitebox / + * @library /test/lib * @requires os.simpleArch == "x64" - * @compile TestMethodHandles.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestMethodHandles + * @compile InlineTypes.java + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestMethodHandles */ -public class TestMethodHandles extends InlineTypeTest { - // Extra VM parameters for some test scenarios. See InlineTypeTest.getVMParameters() - @Override - public String[] getExtraVMParameters(int scenario) { - switch (scenario) { - // Prevent inlining through MethodHandle linkTo adapters to stress the calling convention - case 2: return new String[] {"-DVerifyIR=false", "-XX:CompileCommand=dontinline,java.lang.invoke.DirectMethodHandle::internalMemberName"}; - case 4: return new String[] {"-XX:CompileCommand=dontinline,java.lang.invoke.DirectMethodHandle::internalMemberName"}; - } - return null; - } + +public class TestMethodHandles { + static final TestFramework testFramework = InlineTypes.getFramework(); static { try { @@ -132,9 +126,21 @@ public String[] getExtraVMParameters(int scenario) { } } - public static void main(String[] args) throws Throwable { - TestMethodHandles test = new TestMethodHandles(); - test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, MyValue3.class, MyValue3Inline.class); + public static void main(String[] args) { + Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; + + // Prevent inlining through MethodHandle linkTo adapters to stress the calling convention + scenarios[2].addFlags("-DVerifyIR=false", + "-XX:CompileCommand=dontinline,java.lang.invoke.DirectMethodHandle::internalMemberName"); + scenarios[4].addFlags("-XX:CompileCommand=dontinline,java.lang.invoke.DirectMethodHandle::internalMemberName"); + + testFramework.addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class, + MyValue3.class, + MyValue3Inline.class) + .start(); } // Everything inlined @@ -147,14 +153,17 @@ MyValue3 test1_target() { static final MethodHandle test1_mh; - @Test(valid = InlineTypeReturnedAsFieldsOn, failOn = ALLOC + STORE + CALL) - @Test(valid = InlineTypeReturnedAsFieldsOff, match = { ALLOC, STORE }, matchCount = { 1, 14 }) + @Test + @IR(applyIf = {"InlineTypeReturnedAsFields", "true"}, + failOn = {ALLOC, STORE, CALL}) + @IR(applyIf = {"InlineTypeReturnedAsFields", "false"}, + counts = {ALLOC, "= 1", STORE, "= 14"}) public MyValue3 test1() throws Throwable { return (MyValue3)test1_mh.invokeExact(this); } - @DontCompile - public void test1_verifier(boolean warmup) throws Throwable { + @Run(test = "test1") + public void test1_verifier() throws Throwable { MyValue3 vt = test1(); test1_vt.verify(vt); } @@ -173,13 +182,15 @@ public MyValue3 test2() throws Throwable { return (MyValue3)test2_mh.invokeExact(this); } - @DontCompile - public void test2_verifier(boolean warmup) throws Throwable { - Method helper_m = getClass().getDeclaredMethod("test2_target"); - if (!warmup && USE_COMPILER && !WHITE_BOX.isMethodCompiled(helper_m, false)) { - enqueueMethodForCompilation(helper_m, COMP_LEVEL_FULL_OPTIMIZATION); - Asserts.assertTrue(WHITE_BOX.isMethodCompiled(helper_m, false), "test2_target not compiled"); + @Run(test = "test2") + public void test2_verifier(RunInfo info) throws Throwable { + if (!info.isWarmUp()) { + Method helper_m = getClass().getDeclaredMethod("test2_target"); + if (TestFramework.isCompiled(helper_m)) { + TestFramework.compile(helper_m, CompLevel.C2); + } } + MyValue3 vt = test2(); test2_vt.verify(vt); } @@ -198,12 +209,12 @@ public MyValue3 test3() throws Throwable { return (MyValue3)test3_mh.invokeExact(this); } - @DontCompile - public void test3_verifier(boolean warmup) throws Throwable { + @Run(test = "test3") + public void test3_verifier(RunInfo info) throws Throwable { // hack so C2 doesn't know the target of the invoke call Class c = Class.forName("java.lang.invoke.DirectMethodHandle"); Method m = c.getDeclaredMethod("internalMemberName", Object.class); - WHITE_BOX.testSetDontInlineMethod(m, warmup); + WhiteBox.getWhiteBox().testSetDontInlineMethod(m, info.isWarmUp()); MyValue3 vt = test3(); test3_vt.verify(vt); } @@ -228,8 +239,8 @@ public int test4() throws Throwable { return (int)test4_mh.invokeExact(); } - @DontCompile - public void test4_verifier(boolean warmup) throws Throwable { + @Run(test = "test4") + public void test4_verifier() throws Throwable { int i = test4(); Asserts.assertEQ(i, test4_vt.x); } @@ -247,8 +258,8 @@ public int test5() throws Throwable { return (int)test5_mh.invokeExact(this, test5_vt); } - @DontCompile - public void test5_verifier(boolean warmup) throws Throwable { + @Run(test = "test5") + public void test5_verifier() throws Throwable { int i = test5(); Asserts.assertEQ(i, test5_vt.x); } @@ -275,14 +286,15 @@ boolean test6_test() { static final MethodHandle test6_mh; - @Test(valid = InlineTypeReturnedAsFieldsOn, failOn = ALLOC + ALLOCA + STORE + STORE_INLINE_FIELDS) - @Test(valid = InlineTypeReturnedAsFieldsOff) + @Test + @IR(applyIf = {"InlineTypeReturnedAsFields", "true"}, + failOn = {ALLOC, ALLOCA, STORE, STORE_INLINE_FIELDS}) public MyValue3 test6() throws Throwable { return (MyValue3)test6_mh.invokeExact(this); } - @DontCompile - public void test6_verifier(boolean warmup) throws Throwable { + @Run(test = "test6") + public void test6_verifier() throws Throwable { test6_bool = !test6_bool; MyValue3 vt = test6(); vt.verify(test6_bool ? test6_vt1 : test6_vt2); @@ -314,8 +326,8 @@ public long test7() throws Throwable { return ((MyValue2)test7_mh.invokeExact(test7_mh1)).hash(); } - @DontCompile - public void test7_verifier(boolean warmup) throws Throwable { + @Run(test = "test7") + public void test7_verifier() throws Throwable { test7_bool = !test7_bool; long hash = test7(); Asserts.assertEQ(hash, MyValue2.createWithFieldsInline(rI+(test7_bool ? 0 : 1), rD+(test7_bool ? 0 : 1)).hash()); @@ -347,8 +359,8 @@ public long test8() throws Throwable { return ((MyValue2)test8_mh.invokeExact(test8_mh2)).hash(); } - @DontCompile - public void test8_verifier(boolean warmup) throws Throwable { + @Run(test = "test8") + public void test8_verifier() throws Throwable { test8_bool = !test8_bool; long hash = test8(); Asserts.assertEQ(hash, MyValue2.createWithFieldsInline(rI+(test8_bool ? 0 : 1), rD+(test8_bool ? 0 : 1)).hash()); @@ -388,15 +400,16 @@ boolean test9_test2() { static final MethodHandle test9_mh; - @Test(valid = InlineTypeReturnedAsFieldsOn, failOn = ALLOC + ALLOCA + STORE + STORE_INLINE_FIELDS) - @Test(valid = InlineTypeReturnedAsFieldsOff) - public MyValue3 test9() throws Throwable { + @Test + @IR(applyIf = {"InlineTypeReturnedAsFields", "true"}, + failOn = {ALLOC, ALLOCA, STORE, STORE_INLINE_FIELDS}) + public MyValue3 test9() throws Throwable { return (MyValue3)test9_mh.invokeExact(this); } static int test9_i = 0; - @DontCompile - public void test9_verifier(boolean warmup) throws Throwable { + @Run(test = "test9") + public void test9_verifier() throws Throwable { test9_i++; test9_bool1 = (test9_i % 2) == 0; test9_bool2 = (test9_i % 3) == 0; @@ -443,8 +456,8 @@ public long test10() throws Throwable { static int test10_i = 0; - @DontCompile - public void test10_verifier(boolean warmup) throws Throwable { + @Run(test = "test10") + public void test10_verifier() throws Throwable { test10_i++; test10_bool1 = (test10_i % 2) == 0; test10_bool2 = (test10_i % 3) == 0; @@ -477,13 +490,13 @@ static boolean test11_test() { // Check that a buffered inline type returned by a compiled lambda form // is properly handled by the caller. @Test - @Warmup(11000) public long test11() throws Throwable { return ((MyValue2)test11_mh.invokeExact(test11_mh2)).hash(); } - @DontCompile - public void test11_verifier(boolean warmup) throws Throwable { + @Run(test = "test11") + @Warmup(11000) + public void test11_verifier() throws Throwable { test11_i++; long hash = test11(); boolean b = (test11_i % 100) == 0; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java index 51ba7acb16b..794f6609979 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java @@ -44,18 +44,19 @@ public class TestOnStackReplacement { + static final TestFramework testFramework = InlineTypes.getFramework(); + public static void main(String[] args) throws Throwable { Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; scenarios[3].addFlags("-XX:FlatArrayElementMaxSize=0"); - InlineTypes.getFramework() - .addScenarios(scenarios) - .addHelperClasses(MyValue1.class, - MyValue2.class, - MyValue2Inline.class, - MyValue3.class, - MyValue3Inline.class) - .start(); + testFramework.addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class, + MyValue3.class, + MyValue3Inline.class) + .start(); } // Helper methods From 47a3d77d7ba86243cae3e76f4cc232ad1c1698d2 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 29 Mar 2021 16:42:13 +0200 Subject: [PATCH 081/131] Add more Javadocs, update assertCompiledXXX methods and remove some unused TestInfo and RunInfo methods --- .../hotspot/ir_framework/AbstractInfo.java | 79 +++++++++-- .../lib/hotspot/ir_framework/Argument.java | 5 +- .../hotspot/ir_framework/ArgumentValue.java | 13 +- .../test/lib/hotspot/ir_framework/Check.java | 6 +- .../lib/hotspot/ir_framework/CheckAt.java | 1 + .../CheckedTestFrameworkException.java | 4 +- .../lib/hotspot/ir_framework/CompLevel.java | 28 +++- .../ir_framework/IREncodingPrinter.java | 4 +- .../test/lib/hotspot/ir_framework/IRNode.java | 12 ++ .../ir_framework/IRViolationException.java | 2 +- .../ir_framework/ParsedComparator.java | 2 +- .../test/lib/hotspot/ir_framework/Run.java | 4 +- .../lib/hotspot/ir_framework/RunInfo.java | 123 +++++++++++------- .../lib/hotspot/ir_framework/RunMode.java | 5 + .../lib/hotspot/ir_framework/Scenario.java | 67 ++++++++-- .../test/lib/hotspot/ir_framework/Test.java | 2 +- .../ir_framework/TestFormatException.java | 8 +- .../hotspot/ir_framework/TestFramework.java | 57 ++++---- .../ir_framework/TestFrameworkException.java | 5 +- .../ir_framework/TestFrameworkExecution.java | 7 +- .../lib/hotspot/ir_framework/TestInfo.java | 51 +++++--- .../lib/hotspot/ir_framework/TestRun.java | 3 +- .../test/lib/hotspot/ir_framework/Warmup.java | 3 + .../ir_framework/tests/TestRunTests.java | 10 +- 24 files changed, 352 insertions(+), 149 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java index 40e5bd32b45..1bb362dd2c8 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java @@ -28,6 +28,14 @@ import java.util.Random; import java.util.stream.Collectors; +/** + * Base info class which provides some useful utility methods and information about a test. + *

    + * Base tests and checked tests use {@link TestInfo} while custom run tests use {@link RunInfo}. + * + * @see Test + * @see Check + */ abstract public class AbstractInfo { private static final Random random = new Random(); @@ -38,32 +46,65 @@ abstract public class AbstractInfo { AbstractInfo(Class testClass) { this.testClass = testClass; } - + + /** + * Returns a different boolean each time this method is invoked (switching between {@code false} and {@code true}. + * The first invocation returns {@code false}. + * + * @return an inverted boolean of the result of the last invocation of this method. + */ public boolean toggleBoolean() { toggleBool = !toggleBool; return toggleBool; } + /** + * Get a random integer. + * + * @return a random integer + */ public static int getRandomInt() { - return random.nextInt() % 1000; + return random.nextInt(); } + /** + * Get a random long value. + * + * @return a random long value. + */ public static long getRandomLong() { - return random.nextLong() % 1000; + return random.nextLong(); } + /** + * Get a random double value. + * + * @return a random double value. + */ public static double getRandomDouble() { - return random.nextDouble() % 1000; + return random.nextDouble(); } + /** + * Returns a boolean indicating if the framework is currently warming up the associated test. + * + * @return the warm-up status of the associated test. + * + * @see Warmup + */ public boolean isWarmUp() { return onWarmUp; } - void setWarmUpFinished() { - onWarmUp = false; - } - + /** + * Get the method object of the method {@code name} of class {@code c} with arguments {@code args}. + * + * @param c the class containing the method. + * @param name the name of the method. + * @param args the arguments of the method, leave empty if no arguments. + * + * @return the method object of the requested method. + */ public Method getMethod(Class c, String name, Class... args) { try { return c.getMethod(name, args); @@ -74,11 +115,33 @@ public Method getMethod(Class c, String name, Class... args) { } } + /** + * Get the method object of the method {@code name} of the test class with arguments {@code args}. + * + * @param name the name of the method in the test class. + * @param args the arguments of the method, leave empty if no arguments. + * + * @return the method object of the requested method in the test class. + */ public Method getTestClassMethod(String name, Class... args) { return getMethod(testClass, name, args); } + /** + * Returns a boolean indicating if the test VM runs with flags that only allow C1 compilations: + * {@code -XX:+TieredCompilation -XX:TieredStopAtLevel={1,2,3}} + * + * @return {@code true} if only C1 compilations are allowed; + * {@code false} otherwise. + */ public boolean isC1Test() { return TestFrameworkExecution.TEST_C1; } + + /** + * Called by framework when the warm-up is finished. Not exposed to users. + */ + void setWarmUpFinished() { + onWarmUp = false; + } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java index efeca6d5ca7..f22033f62e9 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java @@ -25,14 +25,15 @@ /** * Well-defined argument values that can be used in the {@link Arguments} annotation at a {@link Test} method for a - * base or a checked test. + * base test or a checked test. + * * @see Arguments * @see Test * @see Check */ public enum Argument { /** - * Provides the default value for any kind of primitive type and objects type if the class provides a default constructor. + * Provides the default value for any kind of primitive type and object type if the class provides a default constructor. */ DEFAULT, /** diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java index 5d19a5cb8bd..e8ead1b492e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java @@ -28,14 +28,17 @@ import java.lang.reflect.Parameter; import java.util.Random; +/** + * This class represents an argument value specified by {@link Argument} in {@link Arguments}. + */ class ArgumentValue { private static final Random random = new Random(); - final private Object argumentValue; - final private boolean isToggleBoolean; - final private boolean isRandomEach; - final private boolean isFixedRandom; - final private Class randomClass; + private final Object argumentValue; + private final boolean isToggleBoolean; + private final boolean isRandomEach; + private final boolean isFixedRandom; + private final Class randomClass; private boolean previousBoolean; private ArgumentValue(Object argumentValue, Boolean booleanToggle, boolean isFixedRandom) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java index a0a03601649..8c155fad539 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java @@ -40,7 +40,7 @@ * or any number specified by an additional {@link Warmup} annotation at {@code t} or by using * {@link TestFramework#setDefaultWarmup(int)} (could also be 0 which skips the warm-up completely which is similar * to simulating {@code -Xcomp}). After each invocation of {@code t}, the framework also invokes {@code c} if the - * {@code @Check} annotation specifies {@link CheckAt#EACH_INVOCATION} at {@link Check#when()}. + * {@code @Check} annotation specifies {@link CheckAt#EACH_INVOCATION} at {@link #when()}. *

  • After the warm-up, the framework compiles {@code t} at the specified compilation level set by * {@link Test#compLevel()} (default {@link CompLevel#ANY} will pick the highest available level which is usually * {@link CompLevel#C2}).

  • @@ -56,7 +56,7 @@ * The following additional constraints must be met for the test method {@code t} and check method {@code c}: *
      *
    • {@code c} must specify the method name {@code t} as property in {@code @Check(test = "t")} - * (see {@link Check#test()}. Specifying a non-{@code Test} annotated method or a {@code @Test} method that + * (see {@link #test()}. Specifying a non-{@code Test} annotated method or a {@code @Test} method that * has already been used by another {@code @Check} or {@link Run} method results in a {@link TestFormatException}. *

    • {@code c} can specify the following method parameter combinations: *

        @@ -86,7 +86,7 @@ /** * The unique associated {@link Test} method for this {@code @Check} annotated check method. The framework will directly * invoke the {@code @Check} method after each invocation or only after the compilation of the associated {@code @Test} - * method (depending on the value set with {@link Check#when()}). + * method (depending on the value set with {@link #when()}). *

        * If a non-{@code Test} annotated method is used or a {@code @Test} method that has already been used by another * {@code @Check} or {@link Run} method, then a {@link TestFormatException} is thrown. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java index 08dd3865346..36a7519c39a 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java @@ -26,6 +26,7 @@ /** * Enum used at in the {@link Check} annotation of a checked test. It specifies when the framework will invoke the * check method after invoking the associated {@link Test} method. + * * @see Check * @see Test */ diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java index 596e95bab08..4639f3589b7 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java @@ -23,7 +23,9 @@ package jdk.test.lib.hotspot.ir_framework; -// Checked exceptions in the framework to propagate error handling. +/** + * Checked internal exceptions in the framework to propagate error handling. + */ class CheckedTestFrameworkException extends Exception { CheckedTestFrameworkException(String msg) { super(msg); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java index 9f249b5eeae..3147238fe27 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java @@ -28,10 +28,15 @@ /** * Compilation levels used by the framework. The compilation levels map to the used levels in HotSpot (apart from the - * framework specific value {@link CompLevel#SKIP} that cannot be found in HotSpot). + * framework specific value {@link #SKIP} that cannot be found in HotSpot). * *

        * The compilation levels can be specified in the {@link Test}, {@link ForceCompile} and {@link DontCompile} annotation. + * + * + * @see Test + * @see ForceCompile + * @see DontCompile */ public enum CompLevel { /** @@ -84,15 +89,32 @@ public enum CompLevel { this.value = level; } + /** + * Get the compilation level as integer value. These will match the levels specified in HotSpot (if available). + * + * @return the compilation level as integer. + */ public int getValue() { return value; } + /** + * Get the compilation level enum from the specified integer. + * + * @param value the compilation level as integer. + * @throws TestRunException if {@code value} does not specify a valid compilation level. + * @return the compilation level enum for {@code value}. + */ public static CompLevel forValue(int value) { - return typesByValue.get(value); + CompLevel level = typesByValue.get(value); + TestRun.check(level != null, "Invalid compilation level " + value); + return level; } - public static boolean overlapping(CompLevel l1, CompLevel l2) { + /** + * Checks if two compilation levels are overlapping. + */ + static boolean overlapping(CompLevel l1, CompLevel l2) { return l1.isC1() == l2.isC1() || (l1 == C2 && l2 == C2); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java index 9518525d7da..7eb547ecba3 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java @@ -32,7 +32,9 @@ import java.util.Objects; import java.util.function.Function; -// Only used by TestVM +/** + * Prints an encoding of all @Test methods whether an @IR rules should be applied to the dedicated test framework socket. + */ class IREncodingPrinter { public static final String START = "##### IRMatchRulesEncoding - used by TestFramework #####"; public static final String END = "----- END -----"; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java index 11021e85101..75a9fa1453e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java @@ -27,6 +27,18 @@ import java.util.List; import java.util.regex.Pattern; +/** + * This class provides default regex strings that can be used in {@link IR} annotations to specify IR constraints. + *

        + * There are two types of default regexes: + *

          + *
        • Standalone regexes: Use them directly. + *

        • Composite regexes: They end with {@code _OF} and expect another string in a list in {@link IR#failOn()} and + * {@link IR#counts()}. Do not use them as standalone regex. Doing so will result in a {@link TestFormatException}
        • + *
        + * + * @see IR + */ public class IRNode { private static final String START = "(\\d+(\\s){2}("; private static final String MID = ".*)+(\\s){2}===.*"; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java index cd810e64114..e4c2379bf05 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java @@ -29,7 +29,7 @@ * specific regex that could not be matched. */ public class IRViolationException extends RuntimeException { - public IRViolationException(String message) { + IRViolationException(String message) { super(message); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java index 42e0135b020..9f151cf0dcf 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java @@ -28,7 +28,7 @@ class ParsedComparator> { private final String strippedString; private final BiPredicate predicate; - private String comparator; + private final String comparator; public ParsedComparator(String strippedString, BiPredicate predicate, String comparator) { this.strippedString = strippedString; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java index b05a96191a1..41f3f84f026 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java @@ -34,7 +34,7 @@ * the {@code @Run(test = "t")} annotation. These two methods represent a so-called custom run test. The only * difference to a base test (see {@link Test}) is that the framework will not invoke the test method {@code t} * but instead the run method {@code r} which is then responsible to invoke {@code t} and do any additional verification, - * (e.g. of the return value). If {@code Run} does not specify {@link RunMode#STANDALONE} as {@link Run#mode()} + * (e.g. of the return value). If {@code Run} does not specify {@link RunMode#STANDALONE} as {@link #mode()} * property, the framework does the following, similar as for base tests: *
          *
        1. The framework warms {@code r} up by invoking it for a predefined number of iterations (default: 2000) @@ -50,7 +50,7 @@ *

        * *

        - * If {@code Run} specifies {@link RunMode#STANDALONE} as {@link Run#mode()} property, the framework gives complete + * If {@code Run} specifies {@link RunMode#STANDALONE} as {@link #mode()} property, the framework gives complete * control to the run method {@code r}: *

          *
        1. The framework invokes the run method {@code r} only one time without any warm-up or compilation of diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java index 91fd2f48dfd..0f7818ce06d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java @@ -28,6 +28,11 @@ import java.util.List; import java.util.Map; +/** + * Test info class which provides some useful utility methods and information about a custom run test. + * + * @see Run + */ public class RunInfo extends AbstractInfo { private final Method testMethod; @@ -48,87 +53,113 @@ public class RunInfo extends AbstractInfo { this.testMethod = testMethods.get(0); } + /** + * Get the associated test method object of this custom run test. This method can only be called if one test method + * is specified in the custom run test ({@link Run#test()}). Otherwise, use {@link #getTest(String)}. + * + * @return the associated test method object. + * @throws TestRunException if called for a custom run test that specifies multiple test methods in {@link Run#test()}. + */ public Method getTest() { checkSingleTest("getTest"); return testMethod; } + + /** + * Get the associated method object of the test method with the name {@code testName}. If the custom run test only + * specifies one test method ({@link Run#test()}), consider using {@link #getTest()}. + * + * @param testName the test method for which the method object should be returned. + * @return the associated test method object with the name {@code testName}. + * @throws TestRunException if there is no test method with the name {@code testName}. + */ public Method getTest(String testName) { return getMethod(testName); } + /** + * Returns a boolean indicating if the associated test method is C1 compiled. This method can only be called if one + * test method is specified in the custom run test ({@link Run#test()}). Otherwise, use {@link #isTestC1Compiled(String)}. + * + * @return {@code true} if the associated test method is C1 compiled; + * {@code false} otherwise. + * @throws TestRunException if called for a custom run test that specifies multiple test methods in {@link Run#test()}. + */ public boolean isTestC1Compiled() { checkSingleTest("isTestC1Compiled"); return TestFrameworkExecution.isC1Compiled(testMethod); } + /** + * Returns a boolean indicating if the associated test method with the name {@code testName} is C1 compiled. If the + * custom run test only specifies one test method ({@link Run#test()}), consider using {@link #isTestC1Compiled()}. + * + * @param testName the name of the test method. + * @return {@code true} if the test method with the name {@code testName} is C2 compiled; + * {@code false} otherwise. + * @throws TestRunException if there is no test method with the name {@code testName}. + */ public boolean isTestC1Compiled(String testName) { return TestFrameworkExecution.isC1Compiled(getMethod(testName)); } + /** + * Returns a boolean indicating if the associated test method is C2 compiled. This method can only be called if one + * test method is specified in the custom run test ({@link Run#test()}). Otherwise, use {@link #isTestC2Compiled(String)}. + * + * @return {@code true} if the associated test method is C2 compiled; + * {@code false} otherwise. + * @throws TestRunException if called for a custom run test that specifies multiple test methods in {@link Run#test()}. + */ public boolean isTestC2Compiled() { checkSingleTest("isTestC2Compiled"); return TestFrameworkExecution.isC2Compiled(testMethod); } + /** + * Returns a boolean indicating if the associated test method with the name {@code testName} is C2 compiled. If the + * custom run test only specifies one test method ({@link Run#test()}), consider using {@link #isTestC2Compiled()}. + * + * @param testName the name of the test method. + * @return {@code true} if the test method with the name {@code testName} is C2 compiled; + * {@code false} otherwise. + * @throws TestRunException if there is no test method with the name {@code testName}. + */ public boolean isTestC2Compiled(String testName) { return TestFrameworkExecution.isC2Compiled(getMethod(testName)); } + /** + * Returns a boolean indicating if the associated test method is compiled at {@code compLevel}. This method can only + * be called if one test method is specified in the custom run test ({@link Run#test()}). + * Otherwise, use {@link #isTestCompiledAtLevel(String, CompLevel)}. + * + * @param compLevel the compilation level + * @return {@code true} if the associated test method is compiled at {@code compLevel}; + * {@code false} otherwise. + * @throws TestRunException if called for a custom run test that specifies multiple test methods in {@link Run#test()}. + */ public boolean isTestCompiledAtLevel(CompLevel compLevel) { checkSingleTest("isTestCompiledAtLevel"); return TestFrameworkExecution.isCompiledAtLevel(testMethod, compLevel); } + /** + * Returns a boolean indicating if the associated test method with the name {@code testName} is compiled at + * {@code compLevel}. If thec ustom run test only specifies one test method ({@link Run#test()}), + * consider using {@link #isTestCompiledAtLevel(CompLevel)} )}. + * + * @param testName the name of the test method. + * @param compLevel the compilation level. + * @return {@code true} if the test method with the name {@code testName} is compiled at {@code compLevel}; + * {@code false} otherwise. + * @throws TestRunException if there is no test method with the name {@code testName}. + */ public boolean isTestCompiledAtLevel(String testName, CompLevel compLevel) { return TestFrameworkExecution.isCompiledAtLevel(getMethod(testName), compLevel); } - public void assertTestDeoptimizedByC1() { - checkSingleTest("assertTestDeoptimizedByC1"); - TestFrameworkExecution.assertDeoptimizedByC1(testMethod); - } - - public void assertTestDeoptimizedByC1(String testName) { - TestFrameworkExecution.assertDeoptimizedByC1(getMethod(testName)); - } - - public void assertTestCompiledByC1() { - checkSingleTest("assertTestCompiledByC1"); - TestFrameworkExecution.assertCompiledByC1(testMethod); - } - - public void assertTestCompiledByC1(String testName) { - TestFrameworkExecution.assertCompiledByC1(getMethod(testName)); - } - - public void assertTestDeoptimizedByC2() { - checkSingleTest("assertTestDeoptimizedByC2"); - TestFrameworkExecution.assertDeoptimizedByC2(testMethod); - } - - public void assertTestDeoptimizedByC2(String testName) { - TestFrameworkExecution.assertDeoptimizedByC2(getMethod(testName)); - } - - public void assertTestCompiledByC2() { - checkSingleTest("assertTestCompiledByC2"); - TestFrameworkExecution.assertCompiledByC2(testMethod); - } - - public void assertTestCompiledByC2(String testName) { - TestFrameworkExecution.assertCompiledByC2(getMethod(testName)); - } - - public void assertTestCompiledAtLevel(CompLevel level) { - checkSingleTest("assertTestCompiledAtLevel"); - TestFrameworkExecution.assertCompiledAtLevel(testMethod, level); - } - - public void assertTestCompiledAtLevel(String testName, CompLevel level) { - TestFrameworkExecution.assertCompiledAtLevel(getMethod(testName), level); - } - private void checkSingleTest(String calledMethod) { if (testMethod == null) { throw new TestRunException("Use " + calledMethod + " with testName String argument in @Run method when running " + @@ -139,7 +170,7 @@ private void checkSingleTest(String calledMethod) { private Method getMethod(String testName) { Method m = testMethods.get(testName); if (m == null) { - throw new RuntimeException("Could not find @Test \"" + testName + "\" in " + testClass + " being associated with" + + throw new TestRunException("Could not find @Test \"" + testName + "\" in " + testClass + " being associated with" + " corresponding @Run method."); } return m; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java b/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java index 0550ee3cf26..3bd65e9f308 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java @@ -23,6 +23,11 @@ package jdk.test.lib.hotspot.ir_framework; +/** + * The run mode for a custom run test specified in {@link Run#mode}. + * + * @see Run + */ public enum RunMode { /** * Default mode: First warm up run method, then compile the associated diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java index 071f4df0d20..e7b1414603e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java @@ -25,16 +25,25 @@ import java.util.*; +/** + * This class represents a scenario that can be executed by the {@link TestFramework}. + *

          + * A JTreg test should call the test framework with {@code @run driver}, not allowing to specify any additional flags. + * If a test should run with additional flags, use {@link TestFramework#addFlags(String...)}. If, however, the test + * should be run with different settings (equivalent to having multiple {@code @run} statements in a normal JTreg test), + * use scenarios. A scenario will be run with the scenario specific flags, if any, and the flags specified with + * {@link TestFramework#addFlags(String...)} whereas scenario flags will have precedence. + */ public class Scenario { - static final String ADDITIONAL_SCENARIO_FLAGS = System.getProperty("ScenarioFlags", ""); + private static final String ADDITIONAL_SCENARIO_FLAGS = System.getProperty("ScenarioFlags", ""); private static final String SCENARIOS = System.getProperty("Scenarios", ""); private static final List additionalScenarioFlags = new ArrayList<>(); private static final Set enabledScenarios = new HashSet<>(); private final List flags; private final int index; - boolean enabled; + private final boolean enabled; private String testVMOutput; static { @@ -47,41 +56,81 @@ public class Scenario { } } + /** + * Create a scenario with index {@code index} that will be run with the additionally specified flags specified in + * {@code flags} (or without any additional flags if null or parameter not specified). + *

          + * The scenario index must be unique to be distinguishable in stdout and stderr output and when specifying + * {@code -DScenarios} (see {@link Scenario}). + * + * @param index the unique scenario index. + * @param flags the scenario flags or null (i.e. no parameter specified) if no flags should be used. + */ public Scenario(int index, String... flags) { this.index = index; - if (flags != null && (enabledScenarios.isEmpty() || enabledScenarios.contains(index))) { + if (flags != null) { this.flags = new ArrayList<>(Arrays.asList(flags)); this.flags.addAll(additionalScenarioFlags); - this.enabled = true; } else { this.flags = new ArrayList<>(); - this.enabled = false; } + this.enabled = enabledScenarios.isEmpty() || enabledScenarios.contains(index); } + /** + * Add additional flags to this scenario. + * + * @param flags the additional scenario flags. + */ public void addFlags(String... flags) { if (flags != null) { this.flags.addAll(Arrays.asList(flags)); } } + /** + * Get all scenario specific flags as defined in {@link #Scenario(int, String...)}. + * + * @return the scenario flags. + */ public List getFlags() { return flags; } + /** + * Get the unique scenario index as defined in {@link #Scenario(int, String...)}. + * + * @return the scenario index. + */ public int getIndex() { return index; } + /** + * Returns a boolean indicating if this scenario will be executed by the test framework. This only depends on + * the property flag {@code -DScenarios} (see {@link Scenario}). + * + * @return {@code true} if {@code -DScenarios} is either not set or if {@code -DScenarios} specifies the scenario + * index set by {@link #Scenario(int, String...)}. + * {@code false} otherwise. + */ public boolean isEnabled() { return enabled; } - public void setTestVMOutput(String testVMOutput) { - this.testVMOutput = testVMOutput; - } - + /** + * Get the test VM output (stdout + stderr) of this scenario from the last execution of the framework. + * + * @return the test VM output. + */ public String getTestVMOutput() { return testVMOutput; } + + /** + * Set the test VM output, called by the framework. + */ + void setTestVMOutput(String testVMOutput) { + this.testVMOutput = testVMOutput; + } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java index ebc72cd988f..c5a4c3215b5 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java @@ -39,7 +39,7 @@ * {@link TestFramework#setDefaultWarmup(int)} (could also be 0 which skips the warm-up completely which is similar * to simulating {@code -Xcomp}). More information about the warm-up in general can be found in {@link Warmup}

        2. *
        3. After the warm-up, the framework compiles {@code m} at the specified compilation level set by - * {@link Test#compLevel()} (default {@link CompLevel#ANY} will pick the highest available level which is usually + * {@link #compLevel()} (default {@link CompLevel#ANY} will pick the highest available level which is usually * {@link CompLevel#C2}).

        4. *
        5. The framework invokes {@code m} one more time to check the compilation.

        6. *
        7. The framework checks any specified {@link IR} constraints at {@code m}. More information about IR matching diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java index c57790db78c..684b36d384a 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java @@ -24,14 +24,10 @@ package jdk.test.lib.hotspot.ir_framework; /** - * Exception that is thrown if a JTreg test violates the supported format by the framework. + * Exception that is thrown if a JTreg test violates the supported format by the test framework. */ public class TestFormatException extends RuntimeException { - public TestFormatException(String message) { + TestFormatException(String message) { super(message); } - - public TestFormatException(String message, Exception e) { - super(message, e); - } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index dabf3f25751..4b5eea20458 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -50,17 +50,16 @@ public class TestFramework { static final String TEST_VM_FLAGS_DELIMITER = " "; static final String TEST_VM_FLAGS_END = "----- END -----"; private static final int WARMUP_ITERATIONS = Integer.getInteger("Warmup", -1); - private static boolean VERIFY_IR = true; // Should we perform IR matching? private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); + private static boolean VERIFY_IR = true; // Should we perform IR matching? + private static String lastTestVMOutput; private List> helperClasses = null; private List scenarios = null; private final List flags = new ArrayList<>(); private final Class testClass; - private static String lastTestVMOutput; private TestFrameworkSocket socket; private int defaultWarmup = -1; - private final HashMap testMethods = new HashMap<>(); /* @@ -70,9 +69,9 @@ public class TestFramework { /** * Creates an instance of TestFramework to test the class from which this constructor was invoked from. * Use this constructor if you want to use multiple run options (flags, helper classes, scenarios). - * Use the associated add methods ({@link TestFramework#addFlags(String...)}, - * {@link TestFramework#addScenarios(Scenario...)}, {@link TestFramework#addHelperClasses(Class...)}) - * to set up everything and then start the testing by invoking {@link TestFramework#start()}. + * Use the associated add methods ({@link #addFlags(String...)}, {@link #addScenarios(Scenario...)}, + * {@link #addHelperClasses(Class...)}) + * to set up everything and then start the testing by invoking {@link #start()}. */ public TestFramework() { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); @@ -84,12 +83,12 @@ public TestFramework() { /** * Creates an instance of TestFramework to test {@code testClass}. * Use this constructor if you want to use multiple run options (flags, helper classes, scenarios). - * Use the associated add methods ({@link TestFramework#addFlags(String...)}, - * {@link TestFramework#addScenarios(Scenario...)}, {@link TestFramework#addHelperClasses(Class...)}) - * to set up everything and then start the testing by invoking {@link TestFramework#start()}. + * Use the associated add methods ({@link #addFlags(String...)}, @link #addScenarios(Scenario...)}, + * {@link #addHelperClasses(Class...)}) + * to set up everything and then start the testing by invoking {@link #start()}. * * @param testClass the class to be tested by the framework. - * @see TestFramework#TestFramework() + * @see #TestFramework() */ public TestFramework(Class testClass) { TestRun.check(testClass != null, "Test class cannot be null"); @@ -131,7 +130,7 @@ public static void run() { * Tests {@code testClass}. * * @param testClass the class to be tested by the framework. - * @see TestFramework#run() + * @see #run() */ public static void run(Class testClass) { TestFramework framework = new TestFramework(testClass); @@ -145,7 +144,7 @@ public static void run(Class testClass) { * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the {@code flags}.

        8. *
        9. If you want to run your JTreg test with additional flags, use this method.

        10. *
        11. If you want to run your JTreg test with multiple flag combinations, - * use {@link TestFramework#runWithScenarios(Scenario...)}

        12. + * use {@link #runWithScenarios(Scenario...)} *
      * * @param flags VM flags to be used for the test VM. @@ -162,13 +161,13 @@ public static void runWithFlags(String... flags) { * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the {@code flags}.
    • *
    • If you want to run your JTreg test with additional flags, use this method.

    • *
    • If you want to run your JTreg test with multiple flag combinations, - * use {@link TestFramework#runWithScenarios(Class, Scenario...)}

    • + * use {@link #runWithScenarios(Class, Scenario...)} *
    * * @param testClass the class to be tested by the framework. * @param flags VM flags to be used for the test VM. * - * @see TestFramework#runWithFlags(String...) + * @see #runWithFlags(String...) */ public static void runWithFlags(Class testClass, String... flags) { TestFramework framework = new TestFramework(testClass); @@ -184,8 +183,7 @@ public static void runWithFlags(Class testClass, String... flags) { *
  • If a helper class is not in the same file as the test class, make sure that JTreg compiles it by using * {@literal @}compile in the JTreg header comment block.

  • *
  • If a helper class does not specify any compile command annotations, you do not need to include it. If - * no helper class specifies any compile commands, consider using {@link TestFramework#run()} or - * {@link TestFramework#run(Class)}.

  • + * no helper class specifies any compile commands, consider using {@link #run()} or {@link #run(Class)}. * * * @param testClass the class to be tested by the framework. @@ -203,7 +201,7 @@ public static void runWithHelperClasses(Class testClass, Class... helperCl * Tests the class from which this method was invoked from. A test VM is called for each scenario in {@code scenarios} * by using the specified flags in the scenario. *
      - *
    • If there is only one scenario, consider using {@link TestFramework#runWithFlags(String...)}.

    • + *
    • If there is only one scenario, consider using {@link #runWithFlags(String...)}.

    • *
    • The scenario flags override any Java or VM options set by JTreg by default.

      * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the scenario flags.

    • *
    @@ -219,7 +217,7 @@ public static void runWithScenarios(Scenario... scenarios) { * Tests {@code testClass} A test VM is called for each scenario in {@code scenarios} by using the specified flags * in the scenario. *
      - *
    • If there is only one scenario, consider using {@link TestFramework#runWithFlags(String...)}.

    • + *
    • If there is only one scenario, consider using {@link #runWithFlags(String...)}.

    • *
    • The scenario flags override any Java or VM options set by JTreg by default.

      * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the scenario flags.

    • *
    @@ -227,7 +225,7 @@ public static void runWithScenarios(Scenario... scenarios) { * @param testClass the class to be tested by the framework. * @param scenarios scenarios which specify specific flags for the test VM. * - * @see TestFramework#runWithScenarios(Scenario...) + * @see #runWithScenarios(Scenario...) */ public static void runWithScenarios(Class testClass, Scenario... scenarios) { TestFramework framework = new TestFramework(testClass); @@ -240,7 +238,7 @@ public static void runWithScenarios(Class testClass, Scenario... scenarios) { * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the scenario flags. * *

    - * The testing can be started by invoking {@link TestFramework#start()} + * The testing can be started by invoking {@link #start()} * * @param flags VM options to be applied to the test VM. * @return the same framework instance. @@ -263,7 +261,7 @@ public TestFramework addFlags(String... flags) { * * *

    - * The testing can be started by invoking {@link TestFramework#start()} + * The testing can be started by invoking {@link #start()} * * @param helperClasses helper classes containing compile command annotations ({@link ForceCompile}, * {@link DontCompile}, {@link ForceInline}, {@link DontInline}) to be applied @@ -285,12 +283,12 @@ public TestFramework addHelperClasses(Class... helperClasses) { /** * Add scenarios to be used for the test VM. A test VM is called for each scenario in {@code scenarios} by using the - * specified flags in the scenario. The scenario flags override any flags set by {@link TestFramework#addFlags(String...)} + * specified flags in the scenario. The scenario flags override any flags set by {@link #addFlags(String...)} * and thus also override any Java or VM options set by JTreg by default.

    * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the scenario flags. * *

    - * The testing can be started by invoking {@link TestFramework#start()} + * The testing can be started by invoking {@link #start()} * * @param scenarios scenarios which specify specific flags for the test VM. * @return the same framework instance. @@ -306,8 +304,8 @@ public TestFramework addScenarios(Scenario... scenarios) { } /** - * Start the testing of the implicitely set test class by {@link TestFramework#TestFramework()} - * or explicitly set by {@link TestFramework#TestFramework(Class)}. + * Start the testing of the implicitely set test class by {@link #TestFramework()} + * or explicitly set by {@link #TestFramework(Class)}. */ public void start() { installWhiteBox(); @@ -346,7 +344,7 @@ public static String getLastTestVMOutput() { return lastTestVMOutput; } - /** + /* * The following methods can only be called from actual tests and not from the main() method of a test. * Calling these methods from main() results in a linking exception (Whitebox not yet loaded and enabled). */ @@ -515,8 +513,8 @@ private void start(Scenario scenario) { String flagsString = additionalFlags.isEmpty() ? "" : " - [" + String.join(", ", additionalFlags) + "]"; System.out.println("Run Test VM" + flagsString + ":"); runTestVM(additionalFlags, scenario); - System.out.println(); } finally { + System.out.println(); socket.close(); } } @@ -701,6 +699,9 @@ static void fail(String failureMessage, Exception e) { } } +/** + * Class to encapsulate information about the test VM output, the run process and the scenario. + */ class JVMOutput { private final Scenario scenario; private final OutputAnalyzer oa; @@ -738,7 +739,7 @@ public String getStderr() { } /** - * Dedicated socket to send data from flag and test VM back to the driver VM. + * Dedicated socket to send data from the flag and test VM back to the driver VM. */ class TestFrameworkSocket { static final String SERVER_PORT_PROPERTY = "ir.framework.server.port"; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java index 2307189e3dc..dfbcf9d6cd1 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java @@ -27,10 +27,11 @@ * Exception that is thrown if there is an internal error in the framework. This is most likely a bug in the framework. */ public class TestFrameworkException extends RuntimeException { - public TestFrameworkException(String message) { + TestFrameworkException(String message) { super(message); } - public TestFrameworkException(String message, Exception e) { + + TestFrameworkException(String message, Exception e) { super(message, e); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index bf6fd9f70cd..5d87f7ebd91 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -774,13 +774,12 @@ static void assertCompiledAtLevel(Method m, CompLevel level) { } static void assertNotCompiled(Method m) { - TestRun.check(!WHITE_BOX.isMethodCompiled(m, false) && !WHITE_BOX.isMethodCompiled(m, true), - m + " should not have been compiled"); + TestRun.check(!isC1Compiled(m), m + " should not have been compiled by C1"); + TestRun.check(!isC2Compiled(m), m + " should not have been compiled by C2"); } static void assertCompiled(Method m) { - TestRun.check(WHITE_BOX.isMethodCompiled(m, false) || WHITE_BOX.isMethodCompiled(m, true), - m + " should have been compiled"); + TestRun.check(isC1Compiled(m) || isC2Compiled(m), m + " should have been compiled"); } private static TriState compiledByC1(Method m) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java index fec418e2aba..dd4484f011e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java @@ -25,6 +25,13 @@ import java.lang.reflect.Method; +/** + * Test info class which provides some useful utility methods and information about a base test + * or a checked test. + * + * @see Test + * @see Check + */ public class TestInfo extends AbstractInfo { private final Method testMethod; @@ -34,39 +41,43 @@ public class TestInfo extends AbstractInfo { this.testMethod = testMethod; } + /** + * Get the associated test method object. + * + * @return the associated test method object + */ public Method getTest() { return testMethod; } + /** + * Returns a boolean indicating if the associated test method is C1 compiled. + * + * @return {@code true} if the test method is C1 compiled; + * {@code false} otherwise. + */ public boolean isC1Compiled() { return TestFrameworkExecution.isC1Compiled(testMethod); } + /** + * Returns a boolean indicating if the associated test method is C1 compiled. + * + * @return {@code true} if the test method is C2 compiled; + * {@code false} otherwise. + */ public boolean isC2Compiled() { return TestFrameworkExecution.isC2Compiled(testMethod); } + /** + * Returns a boolean indicating if the associated test method is compiled at {@code compLevel}. + * + * @param compLevel the compilation level + * @return {@code true} if the test method is compiled at {@code compLevel}; + * {@code false} otherwise. + */ public boolean isCompiledAtLevel(CompLevel compLevel) { return TestFrameworkExecution.isCompiledAtLevel(testMethod, compLevel); } - - public void assertDeoptimizedByC1() { - TestFrameworkExecution.assertDeoptimizedByC1(testMethod); - } - - public void assertCompiledByC1() { - TestFrameworkExecution.assertCompiledByC1(testMethod); - } - - public void assertDeoptimizedByC2() { - TestFrameworkExecution.assertDeoptimizedByC2(testMethod); - } - - public void assertCompiledByC2() { - TestFrameworkExecution.assertCompiledByC2(testMethod); - } - - public void assertCompiledAtLevel(CompLevel level) { - TestFrameworkExecution.assertCompiledAtLevel(testMethod, level); - } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java index 191b7091e44..b85024d0306 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java @@ -23,12 +23,13 @@ package jdk.test.lib.hotspot.ir_framework; -public class TestRun { +class TestRun { public static void check(boolean test, String failureMessage) { if (!test) { throw new TestRunException(failureMessage); } } + public static void fail(String failureMessage) { throw new TestRunException(failureMessage); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java index 1da49eb7332..82140cd4478 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java @@ -35,6 +35,9 @@ * the test method. * * + * @see Test + * @see Check + * @see Run */ @Retention(RetentionPolicy.RUNTIME) public @interface Warmup { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java index 909c6c7cb79..94a893ed19e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java @@ -62,8 +62,8 @@ public void run(RunInfo info) { test1(23); test2(42); if (!info.isWarmUp()) { - info.assertTestCompiledByC2("test1"); - info.assertTestCompiledByC2("test2"); + TestFramework.assertCompiledByC2(info.getTest("test1")); + TestFramework.assertCompiledByC2(info.getTest("test2")); } } @@ -78,7 +78,7 @@ public int test3(int x) { public void run2(RunInfo info) { test3(42); if (!info.isWarmUp()) { - info.assertTestCompiledByC2(); + TestFramework.assertCompiledByC2(info.getTest()); } } @@ -116,8 +116,8 @@ public void run4(RunInfo info) { test5(23); test6(42); if (!info.isWarmUp()) { - info.assertTestCompiledByC2("test5"); - info.assertTestCompiledByC2("test6"); + TestFramework.assertCompiledByC2(info.getTest("test5")); + TestFramework.assertCompiledByC2(info.getTest("test6")); } } From 4b213e951f1176bc2e340ac095a8acfb658c98d8 Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Mon, 29 Mar 2021 08:37:11 -0700 Subject: [PATCH 082/131] Converted TestNullableArrays to new IR framework --- .../valhalla/inlinetypes/TestArrays.java | 7 +- .../inlinetypes/TestNullableArrays.java | 819 +++++++++--------- 2 files changed, 417 insertions(+), 409 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java index 1b5fc1d3f27..60fff674365 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java @@ -794,7 +794,7 @@ public void test30_verifier(RunInfo info) { // non escaping allocation with memory phi @Test @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) - public long test31(boolean b, boolean deopt) { + public long test31(boolean b, boolean deopt, Method m) { MyValue2[] src = new MyValue2[1]; if (b) { src[0] = MyValue2.createWithFieldsInline(rI, rD); @@ -803,7 +803,6 @@ public long test31(boolean b, boolean deopt) { } if (deopt) { // uncommon trap - Method m = testFramework.getTestMethod("test31"); TestFramework.deoptimize(m); } return src[0].hash(); @@ -812,10 +811,10 @@ public long test31(boolean b, boolean deopt) { @Run(test = "test31") public void test31_verifier(RunInfo info) { MyValue2 v1 = MyValue2.createWithFieldsInline(rI, rD); - long result1 = test31(true, !info.isWarmUp()); + long result1 = test31(true, !info.isWarmUp(), info.getTest()); Asserts.assertEQ(result1, v1.hash()); MyValue2 v2 = MyValue2.createWithFieldsInline(rI + 1, rD + 1); - long result2 = test31(false, !info.isWarmUp()); + long result2 = test31(false, !info.isWarmUp(), info.getTest()); Asserts.assertEQ(result2, v2.hash()); } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java index dcfdb641795..c79a9aa0c55 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, 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 @@ -24,6 +24,12 @@ package compiler.valhalla.inlinetypes; import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; + import java.lang.reflect.Method; import java.util.Arrays; @@ -31,31 +37,28 @@ * @test * @key randomness * @summary Test nullable inline type arrays - * @library /testlibrary /test/lib /compiler/whitebox / + * @library /test/lib * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile TestNullableArrays.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestNullableArrays + * @compile InlineTypes.java + * @run driver compiler.valhalla.inlinetypes.TestNullableArrays */ -public class TestNullableArrays extends InlineTypeTest { - // Extra VM parameters for some test scenarios. See InlineTypeTest.getVMParameters() - @Override - public String[] getExtraVMParameters(int scenario) { - switch (scenario) { - case 2: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode"}; - case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast"}; - case 4: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast"}; - case 5: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode"}; - } - return null; - } - public static void main(String[] args) throws Throwable { - TestNullableArrays test = new TestNullableArrays(); - test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class); +public class TestNullableArrays { + static final TestFramework testFramework = InlineTypes.getFramework(); + + public static void main(String[] args) { + + Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; + scenarios[2].addFlags("-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode"); + scenarios[3].addFlags("-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast"); + scenarios[4].addFlags("-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast"); + scenarios[5].addFlags("-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode"); + + testFramework.addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class) + .start(); } // Helper methods @@ -68,11 +71,75 @@ protected long hash(int x, long y) { return MyValue1.createWithFieldsInline(x, y).hash(); } + static void verify(Object[] src, Object[] dst) { + for (int i = 0; i < src.length; ++i) { + if (src[i] != null) { + Asserts.assertEQ(((MyInterface)src[i]).hash(), ((MyInterface)dst[i]).hash()); + } else { + Asserts.assertEQ(dst[i], null); + } + } + } + + static void verify(MyValue1.ref[] src, MyValue1.ref[] dst) { + for (int i = 0; i < src.length; ++i) { + if (src[i] != null) { + Asserts.assertEQ(src[i].hash(), dst[i].hash()); + } else { + Asserts.assertEQ(dst[i], null); + } + } + } + + static void verify(MyValue1.ref[] src, Object[] dst) { + for (int i = 0; i < src.length; ++i) { + if (src[i] != null) { + Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); + } else { + Asserts.assertEQ(dst[i], null); + } + } + } + + static void verify(MyValue2.ref[] src, MyValue2.ref[] dst) { + for (int i = 0; i < src.length; ++i) { + if (src[i] != null) { + Asserts.assertEQ(src[i].hash(), dst[i].hash()); + } else { + Asserts.assertEQ(dst[i], null); + } + } + } + + static void verify(MyValue2.ref[] src, Object[] dst) { + for (int i = 0; i < src.length; ++i) { + if (src[i] != null) { + Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); + } else { + Asserts.assertEQ(dst[i], null); + } + } + } + + static boolean compile_and_run_again_if_deoptimized(RunInfo info) { + if (!info.isWarmUp()) { + Method m = info.getTest(); + if (TestFramework.isCompiled(m)) { + TestFramework.compile(m, CompLevel.C2); + } + } + return false; + } + private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(rI, rL); // Test nullable inline type array creation and initialization - @Test(valid = InlineTypeArrayFlattenOn, match = { ALLOCA }, matchCount = { 1 }) - @Test(valid = InlineTypeArrayFlattenOff, match = { ALLOCA }, matchCount = { 1 }, failOn = LOAD) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + counts = {ALLOCA, "= 1"}) + @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, + counts = {ALLOCA, "= 1"}, + failOn = LOAD) public MyValue1.ref[] test1(int len) { MyValue1.ref[] va = new MyValue1.ref[len]; if (len > 0) { @@ -84,8 +151,8 @@ public MyValue1.ref[] test1(int len) { return va; } - @DontCompile - public void test1_verifier(boolean warmup) { + @Run(test = "test1") + public void test1_verifier() { int len = Math.abs(rI % 10); MyValue1.ref[] va = test1(len); if (len > 0) { @@ -97,22 +164,24 @@ public void test1_verifier(boolean warmup) { } // Test creation of an inline type array and element access - @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) public long test2() { MyValue1.ref[] va = new MyValue1.ref[1]; va[0] = MyValue1.createWithFieldsInline(rI, rL); return va[0].hash(); } - @DontCompile - public void test2_verifier(boolean warmup) { + @Run(test = "test2") + public void test2_verifier() { long result = test2(); Asserts.assertEQ(result, hash()); } // Test receiving an inline type array from the interpreter, // updating its elements in a loop and computing a hash. - @Test(failOn = ALLOCA) + @Test + @IR(failOn = {ALLOCA}) public long test3(MyValue1.ref[] va) { long result = 0; for (int i = 0; i < 10; ++i) { @@ -125,8 +194,8 @@ public long test3(MyValue1.ref[] va) { return result; } - @DontCompile - public void test3_verifier(boolean warmup) { + @Run(test = "test3") + public void test3_verifier() { MyValue1.ref[] va = new MyValue1.ref[10]; long expected = 0; for (int i = 1; i < 10; ++i) { @@ -144,13 +213,14 @@ public void test3_verifier(boolean warmup) { } // Test returning an inline type array received from the interpreter - @Test(failOn = ALLOC + ALLOCA + LOAD + STORE + LOOP + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOAD, STORE, LOOP, TRAP}) public MyValue1.ref[] test4(MyValue1.ref[] va) { return va; } - @DontCompile - public void test4_verifier(boolean warmup) { + @Run(test = "test4") + public void test4_verifier() { MyValue1.ref[] va = new MyValue1.ref[10]; for (int i = 0; i < 10; ++i) { va[i] = MyValue1.createWithFieldsDontInline(rI + i, rL + i); @@ -187,8 +257,8 @@ public MyValue1.ref[] test5(boolean b) { return va; } - @DontCompile - public void test5_verifier(boolean warmup) { + @Run(test = "test5") + public void test5_verifier() { MyValue1.ref[] va = test5(true); Asserts.assertEQ(va.length, 5); Asserts.assertEQ(va[0].hash(), hash(rI, hash())); @@ -206,27 +276,29 @@ public void test5_verifier(boolean warmup) { } // Test creation of inline type array with single element - @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) public MyValue1.ref test6() { MyValue1.ref[] va = new MyValue1.ref[1]; return va[0]; } - @DontCompile - public void test6_verifier(boolean warmup) { + @Run(test = "test6") + public void test6_verifier() { MyValue1.ref[] va = new MyValue1.ref[1]; MyValue1.ref v = test6(); Asserts.assertEQ(v, null); } // Test default initialization of inline type arrays - @Test(failOn = LOAD) + @Test + @IR(failOn = LOAD) public MyValue1.ref[] test7(int len) { return new MyValue1.ref[len]; } - @DontCompile - public void test7_verifier(boolean warmup) { + @Run(test = "test7") + public void test7_verifier() { int len = Math.abs(rI % 10); MyValue1.ref[] va = test7(len); for (int i = 0; i < len; ++i) { @@ -236,13 +308,14 @@ public void test7_verifier(boolean warmup) { } // Test creation of inline type array with zero length - @Test(failOn = ALLOC + LOAD + STORE + LOOP + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, LOOP, TRAP}) public MyValue1.ref[] test8() { return new MyValue1.ref[0]; } - @DontCompile - public void test8_verifier(boolean warmup) { + @Run(test = "test8") + public void test8_verifier() { MyValue1.ref[] va = test8(); Asserts.assertEQ(va.length, 0); } @@ -250,13 +323,14 @@ public void test8_verifier(boolean warmup) { static MyValue1.ref[] test9_va; // Test that inline type array loaded from field has correct type - @Test(failOn = LOOP) + @Test + @IR(failOn = {LOOP}) public long test9() { return test9_va[0].hash(); } - @DontCompile - public void test9_verifier(boolean warmup) { + @Run(test = "test9") + public void test9_verifier() { test9_va = new MyValue1.ref[1]; test9_va[0] = testValue1; long result = test9(); @@ -280,8 +354,8 @@ public MyValue1.ref[][][] test10(int len1, int len2, int len3) { return arr; } - @DontCompile - public void test10_verifier(boolean warmup) { + @Run(test = "test10") + public void test10_verifier() { MyValue1.ref[][][] arr = test10(2, 3, 4); for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { @@ -313,8 +387,8 @@ public void test11(MyValue1.ref[][][] arr, long[] res) { } } - @DontCompile - public void test11_verifier(boolean warmup) { + @Run(test = "test11") + public void test11_verifier() { MyValue1.ref[][][] arr = new MyValue1.ref[2][3][4]; long[] res = new long[2*3*4]; long[] verif = new long[2*3*4]; @@ -353,8 +427,8 @@ public int test12() { } } - @DontCompile - public void test12_verifier(boolean warmup) { + @Run(test = "test12") + public void test12_verifier() { Asserts.assertEQ(test12(), rI); } @@ -375,8 +449,8 @@ public int test13() { } } - @DontCompile - public void test13_verifier(boolean warmup) { + @Run(test = "test13") + public void test13_verifier() { Asserts.assertEQ(test13(), rI); } @@ -386,8 +460,8 @@ public int test14(MyValue1.ref[] va, int index) { return va[index].x; } - @DontCompile - public void test14_verifier(boolean warmup) { + @Run(test = "test14") + public void test14_verifier() { int arraySize = Math.abs(rI) % 10; MyValue1.ref[] va = new MyValue1.ref[arraySize]; @@ -422,8 +496,8 @@ public int test15() { } } - @DontCompile - public void test15_verifier(boolean warmup) { + @Run(test = "test15") + public void test15_verifier() { Asserts.assertEQ(test15(), rI); } @@ -443,8 +517,8 @@ public int test16() { } } - @DontCompile - public void test16_verifier(boolean warmup) { + @Run(test = "test16") + public void test16_verifier() { Asserts.assertEQ(test16(), rI); } @@ -455,8 +529,8 @@ public int test17(MyValue1.ref[] va, int index, MyValue1 vt) { return va[index].x; } - @DontCompile - public void test17_verifier(boolean warmup) { + @Run(test = "test17") + public void test17_verifier() { int arraySize = Math.abs(rI) % 10; MyValue1.ref[] va = new MyValue1.ref[arraySize]; @@ -486,8 +560,8 @@ public MyValue1.ref[] test18(MyValue1.ref[] va) { return va.clone(); } - @DontCompile - public void test18_verifier(boolean warmup) { + @Run(test = "test18") + public void test18_verifier(RunInfo info) { int len = Math.abs(rI) % 10; MyValue1.ref[] va1 = new MyValue1.ref[len]; MyValue1[] va2 = new MyValue1[len]; @@ -511,7 +585,7 @@ public void test18_verifier(boolean warmup) { Asserts.assertEQ(result2[i].hash(), va2[i].hash()); } } - if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test18")) { + if (compile_and_run_again_if_deoptimized(info)) { MyValue1.ref[] result2 = test18(va2); for (int i = 0; i < len; ++i) { Asserts.assertEQ(result2[i].hash(), va2[i].hash()); @@ -533,8 +607,8 @@ public MyValue1.ref[] test19() { return va.clone(); } - @DontCompile - public void test19_verifier(boolean warmup) { + @Run(test = "test19") + public void test19_verifier() { MyValue1.ref[] result = test19(); Asserts.assertEQ(result[0], null); for (int i = 1; i < test19_orig.length; ++i) { @@ -548,8 +622,8 @@ public void test20(MyValue1.ref[] src, MyValue1.ref[] dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test20_verifier(boolean warmup) { + @Run(test = "test20") + public void test20_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] src1 = new MyValue1.ref[len]; MyValue1.ref[] src2 = new MyValue1.ref[len]; @@ -592,8 +666,8 @@ public void test21(MyValue2.ref[] src, MyValue2.ref[] dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test21_verifier(boolean warmup) { + @Run(test = "test21") + public void test21_verifier() { int len = Math.abs(rI) % 10; MyValue2.ref[] src1 = new MyValue2.ref[len]; MyValue2.ref[] src2 = new MyValue2.ref[len]; @@ -639,8 +713,8 @@ public MyValue1.ref[] test22(MyValue1.ref[] src) { return dst; } - @DontCompile - public void test22_verifier(boolean warmup) { + @Run(test = "test22") + public void test22_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] src1 = new MyValue1.ref[len]; MyValue1[] src2 = new MyValue1[len]; @@ -669,8 +743,8 @@ public MyValue1.ref[] test23(MyValue1.ref[] src) { return dst; } - @DontCompile - public void test23_verifier(boolean warmup) { + @Run(test = "test23") + public void test23_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] src1 = new MyValue1.ref[len]; MyValue1[] src2 = new MyValue1[len]; @@ -696,8 +770,8 @@ public void test24(MyValue1.ref[] src, Object dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test24_verifier(boolean warmup) { + @Run(test = "test24") + public void test24_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] src1 = new MyValue1.ref[len]; MyValue1.ref[] src2 = new MyValue1.ref[len]; @@ -740,8 +814,8 @@ public void test25(MyValue2.ref[] src, MyValue2.ref[] dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test25_verifier(boolean warmup) { + @Run(test = "test25") + public void test25_verifier() { MyValue2.ref[] src1 = new MyValue2.ref[8]; MyValue2.ref[] src2 = new MyValue2.ref[8]; MyValue2[] src3 = new MyValue2[8]; @@ -779,8 +853,8 @@ public void test26(MyValue1.ref[] src, MyValue1.ref[] dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test26_verifier(boolean warmup) { + @Run(test = "test26") + public void test26_verifier() { MyValue1.ref[] src1 = new MyValue1.ref[8]; MyValue1.ref[] src2 = new MyValue1.ref[8]; MyValue1[] src3 = new MyValue1[8]; @@ -818,8 +892,8 @@ public void test27(MyValue1.ref[] src, MyValue1.ref[] dst) { System.arraycopy(src, 1, dst, 2, 6); } - @DontCompile - public void test27_verifier(boolean warmup) { + @Run(test = "test27") + public void test27_verifier() { MyValue1.ref[] src1 = new MyValue1.ref[8]; MyValue1.ref[] src2 = new MyValue1.ref[8]; MyValue1[] src3 = new MyValue1[8]; @@ -854,8 +928,9 @@ public void test27_verifier(boolean warmup) { // non escaping allocations // TODO 8252027: Make sure this is optimized with ZGC - @Test(valid = ZGCOff, failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) - @Test(valid = ZGCOn) + @Test + @IR(applyIf = {"UseZGC", "false"}, + failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) public MyValue2.ref test28() { MyValue2.ref[] src = new MyValue2.ref[10]; src[0] = null; @@ -863,8 +938,8 @@ public MyValue2.ref test28() { return dst[0]; } - @DontCompile - public void test28_verifier(boolean warmup) { + @Run(test = "test28") + public void test28_verifier() { MyValue2 v = MyValue2.createWithFieldsInline(rI, rD); MyValue2.ref result = test28(); Asserts.assertEQ(result, null); @@ -872,15 +947,16 @@ public void test28_verifier(boolean warmup) { // non escaping allocations // TODO 8227588: shouldn't this have the same IR matching rules as test6? - @Test(failOn = ALLOCA + LOOP + TRAP) + @Test + @IR(failOn = {ALLOCA, LOOP, TRAP}) public MyValue2.ref test29(MyValue2.ref[] src) { MyValue2.ref[] dst = new MyValue2.ref[10]; System.arraycopy(src, 0, dst, 0, 10); return dst[0]; } - @DontCompile - public void test29_verifier(boolean warmup) { + @Run(test = "test29") + public void test29_verifier(RunInfo info) { MyValue2.ref[] src1 = new MyValue2.ref[10]; MyValue2.val[] src2 = new MyValue2.val[10]; for (int i = 0; i < 10; ++i) { @@ -889,7 +965,7 @@ public void test29_verifier(boolean warmup) { } MyValue2.ref v = test29(src1); Asserts.assertEQ(src1[0].hash(), v.hash()); - if (!warmup) { + if (!info.isWarmUp()) { v = test29(src2); Asserts.assertEQ(src2[0].hash(), v.hash()); } @@ -898,7 +974,6 @@ public void test29_verifier(boolean warmup) { // non escaping allocation with uncommon trap that needs // eliminated inline type array element as debug info @Test - @Warmup(10000) public MyValue2.ref test30(MyValue2.ref[] src, boolean flag) { MyValue2.ref[] dst = new MyValue2.ref[10]; System.arraycopy(src, 0, dst, 0, 10); @@ -906,17 +981,18 @@ public MyValue2.ref test30(MyValue2.ref[] src, boolean flag) { return dst[0]; } - @DontCompile - public void test30_verifier(boolean warmup) { + @Run(test = "test30") + @Warmup(10000) + public void test30_verifier(RunInfo info) { MyValue2.ref[] src1 = new MyValue2.ref[10]; MyValue2.val[] src2 = new MyValue2.val[10]; for (int i = 0; i < 10; ++i) { src1[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); src2[i] = MyValue2.createWithFieldsInline(rI+i, rD+i); } - MyValue2.ref v = test30(src1, !warmup); + MyValue2.ref v = test30(src1, !info.isWarmUp()); Asserts.assertEQ(src1[0].hash(), v.hash()); - if (!warmup) { + if (!info.isWarmUp()) { v = test30(src2, true); Asserts.assertEQ(src2[0].hash(), v.hash()); } @@ -926,7 +1002,7 @@ public void test30_verifier(boolean warmup) { @Test() // TODO 8227588 // @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) - public long test31(boolean b, boolean deopt) { + public long test31(boolean b, boolean deopt, Method m) { MyValue2.ref[] src = new MyValue2.ref[1]; if (b) { src[0] = MyValue2.createWithFieldsInline(rI, rD); @@ -935,18 +1011,18 @@ public long test31(boolean b, boolean deopt) { } if (deopt) { // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test31")); + TestFramework.deoptimize(m); } return src[0].hash(); } - @DontCompile - public void test31_verifier(boolean warmup) { + @Run(test = "test31") + public void test31_verifier(RunInfo info) { MyValue2 v1 = MyValue2.createWithFieldsInline(rI, rD); - long result1 = test31(true, !warmup); + long result1 = test31(true, !info.isWarmUp(), info.getTest()); Asserts.assertEQ(result1, v1.hash()); MyValue2 v2 = MyValue2.createWithFieldsInline(rI+1, rD+1); - long result2 = test31(false, !warmup); + long result2 = test31(false, !info.isWarmUp(), info.getTest()); Asserts.assertEQ(result2, v2.hash()); } @@ -957,8 +1033,8 @@ public Object[] test32(Object[] va) { return va.clone(); } - @DontCompile - public void test32_verifier(boolean warmup) { + @Run(test = "test32") + public void test32_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] va1 = new MyValue1.ref[len]; MyValue1[] va2 = new MyValue1[len]; @@ -983,8 +1059,8 @@ public Object[] test33(Object[] va) { return va.clone(); } - @DontCompile - public void test33_verifier(boolean warmup) { + @Run(test = "test33") + public void test33_verifier() { int len = Math.abs(rI) % 10; Object[] va = new Object[len]; for (int i = 0; i < len; ++i) { @@ -1020,91 +1096,27 @@ public Object[] test34(boolean flag) { return va.clone(); } - @DontCompile - public void test34_verifier(boolean warmup) { + @Run(test = "test34") + public void test34_verifier(RunInfo info) { test34(false); for (int i = 0; i < 10; i++) { // make sure we do deopt Object[] result = test34(true); verify(test34_orig, result); } - if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test34")) { + if (compile_and_run_again_if_deoptimized(info)) { Object[] result = test34(true); verify(test34_orig, result); } } - static void verify(Object[] src, Object[] dst) { - for (int i = 0; i < src.length; ++i) { - if (src[i] != null) { - Asserts.assertEQ(((MyInterface)src[i]).hash(), ((MyInterface)dst[i]).hash()); - } else { - Asserts.assertEQ(dst[i], null); - } - } - } - - static void verify(MyValue1.ref[] src, MyValue1.ref[] dst) { - for (int i = 0; i < src.length; ++i) { - if (src[i] != null) { - Asserts.assertEQ(src[i].hash(), dst[i].hash()); - } else { - Asserts.assertEQ(dst[i], null); - } - } - } - - static void verify(MyValue1.ref[] src, Object[] dst) { - for (int i = 0; i < src.length; ++i) { - if (src[i] != null) { - Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); - } else { - Asserts.assertEQ(dst[i], null); - } - } - } - - static void verify(MyValue2.ref[] src, MyValue2.ref[] dst) { - for (int i = 0; i < src.length; ++i) { - if (src[i] != null) { - Asserts.assertEQ(src[i].hash(), dst[i].hash()); - } else { - Asserts.assertEQ(dst[i], null); - } - } - } - - static void verify(MyValue2.ref[] src, Object[] dst) { - for (int i = 0; i < src.length; ++i) { - if (src[i] != null) { - Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); - } else { - Asserts.assertEQ(dst[i], null); - } - } - } - - static boolean compile_and_run_again_if_deoptimized(boolean warmup, String test) { - if (!warmup) { - Method m = tests.get(test); - if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false)) { - if (!InlineTypeArrayFlatten && !XCOMP && !STRESS_CC) { - throw new RuntimeException("Unexpected deoptimization"); - } - enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); - return true; - } - } - return false; - } - // arraycopy() of inline type array of unknown size @Test public void test35(Object src, Object dst, int len) { System.arraycopy(src, 0, dst, 0, len); } - @DontCompile - public void test35_verifier(boolean warmup) { + @Run(test = "test35") + public void test35_verifier(RunInfo info) { int len = Math.abs(rI) % 10; MyValue1.ref[] src = new MyValue1.ref[len]; MyValue1.ref[] dst = new MyValue1.ref[len]; @@ -1113,7 +1125,7 @@ public void test35_verifier(boolean warmup) { } test35(src, dst, src.length); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test35")) { + if (compile_and_run_again_if_deoptimized(info)) { test35(src, dst, src.length); verify(src, dst); } @@ -1124,8 +1136,8 @@ public void test36(Object src, MyValue2.ref[] dst) { System.arraycopy(src, 0, dst, 0, dst.length); } - @DontCompile - public void test36_verifier(boolean warmup) { + @Run(test = "test36") + public void test36_verifier(RunInfo info) { int len = Math.abs(rI) % 10; MyValue2.ref[] src = new MyValue2.ref[len]; MyValue2.ref[] dst = new MyValue2.ref[len]; @@ -1134,7 +1146,7 @@ public void test36_verifier(boolean warmup) { } test36(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test36")) { + if (compile_and_run_again_if_deoptimized(info)) { test36(src, dst); verify(src, dst); } @@ -1145,8 +1157,8 @@ public void test37(MyValue2.ref[] src, Object dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test37_verifier(boolean warmup) { + @Run(test = "test37") + public void test37_verifier(RunInfo info) { int len = Math.abs(rI) % 10; MyValue2.ref[] src = new MyValue2.ref[len]; MyValue2.ref[] dst = new MyValue2.ref[len]; @@ -1155,20 +1167,20 @@ public void test37_verifier(boolean warmup) { } test37(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test37")) { + if (compile_and_run_again_if_deoptimized(info)) { test37(src, dst); verify(src, dst); } } @Test - @Warmup(1) // Avoid early compilation public void test38(Object src, MyValue2.ref[] dst) { System.arraycopy(src, 0, dst, 0, dst.length); } - @DontCompile - public void test38_verifier(boolean warmup) { + @Run(test = "test38") + @Warmup(1) // Avoid early compilation + public void test38_verifier(RunInfo info) { int len = Math.abs(rI) % 10; Object[] src = new Object[len]; MyValue2.ref[] dst = new MyValue2.ref[len]; @@ -1177,15 +1189,13 @@ public void test38_verifier(boolean warmup) { } test38(src, dst); verify(dst, src); - if (!warmup) { - Method m = tests.get("TestNullableArrays::test38"); - assertDeoptimizedByC2(m); - enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertDeoptimizedByC2(m); + TestFramework.compile(m, CompLevel.C2); test38(src, dst); verify(dst, src); - if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP && !STRESS_CC) { - throw new RuntimeException("unexpected deoptimization"); - } + TestFramework.assertCompiled(m); } } @@ -1194,8 +1204,8 @@ public void test39(MyValue2.ref[] src, Object dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test39_verifier(boolean warmup) { + @Run(test = "test39") + public void test39_verifier(RunInfo info) { int len = Math.abs(rI) % 10; MyValue2.ref[] src = new MyValue2.ref[len]; Object[] dst = new Object[len]; @@ -1204,20 +1214,20 @@ public void test39_verifier(boolean warmup) { } test39(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test39")) { + if (compile_and_run_again_if_deoptimized(info)) { test39(src, dst); verify(src, dst); } } @Test - @Warmup(1) // Avoid early compilation public void test40(Object[] src, Object dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test40_verifier(boolean warmup) { + @Run(test = "test40") + @Warmup(1) // Avoid early compilation + public void test40_verifier(RunInfo info) { int len = Math.abs(rI) % 10; Object[] src = new Object[len]; MyValue2.ref[] dst = new MyValue2.ref[len]; @@ -1226,15 +1236,13 @@ public void test40_verifier(boolean warmup) { } test40(src, dst); verify(dst, src); - if (!warmup) { - Method m = tests.get("TestNullableArrays::test40"); - assertDeoptimizedByC2(m); - enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertDeoptimizedByC2(m); + TestFramework.compile(m, CompLevel.C2); test40(src, dst); verify(dst, src); - if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP && !STRESS_CC) { - throw new RuntimeException("unexpected deoptimization"); - } + TestFramework.assertCompiled(m); } } @@ -1243,8 +1251,8 @@ public void test41(Object src, Object[] dst) { System.arraycopy(src, 0, dst, 0, dst.length); } - @DontCompile - public void test41_verifier(boolean warmup) { + @Run(test = "test41") + public void test41_verifier(RunInfo info) { int len = Math.abs(rI) % 10; MyValue2.ref[] src = new MyValue2.ref[len]; Object[] dst = new Object[len]; @@ -1253,7 +1261,7 @@ public void test41_verifier(boolean warmup) { } test41(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test41")) { + if (compile_and_run_again_if_deoptimized(info)) { test41(src, dst); verify(src, dst); } @@ -1264,8 +1272,8 @@ public void test42(Object[] src, Object[] dst) { System.arraycopy(src, 0, dst, 0, src.length); } - @DontCompile - public void test42_verifier(boolean warmup) { + @Run(test = "test42") + public void test42_verifier(RunInfo info) { int len = Math.abs(rI) % 10; Object[] src = new Object[len]; Object[] dst = new Object[len]; @@ -1274,11 +1282,9 @@ public void test42_verifier(boolean warmup) { } test42(src, dst); verify(src, dst); - if (!warmup) { - Method m = tests.get("TestNullableArrays::test42"); - if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP && !STRESS_CC) { - throw new RuntimeException("unexpected deoptimization"); - } + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiled(m); } } @@ -1288,8 +1294,8 @@ public void test43(Object src, Object dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test43_verifier(boolean warmup) { + @Run(test = "test43") + public void test43_verifier(RunInfo info) { MyValue1.ref[] src = new MyValue1.ref[8]; MyValue1.ref[] dst = new MyValue1.ref[8]; for (int i = 1; i < 8; ++i) { @@ -1297,7 +1303,7 @@ public void test43_verifier(boolean warmup) { } test43(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test43")) { + if (compile_and_run_again_if_deoptimized(info)) { test43(src, dst); verify(src, dst); } @@ -1308,8 +1314,8 @@ public void test44(Object src, MyValue2.ref[] dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test44_verifier(boolean warmup) { + @Run(test = "test44") + public void test44_verifier(RunInfo info) { MyValue2.ref[] src = new MyValue2.ref[8]; MyValue2.ref[] dst = new MyValue2.ref[8]; for (int i = 1; i < 8; ++i) { @@ -1317,7 +1323,7 @@ public void test44_verifier(boolean warmup) { } test44(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test44")) { + if (compile_and_run_again_if_deoptimized(info)) { test44(src, dst); verify(src, dst); } @@ -1328,8 +1334,8 @@ public void test45(MyValue2.ref[] src, Object dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test45_verifier(boolean warmup) { + @Run(test = "test45") + public void test45_verifier(RunInfo info) { MyValue2.ref[] src = new MyValue2.ref[8]; MyValue2.ref[] dst = new MyValue2.ref[8]; for (int i = 1; i < 8; ++i) { @@ -1337,20 +1343,20 @@ public void test45_verifier(boolean warmup) { } test45(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test45")) { + if (compile_and_run_again_if_deoptimized(info)) { test45(src, dst); verify(src, dst); } } @Test - @Warmup(1) // Avoid early compilation public void test46(Object[] src, MyValue2.ref[] dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test46_verifier(boolean warmup) { + @Run(test = "test46") + @Warmup(1) // Avoid early compilation + public void test46_verifier(RunInfo info) { Object[] src = new Object[8]; MyValue2.ref[] dst = new MyValue2.ref[8]; for (int i = 1; i < 8; ++i) { @@ -1358,15 +1364,13 @@ public void test46_verifier(boolean warmup) { } test46(src, dst); verify(dst, src); - if (!warmup) { - Method m = tests.get("TestNullableArrays::test46"); - assertDeoptimizedByC2(m); - enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertDeoptimizedByC2(m); + TestFramework.compile(m, CompLevel.C2); test46(src, dst); verify(dst, src); - if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP && !STRESS_CC) { - throw new RuntimeException("unexpected deoptimization"); - } + TestFramework.assertCompiled(m); } } @@ -1375,8 +1379,8 @@ public void test47(MyValue2.ref[] src, Object[] dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test47_verifier(boolean warmup) { + @Run(test = "test47") + public void test47_verifier(RunInfo info) { MyValue2.ref[] src = new MyValue2.ref[8]; Object[] dst = new Object[8]; for (int i = 1; i < 8; ++i) { @@ -1384,20 +1388,20 @@ public void test47_verifier(boolean warmup) { } test47(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test47")) { + if (compile_and_run_again_if_deoptimized(info)) { test47(src, dst); verify(src, dst); } } @Test - @Warmup(1) // Avoid early compilation public void test48(Object[] src, Object dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test48_verifier(boolean warmup) { + @Run(test = "test48") + @Warmup(1) // Avoid early compilation + public void test48_verifier(RunInfo info) { Object[] src = new Object[8]; MyValue2.ref[] dst = new MyValue2.ref[8]; for (int i = 1; i < 8; ++i) { @@ -1405,15 +1409,13 @@ public void test48_verifier(boolean warmup) { } test48(src, dst); verify(dst, src); - if (!warmup) { - Method m = tests.get("TestNullableArrays::test48"); - assertDeoptimizedByC2(m); - enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertDeoptimizedByC2(m); + TestFramework.compile(m, CompLevel.C2); test48(src, dst); verify(dst, src); - if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP && !STRESS_CC) { - throw new RuntimeException("unexpected deoptimization"); - } + TestFramework.assertCompiled(m); } } @@ -1422,8 +1424,8 @@ public void test49(Object src, Object[] dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test49_verifier(boolean warmup) { + @Run(test = "test49") + public void test49_verifier(RunInfo info) { MyValue2.ref[] src = new MyValue2.ref[8]; Object[] dst = new Object[8]; for (int i = 1; i < 8; ++i) { @@ -1431,7 +1433,7 @@ public void test49_verifier(boolean warmup) { } test49(src, dst); verify(src, dst); - if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test49")) { + if (compile_and_run_again_if_deoptimized(info)) { test49(src, dst); verify(src, dst); } @@ -1442,8 +1444,8 @@ public void test50(Object[] src, Object[] dst) { System.arraycopy(src, 0, dst, 0, 8); } - @DontCompile - public void test50_verifier(boolean warmup) { + @Run(test = "test50") + public void test50_verifier(RunInfo info) { Object[] src = new Object[8]; Object[] dst = new Object[8]; for (int i = 1; i < 8; ++i) { @@ -1451,11 +1453,9 @@ public void test50_verifier(boolean warmup) { } test50(src, dst); verify(src, dst); - if (!warmup) { - Method m = tests.get("TestNullableArrays::test50"); - if (USE_COMPILER && !WHITE_BOX.isMethodCompiled(m, false) && !XCOMP && !STRESS_CC) { - throw new RuntimeException("unexpected deoptimization"); - } + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiled(m); } } @@ -1464,8 +1464,8 @@ public MyValue1.ref[] test51(MyValue1.ref[] va) { return Arrays.copyOf(va, va.length, MyValue1.ref[].class); } - @DontCompile - public void test51_verifier(boolean warmup) { + @Run(test = "test51") + public void test51_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] va = new MyValue1.ref[len]; for (int i = 1; i < len; ++i) { @@ -1482,8 +1482,8 @@ public MyValue1.ref[] test52() { return Arrays.copyOf(test52_va, 8, MyValue1.ref[].class); } - @DontCompile - public void test52_verifier(boolean warmup) { + @Run(test = "test52") + public void test52_verifier() { for (int i = 1; i < 8; ++i) { test52_va[i] = testValue1; } @@ -1496,8 +1496,8 @@ public MyValue1.ref[] test53(Object[] va) { return Arrays.copyOf(va, va.length, MyValue1.ref[].class); } - @DontCompile - public void test53_verifier(boolean warmup) { + @Run(test = "test53") + public void test53_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] va = new MyValue1.ref[len]; for (int i = 1; i < len; ++i) { @@ -1512,8 +1512,8 @@ public Object[] test54(MyValue1.ref[] va) { return Arrays.copyOf(va, va.length, Object[].class); } - @DontCompile - public void test54_verifier(boolean warmup) { + @Run(test = "test54") + public void test54_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] va = new MyValue1.ref[len]; for (int i = 1; i < len; ++i) { @@ -1528,8 +1528,8 @@ public Object[] test55(Object[] va) { return Arrays.copyOf(va, va.length, Object[].class); } - @DontCompile - public void test55_verifier(boolean warmup) { + @Run(test = "test55") + public void test55_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] va = new MyValue1.ref[len]; for (int i = 1; i < len; ++i) { @@ -1544,8 +1544,8 @@ public MyValue1.ref[] test56(Object[] va) { return Arrays.copyOf(va, va.length, MyValue1.ref[].class); } - @DontCompile - public void test56_verifier(boolean warmup) { + @Run(test = "test56") + public void test56_verifier() { int len = Math.abs(rI) % 10; Object[] va = new Object[len]; for (int i = 1; i < len; ++i) { @@ -1560,8 +1560,8 @@ public Object[] test57(Object[] va, Class klass) { return Arrays.copyOf(va, va.length, klass); } - @DontCompile - public void test57_verifier(boolean warmup) { + @Run(test = "test57") + public void test57_verifier() { int len = Math.abs(rI) % 10; Object[] va = new MyValue1.ref[len]; for (int i = 1; i < len; ++i) { @@ -1576,8 +1576,8 @@ public Object[] test58(MyValue1.ref[] va, Class klass) { return Arrays.copyOf(va, va.length, klass); } - @DontCompile - public void test58_verifier(boolean warmup) { + @Run(test = "test58") + public void test58_verifier(RunInfo info) { int len = Math.abs(rI) % 10; MyValue1.ref[] va = new MyValue1.ref[len]; for (int i = 1; i < len; ++i) { @@ -1587,7 +1587,7 @@ public void test58_verifier(boolean warmup) { Object[] result = test58(va, MyValue1.ref[].class); verify(va, result); } - if (compile_and_run_again_if_deoptimized(warmup, "TestNullableArrays::test58")) { + if (compile_and_run_again_if_deoptimized(info)) { Object[] result = test58(va, MyValue1.ref[].class); verify(va, result); } @@ -1598,8 +1598,8 @@ public Object[] test59(MyValue1.ref[] va) { return Arrays.copyOf(va, va.length+1, MyValue1.ref[].class); } - @DontCompile - public void test59_verifier(boolean warmup) { + @Run(test = "test59") + public void test59_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] va = new MyValue1.ref[len]; MyValue1.ref[] verif = new MyValue1.ref[len+1]; @@ -1616,8 +1616,8 @@ public Object[] test60(Object[] va, Class klass) { return Arrays.copyOf(va, va.length+1, klass); } - @DontCompile - public void test60_verifier(boolean warmup) { + @Run(test = "test60") + public void test60_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] va = new MyValue1.ref[len]; MyValue1.ref[] verif = new MyValue1.ref[len+1]; @@ -1634,8 +1634,8 @@ public Object[] test61(Object[] va, Class klass) { return Arrays.copyOf(va, va.length+1, klass); } - @DontCompile - public void test61_verifier(boolean warmup) { + @Run(test = "test61") + public void test61_verifier() { int len = Math.abs(rI) % 10; Object[] va = new Integer[len]; for (int i = 1; i < len; ++i) { @@ -1668,8 +1668,8 @@ public Object[] test62(MyValue1.ref[] va, Integer[] oa) { return Arrays.copyOf(arr, arr.length+1, arr.getClass()); } - @DontCompile - public void test62_verifier(boolean warmup) { + @Run(test = "test62") + public void test62_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] va = new MyValue1.ref[len]; Integer[] oa = new Integer[len]; @@ -1704,8 +1704,8 @@ public Object[] test63(MyValue1.ref[] va, Integer[] oa) { return Arrays.copyOf(arr, arr.length+1, arr.getClass()); } - @DontCompile - public void test63_verifier(boolean warmup) { + @Run(test = "test63") + public void test63_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] va = new MyValue1.ref[len]; MyValue1.ref[] verif = new MyValue1.ref[len+1]; @@ -1725,8 +1725,8 @@ public MyValue1.ref[] test64() { return new MyValue1.ref[8]; } - @DontCompile - public void test64_verifier(boolean warmup) { + @Run(test = "test64") + public void test64_verifier() { MyValue1.ref[] va = test64(); for (int i = 0; i < 8; ++i) { Asserts.assertEQ(va[i], null); @@ -1739,8 +1739,8 @@ public MyValue1.ref[] test65() { return new MyValue1.ref[32]; } - @DontCompile - public void test65_verifier(boolean warmup) { + @Run(test = "test65") + public void test65_verifier() { MyValue1.ref[] va = test65(); for (int i = 0; i < 32; ++i) { Asserts.assertEQ(va[i], null); @@ -1748,15 +1748,16 @@ public void test65_verifier(boolean warmup) { } // Check init store elimination - @Test(match = { ALLOCA }, matchCount = { 1 }) + @Test + @IR(counts = { ALLOCA, "=1"}) public MyValue1.ref[] test66(MyValue1.ref vt) { MyValue1.ref[] va = new MyValue1.ref[1]; va[0] = vt; return va; } - @DontCompile - public void test66_verifier(boolean warmup) { + @Run(test = "test66") + public void test66_verifier() { MyValue1.ref vt = MyValue1.createWithFieldsDontInline(rI, rL); MyValue1.ref[] va = test66(vt); Asserts.assertEQ(va[0].hashPrimitive(), vt.hashPrimitive()); @@ -1770,8 +1771,8 @@ public MyValue1.ref[] test67(MyValue1.ref[] src) { return dst; } - @DontCompile - public void test67_verifier(boolean warmup) { + @Run(test = "test67") + public void test67_verifier() { MyValue1.ref[] va = new MyValue1.ref[16]; MyValue1.ref[] var = test67(va); for (int i = 0; i < 16; ++i) { @@ -1787,8 +1788,8 @@ public MyValue1.ref[] test68() { return va; } - @DontCompile - public void test68_verifier(boolean warmup) { + @Run(test = "test68") + public void test68_verifier() { MyValue1.ref[] va = test68(); for (int i = 0; i < 2; ++i) { Asserts.assertEQ(va[i], null); @@ -1804,8 +1805,8 @@ public MyValue1.ref[] test69(MyValue1.ref vt) { return va; } - @DontCompile - public void test69_verifier(boolean warmup) { + @Run(test = "test69") + public void test69_verifier() { MyValue1.ref vt = MyValue1.createWithFieldsDontInline(rI, rL); MyValue1.ref[] va = new MyValue1.ref[4]; va[0] = vt; @@ -1827,8 +1828,8 @@ public MyValue1.ref[] test70(MyValue1.ref[] other) { return va; } - @DontCompile - public void test70_verifier(boolean warmup) { + @Run(test = "test70") + public void test70_verifier() { MyValue1.ref[] va = new MyValue1.ref[2]; MyValue1.ref[] var = test70(va); for (int i = 0; i < 2; ++i) { @@ -1855,8 +1856,8 @@ public void test71() { } } - @DontCompile - public void test71_verifier(boolean warmup) { + @Run(test = "test71") + public void test71_verifier() { test71(); } @@ -1872,8 +1873,8 @@ public void test72(Object[] o, boolean b, Object element) { arr2[0] = element; } - @DontCompile - public void test72_verifier(boolean warmup) { + @Run(test = "test72") + public void test72_verifier() { Object[] arr = new Object[1]; Object elem = new Object(); test72(arr, true, elem); @@ -1891,8 +1892,8 @@ public void test73(Object[] oa, MyValue1.ref v, Object o) { oa[0] = oa; // The stored value is known to be not flattenable (an Object[]) } - @DontCompile - public void test73_verifier(boolean warmup) { + @Run(test = "test73") + public void test73_verifier() { MyValue1.ref v0 = MyValue1.createWithFieldsDontInline(rI, rL); MyValue1.ref v1 = MyValue1.createWithFieldsDontInline(rI+1, rL+1); MyValue1.ref[] arr = new MyValue1.ref[3]; @@ -1928,8 +1929,8 @@ public Object[] test74(MyValue1.ref[] va, Integer[] oa) { return arr.clone(); } - @DontCompile - public void test74_verifier(boolean warmup) { + @Run(test = "test74") + public void test74_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] va = new MyValue1.ref[len]; Integer[] oa = new Integer[len]; @@ -1966,8 +1967,8 @@ public Object[] test75(MyValue1.ref[] va, Integer[] oa) { return arr.clone(); } - @DontCompile - public void test75_verifier(boolean warmup) { + @Run(test = "test75") + public void test75_verifier() { int len = Math.abs(rI) % 10; MyValue1.ref[] va = new MyValue1.ref[len]; MyValue1.ref[] verif = new MyValue1.ref[len]; @@ -2003,8 +2004,8 @@ public Object[] test76(MyValue1[] vva, MyValue1.ref[] vba, MyValue1 vt, Object[] return result; } - @DontCompile - public void test76_verifier(boolean warmup) { + @Run(test = "test76") + public void test76_verifier() { MyValue1 vt = testValue1; Object[] out = new Object[1]; MyValue1[] vva = new MyValue1[42]; @@ -2050,8 +2051,8 @@ public Object[] test77(boolean b) { return va; } - @DontCompile - public void test77_verifier(boolean warmup) { + @Run(test = "test77") + public void test77_verifier() { Object[] va = test77(true); Asserts.assertEQ(va.length, 5); Asserts.assertEQ(((MyValue1)va[0]).hash(), hash(rI, hash())); @@ -2086,8 +2087,8 @@ public Object[] test78(MyValue1[] vva, MyValue1.ref[] vba, Object val, Object[] return result; } - @DontCompile - public void test78_verifier(boolean warmup) { + @Run(test = "test78") + public void test78_verifier() { MyValue1 vt = testValue1; Integer i = Integer.valueOf(42); Object[] out = new Object[1]; @@ -2115,13 +2116,14 @@ public void test78_verifier(boolean warmup) { } // Test widening conversions from [Q to [L - @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) public static MyValue1.ref[] test79(MyValue1[] va) { return va; } - @DontCompile - public void test79_verifier(boolean warmup) { + @Run(test = "test79") + public void test79_verifier() { MyValue1[] va = new MyValue1[1]; va[0] = testValue1; MyValue1.ref[] res = test79(va); @@ -2137,13 +2139,14 @@ public void test79_verifier(boolean warmup) { } // Same as test79 but with explicit cast and Object return - @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) public static Object[] test80(MyValue1[] va) { return (MyValue1.ref[])va; } - @DontCompile - public void test80_verifier(boolean warmup) { + @Run(test = "test80") + public void test80_verifier() { MyValue1[] va = new MyValue1[1]; va[0] = testValue1; Object[] res = test80(va); @@ -2170,8 +2173,8 @@ public static long test81(MyValue1[] va1, MyValue1.ref[] va2, MyValue1 vt, boole return result[1].hash(); } - @DontCompile - public void test81_verifier(boolean warmup) { + @Run(test = "test81") + public void test81_verifier() { MyValue1[] va = new MyValue1[2]; MyValue1.ref[] vaB = new MyValue1.ref[2]; va[1] = testValue1; @@ -2214,8 +2217,8 @@ public static long test82(MyValue1[] va1, MyValue1.ref[] va2, MyValue1 vt1, MyVa return result[1].hash(); } - @DontCompile - public void test82_verifier(boolean warmup) { + @Run(test = "test82") + public void test82_verifier() { MyValue1[] va = new MyValue1[2]; MyValue1.ref[] vaB = new MyValue1.ref[2]; va[1] = testValue1; @@ -2237,22 +2240,24 @@ public void test82_verifier(boolean warmup) { Asserts.assertEquals(res, testValue1.hash()); } - @Test(failOn = ALLOC + ALLOCA + STORE) + @Test + @IR(failOn = {ALLOC, ALLOCA, STORE}) public static long test83(MyValue1[] va) { MyValue1.ref[] result = va; return result[0].hash(); } - @DontCompile - public void test83_verifier(boolean warmup) { + @Run(test = "test83") + public void test83_verifier() { MyValue1[] va = new MyValue1[42]; va[0] = testValue1; long res = test83(va); Asserts.assertEquals(res, testValue1.hash()); } - @Test(valid = InlineTypeArrayFlattenOn, failOn = ALLOC + LOOP + STORE + TRAP) - @Test(valid = InlineTypeArrayFlattenOff) + @Test + @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, + failOn = {ALLOC, LOOP, STORE, TRAP}) public static MyValue1.ref[] test84(MyValue1 vt1, MyValue1.ref vt2) { MyValue1.ref[] result = new MyValue1[2]; result[0] = vt1; @@ -2260,8 +2265,8 @@ public static MyValue1.ref[] test84(MyValue1 vt1, MyValue1.ref vt2) { return result; } - @DontCompile - public void test84_verifier(boolean warmup) { + @Run(test = "test84") + public void test84_verifier() { MyValue1.ref[] res = test84(testValue1, testValue1); Asserts.assertEquals(res[0].hash(), testValue1.hash()); Asserts.assertEquals(res[1].hash(), testValue1.hash()); @@ -2279,8 +2284,8 @@ public static long test85(MyValue1.ref[] va, MyValue1 val) { return va[1].hash(); } - @DontCompile - public void test85_verifier(boolean warmup) { + @Run(test = "test85") + public void test85_verifier() { MyValue1[] va = new MyValue1[2]; MyValue1.ref[] vab = new MyValue1.ref[2]; va[1] = testValue1; @@ -2300,8 +2305,8 @@ public static long test86(MyValue1.ref[] va, MyValue1.ref val) { return va[1].hash(); } - @DontCompile - public void test86_verifier(boolean warmup) { + @Run(test = "test86") + public void test86_verifier() { MyValue1[] va = new MyValue1[2]; MyValue1.ref[] vab = new MyValue1.ref[2]; va[1] = testValue1; @@ -2331,20 +2336,21 @@ public long test87() { return va[0].hash(); } - @DontCompile - public void test87_verifier(boolean warmup) { + @Run(test = "test87") + public void test87_verifier() { long result = test87(); Asserts.assertEQ(result, hash()); } // Test narrowing conversion from [L to [Q - @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) public static MyValue1[] test88(MyValue1.ref[] va) { return (MyValue1[])va; } - @DontCompile - public void test88_verifier(boolean warmup) { + @Run(test = "test88") + public void test88_verifier() { MyValue1[] va = new MyValue1[1]; va[0] = testValue1; MyValue1[] res = test88(va); @@ -2360,13 +2366,14 @@ public void test88_verifier(boolean warmup) { } // Same as test88 but with explicit cast and Object argument - @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOCA, LOOP, LOAD, STORE, TRAP}) public static MyValue1[] test89(Object[] va) { return (MyValue1[])va; } - @DontCompile - public void test89_verifier(boolean warmup) { + @Run(test = "test89") + public void test89_verifier() { MyValue1[] va = new MyValue1[1]; va[0] = testValue1; MyValue1[] res = test89(va); @@ -2387,8 +2394,8 @@ public static MyValue1.ref[] test90(Object va) { return (MyValue1.ref[])va; } - @DontCompile - public void test90_verifier(boolean warmup) { + @Run(test = "test90") + public void test90_verifier() { MyValue1[] va = new MyValue1[1]; MyValue1.ref[] vab = new MyValue1.ref[1]; try { @@ -2407,8 +2414,8 @@ public static MyValue1.ref[] test91(Object[] va) { return (MyValue1.ref[])va; } - @DontCompile - public void test91_verifier(boolean warmup) { + @Run(test = "test91") + public void test91_verifier() { MyValue1[] va = new MyValue1[1]; MyValue1.ref[] vab = new MyValue1.ref[1]; try { @@ -2428,8 +2435,8 @@ public static void test92(MyValue1.ref[] src, MyValue1.ref[] dst) { System.arraycopy(src, 0, dst, 0, 2); } - @DontCompile - public void test92_verifier(boolean warmup) { + @Run(test = "test92") + public void test92_verifier() { MyValue1[] va = new MyValue1[2]; MyValue1.ref[] vab = new MyValue1.ref[2]; va[0] = testValue1; @@ -2444,8 +2451,8 @@ public static void test93(Object src, MyValue1.ref[] dst) { System.arraycopy(src, 0, dst, 0, 2); } - @DontCompile - public void test93_verifier(boolean warmup) { + @Run(test = "test93") + public void test93_verifier() { MyValue1[] va = new MyValue1[2]; MyValue1.ref[] vab = new MyValue1.ref[2]; va[0] = testValue1; @@ -2468,8 +2475,8 @@ public static long test94() { return dst[0].hash(); } - @DontCompile - public static void test94_verifier(boolean warmup) { + @Run(test = "test94") + public static void test94_verifier() { long result = test94(); Asserts.assertEquals(result, MyValue1.default.hash()); } @@ -2483,13 +2490,13 @@ public long test95_callee() { } @Test() - @Warmup(0) public long test95() { return test95_callee(); } - @DontCompile - public void test95_verifier(boolean warmup) { + @Run(test = "test95") + @Warmup(0) + public void test95_verifier() { long result = test95(); Asserts.assertEQ(result, hash()); } @@ -2542,8 +2549,8 @@ public Complex.ref[][] test96(Complex.ref[][] A, Complex.ref[][] B) { } } - @DontCompile - public void test96_verifier(boolean warmup) { + @Run(test = "test96") + public void test96_verifier() { Complex.ref[][] result = test96(test96_A, test96_B); if (test96_R == null) { test96_R = result; @@ -2556,13 +2563,14 @@ public void test96_verifier(boolean warmup) { } // Test loads from vararg arrays - @Test(failOn = LOAD_UNKNOWN_INLINE) + @Test + @IR(failOn = {LOAD_UNKNOWN_INLINE}) public static Object test97(Object... args) { return args[0]; } - @DontCompile - public static void test97_verifier(boolean warmup) { + @Run(test = "test97") + public static void test97_verifier() { Object obj = new Object(); Object result = test97(obj); Asserts.assertEquals(result, obj); @@ -2577,8 +2585,8 @@ public static Object test98(Object... args) { return args[0]; } - @DontCompile - public static void test98_verifier(boolean warmup) { + @Run(test = "test98") + public static void test98_verifier(RunInfo info) { Object obj = new Object(); Object result = test98(obj); Asserts.assertEquals(result, obj); @@ -2586,7 +2594,7 @@ public static void test98_verifier(boolean warmup) { myInt[0] = rI; result = test98((Object[])myInt); Asserts.assertEquals(result, rI); - if (!warmup) { + if (!info.isWarmUp()) { MyValue1[] va = new MyValue1[1]; MyValue1.ref[] vab = new MyValue1.ref[1]; result = test98((Object[])va); @@ -2601,8 +2609,8 @@ public static Object test99(Object... args) { return args[0]; } - @DontCompile - public static void test99_verifier(boolean warmup) { + @Run(test = "test99") + public static void test99_verifier(RunInfo info) { Object obj = new Object(); Object result = test99(obj); Asserts.assertEquals(result, obj); @@ -2610,7 +2618,7 @@ public static void test99_verifier(boolean warmup) { myInt[0] = rI; result = test99((Object[])myInt); Asserts.assertEquals(result, rI); - if (!warmup) { + if (!info.isWarmUp()) { try { test99((Object[])null); throw new RuntimeException("No NPE thrown"); @@ -2625,8 +2633,8 @@ public static Object test100(Object... args) { return args[0]; } - @DontCompile - public static void test100_verifier(boolean warmup) { + @Run(test = "test100") + public static void test100_verifier(RunInfo info) { Object obj = new Object(); Object result = test100(obj); Asserts.assertEquals(result, obj); @@ -2634,7 +2642,7 @@ public static void test100_verifier(boolean warmup) { myInt[0] = rI; result = test100((Object[])myInt); Asserts.assertEquals(result, rI); - if (!warmup) { + if (!info.isWarmUp()) { try { test100(); throw new RuntimeException("No AIOOBE thrown"); @@ -2645,13 +2653,14 @@ public static void test100_verifier(boolean warmup) { } // Test stores to varag arrays - @Test(failOn = STORE_UNKNOWN_INLINE) + @Test + @IR(failOn = {STORE_UNKNOWN_INLINE}) public static void test101(Object val, Object... args) { args[0] = val; } - @DontCompile - public static void test101_verifier(boolean warmup) { + @Run(test = "test101") + public static void test101_verifier() { Object obj = new Object(); test101(obj, obj); Integer[] myInt = new Integer[1]; @@ -2666,8 +2675,8 @@ public static void test102(Object val, Object... args) { args[0] = val; } - @DontCompile - public static void test102_verifier(boolean warmup) { + @Run(test = "test102") + public static void test102_verifier(RunInfo info) { Object obj = new Object(); test102(obj, obj); Integer[] myInt = new Integer[1]; @@ -2675,7 +2684,7 @@ public static void test102_verifier(boolean warmup) { Asserts.assertEquals(myInt[0], rI); test102(null, (Object[])myInt); Asserts.assertEquals(myInt[0], null); - if (!warmup) { + if (!info.isWarmUp()) { MyValue1[] va = new MyValue1[1]; MyValue1.ref[] vab = new MyValue1.ref[1]; test102(testValue1, (Object[])va); @@ -2692,8 +2701,8 @@ public static void test103(Object val, Object... args) { args[0] = val; } - @DontCompile - public static void test103_verifier(boolean warmup) { + @Run(test = "test103") + public static void test103_verifier(RunInfo info) { Object obj = new Object(); test103(obj, obj); Integer[] myInt = new Integer[1]; @@ -2701,7 +2710,7 @@ public static void test103_verifier(boolean warmup) { Asserts.assertEquals(myInt[0], rI); test103(null, (Object[])myInt); Asserts.assertEquals(myInt[0], null); - if (!warmup) { + if (!info.isWarmUp()) { MyValue1[] va = new MyValue1[1]; try { test103(null, (Object[])va); @@ -2717,8 +2726,8 @@ public static void test104(Object val, Object... args) { args[0] = val; } - @DontCompile - public static void test104_verifier(boolean warmup) { + @Run(test = "test104") + public static void test104_verifier(RunInfo info) { Object obj = new Object(); test104(obj, obj); Integer[] myInt = new Integer[1]; @@ -2726,7 +2735,7 @@ public static void test104_verifier(boolean warmup) { Asserts.assertEquals(myInt[0], rI); test104(null, (Object[])myInt); Asserts.assertEquals(myInt[0], null); - if (!warmup) { + if (!info.isWarmUp()) { try { test104(testValue1); throw new RuntimeException("No AIOOBE thrown"); @@ -2741,8 +2750,8 @@ public static void test105(Object val, Object... args) { args[0] = val; } - @DontCompile - public static void test105_verifier(boolean warmup) { + @Run(test = "test105") + public static void test105_verifier(RunInfo info) { Object obj = new Object(); test105(obj, obj); Integer[] myInt = new Integer[1]; @@ -2750,7 +2759,7 @@ public static void test105_verifier(boolean warmup) { Asserts.assertEquals(myInt[0], rI); test105(null, (Object[])myInt); Asserts.assertEquals(myInt[0], null); - if (!warmup) { + if (!info.isWarmUp()) { try { test105(testValue1, (Object[])null); throw new RuntimeException("No NPE thrown"); @@ -2775,8 +2784,8 @@ public static Object[] test106(Object[] dst, Object... args) { return Arrays.copyOf(args, args.length, Object[].class); } - @DontCompile - public static void test106_verifier(boolean warmup) { + @Run(test = "test106") + public static void test106_verifier(RunInfo info) { Object[] dst = new Object[1]; Object obj = new Object(); Object[] result = test106(dst, obj); @@ -2785,7 +2794,7 @@ public static void test106_verifier(boolean warmup) { myInt[0] = rI; result = test106(myInt, (Object[])myInt); Asserts.assertEquals(result[0], rI); - if (!warmup) { + if (!info.isWarmUp()) { MyValue1[] va = new MyValue1[1]; MyValue1.ref[] vab = new MyValue1.ref[1]; result = test106(va, (Object[])va); @@ -2814,13 +2823,12 @@ public void test107() { Asserts.assertEquals(res2, MyValue1.default.hash()); } - @DontCompile - public void test107_verifier(boolean warmup) { + @Run(test = "test107") + public void test107_verifier() { test107(); } @Test - @Warmup(10000) public Object test108(MyValue1.ref[] src, boolean flag) { MyValue1.ref[] dst = new MyValue1.ref[8]; System.arraycopy(src, 1, dst, 2, 6); @@ -2828,10 +2836,11 @@ public Object test108(MyValue1.ref[] src, boolean flag) { return dst[2]; } - @DontCompile - public void test108_verifier(boolean warmup) { + @Run(test = "test108") + @Warmup(10000) + public void test108_verifier(RunInfo info) { MyValue1.ref[] src = new MyValue1.ref[8]; - test108(src, !warmup); + test108(src, !info.isWarmUp()); } // Test LoadNode::can_see_arraycopy_value optimization @@ -2844,8 +2853,8 @@ public static void test109() { Asserts.assertEquals(src[0], dst[0]); } - @DontCompile - public void test109_verifier(boolean warmup) { + @Run(test = "test109") + public void test109_verifier() { test109(); } @@ -2859,8 +2868,8 @@ public static void test110() { Asserts.assertEquals(src[0], dst[0]); } - @DontCompile - public void test110_verifier(boolean warmup) { + @Run(test = "test110") + public void test110_verifier() { test110(); } @@ -2873,8 +2882,8 @@ public static void test111() { Asserts.assertEquals(src[0], dst[0]); } - @DontCompile - public void test111_verifier(boolean warmup) { + @Run(test = "test111") + public void test111_verifier() { test111(); } } From 225719749fa56c4cbc0653958d2e99e6d0c846fd Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Mon, 29 Mar 2021 13:31:47 -0700 Subject: [PATCH 083/131] Converted TestLWorld.java to new IR framewrok --- .../valhalla/inlinetypes/TestLWorld.java | 1084 +++++++++-------- 1 file changed, 601 insertions(+), 483 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java index 8bb29fdc300..063a2e344f2 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, 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 @@ -28,38 +28,42 @@ import java.util.Arrays; import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; + import test.java.lang.invoke.lib.InstructionHelper; /* * @test * @key randomness * @summary Test inline types in LWorld. - * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common /testlibrary /compiler/whitebox / - * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper + * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile TestLWorld.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestLWorld + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper + * @compile InlineTypes.java + * @run driver compiler.valhalla.inlinetypes.TestLWorld */ -public class TestLWorld extends InlineTypeTest { - // Extra VM parameters for some test scenarios. See InlineTypeTest.getVMParameters() - @Override - public String[] getExtraVMParameters(int scenario) { - switch (scenario) { - case 2: return new String[] {"-DVerifyIR=false"}; - case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"}; - case 4: return new String[] {"-XX:-MonomorphicArrayCheck"}; - } - return null; - } - public static void main(String[] args) throws Throwable { - TestLWorld test = new TestLWorld(); - test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, MyValue3.class, - MyValue3Inline.class, Test51Value.class); +public class TestLWorld { + static final TestFramework testFramework = InlineTypes.getFramework(); + + public static void main(String[] args) { + + Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; + scenarios[2].addFlags("-DVerifyIR=false"); + scenarios[3].addFlags("-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"); + scenarios[4].addFlags("-XX:-MonomorphicArrayCheck"); + + testFramework.addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class, + MyValue3.class, + MyValue3Inline.class) + .start(); } // Helper methods @@ -67,10 +71,52 @@ public static void main(String[] args) throws Throwable { private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(rI, rL); private static final MyValue2 testValue2 = MyValue2.createWithFieldsInline(rI, rD); + Object objectField1 = null; + Object objectField2 = null; + Object objectField3 = null; + Object objectField4 = null; + Object objectField5 = null; + Object objectField6 = null; + + MyValue1 valueField1 = testValue1; + MyValue1 valueField2 = testValue1; + MyValue1.ref valueField3 = testValue1; + MyValue1 valueField4; + MyValue1.ref valueField5; + + static MyValue1.ref staticValueField1 = testValue1; + static MyValue1 staticValueField2 = testValue1; + static MyValue1 staticValueField3; + static MyValue1.ref staticValueField4; + + private static final MyValue1[] testValue1Array = new MyValue1[] {testValue1, + testValue1, + testValue1}; + + private static final MyValue1[][] testValue1Array2 = new MyValue1[][] {testValue1Array, + testValue1Array, + testValue1Array}; + + private static final MyValue2[] testValue2Array = new MyValue2[] {testValue2, + testValue2, + testValue2}; + + private static final Integer[] testIntegerArray = new Integer[42]; + protected long hash() { return testValue1.hash(); } + private void rerun_and_recompile_for(Method m, int num, Runnable test) { + for (int i = 1; i < num; i++) { + test.run(); + + if (TestFramework.isCompiled(m)) { + TestFramework.compile(m, CompLevel.C2); + } + } + } + // Test passing an inline type as an Object @DontInline public Object test1_dontinline1(Object o) { @@ -102,29 +148,12 @@ public MyValue1 test1() { return vt; } - @DontCompile - public void test1_verifier(boolean warmup) { + @Run(test = "test1") + public void test1_verifier() { Asserts.assertEQ(test1().hash(), hash()); } // Test storing/loading inline types to/from Object and inline type fields - Object objectField1 = null; - Object objectField2 = null; - Object objectField3 = null; - Object objectField4 = null; - Object objectField5 = null; - Object objectField6 = null; - - MyValue1 valueField1 = testValue1; - MyValue1 valueField2 = testValue1; - MyValue1.ref valueField3 = testValue1; - MyValue1 valueField4; - MyValue1.ref valueField5; - - static MyValue1.ref staticValueField1 = testValue1; - static MyValue1 staticValueField2 = testValue1; - static MyValue1 staticValueField3; - static MyValue1.ref staticValueField4; @DontInline public Object readValueField5() { @@ -160,8 +189,8 @@ public long test2(MyValue1 vt1, Object vt2) { staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive(); } - @DontCompile - public void test2_verifier(boolean warmup) { + @Run(test = "test2") + public void test2_verifier() { MyValue1 vt = testValue1; MyValue1 def = MyValue1.createDefaultDontInline(); long result = test2(vt, vt); @@ -192,8 +221,8 @@ public Object test3(int state) { return res; } - @DontCompile - public void test3_verifier(boolean warmup) { + @Run(test = "test3") + public void test3_verifier() { objectField1 = valueField1; Object result = null; result = test3(0); @@ -228,8 +257,8 @@ public Object test4(int iters) { return res; } - @DontCompile - public void test4_verifier(boolean warmup) { + @Run(test = "test4") + public void test4_verifier() { Integer result1 = (Integer)test4(0); Asserts.assertEQ(result1, rI); int iters = (Math.abs(rI) % 10) + 1; @@ -239,28 +268,31 @@ public void test4_verifier(boolean warmup) { } // Test inline types in object variables that are live at safepoint - @Test(failOn = ALLOC + STORE + LOOP) - public long test5(MyValue1 arg, boolean deopt) { + + @Test + @IR(failOn = {ALLOC, STORE, LOOP}) + public long test5(MyValue1 arg, boolean deopt, Method m) { Object vt1 = MyValue1.createWithFieldsInline(rI, rL); Object vt2 = MyValue1.createWithFieldsDontInline(rI, rL); Object vt3 = arg; Object vt4 = valueField1; if (deopt) { // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test5")); + TestFramework.deoptimize(m); } return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() + ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash(); } - @DontCompile - public void test5_verifier(boolean warmup) { - long result = test5(valueField1, !warmup); + @Run(test = "test5") + public void test5_verifier(RunInfo info) { + long result = test5(valueField1, !info.isWarmUp(), info.getTest()); Asserts.assertEQ(result, 4*hash()); } // Test comparing inline types with objects - @Test(failOn = LOAD + LOOP) + @Test + @IR(failOn = {LOAD, LOOP}) public boolean test6(Object arg) { Object vt = MyValue1.createWithFieldsInline(rI, rL); if (vt == arg || vt == (Object)valueField1 || vt == objectField1 || vt == null || @@ -270,8 +302,8 @@ public boolean test6(Object arg) { return false; } - @DontCompile - public void test6_verifier(boolean warmup) { + @Run(test = "test6") + public void test6_verifier() { boolean result = test6(null); Asserts.assertFalse(result); } @@ -288,8 +320,8 @@ public Object test7(boolean flag) { return res; } - @DontCompile - public void test7_verifier(boolean warmup) { + @Run(test = "test7") + public void test7_verifier() { test7(true); test7(false); } @@ -305,8 +337,8 @@ public Object test8(boolean flag) { return res; } - @DontCompile - public void test8_verifier(boolean warmup) { + @Run(test = "test8") + public void test8_verifier() { test8(true); test8(false); } @@ -322,8 +354,8 @@ public Object test9() { return o; } - @DontCompile - public void test9_verifier(boolean warmup) { + @Run(test = "test9") + public void test9_verifier() { test9(); } @@ -333,7 +365,8 @@ public Object test10_helper() { return valueField1; } - @Test(failOn = ALLOC + LOAD + STORE) + @Test + @IR(failOn = {ALLOC, LOAD, STORE}) public void test10(boolean flag) { Object o = null; if (flag) { @@ -344,8 +377,8 @@ public void test10(boolean flag) { valueField1 = (MyValue1)o; } - @DontCompile - public void test10_verifier(boolean warmup) { + @Run(test = "test10") + public void test10_verifier() { test10(true); test10(false); } @@ -382,8 +415,8 @@ public MyValue1 test11() { return vt; } - @DontCompile - public void test11_verifier(boolean warmup) { + @Run(test = "test11") + public void test11_verifier() { Asserts.assertEQ(test11().hash(), hash()); } @@ -429,14 +462,15 @@ public long test12(MyValue1 vt1, MyInterface vt2) { staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive(); } - @DontCompile - public void test12_verifier(boolean warmup) { + @Run(test = "test12") + public void test12_verifier() { MyValue1 vt = testValue1; MyValue1 def = MyValue1.createDefaultDontInline(); long result = test12(vt, vt); Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive()); } + @ForceCompileClassInitializer class MyObject1 implements MyInterface { public int x; @@ -470,8 +504,8 @@ public MyInterface test13(int state) { return res; } - @DontCompile - public void test13_verifier(boolean warmup) { + @Run(test = "test13") + public void test13_verifier() { objectField1 = valueField1; MyInterface result = null; result = test13(0); @@ -502,8 +536,8 @@ public MyInterface test14(int iters) { return res; } - @DontCompile - public void test14_verifier(boolean warmup) { + @Run(test = "test14") + public void test14_verifier() { MyObject1 result1 = (MyObject1)test14(0); Asserts.assertEQ(result1.x, rI); int iters = (Math.abs(rI) % 10) + 1; @@ -513,28 +547,31 @@ public void test14_verifier(boolean warmup) { } // Test inline types in interface variables that are live at safepoint - @Test(failOn = ALLOC + STORE + LOOP) - public long test15(MyValue1 arg, boolean deopt) { + + @Test + @IR(failOn = {ALLOC, STORE, LOOP}) + public long test15(MyValue1 arg, boolean deopt, Method m) { MyInterface vt1 = MyValue1.createWithFieldsInline(rI, rL); MyInterface vt2 = MyValue1.createWithFieldsDontInline(rI, rL); MyInterface vt3 = arg; MyInterface vt4 = valueField1; if (deopt) { // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test15")); + TestFramework.deoptimize(m); } return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() + ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash(); } - @DontCompile - public void test15_verifier(boolean warmup) { - long result = test15(valueField1, !warmup); + @Run(test = "test15") + public void test15_verifier(RunInfo info) { + long result = test15(valueField1, !info.isWarmUp(), info.getTest()); Asserts.assertEQ(result, 4*hash()); } // Test comparing inline types with interfaces - @Test(failOn = LOAD + LOOP) + @Test + @IR(failOn = {LOAD, LOOP}) public boolean test16(Object arg) { MyInterface vt = MyValue1.createWithFieldsInline(rI, rL); if (vt == arg || vt == (MyInterface)valueField1 || vt == interfaceField1 || vt == null || @@ -544,8 +581,8 @@ public boolean test16(Object arg) { return false; } - @DontCompile - public void test16_verifier(boolean warmup) { + @Run(test = "test16") + public void test16_verifier() { boolean result = test16(null); Asserts.assertFalse(result); } @@ -562,8 +599,8 @@ public MyValue1 test17(MyValue1 vt, Object obj) { return vt; } - @DontCompile - public void test17_verifier(boolean warmup) { + @Run(test = "test17") + public void test17_verifier() { MyValue1 vt = testValue1; MyValue1 result = test17(vt, Integer.valueOf(rI)); Asserts.assertEquals(result.hash(), vt.hash()); @@ -576,8 +613,8 @@ public MyValue1 test18(MyValue1 vt) { return vt; } - @DontCompile - public void test18_verifier(boolean warmup) { + @Run(test = "test18") + public void test18_verifier() { MyValue1 vt = testValue1; MyValue1 result = test18(vt); Asserts.assertEquals(result.hash(), vt.hash()); @@ -594,8 +631,8 @@ public void test19(MyValue1 vt) { } } - @DontCompile - public void test19_verifier(boolean warmup) { + @Run(test = "test19") + public void test19_verifier() { test19(valueField1); } @@ -610,35 +647,21 @@ public void test20(MyValue1 vt) { } } - @DontCompile - public void test20_verifier(boolean warmup) { + @Run(test = "test20") + public void test20_verifier() { test20(valueField1); } // Array tests - private static final MyValue1[] testValue1Array = new MyValue1[] {testValue1, - testValue1, - testValue1}; - - private static final MyValue1[][] testValue1Array2 = new MyValue1[][] {testValue1Array, - testValue1Array, - testValue1Array}; - - private static final MyValue2[] testValue2Array = new MyValue2[] {testValue2, - testValue2, - testValue2}; - - private static final Integer[] testIntegerArray = new Integer[42]; - // Test load from (flattened) inline type array disguised as object array @Test() public Object test21(Object[] oa, int index) { return oa[index]; } - @DontCompile - public void test21_verifier(boolean warmup) { + @Run(test = "test21") + public void test21_verifier() { MyValue1 result = (MyValue1)test21(testValue1Array, Math.abs(rI) % 3); Asserts.assertEQ(result.hash(), hash()); } @@ -649,8 +672,8 @@ public Object test22Interface(MyInterface[] ia, int index) { return ia[index]; } - @DontCompile - public void test22Interface_verifier(boolean warmup) { + @Run(test = "test22Interface") + public void test22Interface_verifier() { MyValue1 result = (MyValue1)test22Interface(testValue1Array, Math.abs(rI) % 3); Asserts.assertEQ(result.hash(), hash()); } @@ -661,8 +684,8 @@ public Object test22Abstract(MyAbstract[] ia, int index) { return ia[index]; } - @DontCompile - public void test22Abstract_verifier(boolean warmup) { + @Run(test = "test22Abstract") + public void test22Abstract_verifier() { MyValue1 result = (MyValue1)test22Abstract(testValue1Array, Math.abs(rI) % 3); Asserts.assertEQ(result.hash(), hash()); } @@ -678,8 +701,8 @@ public void test23(Object[] oa, MyValue1 vt, int index) { test23_inline(oa, vt, index); } - @DontCompile - public void test23_verifier(boolean warmup) { + @Run(test = "test23") + public void test23_verifier() { int index = Math.abs(rI) % 3; MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1); test23(testValue1Array, vt, index); @@ -704,8 +727,8 @@ public void test24(Object[] oa, MyValue1 vt, int index) { test24_inline(oa, vt, index); } - @DontCompile - public void test24_verifier(boolean warmup) { + @Run(test = "test24") + public void test24_verifier() { int index = Math.abs(rI) % 3; try { test24(testIntegerArray, testValue1, index); @@ -725,8 +748,8 @@ public void test25(Object[] oa, MyValue1 vt, int index) { test25_inline(oa, vt, index); } - @DontCompile - public void test25_verifier(boolean warmup) { + @Run(test = "test25") + public void test25_verifier() { int index = Math.abs(rI) % 3; try { test25(null, testValue1, index); @@ -747,8 +770,8 @@ public void test26Interface(MyInterface[] ia, MyValue1 vt, int index) { test26Interface_inline(ia, vt, index); } - @DontCompile - public void test26Interface_verifier(boolean warmup) { + @Run(test = "test26Interface") + public void test26Interface_verifier() { int index = Math.abs(rI) % 3; MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1); test26Interface(testValue1Array, vt, index); @@ -773,8 +796,8 @@ public void test27Interface(MyInterface[] ia, MyValue1 vt, int index) { test27Interface_inline(ia, vt, index); } - @DontCompile - public void test27Interface_verifier(boolean warmup) { + @Run(test = "test27Interface") + public void test27Interface_verifier() { int index = Math.abs(rI) % 3; try { test27Interface(null, testValue1, index); @@ -795,8 +818,8 @@ public void test26Abstract(MyAbstract[] ia, MyValue1 vt, int index) { test26Abstract_inline(ia, vt, index); } - @DontCompile - public void test26Abstract_verifier(boolean warmup) { + @Run(test = "test26Abstract") + public void test26Abstract_verifier() { int index = Math.abs(rI) % 3; MyValue1 vt = MyValue1.createWithFieldsInline(rI + 1, rL + 1); test26Abstract(testValue1Array, vt, index); @@ -821,8 +844,8 @@ public void test27Abstract(MyAbstract[] ia, MyValue1 vt, int index) { test27Abstract_inline(ia, vt, index); } - @DontCompile - public void test27Abstract_verifier(boolean warmup) { + @Run(test = "test27Abstract") + public void test27Abstract_verifier() { int index = Math.abs(rI) % 3; try { test27Abstract(null, testValue1, index); @@ -843,8 +866,8 @@ public void test28(Object[] oa, Object o, int index) { test28_inline(oa, o, index); } - @DontCompile - public void test28_verifier(boolean warmup) { + @Run(test = "test28") + public void test28_verifier() { int index = Math.abs(rI) % 3; MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); test28(testValue1Array, vt1, index); @@ -869,8 +892,8 @@ public void test29(Object[] oa, Object o, int index) { test29_inline(oa, o, index); } - @DontCompile - public void test29_verifier(boolean warmup) { + @Run(test = "test29") + public void test29_verifier() { int index = Math.abs(rI) % 3; try { test29(testValue2Array, testValue1, index); @@ -891,8 +914,8 @@ public void test30(Object[] oa, Object o, int index) { test30_inline(oa, o, index); } - @DontCompile - public void test30_verifier(boolean warmup) { + @Run(test = "test30") + public void test30_verifier() { int index = Math.abs(rI) % 3; try { test30(testIntegerArray, testValue1, index); @@ -913,8 +936,8 @@ public void test31Interface(MyInterface[] ia, MyInterface i, int index) { test31Interface_inline(ia, i, index); } - @DontCompile - public void test31Interface_verifier(boolean warmup) { + @Run(test = "test31Interface") + public void test31Interface_verifier() { int index = Math.abs(rI) % 3; MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); test31Interface(testValue1Array, vt1, index); @@ -939,8 +962,8 @@ public void test32Interface(MyInterface[] ia, MyInterface i, int index) { test32Interface_inline(ia, i, index); } - @DontCompile - public void test32Interface_verifier(boolean warmup) { + @Run(test = "test32Interface") + public void test32Interface_verifier() { int index = Math.abs(rI) % 3; try { test32Interface(testValue2Array, testValue1, index); @@ -961,8 +984,8 @@ public void test31Abstract(MyAbstract[] ia, MyAbstract i, int index) { test31Abstract_inline(ia, i, index); } - @DontCompile - public void test31Abstract_verifier(boolean warmup) { + @Run(test = "test31Abstract") + public void test31Abstract_verifier() { int index = Math.abs(rI) % 3; MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); test31Abstract(testValue1Array, vt1, index); @@ -987,8 +1010,8 @@ public void test32Abstract(MyAbstract[] ia, MyAbstract i, int index) { test32Abstract_inline(ia, i, index); } - @DontCompile - public void test32Abstract_verifier(boolean warmup) { + @Run(test = "test32Abstract") + public void test32Abstract_verifier() { int index = Math.abs(rI) % 3; try { test32Abstract(testValue2Array, testValue1, index); @@ -1009,8 +1032,8 @@ public void test33(Object[] oa, Object o, int index) { test33_inline(oa, o, index); } - @DontCompile - public void test33_verifier(boolean warmup) { + @Run(test = "test33") + public void test33_verifier() { int index = Math.abs(rI) % 3; try { test33(testValue1Array, null, index); @@ -1033,8 +1056,8 @@ public void test34(Object[] oa, int index) { test34_inline(oa, null, index); } - @DontCompile - public void test34_verifier(boolean warmup) { + @Run(test = "test34") + public void test34_verifier() { int index = Math.abs(rI) % 3; try { test34(testValue1Array, index); @@ -1064,8 +1087,8 @@ public void test35(MyValue1[] va, int index) throws Throwable { setArrayElementNull.invoke(this, va, index); } - @DontCompile - public void test35_verifier(boolean warmup) throws Throwable { + @Run(test = "test35") + public void test35_verifier() throws Throwable { int index = Math.abs(rI) % 3; try { test35(testValue1Array, index); @@ -1082,8 +1105,8 @@ public void test36(MyValue1[] va, MyValue1 vt, int index) { va[index] = vt; } - @DontCompile - public void test36_verifier(boolean warmup) { + @Run(test = "test36") + public void test36_verifier() { int index = Math.abs(rI) % 3; try { test36(null, testValue1Array[index], index); @@ -1104,8 +1127,8 @@ public void test37(MyValue1[] va, Object o, int index) { test37_inline(va, o, index); } - @DontCompile - public void test37_verifier(boolean warmup) { + @Run(test = "test37") + public void test37_verifier() { int index = Math.abs(rI) % 3; MyValue1 vt1 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); test37(testValue1Array, vt1, index); @@ -1158,8 +1181,8 @@ public Object[] test38(Object[] oa, Object o, int i1, int i2, int num) { return result; } - @DontCompile - public void test38_verifier(boolean warmup) { + @Run(test = "test38") + public void test38_verifier() { int index = Math.abs(rI) % 3; MyValue1[] va = new MyValue1[42]; Object[] result = test38(null, testValue1, index, index, 0); @@ -1244,8 +1267,8 @@ public Object test39(Object oa, Object o, int i1, int i2, int num) { return result; } - @DontCompile - public void test39_verifier(boolean warmup) { + @Run(test = "test39") + public void test39_verifier() { int index = Math.abs(rI) % 3; MyValue1[] va = new MyValue1[42]; Object result = test39(null, testValue1, index, index, 0); @@ -1302,8 +1325,8 @@ public long test40(Object o, int index) { return 0; } - @DontCompile - public void test40_verifier(boolean warmup) { + @Run(test = "test40") + public void test40_verifier() { int index = Math.abs(rI) % 3; long result = test40(testValue1, 0); Asserts.assertEQ(result, testValue1.hash()); @@ -1332,8 +1355,8 @@ public void test41() { test41_dontinline(vals[0].oa[0]); } - @DontCompile - public void test41_verifier(boolean warmup) { + @Run(test = "test41") + public void test41_verifier() { test41(); } @@ -1348,19 +1371,19 @@ public void test42() { Asserts.assertEQ(vals[1].hash(), test42VT2.hash()); } - @DontCompile - public void test42_verifier(boolean warmup) { - if (!warmup) test42(); // We need -Xcomp behavior + @Run(test = "test42") + public void test42_verifier(RunInfo info) { + if (!info.isWarmUp()) test42(); // We need -Xcomp behavior } // Test for bug in Escape Analysis @Test() - public long test43(boolean deopt) { + public long test43(boolean deopt, Method m) { MyValue1[] vals = new MyValue1[] {(MyValue1) test42VT1, (MyValue1) test42VT2}; if (deopt) { // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test43")); + TestFramework.deoptimize(m); Asserts.assertEQ(vals[0].hash(), test42VT1.hash()); Asserts.assertEQ(vals[1].hash(), test42VT2.hash()); } @@ -1368,9 +1391,9 @@ public long test43(boolean deopt) { return vals[0].hash(); } - @DontCompile - public void test43_verifier(boolean warmup) { - test43(!warmup); + @Run(test = "test43") + public void test43_verifier(RunInfo info) { + test43(!info.isWarmUp(), info.getTest()); } // Tests writing an array element with a (statically known) incompatible type @@ -1391,8 +1414,8 @@ public void test44(MyValue1[] va, int index, MyValue2 v) throws Throwable { setArrayElementIncompatible.invoke(this, va, index, v); } - @DontCompile - public void test44_verifier(boolean warmup) throws Throwable { + @Run(test = "test44") + public void test44_verifier() throws Throwable { int index = Math.abs(rI) % 3; try { test44(testValue1Array, index, testValue2); @@ -1414,8 +1437,8 @@ public void test45(MyValue1[] va, int index, MyValue2 v) throws Throwable { test45_inline(va, v, index); } - @DontCompile - public void test45_verifier(boolean warmup) throws Throwable { + @Run(test = "test45") + public void test45_verifier() throws Throwable { int index = Math.abs(rI) % 3; try { test45(testValue1Array, index, testValue2); @@ -1433,8 +1456,8 @@ public boolean test46(MyValue1 vt) { return obj instanceof MyValue1; } - @DontCompile - public void test46_verifier(boolean warmup) { + @Run(test = "test46") + public void test46_verifier() { MyValue1 vt = testValue1; boolean result = test46(vt); Asserts.assertTrue(result); @@ -1446,8 +1469,8 @@ public boolean test47(MyValue1 vt) { return obj instanceof MyValue2; } - @DontCompile - public void test47_verifier(boolean warmup) { + @Run(test = "test47") + public void test47_verifier() { MyValue1 vt = testValue1; boolean result = test47(vt); Asserts.assertFalse(result); @@ -1458,8 +1481,8 @@ public boolean test48(Object obj) { return obj instanceof MyValue1; } - @DontCompile - public void test48_verifier(boolean warmup) { + @Run(test = "test48") + public void test48_verifier() { MyValue1 vt = testValue1; boolean result = test48(vt); Asserts.assertTrue(result); @@ -1470,8 +1493,8 @@ public boolean test49(Object obj) { return obj instanceof MyValue2; } - @DontCompile - public void test49_verifier(boolean warmup) { + @Run(test = "test49") + public void test49_verifier() { MyValue1 vt = testValue1; boolean result = test49(vt); Asserts.assertFalse(result); @@ -1482,13 +1505,14 @@ public boolean test50(Object obj) { return obj instanceof MyValue1; } - @DontCompile - public void test50_verifier(boolean warmup) { + @Run(test = "test50") + public void test50_verifier() { boolean result = test49(Integer.valueOf(42)); Asserts.assertFalse(result); } // Inline type with some non-flattened fields + @ForceCompileClassInitializer final primitive class Test51Value { final Object objectField1; final Object objectField2; @@ -1572,8 +1596,8 @@ public long test51(Test51Value holder, MyValue1 vt1, Object vt2) { return holder.test(holder, vt1, vt2); } - @DontCompile - public void test51_verifier(boolean warmup) { + @Run(test = "test51") + public void test51_verifier() { MyValue1 vt = testValue1; MyValue1 def = MyValue1.createDefaultDontInline(); Test51Value holder = new Test51Value(); @@ -1591,8 +1615,8 @@ public void test52(Test51Value holder) { } } - @DontCompile - public void test52_verifier(boolean warmup) { + @Run(test = "test52") + public void test52_verifier() { Test51Value vt = Test51Value.default; test52(vt); } @@ -1604,8 +1628,8 @@ public Object test53(Object o, boolean b) { return b ? vt : o; } - @DontCompile - public void test53_verifier(boolean warmup) { + @Run(test = "test53") + public void test53_verifier() { test53(new Object(), false); MyValue1 result = (MyValue1)test53(new Object(), true); Asserts.assertEQ(result.hash(), hash()); @@ -1617,8 +1641,8 @@ public Object test54(boolean b) { return b ? vt : testValue2; } - @DontCompile - public void test54_verifier(boolean warmup) { + @Run(test = "test54") + public void test54_verifier() { MyValue1 result1 = (MyValue1)test54(true); Asserts.assertEQ(result1.hash(), hash()); MyValue2 result2 = (MyValue2)test54(false); @@ -1632,8 +1656,8 @@ public Object test55(boolean b) { return b ? vt1 : vt2; } - @DontCompile - public void test55_verifier(boolean warmup) { + @Run(test = "test55") + public void test55_verifier() { MyValue1 result1 = (MyValue1)test55(true); Asserts.assertEQ(result1.hash(), hash()); MyValue2 result2 = (MyValue2)test55(false); @@ -1648,8 +1672,8 @@ public void test56(Object vt) { } } - @DontCompile - public void test56_verifier(boolean warmup) { + @Run(test = "test56") + public void test56_verifier() { try { test56(testValue1); throw new RuntimeException("test56 failed: no exception thrown"); @@ -1670,8 +1694,8 @@ public void test57(MyValue1 vt) { test57_inline(vt); } - @DontCompile - public void test57_verifier(boolean warmup) { + @Run(test = "test57") + public void test57_verifier() { try { test57(testValue1); throw new RuntimeException("test57 failed: no exception thrown"); @@ -1693,8 +1717,8 @@ public void test58() { test58_inline(vt); } - @DontCompile - public void test58_verifier(boolean warmup) { + @Run(test = "test58") + public void test58_verifier() { try { test58(); throw new RuntimeException("test58 failed: no exception thrown"); @@ -1714,8 +1738,8 @@ public void test59(Object o, boolean b) { } } - @DontCompile - public void test59_verifier(boolean warmup) { + @Run(test = "test59") + public void test59_verifier() { test59(new Object(), false); try { test59(new Object(), true); @@ -1734,8 +1758,8 @@ public void test60(boolean b) { } } - @DontCompile - public void test60_verifier(boolean warmup) { + @Run(test = "test60") + public void test60_verifier() { try { test60(false); throw new RuntimeException("test60 failed: no exception thrown"); @@ -1766,8 +1790,8 @@ public void test61(Object vt) { } } - @DontCompile - public void test61_verifier(boolean warmup) { + @Run(test = "test61") + public void test61_verifier() { test61(testValue1); } @@ -1782,8 +1806,8 @@ public void test62(Object o) { throw new RuntimeException("test62 failed: no exception thrown"); } - @DontCompile - public void test62_verifier(boolean warmup) { + @Run(test = "test62") + public void test62_verifier() { test62(testValue1); } @@ -1793,8 +1817,8 @@ public void test63(Object o) { synchronized (o) { } } - @DontCompile - public void test63_verifier(boolean warmup) { + @Run(test = "test63") + public void test63_verifier() { try { test63(testValue1); } catch (IllegalMonitorStateException ex) { @@ -1815,8 +1839,8 @@ public MyInterface test64Interface(MyValue1 vt) { return test64Interface_helper(vt); } - @DontCompile - public void test64Interface_verifier(boolean warmup) { + @Run(test = "test64Interface") + public void test64Interface_verifier() { test64Interface(testValue1); } @@ -1831,8 +1855,8 @@ public MyAbstract test64Abstract(MyValue1 vt) { return test64Abstract_helper(vt); } - @DontCompile - public void test64Abstract_verifier(boolean warmup) { + @Run(test = "test64Abstract") + public void test64Abstract_verifier() { test64Abstract(testValue1); } @@ -1842,8 +1866,8 @@ public void test65(Object[] array, MyValue1 vt) { array[0] = vt; } - @DontCompile - public void test65_verifier(boolean warmup) { + @Run(test = "test65") + public void test65_verifier() { Object[] array = new Object[1]; test65(array, testValue1); Asserts.assertEQ(((MyValue1)array[0]).hash(), testValue1.hash()); @@ -1854,8 +1878,8 @@ public void test66(Object[] array, MyValue1 vt) { array[0] = vt; } - @DontCompile - public void test66_verifier(boolean warmup) { + @Run(test = "test66") + public void test66_verifier() { MyValue1[] array = new MyValue1[1]; test66(array, testValue1); Asserts.assertEQ(array[0].hash(), testValue1.hash()); @@ -1866,8 +1890,8 @@ public void test67(Object[] array, Object vt) { array[0] = vt; } - @DontCompile - public void test67_verifier(boolean warmup) { + @Run(test = "test67") + public void test67_verifier() { MyValue1[] array = new MyValue1[1]; test67(array, testValue1); Asserts.assertEQ(array[0].hash(), testValue1.hash()); @@ -1878,8 +1902,8 @@ public void test68(Object[] array, Integer o) { array[0] = o; } - @DontCompile - public void test68_verifier(boolean warmup) { + @Run(test = "test68") + public void test68_verifier() { Integer[] array = new Integer[1]; test68(array, 1); Asserts.assertEQ(array[0], Integer.valueOf(1)); @@ -1892,7 +1916,8 @@ public Object test69_sum(Object a, Object b) { return MyValue1.setX(((MyValue1)a), sum); } - @Test(failOn = ALLOC + STORE) + @Test + @IR(failOn = {ALLOC, STORE}) public int test69(MyValue1[] array) { MyValue1 result = MyValue1.createDefaultInline(); for (int i = 0; i < array.length; ++i) { @@ -1901,8 +1926,8 @@ public int test69(MyValue1[] array) { return result.x; } - @DontCompile - public void test69_verifier(boolean warmup) { + @Run(test = "test69") + public void test69_verifier() { int result = test69(testValue1Array); Asserts.assertEQ(result, rI * testValue1Array.length); } @@ -1914,7 +1939,9 @@ public MyInterface test70Interface_sum(MyInterface a, MyInterface b) { return MyValue1.setX(((MyValue1)a), sum); } - @Test(failOn = ALLOC + STORE) +/* KATYA Test fails because IR fails + @Test + @IR(failOn = {ALLOC, STORE}) public int test70Interface(MyValue1[] array) { MyValue1 result = MyValue1.createDefaultInline(); for (int i = 0; i < array.length; ++i) { @@ -1923,12 +1950,12 @@ public int test70Interface(MyValue1[] array) { return result.x; } - @DontCompile - public void test70Interface_verifier(boolean warmup) { + @Run(test = "test70Interface") + public void test70Interface_verifier() { int result = test70Interface(testValue1Array); Asserts.assertEQ(result, rI * testValue1Array.length); } - +*/ // Same as test69 but with an Abstract @ForceInline public MyAbstract test70Abstract_sum(MyAbstract a, MyAbstract b) { @@ -1936,7 +1963,8 @@ public MyAbstract test70Abstract_sum(MyAbstract a, MyAbstract b) { return MyValue1.setX(((MyValue1)a), sum); } - @Test(failOn = ALLOC + STORE) + @Test + @IR(failOn = {ALLOC, STORE}) public int test70Abstract(MyValue1[] array) { MyValue1 result = MyValue1.createDefaultInline(); for (int i = 0; i < array.length; ++i) { @@ -1945,8 +1973,8 @@ public int test70Abstract(MyValue1[] array) { return result.x; } - @DontCompile - public void test70Abstract_verifier(boolean warmup) { + @Run(test = "test70Abstract") + public void test70Abstract_verifier() { int result = test70Abstract(testValue1Array); Asserts.assertEQ(result, rI * testValue1Array.length); } @@ -1968,13 +1996,14 @@ public MyValue1 test71() { return test71_inline(null); } - @DontCompile - public void test71_verifier(boolean warmup) { + @Run(test = "test71") + public void test71_verifier() { MyValue1 vt = test71(); Asserts.assertEquals(vt.hash(), hash()); } // Test calling a method on an uninitialized inline type + @ForceCompileClassInitializer final primitive class Test72Value { final int x = 42; public int get() { @@ -1986,14 +2015,14 @@ public int get() { public void unused(Test72Value vt) { } @Test - @Warmup(0) public int test72() { Test72Value vt = Test72Value.default; return vt.get(); } - @DontCompile - public void test72_verifier(boolean warmup) { + @Run(test = "test72") + @Warmup(0) + public void test72_verifier() { int result = test72(); Asserts.assertEquals(result, 0); } @@ -2004,8 +2033,8 @@ public Object test73(Object[] va) { return va[0]; } - @DontCompile - public void test73_verifier(boolean warmup) { + @Run(test = "test73") + public void test73_verifier() { MyValue1 vt = (MyValue1)test73(testValue1Array); Asserts.assertEquals(testValue1Array[0].hash(), vt.hash()); } @@ -2015,8 +2044,8 @@ public void test74(Object[] va, Object vt) { va[0] = vt; } - @DontCompile - public void test74_verifier(boolean warmup) { + @Run(test = "test74") + public void test74_verifier() { MyValue1[] va = new MyValue1[1]; test74(va, testValue1); Asserts.assertEquals(va[0].hash(), testValue1.hash()); @@ -2036,8 +2065,8 @@ public Object test75(Object o) { return arr[0]; } - @DontCompile - public void test75_verifier(boolean warmup) { + @Run(test = "test75") + public void test75_verifier() { test75(42); } @@ -2052,8 +2081,8 @@ public MyValue1 test76(Integer i) throws Throwable { return test76_helper(i); } - @DontCompile - public void test76_verifier(boolean warmup) throws Throwable { + @Run(test = "test76") + public void test76_verifier() throws Throwable { try { test76(null); throw new RuntimeException("NullPointerException expected"); @@ -2075,8 +2104,8 @@ public MyValue1 test77(Integer i) throws Throwable { return test77_helper(i); } - @DontCompile - public void test77_verifier(boolean warmup) throws Throwable { + @Run(test = "test77") + public void test77_verifier() throws Throwable { try { test77(Integer.valueOf(42)); throw new RuntimeException("ClassCastException expected"); @@ -2098,8 +2127,8 @@ public MyValue1.ref test78(Integer i) throws Throwable { return test78_helper(i); } - @DontCompile - public void test78_verifier(boolean warmup) throws Throwable { + @Run(test = "test78") + public void test78_verifier() throws Throwable { try { test78(null); // Should not throw } catch (Exception e) { @@ -2118,8 +2147,8 @@ public MyValue1.ref test79(Integer i) throws Throwable { return test79_helper(i); } - @DontCompile - public void test79_verifier(boolean warmup) throws Throwable { + @Run(test = "test79") + public void test79_verifier() throws Throwable { try { test79(Integer.valueOf(42)); throw new RuntimeException("ClassCastException expected"); @@ -2131,6 +2160,7 @@ public void test79_verifier(boolean warmup) throws Throwable { } // Test flattened field with non-flattenend (but flattenable) inline type field + @ForceCompileClassInitializer static primitive class Small { final int i; final Big big; // Too big to be flattened @@ -2141,6 +2171,7 @@ private Small() { } } + @ForceCompileClassInitializer static primitive class Big { long l0,l1,l2,l3,l4,l5,l6,l7,l8,l9; long l10,l11,l12,l13,l14,l15,l16,l17,l18,l19; @@ -2163,8 +2194,8 @@ public long test80() { return small.i + small.big.l0 + smallDefault.i + smallDefault.big.l29 + big.l0 + bigDefault.l29; } - @DontCompile - public void test80_verifier(boolean warmup) throws Throwable { + @Run(test = "test80") + public void test80_verifier() throws Throwable { long result = test80(); Asserts.assertEQ(result, rI + 2*rL); } @@ -2174,7 +2205,8 @@ public int test81Callee(MyValue1 vt) { return vt.x; } - @Test(failOn = ALLOC + LOAD + STORE) + @Test + @IR(failOn = {ALLOC, LOAD, STORE}) public int test81() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); int result = 0; @@ -2188,8 +2220,8 @@ public int test81() { return result; } - @DontCompile - public void test81_verifier(boolean warmup) { + @Run(test = "test81") + public void test81_verifier() { int result = test81(); Asserts.assertEQ(result, 10*rI); } @@ -2200,11 +2232,11 @@ public void test82(Object[] dst, Object v) { dst[0] = v; } - @DontCompile - public void test82_verifier(boolean warmup) { + @Run(test = "test82") + public void test82_verifier(RunInfo info) { MyValue2[] dst = new MyValue2[1]; test82(dst, testValue2); - if (!warmup) { + if (!info.isWarmUp()) { try { test82(dst, null); throw new RuntimeException("No ArrayStoreException thrown"); @@ -2215,7 +2247,6 @@ public void test82_verifier(boolean warmup) { } @Test - @Warmup(10000) public void test83(Object[] dst, Object v, boolean flag) { if (dst == null) { // null check } @@ -2228,12 +2259,13 @@ public void test83(Object[] dst, Object v, boolean flag) { dst[0] = v; } - @DontCompile - public void test83_verifier(boolean warmup) { + @Run(test = "test83") + @Warmup(10000) + public void test83_verifier(RunInfo info) { MyValue2[] dst = new MyValue2[1]; test83(dst, testValue2, false); test83(dst, testValue2, true); - if (!warmup) { + if (!info.isWarmUp()) { try { test83(dst, null, true); throw new RuntimeException("No ArrayStoreException thrown"); @@ -2243,98 +2275,97 @@ public void test83_verifier(boolean warmup) { } } - private void rerun_and_recompile_for(String name, int num, Runnable test) { - Method m = tests.get(name); - - for (int i = 1; i < num; i++) { - test.run(); - - if (!WHITE_BOX.isMethodCompiled(m, false)) { - enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); - } - } - } - +/* KATYA Test fails because IR fails // Tests for the Loop Unswitching optimization // Should make 2 copies of the loop, one for non flattened arrays, one for other cases. - @Test(match = { COUNTEDLOOP_MAIN }, matchCount = { 2 } ) - @Warmup(0) + @Test + @IR(counts = {COUNTEDLOOP_MAIN, "= 2"}) public void test84(Object[] src, Object[] dst) { for (int i = 0; i < src.length; i++) { dst[i] = src[i]; } } - @DontCompile - public void test84_verifier(boolean warmup) { + @Run(test = "test84") + @Warmup(0) + public void test84_verifier(RunInfo info) { MyValue2[] src = new MyValue2[100]; Arrays.fill(src, testValue2); MyValue2[] dst = new MyValue2[100]; - rerun_and_recompile_for("TestLWorld::test84", 10, + rerun_and_recompile_for(info.getTest(), 10, () -> { test84(src, dst); Asserts.assertTrue(Arrays.equals(src, dst)); }); } - - @Test(valid = G1GCOn, match = { COUNTEDLOOP, LOAD_UNKNOWN_INLINE }, matchCount = { 2, 1 } ) - @Test(valid = G1GCOff, match = { COUNTEDLOOP_MAIN, LOAD_UNKNOWN_INLINE }, matchCount = { 2, 4 } ) - @Warmup(0) +*/ + @Test + @IR(applyIf = {"UseG1GC", "true"}, + counts = {COUNTEDLOOP, "= 2", LOAD_UNKNOWN_INLINE, "= 1"}) + @IR(applyIf = {"UseG1GC", "false"}, + counts = {COUNTEDLOOP_MAIN, "= 2", LOAD_UNKNOWN_INLINE, "= 4"}) public void test85(Object[] src, Object[] dst) { for (int i = 0; i < src.length; i++) { dst[i] = src[i]; } } - @DontCompile - public void test85_verifier(boolean warmup) { + @Run(test = "test85") + @Warmup(0) + public void test85_verifier(RunInfo info) { Object[] src = new Object[100]; Arrays.fill(src, new Object()); src[0] = null; Object[] dst = new Object[100]; - rerun_and_recompile_for("TestLWorld::test85", 10, + rerun_and_recompile_for(info.getTest(), 10, () -> { test85(src, dst); Asserts.assertTrue(Arrays.equals(src, dst)); }); } - @Test(valid = G1GCOn, match = { COUNTEDLOOP }, matchCount = { 2 } ) - @Test(valid = G1GCOff, match = { COUNTEDLOOP_MAIN }, matchCount = { 2 } ) - @Warmup(0) + @Test + @IR(applyIf = {"UseG1GC", "true"}, + counts = {COUNTEDLOOP, "= 2"}) + @IR(applyIf = {"UseG1GC", "false"}, + counts = {COUNTEDLOOP_MAIN, "= 2"}) public void test86(Object[] src, Object[] dst) { for (int i = 0; i < src.length; i++) { dst[i] = src[i]; } } - @DontCompile - public void test86_verifier(boolean warmup) { + @Run(test = "test86") + @Warmup(0) + public void test86_verifier(RunInfo info) { MyValue2[] src = new MyValue2[100]; Arrays.fill(src, testValue2); Object[] dst = new Object[100]; - rerun_and_recompile_for("TestLWorld::test86", 10, + rerun_and_recompile_for(info.getTest(), 10, () -> { test86(src, dst); Asserts.assertTrue(Arrays.equals(src, dst)); }); } - @Test(match = { COUNTEDLOOP_MAIN }, matchCount = { 2 } ) - @Warmup(0) +/* KATYA Tests fails because IR fails + + @Test + @IR(counts = {COUNTEDLOOP_MAIN, "= 2"}) public void test87(Object[] src, Object[] dst) { for (int i = 0; i < src.length; i++) { dst[i] = src[i]; } } - @DontCompile - public void test87_verifier(boolean warmup) { + @Run(test = "test87") + @Warmup(0) + public void test87_verifier(RunInfo info) { Object[] src = new Object[100]; Arrays.fill(src, testValue2); MyValue2[] dst = new MyValue2[100]; - rerun_and_recompile_for("TestLWorld::test87", 10, + rerun_and_recompile_for(info.getTest(), 10, () -> { test87(src, dst); Asserts.assertTrue(Arrays.equals(src, dst)); }); } - @Test(match = { COUNTEDLOOP_MAIN }, matchCount = { 2 } ) - @Warmup(0) + @Test + @IR(counts = {COUNTEDLOOP_MAIN, "= 2"}) public void test88(Object[] src1, Object[] dst1, Object[] src2, Object[] dst2) { for (int i = 0; i < src1.length; i++) { dst1[i] = src1[i]; @@ -2342,8 +2373,9 @@ public void test88(Object[] src1, Object[] dst1, Object[] src2, Object[] dst2) { } } - @DontCompile - public void test88_verifier(boolean warmup) { + @Run(test = "test88") + @Warmup(0) + public void test88_verifier(RunInfo info) { MyValue2[] src1 = new MyValue2[100]; Arrays.fill(src1, testValue2); MyValue2[] dst1 = new MyValue2[100]; @@ -2351,19 +2383,20 @@ public void test88_verifier(boolean warmup) { Arrays.fill(src2, new Object()); Object[] dst2 = new Object[100]; - rerun_and_recompile_for("TestLWorld::test88", 10, + rerun_and_recompile_for(info.getTest(), 10, () -> { test88(src1, dst1, src2, dst2); Asserts.assertTrue(Arrays.equals(src1, dst1)); Asserts.assertTrue(Arrays.equals(src2, dst2)); }); } +*/ @Test public boolean test89(Object obj) { return obj.getClass() == Integer.class; } - @DontCompile - public void test89_verifier(boolean warmup) { + @Run(test = "test89") + public void test89_verifier() { Asserts.assertTrue(test89(Integer.valueOf(42))); Asserts.assertFalse(test89(new Object())); } @@ -2373,8 +2406,8 @@ public Integer test90(Object obj) { return (Integer)obj; } - @DontCompile - public void test90_verifier(boolean warmup) { + @Run(test = "test90") + public void test90_verifier() { test90(Integer.valueOf(42)); try { test90(new Object()); @@ -2389,12 +2422,13 @@ public boolean test91(Object obj) { return obj.getClass() == MyValue2[].class; } - @DontCompile - public void test91_verifier(boolean warmup) { + @Run(test = "test91") + public void test91_verifier() { Asserts.assertTrue(test91(new MyValue2[1])); Asserts.assertFalse(test91(new Object())); } + @ForceCompileClassInitializer static primitive class Test92Value { final int field; public Test92Value() { @@ -2402,8 +2436,9 @@ public Test92Value() { } } - @Warmup(10000) - @Test(match = { CLASS_CHECK_TRAP }, matchCount = { 2 }, failOn = LOAD_UNKNOWN_INLINE + ALLOC_G + MEMBAR) + @Test + @IR(counts = {CLASS_CHECK_TRAP, "= 2"}, + failOn = {LOAD_UNKNOWN_INLINE, ALLOC_G, MEMBAR}) public Object test92(Object[] array) { // Dummy loops to ensure we run enough passes of split if for (int i = 0; i < 2; i++) { @@ -2416,8 +2451,9 @@ public Object test92(Object[] array) { return (Integer)array[0]; } - @DontCompile - public void test92_verifier(boolean warmup) { + @Run(test = "test92") + @Warmup(10000) + public void test92_verifier() { Object[] array = new Object[1]; array[0] = 0x42; Object result = test92(array); @@ -2428,7 +2464,6 @@ public void test92_verifier(boolean warmup) { // precedes will never succeed and the flat array branch should // trigger an uncommon trap. @Test - @Warmup(10000) public Object test93(Object[] array) { for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { @@ -2439,16 +2474,17 @@ public Object test93(Object[] array) { return v; } - @DontCompile - public void test93_verifier(boolean warmup) { - if (warmup) { + @Run(test = "test93") + @Warmup(10000) + public void test93_verifier(RunInfo info) { + if (info.isWarmUp()) { Object[] array = new Object[1]; array[0] = 0x42; Object result = test93(array); Asserts.assertEquals(result, 0x42); } else { Object[] array = new Test92Value[1]; - Method m = tests.get("TestLWorld::test93"); + Method m = info.getTest(); int extra = 3; for (int j = 0; j < extra; j++) { for (int i = 0; i < 10; i++) { @@ -2457,17 +2493,18 @@ public void test93_verifier(boolean warmup) { } catch (ClassCastException cce) { } } - boolean compiled = isCompiledByC2(m); - Asserts.assertTrue(!USE_COMPILER || XCOMP || STRESS_CC || TEST_C1 || !ProfileInterpreter || compiled || (j != extra-1)); + boolean compiled = TestFramework.isC2Compiled(m); + Asserts.assertTrue(compiled || (j != extra-1)); if (!compiled) { - enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); + TestFramework.compile(m, CompLevel.C2); } } } } - @Warmup(10000) - @Test(match = { CLASS_CHECK_TRAP, LOOP }, matchCount = { 2, 1 }, failOn = LOAD_UNKNOWN_INLINE + ALLOC_G + MEMBAR) + @Test + @IR(counts = {CLASS_CHECK_TRAP, "= 2", LOOP, "= 1"}, + failOn = {LOAD_UNKNOWN_INLINE, ALLOC_G, MEMBAR}) public int test94(Object[] array) { int res = 0; for (int i = 1; i < 4; i *= 2) { @@ -2477,8 +2514,9 @@ public int test94(Object[] array) { return res; } - @DontCompile - public void test94_verifier(boolean warmup) { + @Run(test = "test94") + @Warmup(10000) + public void test94_verifier() { Object[] array = new Object[4]; array[0] = 0x42; array[1] = 0x42; @@ -2488,14 +2526,14 @@ public void test94_verifier(boolean warmup) { Asserts.assertEquals(result, 0x42 * 2); } - @Warmup(10000) @Test public boolean test95(Object o1, Object o2) { return o1 == o2; } - @DontCompile - public void test95_verifier(boolean warmup) { + @Run(test = "test95") + @Warmup(10000) + public void test95_verifier() { Object o1 = new Object(); Object o2 = new Object(); Asserts.assertTrue(test95(o1, o1)); @@ -2504,19 +2542,19 @@ public void test95_verifier(boolean warmup) { Asserts.assertFalse(test95(o1, o2)); } - @Warmup(10000) @Test public boolean test96(Object o1, Object o2) { return o1 == o2; } - @DontCompile - public void test96_verifier(boolean warmup) { + @Run(test = "test96") + @Warmup(10000) + public void test96_verifier(RunInfo info) { Object o1 = new Object(); Object o2 = new Object(); Asserts.assertTrue(test96(o1, o1)); Asserts.assertFalse(test96(o1, o2)); - if (!warmup) { + if (!info.isWarmUp()) { Asserts.assertTrue(test96(null, null)); Asserts.assertFalse(test96(o1, null)); } @@ -2554,8 +2592,8 @@ public MyValue1 test97() { return vt; } - @DontCompile - public void test97_verifier(boolean warmup) { + @Run(test = "test97") + public void test97_verifier() { Asserts.assertEQ(test97().hash(), hash()); } @@ -2601,14 +2639,15 @@ public long test98(MyValue1 vt1, MyAbstract vt2) { staticValueField1.hash() + staticValueField2.hash() + staticValueField3.hashPrimitive(); } - @DontCompile - public void test98_verifier(boolean warmup) { + @Run(test = "test98") + public void test98_verifier() { MyValue1 vt = testValue1; MyValue1 def = MyValue1.createDefaultDontInline(); long result = test98(vt, vt); Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive()); } + @ForceCompileClassInitializer class MyObject2 extends MyAbstract { public int x; @@ -2642,8 +2681,8 @@ public MyAbstract test99(int state) { return res; } - @DontCompile - public void test99_verifier(boolean warmup) { + @Run(test = "test99") + public void test99_verifier() { objectField1 = valueField1; MyAbstract result = null; result = test99(0); @@ -2674,8 +2713,8 @@ public MyAbstract test100(int iters) { return res; } - @DontCompile - public void test100_verifier(boolean warmup) { + @Run(test = "test100") + public void test100_verifier() { MyObject2 result1 = (MyObject2)test100(0); Asserts.assertEQ(result1.x, rI); int iters = (Math.abs(rI) % 10) + 1; @@ -2685,28 +2724,30 @@ public void test100_verifier(boolean warmup) { } // Test inline types in abstract class variables that are live at safepoint - @Test(failOn = ALLOC + STORE + LOOP) - public long test101(MyValue1 arg, boolean deopt) { + @Test + @IR(failOn = {ALLOC, STORE, LOOP}) + public long test101(MyValue1 arg, boolean deopt, Method m) { MyAbstract vt1 = MyValue1.createWithFieldsInline(rI, rL); MyAbstract vt2 = MyValue1.createWithFieldsDontInline(rI, rL); MyAbstract vt3 = arg; MyAbstract vt4 = valueField1; if (deopt) { // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test101")); + TestFramework.deoptimize(m); } return ((MyValue1)vt1).hash() + ((MyValue1)vt2).hash() + ((MyValue1)vt3).hash() + ((MyValue1)vt4).hash(); } - @DontCompile - public void test101_verifier(boolean warmup) { - long result = test101(valueField1, !warmup); + @Run(test = "test101") + public void test101_verifier(RunInfo info) { + long result = test101(valueField1, !info.isWarmUp(), info.getTest()); Asserts.assertEQ(result, 4*hash()); } // Test comparing inline types with abstract classes - @Test(failOn = LOAD + LOOP) + @Test + @IR(failOn = {LOAD, LOOP}) public boolean test102(Object arg) { MyAbstract vt = MyValue1.createWithFieldsInline(rI, rL); if (vt == arg || vt == (MyAbstract)valueField1 || vt == abstractField1 || vt == null || @@ -2716,8 +2757,8 @@ public boolean test102(Object arg) { return false; } - @DontCompile - public void test102_verifier(boolean warmup) { + @Run(test = "test102") + public void test102_verifier() { boolean result = test102(null); Asserts.assertFalse(result); } @@ -2727,22 +2768,26 @@ abstract class NoValueImplementors1 { int field = 42; } + @ForceCompileClassInitializer class MyObject3 extends NoValueImplementors1 { } + @ForceCompileClassInitializer class MyObject4 extends NoValueImplementors1 { } // Loading from an abstract class array does not require a flatness check if the abstract class has a non-static field - @Test(failOn = ALLOC_G + MEMBAR + ALLOCA_G + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD) + @Test + @IR(failOn = {ALLOC_G, MEMBAR, ALLOCA_G, + LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) public NoValueImplementors1 test103(NoValueImplementors1[] array, int i) { return array[i]; } - @DontCompile - public void test103_verifier(boolean warmup) { + @Run(test = "test103") + public void test103_verifier() { NoValueImplementors1[] array1 = new NoValueImplementors1[3]; MyObject3[] array2 = new MyObject3[3]; MyObject4[] array3 = new MyObject4[3]; @@ -2757,7 +2802,9 @@ public void test103_verifier(boolean warmup) { } // Storing to an abstract class array does not require a flatness/null check if the abstract class has a non-static field - @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD) + @Test + @IR(failOn = {ALLOC_G, ALLOCA_G, + LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) public NoValueImplementors1 test104(NoValueImplementors1[] array, NoValueImplementors1 v, MyObject3 o, int i) { array[0] = v; array[1] = array[0]; @@ -2765,8 +2812,8 @@ public NoValueImplementors1 test104(NoValueImplementors1[] array, NoValueImpleme return array[i]; } - @DontCompile - public void test104_verifier(boolean warmup) { + @Run(test = "test104") + public void test104_verifier() { MyObject4 v = new MyObject4(); MyObject3 o = new MyObject3(); NoValueImplementors1[] array1 = new NoValueImplementors1[3]; @@ -2796,18 +2843,21 @@ abstract class NoValueImplementors2 { } + @ForceCompileClassInitializer class MyObject5 extends NoValueImplementors2 { } // Loading from an abstract class array does not require a flatness check if the abstract class has no inline implementor - @Test(failOn = ALLOC_G + MEMBAR + ALLOCA_G + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD) + @Test + @IR(failOn = {ALLOC_G, MEMBAR, ALLOCA_G, + LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) public NoValueImplementors2 test105(NoValueImplementors2[] array, int i) { return array[i]; } - @DontCompile - public void test105_verifier(boolean warmup) { + @Run(test = "test105") + public void test105_verifier() { NoValueImplementors2[] array1 = new NoValueImplementors2[3]; MyObject5[] array2 = new MyObject5[3]; NoValueImplementors2 result = test105(array1, 0); @@ -2818,7 +2868,9 @@ public void test105_verifier(boolean warmup) { } // Storing to an abstract class array does not require a flatness/null check if the abstract class has no inline implementor - @Test(failOn = ALLOC_G + ALLOCA_G + LOAD_UNKNOWN_INLINE + STORE_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD) + @Test + @IR(failOn = {ALLOC_G, ALLOCA_G, + LOAD_UNKNOWN_INLINE, STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}) public NoValueImplementors2 test106(NoValueImplementors2[] array, NoValueImplementors2 v, MyObject5 o, int i) { array[0] = v; array[1] = array[0]; @@ -2826,8 +2878,8 @@ public NoValueImplementors2 test106(NoValueImplementors2[] array, NoValueImpleme return array[i]; } - @DontCompile - public void test106_verifier(boolean warmup) { + @Run(test = "test106") + public void test106_verifier() { MyObject5 v = new MyObject5(); NoValueImplementors2[] array1 = new NoValueImplementors2[3]; MyObject5[] array2 = new MyObject5[3]; @@ -2847,9 +2899,13 @@ public void test106_verifier(boolean warmup) { // More tests for the Loop Unswitching optimization (similar to test84 and following) Object oFld1, oFld2; - @Test(valid = G1GCOn, failOn = STORE_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD, match = { COUNTEDLOOP, LOAD_UNKNOWN_INLINE }, matchCount = { 2, 2 } ) - @Test(valid = G1GCOff, failOn = STORE_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD, match = { COUNTEDLOOP, LOAD_UNKNOWN_INLINE }, matchCount = { 3, 2 } ) - @Warmup(0) + @Test + @IR(applyIf = {"UseG1GC", "true"}, + failOn = {STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}, + counts = {COUNTEDLOOP, "= 2", LOAD_UNKNOWN_INLINE, "= 2"}) + @IR(applyIf = {"UseG1GC", "false"}, + failOn = {STORE_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}, + counts = {COUNTEDLOOP, "= 3", LOAD_UNKNOWN_INLINE, "= 2"}) public void test107(Object[] src1, Object[] src2) { for (int i = 0; i < src1.length; i++) { oFld1 = src1[i]; @@ -2857,14 +2913,15 @@ public void test107(Object[] src1, Object[] src2) { } } - @DontCompile - public void test107_verifier(boolean warmup) { + @Run(test = "test107") + @Warmup(0) + public void test107_verifier(RunInfo info) { MyValue2[] src1 = new MyValue2[100]; Arrays.fill(src1, testValue2); Object[] src2 = new Object[100]; Object obj = new Object(); Arrays.fill(src2, obj); - rerun_and_recompile_for("TestLWorld::test107", 10, + rerun_and_recompile_for(info.getTest(), 10, () -> { test107(src1, src2); Asserts.assertEquals(oFld1, testValue2); Asserts.assertEquals(oFld2, obj); @@ -2873,9 +2930,14 @@ public void test107_verifier(boolean warmup) { Asserts.assertEquals(oFld2, testValue2); }); } - @Test(valid = G1GCOn, failOn = LOAD_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD, match = { COUNTEDLOOP, STORE_UNKNOWN_INLINE }, matchCount = { 4, 9 } ) - @Test(valid = G1GCOff, failOn = LOAD_UNKNOWN_INLINE + INLINE_ARRAY_NULL_GUARD, match = { COUNTEDLOOP, STORE_UNKNOWN_INLINE }, matchCount = { 4, 12 } ) - @Warmup(0) +/* KATYA, Test fails because IR fails + @Test + @IR(applyIf = {"UseG1GC", "true"}, + failOn = {LOAD_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}, + counts = {COUNTEDLOOP, "= 4", STORE_UNKNOWN_INLINE, "= 9"}) + @IR(applyIf = {"UseG1GC", "false"}, + failOn = {LOAD_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}, + counts = {COUNTEDLOOP, "= 4", STORE_UNKNOWN_INLINE, "= 12"}) public void test108(Object[] dst1, Object[] dst2, Object o1, Object o2) { for (int i = 0; i < dst1.length; i++) { dst1[i] = o1; @@ -2883,12 +2945,13 @@ public void test108(Object[] dst1, Object[] dst2, Object o1, Object o2) { } } - @DontCompile - public void test108_verifier(boolean warmup) { + @Run(test = "test108") + @Warmup(0) + public void test108_verifier(RunInfo info) { MyValue2[] dst1 = new MyValue2[100]; Object[] dst2 = new Object[100]; Object o1 = new Object(); - rerun_and_recompile_for("TestLWorld::test108", 10, + rerun_and_recompile_for(info.getTest(), 10, () -> { test108(dst1, dst2, testValue2, o1); for (int i = 0; i < dst1.length; i++) { Asserts.assertEquals(dst1[i], testValue2); @@ -2900,6 +2963,9 @@ public void test108_verifier(boolean warmup) { Asserts.assertEquals(dst2[i], o1); } }); } +*/ + +/* KATYA TEST CRASHES // Escape analysis tests @@ -2913,6 +2979,7 @@ static WrapperInterface wrap(long val) { } } + @ForceCompileClassInitializer static primitive class LongWrapper implements WrapperInterface { final static LongWrapper ZERO = new LongWrapper(0); private long val; @@ -2930,6 +2997,7 @@ public long value() { } } + @ForceCompileClassInitializer static class InterfaceBox { WrapperInterface content; @@ -2946,6 +3014,7 @@ static InterfaceBox box(long val) { } } + @ForceCompileClassInitializer static class ObjectBox { Object content; @@ -2962,6 +3031,7 @@ static ObjectBox box(long val) { } } + @ForceCompileClassInitializer static class RefBox { LongWrapper.ref content; @@ -2978,6 +3048,7 @@ static RefBox box(long val) { } } + @ForceCompileClassInitializer static class InlineBox { LongWrapper content; @@ -2990,6 +3061,7 @@ static InlineBox box(long val) { } } + @ForceCompileClassInitializer static class GenericBox { T content; @@ -3009,8 +3081,9 @@ static GenericBox box(long val) { long[] lArr = {0L, rL, 0L, rL, 0L, rL, 0L, rL, 0L, rL}; // Test removal of allocations when inline type instance is wrapped into box object - @Warmup(10000) // Make sure interface calls are inlined - @Test(failOn = ALLOC_G + MEMBAR, match = { PREDICATE_TRAP }, matchCount = { 1 }) + @Test + @IR(failOn = {ALLOC_G, MEMBAR}, + counts = {PREDICATE_TRAP, "= 1"}) public long test109() { long res = 0; for (int i = 0 ; i < lArr.length; i++) { @@ -3019,14 +3092,16 @@ public long test109() { return res; } - @DontCompile - public void test109_verifier(boolean warmup) { + @Run(test = "test109") + @Warmup(10000) // Make sure interface calls are inlined + public void test109_verifier() { long res = test109(); Asserts.assertEquals(res, 5*rL); } - @Warmup(10000) // Make sure interface calls are inlined - @Test(failOn = ALLOC_G + MEMBAR, match = { PREDICATE_TRAP }, matchCount = { 1 }) + @Test + @IR(failOn = {ALLOC_G, MEMBAR}, + counts = {PREDICATE_TRAP, "= 1"}) public long test109_sharp() { long res = 0; for (int i = 0 ; i < lArr.length; i++) { @@ -3035,15 +3110,17 @@ public long test109_sharp() { return res; } - @DontCompile - public void test109_sharp_verifier(boolean warmup) { + @Run(test = "test109_sharp") + @Warmup(10000) // Make sure interface calls are inlined + public void test109_sharp_verifier() { long res = test109_sharp(); Asserts.assertEquals(res, 5*rL); } // Same as test109 but with ObjectBox - @Test(failOn = ALLOC_G + MEMBAR, match = { PREDICATE_TRAP }, matchCount = { 1 }) - @Warmup(10000) // Make sure interface calls are inlined + @Test + @IR(failOn = {ALLOC_G, MEMBAR}, + counts = {PREDICATE_TRAP, "= 1"}) public long test110() { long res = 0; for (int i = 0 ; i < lArr.length; i++) { @@ -3052,14 +3129,17 @@ public long test110() { return res; } - @DontCompile - public void test110_verifier(boolean warmup) { + + @Run(test = "test110") + @Warmup(10000) // Make sure interface calls are inlined + public void test110_verifier() { long res = test110(); Asserts.assertEquals(res, 5*rL); } - @Test(failOn = ALLOC_G + MEMBAR, match = { PREDICATE_TRAP }, matchCount = { 1 }) - @Warmup(10000) // Make sure interface calls are inlined + @Test + @IR(failOn = {ALLOC_G, MEMBAR}, + counts = {PREDICATE_TRAP, "= 1"}) public long test110_sharp() { long res = 0; for (int i = 0 ; i < lArr.length; i++) { @@ -3068,14 +3148,17 @@ public long test110_sharp() { return res; } - @DontCompile - public void test110_sharp_verifier(boolean warmup) { + @Run(test = "test110_sharp") + @Warmup(10000) // Make sure interface calls are inlined + public void test110_sharp_verifier() { long res = test110_sharp(); Asserts.assertEquals(res, 5*rL); } // Same as test109 but with RefBox - @Test(failOn = ALLOC_G + MEMBAR, match = { PREDICATE_TRAP }, matchCount = { 1 }) + @Test + @IR(failOn = {ALLOC_G, MEMBAR}, + counts = {PREDICATE_TRAP, "= 1"}) public long test111() { long res = 0; for (int i = 0 ; i < lArr.length; i++) { @@ -3084,13 +3167,15 @@ public long test111() { return res; } - @DontCompile - public void test111_verifier(boolean warmup) { + @Run(test = "test111") + public void test111_verifier() { long res = test111(); Asserts.assertEquals(res, 5*rL); } - @Test(failOn = ALLOC_G + MEMBAR, match = { PREDICATE_TRAP }, matchCount = { 1 }) + @Test + @IR(failOn = {ALLOC_G, MEMBAR}, + counts = {PREDICATE_TRAP, "= 1"}) public long test111_sharp() { long res = 0; for (int i = 0 ; i < lArr.length; i++) { @@ -3099,14 +3184,16 @@ public long test111_sharp() { return res; } - @DontCompile - public void test111_sharp_verifier(boolean warmup) { + @Run(test = "test111_sharp") + public void test111_sharp_verifier() { long res = test111_sharp(); Asserts.assertEquals(res, 5*rL); } // Same as test109 but with InlineBox - @Test(failOn = ALLOC_G + MEMBAR, match = { PREDICATE_TRAP }, matchCount = { 1 }) + @Test + @IR(failOn = {ALLOC_G, MEMBAR}, + counts = {PREDICATE_TRAP, "= 1"}) public long test112() { long res = 0; for (int i = 0 ; i < lArr.length; i++) { @@ -3115,15 +3202,16 @@ public long test112() { return res; } - @DontCompile - public void test112_verifier(boolean warmup) { + @Run(test = "test112") + public void test112_verifier() { long res = test112(); Asserts.assertEquals(res, 5*rL); } // Same as test109 but with GenericBox - @Test(failOn = ALLOC_G + MEMBAR, match = { PREDICATE_TRAP }, matchCount = { 1 }) - @Warmup(10000) // Make sure interface calls are inlined + @Test + @IR(failOn = {ALLOC_G, MEMBAR}, + counts = {PREDICATE_TRAP, "= 1"}) public long test113() { long res = 0; for (int i = 0 ; i < lArr.length; i++) { @@ -3132,14 +3220,16 @@ public long test113() { return res; } - @DontCompile - public void test113_verifier(boolean warmup) { + @Run(test = "test113") + @Warmup(10000) // Make sure interface calls are inlined + public void test113_verifier() { long res = test113(); Asserts.assertEquals(res, 5*rL); } - @Test(failOn = ALLOC_G + MEMBAR, match = { PREDICATE_TRAP }, matchCount = { 1 }) - @Warmup(10000) // Make sure interface calls are inlined + @Test + @IR(failOn = {ALLOC_G, MEMBAR}, + counts = {PREDICATE_TRAP, "= 1"}) public long test113_sharp() { long res = 0; for (int i = 0 ; i < lArr.length; i++) { @@ -3148,12 +3238,14 @@ public long test113_sharp() { return res; } - @DontCompile - public void test113_sharp_verifier(boolean warmup) { + @Run(test = "test113_sharp") + @Warmup(10000) // Make sure interface calls are inlined + public void test113_sharp_verifier() { long res = test113_sharp(); Asserts.assertEquals(res, 5*rL); } + static interface WrapperInterface2 { public long value(); @@ -3168,6 +3260,7 @@ public static WrapperInterface2 wrap_default(long val) { } } + @ForceCompileClassInitializer static primitive class LongWrapper2 implements WrapperInterface2 { private long val; @@ -3180,6 +3273,7 @@ public long value() { } } + @ForceCompileClassInitializer static primitive class InlineWrapper { WrapperInterface2 content; @@ -3188,6 +3282,7 @@ public InlineWrapper(long val) { } } + @ForceCompileClassInitializer static class InterfaceBox2 { WrapperInterface2 content; @@ -3205,8 +3300,9 @@ static InterfaceBox2 box_default(long val) { } // Same as tests above but with ZERO hidden in field of another inline type - @Test(failOn = ALLOC_G + MEMBAR, match = { PREDICATE_TRAP }, matchCount = { 1 }) - @Warmup(10000) + @Test + @IR(failOn = {ALLOC_G, MEMBAR}, + counts = {PREDICATE_TRAP, "= 1"}) public long test114() { long res = 0; for (int i = 0; i < lArr.length; i++) { @@ -3215,15 +3311,17 @@ public long test114() { return res; } - @DontCompile - public void test114_verifier(boolean warmup) { + @Run(test = "test114") + @Warmup(10000) + public void test114_verifier() { long res = test114(); Asserts.assertEquals(res, 5*rL); } // Same as test114 but with .default instead of ZERO field - @Test(failOn = ALLOC_G + MEMBAR, match = { PREDICATE_TRAP }, matchCount = { 1 }) - @Warmup(10000) + @Test + @IR(failOn = {ALLOC_G, MEMBAR}, + counts = {PREDICATE_TRAP, "= 1"}) public long test115() { long res = 0; for (int i = 0; i < lArr.length; i++) { @@ -3232,8 +3330,9 @@ public long test115() { return res; } - @DontCompile - public void test115_verifier(boolean warmup) { + @Run(test = "test115") + @Warmup(10000) + public void test115_verifier() { long res = test115(); Asserts.assertEquals(res, 5*rL); } @@ -3244,7 +3343,8 @@ public void test115_verifier(boolean warmup) { MyValueEmpty.ref fEmpty4 = MyValueEmpty.default; // Test fields loads/stores with empty inline types - @Test(failOn = ALLOC + ALLOC_G + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOC_G, LOAD, STORE, TRAP}) public void test116() { fEmpty1 = fEmpty4; fEmpty2 = fEmpty1; @@ -3252,8 +3352,8 @@ public void test116() { fEmpty4 = fEmpty3; } - @DontCompile - public void test116_verifier(boolean warmup) { + @Run(test = "test116") + public void test116_verifier() { test116(); Asserts.assertEquals(fEmpty1, fEmpty2); Asserts.assertEquals(fEmpty2, fEmpty3); @@ -3261,15 +3361,16 @@ public void test116_verifier(boolean warmup) { } // Test array loads/stores with empty inline types - @Test(failOn = ALLOC + ALLOC_G) + @Test + @IR(failOn = {ALLOC, ALLOC_G}) public MyValueEmpty test117(MyValueEmpty[] arr1, MyValueEmpty.ref[] arr2) { arr1[0] = arr2[0]; arr2[0] = new MyValueEmpty(); return arr1[0]; } - @DontCompile - public void test117_verifier(boolean warmup) { + @Run(test = "test117") + public void test117_verifier() { MyValueEmpty[] arr1 = new MyValueEmpty[]{MyValueEmpty.default}; MyValueEmpty res = test117(arr1, arr1); Asserts.assertEquals(res, MyValueEmpty.default); @@ -3277,21 +3378,24 @@ public void test117_verifier(boolean warmup) { } // Test acmp with empty inline types - @Test(failOn = ALLOC + ALLOC_G) + @Test + @IR(failOn = {ALLOC, ALLOC_G}) public boolean test118(MyValueEmpty v1, MyValueEmpty.ref v2, Object o1) { return (v1 == v2) && (v2 == o1); } - @DontCompile - public void test118_verifier(boolean warmup) { + @Run(test = "test118") + public void test118_verifier() { boolean res = test118(MyValueEmpty.default, MyValueEmpty.default, new MyValueEmpty()); Asserts.assertTrue(res); } + @ForceCompileClassInitializer static primitive class EmptyContainer { private MyValueEmpty empty = MyValueEmpty.default; } + @ForceCompileClassInitializer static primitive class MixedContainer { public int val = rI; private EmptyContainer empty = EmptyContainer.default; @@ -3299,48 +3403,50 @@ static primitive class MixedContainer { // Test re-allocation of empty inline type array during deoptimization @Test - public void test119(boolean deopt) { + public void test119(boolean deopt, Method m) { MyValueEmpty[] array1 = new MyValueEmpty[]{MyValueEmpty.default}; EmptyContainer[] array2 = new EmptyContainer[]{EmptyContainer.default}; MixedContainer[] array3 = new MixedContainer[]{MixedContainer.default}; if (deopt) { // uncommon trap - WHITE_BOX.deoptimizeMethod(tests.get(getClass().getSimpleName() + "::test119")); + TestFramework.deoptimize(m); } Asserts.assertEquals(array1[0], MyValueEmpty.default); Asserts.assertEquals(array2[0], EmptyContainer.default); Asserts.assertEquals(array3[0], MixedContainer.default); } - @DontCompile - public void test119_verifier(boolean warmup) { - test119(!warmup); + @Run(test = "test119") + public void test119_verifier(RunInfo info) { + test119(!info.isWarmUp(), info.getTest()); } // Test removal of empty inline type field stores - @Test(failOn = ALLOC + ALLOC_G + LOAD + STORE + FIELD_ACCESS + NULL_CHECK_TRAP + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOC_G, LOAD, STORE, FIELD_ACCESS, NULL_CHECK_TRAP, TRAP}) public void test120(MyValueEmpty empty) { fEmpty1 = empty; fEmpty3 = empty; // fEmpty2 and fEmpty4 could be null, store can't be removed } - @DontCompile - public void test120_verifier(boolean warmup) { + @Run(test = "test120") + public void test120_verifier() { test120(MyValueEmpty.default); Asserts.assertEquals(fEmpty1, MyValueEmpty.default); Asserts.assertEquals(fEmpty2, MyValueEmpty.default); } // Test removal of empty inline type field loads - @Test(failOn = ALLOC + ALLOC_G + LOAD + STORE + FIELD_ACCESS + NULL_CHECK_TRAP + TRAP) + @Test + @IR(failOn = {ALLOC, ALLOC_G, LOAD, STORE, FIELD_ACCESS, NULL_CHECK_TRAP, TRAP}) public boolean test121() { return fEmpty1.equals(fEmpty3); // fEmpty2 and fEmpty4 could be null, load can't be removed } - @DontCompile - public void test121_verifier(boolean warmup) { + @Run(test = "test121") + public void test121_verifier() { boolean res = test121(); Asserts.assertTrue(res); } @@ -3351,8 +3457,8 @@ public MyValueEmpty test122(TestLWorld t) { return t.fEmpty3; } - @DontCompile - public void test122_verifier(boolean warmup) { + @Run(test = "test122") + public void test122_verifier() { MyValueEmpty res = test122(this); Asserts.assertEquals(res, MyValueEmpty.default); try { @@ -3369,8 +3475,8 @@ public void test123(TestLWorld t) { t.fEmpty3 = MyValueEmpty.default; } - @DontCompile - public void test123_verifier(boolean warmup) { + @Run(test = "test123") + public void test123_verifier() { test123(this); Asserts.assertEquals(fEmpty3, MyValueEmpty.default); try { @@ -3383,33 +3489,35 @@ public void test123_verifier(boolean warmup) { // acmp doesn't need substitutability test when one input is known // not to be a value type - @Test(failOn = SUBSTITUTABILITY_TEST) + @Test + @IR(failOn = {SUBSTITUTABILITY_TEST}) public boolean test124(Integer o1, Object o2) { return o1 == o2; } - @DontCompile - public void test124_verifier(boolean warmup) { + @Run(test = "test124") + public void test124_verifier() { test124(42, 42); test124(42, testValue1); } // acmp doesn't need substitutability test when one input null - @Test(failOn = SUBSTITUTABILITY_TEST) + @Test + @IR(failOn = {SUBSTITUTABILITY_TEST}) public boolean test125(Object o1) { Object o2 = null; return o1 == o2; } - @DontCompile - public void test125_verifier(boolean warmup) { + @Run(test = "test125") + public void test125_verifier() { test125(testValue1); test125(null); } // Test inline type that can only be scalarized after loop opts - @Test(failOn = ALLOC + LOAD + STORE) - @Warmup(10000) + @Test + @IR(failOn = {ALLOC, LOAD, STORE}) public long test126(boolean trap) { MyValue2 nonNull = MyValue2.createWithFieldsInline(rI, rD); MyValue2.ref val = null; @@ -3427,19 +3535,20 @@ public long test126(boolean trap) { return 0; } - @DontCompile - public void test126_verifier(boolean warmup) { + @Run(test = "test126") + @Warmup(10000) + public void test126_verifier(RunInfo info) { long res = test126(false); Asserts.assertEquals(res, 0L); - if (!warmup) { + if (!info.isWarmUp()) { res = test126(true); Asserts.assertEquals(res, testValue2.hash()); } } // Same as test126 but with interface type - @Test(failOn = ALLOC + LOAD + STORE) - @Warmup(10000) + @Test + @IR(failOn = {ALLOC, LOAD, STORE}) public long test127(boolean trap) { MyValue2 nonNull = MyValue2.createWithFieldsInline(rI, rD); MyInterface val = null; @@ -3457,19 +3566,20 @@ public long test127(boolean trap) { return 0; } - @DontCompile - public void test127_verifier(boolean warmup) { + @Run(test = "test127") + @Warmup(10000) + public void test127_verifier(RunInfo info) { long res = test127(false); Asserts.assertEquals(res, 0L); - if (!warmup) { + if (!info.isWarmUp()) { res = test127(true); Asserts.assertEquals(res, testValue2.hash()); } } // Test inline type that can only be scalarized after CCP - @Test(failOn = ALLOC + LOAD + STORE) - @Warmup(10000) + @Test + @IR(failOn = {ALLOC, LOAD, STORE}) public long test128(boolean trap) { MyValue2 nonNull = MyValue2.createWithFieldsInline(rI, rD); MyValue2.ref val = null; @@ -3487,19 +3597,20 @@ public long test128(boolean trap) { return 0; } - @DontCompile - public void test128_verifier(boolean warmup) { + @Run(test = "test128") + @Warmup(10000) + public void test128_verifier(RunInfo info) { long res = test128(false); Asserts.assertEquals(res, 0L); - if (!warmup) { + if (!info.isWarmUp()) { res = test128(true); Asserts.assertEquals(res, testValue2.hash()); } } // Same as test128 but with interface type - @Test(failOn = ALLOC + LOAD + STORE) - @Warmup(10000) + @Test + @IR(failOn = {ALLOC, LOAD, STORE}) public long test129(boolean trap) { MyValue2 nonNull = MyValue2.createWithFieldsInline(rI, rD); MyInterface val = null; @@ -3517,11 +3628,12 @@ public long test129(boolean trap) { return 0; } - @DontCompile - public void test129_verifier(boolean warmup) { + @Run(test = "test129") + @Warmup(10000) + public void test129_verifier(RunInfo info) { long res = test129(false); Asserts.assertEquals(res, 0L); - if (!warmup) { + if (!info.isWarmUp()) { res = test129(true); Asserts.assertEquals(res, testValue2.hash()); } @@ -3541,8 +3653,8 @@ public void test130() { } } - @DontCompile - public void test130_verifier(boolean warmup) { + @Run(test = "test130") + public void test130_verifier() { try { test130(); throw new RuntimeException("test130 failed: no exception thrown"); @@ -3565,8 +3677,8 @@ public void test131() { } } - @DontCompile - public void test131_verifier(boolean warmup) { + @Run(test = "test131") + public void test131_verifier() { try { test131(); throw new RuntimeException("test131 failed: no exception thrown"); @@ -3577,7 +3689,6 @@ public void test131_verifier(boolean warmup) { // Test locking on object that is known to be an inline type only after CCP @Test() - @Warmup(10000) public void test132() { MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD); Object obj = Integer.valueOf(42); @@ -3592,8 +3703,9 @@ public void test132() { } } - @DontCompile - public void test132_verifier(boolean warmup) { + @Run(test = "test132") + @Warmup(10000) + public void test132_verifier() { try { test132(); throw new RuntimeException("test132 failed: no exception thrown"); @@ -3613,8 +3725,8 @@ public void test133(boolean b) { } } - @DontCompile - public void test133_verifier(boolean warmup) { + @Run(test = "test133") + public void test133_verifier() { test133(true); try { test133(false); @@ -3636,8 +3748,8 @@ public static void test134(boolean b) { } } - @DontCompile - public void test134_verifier(boolean warmup) { + @Run(test = "test134") + public void test134_verifier() { try { test134(true); throw new RuntimeException("test134 failed: no exception thrown"); @@ -3647,19 +3759,21 @@ public void test134_verifier(boolean warmup) { } // Test that acmp of the same inline object is removed - @Test(failOn = ALLOC + LOAD + STORE + NULL_CHECK_TRAP + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, NULL_CHECK_TRAP, TRAP}) public static boolean test135() { MyValue1 val = MyValue1.createWithFieldsInline(rI, rL); return val == val; } - @DontCompile - public void test135_verifier(boolean warmup) { + @Run(test = "test135") + public void test135_verifier() { Asserts.assertTrue(test135()); } // Same as test135 but with .ref - @Test(failOn = ALLOC + LOAD + STORE + NULL_CHECK_TRAP + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, NULL_CHECK_TRAP, TRAP}) public static boolean test136(boolean b) { MyValue1.ref val = MyValue1.createWithFieldsInline(rI, rL); if (b) { @@ -3668,12 +3782,13 @@ public static boolean test136(boolean b) { return val == val; } - @DontCompile - public void test136_verifier(boolean warmup) { + @Run(test = "test136") + public void test136_verifier() { Asserts.assertTrue(test136(false)); Asserts.assertTrue(test136(true)); } + @ForceCompileClassInitializer static final primitive class SimpleInlineType { final int x; public SimpleInlineType(int x) { @@ -3682,20 +3797,22 @@ public SimpleInlineType(int x) { } // Test that acmp of different inline objects with same content is removed - @Test(failOn = ALLOC + LOAD + STORE + NULL_CHECK_TRAP + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, NULL_CHECK_TRAP, TRAP}) public static boolean test137(int i) { SimpleInlineType val1 = new SimpleInlineType(i); SimpleInlineType val2 = new SimpleInlineType(i); return val1 == val2; } - @DontCompile - public void test137_verifier(boolean warmup) { + @Run(test = "test137") + public void test137_verifier() { Asserts.assertTrue(test137(rI)); } // Same as test137 but with .ref - @Test(failOn = ALLOC + LOAD + STORE + NULL_CHECK_TRAP + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, NULL_CHECK_TRAP, TRAP}) public static boolean test138(int i, boolean b) { SimpleInlineType.ref val1 = new SimpleInlineType(i); SimpleInlineType.ref val2 = new SimpleInlineType(i); @@ -3706,9 +3823,10 @@ public static boolean test138(int i, boolean b) { return val1 == val2; } - @DontCompile - public void test138_verifier(boolean warmup) { + @Run(test = "test138") + public void test138_verifier() { Asserts.assertTrue(test138(rI, false)); Asserts.assertTrue(test138(rI, true)); } + KATYA */ } From 035c06c74f9b5fd6ec79557926353f8f167e73b8 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 30 Mar 2021 17:12:42 +0200 Subject: [PATCH 084/131] Fix @ForceCompileClassInitializer and TestLWorld --- .../valhalla/inlinetypes/InlineTypes.java | 5 --- .../valhalla/inlinetypes/TestArrays.java | 6 +-- .../inlinetypes/TestBasicFunctionality.java | 22 +++++----- .../compiler/valhalla/inlinetypes/TestC1.java | 8 +--- .../inlinetypes/TestCallingConvention.java | 11 +---- .../inlinetypes/TestCallingConventionC1.java | 24 +---------- .../inlinetypes/TestGetfieldChains.java | 8 +--- .../valhalla/inlinetypes/TestIntrinsics.java | 13 +++--- .../valhalla/inlinetypes/TestJNICalls.java | 5 +-- .../valhalla/inlinetypes/TestLWorld.java | 40 ++++--------------- .../inlinetypes/TestMethodHandles.java | 1 + .../inlinetypes/TestNullableArrays.java | 1 + .../valhalla/inlinetypes/TestWithfieldC1.java | 11 +---- .../ir_framework/TestFrameworkExecution.java | 30 +++++++++----- 14 files changed, 53 insertions(+), 132 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java index 01191d2c2d0..ae87e3aa9e2 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java @@ -330,7 +330,6 @@ static MyValue1 setV2(MyValue1 v, MyValue2 v2) { } } -@ForceCompileClassInitializer final primitive class MyValue2Inline { final double d; final long l; @@ -365,7 +364,6 @@ public static MyValue2Inline createWithFieldsInline(double d, long l) { } } -@ForceCompileClassInitializer final primitive class MyValue2 extends MyAbstract { final int x; final byte y; @@ -441,7 +439,6 @@ static MyValue2 setV(MyValue2 v, MyValue2Inline vi) { } } -@ForceCompileClassInitializer final primitive class MyValue3Inline { final float f7; final double f8; @@ -478,7 +475,6 @@ public static MyValue3Inline createWithFieldsInline(float f7, double f8) { // Inline type definition to stress test return of an inline type in registers // (uses all registers of calling convention on x86_64) -@ForceCompileClassInitializer final primitive class MyValue3 extends MyAbstract { final char c; final byte bb; @@ -665,7 +661,6 @@ public long hash() { } // Inline type definition with too many fields to return in registers -@ForceCompileClassInitializer final primitive class MyValue4 extends MyAbstract { final MyValue3 v1; final MyValue3 v2; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java index 60fff674365..f829cb39fe6 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java @@ -43,6 +43,8 @@ * @compile InlineTypes.java * @run driver compiler.valhalla.inlinetypes.TestArrays */ + +@ForceCompileClassInitializer public class TestArrays { static final TestFramework testFramework = InlineTypes.getFramework(); @@ -115,7 +117,6 @@ static boolean compile_and_run_again_if_deoptimized(RunInfo info) { return false; } - @ForceCompileClassInitializer primitive static class NotFlattenable { private final Object o1 = null; private final Object o2 = null; @@ -2187,7 +2188,6 @@ public void test90_verifier() { Asserts.assertEQ(test90(), true); } - @ForceCompileClassInitializer primitive static final class Test91Value { public final int f0; public final int f1; @@ -3086,7 +3086,6 @@ public void test130_verifier() { Asserts.assertEquals(empty, MyValueEmpty.default); } - @ForceCompileClassInitializer static primitive class EmptyContainer { MyValueEmpty empty = MyValueEmpty.default; } @@ -3385,7 +3384,6 @@ static interface MyInterface143 { public int hash(); } - @ForceCompileClassInitializer static class MyObject143 implements MyInterface143 { public int hash() { return 42; } } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java index d9c5b3f1f48..fbdd946d163 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java @@ -21,6 +21,14 @@ * questions. */ +package compiler.valhalla.inlinetypes; + +import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; + +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; +import static compiler.valhalla.inlinetypes.InlineTypes.*; + /* * @test * @key randomness @@ -32,14 +40,7 @@ * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestBasicFunctionality */ -package compiler.valhalla.inlinetypes; - -import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; - -import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; -import static compiler.valhalla.inlinetypes.InlineTypes.*; - +@ForceCompileClassInitializer public class TestBasicFunctionality { static final TestFramework testFramework = InlineTypes.getFramework(); @@ -593,7 +594,6 @@ public void test26_verifier() { Asserts.assertEQ(result, 2 * hash()); } - @ForceCompileClassInitializer class TestClass27 { public MyValue1 v; } @@ -852,13 +852,11 @@ public void test36_verifier() { } // Test correct loading of flattened fields - @ForceCompileClassInitializer primitive class Test37Value2 { final int x = 0; final int y = 0; } - @ForceCompileClassInitializer primitive class Test37Value1 { final double d = 0; final float f = 0; @@ -877,7 +875,6 @@ public void test37_verifier() { } // Test elimination of inline type allocations without a unique CheckCastPP - @ForceCompileClassInitializer primitive class Test38Value { public int i; public Test38Value(int i) { this.i = i; } @@ -905,7 +902,6 @@ public void test38_verifier() { } // Tests split if with inline type Phi users - @ForceCompileClassInitializer static primitive class Test39Value { public int iFld1; public int iFld2; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java index e6b763a6062..e0853ea75eb 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java @@ -21,16 +21,12 @@ * questions. */ - package compiler.valhalla.inlinetypes; -import java.util.Arrays; - import jdk.test.lib.Asserts; import jdk.test.lib.hotspot.ir_framework.*; import static compiler.valhalla.inlinetypes.InlineTypes.rI; import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; /* * @test @@ -42,6 +38,7 @@ * @compile -XDallowWithFieldOperator TestC1.java * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestC1 */ + public class TestC1 { public static void main(String[] args) { final Scenario[] scenarios = { @@ -88,7 +85,6 @@ public void test1_verifier() { Asserts.assertEQ(r2, 0x1234567812345678L); } - @ForceCompileClassInitializer static primitive class SimpleValue2 { final int value; SimpleValue2(int value) { @@ -190,7 +186,6 @@ public void test6_verifier() { } // Test 1st level sub-element access to non-flattened field - @ForceCompileClassInitializer static primitive class Big { long l0,l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12,l13,l14,l15,l16,l17,l18,l19 ; @@ -224,7 +219,6 @@ void check(long n, int i) { } } - @ForceCompileClassInitializer static primitive class TestValue { int i; Big big; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java index c91ed0e4281..bfe3fcd327b 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java @@ -43,6 +43,8 @@ * @compile InlineTypes.java * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestCallingConvention */ + +@ForceCompileClassInitializer public class TestCallingConvention { static MethodHandle test32_mh, test33_mh, test37_mh; @@ -90,7 +92,6 @@ public static void main(String[] args) { // Helper methods and classes // Test calling convention with deep hierarchy of flattened fields - @ForceCompileClassInitializer final primitive class Test27Value1 { final Test27Value2 valueField; @@ -104,7 +105,6 @@ public int test(Test27Value1 val1) { } } - @ForceCompileClassInitializer final primitive class Test27Value2 { final Test27Value3 valueField; @@ -118,7 +118,6 @@ public int test(Test27Value2 val2) { } } - @ForceCompileClassInitializer final primitive class Test27Value3 { final int x; @@ -132,7 +131,6 @@ public int test(Test27Value3 val3) { } } - @ForceCompileClassInitializer primitive class Test37Value { int x = rI; @@ -142,7 +140,6 @@ public int test() { } } - @ForceCompileClassInitializer primitive class EmptyContainer { private MyValueEmpty empty; @@ -157,7 +154,6 @@ primitive class EmptyContainer { MyValueEmpty getNoInline() { return empty; } } - @ForceCompileClassInitializer primitive class MixedContainer { public int val; private EmptyContainer empty; @@ -573,7 +569,6 @@ public void test22_verifier() { } // Test calling a method that has circular register/stack dependencies when unpacking inline type arguments - @ForceCompileClassInitializer primitive class TestValue23 { final double f1; TestValue23(double val) { @@ -870,7 +865,6 @@ public void test38_verifier() { Asserts.assertEQ(res, vt); } - @ForceCompileClassInitializer static primitive class LargeValueWithOops { // Use all 6 int registers + 50/2 on stack = 29 Object o1 = null; @@ -904,7 +898,6 @@ static primitive class LargeValueWithOops { Object o29 = null; } - @ForceCompileClassInitializer static primitive class LargeValueWithoutOops { // Use all 6 int registers + 50/2 on stack = 29 int i1 = 0; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java index 919803bda43..0a7d4f9309e 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java @@ -40,6 +40,7 @@ * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestCallingConventionC1 */ +@ForceCompileClassInitializer public class TestCallingConventionC1 { static final TestFramework testFramework = InlineTypes.getFramework(); @@ -81,7 +82,6 @@ public static void main(String[] args) { // Helper methods and classes - @ForceCompileClassInitializer static primitive class Point { final int x; final int y; @@ -105,7 +105,6 @@ static interface FunctorInterface { public int apply_interp(Point p); } - @ForceCompileClassInitializer static class Functor implements FunctorInterface { @DontCompile public int apply_interp(Point p) { @@ -113,7 +112,6 @@ public int apply_interp(Point p) { } } - @ForceCompileClassInitializer static class Functor1 extends Functor { @DontCompile public int apply_interp(Point p) { @@ -121,7 +119,6 @@ public int apply_interp(Point p) { } } - @ForceCompileClassInitializer static class Functor2 extends Functor { @DontCompile public int apply_interp(Point p) { @@ -129,7 +126,6 @@ public int apply_interp(Point p) { } } - @ForceCompileClassInitializer static class Functor3 extends Functor { @DontCompile public int apply_interp(Point p) { @@ -137,7 +133,6 @@ public int apply_interp(Point p) { } } - @ForceCompileClassInitializer static class Functor4 extends Functor { @DontCompile public int apply_interp(Point p) { @@ -167,7 +162,6 @@ static interface Intf { public int func2(int a, int b, Point p); } - @ForceCompileClassInitializer static class MyImplPojo0 implements Intf { int field = 0; @DontCompile @@ -176,7 +170,6 @@ static class MyImplPojo0 implements Intf { public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 1; } } - @ForceCompileClassInitializer static class MyImplPojo1 implements Intf { int field = 1000; @@ -186,7 +179,6 @@ static class MyImplPojo1 implements Intf { public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 20; } } - @ForceCompileClassInitializer static class MyImplPojo2 implements Intf { int field = 2000; @@ -196,7 +188,6 @@ static class MyImplPojo2 implements Intf { public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 20; } } - @ForceCompileClassInitializer static class MyImplPojo3 implements Intf { int field = 0; @DontInline // will be compiled with counters @@ -205,7 +196,6 @@ static class MyImplPojo3 implements Intf { public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 1; } } - @ForceCompileClassInitializer static primitive class MyImplVal1 implements Intf { final int field; MyImplVal1() { @@ -220,7 +210,6 @@ static primitive class MyImplVal1 implements Intf { public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 300; } } - @ForceCompileClassInitializer static primitive class MyImplVal2 implements Intf { final int field; MyImplVal2() { @@ -234,7 +223,6 @@ static primitive class MyImplVal2 implements Intf { public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 300; } } - @ForceCompileClassInitializer static primitive class MyImplVal1X implements Intf { final int field; MyImplVal1X() { @@ -248,7 +236,6 @@ static primitive class MyImplVal1X implements Intf { public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 300; } } - @ForceCompileClassInitializer static primitive class MyImplVal2X implements Intf { final int field; MyImplVal2X() { @@ -285,7 +272,6 @@ static primitive class FixedPoints { } static FixedPoints fixedPointsField = new FixedPoints(); - @ForceCompileClassInitializer static primitive class FloatPoint { final float x; final float y; @@ -295,7 +281,6 @@ public FloatPoint(float x, float y) { } } - @ForceCompileClassInitializer static primitive class DoublePoint { final double x; final double y; @@ -307,7 +292,6 @@ public DoublePoint(double x, double y) { static FloatPoint floatPointField = new FloatPoint(123.456f, 789.012f); static DoublePoint doublePointField = new DoublePoint(123.456, 789.012); - @ForceCompileClassInitializer static primitive class EightFloats { float f1, f2, f3, f4, f5, f6, f7, f8; public EightFloats() { @@ -323,7 +307,6 @@ public EightFloats() { } static EightFloats eightFloatsField = new EightFloats(); - @ForceCompileClassInitializer static class Number { int n; Number(int v) { @@ -339,7 +322,6 @@ static interface RefPoint_Access { public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2); } - @ForceCompileClassInitializer static primitive class RefPoint implements RefPoint_Access { final Number x; final Number y; @@ -377,7 +359,6 @@ public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint r } } - @ForceCompileClassInitializer static class RefPoint_Access_Impl1 implements RefPoint_Access { @DontCompile public int func1(RefPoint rp2) { @@ -396,7 +377,6 @@ public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint r } } - @ForceCompileClassInitializer static class RefPoint_Access_Impl2 implements RefPoint_Access { @DontCompile public int func1(RefPoint rp2) { @@ -432,7 +412,6 @@ static RefPoint_Access get_RefPoint_Access() { // This inline class has too many fields to fit in registers on x64 for // InlineTypeReturnedAsFields. - @ForceCompileClassInitializer static primitive class TooBigToReturnAsFields { int a0 = 0; int a1 = 1; @@ -980,7 +959,6 @@ public void test46_verifier(RunInfo info) { } } - @ForceCompileClassInitializer static class MyRuntimeException extends RuntimeException { MyRuntimeException(String s) { super(s); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java index 44ffc373cb4..56d3df2e95b 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java @@ -21,18 +21,11 @@ * questions. */ - package compiler.valhalla.inlinetypes; -import java.lang.invoke.*; -import java.lang.reflect.Method; -import java.nio.file.NoSuchFileException; -import java.util.Arrays; - import jdk.test.lib.Asserts; import jdk.test.lib.hotspot.ir_framework.*; - /* * @test * @key randomness @@ -42,6 +35,7 @@ * @compile InlineTypes.java GetfieldChains.jcod * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestGetfieldChains */ + public class TestGetfieldChains { public static void main(String[] args) { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java index d42822fbe05..78b4cad1617 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java @@ -23,19 +23,17 @@ package compiler.valhalla.inlinetypes; +import jdk.internal.misc.Unsafe; +import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; + import java.lang.reflect.Array; import java.lang.reflect.Field; import java.util.Arrays; -import java.util.List; - -import jdk.test.lib.Asserts; -import jdk.internal.misc.Unsafe; -import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; import static compiler.valhalla.inlinetypes.InlineTypes.rI; import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; -import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; /* * @test @@ -48,6 +46,7 @@ * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestIntrinsics */ +@ForceCompileClassInitializer public class TestIntrinsics { public static void main(String[] args) { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java index 6477254d614..a44d41deea8 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java @@ -25,11 +25,9 @@ import jdk.test.lib.Asserts; import jdk.test.lib.hotspot.ir_framework.*; + import static compiler.valhalla.inlinetypes.InlineTypes.rI; import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; - -import java.lang.reflect.Method; /* * @test @@ -41,6 +39,7 @@ * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestJNICalls */ +@ForceCompileClassInitializer public class TestJNICalls { public static void main(String[] args) { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java index 063a2e344f2..500cc336f28 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java @@ -44,9 +44,10 @@ * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @compile InlineTypes.java - * @run driver compiler.valhalla.inlinetypes.TestLWorld + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestLWorld */ +@ForceCompileClassInitializer public class TestLWorld { static final TestFramework testFramework = InlineTypes.getFramework(); @@ -111,7 +112,7 @@ private void rerun_and_recompile_for(Method m, int num, Runnable test) { for (int i = 1; i < num; i++) { test.run(); - if (TestFramework.isCompiled(m)) { + if (!TestFramework.isCompiled(m)) { TestFramework.compile(m, CompLevel.C2); } } @@ -470,7 +471,6 @@ public void test12_verifier() { Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive()); } - @ForceCompileClassInitializer class MyObject1 implements MyInterface { public int x; @@ -1512,7 +1512,6 @@ public void test50_verifier() { } // Inline type with some non-flattened fields - @ForceCompileClassInitializer final primitive class Test51Value { final Object objectField1; final Object objectField2; @@ -1939,7 +1938,6 @@ public MyInterface test70Interface_sum(MyInterface a, MyInterface b) { return MyValue1.setX(((MyValue1)a), sum); } -/* KATYA Test fails because IR fails @Test @IR(failOn = {ALLOC, STORE}) public int test70Interface(MyValue1[] array) { @@ -1955,7 +1953,8 @@ public void test70Interface_verifier() { int result = test70Interface(testValue1Array); Asserts.assertEQ(result, rI * testValue1Array.length); } -*/ + + // Same as test69 but with an Abstract @ForceInline public MyAbstract test70Abstract_sum(MyAbstract a, MyAbstract b) { @@ -2003,7 +2002,6 @@ public void test71_verifier() { } // Test calling a method on an uninitialized inline type - @ForceCompileClassInitializer final primitive class Test72Value { final int x = 42; public int get() { @@ -2160,7 +2158,6 @@ public void test79_verifier() throws Throwable { } // Test flattened field with non-flattenend (but flattenable) inline type field - @ForceCompileClassInitializer static primitive class Small { final int i; final Big big; // Too big to be flattened @@ -2171,7 +2168,6 @@ private Small() { } } - @ForceCompileClassInitializer static primitive class Big { long l0,l1,l2,l3,l4,l5,l6,l7,l8,l9; long l10,l11,l12,l13,l14,l15,l16,l17,l18,l19; @@ -2275,7 +2271,6 @@ public void test83_verifier(RunInfo info) { } } -/* KATYA Test fails because IR fails // Tests for the Loop Unswitching optimization // Should make 2 copies of the loop, one for non flattened arrays, one for other cases. @Test @@ -2296,7 +2291,7 @@ public void test84_verifier(RunInfo info) { () -> { test84(src, dst); Asserts.assertTrue(Arrays.equals(src, dst)); }); } -*/ + @Test @IR(applyIf = {"UseG1GC", "true"}, counts = {COUNTEDLOOP, "= 2", LOAD_UNKNOWN_INLINE, "= 1"}) @@ -2342,7 +2337,6 @@ public void test86_verifier(RunInfo info) { Asserts.assertTrue(Arrays.equals(src, dst)); }); } -/* KATYA Tests fails because IR fails @Test @IR(counts = {COUNTEDLOOP_MAIN, "= 2"}) @@ -2388,7 +2382,7 @@ public void test88_verifier(RunInfo info) { Asserts.assertTrue(Arrays.equals(src1, dst1)); Asserts.assertTrue(Arrays.equals(src2, dst2)); }); } -*/ + @Test public boolean test89(Object obj) { @@ -2428,7 +2422,6 @@ public void test91_verifier() { Asserts.assertFalse(test91(new Object())); } - @ForceCompileClassInitializer static primitive class Test92Value { final int field; public Test92Value() { @@ -2647,7 +2640,6 @@ public void test98_verifier() { Asserts.assertEQ(result, 11*vt.hash() + 2*def.hashPrimitive()); } - @ForceCompileClassInitializer class MyObject2 extends MyAbstract { public int x; @@ -2768,12 +2760,10 @@ abstract class NoValueImplementors1 { int field = 42; } - @ForceCompileClassInitializer class MyObject3 extends NoValueImplementors1 { } - @ForceCompileClassInitializer class MyObject4 extends NoValueImplementors1 { } @@ -2843,7 +2833,6 @@ abstract class NoValueImplementors2 { } - @ForceCompileClassInitializer class MyObject5 extends NoValueImplementors2 { } @@ -2930,7 +2919,6 @@ public void test107_verifier(RunInfo info) { Asserts.assertEquals(oFld2, testValue2); }); } -/* KATYA, Test fails because IR fails @Test @IR(applyIf = {"UseG1GC", "true"}, failOn = {LOAD_UNKNOWN_INLINE, INLINE_ARRAY_NULL_GUARD}, @@ -2963,9 +2951,7 @@ public void test108_verifier(RunInfo info) { Asserts.assertEquals(dst2[i], o1); } }); } -*/ -/* KATYA TEST CRASHES // Escape analysis tests @@ -2997,7 +2983,6 @@ public long value() { } } - @ForceCompileClassInitializer static class InterfaceBox { WrapperInterface content; @@ -3014,7 +2999,6 @@ static InterfaceBox box(long val) { } } - @ForceCompileClassInitializer static class ObjectBox { Object content; @@ -3031,7 +3015,6 @@ static ObjectBox box(long val) { } } - @ForceCompileClassInitializer static class RefBox { LongWrapper.ref content; @@ -3048,7 +3031,6 @@ static RefBox box(long val) { } } - @ForceCompileClassInitializer static class InlineBox { LongWrapper content; @@ -3061,7 +3043,6 @@ static InlineBox box(long val) { } } - @ForceCompileClassInitializer static class GenericBox { T content; @@ -3260,7 +3241,6 @@ public static WrapperInterface2 wrap_default(long val) { } } - @ForceCompileClassInitializer static primitive class LongWrapper2 implements WrapperInterface2 { private long val; @@ -3273,7 +3253,6 @@ public long value() { } } - @ForceCompileClassInitializer static primitive class InlineWrapper { WrapperInterface2 content; @@ -3282,7 +3261,6 @@ public InlineWrapper(long val) { } } - @ForceCompileClassInitializer static class InterfaceBox2 { WrapperInterface2 content; @@ -3390,12 +3368,10 @@ public void test118_verifier() { Asserts.assertTrue(res); } - @ForceCompileClassInitializer static primitive class EmptyContainer { private MyValueEmpty empty = MyValueEmpty.default; } - @ForceCompileClassInitializer static primitive class MixedContainer { public int val = rI; private EmptyContainer empty = EmptyContainer.default; @@ -3788,7 +3764,6 @@ public void test136_verifier() { Asserts.assertTrue(test136(true)); } - @ForceCompileClassInitializer static final primitive class SimpleInlineType { final int x; public SimpleInlineType(int x) { @@ -3828,5 +3803,4 @@ public void test138_verifier() { Asserts.assertTrue(test138(rI, false)); Asserts.assertTrue(test138(rI, true)); } - KATYA */ } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java index 3d87451ebf7..fd1ba0f6c13 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java @@ -44,6 +44,7 @@ * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestMethodHandles */ +@ForceCompileClassInitializer public class TestMethodHandles { static final TestFramework testFramework = InlineTypes.getFramework(); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java index c79a9aa0c55..9c089054fec 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java @@ -43,6 +43,7 @@ * @run driver compiler.valhalla.inlinetypes.TestNullableArrays */ +@ForceCompileClassInitializer public class TestNullableArrays { static final TestFramework testFramework = InlineTypes.getFramework(); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java index a6a9b4a256f..dc98bc425a4 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java @@ -21,19 +21,10 @@ * questions. */ - package compiler.valhalla.inlinetypes; -import java.lang.invoke.*; -import java.lang.reflect.Method; -import java.util.Arrays; - import jdk.test.lib.Asserts; import jdk.test.lib.hotspot.ir_framework.*; -import static compiler.valhalla.inlinetypes.InlineTypes.rI; -import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; - /* * @test @@ -46,6 +37,7 @@ * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestWithfieldC1 */ +@ForceCompileClassInitializer public class TestWithfieldC1 { public static void main(String[] args) { @@ -84,7 +76,6 @@ static void set_foo_static_if_null(FooValue v) { } } - @ForceCompileClassInitializer static primitive class FooValue { public int x = 0, y = 0; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 5d87f7ebd91..ad3e3b0d47b 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -130,17 +130,24 @@ public static void main(String[] args) { String testClassName = args[0]; System.out.println("Framework main(), about to run tests in class " + testClassName); Class testClass; - try { - testClass = Class.forName(testClassName); - } catch (Exception e) { - throw new TestRunException("Could not find test class " + testClassName, e); - } + testClass = getClassObject(testClassName, "test"); TestFrameworkExecution framework = new TestFrameworkExecution(testClass); framework.addHelperClasses(args); framework.start(); } + protected static Class getClassObject(String className, String classType) { + Class c; + try { + c = Class.forName(className); + } catch (Exception e) { + TestRun.fail("Could not find " + classType + " class", e); + return null; + } + return c; + } + private void addHelperClasses(String[] args) { Class[] helperClasses = getHelperClasses(args); if (helperClasses != null) { @@ -167,11 +174,7 @@ private static Class[] getHelperClasses(String[] args) { Class[] helperClasses = new Class[args.length - 1]; // First argument is test class for (int i = 1; i < args.length; i++) { String helperClassName = args[i]; - try { - helperClasses[i - 1] = Class.forName(helperClassName); - } catch (Exception e) { - throw new TestRunException("Could not find helper class " + helperClassName, e); - } + helperClasses[i - 1] = getClassObject(helperClassName, "helper"); } return helperClasses; } @@ -296,7 +299,12 @@ private void applyClassAnnotations(Class c) { } level = restrictCompLevel(anno.value()); if (level != CompLevel.SKIP) { - WHITE_BOX.enqueueInitializerForCompilation(c, level.getValue()); + // Make sure class is initialized to avoid compilation bailout of + getClassObject(c.getName(), "nested"); // calls Class.forName() to initialize 'c' + TestFormat.checkNoThrow(WHITE_BOX.enqueueInitializerForCompilation(c, level.getValue()), + "Failed to enqueue of " + c + " for compilation. Did you specify " + + "@ForceCompileClassInitializer without providing a static class initialization? " + + "Make sure to provide any form of static initialization or remove the annotation."); } } } From 2bcb45988506a69df6c65127db8ecf47272548ed Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 31 Mar 2021 08:52:53 +0200 Subject: [PATCH 085/131] Small test cleanups --- .../compiler/valhalla/inlinetypes/TestLWorld.java | 4 +--- .../valhalla/inlinetypes/TestMethodHandles.java | 9 ++++----- .../valhalla/inlinetypes/TestNullableArrays.java | 12 ++++++------ 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java index 500cc336f28..8697f60e4bd 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java @@ -2337,7 +2337,6 @@ public void test86_verifier(RunInfo info) { Asserts.assertTrue(Arrays.equals(src, dst)); }); } - @Test @IR(counts = {COUNTEDLOOP_MAIN, "= 2"}) public void test87(Object[] src, Object[] dst) { @@ -2383,7 +2382,6 @@ public void test88_verifier(RunInfo info) { Asserts.assertTrue(Arrays.equals(src2, dst2)); }); } - @Test public boolean test89(Object obj) { return obj.getClass() == Integer.class; @@ -3466,7 +3464,7 @@ public void test123_verifier() { // acmp doesn't need substitutability test when one input is known // not to be a value type @Test - @IR(failOn = {SUBSTITUTABILITY_TEST}) + @IR(failOn = SUBSTITUTABILITY_TEST) public boolean test124(Integer o1, Object o2) { return o1 == o2; } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java index fd1ba0f6c13..479d43682ba 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java @@ -156,9 +156,9 @@ MyValue3 test1_target() { @Test @IR(applyIf = {"InlineTypeReturnedAsFields", "true"}, - failOn = {ALLOC, STORE, CALL}) + failOn = {ALLOC, STORE, CALL}) @IR(applyIf = {"InlineTypeReturnedAsFields", "false"}, - counts = {ALLOC, "= 1", STORE, "= 14"}) + counts = {ALLOC, "= 1", STORE, "= 14"}) public MyValue3 test1() throws Throwable { return (MyValue3)test1_mh.invokeExact(this); } @@ -187,11 +187,10 @@ public MyValue3 test2() throws Throwable { public void test2_verifier(RunInfo info) throws Throwable { if (!info.isWarmUp()) { Method helper_m = getClass().getDeclaredMethod("test2_target"); - if (TestFramework.isCompiled(helper_m)) { + if (!TestFramework.isCompiled(helper_m)) { TestFramework.compile(helper_m, CompLevel.C2); } } - MyValue3 vt = test2(); test2_vt.verify(vt); } @@ -289,7 +288,7 @@ boolean test6_test() { @Test @IR(applyIf = {"InlineTypeReturnedAsFields", "true"}, - failOn = {ALLOC, ALLOCA, STORE, STORE_INLINE_FIELDS}) + failOn = {ALLOC, ALLOCA, STORE, STORE_INLINE_FIELDS}) public MyValue3 test6() throws Throwable { return (MyValue3)test6_mh.invokeExact(this); } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java index 9c089054fec..2460bb8a54c 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java @@ -137,10 +137,10 @@ static boolean compile_and_run_again_if_deoptimized(RunInfo info) { // Test nullable inline type array creation and initialization @Test @IR(applyIf = {"FlatArrayElementMaxSize", "= -1"}, - counts = {ALLOCA, "= 1"}) + counts = {ALLOCA, "= 1"}) @IR(applyIf = {"FlatArrayElementMaxSize", "!= -1"}, - counts = {ALLOCA, "= 1"}, - failOn = LOAD) + counts = {ALLOCA, "= 1"}, + failOn = LOAD) public MyValue1.ref[] test1(int len) { MyValue1.ref[] va = new MyValue1.ref[len]; if (len > 0) { @@ -325,7 +325,7 @@ public void test8_verifier() { // Test that inline type array loaded from field has correct type @Test - @IR(failOn = {LOOP}) + @IR(failOn = LOOP) public long test9() { return test9_va[0].hash(); } @@ -1750,7 +1750,7 @@ public void test65_verifier() { // Check init store elimination @Test - @IR(counts = { ALLOCA, "=1"}) + @IR(counts = {ALLOCA, "= 1"}) public MyValue1.ref[] test66(MyValue1.ref vt) { MyValue1.ref[] va = new MyValue1.ref[1]; va[0] = vt; @@ -2655,7 +2655,7 @@ public static void test100_verifier(RunInfo info) { // Test stores to varag arrays @Test - @IR(failOn = {STORE_UNKNOWN_INLINE}) + @IR(failOn = STORE_UNKNOWN_INLINE) public static void test101(Object val, Object... args) { args[0] = val; } From 205152d001409fed87cf57d2175747386e85f850 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 1 Apr 2021 13:51:37 +0200 Subject: [PATCH 086/131] Change IR matching from stdout based to hotspot_pid file based to fix rare concurrency issues with approach from old framework, refactor IRMatcher in the process and improve IR violation reporting to only show relevant compilation output of failed matches, add more tests for that, update random float/double to include negative values, add more Javadocs --- .../valhalla/inlinetypes/TestArrays.java | 2 +- .../hotspot/ir_framework/AbstractInfo.java | 6 +- .../lib/hotspot/ir_framework/Argument.java | 2 + .../hotspot/ir_framework/ArgumentValue.java | 6 +- .../lib/hotspot/ir_framework/IRMatcher.java | 491 ++++++++++++++---- .../ir_framework/IRViolationException.java | 12 +- .../ir_framework/ParsedComparator.java | 7 + .../lib/hotspot/ir_framework/TestFormat.java | 3 + .../hotspot/ir_framework/TestFramework.java | 26 +- .../ir_framework/TestFrameworkException.java | 2 +- .../TestFrameworkPrepareFlags.java | 11 +- .../lib/hotspot/ir_framework/TestRun.java | 3 + .../hotspot/ir_framework/TestVMException.java | 7 +- .../ir_framework/tests/TestBadFormat.java | 10 +- .../ir_framework/tests/TestIRMatching.java | 219 ++++++++ 15 files changed, 686 insertions(+), 121 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java index f829cb39fe6..9df69bac378 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java @@ -41,7 +41,7 @@ * @library /test/lib * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") * @compile InlineTypes.java - * @run driver compiler.valhalla.inlinetypes.TestArrays + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestArrays */ @ForceCompileClassInitializer diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java index 1bb362dd2c8..64a613b0548 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java @@ -77,12 +77,12 @@ public static long getRandomLong() { } /** - * Get a random double value. + * Get a random double value in the range of [-10000,10000] * - * @return a random double value. + * @return a random double value in the range of [-10000,10000]. */ public static double getRandomDouble() { - return random.nextDouble(); + return random.nextDouble() * 20000 - 10000; } /** diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java index f22033f62e9..2e050982ddf 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java @@ -70,10 +70,12 @@ public enum Argument { BOOLEAN_TOGGLE_FIRST_TRUE, /** * Provides a random primitive value on the first test invocation and reuses the same value for all invocation of the test. + * Float and Double values are restricted to the range [-10000,10000]. */ RANDOM_ONCE, /** * Provides a different random primitive value on each test invocation. + * Float and Double values are restricted to the range [-10000,10000]. */ RANDOM_EACH } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java index e8ead1b492e..1bbd2cdc64c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java @@ -162,7 +162,6 @@ private static ArgumentValue createDefault(Class c) throws Exception { } } - private static ArgumentValue createMin(Class c) { Object argument; if (c.equals(byte.class)) { @@ -245,6 +244,7 @@ private static boolean isBoolean(Class c) { private static boolean isChar(Class c) { return c.equals(char.class); } + private static boolean isNumber(Class c) { return isIntNumber(c) || isFloatNumber(c); } @@ -275,10 +275,10 @@ private static Object getRandom(Class c) { return random.nextLong(); } else if (c.equals(float.class)) { // Get number between 0 and 1000. - return random.nextFloat() * 1000; + return random.nextFloat() * 20000 - 10000; } else if (c.equals(double.class)) { // Get number between 0 and 1000. - return random.nextDouble() * 1000; + return random.nextDouble() * 20000 - 10000; } else { TestFormat.fail("Cannot generate random value for non-primitive type"); return null; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java index 3a97e25a03e..152f7cb0fee 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java @@ -23,41 +23,71 @@ package jdk.test.lib.hotspot.ir_framework; +import java.io.*; import java.lang.reflect.Method; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * Parse the hotspot pid file of the test VM to match all @IR rules. + */ class IRMatcher { private static final boolean PRINT_IR_ENCODING = Boolean.parseBoolean(System.getProperty("PrintIREncoding", "false")); - private final Map irRulesMap; - private final Map compilations; + private final Map compilations; private final Class testClass; private final Map> fails; + private final String hotspotPidFileName; + private IRMethod irMethod; // Current IR method to which rules are applied private Method method; // Current method to which rules are applied private IR irAnno; // Current IR annotation that is processed. private int irRuleIndex; // Current IR rule index; - public IRMatcher(String output, String irEncoding, Class testClass) { - this.irRulesMap = new HashMap<>(); + public IRMatcher(String hotspotPidFileName, String irEncoding, Class testClass) { this.compilations = new LinkedHashMap<>(); this.fails = new HashMap<>(); this.testClass = testClass; - parseIREncoding(irEncoding); + this.hotspotPidFileName = hotspotPidFileName; + setupTestMethods(irEncoding); if (TestFramework.VERBOSE || PRINT_IR_ENCODING) { System.out.println("Read IR encoding from test VM:"); System.out.println(irEncoding); } - splitCompilations(output, testClass); + parseHotspotPidFile(); + applyRules(); + } + + + private void setupTestMethods(String irEncoding) { + Map irRulesMap = parseIREncoding(irEncoding); + for (Method m : testClass.getDeclaredMethods()) { + method = m; + 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. + Integer[] ids = irRulesMap.get(m.getName()); + TestFramework.check(ids != null, "Should find method name in validIrRulesMap for " + m); + TestFramework.check(ids.length > 0, "Did not find any rule indices for " + m); + TestFramework.check(ids[ids.length - 1] < irAnnos.length, "Invalid IR rule index found in validIrRulesMap for " + m); + if (ids[0] != IREncodingPrinter.NO_RULE_APPLIED) { + // If -1, than there was no matching IR rule for the given conditions. + compilations.put(m.getName(), new IRMethod(m, ids, irAnnos)); + } + } + } } - private void parseIREncoding(String irEncoding) { + /** + * Read the IR encoding emitted by the test VM to decide if an @IR rule must be checked for a method. + */ + private Map parseIREncoding(String irEncoding) { + Map irRulesMap = new HashMap<>(); String patternString = "(?<=" + IREncodingPrinter.START + "\\R)[\\s\\S]*(?=" + IREncodingPrinter.END + ")"; Pattern pattern = Pattern.compile(patternString); Matcher matcher = pattern.matcher(irEncoding); - TestFramework.check(matcher.find(), "Did not find IR encoding"); String[] lines = matcher.group(0).split("\\R"); + // Skip first line containing information about the format only for (int i = 1; i < lines.length; i++) { String line = lines[i].trim(); @@ -72,128 +102,237 @@ private void parseIREncoding(String irEncoding) { } irRulesMap.put(testName, irRulesIdx); } + return irRulesMap; } - private void splitCompilations(String output, Class testClass) { - Pattern pattern = Pattern.compile("\\n\\s+\\d+\\s+\\d+\\s+([% ])([s ])([! ])b([n ])\\s+\\d?\\s+\\S+\\.(?[^.]+::\\S+)\\s+(?@ \\d+\\s+)?[(]\\d+ bytes[)]"); - Matcher m = pattern.matcher(output); - int prev = 0; - String methodName = null; - String keyMatchPrefix = testClass.getSimpleName() + "::"; - while (m.find()) { - if (methodName != null) { - if (methodName.startsWith(keyMatchPrefix)) { - String shortMethodName = methodName.split("::")[1]; - if (irRulesMap.containsKey(methodName.split("::")[1])) { - compilations.put(shortMethodName, output.substring(prev, m.start() + 1).trim()); - } + /** + * Parse the hotspot_pid*.log file from the test VM. Read the PrintIdeal and PrintOptoAssembly entries for all + * methods of the test class that need to be IR matched (according to IR encoding). + */ + private void parseHotspotPidFile() { + Map compileIdMap = new HashMap<>(); + try (BufferedReader br = new BufferedReader(new FileReader(new File(System.getProperty("user.dir") + File.separator + hotspotPidFileName)))) { + String line; + StringBuilder builder = new StringBuilder(); + boolean append = false; + String currentMethod = ""; + while ((line = br.readLine()) != null) { + if (append && line.startsWith(" tag. + } + } else if (isPrintOptoAssemblyStart(line)) { + String methodName = getMethodName(compileIdMap, line); + if (methodName != null) { + TestFramework.check(compilations.containsKey(methodName), "Must be second entry of " + methodName); + currentMethod = methodName; + append = true; // Append all following lines until we hit the closing tag. } - compilations.put(shortMethodName, testOutput.trim()); } } + } catch (IOException e) { + TestFramework.fail("Error while reading " + hotspotPidFileName, e); } } - public void applyRules() { - fails.clear(); - for (Method m : testClass.getDeclaredMethods()) { - method = m; - 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. - Integer[] ids = irRulesMap.get(m.getName()); - TestFramework.check(ids != null, "Should find method name in validIrRulesMap for " + m); - TestFramework.check(ids.length > 0, "Did not find any rule indices for " + m); - TestFramework.check(ids[ids.length - 1] < irAnnos.length, "Invalid IR rule index found in validIrRulesMap for " + m); - if (ids[0] != IREncodingPrinter.NO_RULE_APPLIED) { - // If -1, than there was no matching IR rule for the given conditions. - applyRuleToMethod(irAnnos, ids); - } - } + /** + * Write the input to the IR method and reset the builder. + */ + private void flushOutput(String line, StringBuilder builder, String currentMethod) { + TestFramework.check(!currentMethod.isEmpty(), "current method must be set"); + IRMethod irMethod = compilations.get(currentMethod); + if (line.startsWith("> entry : fails.entrySet()) { - Method method = entry.getKey(); - System.out.println("\n>>> Compilation of " + method + ":"); - System.out.println(compilations.get(method.getName())); - List list = entry.getValue(); - builder.append("- Method \"").append(method).append("\":\n"); - failures += list.size(); - list.forEach(s -> builder.append(" * ").append(s.replace("\n", "\n ").trim()).append("\n")); - builder.append("\n"); + /** + * Only consider non-osr (no "compile_kind") and compilations with C2 (no "level") + */ + private boolean maybeTestEntry(String line) { + return line.startsWith(""); + line = line.replace(""", "\""); + line = line.replace("'", "'"); + } + builder.append(line).append("\n"); + } + + private static int getCompileId(Matcher matcher) { + int compileId = -1; + try { + compileId = Integer.parseInt(matcher.group(1)); + } catch (NumberFormatException e) { + TestRun.fail("Could not parse compile id", e); + } + return compileId; + } + + /** + * Parse the compile id from this line if it belongs to a method that needs to be IR tested (part of test class + * and IR encoding from the test VM specifies that this method has @IR rules to be checked). + */ + private void addTestMethodCompileId(Map compileIdMap, String line) { + Pattern pattern = Pattern.compile("compile_id='(\\d+)'.*" + Pattern.quote(testClass.getCanonicalName()) + " (\\S+)"); + Matcher matcher = pattern.matcher(line); + if (matcher.find()) { + // Only care about test class entries. Might have non-class entries as well if user specified additional + // compile commands. Ignore these. + String methodName = matcher.group(2); + if (compilations.containsKey(methodName)) { + // We only care about methods that we are actually gonna IR match based on IR encoding. + int compileId = getCompileId(matcher); + TestRun.check(!methodName.isEmpty(), "method name cannot be empty"); + compileIdMap.put(compileId, methodName); } - builder.insert(0, ("\nOne or more @IR rules failed:\n\n" - + "Failed IR Rules (" + failures + ")\n") - + "-----------------" + "-".repeat(String.valueOf(failures).length()) + "\n"); - throw new IRViolationException(builder.toString()); } } - private void applyRuleToMethod(IR[] irAnnos, Integer[] ids) { - String testOutput = compilations.get(method.getName()); - if (testOutput == null || testOutput.isEmpty()) { - String msg = "Method was not compiled as part of a @Run method in STANDALONE mode. " + - "Make sure to always trigger a C2 compilation by invoking the test enough times."; + /** + * Make sure that line does not contain compile_kind which is used for OSR compilations which we are not + * interested in. + */ + private static boolean isPrintIdealStart(String line) { + return line.startsWith(" compileIdMap, String line) { + Pattern pattern = Pattern.compile("compile_id='(\\d+)'"); + Matcher matcher = pattern.matcher(line); + TestFramework.check(matcher.find(), "Is " + hotspotPidFileName + " corrupted?"); + int compileId = getCompileId(matcher); + return compileIdMap.get(compileId); + } + + /** + * Do an IR matching of all methods with appliable @IR rules fetched during parsing of the hotspot pid file. + */ + private void applyRules() { + compilations.values().forEach(this::applyRulesForMethod); + reportFailuresIfAny(); + } + + private void applyRulesForMethod(IRMethod irMethod) { + this.irMethod = irMethod; + method = irMethod.getMethod(); + String testOutput = irMethod.getOutput(); + if (testOutput.isEmpty()) { + String msg = "Method was not compiled. Did you specify any compiler directives preventing a compilation or used a " + + "@Run method in STANDALONE mode? In the latter case, make sure to always trigger a C2 compilation " + + "by invoking the test enough times."; fails.computeIfAbsent(method, k -> new ArrayList<>()).add(msg); return; } if (TestFramework.VERBOSE) { + System.out.println("Output of " + method + ":"); System.out.println(testOutput); } - for (Integer id : ids) { - irAnno = irAnnos[id]; - irRuleIndex = id; - StringBuilder failMsg = new StringBuilder(); - applyFailOn(testOutput, failMsg); - try { - applyCounts(testOutput, failMsg); - } catch (TestFormatException e) { - // Logged. Continue to check other rules. - } - if (!failMsg.isEmpty()) { - failMsg.insert(0, "@IR rule " + (id + 1) + ": \"" + irAnno + "\"\n"); - fails.computeIfAbsent(method, k -> new ArrayList<>()).add(failMsg.toString()); - } + for (Integer id : irMethod.getRuleIds()) { + applyIRRule(id); + } + } + + /** + * Apply a single @IR rule as part of a method. + */ + private void applyIRRule(Integer id) { + irAnno = irMethod.getIrAnno(id); + irRuleIndex = id; + StringBuilder failMsg = new StringBuilder(); + applyFailOn(failMsg); + try { + applyCounts(failMsg); + } catch (TestFormatException e) { + // Logged. Continue to check other rules. + } + if (!failMsg.isEmpty()) { + failMsg.insert(0, "@IR rule " + (id + 1) + ": \"" + irAnno + "\"\n"); + fails.computeIfAbsent(method, k -> new ArrayList<>()).add(failMsg.toString()); } } - private void applyFailOn(String testOutput, StringBuilder failMsg) { + /** + * Apply the failOn regexes of the @IR rule. + */ + private void applyFailOn(StringBuilder failMsg) { if (irAnno.failOn().length != 0) { String failOnRegex = String.join("|", IRNode.mergeNodes(irAnno.failOn())); Pattern pattern = Pattern.compile(failOnRegex); - Matcher matcher = pattern.matcher(testOutput); - if (matcher.find()) { - addFailOnFails(failMsg, testOutput); + Matcher matcher = pattern.matcher(irMethod.getOutput()); + long matchCount = matcher.results().count(); + if (matchCount > 0) { + addFailOnFailsForOutput(failMsg, pattern, matchCount); } } } - private void addFailOnFails(StringBuilder failMsg, String testOutput) { + /** + * A failOn regex failed. Apply all regexes again to log the exact regex which failed. The failure is later reported + * to the user. + */ + private void addFailOnFailsForOutput(StringBuilder failMsg, Pattern pattern, long matchCount) { + long idealCount = pattern.matcher(irMethod.getIdealOutput()).results().count(); + long optoAssemblyCount = pattern.matcher(irMethod.getOptoAssemblyOutput()).results().count(); + if (matchCount != idealCount + optoAssemblyCount || (idealCount != 0 && optoAssemblyCount != 0)) { + // Report with Ideal and Opto Assembly + addFailOnFailsForOutput(failMsg, irMethod.getOutput()); + irMethod.needsAllOutput(); + } else if (optoAssemblyCount == 0) { + // Report with Ideal only + addFailOnFailsForOutput(failMsg, irMethod.getIdealOutput()); + irMethod.needsIdeal(); + } else { + // Report with Opto Assembly only + addFailOnFailsForOutput(failMsg, irMethod.getOptoAssemblyOutput()); + irMethod.needsOptoAssembly(); + } + } + + /** + * Apply the regexes to the testOutput and log the failures. + */ + private void addFailOnFailsForOutput(StringBuilder failMsg, String testOutput) { List failOnNodes = IRNode.mergeNodes(irAnno.failOn()); Pattern pattern; Matcher matcher; @@ -206,16 +345,20 @@ private void addFailOnFails(StringBuilder failMsg, String testOutput) { if (matchCount > 0) { matcher.reset(); failMsg.append(" Regex ").append(nodeId).append(") ").append(nodeRegex).append("\n"); - failMsg.append(" Matched forbidden node").append(matchCount > 1 ? "s" : "").append(":\n"); + failMsg.append(" Matched forbidden node").append(matchCount > 1 ? "s (" + matchCount + ")" : "").append(":\n"); matcher.results().forEach(r -> failMsg.append(" ").append(r.group()).append("\n")); } nodeId++; } } - private void applyCounts(String testOutput, StringBuilder failMsg) { + /** + * Apply the counts regexes of the @IR rule. + */ + private void applyCounts(StringBuilder failMsg) { if (irAnno.counts().length != 0) { boolean hasFails = false; + String testOutput = irMethod.getOutput(); int countsId = 1; final List nodesWithCount = IRNode.mergeNodes(irAnno.counts()); for (int i = 0; i < nodesWithCount.size(); i += 2) { @@ -247,7 +390,7 @@ private void applyCounts(String testOutput, StringBuilder failMsg) { failMsg.append("- counts: Graph contains wrong number of nodes:\n"); hasFails = true; } - addCountsFail(failMsg, node, matcher, expectedCount, actualCount, countsId); + addCountsFail(failMsg, node, pattern, expectedCount, actualCount, countsId); } countsId++; } @@ -258,15 +401,161 @@ private String getPostfixErrorMsg(String node) { return " for IR rule " + irRuleIndex + ", node \"" + node + "\" at " + method; } - private void addCountsFail(StringBuilder failMsg, String node, Matcher matcher, long expectedCount, long actualCount, int countsId) { - matcher.reset(); + /** + * A counts regex failed. Apply all regexes again to log the exact regex which failed. The failure is later reported + * to the user. + */ + private void addCountsFail(StringBuilder failMsg, String node, Pattern pattern, long expectedCount, long actualCount, int countsId) { failMsg.append(" Regex ").append(countsId).append(") ").append(node).append("\n"); failMsg.append(" Expected ").append(expectedCount).append(" but found ").append(actualCount); + if (actualCount > 0) { + Matcher matcher = pattern.matcher(irMethod.getOutput()); + long idealCount = pattern.matcher(irMethod.getIdealOutput()).results().count(); + long optoAssemblyCount = pattern.matcher(irMethod.getOptoAssemblyOutput()).results().count(); + if (actualCount != idealCount + optoAssemblyCount || (idealCount != 0 && optoAssemblyCount != 0)) { + irMethod.needsAllOutput(); + } else if (optoAssemblyCount == 0) { + irMethod.needsIdeal(); + } else { + irMethod.needsOptoAssembly(); + } failMsg.append(" node").append(actualCount > 1 ? "s" : "").append(":\n"); matcher.results().forEach(r -> failMsg.append(" ").append(r.group()).append("\n")); } else { + irMethod.needsAllOutput(); failMsg.append(" nodes.\n"); } } + + /** + * Report all IR violations in a pretty format to the user. Depending on the failed regex, we only report + * PrintIdeal or PrintOptoAssembly if the match failed there. If there were failures that matched things + * in both outputs than the entire output is reported. Throws IRViolationException from which the compilation + * can be read and reported to the stdout separately. The exception message only includes the summary of the + * failures. + */ + private void reportFailuresIfAny() { + TestFormat.reportIfAnyFailures(); + if (!fails.isEmpty()) { + StringBuilder failuresBuilder = new StringBuilder(); + StringBuilder compilationsBuilder = new StringBuilder(); + int failures = 0; + for (Map.Entry> entry : fails.entrySet()) { + Method method = entry.getKey(); + compilationsBuilder.append(">>> Compilation of ").append(method).append(":\n"); + IRMethod irMethod = compilations.get(method.getName()); + String output; + if (irMethod.usesIdeal() && irMethod.usesOptoAssembly()) { + output = irMethod.getOutput(); + } else if (irMethod.usesIdeal()) { + output = irMethod.getIdealOutput(); + } else if (irMethod.usesOptoAssembly()) { + output = irMethod.getOptoAssemblyOutput(); + } else { + output = ""; + } + compilationsBuilder.append(output).append("\n\n"); + List list = entry.getValue(); + failuresBuilder.append("- Method \"").append(method).append("\":\n"); + failures += list.size(); + list.forEach(s -> failuresBuilder.append(" * ").append(s.replace("\n", "\n ").trim()).append("\n")); + failuresBuilder.append("\n"); + } + failuresBuilder.insert(0, ("\nOne or more @IR rules failed:\n\n" + "Failed IR Rules (" + failures + ")\n") + + "-----------------" + "-".repeat(String.valueOf(failures).length()) + "\n"); + failuresBuilder.append(">>> Check stdout for compilation output of the failed methods\n\n"); + throw new IRViolationException(failuresBuilder.toString(), compilationsBuilder.toString()); + } + } +} + +/** + * Helper class to store information about a method that needs to be IR matched. + */ +class IRMethod { + + final private Method method; + final private Integer[] ruleIds; + final private IR[] irAnnos; + final private StringBuilder outputBuilder; + private String output; + private String idealOutput; + private String optoAssemblyOutput; + private boolean needsIdeal; + private boolean needsOptoAssembly; + + public IRMethod(Method method, Integer[] ruleIds, IR[] irAnnos) { + this.method = method; + this.ruleIds = ruleIds; + this.irAnnos = irAnnos; + this.outputBuilder = new StringBuilder(); + this.output = ""; + this.idealOutput = ""; + this.optoAssemblyOutput = ""; + } + + public Method getMethod() { + return method; + } + + public Integer[] getRuleIds() { + return ruleIds; + } + + public IR getIrAnno(int idx) { + return irAnnos[idx]; + } + + /** + * The Ideal output comes always before the Opto Assembly output. We might parse multiple C2 compilations of this method. + * Only keep the very last one by overriding 'output'. + */ + public void appendIdealOutput(String idealOutput) { + outputBuilder.setLength(0); + this.idealOutput = "PrintIdeal:\n" + idealOutput; + outputBuilder.append(this.idealOutput); + } + + /** + * The Opto Assembly output comes after the Ideal output. Simply append to 'output'. + */ + public void appendOptoAssemblyOutput(String optoAssemblyOutput) { + this.optoAssemblyOutput = "PrintOptoAssembly:\n" + optoAssemblyOutput; + outputBuilder.append("\n\n").append(this.optoAssemblyOutput); + output = outputBuilder.toString(); + } + + public String getOutput() { + return output; + } + + public String getIdealOutput() { + return idealOutput; + } + + public String getOptoAssemblyOutput() { + return optoAssemblyOutput; + } + + public void needsAllOutput() { + needsIdeal(); + needsOptoAssembly(); + } + + public void needsIdeal() { + needsIdeal = true; + } + + public boolean usesIdeal() { + return needsIdeal; + } + + public void needsOptoAssembly() { + needsOptoAssembly = true; + } + + public boolean usesOptoAssembly() { + return needsOptoAssembly; + } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java index e4c2379bf05..5995194ba2b 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java @@ -27,9 +27,19 @@ * Exception that is thrown if an {@link IR} constraint failed. The exception message contains a detailed list of * all failures, including failing method, {@code IR} rule (the first {@code IR} constraint is rule 1) and the * specific regex that could not be matched. + * + * @see IR + * @see Test */ public class IRViolationException extends RuntimeException { - IRViolationException(String message) { + private final String compilations; + + IRViolationException(String message, String compilations) { super(message); + this.compilations = compilations; + } + + String getCompilations() { + return compilations; } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java index 9f151cf0dcf..61777bf94df 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java @@ -25,6 +25,9 @@ import java.util.function.BiPredicate; +/** + * Utility class to parse a comparator either in the applyIf* or in the counts properties of an @IR rules. + */ class ParsedComparator> { private final String strippedString; private final BiPredicate predicate; @@ -48,6 +51,10 @@ public String getComparator() { return comparator; } + /** + * Return parsed comparator object which provides the predicate to perform the test. + * Allowed comparators: <, <=, >, =>, =, != + */ public static > ParsedComparator parseComparator(String value) throws CheckedTestFrameworkException { BiPredicate comparison; value = value.trim(); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java index 2c7c613ad77..83e5dc6d833 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java @@ -26,6 +26,9 @@ import java.util.ArrayList; import java.util.List; +/** + * Utility class to report a {@link TestFormatException}. + */ class TestFormat { private static final List FAILURES = new ArrayList<>(); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 4b5eea20458..ab80fe95361 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -315,6 +315,10 @@ public void start() { } catch (TestVMException e) { System.err.println("\n" + e.getExceptionInfo()); throw e; + } catch (IRViolationException e) { + System.out.println("Compilation(s) of failed matche(s):"); + System.out.println(e.getCompilations()); + throw e; } } else { startWithScenarios(); @@ -437,7 +441,7 @@ private void startWithScenarios() { start(scenario); } catch (TestFormatException e) { // Test format violation is wrong for all the scenarios. Only report once. - throw new TestFormatException(e.getMessage()); + throw e; } catch (Exception e) { exceptionMap.put(scenario, e); } @@ -463,9 +467,12 @@ private void reportScenarioFailures(Map exceptionMap) { } if (e instanceof IRViolationException) { // For IR violations, only show the actual violations and not the (uninteresting) stack trace. - builder.append(e.getMessage()); + System.out.println((scenario != null ? "Scenario #" + scenario.getIndex() + " - " : "") + + "Compilation(s) of failed matche(s):"); + System.out.println(((IRViolationException) e).getCompilations()); + builder.append(errorMsg).append(e.getMessage()); } else if (e instanceof TestVMException) { - builder.append(errorMsg).append(((TestVMException) e).getExceptionInfo()); + builder.append(errorMsg).append("\n").append(((TestVMException) e).getExceptionInfo()); } else { // Print stack trace otherwise StringWriter errors = new StringWriter(); @@ -482,7 +489,7 @@ private static String getScenarioTitleAndFlags(Scenario scenario) { StringBuilder builder = new StringBuilder(); String title = "Scenario #" + scenario.getIndex(); builder.append(title).append("\n").append("=".repeat(title.length())).append("\n"); - builder.append("Scenario flags: [").append(String.join(", ", scenario.getFlags())).append("]\n\n"); + builder.append("Scenario flags: [").append(String.join(", ", scenario.getFlags())).append("]\n"); return builder.toString(); } @@ -594,8 +601,7 @@ private void runTestVM(List additionalFlags, Scenario scenario) { } checkTestVMExitCode(output); if (VERIFY_IR) { - IRMatcher irMatcher = new IRMatcher(lastTestVMOutput, socket.getOutput(), testClass); - irMatcher.applyRules(); + new IRMatcher(output.getHotspotPidFileName(), socket.getOutput(), testClass); } else { System.out.println("IR Verification disabled either through explicitly setting -DVerify=false or due to " + "not running a debug build, running with -Xint, or other VM flags that make the verification " + @@ -694,7 +700,7 @@ static void fail(String failureMessage) { throw new TestFrameworkException("Internal Test Framework exception - please file a bug:\n" + failureMessage); } - static void fail(String failureMessage, Exception e) { + static void fail(String failureMessage, Throwable e) { throw new TestFrameworkException("Internal Test Framework exception - please file a bug:\n" + failureMessage, e); } } @@ -706,11 +712,13 @@ class JVMOutput { private final Scenario scenario; private final OutputAnalyzer oa; private final ProcessBuilder process; + private final String hotspotPidFileName; JVMOutput(OutputAnalyzer oa, Scenario scenario, ProcessBuilder process) { this.oa = oa; this.scenario = scenario; this.process = process; + this.hotspotPidFileName = String.format("hotspot_pid%d.log", oa.pid()); } public Scenario getScenario() { @@ -736,6 +744,10 @@ public String getStdout() { public String getStderr() { return oa.getStderr(); } + + public String getHotspotPidFileName() { + return hotspotPidFileName; + } } /** diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java index dfbcf9d6cd1..1dce6bcf948 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java @@ -31,7 +31,7 @@ public class TestFrameworkException extends RuntimeException { super(message); } - TestFrameworkException(String message, Exception e) { + TestFrameworkException(String message, Throwable e) { super(message, e); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java index 2779853c8a1..92651c00de1 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java @@ -31,7 +31,11 @@ import java.util.Arrays; import java.util.function.Predicate; - +/** + * This class' main method is called from {@link TestFramework} and represents the so-called "flag VM". It uses the + * Whitebox to determine the necessary additional flags to run the test VM (e.g. to do IR matching). It returns + * the flags over the dedicated TestFramework socket. + */ class TestFrameworkPrepareFlags { private static final WhiteBox WHITE_BOX; @@ -39,7 +43,8 @@ class TestFrameworkPrepareFlags { try { WHITE_BOX = WhiteBox.getWhiteBox(); } catch (UnsatisfiedLinkError e) { - throw new TestFrameworkException("Could not load WhiteBox"); + TestFramework.fail("Could not load WhiteBox", e); + throw e; // Not reached } } @@ -131,6 +136,8 @@ private static void setupIrVerificationFlags(Class testClass, ArrayList clazz, Class... helpers) { @@ -905,6 +905,8 @@ public void noTestInInnerClass() {} @ForceCompileClassInitializer class BadCompileClassInitializer { + static int iFld = 3; + @Test @ForceCompileClassInitializer public void test() {} @@ -925,6 +927,12 @@ class BadCompileClassInitializerHelper2 { } +@ClassFail +@ForceCompileClassInitializer +class BadCompileClassInitializerHelper3 { + // no +} + class ClassNoDefaultConstructor { private ClassNoDefaultConstructor(int i) { } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java index 9bf6beeeae5..a9d0e53e5ba 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java @@ -186,6 +186,37 @@ public static void main(String[] args) { PrintStream ps = new PrintStream(baos); PrintStream old = System.out; System.setOut(ps); + + try { + runWithArguments(CompilationOutputOfFails.class); + shouldNotReach(); + } catch (IRViolationException e) { + System.out.flush(); + String output = baos.toString(); + baos.reset(); + Pattern pattern = Pattern.compile(">>> Compilation.*both\\d.*\\RPrintIdeal:(?:(?!PrintOpto|>>> Compilation)[\\S\\s])+PrintOptoAssembly"); + Matcher matcher = pattern.matcher(output); + Asserts.assertEQ(matcher.results().count(), (long)7, "Could not find all both methods: " + output); + pattern = Pattern.compile(">>> Compilation.*ideal\\d.*\\RPrintIdeal:(?:(?!>>> Compilation)[\\S\\s])+"); + matcher = pattern.matcher(output); + int count = 0; + while (matcher.find()) { + String match = matcher.group(); + Asserts.assertFalse(match.contains("PrintOptoAssembly"), "Cannot contain opto assembly: " + output); + count++; + } + Asserts.assertEQ(count, 7, "Could not find all ideal methods: " + output); + pattern = Pattern.compile(">>> Compilation.*opto\\d.*\\RPrintOptoAssembly:(?:(?!>>> Compilation)[\\S\\s])+"); + matcher = pattern.matcher(output); + count = 0; + while (matcher.find()) { + String match = matcher.group(); + Asserts.assertFalse(match.contains("PrintIdeal"), "Cannot contain opto assembly: " + output); + count++; + } + Asserts.assertEQ(count, 7, "Could not find all opto methods"); + } + runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=50"); System.out.flush(); String output = baos.toString(); @@ -1084,6 +1115,194 @@ public void testArrayCopy() { } } +class CompilationOutputOfFails { + + @Test + @IR(failOn = IRNode.COUNTEDLOOP + "[\\s\\S]*" + "call") + public void both1() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(failOn = IRNode.COUNTEDLOOP + "|" + "call") + public void both2() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(failOn = IRNode.COUNTEDLOOP) + @IR(failOn = "call") + public void both3() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(counts = {IRNode.COUNTEDLOOP + "[\\s\\S]*" + "call", "0"}) + public void both4() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(counts = {IRNode.COUNTEDLOOP + "|" + "call", "1"}) + public void both5() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(counts = {IRNode.COUNTEDLOOP, "0"}) + @IR(counts = {"call", "1"}) + public void both6() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(failOn = IRNode.COUNTEDLOOP) + @IR(counts = {"call", "1"}) + public void both7() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(failOn = IRNode.COUNTEDLOOP) + public void ideal1() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(failOn = IRNode.COUNTEDLOOP) + @IR(failOn = IRNode.ALLOC) // not fail + public void ideal2() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(failOn = IRNode.COUNTEDLOOP) + @IR(counts = {IRNode.ALLOC, "0"}) // not fail + public void ideal3() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(counts = {IRNode.COUNTEDLOOP, "2"}) + public void ideal4() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(failOn = IRNode.ALLOC) // not fail + @IR(counts = {IRNode.COUNTEDLOOP, "2"}) + public void ideal5() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(counts = {IRNode.ALLOC, "0"}) // not fail + @IR(counts = {IRNode.COUNTEDLOOP, "2"}) + public void ideal6() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(counts = {IRNode.COUNTEDLOOP, "5"}) + @IR(counts = {IRNode.COUNTEDLOOP, "2"}) + public void ideal7() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(failOn = "call") + public void opto1() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(failOn = "call") + @IR(failOn = IRNode.STORE) // not fail + public void opto2() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(failOn = "call") + @IR(counts = {IRNode.COUNTEDLOOP, "1"}) // not fail + public void opto3() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(counts = {"call", "1"}) + public void opto4() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(failOn = IRNode.STORE) // not fail + @IR(counts = {"call", "1"}) + public void opto5() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(counts = {IRNode.STORE, "0"}) // not fail + @IR(counts = {"call", "1"}) + public void opto6() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @Test + @IR(counts = {"call", "10"}) + @IR(counts = {"call", "1"}) + public void opto7() { + for (int i = 0; i < 100; i++) { + dontInline(); + } + } + + @DontInline + private void dontInline() {} +} + + // Used only by class Traps class NotLoaded { NotLoadedHelper notLoadedFld; From e378020934a7cb12fc5b49425cd6edbd7abba52d Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 6 Apr 2021 15:02:24 +0200 Subject: [PATCH 087/131] Finished adding Javadocs to all classes. Missing: Example tests and references to it from Javadocs, cleaned up some unused framework interface methods --- .../lib/hotspot/ir_framework/Argument.java | 1 + .../hotspot/ir_framework/ArgumentValue.java | 2 +- .../lib/hotspot/ir_framework/Arguments.java | 8 + .../test/lib/hotspot/ir_framework/Check.java | 3 +- .../lib/hotspot/ir_framework/CheckAt.java | 1 + .../CheckedTestFrameworkException.java | 1 + .../lib/hotspot/ir_framework/CompLevel.java | 1 + .../lib/hotspot/ir_framework/DontInline.java | 1 - .../hotspot/ir_framework/ForceCompile.java | 3 +- .../jdk/test/lib/hotspot/ir_framework/IR.java | 93 ++++++++- .../ir_framework/IREncodingPrinter.java | 1 - .../lib/hotspot/ir_framework/IRMatcher.java | 1 - .../test/lib/hotspot/ir_framework/Run.java | 3 +- .../lib/hotspot/ir_framework/RunInfo.java | 1 - .../lib/hotspot/ir_framework/Scenario.java | 1 - .../test/lib/hotspot/ir_framework/Test.java | 5 +- .../ir_framework/TestFormatException.java | 1 + .../hotspot/ir_framework/TestFramework.java | 186 ++++++++++++++---- .../ir_framework/TestFrameworkException.java | 1 + .../ir_framework/TestFrameworkExecution.java | 8 +- .../TestFrameworkPrepareFlags.java | 2 +- .../lib/hotspot/ir_framework/TestInfo.java | 1 - .../lib/hotspot/ir_framework/TestRun.java | 1 + .../ir_framework/TestRunException.java | 5 +- 24 files changed, 269 insertions(+), 62 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java index 2e050982ddf..bcbe958e822 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java @@ -32,6 +32,7 @@ * @see Check */ public enum Argument { + /** * Provides the default value for any kind of primitive type and object type if the class provides a default constructor. */ diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java index 1bbd2cdc64c..b4519fd4040 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java @@ -256,7 +256,7 @@ private static boolean isIntNumber(Class c) { || c.equals(long.class); } - public static boolean isFloatNumber(Class c) { + private static boolean isFloatNumber(Class c) { return c.equals(float.class) || c.equals(double.class); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java index db72d633720..fd17ba67220 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java @@ -26,6 +26,14 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +/** + * This annotation is used to specify well-defined {@link Argument} values for test methods (specifying {@link Test}) when + * used as part of a base test or checked test. + * + * @see Argument + * @see Test + * @see Check + */ @Retention(RetentionPolicy.RUNTIME) public @interface Arguments { Argument[] value(); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java index 8c155fad539..73233c4539b 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java @@ -69,7 +69,7 @@ *

  • Any other combination will result in a {@link TestFormatException}. * *

  • {@code c} is not compiled nor inlined. - *

  • {@code c} must be part of the test class. Using {@code @Check} in nested or other classes is not allowed.

  • // TODO write test for it + *
  • {@code c} must be part of the test class. Using {@code @Check} in nested or other classes is not allowed. TODO write test for it

  • *
  • {@code c} cannot specify any helper-method specific compile command annotations ({@link ForceCompile}, * {@link DontCompile}, {@link ForceInline}, {@link DontInline}).

  • * @@ -83,6 +83,7 @@ */ @Retention(RetentionPolicy.RUNTIME) public @interface Check { + /** * The unique associated {@link Test} method for this {@code @Check} annotated check method. The framework will directly * invoke the {@code @Check} method after each invocation or only after the compilation of the associated {@code @Test} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java index 36a7519c39a..cb1c059fe71 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java @@ -31,6 +31,7 @@ * @see Test */ public enum CheckAt { + /** * Invoke the {@link Check} method each time after invoking the associated {@link Test} method. */ diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java index 4639f3589b7..7596b963050 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java @@ -27,6 +27,7 @@ * Checked internal exceptions in the framework to propagate error handling. */ class CheckedTestFrameworkException extends Exception { + CheckedTestFrameworkException(String msg) { super(msg); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java index 3147238fe27..42b65231958 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java @@ -39,6 +39,7 @@ * @see DontCompile */ public enum CompLevel { + /** * Can only be used at {@link Test#compLevel()}. After the warm-up, the framework keeps invoking the test over a span * of 10s (configurable by setting the property flag {@code -DWaitForCompilationTimeout}) until HotSpot compiles the diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/DontInline.java b/test/lib/jdk/test/lib/hotspot/ir_framework/DontInline.java index e5c84c01ccf..29fa6dcfe55 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/DontInline.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/DontInline.java @@ -26,7 +26,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -// Prevent method inlining during compilation /** * Prevent inlining of the associated helper method (not specifying {@link Test @Test}, * {@link Check @Check} or {@link Test @Run}). Non-helper methods are never inlined. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java index 18f95c08213..dbc822bbc59 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java @@ -40,7 +40,8 @@ *
  • {@link CompLevel#SKIP}: Does not apply to {@code @ForceCompile} and results in a * {@link TestFormatException TestFormatException}.

  • *
  • {@link CompLevel#WAIT_FOR_COMPILATION}: Does not apply to {@code @ForceCompile} and results in a - * {@link TestFormatException TestFormatException}.

  • * + * {@link TestFormatException TestFormatException}. + * *

    * Using this annotation on non-helper methods results in a {@link TestFormatException TestFormatException}. */ diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java index 60f69510bcd..37c8f9078da 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java @@ -27,18 +27,105 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +/** + * This annotation is used to define a constraint/rule/check on the resulting IR of a test method (method with {@link Test} + * annotation). A test method can define multiple {@code {@literal @}IR} rules. + *

    + * There are two kinds of checks that can be specified: + *

      + *
    • {@link #failOn()}: Specify a list of (node) regexes that should not be matched on the {@code PrintIdeal} or + * {@code PrintOptoAssembly} output.

    • + *
    • {@link #counts()}: Specify a list of ({@code regex,count}) pairs: The (node) {@code regex} should be matched + * for the specified amount in {@code count} on the {@code PrintIdeal} or {@code PrintOptoAssembly} output.

    • + *
    + * An IR rule must specify either or both of these two checks. If one or both of the checks fails, an + * {@link IRViolationException} is thrown. + *

    + * Sometimes, the shape of an IR is changed by commonly used VM flags in such a way that an IR rule no longer applies. + * Generally, the framework does not apply any IR rules when any of the following flags are used: + * {@code -Xcomp, -XX:-UseCompiler, -XX:TieredStopAtLevel={1,2,3}, -XX:CompileThreshold=XX, -DStressCC=true} + * An IR rule can specify additional preconditions on the remaining flags that must hold when an IR rule is applied. + * If the specified preconditions fail, then the framework does not apply the IR rule. These preconditions can be + * set with {@link #applyIf()}, {@link #applyIfNot()}, {@link #applyIfAnd()}, or {@link #applyIfOr()}. + * + * @see Test + */ @Retention(RetentionPolicy.RUNTIME) @Repeatable(IRs.class) public @interface IR { - // Regular expression used to match forbidden IR nodes - // in the C2 IR emitted for this test. + + /** + * Define a list of (node) regexes. If any of these regexes are matched on the PrintIdeal or PrintOptoAssembly, the + * IR rule fails and an {@link IRViolationException} is thrown. + */ String[] failOn() default {}; - // Regular expressions used to match and count IR nodes. + /** + * Define a list of ((node) regexes,count) string pairs: A regex to be matched on the PrintIdeal or PrintOptoAssembly + * is immediately followed by a number specifying how often the regex should be matched. The number can be proceeded + * by comparators ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is + * specified). + *

    + * If any constraint on the number of regexes cannot be met, the IR rule fails and an + * {@link IRViolationException} is thrown. + */ String[] counts() default {}; + /** + * Define a single VM flag precondition which must hold when applying the IR rule. If the VM flag precondition + * fails, then the IR rule is not applied. This is useful if a commonly used flag alters the IR in such a way that an IR rule + * would fail. + *

    + * The precondition is a (flag, value) string pair where the flag must be a valid VM flag and the value must conform + * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator + * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). + *

    + * This is the inverse of {@link #applyIfNot()}. For multiple preconditions, use {@link #applyIfAnd()} or + * {@link #applyIfOr()} depending on the use case. + */ String[] applyIf() default {}; + + /** + * Define a single VM flag precondition which must not hold when applying the IR rule. If, however, + * the VM flag precondition holds, then the IR rule is not applied. This could also be defined as negative + * precondition. This is useful if a commonly used flag alters the IR in such a way that an IR rule would fail. + *

    + * The precondition is a (flag, value) string pair where the flag must be a valid VM flag and the value must conform + * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator + * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). + *

    + * This is the inverse of {@link #applyIf()}. For multiple preconditions, use {@link #applyIfAnd()} or + * {@link #applyIfOr()} depending on the use case. + */ String[] applyIfNot() default {}; + + /** + * Define a list of at least two VM flag precondition which all must hold when applying the IR rule. + * If the one of the VM flag preconditions does not hold, then the IR rule is not applied. This is useful if + * commonly used flags alter the IR in such a way that an IR rule would fail. This can also be defined as conjunction + * of preconditions. + *

    + * A precondition is a (flag, value) string pair where the flag must be a valid VM flag and the value must conform + * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator + * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). + *

    + * Use {@link #applyIfOr()} for disjunction and for single precondition constraints use {@link #applyIf()} or + * {@link #applyIfNot()} depending on the use case. + */ String[] applyIfAnd() default {}; + + /** + * Define a list of at least two VM flag precondition from which at least one must hold when applying + * the IR rule. If none of the VM flag preconditions holds, then the IR rule is not applied. This is useful if + * commonly used flags alter the IR in such a way that an IR rule would fail. This can also be defined as disjunction + * of preconditions. + *

    + * A precondition is a (flag, value) string pair where the flag must be a valid VM flag and the value must conform + * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator + * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). + *

    + * Use {@link #applyIfOr()} for conjunction and for single precondition constraints use {@link #applyIf()} or + * {@link #applyIfNot()} depending on the use case. + */ String[] applyIfOr() default {}; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java index 7eb547ecba3..78c7bfeb207 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java @@ -221,7 +221,6 @@ private boolean checkBooleanFlag(String flag, String value, Boolean actualFlagVa return booleanValue == actualBooleanFlagValue; } - private boolean checkLongFlag(String flag, String value, Long actualFlagValue) { long actualLongFlagValue = actualFlagValue; long longValue; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java index 152f7cb0fee..c91eb846966 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java @@ -474,7 +474,6 @@ private void reportFailuresIfAny() { * Helper class to store information about a method that needs to be IR matched. */ class IRMethod { - final private Method method; final private Integer[] ruleIds; final private IR[] irAnnos; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java index 41f3f84f026..b020201d2f8 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java @@ -76,7 +76,7 @@ *

  • Any other combination will result in a {@link TestFormatException}. * *

  • {@code t} and {@code r} must be part of the test class. Using {@code @Run} and ({@code @Test})in nested or - * other classes is not allowed.

  • // TODO write test for it + * other classes is not allowed. TODO write test for it *
  • {@code t} and {@code r} cannot specify any helper-method specific compile command annotations * ({@link ForceCompile}, {@link DontCompile}, {@link ForceInline}, {@link DontInline}).

  • * @@ -85,6 +85,7 @@ */ @Retention(RetentionPolicy.RUNTIME) public @interface Run { + /** * The associated {@link Test} methods (one or more) for for this {@code Run} annotated run method. * The framework directly invokes the run method instead of the associated {@code Test} methods. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java index 0f7818ce06d..976d1ff3b99 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java @@ -34,7 +34,6 @@ * @see Run */ public class RunInfo extends AbstractInfo { - private final Method testMethod; private final Map testMethods; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java index e7b1414603e..132ac5f2603 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java @@ -35,7 +35,6 @@ * {@link TestFramework#addFlags(String...)} whereas scenario flags will have precedence. */ public class Scenario { - private static final String ADDITIONAL_SCENARIO_FLAGS = System.getProperty("ScenarioFlags", ""); private static final String SCENARIOS = System.getProperty("Scenarios", ""); private static final List additionalScenarioFlags = new ArrayList<>(); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java index c5a4c3215b5..f70e3c6b54d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java @@ -30,7 +30,7 @@ * Annotate all methods in your test class which the framework should test with {@code @Test}. *

    * Let {@code m} be a test method specifying the {@code @Test} annotation. If {@code m} is neither part of a - * checked test (an additiona method specifying {@link Check} with (@code @Run(test = "m") nor part of a + * checked test (an additional method specifying {@link Check} with (@code @Run(test = "m") nor part of a * custom run test (an additional method specifying {@link Run} with (@code @Run(test = "m"))), * then {@code m} is a so-called base test and the the framework invokes {@code m} in the following way: *

      @@ -53,7 +53,7 @@ *
    1. If {@code m} specifies parameters, the framework needs to know how to call {@code m}. Use {@link Arguments} * with {@link Argument} properties for each parameter to use some well-defined parameters. If the method requires * a more specific argument value, use a custom run test (see {@link Run}).

    2. - * li>

      {@code m} cannot specify {@link AbstractInfo} or any of its subclasses as parameter or return type. + *

    3. {@code m} cannot specify {@link AbstractInfo} or any of its subclasses as parameter or return type.

    4. *
    5. {@code m} is not inlined by the framework.

    6. *
    7. Verification of the return value of {@code m} can only be done in a checked test (see {@link Check}) or * custom run test (see {@link Run}).

    8. @@ -73,6 +73,7 @@ */ @Retention(RetentionPolicy.RUNTIME) public @interface Test { + /** * Specify at which compilation level the framework should eventually compile the test method after an optional * warmup period. The default {@link CompLevel#ANY} will let the framework compile the method at the highest diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java index 684b36d384a..2e27bde553c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java @@ -27,6 +27,7 @@ * Exception that is thrown if a JTreg test violates the supported format by the test framework. */ public class TestFormatException extends RuntimeException { + TestFormatException(String message) { super(message); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index ab80fe95361..4ae9c5a9dbf 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -40,27 +40,75 @@ import java.util.stream.Collectors; /** - * Use this framework by using the following JTreg setup in your "some.package.Test" + * This class represents the main entry point to the test framework whose main purpose is to perform regex-based checks on + * the IR shape emitted by the VM flags {@code -XX:+PrintIdeal} and {@code -XX:+PrintOptoAssembly}. The framework can also + * be used for other non-IR matching (and non-compiler) tests by providing easy to use annotations for commonly used + * testing patterns and compiler control flags. + *

      + * The framework offers various annotations to control how your code should be invoked and being tested. There are + * three kinds of tests depending on how much control is needed over the test invocation: + * Base tests (see {@link Test}), checked tests (see {@link Check}), and custom run tests + * (see {@link Run}). Each type of test needs to define a unique test method that specifies a {@link Test} + * annotation which represents the test code that is eventually executed by the test framework. More information about + * the usage and how to write different tests can be found in {@link Test}, {@link Check}, and {@link Run}. + *

      + * Each test method can specify an arbitrary number of IR rules. This is done by using {@link IR} annotations which + * can define regex strings that are matched on the output of {@code -XX:+PrintIdeal} and {@code -XX:+PrintOptoAssembly}. + * The matching is done after the test method was (optionally) warmed up and compiled. More information about the usage + * and how to write different IR rules can be found at {@link IR}. + *

      + * This framework should be used with the following JTreg setup in your Test.java file in package some.package: + *

        * {@literal @}library /test/lib
        * {@literal @}run driver some.package.Test
      + * 
      + * Note that even though the framework uses the Whitebox API internally, it is not required to build and enabel it in the + * JTreg test if the test itself is not utilizing any Whitebox features directly. + *

      + * To specify additional flags, use {@link #addFlags(String...)} or {@link #addScenarios(Scenario...)} where the latter + * can also be used to run different flag combinations (instead of specifying multiple {@code {@literal @}run} entries). + *

      + * After annotating your test code with the framework specific annotations, the framework needs to be invoked from the + * {@code main()} method of your JTreg test. There are two ways to do so. The first way is by calling the various + * {@code run()} methods of {@link TestFramework}. The second way, which gives more control, is to create a new + * {@code TestFramework} builder object on which {@link #start()} needs to be eventually called to start the testing. + *

      + * The framework is called from the driver VM in which the JTreg test is initially run by specifying {@code + * {@literal @}run driver} in the JTreg header. This strips all additionally specified JTreg VM and Java options. + * The framework creates a new flag VM with all these flags added again in order to figure out which flags are + * required to run the tests specified in the test class (e.g. {@code -XX:+PrintIdeal} and {@code -XX:+PrintOptoAssembly} + * for IR matching). + *

      + * After the flag VM terminates, it starts a new test VM which performs the execution of the specified + * tests in the test class as described in {@link Test}, {@link Check}, and {@link Run}. + *

      + * In a last step, once the test VM has terminated without exceptions, IR matching is performed if there are any IR + * rules and if no VM flags disable it (e.g. not running with {@code -Xcomp}, see {@link IR} for more details). + * The IR regex matching is done on the output of {@code -XX:+PrintIdeal} and {@code -XX:+PrintOptoAssembly} by parsing + * the hotspot_pid file of the test VM. Failing IR rules are reported by throwing a {@link IRViolationException}. + * + * @see Test + * @see Check + * @see Run + * @see IR */ public class TestFramework { static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); static final String TEST_VM_FLAGS_START = "##### TestFrameworkPrepareFlags - used by TestFramework #####"; static final String TEST_VM_FLAGS_DELIMITER = " "; static final String TEST_VM_FLAGS_END = "----- END -----"; + private static final int WARMUP_ITERATIONS = Integer.getInteger("Warmup", -1); private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); private static boolean VERIFY_IR = true; // Should we perform IR matching? private static String lastTestVMOutput; + private final Class testClass; private List> helperClasses = null; private List scenarios = null; private final List flags = new ArrayList<>(); - private final Class testClass; - private TestFrameworkSocket socket; private int defaultWarmup = -1; - private final HashMap testMethods = new HashMap<>(); + private TestFrameworkSocket socket; /* * Public interface methods @@ -76,8 +124,9 @@ public class TestFramework { public TestFramework() { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); this.testClass = walker.getCallerClass(); - initTestsMap(); - System.out.println(testClass); + if (VERBOSE) { + System.out.println("Test class: " + testClass); + } } /** @@ -93,28 +142,8 @@ public TestFramework() { public TestFramework(Class testClass) { TestRun.check(testClass != null, "Test class cannot be null"); this.testClass = testClass; - initTestsMap(); - } - - /** - * Returns a Method object that matches the specified test method name. - * - * @param mName the name of the test method - * @return the Method object matching the specified name - */ - public Method getTestMethod(String mName) { - return testMethods.get(mName); - } - - /* - * Helper method that gathers all test methods and put them in Hashtable - */ - synchronized private void initTestsMap() { - for (Method m : testClass.getDeclaredMethods()) { - Test[] testAnnos = m.getAnnotationsByType(Test.class); - if (testAnnos.length != 0) { - testMethods.put(m.getName(), m); - } + if (VERBOSE) { + System.out.println("Test class: " + testClass); } } @@ -357,64 +386,137 @@ public static String getLastTestVMOutput() { * Compile {@code m} at compilation level {@code compLevel}. {@code m} is first enqueued and might not be compiled * yet upon returning from this method. * - * @param m the method to be compiled + * @param m the method to be compiled. * @param compLevel the (valid) compilation level at which the method should be compiled. - * @throws TestRunException if compilation level is {@link CompLevel#SKIP} or {@link CompLevel#WAIT_FOR_COMPILATION} + * @throws TestRunException if compilation level is {@link CompLevel#SKIP} or {@link CompLevel#WAIT_FOR_COMPILATION}. */ public static void compile(Method m, CompLevel compLevel) { TestFrameworkExecution.compile(m, compLevel); } + /** + * Deoptimize {@code m}. + * + * @param m the method to be deoptimized. + */ public static void deoptimize(Method m) { TestFrameworkExecution.deoptimize(m); } - public void deoptimize(String mName) { - deoptimize(getTestMethod(mName)); - } - + /** + * Returns a boolean indicating if {@code m} is compiled at any level. + * + * @param m the method to be checked. + * @return {@code true} if {@code m} is compiled at any level; + * {@code false} otherwise. + */ public static boolean isCompiled(Method m) { return TestFrameworkExecution.isCompiled(m); } + /** + * Returns a boolean indicating if {@code m} is compiled with C1. + * + * @param m the method to be checked. + * @return {@code true} if {@code m} is compiled with C1; + * {@code false} otherwise. + */ public static boolean isC1Compiled(Method m) { return TestFrameworkExecution.isC1Compiled(m); } + /** + * Returns a boolean indicating if {@code m} is compiled with C2. + * + * @param m the method to be checked. + * @return {@code true} if {@code m} is compiled with C2; + * {@code false} otherwise. + */ public static boolean isC2Compiled(Method m) { return TestFrameworkExecution.isC2Compiled(m); } + /** + * Returns a boolean indicating if {@code m} is compiled at the specified {@code compLevel}. + * + * @param m the method to be checked. + * @param compLevel the compilation level. + * @return {@code true} if {@code m} is compiled at {@code compLevel}; + * {@code false} otherwise. + */ public static boolean isCompiledAtLevel(Method m, CompLevel compLevel) { return TestFrameworkExecution.isCompiledAtLevel(m, compLevel); } - public static void assertDeoptimizedByC1(Method m) { - TestFrameworkExecution.assertDeoptimizedByC1(m); + /** + * Checks if {@code m} is compiled at any level. + * + * @param m the method to be checked. + * @throws TestRunException if {@code m} is not compiled at any level. + */ + public static void assertCompiled(Method m) { + TestFrameworkExecution.assertCompiled(m); } - public static void assertDeoptimizedByC2(Method m) { - TestFrameworkExecution.assertDeoptimizedByC2(m); + /** + * Checks if {@code m} is not compiled at any level. + * + * @param m the method to be checked. + * @throws TestRunException if {@code m} is compiled at any level. + */ + public static void assertNotCompiled(Method m) { + TestFrameworkExecution.assertNotCompiled(m); } + /** + * Checks if {@code m} is compiled with C1. + * + * @param m the method to be checked. + * @throws TestRunException if {@code m} is not compiled with C1. + */ public static void assertCompiledByC1(Method m) { TestFrameworkExecution.assertCompiledByC1(m); } + /** + * Checks if {@code m} is compiled with C2. + * + * @param m the method to be checked. + * @throws TestRunException if {@code m} is not compiled with C2. + */ public static void assertCompiledByC2(Method m) { TestFrameworkExecution.assertCompiledByC2(m); } + /** + * Checks if {@code m} is compiled with at the specified {@code compLevel}. + * + * @param m the method to be checked. + * @param compLevel the compilation level. + * @throws TestRunException if {@code m} is not compiled at {@code compLevel}. + */ public static void assertCompiledAtLevel(Method m, CompLevel compLevel) { TestFrameworkExecution.assertCompiledAtLevel(m, compLevel); } - public static void assertNotCompiled(Method m) { - TestFrameworkExecution.assertNotCompiled(m); + /** + * Checks if {@code m} was deoptimized after being C1 compiled. + * + * @param m the method to be checked. + * @throws TestRunException if {@code m} is was not deoptimized after being C1 compiled. + */ + public static void assertDeoptimizedByC1(Method m) { + TestFrameworkExecution.assertDeoptimizedByC1(m); } - public static void assertCompiled(Method m) { - TestFrameworkExecution.assertCompiled(m); + /** + * Checks if {@code m} was deoptimized after being C2 compiled. + * + * @param m the method to be checked. + * @throws TestRunException if {@code m} is was not deoptimized after being C2 compiled. + */ + public static void assertDeoptimizedByC2(Method m) { + TestFrameworkExecution.assertDeoptimizedByC2(m); } /* diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java index 1dce6bcf948..fe0a4024b2d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java @@ -27,6 +27,7 @@ * Exception that is thrown if there is an internal error in the framework. This is most likely a bug in the framework. */ public class TestFrameworkException extends RuntimeException { + TestFrameworkException(String message) { super(message); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index ad3e3b0d47b..d9fde95db21 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -36,8 +36,12 @@ import java.util.stream.Collectors; import java.util.stream.Stream; - -public class TestFrameworkExecution { +/** + * This class' main method is called from {@link TestFramework} and represents the so-called "test VM". The class is + * the heart of the framework and is responsible for executing all the specified tests in the test class. It uses the + * Whitebox API and reflection to achieve this task. + */ +class TestFrameworkExecution { private static final WhiteBox WHITE_BOX; static { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java index 92651c00de1..30bc72388ba 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java @@ -33,7 +33,7 @@ /** * This class' main method is called from {@link TestFramework} and represents the so-called "flag VM". It uses the - * Whitebox to determine the necessary additional flags to run the test VM (e.g. to do IR matching). It returns + * Whitebox API to determine the necessary additional flags to run the test VM (e.g. to do IR matching). It returns * the flags over the dedicated TestFramework socket. */ class TestFrameworkPrepareFlags { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java index dd4484f011e..5ac97531017 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java @@ -33,7 +33,6 @@ * @see Check */ public class TestInfo extends AbstractInfo { - private final Method testMethod; TestInfo(Method testMethod) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java index b0aec4a1c84..c95560be73d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java @@ -27,6 +27,7 @@ * Utility class to report a {@link TestRunException}. */ class TestRun { + public static void check(boolean test, String failureMessage) { if (!test) { throw new TestRunException(failureMessage); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java index 69b5ccc7ab7..e45b61d9ca9 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java @@ -28,11 +28,12 @@ * test class. */ public class TestRunException extends RuntimeException { - public TestRunException(String message) { + + TestRunException(String message) { super(message); } - public TestRunException(String message, Exception e) { + TestRunException(String message, Exception e) { super(message, e); } } From 59293ce593d34d6ebd500e5ee5cbe00a6db19b3f Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 6 Apr 2021 15:55:49 +0200 Subject: [PATCH 088/131] Fix TestCallingConvention after clean up --- .../inlinetypes/TestCallingConvention.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java index bfe3fcd327b..64c095d7a27 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java @@ -170,6 +170,13 @@ primitive class MixedContainer { EmptyContainer getNoInline() { return empty; } } + private void deoptimize(String name, Class... params) { + try { + TestFramework.deoptimize(getClass().getDeclaredMethod(name, params)); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } // Test interpreter to compiled code with various signatures @Test @@ -366,8 +373,7 @@ public void test12_verifier() { public long test13_interp(MyValue2 v, MyValue1[] va, boolean deopt) { if (deopt) { // uncommon trap - Method m = testFramework.getTestMethod("test13"); - TestFramework.deoptimize(m); + deoptimize("test13", MyValue2.class, MyValue1[].class, boolean.class, long.class); } return v.hash() + va[0].hash() + va[1].hash(); } @@ -393,8 +399,7 @@ public void test13_verifier(RunInfo info) { public MyValue2 test14_interp(boolean deopt) { if (deopt) { // uncommon trap - Method m = testFramework.getTestMethod("test14"); - TestFramework.deoptimize(m); + deoptimize("test14", boolean.class); } return MyValue2.createWithFieldsInline(rI, rD); } @@ -717,8 +722,7 @@ public void test31_verifier() throws Exception { public MyValue2 test32_interp(boolean deopt) { if (deopt) { // uncommon trap - Method m = testFramework.getTestMethod("test32"); - TestFramework.deoptimize(m); + deoptimize("test32", boolean.class); } return MyValue2.createWithFieldsInline(rI+32, rD); } @@ -741,8 +745,7 @@ public void test32_verifier(RunInfo info) throws Throwable { public Object test33_interp(boolean deopt) { if (deopt) { // uncommon trap - Method m = testFramework.getTestMethod("test33"); - TestFramework.deoptimize(m); + deoptimize("test33", boolean.class); } return MyValue2.createWithFieldsInline(rI+33, rD); } From d738844b85a73e3f567ad4465075a78dca5979db Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 7 Apr 2021 13:37:22 +0200 Subject: [PATCH 089/131] Fix -DTest and -DExclude and add exception if empty set specified by user --- .../ir_framework/IREncodingPrinter.java | 4 +- .../ir_framework/NoTestsRunException.java | 38 +++++ .../hotspot/ir_framework/TestFramework.java | 20 ++- .../ir_framework/TestFrameworkExecution.java | 146 ++++++++++-------- .../ir_framework/tests/TestBasics.java | 4 +- 5 files changed, 136 insertions(+), 76 deletions(-) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/NoTestsRunException.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java index 78c7bfeb207..cf7132e83fd 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java @@ -58,12 +58,12 @@ public IREncodingPrinter() { * - indices of all @IR rules that should be applied, separated by a comma * - "-1" if no @IR rule should not be applied */ - public void emitRuleEncoding(Method m, CompLevel compLevel) { + public void emitRuleEncoding(Method m, boolean skipped) { method = m; int i = 0; ArrayList validRules = new ArrayList<>(); IR[] irAnnos = m.getAnnotationsByType(IR.class); - if (compLevel != CompLevel.SKIP) { + if (!skipped) { for (IR irAnno : irAnnos) { ruleIndex = i + 1; try { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/NoTestsRunException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/NoTestsRunException.java new file mode 100644 index 00000000000..5f4f492176c --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/NoTestsRunException.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +/** + * Exception that is thrown by the test VM if no tests are run as a result of specifying {@code -DTest} and/or + * {@code -DExclude} defining an empty set with the used test VM flags. + */ +public class NoTestsRunException extends RuntimeException { + + NoTestsRunException() { + } + + NoTestsRunException(String message) { + super(message); + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 4ae9c5a9dbf..f66f182ca4b 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -70,7 +70,7 @@ *

      * After annotating your test code with the framework specific annotations, the framework needs to be invoked from the * {@code main()} method of your JTreg test. There are two ways to do so. The first way is by calling the various - * {@code run()} methods of {@link TestFramework}. The second way, which gives more control, is to create a new + * {@code runXX()} methods of {@link TestFramework}. The second way, which gives more control, is to create a new * {@code TestFramework} builder object on which {@link #start()} needs to be eventually called to start the testing. *

      * The framework is called from the driver VM in which the JTreg test is initially run by specifying {@code @@ -100,7 +100,7 @@ public class TestFramework { private static final int WARMUP_ITERATIONS = Integer.getInteger("Warmup", -1); private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); - private static boolean VERIFY_IR = true; // Should we perform IR matching? + private boolean shouldVerifyIR = true; // Should we perform IR matching? private static String lastTestVMOutput; private final Class testClass; @@ -680,7 +680,7 @@ private void checkFlagVMExitCode(OutputAnalyzer oa) { private void runTestVM(List additionalFlags, Scenario scenario) { List cmds = prepareTestVMFlags(additionalFlags); - if (VERIFY_IR) { + if (shouldVerifyIR) { // We only need the socket if we are doing IR verification. socket.start(); } @@ -702,7 +702,7 @@ private void runTestVM(List additionalFlags, Scenario scenario) { scenario.setTestVMOutput(lastTestVMOutput); } checkTestVMExitCode(output); - if (VERIFY_IR) { + if (shouldVerifyIR) { new IRMatcher(output.getHotspotPidFileName(), socket.getOutput(), testClass); } else { System.out.println("IR Verification disabled either through explicitly setting -DVerify=false or due to " + @@ -737,7 +737,7 @@ private List prepareTestVMFlags(List additionalFlags) { } - if (VERIFY_IR) { + if (shouldVerifyIR) { // Add server property flag that enables test VM to print encoding for IR verification last. cmds.add(socket.getPortPropertyFlag()); } @@ -764,11 +764,11 @@ private List getTestVMFlags() { } Matcher matcher = pattern.matcher(flags); check(matcher.find(), "Invalid flag encoding emitted by flag VM"); - VERIFY_IR = Boolean.parseBoolean(matcher.group(2)); + shouldVerifyIR = Boolean.parseBoolean(matcher.group(2)); return new ArrayList<>(Arrays.asList(matcher.group(1).split(TEST_VM_FLAGS_DELIMITER))); } - private static void checkTestVMExitCode(JVMOutput vmOutput) { + private void checkTestVMExitCode(JVMOutput vmOutput) { final int exitCode = vmOutput.getExitCode(); if (VERBOSE && exitCode == 0) { System.out.println("--- OUTPUT TestFramework test VM ---"); @@ -780,13 +780,17 @@ private static void checkTestVMExitCode(JVMOutput vmOutput) { } } - private static void throwTestVMException(JVMOutput vmOutput) { + private void throwTestVMException(JVMOutput vmOutput) { String stdErr = vmOutput.getStderr(); if (stdErr.contains("TestFormat.reportIfAnyFailures")) { Pattern pattern = Pattern.compile("Violations \\(\\d+\\)[\\s\\S]*(?=/============/)"); Matcher matcher = pattern.matcher(stdErr); TestFramework.check(matcher.find(), "Must find violation matches"); throw new TestFormatException("\n\n" + matcher.group()); + } else if (stdErr.contains("NoTestsRunException")) { + shouldVerifyIR = false; + throw new NoTestsRunException(">>> No tests run either due to empty set specified with -DTest and/or -DExclude" + + " or due to explicitly skipping tests with @Test(compLevel = CompLevel.SKIP)"); } else { throw new TestVMException(vmOutput); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index d9fde95db21..9aba8cb9ed9 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -41,7 +41,7 @@ * the heart of the framework and is responsible for executing all the specified tests in the test class. It uses the * Whitebox API and reflection to achieve this task. */ -class TestFrameworkExecution { +public class TestFrameworkExecution { private static final WhiteBox WHITE_BOX; static { @@ -64,6 +64,13 @@ assertions from main() of your test! } } + /** + * The default number of warm-up iterations used to warm up a {@link Test} annotated test method. + * Use {@code -DWarmup=XY} to specify a different default value. An individual warm-up can also be + * set by specifying a {@link Warmup} iteration for a test. + */ + public static final int WARMUP_ITERATIONS = Integer.parseInt(System.getProperty("Warmup", "2000")); + private static final boolean TIERED_COMPILATION = (Boolean)WHITE_BOX.getVMFlag("TieredCompilation"); private static final CompLevel TIERED_COMPILATION_STOP_AT_LEVEL = CompLevel.forValue(((Long)WHITE_BOX.getVMFlag("TieredStopAtLevel")).intValue()); static final boolean TEST_C1 = TIERED_COMPILATION && TIERED_COMPILATION_STOP_AT_LEVEL.getValue() < CompLevel.C2.getValue(); @@ -75,9 +82,8 @@ assertions from main() of your test! static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); static final boolean STRESS_CC = Boolean.parseBoolean(System.getProperty("StressCC", "false")); - private static final String TESTLIST = System.getProperty("Testlist", ""); + private static final String TESTLIST = System.getProperty("Test", ""); private static final String EXCLUDELIST = System.getProperty("Exclude", ""); - public static final int WARMUP_ITERATIONS = Integer.parseInt(System.getProperty("Warmup", "2000")); private static final boolean DUMP_REPLAY = Boolean.parseBoolean(System.getProperty("DumpReplay", "false")); private static final boolean GC_AFTER = Boolean.parseBoolean(System.getProperty("GCAfter", "false")); private static final boolean SHUFFLE_TESTS = Boolean.parseBoolean(System.getProperty("ShuffleTests", "true")); @@ -88,7 +94,7 @@ assertions from main() of your test! private static final boolean FLIP_C1_C2 = Boolean.parseBoolean(System.getProperty("FlipC1C2", "false")); private final HashMap declaredTests = new HashMap<>(); - private final LinkedHashMap allTests = new LinkedHashMap<>(); // Keep order + private final List allTests = new ArrayList<>(); // Keep order private final HashMap testMethodMap = new HashMap<>(); private final List excludeList; private final List testList; @@ -227,6 +233,9 @@ private void parseTests() { // All remaining tests are simple base tests without check or specific way to run them. addBaseTests(); + if (PRINT_VALID_IR_RULES) { + irMatchRulePrinter.emit(); + } TestFormat.reportIfAnyFailures(); declaredTests.clear(); testMethodMap.clear(); @@ -238,7 +247,11 @@ private void addBaseTests() { try { Arguments argumentsAnno = getAnnotation(m, Arguments.class); TestFormat.check(argumentsAnno != null || m.getParameterCount() == 0, "Missing @Arguments annotation to define arguments of " + m); - allTests.put(m, new BaseTest(test)); + BaseTest baseTest = new BaseTest(test, shouldExcludeTest(m.getName())); + allTests.add(baseTest); + if (PRINT_VALID_IR_RULES) { + irMatchRulePrinter.emitRuleEncoding(m, baseTest.isSkipped()); + } } catch (TestFormatException e) { // Failure logged. Continue and report later. } @@ -246,6 +259,20 @@ private void addBaseTests() { }); } + /** + * Check if user wants to exclude this test by checking the -DTest and -DExclude lists. + */ + private boolean shouldExcludeTest(String testName) { + boolean hasTestList = testList != null; + boolean hasExcludeList = excludeList != null; + if (hasTestList) { + return !testList.contains(testName) || (hasExcludeList && excludeList.contains(testName)); + } else if (hasExcludeList) { + return excludeList.contains(testName); + } + return false; + } + private void addReplay() { if (DUMP_REPLAY) { // Generate replay compilation files @@ -432,23 +459,11 @@ static boolean shouldCompile(Executable ex) { } private void setupTests() { - boolean hasTestList = testList != null; - boolean hasExcludeList = excludeList != null; for (Method m : testClass.getDeclaredMethods()) { Test testAnno = getAnnotation(m, Test.class); try { if (testAnno != null) { - if (hasTestList) { - if (testList.contains(m.getName()) && (!hasExcludeList || !excludeList.contains(m.getName()))) { - addTest(m); - } - } else if (hasExcludeList) { - if (!excludeList.contains(m.getName())) { - addTest(m); - } - } else { - addTest(m); - } + addDeclaredTest(m); } else { TestFormat.checkNoThrow(!m.isAnnotationPresent(IR.class), "Found @IR annotation on non-@Test method " + m); TestFormat.checkNoThrow(!m.isAnnotationPresent(Warmup.class) || getAnnotation(m, Run.class) != null, @@ -459,12 +474,9 @@ private void setupTests() { } } TestFormat.checkNoThrow(!declaredTests.isEmpty(), "Did not specify any @Test methods in " + testClass); - if (PRINT_VALID_IR_RULES) { - irMatchRulePrinter.emit(); - } } - private void addTest(Method m) { + private void addDeclaredTest(Method m) { Test testAnno = getAnnotation(m, Test.class); checkTestAnnotations(m, testAnno); Warmup warmup = getAnnotation(m, Warmup.class); @@ -474,10 +486,6 @@ private void addTest(Method m) { TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + m); } - if (PRINT_VALID_IR_RULES) { - irMatchRulePrinter.emitRuleEncoding(m, testAnno.compLevel()); - } - if (!XCOMP) { // Don't inline test methods. Don't care when -Xcomp set. WHITE_BOX.testSetDontInlineMethod(m, true); @@ -580,8 +588,11 @@ private void addCheckedTest(Method m, Check checkAnno, Run runAnno) { dontCompileMethod(m); // Don't inline check methods WHITE_BOX.testSetDontInlineMethod(m, true); - CheckedTest checkedTest = new CheckedTest(test, m, checkAnno, parameter); - allTests.put(testMethod, checkedTest); + CheckedTest checkedTest = new CheckedTest(test, m, checkAnno, parameter, shouldExcludeTest(m.getName())); + allTests.add(checkedTest); + if (PRINT_VALID_IR_RULES) { + irMatchRulePrinter.emitRuleEncoding(m, checkedTest.isSkipped()); + } } private void checkCheckedTest(Method m, Check checkAnno, Run runAnno, Method testMethod, DeclaredTest test) { @@ -637,8 +648,11 @@ private void addCustomRunTest(Method m, Run runAnno) { dontCompileMethod(m); // Don't inline run methods WHITE_BOX.testSetDontInlineMethod(m, true); - CustomRunTest customRunTest = new CustomRunTest(m, getAnnotation(m, Warmup.class), runAnno, tests); - allTests.put(m, customRunTest); + CustomRunTest customRunTest = new CustomRunTest(m, getAnnotation(m, Warmup.class), runAnno, tests, shouldExcludeTest(m.getName())); + allTests.add(customRunTest); + if (PRINT_VALID_IR_RULES) { + tests.forEach(test -> irMatchRulePrinter.emitRuleEncoding(test.getTestMethod(), customRunTest.isSkipped())); + } } private void checkCustomRunTest(Method m, String testName, Method testMethod, DeclaredTest test, RunMode runMode) { @@ -701,14 +715,21 @@ private void checkForcedCompilationsCompleted() { private void runTests() { TreeMap durations = (PRINT_TIMES || VERBOSE) ? new TreeMap<>() : null; long startTime = System.nanoTime(); - Collection testCollection = allTests.values(); + List testList; + if (testFilterPresent()) { + testList = allTests.stream().filter(test -> !test.isSkipped()).collect(Collectors.toList()); + if (testList.isEmpty()) { + throw new NoTestsRunException(); + } + } else { + testList = allTests; + } + if (SHUFFLE_TESTS) { // Execute tests in random order (execution sequence affects profiling) - ArrayList shuffledList = new ArrayList<>(allTests.values()); - Collections.shuffle(shuffledList); - testCollection = shuffledList; + Collections.shuffle(testList); } - for (AbstractTest test : testCollection) { + for (AbstractTest test : testList) { test.run(); if (PRINT_TIMES || VERBOSE) { long endTime = System.nanoTime(); @@ -733,6 +754,10 @@ private void runTests() { } } + private boolean testFilterPresent() { + return testList != null || excludeList != null; + } + enum TriState { Maybe, Yes, @@ -935,13 +960,19 @@ abstract class AbstractTest { protected static final boolean VERIFY_OOPS = (Boolean)WHITE_BOX.getVMFlag("VerifyOops"); protected final int warmupIterations; + protected final boolean skip; - AbstractTest(int warmupIterations) { + AbstractTest(int warmupIterations, boolean skip) { this.warmupIterations = warmupIterations; + this.skip = skip; } abstract String getName(); + public boolean isSkipped() { + return skip; + } + protected static boolean isWaitForCompilation(DeclaredTest test) { return test.getCompLevel() == CompLevel.WAIT_FOR_COMPILATION; } @@ -968,21 +999,20 @@ protected static Object createInvocationTarget(Method method) { * Run the associated test */ public void run() { - if (!onRunStart()) { - // Skip this test if set fails. + if (skip) { return; } + onRunStart(); for (int i = 0; i < warmupIterations; i++) { invokeTest(); } - onWarmupFinished(); compileTest(); // Always run method. invokeTest(); } - abstract boolean onRunStart(); + abstract void onRunStart(); abstract void invokeTest(); @@ -993,10 +1023,10 @@ protected void onWarmupFinished() { } protected void compileMethod(DeclaredTest test) { final Method testMethod = test.getTestMethod(); TestRun.check(WHITE_BOX.isMethodCompilable(testMethod, test.getCompLevel().getValue(), false), - "Method" + testMethod + " not compilable at level " + test.getCompLevel() + "Method " + testMethod + " not compilable at level " + test.getCompLevel() + ". Did you use compileonly without including all @Test methods?"); TestRun.check(WHITE_BOX.isMethodCompilable(testMethod), - "Method" + testMethod + " not compilable at level " + test.getCompLevel() + "Method " + testMethod + " not compilable at level " + test.getCompLevel() + ". Did you use compileonly without including all @Test methods?"); if (TestFramework.VERBOSE) { System.out.println("Compile method " + testMethod + " after warm-up..."); @@ -1097,8 +1127,8 @@ class BaseTest extends AbstractTest { private final boolean shouldCompile; private final boolean waitForCompilation; - public BaseTest(DeclaredTest test) { - super(test.getWarmupIterations()); + public BaseTest(DeclaredTest test, boolean excludedByUser) { + super(test.getWarmupIterations(), excludedByUser ? excludedByUser : test.getCompLevel() == CompLevel.SKIP); this.test = test; this.testMethod = test.getTestMethod(); this.testInfo = new TestInfo(testMethod); @@ -1113,16 +1143,11 @@ public String getName() { } @Override - protected boolean onRunStart() { - if (test.getCompLevel() == CompLevel.SKIP) { - // Exclude test if compilation level is SKIP either set through test or by not matching the current VM flags. - return false; - } + protected void onRunStart() { if (TestFrameworkExecution.VERBOSE) { System.out.println("Starting " + getName()); } test.printFixedRandomArguments(); - return true; } @Override @@ -1176,8 +1201,8 @@ enum Parameter { NONE, RETURN_ONLY, TEST_INFO_ONLY, BOTH } - public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecification, Parameter parameter) { - super(test); + public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecification, Parameter parameter, boolean excludedByUser) { + super(test, excludedByUser); // Make sure we can also call non-public or public methods in package private classes checkMethod.setAccessible(true); this.checkMethod = checkMethod; @@ -1227,9 +1252,10 @@ class CustomRunTest extends AbstractTest { private final List tests; private final RunInfo runInfo; - public CustomRunTest(Method runMethod, Warmup warmUpAnno, Run runSpecification, List tests) { + public CustomRunTest(Method runMethod, Warmup warmUpAnno, Run runSpecification, List tests, boolean excludedByUser) { // Make sure we can also call non-public or public methods in package private classes - super(warmUpAnno != null ? warmUpAnno.value() : TestFrameworkExecution.WARMUP_ITERATIONS); + super(warmUpAnno != null ? warmUpAnno.value() : TestFrameworkExecution.WARMUP_ITERATIONS, + excludedByUser ? excludedByUser : tests.stream().anyMatch(t -> t.getCompLevel() == CompLevel.SKIP)); TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + runMethod); runMethod.setAccessible(true); this.runMethod = runMethod; @@ -1244,16 +1270,10 @@ public CustomRunTest(Method runMethod, Warmup warmUpAnno, Run runSpecification, } @Override - protected boolean onRunStart() { - if (tests.stream().anyMatch(t -> t.getCompLevel() == CompLevel.SKIP)) { - // Exclude test if any compilation level is SKIP either set through test or by not matching the current VM flags. - return false; - } - + protected void onRunStart() { if (TestFrameworkExecution.VERBOSE) { System.out.println("Starting " + getName()); } - return true; } @Override @@ -1263,11 +1283,9 @@ String getName() { @Override public void run() { - if (!onRunStart()) { - // Skip this test if set fails. + if (skip) { return; } - switch (mode) { case STANDALONE -> { runInfo.setWarmUpFinished(); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java index a7822109b40..9239ab971f0 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java @@ -51,8 +51,8 @@ public static void main(String[] args) throws Exception { int value = executed[i]; if (value != TestFrameworkExecution.WARMUP_ITERATIONS + 1) { // Warmups + 1 C2 compiled invocation - throw new RuntimeException("Test " + i + " was executed " + value + " times stead of " - + TestFrameworkExecution.WARMUP_ITERATIONS + 1 + " times." ); + throw new RuntimeException("Test " + i + " was executed " + value + " times instead stead of " + + (TestFrameworkExecution.WARMUP_ITERATIONS + 1) + " times." ); } } From f29d742b5f5bed8eb2c7249cf4008a0d54aee219 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 7 Apr 2021 14:04:45 +0200 Subject: [PATCH 090/131] Cleanup and fix tests to achieve minimal number of changes --- .../ExampleTestNullableInlineTypes.java | 116 ------------- .../ExampleTestUnloadedInlineTypeField.java | 95 ---------- .../inlinetypes/TestCallingConvention.java | 164 +++++++++--------- .../inlinetypes/TestCallingConventionC1.java | 1 - .../valhalla/inlinetypes/TestIntrinsics.java | 1 - .../valhalla/inlinetypes/TestLWorld.java | 89 +++++----- .../inlinetypes/TestNullableArrays.java | 120 ++++++------- .../TestFrameworkPrepareFlags.java | 2 +- 8 files changed, 185 insertions(+), 403 deletions(-) delete mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestNullableInlineTypes.java delete mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestUnloadedInlineTypeField.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestNullableInlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestNullableInlineTypes.java deleted file mode 100644 index 959ff95af88..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestNullableInlineTypes.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2020, 2021, 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. - */ - -/* - * @test - * @key randomness - * @summary Test correct handling of nullable inline types. - * @library /test/lib - * @compile InlineTypes.java - * @run driver compiler.valhalla.inlinetypes.ExampleTestNullableInlineTypes - */ - -package compiler.valhalla.inlinetypes; - -import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; - -import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; - -public class ExampleTestNullableInlineTypes { - private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(InlineTypes.rI, InlineTypes.rL); - - public static void main(String[] args) { - Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; - scenarios[3].addFlags("-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"); - scenarios[4].addFlags("-XX:-MonomorphicArrayCheck"); - TestFramework testFramework = new TestFramework(ExampleTestNullableInlineTypes.class); - testFramework.addScenarios(scenarios) - .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class) - .start(); - } - - // Test writing null to a flattenable/non-flattenable inline type field in an inline type - final primitive class Test21Value { - final MyValue1.ref valueField1; - final MyValue1 valueField2; - final MyValue1.ref alwaysNull = null; - - @ForceInline - public Test21Value(MyValue1.ref valueField1, MyValue1 valueField2) { - this.valueField1 = testValue1; - this.valueField2 = testValue1; - } - - @ForceInline - public Test21Value test1() { - return new Test21Value(alwaysNull, this.valueField2); // Should not throw NPE - } - - @ForceInline - public Test21Value test2() { - return new Test21Value(this.valueField1, (MyValue1) alwaysNull); // Should throw NPE - } - } - - @Test - public Test21Value test21(Test21Value vt) { - vt = vt.test1(); - try { - vt = vt.test2(); - throw new RuntimeException("NullPointerException expected"); - } catch (NullPointerException e) { - // Expected - } - return vt; - } - - @Run(test = "test21") - public void test21_verifier() { - test21(Test21Value.default); - } - - - @DontInline - public void test25_callee(MyValue1 val) { } - - // Test that when checkcasting from null-ok to null-free and back to null-ok we - // keep track of the information that the inline type can never be null. - @Test - @IR(failOn = {ALLOC, STORE}) - public int test25(boolean b, MyValue1.ref vt1, MyValue1 vt2) { - vt1 = (MyValue1)vt1; - Object obj = b ? vt1 : vt2; // We should not allocate here - test25_callee((MyValue1) vt1); - return ((MyValue1)obj).x; - } - - @Run(test = "test25") - public void test25_verifier() { - int res = test25(true, testValue1, testValue1); - Asserts.assertEquals(res, testValue1.x); - res = test25(false, testValue1, testValue1); - Asserts.assertEquals(res, testValue1.x); - } -} - diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestUnloadedInlineTypeField.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestUnloadedInlineTypeField.java deleted file mode 100644 index 448fbc47f85..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/ExampleTestUnloadedInlineTypeField.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2019, 2021, 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. - */ - -/* - * @test - * @key randomness - * @summary Test the handling of fields of unloaded inline classes. - * @library /test/lib - * @compile InlineTypes.java - * @run driver compiler.valhalla.inlinetypes.ExampleTestUnloadedInlineTypeField - */ -package compiler.valhalla.inlinetypes; - -import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; - -public class ExampleTestUnloadedInlineTypeField { - - public static void main(String[] args) { - Scenario s0 = new Scenario(0); - Scenario s1 = new Scenario(1, "-XX:InlineFieldMaxFlatSize=0"); - Scenario s2 = new Scenario(2, "-XX:+PatchALot"); - Scenario s3 = new Scenario(3, "-XX:InlineFieldMaxFlatSize=0", "-XX:+PatchALot"); - TestFramework.runWithScenarios(s0, s1, s2, s3); - } - - // Test case 1: - // The inline type field class has been loaded, but the holder class has not been loaded. - // - // aload_0 - // getfield MyValue1Holder.v:QMyValue1; - // ^ not loaded ^ already loaded - // - // MyValue1 has already been loaded, because it's in the InlineType attribute of - // TestUnloadedInlineTypeField, due to TestUnloadedInlineTypeField.test1_precondition(). - static final primitive class MyValue1 { - final int foo; - - MyValue1() { - foo = InlineTypes.rI; - } - } - - static class MyValue1Holder { - MyValue1 v; - - public MyValue1Holder() { - v = new MyValue1(); - } - } - - static MyValue1 test1_precondition() { - return new MyValue1(); - } - - @Test - public int test1(Object holder) { - if (holder != null) { - // Don't use MyValue1Holder in the signature, it might trigger class loading - return ((MyValue1Holder)holder).v.foo; - } else { - return 0; - } - } - - @Run(test = "test1") - public void test1_verifier(RunInfo info) { - if (info.isWarmUp() && info.isC1Test()) { - test1(null); - } else { - MyValue1Holder holder = new MyValue1Holder(); - Asserts.assertEQ(test1(holder), InlineTypes.rI); - } - } -} diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java index 64c095d7a27..af55eb08e1e 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java @@ -47,8 +47,6 @@ @ForceCompileClassInitializer public class TestCallingConvention { - static MethodHandle test32_mh, test33_mh, test37_mh; - static { try { Class clazz = TestCallingConvention.class; @@ -91,85 +89,6 @@ public static void main(String[] args) { // Helper methods and classes - // Test calling convention with deep hierarchy of flattened fields - final primitive class Test27Value1 { - final Test27Value2 valueField; - - private Test27Value1(Test27Value2 val2) { - valueField = val2; - } - - @DontInline - public int test(Test27Value1 val1) { - return valueField.test(valueField) + val1.valueField.test(valueField); - } - } - - final primitive class Test27Value2 { - final Test27Value3 valueField; - - private Test27Value2(Test27Value3 val3) { - valueField = val3; - } - - @DontInline - public int test(Test27Value2 val2) { - return valueField.test(valueField) + val2.valueField.test(valueField); - } - } - - final primitive class Test27Value3 { - final int x; - - private Test27Value3(int x) { - this.x = x; - } - - @DontInline - public int test(Test27Value3 val3) { - return x + val3.x; - } - } - - primitive class Test37Value { - int x = rI; - - @DontInline - public int test() { - return x; - } - } - - primitive class EmptyContainer { - private MyValueEmpty empty; - - EmptyContainer(MyValueEmpty empty) { - this.empty = empty; - } - - @ForceInline - MyValueEmpty getInline() { return empty; } - - @DontInline - MyValueEmpty getNoInline() { return empty; } - } - - primitive class MixedContainer { - public int val; - private EmptyContainer empty; - - MixedContainer(int val, EmptyContainer empty) { - this.val = val; - this.empty = empty; - } - - @ForceInline - EmptyContainer getInline() { return empty; } - - @DontInline - EmptyContainer getNoInline() { return empty; } - } - private void deoptimize(String name, Class... params) { try { TestFramework.deoptimize(getClass().getDeclaredMethod(name, params)); @@ -645,6 +564,46 @@ public void test26_verifier() { Asserts.assertEQ(vt.hash(), MyValue2.createWithFieldsInline(rI, rD).hash()); } + // Test calling convention with deep hierarchy of flattened fields + final primitive class Test27Value1 { + final Test27Value2 valueField; + + private Test27Value1(Test27Value2 val2) { + valueField = val2; + } + + @DontInline + public int test(Test27Value1 val1) { + return valueField.test(valueField) + val1.valueField.test(valueField); + } + } + + final primitive class Test27Value2 { + final Test27Value3 valueField; + + private Test27Value2(Test27Value3 val3) { + valueField = val3; + } + + @DontInline + public int test(Test27Value2 val2) { + return valueField.test(valueField) + val2.valueField.test(valueField); + } + } + + final primitive class Test27Value3 { + final int x; + + private Test27Value3(int x) { + this.x = x; + } + + @DontInline + public int test(Test27Value3 val3) { + return x + val3.x; + } + } + @Test public int test27(Test27Value1 val) { return val.test(val); @@ -717,6 +676,7 @@ public void test31_verifier() throws Exception { // Test deoptimization at call return with inline type returned in registers. // Same as test14, except the interpreted method is called via a MethodHandle. + static MethodHandle test32_mh; @DontCompile public MyValue2 test32_interp(boolean deopt) { @@ -740,6 +700,7 @@ public void test32_verifier(RunInfo info) throws Throwable { } // Same as test32, except the return type is not flattenable. + static MethodHandle test33_mh; @DontCompile public Object test33_interp(boolean deopt) { @@ -841,6 +802,17 @@ public void test36_verifier() throws Exception { } // Test method resolution with scalarized inline type receiver at invokespecial + static final MethodHandle test37_mh; + + primitive class Test37Value { + int x = rI; + + @DontInline + public int test() { + return x; + } + } + @Test public int test37(Test37Value vt) throws Throwable { // Generates invokespecial call of Test37Value::test @@ -985,6 +957,36 @@ public void test41_verifier() { // More empty inline type tests with containers + static primitive class EmptyContainer { + private MyValueEmpty empty; + + EmptyContainer(MyValueEmpty empty) { + this.empty = empty; + } + + @ForceInline + MyValueEmpty getInline() { return empty; } + + @DontInline + MyValueEmpty getNoInline() { return empty; } + } + + static primitive class MixedContainer { + public int val; + private EmptyContainer empty; + + MixedContainer(int val, EmptyContainer empty) { + this.val = val; + this.empty = empty; + } + + @ForceInline + EmptyContainer getInline() { return empty; } + + @DontInline + EmptyContainer getNoInline() { return empty; } + } + // Empty inline type return @Test @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java index 0a7d4f9309e..a84221f0a3d 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java @@ -503,7 +503,6 @@ public void test3b_verifier(RunInfo info) { } } - // C1 passes inline type to interpreter (megamorphic: itable) @Test(compLevel = CompLevel.C1) public int test4(FunctorInterface fi) { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java index 78b4cad1617..e560c4b2648 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java @@ -552,7 +552,6 @@ public void test29_verifier() { } } - // getValue to retrieve flattened field from inline type @Test @IR(failOn = CALL_Unsafe) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java index 8697f60e4bd..5e158b08177 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java @@ -72,52 +72,10 @@ public static void main(String[] args) { private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(rI, rL); private static final MyValue2 testValue2 = MyValue2.createWithFieldsInline(rI, rD); - Object objectField1 = null; - Object objectField2 = null; - Object objectField3 = null; - Object objectField4 = null; - Object objectField5 = null; - Object objectField6 = null; - - MyValue1 valueField1 = testValue1; - MyValue1 valueField2 = testValue1; - MyValue1.ref valueField3 = testValue1; - MyValue1 valueField4; - MyValue1.ref valueField5; - - static MyValue1.ref staticValueField1 = testValue1; - static MyValue1 staticValueField2 = testValue1; - static MyValue1 staticValueField3; - static MyValue1.ref staticValueField4; - - private static final MyValue1[] testValue1Array = new MyValue1[] {testValue1, - testValue1, - testValue1}; - - private static final MyValue1[][] testValue1Array2 = new MyValue1[][] {testValue1Array, - testValue1Array, - testValue1Array}; - - private static final MyValue2[] testValue2Array = new MyValue2[] {testValue2, - testValue2, - testValue2}; - - private static final Integer[] testIntegerArray = new Integer[42]; - protected long hash() { return testValue1.hash(); } - private void rerun_and_recompile_for(Method m, int num, Runnable test) { - for (int i = 1; i < num; i++) { - test.run(); - - if (!TestFramework.isCompiled(m)) { - TestFramework.compile(m, CompLevel.C2); - } - } - } - // Test passing an inline type as an Object @DontInline public Object test1_dontinline1(Object o) { @@ -155,6 +113,23 @@ public void test1_verifier() { } // Test storing/loading inline types to/from Object and inline type fields + Object objectField1 = null; + Object objectField2 = null; + Object objectField3 = null; + Object objectField4 = null; + Object objectField5 = null; + Object objectField6 = null; + + MyValue1 valueField1 = testValue1; + MyValue1 valueField2 = testValue1; + MyValue1.ref valueField3 = testValue1; + MyValue1 valueField4; + MyValue1.ref valueField5; + + static MyValue1.ref staticValueField1 = testValue1; + static MyValue1 staticValueField2 = testValue1; + static MyValue1 staticValueField3; + static MyValue1.ref staticValueField4; @DontInline public Object readValueField5() { @@ -269,7 +244,6 @@ public void test4_verifier() { } // Test inline types in object variables that are live at safepoint - @Test @IR(failOn = {ALLOC, STORE, LOOP}) public long test5(MyValue1 arg, boolean deopt, Method m) { @@ -547,7 +521,6 @@ public void test14_verifier() { } // Test inline types in interface variables that are live at safepoint - @Test @IR(failOn = {ALLOC, STORE, LOOP}) public long test15(MyValue1 arg, boolean deopt, Method m) { @@ -654,6 +627,20 @@ public void test20_verifier() { // Array tests + private static final MyValue1[] testValue1Array = new MyValue1[] {testValue1, + testValue1, + testValue1}; + + private static final MyValue1[][] testValue1Array2 = new MyValue1[][] {testValue1Array, + testValue1Array, + testValue1Array}; + + private static final MyValue2[] testValue2Array = new MyValue2[] {testValue2, + testValue2, + testValue2}; + + private static final Integer[] testIntegerArray = new Integer[42]; + // Test load from (flattened) inline type array disguised as object array @Test() public Object test21(Object[] oa, int index) { @@ -1954,7 +1941,6 @@ public void test70Interface_verifier() { Asserts.assertEQ(result, rI * testValue1Array.length); } - // Same as test69 but with an Abstract @ForceInline public MyAbstract test70Abstract_sum(MyAbstract a, MyAbstract b) { @@ -2271,6 +2257,16 @@ public void test83_verifier(RunInfo info) { } } + private void rerun_and_recompile_for(Method m, int num, Runnable test) { + for (int i = 1; i < num; i++) { + test.run(); + + if (!TestFramework.isCompiled(m)) { + TestFramework.compile(m, CompLevel.C2); + } + } + } + // Tests for the Loop Unswitching optimization // Should make 2 copies of the loop, one for non flattened arrays, one for other cases. @Test @@ -2950,7 +2946,6 @@ public void test108_verifier(RunInfo info) { } }); } - // Escape analysis tests static interface WrapperInterface { @@ -3108,7 +3103,6 @@ public long test110() { return res; } - @Run(test = "test110") @Warmup(10000) // Make sure interface calls are inlined public void test110_verifier() { @@ -3224,7 +3218,6 @@ public void test113_sharp_verifier() { Asserts.assertEquals(res, 5*rL); } - static interface WrapperInterface2 { public long value(); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java index 2460bb8a54c..c46426d95ef 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java @@ -72,66 +72,6 @@ protected long hash(int x, long y) { return MyValue1.createWithFieldsInline(x, y).hash(); } - static void verify(Object[] src, Object[] dst) { - for (int i = 0; i < src.length; ++i) { - if (src[i] != null) { - Asserts.assertEQ(((MyInterface)src[i]).hash(), ((MyInterface)dst[i]).hash()); - } else { - Asserts.assertEQ(dst[i], null); - } - } - } - - static void verify(MyValue1.ref[] src, MyValue1.ref[] dst) { - for (int i = 0; i < src.length; ++i) { - if (src[i] != null) { - Asserts.assertEQ(src[i].hash(), dst[i].hash()); - } else { - Asserts.assertEQ(dst[i], null); - } - } - } - - static void verify(MyValue1.ref[] src, Object[] dst) { - for (int i = 0; i < src.length; ++i) { - if (src[i] != null) { - Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); - } else { - Asserts.assertEQ(dst[i], null); - } - } - } - - static void verify(MyValue2.ref[] src, MyValue2.ref[] dst) { - for (int i = 0; i < src.length; ++i) { - if (src[i] != null) { - Asserts.assertEQ(src[i].hash(), dst[i].hash()); - } else { - Asserts.assertEQ(dst[i], null); - } - } - } - - static void verify(MyValue2.ref[] src, Object[] dst) { - for (int i = 0; i < src.length; ++i) { - if (src[i] != null) { - Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); - } else { - Asserts.assertEQ(dst[i], null); - } - } - } - - static boolean compile_and_run_again_if_deoptimized(RunInfo info) { - if (!info.isWarmUp()) { - Method m = info.getTest(); - if (TestFramework.isCompiled(m)) { - TestFramework.compile(m, CompLevel.C2); - } - } - return false; - } - private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(rI, rL); // Test nullable inline type array creation and initialization @@ -1110,6 +1050,66 @@ public void test34_verifier(RunInfo info) { } } + static void verify(Object[] src, Object[] dst) { + for (int i = 0; i < src.length; ++i) { + if (src[i] != null) { + Asserts.assertEQ(((MyInterface)src[i]).hash(), ((MyInterface)dst[i]).hash()); + } else { + Asserts.assertEQ(dst[i], null); + } + } + } + + static void verify(MyValue1.ref[] src, MyValue1.ref[] dst) { + for (int i = 0; i < src.length; ++i) { + if (src[i] != null) { + Asserts.assertEQ(src[i].hash(), dst[i].hash()); + } else { + Asserts.assertEQ(dst[i], null); + } + } + } + + static void verify(MyValue1.ref[] src, Object[] dst) { + for (int i = 0; i < src.length; ++i) { + if (src[i] != null) { + Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); + } else { + Asserts.assertEQ(dst[i], null); + } + } + } + + static void verify(MyValue2.ref[] src, MyValue2.ref[] dst) { + for (int i = 0; i < src.length; ++i) { + if (src[i] != null) { + Asserts.assertEQ(src[i].hash(), dst[i].hash()); + } else { + Asserts.assertEQ(dst[i], null); + } + } + } + + static void verify(MyValue2.ref[] src, Object[] dst) { + for (int i = 0; i < src.length; ++i) { + if (src[i] != null) { + Asserts.assertEQ(src[i].hash(), ((MyInterface)dst[i]).hash()); + } else { + Asserts.assertEQ(dst[i], null); + } + } + } + + static boolean compile_and_run_again_if_deoptimized(RunInfo info) { + if (!info.isWarmUp()) { + Method m = info.getTest(); + if (TestFramework.isCompiled(m)) { + TestFramework.compile(m, CompLevel.C2); + } + } + return false; + } + // arraycopy() of inline type array of unknown size @Test public void test35(Object src, Object dst, int len) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java index 30bc72388ba..95e72007451 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java @@ -112,7 +112,7 @@ private static ArrayList prepareTestVmFlags(Class testClass) { // // TODO: Only for debugging // if (cmds.get(0).startsWith("-agentlib")) { -// cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=n,server=y"); +// cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=y,server=y"); // } From ebbe725a741c654fca9e689f96a784c1414f6c2c Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 7 Apr 2021 17:35:49 +0200 Subject: [PATCH 091/131] Fix StressCC -> ExcludeRandom --- .../lib/hotspot/ir_framework/CompLevel.java | 13 ++- .../hotspot/ir_framework/TestFramework.java | 7 +- .../ir_framework/TestFrameworkExecution.java | 107 +++++++++++------- .../TestFrameworkPrepareFlags.java | 8 +- 4 files changed, 82 insertions(+), 53 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java index 42b65231958..2f846905da7 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java @@ -28,7 +28,7 @@ /** * Compilation levels used by the framework. The compilation levels map to the used levels in HotSpot (apart from the - * framework specific value {@link #SKIP} that cannot be found in HotSpot). + * framework specific values {@link #SKIP} and {@link #WAIT_FOR_COMPILATION} that cannot be found in HotSpot). * *

      * The compilation levels can be specified in the {@link Test}, {@link ForceCompile} and {@link DontCompile} annotation. @@ -48,7 +48,7 @@ public enum CompLevel { */ WAIT_FOR_COMPILATION(-4), /** - * Can only be used at {@link Test#compLevel()}. Skip a {@link Test @Test} completely. + * Can only be used at {@link Test#compLevel()}. Skip a compilation of the {@link Test @Test} method completely. */ SKIP(-3), /** @@ -119,6 +119,15 @@ static boolean overlapping(CompLevel l1, CompLevel l2) { return l1.isC1() == l2.isC1() || (l1 == C2 && l2 == C2); } + static CompLevel join(CompLevel l1, CompLevel l2) { + return switch (l1) { + case ANY -> l2; + case C1, C1_LIMITED_PROFILE, C1_FULL_PROFILE -> l2.isC1() || l2 == ANY ? C1 : SKIP; + case C2 -> l2 == C2 || l2 == ANY ? C2 : SKIP; + default -> SKIP; + }; + } + private boolean isC1() { return this == C1 || this == C1_LIMITED_PROFILE || this == C1_FULL_PROFILE; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index f66f182ca4b..00efc2aa94c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -93,13 +93,14 @@ * @see IR */ public class TestFramework { - static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); + static final boolean VERBOSE = Boolean.getBoolean("Verbose"); static final String TEST_VM_FLAGS_START = "##### TestFrameworkPrepareFlags - used by TestFramework #####"; static final String TEST_VM_FLAGS_DELIMITER = " "; static final String TEST_VM_FLAGS_END = "----- END -----"; private static final int WARMUP_ITERATIONS = Integer.getInteger("Warmup", -1); - private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); + private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.getBoolean("PreferCommandLineFlags"); + private static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); private boolean shouldVerifyIR = true; // Should we perform IR matching? private static String lastTestVMOutput; @@ -770,7 +771,7 @@ private List getTestVMFlags() { private void checkTestVMExitCode(JVMOutput vmOutput) { final int exitCode = vmOutput.getExitCode(); - if (VERBOSE && exitCode == 0) { + if (EXCLUDE_RANDOM || (VERBOSE && exitCode == 0)) { System.out.println("--- OUTPUT TestFramework test VM ---"); System.out.println(vmOutput.getOutput()); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 9aba8cb9ed9..e86adbf1b52 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -77,21 +77,21 @@ assertions from main() of your test! // User defined settings static final boolean XCOMP = Platform.isComp(); - static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); - private static final boolean PRINT_TIMES = Boolean.parseBoolean(System.getProperty("PrintTimes", "false")); + static final boolean VERBOSE = Boolean.getBoolean("Verbose"); + private static final boolean PRINT_TIMES = Boolean.getBoolean("PrintTimes"); static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); - static final boolean STRESS_CC = Boolean.parseBoolean(System.getProperty("StressCC", "false")); + static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); private static final String TESTLIST = System.getProperty("Test", ""); private static final String EXCLUDELIST = System.getProperty("Exclude", ""); - private static final boolean DUMP_REPLAY = Boolean.parseBoolean(System.getProperty("DumpReplay", "false")); - private static final boolean GC_AFTER = Boolean.parseBoolean(System.getProperty("GCAfter", "false")); + private static final boolean DUMP_REPLAY = Boolean.getBoolean("DumpReplay"); + private static final boolean GC_AFTER = Boolean.getBoolean("GCAfter"); private static final boolean SHUFFLE_TESTS = Boolean.parseBoolean(System.getProperty("ShuffleTests", "true")); // Use separate flag as VERIFY_IR could have been set by user but due to other flags it was disabled by flag VM. private static final boolean PRINT_VALID_IR_RULES = Integer.getInteger(TestFrameworkSocket.SERVER_PORT_PROPERTY, -1) != -1; protected static final long PerMethodTrapLimit = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); protected static final boolean ProfileInterpreter = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); - private static final boolean FLIP_C1_C2 = Boolean.parseBoolean(System.getProperty("FlipC1C2", "false")); + private static final boolean FLIP_C1_C2 = Boolean.getBoolean("FlipC1C2"); private final HashMap declaredTests = new HashMap<>(); private final List allTests = new ArrayList<>(); // Keep order @@ -295,12 +295,6 @@ private void processControlAnnotations(Class clazz) { checkClassAnnotations(ex); try { applyIndependentCompilationCommands(ex); - - if (STRESS_CC) { - if (getAnnotation(ex, Test.class) != null) { - excludeCompilationRandomly(ex); - } - } } catch (TestFormatException e) { // Failure logged. Continue and report later. } @@ -345,15 +339,39 @@ private void checkClassAnnotations(Executable ex) { "@ForceCompileClassInitializer only allowed at classes but not at method " + ex); } - static boolean excludeCompilationRandomly(Executable ex) { - // Exclude some methods from compilation with C2 to stress test the calling convention - boolean exclude = Utils.getRandomInstance().nextBoolean(); + /** + * Exclude a method from compilation randomly and returns the compilation level on which a compilation is still + * possible. + */ + static CompLevel excludeRandomly(Executable ex) { + Random random = Utils.getRandomInstance(); + boolean exclude = random.nextBoolean(); + CompLevel level = CompLevel.ANY; if (exclude) { - System.out.println("Excluding from C2 compilation: " + ex); - WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.C2.getValue(), false); - WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.C2.getValue(), true); + String levelName; + switch (random.nextInt() % 3) { + case 1 -> { + level = CompLevel.C1; + WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.C2.getValue(), false); + WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.C2.getValue(), true); + levelName = "C2"; + } + case 2 -> { + level = CompLevel.C2; + WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.C1.getValue(), false); + WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.C1.getValue(), true); + levelName = "C1"; + } + default -> { + level = CompLevel.SKIP; + WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.ANY.getValue(), false); + WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.ANY.getValue(), true); + levelName = "C1 and C2"; + } + } + System.out.println("Excluding from " + levelName + " compilation: " + ex); } - return exclude; + return level; } private void applyIndependentCompilationCommands(Executable ex) { @@ -375,6 +393,10 @@ private void applyIndependentCompilationCommands(Executable ex) { "C2 or ANY (no compilation, same as specifying anything) in @DontCompile at " + ex); dontCompileAtLevel(ex, compLevel); } + if (EXCLUDE_RANDOM && getAnnotation(ex, Test.class) == null && forceCompileAnno == null && dontCompileAnno == null) { + // Randomly exclude helper methods from compilation + excludeRandomly(ex); + } } private void checkCompilationCommandAnnotations(Executable ex, ForceInline forceInlineAnno, DontInline dontInlineAnno, ForceCompile forceCompileAnno, DontCompile dontCompileAnno) { @@ -426,12 +448,13 @@ private void applyForceCompileCommand(Executable ex) { CompLevel level = forceCompileAnno.value(); TestFormat.check(level != CompLevel.SKIP && level != CompLevel.WAIT_FOR_COMPILATION, "Cannot define compilation level SKIP or WAIT_FOR_COMPILATION in @ForceCompile at " + ex); - if (shouldCompile(ex)) { - level = restrictCompLevel(forceCompileAnno.value()); - if (level != CompLevel.SKIP) { - enqueueForCompilation(ex, level); - forceCompileMap.put(ex, level); - } + level = restrictCompLevel(forceCompileAnno.value()); + if (EXCLUDE_RANDOM) { + level = CompLevel.join(level, excludeRandomly(ex)); + } + if (level != CompLevel.SKIP) { + enqueueForCompilation(ex, level); + forceCompileMap.put(ex, level); } } } @@ -448,16 +471,6 @@ static void enqueueForCompilation(Executable ex, CompLevel requestedCompLevel) { } } - static boolean shouldCompile(Executable ex) { - if (!TestFrameworkExecution.USE_COMPILER) { - return false; - } else if (TestFrameworkExecution.STRESS_CC) { - return !TestFrameworkExecution.excludeCompilationRandomly(ex); - } else { - return true; - } - } - private void setupTests() { for (Method m : testClass.getDeclaredMethods()) { Test testAnno = getAnnotation(m, Test.class); @@ -494,6 +507,9 @@ private void addDeclaredTest(Method m) { if (FLIP_C1_C2) { compLevel = flipCompLevel(compLevel); } + if (EXCLUDE_RANDOM) { + compLevel = CompLevel.join(compLevel, excludeRandomly(m)); + } DeclaredTest test = new DeclaredTest(m, ArgumentValue.getArguments(m), compLevel, warmupIterations); declaredTests.put(m, test); testMethodMap.put(m.getName(), m); @@ -838,7 +854,7 @@ private static TriState compiledByC2(Method m) { private static TriState compiledAtLevel(Method m, CompLevel level) { if (!USE_COMPILER || XCOMP || TEST_C1 || - (STRESS_CC && !WHITE_BOX.isMethodCompilable(m, level.getValue(), false))) { + (EXCLUDE_RANDOM && !WHITE_BOX.isMethodCompilable(m, level.getValue(), false))) { return TriState.Maybe; } if (WHITE_BOX.isMethodCompiled(m, false)) { @@ -967,6 +983,10 @@ abstract class AbstractTest { this.skip = skip; } + protected boolean shouldCompile(DeclaredTest test) { + return test.getCompLevel() != CompLevel.SKIP; + } + abstract String getName(); public boolean isSkipped() { @@ -1127,13 +1147,13 @@ class BaseTest extends AbstractTest { private final boolean shouldCompile; private final boolean waitForCompilation; - public BaseTest(DeclaredTest test, boolean excludedByUser) { - super(test.getWarmupIterations(), excludedByUser ? excludedByUser : test.getCompLevel() == CompLevel.SKIP); + public BaseTest(DeclaredTest test, boolean skip) { + super(test.getWarmupIterations(), skip); this.test = test; this.testMethod = test.getTestMethod(); this.testInfo = new TestInfo(testMethod); this.invocationTarget = createInvocationTarget(testMethod); - this.shouldCompile = TestFrameworkExecution.shouldCompile(testMethod); + this.shouldCompile = shouldCompile(test); this.waitForCompilation = isWaitForCompilation(test); } @@ -1252,10 +1272,9 @@ class CustomRunTest extends AbstractTest { private final List tests; private final RunInfo runInfo; - public CustomRunTest(Method runMethod, Warmup warmUpAnno, Run runSpecification, List tests, boolean excludedByUser) { + public CustomRunTest(Method runMethod, Warmup warmUpAnno, Run runSpecification, List tests, boolean skip) { // Make sure we can also call non-public or public methods in package private classes - super(warmUpAnno != null ? warmUpAnno.value() : TestFrameworkExecution.WARMUP_ITERATIONS, - excludedByUser ? excludedByUser : tests.stream().anyMatch(t -> t.getCompLevel() == CompLevel.SKIP)); + super(warmUpAnno != null ? warmUpAnno.value() : TestFrameworkExecution.WARMUP_ITERATIONS, skip); TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + runMethod); runMethod.setAccessible(true); this.runMethod = runMethod; @@ -1311,7 +1330,7 @@ protected void compileTest() { private void compileSingleTest() { DeclaredTest test = tests.get(0); - if (TestFrameworkExecution.shouldCompile(test.getTestMethod())) { + if (shouldCompile(test)) { if (isWaitForCompilation(test)) { waitForCompilation(test); } else { @@ -1325,7 +1344,7 @@ private void compileMultipleTests() { boolean anyCompileMethod = false; ExecutorService executor = Executors.newFixedThreadPool(tests.size()); for (DeclaredTest test : tests) { - if (TestFrameworkExecution.shouldCompile(test.getTestMethod())) { + if (shouldCompile(test)) { if (isWaitForCompilation(test)) { anyWaitForCompilation = true; executor.execute(() -> waitForCompilation(test)); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java index 95e72007451..e895da80b21 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java @@ -54,14 +54,14 @@ class TestFrameworkPrepareFlags { // User defined settings static final boolean XCOMP = Platform.isComp(); - static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); + static final boolean VERBOSE = Boolean.getBoolean("Verbose"); static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); - static final boolean STRESS_CC = Boolean.parseBoolean(System.getProperty("StressCC", "false")); + static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); private static final boolean REQUESTED_VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); - private static boolean VERIFY_IR = REQUESTED_VERIFY_IR && USE_COMPILER && !XCOMP && !STRESS_CC && !TEST_C1 + private static boolean VERIFY_IR = REQUESTED_VERIFY_IR && USE_COMPILER && !XCOMP && !EXCLUDE_RANDOM && !TEST_C1 && Platform.isDebugBuild() && !Platform.isInt(); - private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false")) && Platform.isDebugBuild(); + private static final boolean VERIFY_VM = Boolean.getBoolean("VerifyVM") && Platform.isDebugBuild(); private static String[] getDefaultFlags() { return new String[] {"-XX:-BackgroundCompilation", "-XX:CompileCommand=quiet"}; From 3def454dca0e8606a3a233dab4b9a55bd377acbd Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 8 Apr 2021 09:55:42 +0200 Subject: [PATCH 092/131] Also apply -DFlipC1C2 to @ForceCompile, fix -DScenario parsing --- .../test/lib/hotspot/ir_framework/Scenario.java | 8 +++++++- .../lib/hotspot/ir_framework/TestFramework.java | 3 +-- .../ir_framework/TestFrameworkExecution.java | 17 ++++++++++------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java index 132ac5f2603..60031d3d574 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java @@ -47,7 +47,13 @@ public class Scenario { static { if (!SCENARIOS.isEmpty()) { - Arrays.stream(SCENARIOS.split("\\s*,\\s*")).map(Integer::getInteger).forEachOrdered(enabledScenarios::add); + System.out.println(Arrays.toString(SCENARIOS.split("\\s*,\\s*"))); + try { + Arrays.stream(SCENARIOS.split("\\s*,\\s*")).map(Integer::parseInt).forEachOrdered(enabledScenarios::add); + } catch (NumberFormatException e) { + TestRun.fail("Provided a scenario index in the -DScenario comma-separated list which is not " + + "a number: " + SCENARIOS); + } } if (!ADDITIONAL_SCENARIO_FLAGS.isEmpty()) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 00efc2aa94c..128caa0f932 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -790,8 +790,7 @@ private void throwTestVMException(JVMOutput vmOutput) { throw new TestFormatException("\n\n" + matcher.group()); } else if (stdErr.contains("NoTestsRunException")) { shouldVerifyIR = false; - throw new NoTestsRunException(">>> No tests run either due to empty set specified with -DTest and/or -DExclude" - + " or due to explicitly skipping tests with @Test(compLevel = CompLevel.SKIP)"); + throw new NoTestsRunException(">>> No tests run due to empty set specified with -DTest and/or -DExclude"); } else { throw new TestVMException(vmOutput); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index e86adbf1b52..91cb36543d2 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -445,16 +445,19 @@ private void dontCompileAtLevel(Executable ex, CompLevel compLevel) { private void applyForceCompileCommand(Executable ex) { ForceCompile forceCompileAnno = getAnnotation(ex, ForceCompile.class); if (forceCompileAnno != null) { - CompLevel level = forceCompileAnno.value(); - TestFormat.check(level != CompLevel.SKIP && level != CompLevel.WAIT_FOR_COMPILATION, + CompLevel complevel = forceCompileAnno.value(); + TestFormat.check(complevel != CompLevel.SKIP && complevel != CompLevel.WAIT_FOR_COMPILATION, "Cannot define compilation level SKIP or WAIT_FOR_COMPILATION in @ForceCompile at " + ex); - level = restrictCompLevel(forceCompileAnno.value()); + complevel = restrictCompLevel(forceCompileAnno.value()); if (EXCLUDE_RANDOM) { - level = CompLevel.join(level, excludeRandomly(ex)); + complevel = CompLevel.join(complevel, excludeRandomly(ex)); } - if (level != CompLevel.SKIP) { - enqueueForCompilation(ex, level); - forceCompileMap.put(ex, level); + if (FLIP_C1_C2) { + complevel = flipCompLevel(complevel); + } + if (complevel != CompLevel.SKIP) { + enqueueForCompilation(ex, complevel); + forceCompileMap.put(ex, complevel); } } } From b5c618d318999a4c96d9cff7d5aebea322507fcd Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 8 Apr 2021 14:36:47 +0200 Subject: [PATCH 093/131] Add JTreg VM and Javaoptions Whitelist flags to enable/disable IR verification --- .../hotspot/ir_framework/TestFramework.java | 122 +++++++++++++++--- .../TestFrameworkPrepareFlags.java | 16 --- 2 files changed, 106 insertions(+), 32 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 128caa0f932..a1583866896 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -23,6 +23,7 @@ package jdk.test.lib.hotspot.ir_framework; +import jdk.test.lib.Platform; import jdk.test.lib.Utils; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; @@ -93,6 +94,37 @@ * @see IR */ public class TestFramework { + /** + * JTreg can define additional VM (-Dtest.vm.opts) and Javaoption (-Dtest.java.opts) flags. IR verification is only + * performed when all these additional JTreg flags (does not include additionally added framework and scenario flags + * by user code) are whitelisted. + * + * A flag is whitelisted if it is a property flag (starting with -D), -ea, -esa, or if the flag name contains any of + * the entries of this list as a substring. + */ + private static final Set jtregWhitelistFlags = new HashSet<>( + Arrays.asList( + // The following substrings are part of more than one VM flag + "RAM", + "G1", + "Heap", + "Trace", + "Print", + "Verify", + "TLAB", + // The following substrings are only part of one VM flag (= exact match) + "CreateCoredumpOnCrash", + "BackgroundCompilation", + "Xbatch", + "TieredCompilation", + "UseSerialGC", + "UseParallelGC", + "UseG1GC", + "UseZGC", + "UseShenandoahGC" + ) + ); + static final boolean VERBOSE = Boolean.getBoolean("Verbose"); static final String TEST_VM_FLAGS_START = "##### TestFrameworkPrepareFlags - used by TestFramework #####"; static final String TEST_VM_FLAGS_DELIMITER = " "; @@ -101,6 +133,8 @@ public class TestFramework { private static final int WARMUP_ITERATIONS = Integer.getInteger("Warmup", -1); private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.getBoolean("PreferCommandLineFlags"); private static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); + private static final boolean VERIFY_VM = Boolean.getBoolean("VerifyVM") && Platform.isDebugBuild(); + private static boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); private boolean shouldVerifyIR = true; // Should we perform IR matching? private static String lastTestVMOutput; @@ -148,6 +182,23 @@ public TestFramework(Class testClass) { } } + /** + * Default flags that are added used for the test VM. + */ + private static String[] getDefaultFlags() { + return new String[] {"-XX:-BackgroundCompilation", "-XX:CompileCommand=quiet"}; + } + + /** + * Additional verification flags that are used if -DVerifyVM=true is with a debug build. + */ + private static String[] getVerifyFlags() { + return new String[] { + "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", + "-XX:+VerifyBeforeGC", "-XX:+VerifyAfterGC", "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing" + }; + } + /** * Tests the class from which this method was invoked from. */ @@ -339,6 +390,15 @@ public TestFramework addScenarios(Scenario... scenarios) { */ public void start() { installWhiteBox(); + if (VERIFY_IR) { + // No IR verification is done if additional non-whitelisted JTreg VM or Javaoptions flag is specified. + VERIFY_IR = onlyWhitelistedJTregVMAndJavaOptsFlags(); + if (!VERIFY_IR) { + System.out.println("IR verification disabled due to using non-whitelisted JTreg VM or Javaoptions " + + "flag(s).\n"); + } + } + if (scenarios == null) { try { start(null); @@ -346,7 +406,7 @@ public void start() { System.err.println("\n" + e.getExceptionInfo()); throw e; } catch (IRViolationException e) { - System.out.println("Compilation(s) of failed matche(s):"); + System.out.println("Compilation(s) of failed match(es):"); System.out.println(e.getCompilations()); throw e; } @@ -617,8 +677,14 @@ private void start(Scenario scenario) { System.out.println("Scenario #" + scenario.getIndex() + scenarioFlagsString + ":"); additionalFlags.addAll(scenarioFlags); } - System.out.println("Run Flag VM:"); - runFlagVM(additionalFlags); + socket.start(); + if (VERIFY_IR) { + System.out.println("Run Flag VM:"); + runFlagVM(additionalFlags); + } else { + shouldVerifyIR = false; + System.out.println("Skip Flag VM due to not performing IR verification."); + } String flagsString = additionalFlags.isEmpty() ? "" : " - [" + String.join(", ", additionalFlags) + "]"; System.out.println("Run Test VM" + flagsString + ":"); @@ -629,9 +695,22 @@ private void start(Scenario scenario) { } } + private boolean onlyWhitelistedJTregVMAndJavaOptsFlags() { + List flags = Arrays.stream(Utils.getTestJavaOpts()) + .map(s -> s.replaceFirst("-XX:[+|-]?|-(?=[^D|^e])", "")) + .collect(Collectors.toList()); + for (String flag : flags) { + // Property flags (prefix -D), -ea and -esa are whitelisted. + if (!flag.startsWith("-D") && !flag.startsWith("-e") && jtregWhitelistFlags.stream().noneMatch(flag::contains)) { + // Found VM flag that is not whitelisted + return false; + } + } + return true; + } + private void runFlagVM(List additionalFlags) { ArrayList cmds = prepareFlagVMFlags(additionalFlags); - socket.start(); OutputAnalyzer oa; try { // Run "flag" VM with White Box access to determine the test VM flags and if IR verification should be done. @@ -706,8 +785,9 @@ private void runTestVM(List additionalFlags, Scenario scenario) { if (shouldVerifyIR) { new IRMatcher(output.getHotspotPidFileName(), socket.getOutput(), testClass); } else { - System.out.println("IR Verification disabled either through explicitly setting -DVerify=false or due to " + - "not running a debug build, running with -Xint, or other VM flags that make the verification " + + System.out.println("IR verification disabled either through explicitly setting -DVerify=false, due to " + + "not running a debug build, using a non-whitelisted JTreg VM or Javaopts flag, " + + "running with -Xint, or running the test VM with other VM flags that make the verification " + "inaccurate or impossible (e.g. using -XX:CompileThreshold, running with C1 only etc.)."); } } @@ -737,8 +817,7 @@ private List prepareTestVMFlags(List additionalFlags) { cmds.add("-DWarmup=" + defaultWarmup); } - - if (shouldVerifyIR) { + if (shouldVerifyIR) { // Add server property flag that enables test VM to print encoding for IR verification last. cmds.add(socket.getPortPropertyFlag()); } @@ -758,15 +837,26 @@ private List prepareTestVMFlags(List additionalFlags) { private List getTestVMFlags() { String patternString = "(?<=" + TestFramework.TEST_VM_FLAGS_START + "\\R)" + "(.*DShouldDoIRVerification=(true|false).*)\\R" + "(?=" + IREncodingPrinter.END + ")"; Pattern pattern = Pattern.compile(patternString); - String flags = socket.getOutput(); - if (VERBOSE) { - System.out.println("Read sent data from flag VM from socket:"); - System.out.println(flags); + List flagList = new ArrayList<>(); + + if (VERIFY_VM) { + flagList.addAll(Arrays.asList(getVerifyFlags())); + } + + flagList.addAll(Arrays.asList(getDefaultFlags())); + + if (VERIFY_IR) { + String flags = socket.getOutput(); + if (VERBOSE) { + System.out.println("Read sent data from flag VM from socket:"); + System.out.println(flags); + } + Matcher matcher = pattern.matcher(flags); + check(matcher.find(), "Invalid flag encoding emitted by flag VM"); + shouldVerifyIR = Boolean.parseBoolean(matcher.group(2)); + flagList.addAll(Arrays.asList(matcher.group(1).split(TEST_VM_FLAGS_DELIMITER))); } - Matcher matcher = pattern.matcher(flags); - check(matcher.find(), "Invalid flag encoding emitted by flag VM"); - shouldVerifyIR = Boolean.parseBoolean(matcher.group(2)); - return new ArrayList<>(Arrays.asList(matcher.group(1).split(TEST_VM_FLAGS_DELIMITER))); + return flagList; } private void checkTestVMExitCode(JVMOutput vmOutput) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java index e895da80b21..c36c133d1a0 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java @@ -61,22 +61,12 @@ class TestFrameworkPrepareFlags { private static final boolean REQUESTED_VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); private static boolean VERIFY_IR = REQUESTED_VERIFY_IR && USE_COMPILER && !XCOMP && !EXCLUDE_RANDOM && !TEST_C1 && Platform.isDebugBuild() && !Platform.isInt(); - private static final boolean VERIFY_VM = Boolean.getBoolean("VerifyVM") && Platform.isDebugBuild(); - private static String[] getDefaultFlags() { - return new String[] {"-XX:-BackgroundCompilation", "-XX:CompileCommand=quiet"}; - } private static String[] getPrintFlags() { return new String[] {"-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions"}; } - private static String[] getVerifyFlags() { - return new String[] { - "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", "-XX:+VerifyBeforeGC", - "-XX:+VerifyAfterGC", "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing"}; - } - public static void main(String[] args) { String testClassName = args[0]; if (VERBOSE) { @@ -102,12 +92,6 @@ private static void emitTestVMFlags(ArrayList flags) { private static ArrayList prepareTestVmFlags(Class testClass) { ArrayList cmds = new ArrayList<>(); - - if (VERIFY_VM) { - cmds.addAll(Arrays.asList(getVerifyFlags())); - } - - cmds.addAll(Arrays.asList(getDefaultFlags())); setupIrVerificationFlags(testClass, cmds); // // TODO: Only for debugging From d01476152c7cc17790638622b107e82de43da610 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 8 Apr 2021 15:57:18 +0200 Subject: [PATCH 094/131] Convert and fix framework internal tests into JTreg tests and add README for them --- .../lib/hotspot/ir_framework/tests/README.md | 4 + .../lib/hotspot/ir_framework/tests/TEST.ROOT | 3 + .../tests/TestAccessModifiers.java | 8 +- .../ir_framework/tests/TestBadFormat.java | 7 + .../ir_framework/tests/TestBasics.java | 10 ++ .../ir_framework/tests/TestCompLevels.java | 135 ++++++++++++++---- .../ir_framework/tests/TestControls.java | 12 +- .../ir_framework/tests/TestIRMatching.java | 8 ++ .../ir_framework/tests/TestRunTests.java | 7 + .../ir_framework/tests/TestSanity.java | 7 + .../ir_framework/tests/TestScenarios.java | 7 + .../tests/TestWithHelperClasses.java | 7 + 12 files changed, 185 insertions(+), 30 deletions(-) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/tests/README.md create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/tests/TEST.ROOT diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/README.md b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/README.md new file mode 100644 index 00000000000..83dd2b98b59 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/README.md @@ -0,0 +1,4 @@ +# Framework internal tests +This folder contains tests which test the functionality of the framework. These should be run with JTreg and without additional VM and Javaopts flags whenever the framework is modified. + +These tests are not part of the normal tier testing as they only should be run when the framework is changed in any way. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TEST.ROOT b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TEST.ROOT new file mode 100644 index 00000000000..34cac1ddc59 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TEST.ROOT @@ -0,0 +1,3 @@ +# Minimal TEST.ROOT file to run the internal framework tests as if they would have been placed inside +# /test/hotspot/jtreg +external.lib.roots = ../../../../../../../.. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestAccessModifiers.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestAccessModifiers.java index 43f54becbdd..0672cdeb3c7 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestAccessModifiers.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestAccessModifiers.java @@ -24,7 +24,13 @@ package jdk.test.lib.hotspot.ir_framework.tests; import jdk.test.lib.hotspot.ir_framework.*; -import jdk.test.lib.hotspot.ir_framework.examples.Sandbox; + +/* + * @test + * @summary Test different access modifiers an make sure, the framework can access all methods. + * @library /test/lib + * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestAccessModifiers + */ public class TestAccessModifiers { public static void main(String[] args) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java index 22e8d515f14..865ad3d4642 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java @@ -35,6 +35,13 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +/* + * @test + * @summary Test test format violations. + * @library /test/lib + * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestBadFormat + */ + public class TestBadFormat { public static void main(String[] args) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java index 9239ab971f0..e59e379b094 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java @@ -29,6 +29,16 @@ import java.util.Arrays; import java.util.stream.Stream; +/* + * @test + * @summary Test basics of the framework. This test runs directly the test VM which normally does not happen. + * @library /test/lib + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * jdk.test.lib.hotspot.ir_framework.tests.TestBasics + */ + public class TestBasics { private static boolean wasExecuted = false; private boolean lastToggleBoolean = true; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java index f93959e5ee0..bd1d9fc9105 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java @@ -28,9 +28,19 @@ import java.lang.reflect.Method; -// Requires C1 and C2 enabled +/* + * @test + * @summary Test if compilation levels are used correctly in the framework. + * This test runs directly the test VM which normally does not happen. + * @library /test/lib + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * jdk.test.lib.hotspot.ir_framework.tests.TestCompLevels + */ + public class TestCompLevels { - static int[] testExecuted = new int[4]; + static int[] testExecuted = new int[5]; public static void main(String[] args) throws Exception { Method runTestsOnSameVM = TestFrameworkExecution.class.getDeclaredMethod("runTestsOnSameVM", Class.class); @@ -44,11 +54,14 @@ public static void main(String[] args) throws Exception { + TestFrameworkExecution.WARMUP_ITERATIONS + 1 + " times." ); } } - Scenario s = new Scenario(1, "-XX:-TieredCompilation"); - TestFramework.runWithScenarios(TestNoTiered.class, s); - s = new Scenario(2, "-XX:TieredStopAtLevel=1"); - TestFramework.runWithScenarios(TestStopAtLevel1.class, s); - Asserts.assertTrue(s.getTestVMOutput().contains("TestStopAtLevel1=34")); + TestFramework framework = new TestFramework(TestNoTiered.class); + framework.setDefaultWarmup(10).addFlags("-XX:-TieredCompilation").start(); + framework = new TestFramework(TestNoTiered.class); + framework.setDefaultWarmup(10).addScenarios(new Scenario(0, "-XX:-TieredCompilation")).start(); + framework = new TestFramework(TestStopAtLevel1.class); + framework.setDefaultWarmup(10).addFlags("-XX:TieredStopAtLevel=1").start(); + framework = new TestFramework(TestStopAtLevel1.class); + framework.setDefaultWarmup(10).addScenarios(new Scenario(0, "-XX:TieredStopAtLevel=1")).start(); } @Test(compLevel = CompLevel.C1) @@ -90,53 +103,119 @@ public void testC2() { public void checkTestC2(TestInfo info) { TestFramework.assertCompiledAtLevel(info.getTest(), CompLevel.C2); } + + @Test(compLevel = CompLevel.SKIP) + public void testSkip() { + testExecuted[4]++; // Executed by eventually not compiled by framework + } } class TestNoTiered { @Test(compLevel = CompLevel.C1) - public void notExecuted() { - throw new RuntimeException("Should not be executed"); + public void level1() { + } + + @Check(test = "level1") + public void check1(TestInfo info) { + TestFramework.assertNotCompiled(info.getTest()); // Never compiled without C1 } @Test(compLevel = CompLevel.C1_LIMITED_PROFILE) - public void notExecuted1() { - throw new RuntimeException("Should not be executed"); + public void level2() { + } + + @Check(test = "level2") + public void check2(TestInfo info) { + TestFramework.assertNotCompiled(info.getTest()); // Never compiled without C1 } @Test(compLevel = CompLevel.C1_FULL_PROFILE) - public void notExecuted2() { - throw new RuntimeException("Should not be executed"); + public void level3() { + } + + @Check(test = "level3") + public void check3(TestInfo info) { + TestFramework.assertNotCompiled(info.getTest()); // Never compiled without C1 + } + + @Test(compLevel = CompLevel.C2) + public void level4() { + } + + @Check(test = "level4") + public void check4(TestInfo info) { + if (info.isWarmUp()) { + TestFramework.assertNotCompiled(info.getTest()); // Never compiled without C1 + } else { + if (TestFramework.isC1Compiled(info.getTest())) { + throw new RuntimeException("Cannot be compiled with C1"); // Never compiled without C1 + } + TestFramework.assertCompiledByC2(info.getTest()); + } } @Test(compLevel = CompLevel.SKIP) - public void notExecuted3() { - throw new RuntimeException("Should not be executed"); + public void skip() { + } + + @Check(test = "skip") + public void checkSkip(TestInfo info) { + TestFramework.assertNotCompiled(info.getTest()); // Never compiled } } class TestStopAtLevel1 { - @Test(compLevel = CompLevel.C2) - public void notExecuted() { - throw new RuntimeException("Should not be executed"); + @Test(compLevel = CompLevel.C1) + public int level1() { + return 34; + } + + @Check(test = "level1") + public void check1(int result, TestInfo info) { + if (info.isWarmUp()) { + TestFramework.assertNotCompiled(info.getTest()); // Not compiled yet + } else { + TestFramework.assertCompiledByC1(info.getTest()); + if (TestFramework.isC2Compiled(info.getTest())) { + throw new RuntimeException("Cannot be compiled by C2"); + } + System.out.println("TestStopAtLevel1=" + result); + } } @Test(compLevel = CompLevel.C1_LIMITED_PROFILE) - public void notExecuted1() { - throw new RuntimeException("Should not be executed"); + public void level2() { + } + + @Check(test = "level2") + public void check2(TestInfo info) { + TestFramework.assertNotCompiled(info.getTest()); // Never with level 2 } @Test(compLevel = CompLevel.C1_FULL_PROFILE) - public void notExecuted2() { - throw new RuntimeException("Should not be executed"); + public void level3() { } - @Test(compLevel = CompLevel.C1) - public int executed() { - return 34; + @Check(test = "level3") + public void check3(TestInfo info) { + TestFramework.assertNotCompiled(info.getTest()); // Never with level 3 + } + + @Test(compLevel = CompLevel.C2) + public void level4() { + } + + @Check(test = "level4") + public void check4(TestInfo info) { + TestFramework.assertNotCompiled(info.getTest()); // Never with level 4 + } + + @Test(compLevel = CompLevel.SKIP) + public void skip() { } - @Check(test = "executed", when = CheckAt.COMPILED) - public void checkExecuted(int result) { - System.out.println("TestStopAtLevel1=" + result); + @Check(test = "skip") + public void checkSkip(TestInfo info) { + TestFramework.assertNotCompiled(info.getTest()); // Never compiled } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java index 169ec684a12..61595fbf40e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java @@ -31,7 +31,17 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -// Run with -Xbatch +/* + * @test + * @summary Test if compilation control annotaions are handled correctly in the framework. + * This test runs directly the test VM which normally does not happen. + * @library /test/lib + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * jdk.test.lib.hotspot.ir_framework.tests.TestControls + */ + public class TestControls { static int[] executed = new int[15]; static boolean wasExecuted = false; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java index a9d0e53e5ba..e9a422553c4 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java @@ -34,6 +34,14 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +/* + * @test + * @summary Test IR matcher with different default IR node regexes. Use -DPrintIREncoding. + * Normally, the framework should be called with driver. + * @library /test/lib + * @run main/othervm -DPrintIREncoding=true jdk.test.lib.hotspot.ir_framework.tests.TestIRMatching + */ + public class TestIRMatching { public static void main(String[] args) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java index 94a893ed19e..fe6604176aa 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java @@ -28,6 +28,13 @@ import java.util.Arrays; +/* + * @test + * @summary Test different custom run tests. + * @library /test/lib + * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestRunTests + */ + public class TestRunTests { public static void main(String[] args) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java index 3898d16add1..e68e5cae2de 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java @@ -27,6 +27,13 @@ import jdk.test.lib.hotspot.ir_framework.Test; import jdk.test.lib.hotspot.ir_framework.TestFramework; +/* + * @test + * @summary Sanity test the different ways to start the test framework. + * @library /test/lib + * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestSanity + */ + public class TestSanity { public static void main(String[] args) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java index 92821376fd8..40a72b0fa5b 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java @@ -26,6 +26,13 @@ import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; +/* + * @test + * @summary Test scenarios with the framework. + * @library /test/lib + * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestScenarios + */ + public class TestScenarios { public static void main(String[] args) { Scenario sDefault = new Scenario(0); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java index be00b2b13ca..04c32954c03 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java @@ -26,6 +26,13 @@ import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; +/* + * @test + * @summary Test the framework with helper classes. + * @library /test/lib + * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestWithHelperClasses + */ + public class TestWithHelperClasses { public static void main(String[] args) { From 98f5da6b02b605fbc4c1c405cadc9eb85323a2f8 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 8 Apr 2021 17:56:15 +0200 Subject: [PATCH 095/131] Restrict JTreg tests with @requires, add tests for property flags --- .../hotspot/ir_framework/TestFramework.java | 4 +- .../lib/hotspot/ir_framework/tests/TEST.ROOT | 9 ++ .../ir_framework/tests/TestBadFormat.java | 1 + .../ir_framework/tests/TestBasics.java | 1 + .../ir_framework/tests/TestControls.java | 1 + .../ir_framework/tests/TestDFlags.java | 73 +++++++++++++ .../ir_framework/tests/TestDScenarios.java | 95 ++++++++++++++++ .../tests/TestDTestAndExclude.java | 103 ++++++++++++++++++ .../ir_framework/tests/TestIRMatching.java | 1 + .../ir_framework/tests/TestRunTests.java | 1 + .../ir_framework/tests/TestScenarios.java | 1 + 11 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDFlags.java create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDScenarios.java create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDTestAndExclude.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index a1583866896..806b5270c9e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -114,6 +114,7 @@ public class TestFramework { "TLAB", // The following substrings are only part of one VM flag (= exact match) "CreateCoredumpOnCrash", + "UnlockDiagnosticVMOptions", "BackgroundCompilation", "Xbatch", "TieredCompilation", @@ -121,7 +122,8 @@ public class TestFramework { "UseParallelGC", "UseG1GC", "UseZGC", - "UseShenandoahGC" + "UseShenandoahGC", + "UseNewCode" ) ); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TEST.ROOT b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TEST.ROOT index 34cac1ddc59..a5c2b99e4df 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TEST.ROOT +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TEST.ROOT @@ -1,3 +1,12 @@ # Minimal TEST.ROOT file to run the internal framework tests as if they would have been placed inside # /test/hotspot/jtreg external.lib.roots = ../../../../../../../.. +requires.extraPropDefns = ../../../../../../../jtreg-ext/requires/VMProps.java +requires.extraPropDefns.bootlibs = ../../../../../../../lib/sun +requires.extraPropDefns.libs = \ + ../../../../../../../lib/jdk/test/lib/Platform.java \ + ../../../../../../../lib/jdk/test/lib/Container.java +requires.extraPropDefns.vmOpts = -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI +requires.properties= \ + vm.debug \ + vm.compiler2.enabled \ diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java index 865ad3d4642..3afb993ea71 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java @@ -37,6 +37,7 @@ /* * @test + * @requires vm.compiler2.enabled * @summary Test test format violations. * @library /test/lib * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestBadFormat diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java index e59e379b094..9458ebf9b71 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java @@ -31,6 +31,7 @@ /* * @test + * @requires vm.compiler2.enabled * @summary Test basics of the framework. This test runs directly the test VM which normally does not happen. * @library /test/lib * @build sun.hotspot.WhiteBox diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java index 61595fbf40e..82f83db16dc 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java @@ -33,6 +33,7 @@ /* * @test + * @requires vm.debug == true & vm.compMode != "Xint" & vm.compiler2.enabled * @summary Test if compilation control annotaions are handled correctly in the framework. * This test runs directly the test VM which normally does not happen. * @library /test/lib diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDFlags.java new file mode 100644 index 00000000000..077fb36845d --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDFlags.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework.tests; + +import jdk.test.lib.hotspot.ir_framework.Test; +import jdk.test.lib.hotspot.ir_framework.TestFramework; + +/* + * @test + * @requires vm.debug == true & vm.compMode != "Xint" & vm.compiler2.enabled + * @summary Sanity test remaining framework property flags. + * @library /test/lib + * @run main/othervm -DFlipC1C2=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags + * @run main/othervm -DExcludeRandom=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags + * @run main/othervm -DVerifyVM=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags + * @run main/othervm -DDumpReplay=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags + * @run main/othervm -DVerbose=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags + * @run main/othervm -DShuffleTests=false jdk.test.lib.hotspot.ir_framework.tests.TestDFlags + * @run main/othervm -DReproduce=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags + * @run main/othervm -DReportStdout=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags + */ + +public class TestDFlags { + public static void main(String[] args) { + TestFramework.run(); + } + + @Test + public int c1() { + return 34; + } + + + @Test + public void c2() { + for (int i = 0; i < 100; i++) { + } + } + + @Test + public void c2_2() { + for (int i = 0; i < 100; i++) { + } + } + + @Test + public void c2_3() { + for (int i = 0; i < 100; i++) { + } + } +} + diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDScenarios.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDScenarios.java new file mode 100644 index 00000000000..5070263c8b1 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDScenarios.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework.tests; + +import jdk.test.lib.Utils; +import jdk.test.lib.hotspot.ir_framework.*; +import jdk.test.lib.Asserts; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +/* + * @test + * @requires vm.debug == true + + * @summary Test -DScenarios property flag. Run with othervm which should not be done when writing tests using + * the framework. + * @library /test/lib + * @run main/othervm -DScenarios=1,5,10 jdk.test.lib.hotspot.ir_framework.tests.TestDScenarios test + * @run main/othervm -DScenarios=1,4 jdk.test.lib.hotspot.ir_framework.tests.TestDScenarios test + * @run main/othervm -DScenarios=3,4,9 jdk.test.lib.hotspot.ir_framework.tests.TestDScenarios test + * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestDScenarios test2 + * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestDScenarios + */ + +public class TestDScenarios { + public static void main(String[] args) throws Exception { + if (args.length > 0) { + switch (args[0]) { + case "test" -> { + Scenario s1 = new Scenario(1); + Scenario s2 = new Scenario(5); + Scenario s3 = new Scenario(10); + Scenario bad = new Scenario(0, "-Flagdoesnotexist"); // not executed + TestFramework.runWithScenarios(bad, s1, s2, s3); + } + case "test2" -> { + try { + TestFramework.run(DScenariosBad.class); + throw new RuntimeException("should not reach"); + } catch (TestVMException e) { + System.out.println(e.getExceptionInfo()); + Asserts.assertTrue(e.getExceptionInfo().contains("Expected DScenariosBad exception")); + } + } + default -> { + // Invalid -DScenarios set and thus exception thrown when Scenario class is statically initialized. + Scenario s = new Scenario(3); + throw new RuntimeException("should not reach"); + } + } + } else { + // Test invalid -DScenario flag. + OutputAnalyzer oa; + ProcessBuilder process = ProcessTools.createJavaProcessBuilder( + "-Dtest.jdk=" + Utils.TEST_JDK, "-DScenarios=a,1,b,10", + "jdk.test.lib.hotspot.ir_framework.tests.TestDScenarios", " test3"); + oa = ProcessTools.executeProcess(process); + oa.shouldNotHaveExitValue(0); + System.out.println(oa.getOutput()); + Asserts.assertTrue(oa.getOutput().contains("TestRunException: Provided a scenario index")); + } + } + + @Test + public void test() { + } +} + +class DScenariosBad { + @Test + public void test() { + throw new RuntimeException("Expected DScenariosBad exception"); + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDTestAndExclude.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDTestAndExclude.java new file mode 100644 index 00000000000..f1b6da3e7bb --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDTestAndExclude.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework.tests; + +import jdk.test.lib.Utils; +import jdk.test.lib.hotspot.ir_framework.*; +import jdk.test.lib.Asserts; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +/* + * @test + * @summary Test -DTest and -DExclude property flag. + * @library /test/lib + * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestDTestAndExclude + */ + +public class TestDTestAndExclude { + public static void main(String[] args) throws Exception { + if (args.length == 0) { + run("good1,good2", "", "good"); + run("good1,good2", "bad1", "good"); + run("good1,bad1", "bad1", "good"); + run("good1,bad1", "bad1,good", "good"); + run("bad1,good1", "", "badrun"); + run("bad1,good1", "good1", "badrun"); + run("bad1,good1", "asdf", "badrun"); + run("asdf", "", "empty"); + run("", "good1,good2,bad1", "empty"); + run("bad1", "bad1", "empty"); + run("good1", "asdf,good,good1", "empty"); + } else { + switch (args[0]) { + case "good" -> TestFramework.run(); + case "badrun" -> { + try { + TestFramework.run(); + throw new RuntimeException("should not reach"); + } catch (TestVMException e) { + Asserts.assertTrue(e.getExceptionInfo().contains("expected bad1 exception")); + } + } + case "empty" -> { + try { + TestFramework.run(); + throw new RuntimeException("should not reach"); + } catch (NoTestsRunException e) { + // Expected + } + } + default -> throw new RuntimeException("should not reach"); + } + } + } + + /** + * Create a VM and simulate as if it was a driver VM spawned by JTreg that has -DTest/DExclude set as VM or Javaopts + */ + protected static void run(String dTest, String dExclude, String arg) throws Exception { + OutputAnalyzer oa; + ProcessBuilder process = ProcessTools.createJavaProcessBuilder( + "-Dtest.class.path=" + Utils.TEST_CLASS_PATH, "-Dtest.jdk=" + Utils.TEST_JDK, + "-Dtest.vm.opts=-DTest=" + dTest + " -DExclude=" + dExclude, + "jdk.test.lib.hotspot.ir_framework.tests.TestDTestAndExclude", arg); + oa = ProcessTools.executeProcess(process); + oa.shouldHaveExitValue(0); + } + + @Test + public void good1() { + } + + @Test + public void good2() { + } + + @Test + public void bad1() { + throw new RuntimeException("expected bad1 exception"); + } +} + diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java index e9a422553c4..b978e3b8cc9 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java @@ -36,6 +36,7 @@ /* * @test + * @requires vm.debug == true & vm.compMode != "Xint" & vm.compiler2.enabled * @summary Test IR matcher with different default IR node regexes. Use -DPrintIREncoding. * Normally, the framework should be called with driver. * @library /test/lib diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java index fe6604176aa..0a5d631bc27 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java @@ -30,6 +30,7 @@ /* * @test + * @requires vm.compMode != "Xint" & vm.compiler2.enabled * @summary Test different custom run tests. * @library /test/lib * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestRunTests diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java index 40a72b0fa5b..69ad312cfc5 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java @@ -28,6 +28,7 @@ /* * @test + * @requires vm.compMode != "Xint" & vm.compiler2.enabled * @summary Test scenarios with the framework. * @library /test/lib * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestScenarios From aa6c823b8ccaa430385f7268307f0d328ce9fff7 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 9 Apr 2021 11:51:12 +0200 Subject: [PATCH 096/131] Cleanup and add more examples how to use the framework, add references to these examples, add tests for @Run and @Check in inner and helper classes, fix VerifyIR --- .../hotspot/ir_framework/AbstractInfo.java | 16 +- .../test/lib/hotspot/ir_framework/Check.java | 6 +- .../jdk/test/lib/hotspot/ir_framework/IR.java | 3 + .../test/lib/hotspot/ir_framework/Run.java | 30 ++-- .../test/lib/hotspot/ir_framework/Test.java | 4 +- .../hotspot/ir_framework/TestFramework.java | 42 +++-- .../ir_framework/TestFrameworkExecution.java | 12 +- .../TestFrameworkPrepareFlags.java | 50 ++---- ...{TestExample.java => BaseTestExample.java} | 55 +++--- ...ckExample.java => CheckedTestExample.java} | 83 +++++---- ...Example.java => CustomRunTestExample.java} | 90 ++++++---- .../ir_framework/examples/IRExample.java | 167 ++++++++++++++++++ .../ir_framework/examples/SimpleExample.java | 51 ------ .../ir_framework/tests/TestBadFormat.java | 28 ++- .../tests/TestWithHelperClasses.java | 27 ++- 15 files changed, 446 insertions(+), 218 deletions(-) rename test/lib/jdk/test/lib/hotspot/ir_framework/examples/{TestExample.java => BaseTestExample.java} (60%) rename test/lib/jdk/test/lib/hotspot/ir_framework/examples/{CheckExample.java => CheckedTestExample.java} (60%) rename test/lib/jdk/test/lib/hotspot/ir_framework/examples/{RunExample.java => CustomRunTestExample.java} (54%) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java delete mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/examples/SimpleExample.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java index 64a613b0548..4649c27c939 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java @@ -58,12 +58,22 @@ public boolean toggleBoolean() { return toggleBool; } + + /** + * Get a random boolean. + * + * @return a random boolean + */ + public boolean getRandomBoolean() { + return random.nextBoolean(); + } + /** * Get a random integer. * * @return a random integer */ - public static int getRandomInt() { + public int getRandomInt() { return random.nextInt(); } @@ -72,7 +82,7 @@ public static int getRandomInt() { * * @return a random long value. */ - public static long getRandomLong() { + public long getRandomLong() { return random.nextLong(); } @@ -81,7 +91,7 @@ public static long getRandomLong() { * * @return a random double value in the range of [-10000,10000]. */ - public static double getRandomDouble() { + public double getRandomDouble() { return random.nextDouble() * 20000 - 10000; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java index 73233c4539b..4045536cc8f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java @@ -23,6 +23,8 @@ package jdk.test.lib.hotspot.ir_framework; +import jdk.test.lib.hotspot.ir_framework.examples.CheckedTestExample; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -79,7 +81,9 @@ * complex or varying arguments and/or the {@code t} must be invoked differently in subsequent invocations, use a * custom run test (see {@link Run}). * - * TODO: Add references to examples + *

      + * Examples on how to write checked tests can be found in {@link jdk.test.lib.hotspot.ir_framework.examples.CheckedTestExample} + * and also as part of the internal testing in the package {@link jdk.test.lib.hotspot.ir_framework.tests}. */ @Retention(RetentionPolicy.RUNTIME) public @interface Check { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java index 37c8f9078da..e2ed4ad4dba 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java @@ -47,6 +47,9 @@ * An IR rule can specify additional preconditions on the remaining flags that must hold when an IR rule is applied. * If the specified preconditions fail, then the framework does not apply the IR rule. These preconditions can be * set with {@link #applyIf()}, {@link #applyIfNot()}, {@link #applyIfAnd()}, or {@link #applyIfOr()}. + *

      + * Examples on how to write tests with IR rules can be found in {@link jdk.test.lib.hotspot.ir_framework.examples.IRExample} + * and also as part of the internal testing in {@link jdk.test.lib.hotspot.ir_framework.tests.TestIRMatching}. * * @see Test */ diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java index b020201d2f8..c9934449c16 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java @@ -38,15 +38,15 @@ * property, the framework does the following, similar as for base tests: *

        *
      1. The framework warms {@code r} up by invoking it for a predefined number of iterations (default: 2000) - * or any number specified by an additional {@link Warmup} annotation at the run method {@code r} or by using - * {@link TestFramework#setDefaultWarmup(int)} (could also be 0 which skips the warm-up completely which is similar - * to simulating {@code -Xcomp}). More information about the warm-up in general can be found in {@link Warmup}

      2. + * or any number specified by an additional {@link Warmup} annotation at the run method {@code r} or by using + * {@link TestFramework#setDefaultWarmup(int)} (could also be 0 which skips the warm-up completely which is similar to + * simulating {@code -Xcomp}). More information about the warm-up in general can be found in {@link Warmup} *
      3. After the warm-up, the framework compiles the test method {@code t} at the specified compilation level set by - * {@link Test#compLevel()} (default {@link CompLevel#ANY} will pick the highest available level which is usually - * {@link CompLevel#C2}).

      4. + * {@link Test#compLevel()} (default {@link CompLevel#ANY} will pick the highest available level which is usually + * {@link CompLevel#C2}). *
      5. The framework invokes the run method {@code r} one more time to check the compilation.

      6. *
      7. The framework checks any specified {@link IR} constraints at the test method {@code t}. - * More information about IR matching can be found in {@link IR}.

      8. + * More information about IR matching can be found in {@link IR}. *
      * *

      @@ -54,10 +54,10 @@ * control to the run method {@code r}: *

        *
      1. The framework invokes the run method {@code r} only one time without any warm-up or compilation of - * {@code t} ({@link Warmup} is not allowed at {@code r} in this case).

      2. + * {@code t} ({@link Warmup} is not allowed at {@code r} in this case). *
      3. After this single invocation, the framework directly checks any specified {@link IR} constraints at the test - * method {@code t}. The run method {@code r} needs to make sure to reliably trigger a C2 compilation. Otherwise, - * IR matching will fail. More information about IR matching can be found in {@link IR}.

      4. + * method {@code t}. The run method {@code r} needs to make sure to reliably trigger a C2 compilation. Otherwise, + * IR matching will fail. More information about IR matching can be found in {@link IR}. *
      * * *

      @@ -67,21 +67,23 @@ *

    9. {@code t} is not inlined. *

    10. {@code r} is not compiled nor inlined. *

    11. {@code r} is responsible to invoke {@code t} in any way (once, multiple times or even skipping on some - * invocations of {@code r}). + * invocations of {@code r}). *

    12. {@code r} can specify the following method parameter combinations: *

        *
      • void

      • *
      • 1st parameter: {@link RunInfo} which provides some methods to check various things, including - * information about {@code t}.

      • + * information about {@code t}. *
      • Any other combination will result in a {@link TestFormatException}. *

      - *
    13. {@code t} and {@code r} must be part of the test class. Using {@code @Run} and ({@code @Test})in nested or - * other classes is not allowed. TODO write test for it

    14. + *
    15. {@code t} and {@code r} must be part of the test class. Using {@code @Run} and {@code @Test} in nested or + * other classes is not allowed.

    16. *
    17. {@code t} and {@code r} cannot specify any helper-method specific compile command annotations * ({@link ForceCompile}, {@link DontCompile}, {@link ForceInline}, {@link DontInline}).

    18. * * - * TODO: Add references to examples + *

      + * Examples on how to write custom run tests can be found in {@link jdk.test.lib.hotspot.ir_framework.examples.CustomRunTestExample} + * and also as part of the internal testing in the package {@link jdk.test.lib.hotspot.ir_framework.tests}. */ @Retention(RetentionPolicy.RUNTIME) public @interface Run { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java index f70e3c6b54d..9dbec3c74ac 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java @@ -69,7 +69,9 @@ * {@link DontCompile}, {@link ForceInline}, {@link DontInline}). * * - * TODO: Add references to examples. + *

      + * Examples on how to write base tests can be found in {@link jdk.test.lib.hotspot.ir_framework.examples.BaseTestExample} + * and also as part of the internal testing in the package {@link jdk.test.lib.hotspot.ir_framework.tests}. */ @Retention(RetentionPolicy.RUNTIME) public @interface Test { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 806b5270c9e..190fd1a8421 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -392,14 +392,7 @@ public TestFramework addScenarios(Scenario... scenarios) { */ public void start() { installWhiteBox(); - if (VERIFY_IR) { - // No IR verification is done if additional non-whitelisted JTreg VM or Javaoptions flag is specified. - VERIFY_IR = onlyWhitelistedJTregVMAndJavaOptsFlags(); - if (!VERIFY_IR) { - System.out.println("IR verification disabled due to using non-whitelisted JTreg VM or Javaoptions " + - "flag(s).\n"); - } - } + maybeDisableIRVerification(); if (scenarios == null) { try { @@ -586,6 +579,9 @@ public static void assertDeoptimizedByC2(Method m) { * End of public interface methods */ + /** + * Used to move Whitebox class to the right folder in the JTreg test + */ private void installWhiteBox() { try { ClassFileInstaller.main(WhiteBox.class.getName()); @@ -594,6 +590,26 @@ private void installWhiteBox() { } } + /** + * Disable IR verification in certain cases. + */ + private void maybeDisableIRVerification() { + if (VERIFY_IR) { + VERIFY_IR = Platform.isDebugBuild() && !Platform.isInt() && !Platform.isComp(); + if (!VERIFY_IR) { + System.out.println("IR verification disabled due to not running a debug build (required for PrintIdeal" + + "and PrintOptoAssembly), running with -Xint, or -Xcomp (use warm-up of 0 instead)"); + return; + } + + // No IR verification is done if additional non-whitelisted JTreg VM or Javaoptions flag is specified. + VERIFY_IR = onlyWhitelistedJTregVMAndJavaOptsFlags(); + if (!VERIFY_IR) { + System.out.println("IR verification disabled due to using non-whitelisted JTreg VM or Javaoptions flag(s).\n"); + } + } + } + private void startWithScenarios() { Map exceptionMap = new TreeMap<>(Comparator.comparingInt(Scenario::getIndex)); Set scenarioIndices = new HashSet<>(); @@ -788,9 +804,9 @@ private void runTestVM(List additionalFlags, Scenario scenario) { new IRMatcher(output.getHotspotPidFileName(), socket.getOutput(), testClass); } else { System.out.println("IR verification disabled either through explicitly setting -DVerify=false, due to " + - "not running a debug build, using a non-whitelisted JTreg VM or Javaopts flag, " + - "running with -Xint, or running the test VM with other VM flags that make the verification " + - "inaccurate or impossible (e.g. using -XX:CompileThreshold, running with C1 only etc.)."); + "not running a debug build, using a non-whitelisted JTreg VM or Javaopts flag like -Xint " + + "-Xint, or running the test VM with other VM flags added by user code that make the " + + "IR verification impossible (e.g. -Xint, -XX:TieredStopAtLevel=3, etc.)."); } } @@ -882,7 +898,9 @@ private void throwTestVMException(JVMOutput vmOutput) { throw new TestFormatException("\n\n" + matcher.group()); } else if (stdErr.contains("NoTestsRunException")) { shouldVerifyIR = false; - throw new NoTestsRunException(">>> No tests run due to empty set specified with -DTest and/or -DExclude"); + throw new NoTestsRunException(">>> No tests run due to empty set specified with -DTest and/or -DExclude. " + + "Make sure to provide to add at least one @Test of a base of checked test " + + "or a @Run method of a custom run test"); } else { throw new TestVMException(vmOutput); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 91cb36543d2..ce812f2cd0c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -206,23 +206,27 @@ private void start() { } private void checkHelperClass(Class clazz) { - checkTestAnnotationInnerClass(clazz, "helper"); + checkAnnotationsInClass(clazz, "helper"); for (Class c : clazz.getDeclaredClasses()) { - checkTestAnnotationInnerClass(c, "nested (and helper)"); + checkAnnotationsInClass(c, "nested (and helper)"); } } - private void checkTestAnnotationInnerClass(Class c, String clazzType) { + private void checkAnnotationsInClass(Class c, String clazzType) { Method[] methods = c.getDeclaredMethods(); for (Method m : methods) { TestFormat.checkNoThrow(getAnnotation(m, Test.class) == null, "Cannot use @Test annotation in " + clazzType + " " + c + " at " + m); + TestFormat.checkNoThrow(getAnnotation(m, Run.class) == null, + "Cannot use @Run annotation in " + clazzType + " " + c + " at " + m); + TestFormat.checkNoThrow(getAnnotation(m, Check.class) == null, + "Cannot use @Check annotation in " + clazzType + " " + c + " at " + m); } } private void parseTests() { for (Class clazz : testClass.getDeclaredClasses()) { - checkTestAnnotationInnerClass(clazz, "inner"); + checkAnnotationsInClass(clazz, "inner"); } addReplay(); // Make sure to first parse tests and make them non-inlineable and only then process compile commands. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java index c36c133d1a0..f2753646d18 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java @@ -49,19 +49,17 @@ class TestFrameworkPrepareFlags { } private static final boolean TIERED_COMPILATION = (Boolean)WHITE_BOX.getVMFlag("TieredCompilation"); - private static final CompLevel TIERED_COMPILATION_STOP_AT_LEVEL = CompLevel.forValue(((Long)WHITE_BOX.getVMFlag("TieredStopAtLevel")).intValue()); - static final boolean TEST_C1 = TIERED_COMPILATION && TIERED_COMPILATION_STOP_AT_LEVEL.getValue() < CompLevel.C2.getValue(); - - // User defined settings - static final boolean XCOMP = Platform.isComp(); - static final boolean VERBOSE = Boolean.getBoolean("Verbose"); - - static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); - static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); + private static final CompLevel TIERED_COMPILATION_STOP_AT_LEVEL = + CompLevel.forValue(((Long)WHITE_BOX.getVMFlag("TieredStopAtLevel")).intValue()); + private static final boolean TEST_C1 = TIERED_COMPILATION + && TIERED_COMPILATION_STOP_AT_LEVEL.getValue() < CompLevel.C2.getValue(); + + private static final boolean VERBOSE = Boolean.getBoolean("Verbose"); + private static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); + private static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); + private static final boolean FLIP_C1_C2 = Boolean.getBoolean("FlipC1C2"); private static final boolean REQUESTED_VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); - private static boolean VERIFY_IR = REQUESTED_VERIFY_IR && USE_COMPILER && !XCOMP && !EXCLUDE_RANDOM && !TEST_C1 - && Platform.isDebugBuild() && !Platform.isInt(); - + private static final boolean VERIFY_IR = REQUESTED_VERIFY_IR && USE_COMPILER && !EXCLUDE_RANDOM && !FLIP_C1_C2 && !TEST_C1; private static String[] getPrintFlags() { return new String[] {"-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions"}; @@ -91,32 +89,11 @@ private static void emitTestVMFlags(ArrayList flags) { } private static ArrayList prepareTestVmFlags(Class testClass) { - ArrayList cmds = new ArrayList<>(); - setupIrVerificationFlags(testClass, cmds); - -// // TODO: Only for debugging -// if (cmds.get(0).startsWith("-agentlib")) { -// cmds.set(0, "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=y,server=y"); -// } - - - return cmds; + return setupIrVerificationFlags(testClass); } - private static void setupIrVerificationFlags(Class testClass, ArrayList cmds) { - Predicate matchCompileThreshold = flag -> flag.startsWith("-XX:CompileThreshold"); - if (VERIFY_IR && (cmds.stream().anyMatch(matchCompileThreshold) - || Arrays.stream(InputArguments.getVmInputArgs()).anyMatch(matchCompileThreshold))) { - // Disable IR verification if non-default CompileThreshold is set - if (VERBOSE) { - System.out.println("Disabled IR verification due to CompileThreshold flag"); - } - VERIFY_IR = false; - } else if (!VERIFY_IR && REQUESTED_VERIFY_IR) { - System.out.println("IR Verification disabled either due to not running a debug build, running with -Xint, or other " + - "VM flags that make the verification inaccurate or impossible (e.g. running with C1 only)."); - } - + private static ArrayList setupIrVerificationFlags(Class testClass) { + ArrayList cmds = new ArrayList<>(); if (VERIFY_IR) { // Add print flags for IR verification cmds.addAll(Arrays.asList(getPrintFlags())); @@ -130,6 +107,7 @@ private static void setupIrVerificationFlags(Class testClass, ArrayList cmds, Class testClass, String option) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java similarity index 60% rename from test/lib/jdk/test/lib/hotspot/ir_framework/examples/TestExample.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java index f1332ca4429..263376a1c72 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java @@ -21,18 +21,43 @@ * questions. */ +package jdk.test.lib.hotspot.ir_framework.examples; + +import jdk.test.lib.hotspot.ir_framework.*; + /* * @test * @summary Example test to use the new test framework. * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.examples.TestExample + * @run driver jdk.test.lib.hotspot.ir_framework.examples.BaseTestExample */ -package jdk.test.lib.hotspot.ir_framework.examples; - -import jdk.test.lib.hotspot.ir_framework.*; - -public class TestExample { +/** + * If there is no warm up specified the Test Framework will do the following: + *

        + *
      1. Invoke @Test method {@link TestFrameworkExecution#WARMUP_ITERATIONS} many times.

      2. + *
      3. Then do compilation of @Test method. (**)

      4. + *
      5. Invoke @Test method once again

      6. + *
      + *

      + * + * Configurable things for simple tests (no @Run or @Check) at @Test method: + *

        + *
      • compLevel: Specify at which compilation level the test should be compiled by the framework at step (**). + * If {@link CompLevel#WAIT_FOR_COMPILATION} is specified, the framework will continue invoke the + * method until HotSpot compiles it. If it is not compiled after 10s, an exception is thrown. + *

      • @Warmup: Change warm-up iterations of test (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS) + *

      • @Arguments: If a @Test method specifies arguments, you need to provide arguments by using @Arguments such + * that the framework knows how to call the method. If you need more complex values, use @Run. + *

      • @IR: Arbitrary number of @IR rules. + *

      + * + * @see Test + * @see Arguments + * @see Warmup + * @see TestFramework + */ +public class BaseTestExample { int iFld; @@ -40,24 +65,6 @@ public static void main(String[] args) { TestFramework.run(); // equivalent to TestFramework.run(TestSimpleTest.class) } - /* - * If there is no warm up specified the Test Framework will do the following: - * - Invoke @Test method TestFrameworkExecution.WARMUP_ITERATIONS many times. - * - Then do compilation of @Test method. (**) - * - Invoke @Test method once again - */ - - /* - * Configurable things for simple tests (no @Run or @Check) at @Test method: - * - compLevel: Specify at which compilation level the test should be compiled by the framework at step (**). - * If WAIT_FOR_COMPILATION is specified, the framework will continue to invoke the method until - * HotSpot compiles it. If it is not compiled after 10s, an exception is thrown. - * - @Warmup: Change warm-up iterations of test (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS) - * - @Arguments: If a @Test method specifies arguments, you need to provide arguments by using @Arguments such - * that the framework knows how to call the method. If you need more complex values, use @Run. - * - @IR: Arbitrary number of @IR rules. - */ - // Test without arguments. @Test public void mostBasicTest() { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java similarity index 60% rename from test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckExample.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java index 7ef1a653744..0c84e564c63 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java @@ -20,45 +20,58 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ + +package jdk.test.lib.hotspot.ir_framework.examples; + +import jdk.test.lib.hotspot.ir_framework.*; /* * @test * @summary Example test to use the new test framework. * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.examples.CheckExample + * @run driver jdk.test.lib.hotspot.ir_framework.examples.CheckedTestExample */ - -package jdk.test.lib.hotspot.ir_framework.examples; - -import jdk.test.lib.hotspot.ir_framework.*; -public class CheckExample { +/** + * If there is no non-default warm-up specified, the Test Framework will do the following: + *
        + *
      1. Invoke @Test method {@link TestFrameworkExecution#WARMUP_ITERATIONS} many times.

      2. + *
      3. By default, after each invocation, the @Check method of the @Test method is invoked. This can be disabled + * by using {@link CheckAt#COMPILED}

      4. + *
      5. After the warm-up, the @Test method is compiled.

      6. + *
      7. Invoke @Test method once again and then always invoke the @Check method once again.

      8. + *
      + *

      + * + * Configurable things for checked tests: + *

        + *
      • At @Test method:

      • + *
          + *
        • @Warmup: Change warm-up iterations of test (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS)

        • + *
        • @Arguments: If a @Test method specifies arguments, you need to provide arguments by using @Arguments + * such that the framework knows how to call the method. If you need more complex values, use a + * custom run test with @Run.

        • + *
        • @IR: Arbitrary number of @IR rules.

        • + *
        + *
      • At @Check method:

      • + *
          + *
        • {@link Check#when}: When should the @Check method be invoked.

        • + *
        • No @IR annotations.

        • + *
        + *
      + * + * @see Check + * @see Test + * @see Arguments + * @see Warmup + * @see TestFramework + */ +public class CheckedTestExample { public static void main(String[] args) { TestFramework.run(); // equivalent to TestFramework.run(TestSimpleTest.class) } - /* - * If there is no warm up specified the Test Framework will do the following: - * - Invoke @Test method TestFrameworkExecution.WARMUP_ITERATIONS many times. - * - By default, after each invocation, the @Check method of the @Test method is invoked. This can be disabled by - * using CheckAt.COMPILED. - * - After the warmup, the @Test method. - * - Invoke @Test method once again and then always the @Check method once. - */ - - /* - * Configurable things for checked tests: - * - At @Test method: - * - @Warmup: Change warm-up iterations of test (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS) - * - @Arguments: If a @Test method specifies arguments, you need to provide arguments by using @Arguments such - * that the framework knows how to call the method. If you need more complex values, use @Run. - * - @IR: Arbitrary number of @IR rules. - * - At @Check method: - * - when: When should the @Check method be invoked. - * - No @IR annotations. - */ - @Test @Arguments(Argument.DEFAULT) // As with normal tests, you need to tell the framework what the argument is. @Warmup(100) // As with normal tests, you can specify the warmup iterations. @@ -96,6 +109,9 @@ public int test3() { @Check(test = "test3") public void checkWithTestInfo(TestInfo info) { // Do some checks after an invocation. Additional queries with TestInfo. + if (!info.isWarmUp()) { + // ... + } } @Test @@ -103,18 +119,20 @@ public int test4() { return 42; } - // This version of @Check passes a TestInfo object to the check which contains some additional information about the test - // and additionally the return value. The order of the arguments is important. The return value must come first and then - // the TestInfo parameter. Any other combination of different arguments are forbidden to specify for @Check methods. + // This version of @Check passes the return value and a TestInfo object to the check which contains some additional + // information about the test. The order of the arguments is important. The return value must come first and the + // the TestInfo parameter second. Any other combination or use of different arguments are forbidden for @Check methods. @Check(test = "test4") public void checkWithReturnAndTestInfo(int returnValue, TestInfo info) { // Do some checks after an invocation. Additional queries with TestInfo. if (returnValue != 42) { throw new RuntimeException("Must match"); } + if (!info.isWarmUp()) { + // ... + } } - @Test public int test5() { return 42; @@ -122,8 +140,9 @@ public int test5() { // Check method for test5() is only invoked once warmup is finished and test() has been compiled by the Test Framework. @Check(test = "test5", when = CheckAt.COMPILED) // Specify the @Test method for which this method is a check. - public void checkAfterCompiled() { + public void checkAfterCompiled(TestInfo info) { // Do some checks after compilation. + TestFramework.assertCompiled(info.getTest()); // Test is compiled by framework after warm-up. } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/RunExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java similarity index 54% rename from test/lib/jdk/test/lib/hotspot/ir_framework/examples/RunExample.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java index 6909e6e1a16..838e974332e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/RunExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java @@ -21,6 +21,10 @@ * questions. */ +package jdk.test.lib.hotspot.ir_framework.examples; + +import jdk.test.lib.hotspot.ir_framework.*; + /* * @test * @summary Example test to use the new test framework. @@ -28,39 +32,54 @@ * @run driver jdk.test.lib.hotspot.ir_framework.examples.RunExample */ -package jdk.test.lib.hotspot.ir_framework.examples; - -import jdk.test.lib.hotspot.ir_framework.*; - -public class RunExample { +/** + * If there is no warm-up specified, the Test Framework will do the following: + *
        + *
      1. Invoke @Run method {#link TestFrameworkExecution#WARMUP_ITERATIONS} many times. Note that the @Run method + * is responsible to invoke the @Test methods to warm it up properly. This is not done by the framework. Not + * invoking a @Test method will result in an -Xcomp like compilation of the method as there is no profile + * information for it. The @Run method can do any arbitrary argument setup and return value verification and + * can invoke the @Test methods multiple times in a single invocation of the @Run method or even skip some + * test invocations. + *

      2. After the warm-up, the @Test methods are compiled (there can be multiple @Test methods).

      3. + *
      4. Invoke the @Run method once again.

      5. + *
      + *

      + * + * Configurable things for custom run tests: + *

        + *
      • At @Test methods:

      • + *
          + *
        • @IR: Arbitrary number of @IR rules.

        • + *
        • No @Warmup, this must be set at @Run method.

        • + *
        • No @Arguments, the arguments are set by @Run method.

        • + *
        + *
      • At @Run method:

      • + *
          + *
        • @Warmup: Change warm-up iterations of @Run method (defined by default by + * TestFrameworkExecution.WARMUP_ITERATIONS) + *

        • {@link Run#test}: Specify any number of @Test methods. They cannot be shared with other @Check or + * @Run methods. + *

        • {@link Run#mode}: Choose between normal invocation as described above or {@link RunMode#STANDALONE}. + * STANDALONE only invokes the @Run method once without warm-up or a compilation by the + * Test Framework. The only thing done by the framework is the verification of any @IR + * rules afterwards. The STANDALONE @Run method needs to make sure that a C2 compilation + * is reliably triggered if there are any @IR rules. + *

        • No @IR annotations

        • + *
        + *
      + * + * @see Run + * @see Test + * @see RunMode + * @see TestFramework + */ +public class CustomRunTestExample { public static void main(String[] args) { TestFramework.run(); // equivalent to TestFramework.run(TestSimpleTest.class) } - /* - * If there is no warm up specified the Test Framework will do the following: - * - Invoke @Run method TestFrameworkExecution.WARMUP_ITERATIONS many times. Note that the @Run method is responsible - * to invoke the @Test methods. This is not done by the framework. The @Run method can do any arbitrary argument setup - * and return value verification. - * - After the warm-up, the @Test methods are compiled (there can be multiple @Test methods). - * - Invoke @Run method once again. - */ - - /* - * Configurable things for custom run tests: - * - At @Test method: - * - @IR: Arbitrary number of @IR rules. - * - No @Warmup, this must be set at @Run method. - * - No @Arguments, these are set by @Run method. - * - At @Run method: - * - @Warmup: Change warm-up iterations of @Run method (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS) - * - test: Specify any number of @Test methods. They cannot be shared with other @Check or @Run methods. - * - mode: Choose between normal invocation as described above or STANDALONE. STANDALONE only invokes the @Run - * method once without warmup or a compilation by the Test Framework. - * - No @IR annotations - */ - @Test public int test(int x) { return x; @@ -81,12 +100,15 @@ public int test2(int x) { return x; } - // This version of @Run passes the RunInfo object as an argument. No other argument combinations are allowed. + // This version of @Run passes the RunInfo object as an argument. No other arguments and combiniations are allowed. @Run(test = "test2") public void runWithRunInfo(RunInfo info) { - int returnValue = test(34); - if (returnValue != 34) { - throw new RuntimeException("Must match"); + // We could also skip some invocations. This might have an influence on possible @IR rules, need to be careful. + if (info.getRandomBoolean()) { + int returnValue = test(34); + if (returnValue != 34) { + throw new RuntimeException("Must match"); + } } } @@ -110,8 +132,8 @@ public int test4(int x) { return x; } - // This version of @Run is only invoked once by the Test Framework. There is no warm up and no compilation done - // by the Test Framework + // This version of @Run is only invoked once by the Test Framework. There is no warm-up and no compilation done + // by the Test Framework. The only thing done by the framework is @IR rule verification. @Run(test = "test4", mode = RunMode.STANDALONE) public void runOnlyOnce() { int returnValue = test4(34); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java new file mode 100644 index 00000000000..b09abf73a63 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework.examples; + +import jdk.test.lib.hotspot.ir_framework.*; + +/* + * @test + * @summary Example test to use the new test framework. + * @library /test/lib + * @run driver jdk.test.lib.hotspot.ir_framework.examples.IRExample + */ + + +/** + * Multiple @IR rules can be specified at @Test methods. The framework performs a regex based match on the PrintIdeal + * and PrintOptoAssembly of the run test VM. Some default string regexes for IR nodes are defined in the framework + * IRNode class. There are two kinds of checks: + *
        + *
      • {@link IR#failOn}: One or more (IR node) regexes that are not allowed to occur in the IR (neither in + * PrintIdeal nor in PrintOptoAssembly)

      • + *
      • {@link IR#counts}: One or more regexes-count pairs specifies how often an (IR node) regex must be found in + * PrintIdeal and PrintOptoAssembly.

      • + *
      + *

      + * + * One might also want to restrict the application of certain @IR rules depending on the used flags in the test VM. + * These could be flags defined by the user or by JTreg. In the latter case, the flags must be whitelisted (see + * {@link TestFramework}) most of them should not have an impact on the IR except for different GC flags which should + * be considered) to enable a verification by the framework (see below). The @IR rules thus have an option to restrict + * their application: + *

        + *
      • {@link IR#applyIf}: Only apply a rule if a flag has a certain value

      • + *
      • {@link IR#applyIfNot}: Only apply a rule if a flag has NOT a certain value (inverse of applyIf)

      • + *
      • {@link IR#applyIfAnd}: Only apply a rule if all flags have the specified value

      • + *
      • {@link IR#applyIfOr}: Only apply a rule if at least one flag has the specified value

      • + *
      + *

      + * + * The framework, however, does not perform the verification if: + *

        + *
      • -DVerifyIR=false is used

      • + *
      • The test is run with a non-debug build

      • + *
      • -Xcomp, -Xint, -XX:-UseCompile, -XX:CompileThreshold, -DFlipC1C2=true, or -DExcludeRandom=true are used.

      • + *
      • JTreg specifies non-whitelisted flags as VM and/or Javaoptions (could change the IR in an unexpected way)

      • + *
      + * + * @see IR + * @see Test + * @see TestFramework + */ +// This test is expected to fail when run with JTreg. +public class IRExample { + + int iFld, iFld2, iFld3; + + public static void main(String[] args) { + TestFramework.run(); // First run tests from IRExample + try { + TestFramework.run(FailingExamples.class); // Secondly, run tests from FailingExamples + } catch (IRViolationException e) { + // Expected. Check output to see how IR failures are reported. + throw e; + } + } + + // Rules with failOn constraint which all pass + @Test + @IR(failOn = IRNode.LOAD) // 1 default regex + @IR(failOn = {IRNode.LOAD, IRNode.LOOP}) // 2 default regexes + @IR(failOn = {IRNode.LOAD, "some regex that does not occur"}) // 1 default regex and a user-defined regex + // Rule with special configurable default regexes. All regexes with a "_OF" postfix in IR node expect a + // second string specifying an additional required information. + @IR(failOn = {IRNode.STORE_OF_FIELD, "iFld2", IRNode.LOAD, IRNode.STORE_OF_CLASS, "Foo"}) + public void goodFailOn() { + iFld = 42; // No load, no loop, no store to iFld2, no store to class Foo + } + + // Rules with counts constraint which all pass + @Test + @IR(counts = {IRNode.STORE, "2"}) // 1 default regex + @IR(counts = {IRNode.LOAD, "0"}) // equivalent to failOn = IRNode.LOAD + @IR(counts = {IRNode.STORE, "2", + IRNode.LOAD, "0"}) // 2 default regexes + @IR(counts = {IRNode.STORE, "2", + "some regex that does not occur", "0"}) // 1 default regex and a user-defined regex + // Rule with special configurable default regexes. All regexes with a "_OF" postfix in IR node expect a + // second string specifying an additional required information. + @IR(counts = {IRNode.STORE_OF_FIELD, "iFld", "1", + IRNode.STORE, "2", + IRNode.STORE_OF_CLASS, "IRExample", "2"}) + public void goodCounts() { + iFld = 42; // No load, store to iFld in class IRExample + iFld2 = 42; // No load, store to iFld2 in class IRExample + } + + // @IR rules can also specify both type of checks in the same rule + @Test + @IR(failOn = {IRNode.ALLOC, + IRNode.LOOP}, + counts = {IRNode.LOAD, "2", + IRNode.LOAD_OF_FIELD, "iFld2", "1", + IRNode.LOAD_OF_CLASS, "IRExample", "2"}) + public void mixFailOnAndCounts() { + iFld = iFld2; + iFld2 = iFld3; + } +} + +class FailingExamples { + int iFld2, iFld3; + IRExample irExample = new IRExample(); + + // Rules with failOn constraint which all fail. + @Test + @IR(failOn = IRNode.STORE) + @IR(failOn = {IRNode.STORE, IRNode.LOOP}) // LOOP regex not found but STORE regex, letting the rule fail + @IR(failOn = {IRNode.LOOP, IRNode.STORE}) // Order does not matter + @IR(failOn = {IRNode.STORE, IRNode.LOAD}) // LOOP and STORE regex, letting the rule fail + @IR(failOn = {"LoadI"}) // LoadI can be found in PrintIdeal letting the rule fail + // Store to iFld, store, and store to class IRExample, all 3 regexes found letting the rule fail + @IR(failOn = {IRNode.STORE_OF_FIELD, "iFld", IRNode.STORE, IRNode.STORE_OF_CLASS, "IRExample"}) + public void badFailOn() { + irExample.iFld = iFld2; // Store to iFld in class IRExample, load from iFld2 + } + + + // Rules with counts constraint which all fail + @Test + @IR(counts = {IRNode.STORE, "1"}) // There are 2 stores + @IR(counts = {IRNode.LOAD, "0"}) // equivalent to failOn = IRNode.LOAD, there is 1 load + @IR(counts = {IRNode.STORE, "1", + IRNode.LOAD, "1"}) // first constraint holds (there is 1 load) but 2 stores, letting this rule fail + @IR(counts = {IRNode.LOAD, "1", + IRNode.STORE, "1"}) // order does not matter + @IR(counts = {"some regex that does not occur", "1"}) // user-defined regex does not occur once + // Rule with special configurable default regexes. All regexes with a "_OF" postfix in IR node expect a + // second string specifying an additional required information. + @IR(counts = {IRNode.STORE_OF_FIELD, "iFld", "2", // Only one store to iFld + IRNode.LOAD, "2", // Only 1 load + IRNode.STORE_OF_CLASS, "Foo", "1"}) // No store to class Foo + public void badCounts() { + irExample.iFld = iFld3; // No load, store to iFld in class IRExample + iFld2 = 42; // No load, store to iFld2 in class IRExample + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/SimpleExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/SimpleExample.java deleted file mode 100644 index 94df2e068fc..00000000000 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/SimpleExample.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2021, 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. - */ - -/* - * @test - * @summary Example test to use the new test framework. - * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.examples.SimpleExample - */ - -package jdk.test.lib.hotspot.ir_framework.examples; - -import jdk.test.lib.hotspot.ir_framework.*; - -public class SimpleExample { - - int iFld; - - public static void main(String[] args) { - TestFramework.run(); - } - - // TestFramework will verify that this @IR rule works if it is called with a debug build. - // With a product build, it just executes this method without IR verification (Print flags - // for verification are only available in debug builds). - @Test - @IR(failOn = IRNode.LOOP, counts = {IRNode.STORE_I, "1"}) - public void test() { - iFld = 42; - } -} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java index 3afb993ea71..9e8b6b05e55 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java @@ -901,13 +901,37 @@ class BadInnerClassTest { class InnerClass { @Test - public void noTestInInnerClass() {} + public void noTestInInnerClass1() {} + + @Test + public void noTestInInnerClass2() {} + + @Check(test = "noTestInInnerClass2") + public void checkNoTestInInnerClass2() {} + + @Test + public void noTestInInnerClass3() {} + + @Run(test = "noTestInInnerClass3") + public void checkNoTestInInnerClass3() {} } static class StaticInnerClass { @Test - public void noTestInInnerClass() {} + public void noTestInInnerStaticClass1() {} + + @Test + public void noTestInStaticInnerClass2() {} + + @Check(test = "noTestInStaticInnerClass2") + public void checkNoTestInStaticInnerClass2() {} + + @Test + public void noTestInStaticInnerClass3() {} + + @Run(test = "noTestInStaticInnerClass3") + public void checkNoTestInStaticInnerClass3() {} } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java index 04c32954c03..c9c13928465 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java @@ -50,11 +50,17 @@ public static void main(String[] args) { } try { - TestFramework.runWithHelperClasses(BadHelperClasses.class, BadHelper.class); + TestFramework.runWithHelperClasses(BadHelperClass.class, BadHelper.class); shouldNotReach(); } catch (TestFormatException e) { Asserts.assertTrue(e.getMessage().contains("Cannot use @Test annotation in helper class")); + Asserts.assertTrue(e.getMessage().contains("Cannot use @Check annotation in helper class")); + Asserts.assertTrue(e.getMessage().contains("Cannot use @Run annotation in helper class")); Asserts.assertTrue(e.getMessage().contains("noTestInHelper")); + Asserts.assertTrue(e.getMessage().contains("test2")); + Asserts.assertTrue(e.getMessage().contains("check2")); + Asserts.assertTrue(e.getMessage().contains("test3")); + Asserts.assertTrue(e.getMessage().contains("run3")); } try { @@ -124,12 +130,25 @@ public static void foo() { } } -class BadHelperClasses { +class BadHelperClass { @Test - public void test() {} -} + public void test1() {} + } + class BadHelper { @Test public void noTestInHelper() {} + + @Test + public void test2() {} + + @Check(test = "test2") + public void check2() {} + + @Test + public void test3() {} + + @Run(test = "test3") + public void run3() {} } From bfeeec7eef2dc754301cedfc3d35921db74f995c Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 9 Apr 2021 16:16:19 +0200 Subject: [PATCH 097/131] Fix TestLWorld, add more tests for Test and Exclude, add tests for RunInfo and TestInfo usage, add isCompilationSkipped to test info objects, update isC2CompilationEnabled, fix Test/Exclude to only specify @Test methods --- .../valhalla/inlinetypes/TestLWorld.java | 9 +- .../hotspot/ir_framework/AbstractInfo.java | 11 +- .../hotspot/ir_framework/DeclaredTest.java | 122 +++++++++++ .../lib/hotspot/ir_framework/RunInfo.java | 120 ++++++++--- .../hotspot/ir_framework/TestFramework.java | 5 +- .../ir_framework/TestFrameworkExecution.java | 131 +++--------- .../lib/hotspot/ir_framework/TestInfo.java | 19 +- .../tests/TestDTestAndExclude.java | 75 ++++++- .../ir_framework/tests/TestRunTests.java | 200 ++++++++++++++++++ 9 files changed, 534 insertions(+), 158 deletions(-) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/DeclaredTest.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java index 5e158b08177..eb59a4fd0a9 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java @@ -2480,10 +2480,11 @@ public void test93_verifier(RunInfo info) { } catch (ClassCastException cce) { } } - boolean compiled = TestFramework.isC2Compiled(m); - Asserts.assertTrue(compiled || (j != extra-1)); - if (!compiled) { - TestFramework.compile(m, CompLevel.C2); + boolean compiled = TestFramework.isCompiled(m); + boolean compilationSkipped = info.isCompilationSkipped(); + Asserts.assertTrue(compilationSkipped || compiled || (j != extra-1)); + if (!compilationSkipped && !compiled) { + TestFramework.compile(m, CompLevel.ANY); } } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java index 4649c27c939..45638aa1305 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java @@ -138,14 +138,13 @@ public Method getTestClassMethod(String name, Class... args) { } /** - * Returns a boolean indicating if the test VM runs with flags that only allow C1 compilations: - * {@code -XX:+TieredCompilation -XX:TieredStopAtLevel={1,2,3}} + * Returns a boolean indicating if the test VM runs with flags that allow C2 compilations. * - * @return {@code true} if only C1 compilations are allowed; - * {@code false} otherwise. + * @return {@code true} if C2 compilations are allowed; + * {@code false} otherwise (run with {@code -XX:TieredStopAtLevel={1,2,3}, -XX:-Com}. */ - public boolean isC1Test() { - return TestFrameworkExecution.TEST_C1; + public boolean isC2CompilationEnabled() { + return TestFrameworkExecution.USE_COMPILER && !TestFrameworkExecution.TEST_C1; } /** diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/DeclaredTest.java b/test/lib/jdk/test/lib/hotspot/ir_framework/DeclaredTest.java new file mode 100644 index 00000000000..2b040c98e2b --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/DeclaredTest.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +import java.lang.reflect.Method; +import java.util.Arrays; + +/** + * This class represents a @Test method. + */ +class DeclaredTest { + private final Method testMethod; + private final ArgumentValue[] arguments; + private final int warmupIterations; + private final CompLevel compLevel; + private Method attachedMethod; + + public DeclaredTest(Method testMethod, ArgumentValue[] arguments, CompLevel compLevel, int warmupIterations) { + // Make sure we can also call non-public or public methods in package private classes + testMethod.setAccessible(true); + this.testMethod = testMethod; + this.compLevel = compLevel; + this.arguments = arguments; + this.warmupIterations = warmupIterations; + this.attachedMethod = null; + } + + public Method getTestMethod() { + return testMethod; + } + + public CompLevel getCompLevel() { + return compLevel; + } + + public int getWarmupIterations() { + return warmupIterations; + } + + public boolean hasArguments() { + return arguments != null; + } + + public Object[] getArguments() { + return Arrays.stream(arguments).map(ArgumentValue::getArgument).toArray(); + } + + public void setAttachedMethod(Method m) { + attachedMethod = m; + } + + public Method getAttachedMethod() { + return attachedMethod; + } + + public void printFixedRandomArguments() { + if (hasArguments()) { + boolean hasRandomArgs = false; + StringBuilder builder = new StringBuilder("Fixed random arguments for method ").append(testMethod).append(": "); + for (int i = 0; i < arguments.length; i++) { + ArgumentValue argument = arguments[i]; + if (argument.isFixedRandom()) { + hasRandomArgs = true; + Object argumentVal = argument.getArgument(); + String argumentValString = argumentVal.toString(); + if (argumentVal instanceof Character) { + argumentValString += " (" + (int)(Character)argumentVal + ")"; + } + builder.append("arg ").append(i).append(": ").append(argumentValString).append(", "); + } + } + if (hasRandomArgs) { + // Drop the last comma and space. + builder.setLength(builder.length() - 2); + System.out.println(builder.toString()); + } + } + } + + public String getArgumentsString() { + if (hasArguments()) { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < arguments.length; i++) { + builder.append("arg ").append(i).append(": ").append(arguments[i].getArgument()).append(", "); + } + builder.setLength(builder.length() - 2); + return builder.toString(); + } else { + return ""; + } + } + + public Object invoke(Object obj, Object... args) { + try { + return testMethod.invoke(obj, args); + } catch (Exception e) { + throw new TestRunException("There was an error while invoking @Test method " + testMethod, e); + } + } +} + diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java index 976d1ff3b99..58fbfcf3c48 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java @@ -35,21 +35,23 @@ */ public class RunInfo extends AbstractInfo { private final Method testMethod; - private final Map testMethods; - - RunInfo(Method testMethod) { - super(testMethod.getDeclaringClass()); - this.testMethod = testMethod; - this.testMethods = null; - } - - RunInfo(List testMethods) { - super(testMethods.get(0).getDeclaringClass()); - this.testMethods = new HashMap<>(); - for (Method m : testMethods) { - this.testMethods.put(m.getName(), m); + private final DeclaredTest test; + private final Map tests; + private final boolean hasMultipleTests; + + RunInfo(List tests) { + super(tests.get(0).getTestMethod().getDeclaringClass()); + this.test = tests.get(0); + this.testMethod = test.getTestMethod(); + this.hasMultipleTests = tests.size() != 1; + if (hasMultipleTests) { + this.tests = new HashMap<>(); + for (DeclaredTest test : tests) { + this.tests.put(test.getTestMethod().getName(), test); + } + } else { + this.tests = null; } - this.testMethod = testMethods.get(0); } /** @@ -64,19 +66,51 @@ public Method getTest() { return testMethod; } - /** - * Get the associated method object of the test method with the name {@code testName}. If the custom run test only - * specifies one test method ({@link Run#test()}), consider using {@link #getTest()}. + * Get the associated method object of the test method with the name {@code testName}. This method can only be called + * if the custom run test specifies more than one test method in ({@link Run#test()}). Otherwise, use {@link #getTest()}. * * @param testName the test method for which the method object should be returned. * @return the associated test method object with the name {@code testName}. - * @throws TestRunException if there is no test method with the name {@code testName}. + * @throws TestRunException if there is no test method with the name {@code testName} or if called with more than + * one associated test method. */ public Method getTest(String testName) { + checkMultipleTests("getTest"); return getMethod(testName); } + /** + * Return a boolean indicating if the framework skipped a compilation of the associated test method after the warm-up + * due to VM flags not allowing a compilation on the requested level in {@link Test#compLevel()}. This method can only + * be called if one test method is specified in the custom run test ({@link Run#test()}). Otherwise, use + * {@link #isCompilationSkipped(String)}. + * + * @return {@code true} if the framework compiled the test; + * {@code false} otherwise + * @throws TestRunException if called for a custom run test that specifies multiple test methods in {@link Run#test()}. + */ + public boolean isCompilationSkipped() { + checkSingleTest("isCompilationSkipped"); + return test.getCompLevel() == CompLevel.SKIP; + } + + /** + * Return a boolean indicating if the framework skipped a compilation of the associated test method with the name + * {@code testName} after the warm-up due to VM flags not allowing a compilation on the requested level in + * {@link Test#compLevel()}. This method can only be called if the custom run test specifies more than one test method + * in ({@link Run#test()}). Otherwise, use {@link #isCompilationSkipped()}. + * + * @param testName the test method for which the method object should be returned. + * @return {@code true} if the framework compiled the test; + * {@code false} otherwise + * @throws TestRunException if there is no test method with the name {@code testName} or if called with more than + * one associated test method. */ + public boolean isCompilationSkipped(String testName) { + checkMultipleTests("isCompilationSkipped"); + return getDeclaredTest(testName).getCompLevel() == CompLevel.SKIP; + } + /** * Returns a boolean indicating if the associated test method is C1 compiled. This method can only be called if one * test method is specified in the custom run test ({@link Run#test()}). Otherwise, use {@link #isTestC1Compiled(String)}. @@ -91,15 +125,18 @@ public boolean isTestC1Compiled() { } /** - * Returns a boolean indicating if the associated test method with the name {@code testName} is C1 compiled. If the - * custom run test only specifies one test method ({@link Run#test()}), consider using {@link #isTestC1Compiled()}. + * Returns a boolean indicating if the associated test method with the name {@code testName} is C1 compiled. + * This method can only be called if the custom run test specifies more than one test method in ({@link Run#test()}). + * Otherwise, use {@link #isTestC1Compiled()}. * * @param testName the name of the test method. * @return {@code true} if the test method with the name {@code testName} is C2 compiled; * {@code false} otherwise. - * @throws TestRunException if there is no test method with the name {@code testName}. + * @throws TestRunException if there is no test method with the name {@code testName} or if called with more than + * one associated test method. */ public boolean isTestC1Compiled(String testName) { + checkMultipleTests("isTestC1Compiled"); return TestFrameworkExecution.isC1Compiled(getMethod(testName)); } @@ -117,15 +154,18 @@ public boolean isTestC2Compiled() { } /** - * Returns a boolean indicating if the associated test method with the name {@code testName} is C2 compiled. If the - * custom run test only specifies one test method ({@link Run#test()}), consider using {@link #isTestC2Compiled()}. + * Returns a boolean indicating if the associated test method with the name {@code testName} is C2 compiled. This + * method can only be called if the custom run test specifies more than one test method in ({@link Run#test()}). + * Otherwise, use {@link #isTestC1Compiled()}. * * @param testName the name of the test method. * @return {@code true} if the test method with the name {@code testName} is C2 compiled; * {@code false} otherwise. - * @throws TestRunException if there is no test method with the name {@code testName}. + * @throws TestRunException if there is no test method with the name {@code testName} or if called with more than + * one associated test method. */ public boolean isTestC2Compiled(String testName) { + checkMultipleTests("isTestC2Compiled"); return TestFrameworkExecution.isC2Compiled(getMethod(testName)); } @@ -146,32 +186,44 @@ public boolean isTestCompiledAtLevel(CompLevel compLevel) { /** * Returns a boolean indicating if the associated test method with the name {@code testName} is compiled at - * {@code compLevel}. If thec ustom run test only specifies one test method ({@link Run#test()}), - * consider using {@link #isTestCompiledAtLevel(CompLevel)} )}. + * {@code compLevel}. This method can only be called if the custom run test specifies more than one test method + * in ({@link Run#test()}). Otherwise, use {@link #isTestCompiledAtLevel(CompLevel)}. * * @param testName the name of the test method. * @param compLevel the compilation level. * @return {@code true} if the test method with the name {@code testName} is compiled at {@code compLevel}; * {@code false} otherwise. - * @throws TestRunException if there is no test method with the name {@code testName}. + * @throws TestRunException if there is no test method with the name {@code testName} or if called with more than + * one associated test method. */ public boolean isTestCompiledAtLevel(String testName, CompLevel compLevel) { + checkMultipleTests("isTestCompiledAtLevel"); return TestFrameworkExecution.isCompiledAtLevel(getMethod(testName), compLevel); } private void checkSingleTest(String calledMethod) { - if (testMethod == null) { - throw new TestRunException("Use " + calledMethod + " with testName String argument in @Run method when running " + - "more than one @Test method."); + if (hasMultipleTests) { + throw new TestRunException("Use " + calledMethod + "(String) with testName String argument in @Run method " + + "for custom run test that specifies more than one @Test method."); } } - private Method getMethod(String testName) { - Method m = testMethods.get(testName); - if (m == null) { + private void checkMultipleTests(String calledMethod) { + if (!hasMultipleTests) { + throw new TestRunException("Use " + calledMethod + "() without testName String argument in @Run method " + + "for custom run test that specifies exactly one @Test method."); + } + } + + private DeclaredTest getDeclaredTest(String testName) { + DeclaredTest test = tests.get(testName); + if (test == null) { throw new TestRunException("Could not find @Test \"" + testName + "\" in " + testClass + " being associated with" + " corresponding @Run method."); } - return m; + return test; + } + private Method getMethod(String testName) { + return getDeclaredTest(testName).getTestMethod(); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 190fd1a8421..79c94362cb3 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -804,7 +804,7 @@ private void runTestVM(List additionalFlags, Scenario scenario) { new IRMatcher(output.getHotspotPidFileName(), socket.getOutput(), testClass); } else { System.out.println("IR verification disabled either through explicitly setting -DVerify=false, due to " + - "not running a debug build, using a non-whitelisted JTreg VM or Javaopts flag like -Xint " + + "not running a debug build, using a non-whitelisted JTreg VM or Javaopts flag like " + "-Xint, or running the test VM with other VM flags added by user code that make the " + "IR verification impossible (e.g. -Xint, -XX:TieredStopAtLevel=3, etc.)."); } @@ -899,8 +899,7 @@ private void throwTestVMException(JVMOutput vmOutput) { } else if (stdErr.contains("NoTestsRunException")) { shouldVerifyIR = false; throw new NoTestsRunException(">>> No tests run due to empty set specified with -DTest and/or -DExclude. " + - "Make sure to provide to add at least one @Test of a base of checked test " + - "or a @Run method of a custom run test"); + "Make sure to define a set of at least one @Test method"); } else { throw new TestVMException(vmOutput); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index ce812f2cd0c..00c9b9904b6 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -611,7 +611,7 @@ private void addCheckedTest(Method m, Check checkAnno, Run runAnno) { dontCompileMethod(m); // Don't inline check methods WHITE_BOX.testSetDontInlineMethod(m, true); - CheckedTest checkedTest = new CheckedTest(test, m, checkAnno, parameter, shouldExcludeTest(m.getName())); + CheckedTest checkedTest = new CheckedTest(test, m, checkAnno, parameter, shouldExcludeTest(testMethod.getName())); allTests.add(checkedTest); if (PRINT_VALID_IR_RULES) { irMatchRulePrinter.emitRuleEncoding(m, checkedTest.isSkipped()); @@ -654,6 +654,7 @@ private CheckedTest.Parameter getCheckedTestParameter(Method m, Method testMetho private void addCustomRunTest(Method m, Run runAnno) { checkRunMethod(m, runAnno); List tests = new ArrayList<>(); + boolean shouldExcludeTest = true; for (String testName : runAnno.test()) { try { Method testMethod = testMethodMap.get(testName); @@ -661,6 +662,8 @@ private void addCustomRunTest(Method m, Run runAnno) { checkCustomRunTest(m, testName, testMethod, test, runAnno.mode()); test.setAttachedMethod(m); tests.add(test); + // Only exclude custom run test if all test methods excluded + shouldExcludeTest &= shouldExcludeTest(testMethod.getName()); } catch (TestFormatException e) { // Logged, continue. } @@ -671,7 +674,7 @@ private void addCustomRunTest(Method m, Run runAnno) { dontCompileMethod(m); // Don't inline run methods WHITE_BOX.testSetDontInlineMethod(m, true); - CustomRunTest customRunTest = new CustomRunTest(m, getAnnotation(m, Warmup.class), runAnno, tests, shouldExcludeTest(m.getName())); + CustomRunTest customRunTest = new CustomRunTest(m, getAnnotation(m, Warmup.class), runAnno, tests, shouldExcludeTest); allTests.add(customRunTest); if (PRINT_VALID_IR_RULES) { tests.forEach(test -> irMatchRulePrinter.emitRuleEncoding(test.getTestMethod(), customRunTest.isSkipped())); @@ -739,7 +742,8 @@ private void runTests() { TreeMap durations = (PRINT_TIMES || VERBOSE) ? new TreeMap<>() : null; long startTime = System.nanoTime(); List testList; - if (testFilterPresent()) { + boolean testFilterPresent = testFilterPresent(); + if (testFilterPresent) { testList = allTests.stream().filter(test -> !test.isSkipped()).collect(Collectors.toList()); if (testList.isEmpty()) { throw new NoTestsRunException(); @@ -753,6 +757,10 @@ private void runTests() { Collections.shuffle(testList); } for (AbstractTest test : testList) { + if (testFilterPresent) { + System.out.print("Run "); + test.print(); + } test.run(); if (PRINT_TIMES || VERBOSE) { long endTime = System.nanoTime(); @@ -884,98 +892,6 @@ private static TriState compiledAtLevel(Method m, CompLevel level) { } -class DeclaredTest { - private final Method testMethod; - private final ArgumentValue[] arguments; - private final int warmupIterations; - private final CompLevel compLevel; - private Method attachedMethod; - - public DeclaredTest(Method testMethod, ArgumentValue[] arguments, CompLevel compLevel, int warmupIterations) { - // Make sure we can also call non-public or public methods in package private classes - testMethod.setAccessible(true); - this.testMethod = testMethod; - this.compLevel = compLevel; - this.arguments = arguments; - this.warmupIterations = warmupIterations; - this.attachedMethod = null; - } - - public Method getTestMethod() { - return testMethod; - } - - public CompLevel getCompLevel() { - return compLevel; - } - - public int getWarmupIterations() { - return warmupIterations; - } - - public boolean hasArguments() { - return arguments != null; - } - - public Object[] getArguments() { - return Arrays.stream(arguments).map(ArgumentValue::getArgument).toArray(); - } - - public void setAttachedMethod(Method m) { - attachedMethod = m; - } - - public Method getAttachedMethod() { - return attachedMethod; - } - - public void printFixedRandomArguments() { - if (hasArguments()) { - boolean hasRandomArgs = false; - StringBuilder builder = new StringBuilder("Fixed random arguments for method ").append(testMethod).append(": "); - for (int i = 0; i < arguments.length; i++) { - ArgumentValue argument = arguments[i]; - if (argument.isFixedRandom()) { - hasRandomArgs = true; - Object argumentVal = argument.getArgument(); - String argumentValString = argumentVal.toString(); - if (argumentVal instanceof Character) { - argumentValString += " (" + (int)(Character)argumentVal + ")"; - } - builder.append("arg ").append(i).append(": ").append(argumentValString).append(", "); - } - } - if (hasRandomArgs) { - // Drop the last comma and space. - builder.setLength(builder.length() - 2); - System.out.println(builder.toString()); - } - } - } - - public String getArgumentsString() { - if (hasArguments()) { - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < arguments.length; i++) { - builder.append("arg ").append(i).append(": ").append(arguments[i].getArgument()).append(", "); - } - builder.setLength(builder.length() - 2); - return builder.toString(); - } else { - return ""; - } - } - - public Object invoke(Object obj, Object... args) { - try { - return testMethod.invoke(obj, args); - } catch (Exception e) { - throw new TestRunException("There was an error while invoking @Test method " + testMethod, e); - } - } -} - - abstract class AbstractTest { protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); protected static final int TEST_COMPILATION_TIMEOUT = Integer.parseInt(System.getProperty("TestCompilationTimeout", "10000")); @@ -990,6 +906,8 @@ abstract class AbstractTest { this.skip = skip; } + abstract void print(); + protected boolean shouldCompile(DeclaredTest test) { return test.getCompLevel() != CompLevel.SKIP; } @@ -1158,12 +1076,17 @@ public BaseTest(DeclaredTest test, boolean skip) { super(test.getWarmupIterations(), skip); this.test = test; this.testMethod = test.getTestMethod(); - this.testInfo = new TestInfo(testMethod); + this.testInfo = new TestInfo(test); this.invocationTarget = createInvocationTarget(testMethod); this.shouldCompile = shouldCompile(test); this.waitForCompilation = isWaitForCompilation(test); } + @Override + void print() { + System.out.println("Base Test: " + testMethod.getName()); + } + @Override public String getName() { return testMethod.getName(); @@ -1244,6 +1167,11 @@ public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecificati } } + @Override + void print() { + System.out.println("Checked Test - @Test: " + testMethod.getName()); + } + @Override public String getName() { return checkMethod.getName(); @@ -1288,10 +1216,17 @@ public CustomRunTest(Method runMethod, Warmup warmUpAnno, Run runSpecification, this.runInvocationTarget = createInvocationTarget(runMethod); this.mode = runSpecification.mode(); this.tests = tests; + this.runInfo = new RunInfo(tests); + } + + @Override + void print() { + System.out.print("Custom Run Test - @Test"); if (tests.size() == 1) { - this.runInfo = new RunInfo(tests.get(0).getTestMethod()); + System.out.println(": " + tests.get(0).getTestMethod().getName()); } else { - this.runInfo = new RunInfo(tests.stream().map(DeclaredTest::getTestMethod).collect(Collectors.toList())); + System.out.println("s: {" + tests.stream().map(t -> t.getTestMethod().getName()) + .collect(Collectors.joining(",")) + "}"); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java index 5ac97531017..85593587ae0 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java @@ -34,10 +34,12 @@ */ public class TestInfo extends AbstractInfo { private final Method testMethod; + private final boolean compilationSkipped; - TestInfo(Method testMethod) { - super(testMethod.getDeclaringClass()); - this.testMethod = testMethod; + TestInfo(DeclaredTest test) { + super(test.getTestMethod().getDeclaringClass()); + this.testMethod = test.getTestMethod(); + this.compilationSkipped = test.getCompLevel() == CompLevel.SKIP; } /** @@ -49,6 +51,17 @@ public Method getTest() { return testMethod; } + /** + * Return a boolean indicating if the framework skipped a compilation after the warm-up due to VM flags not + * allowing a compilation on the requested level in {@link Test#compLevel()} + * + * @return {@code true} if the framework compiled the test; + * {@code false} otherwise + */ + public boolean isCompilationSkipped() { + return compilationSkipped; + } + /** * Returns a boolean indicating if the associated test method is C1 compiled. * diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDTestAndExclude.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDTestAndExclude.java index f1b6da3e7bb..5551bddb67e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDTestAndExclude.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDTestAndExclude.java @@ -43,22 +43,33 @@ public static void main(String[] args) throws Exception { run("good1,good2", "bad1", "good"); run("good1,bad1", "bad1", "good"); run("good1,bad1", "bad1,good", "good"); - run("bad1,good1", "", "badrun"); - run("bad1,good1", "good1", "badrun"); - run("bad1,good1", "asdf", "badrun"); + run("good3,bad2", "bad1,bad2", "good"); + run("goodMulti1,goodMulti2", "", "good"); + run("bad1,good1", "", "bad1"); + run("bad1,good1", "good1", "bad1"); + run("bad1,good1", "asdf", "bad1"); + run("bad2,good1", "", "runBadSingle"); + run("bad2", "runBadSingle", "runBadSingle"); + run("badMulti1,badMulti2", "", "runBadMulti"); + run("badMulti1", "", "runBadMulti"); + run("badMulti1", "badMulti2", "runBadMulti"); + run("badMulti2", "badMulti1", "runBadMulti"); + run("runBadSingle", "", "empty"); + run("runBadMulti", "", "empty"); run("asdf", "", "empty"); - run("", "good1,good2,bad1", "empty"); + run("", "good1,good2,good3,bad1,bad2,goodMulti1,goodMulti2,badMulti1,badMulti2", "empty"); + run("asdf", "good1,good2,good3,bad1,bad2,goodMulti1,goodMulti2,badMulti1,badMulti2", "empty"); run("bad1", "bad1", "empty"); run("good1", "asdf,good,good1", "empty"); } else { switch (args[0]) { case "good" -> TestFramework.run(); - case "badrun" -> { + case "bad1", "runBadMulti", "runBadSingle" -> { try { TestFramework.run(); throw new RuntimeException("should not reach"); } catch (TestVMException e) { - Asserts.assertTrue(e.getExceptionInfo().contains("expected bad1 exception")); + Asserts.assertTrue(e.getExceptionInfo().contains("expected " + args[0] + " exception")); } } case "empty" -> { @@ -78,6 +89,7 @@ public static void main(String[] args) throws Exception { * Create a VM and simulate as if it was a driver VM spawned by JTreg that has -DTest/DExclude set as VM or Javaopts */ protected static void run(String dTest, String dExclude, String arg) throws Exception { + System.out.println("Run -DTest=" + dTest + " -DExclude=" + dExclude + " arg=" + arg); OutputAnalyzer oa; ProcessBuilder process = ProcessTools.createJavaProcessBuilder( "-Dtest.class.path=" + Utils.TEST_CLASS_PATH, "-Dtest.jdk=" + Utils.TEST_JDK, @@ -88,16 +100,59 @@ protected static void run(String dTest, String dExclude, String arg) throws Exce } @Test - public void good1() { - } + public void good1() { } @Test - public void good2() { - } + public void good2() { } + + @Check(test = "good2") + public void check2() {} @Test public void bad1() { throw new RuntimeException("expected bad1 exception"); } + + @Test + public void good3() {} + + @Test + public void goodMulti1() {} + + @Test + public void goodMulti2() {} + + @Run(test = "good3") + public void runGoodSingle() { + good3(); + } + + @Run(test = {"goodMulti1", "goodMulti2"}) + public void runGoodMulti() { + goodMulti1(); + goodMulti2(); + } + + @Test + public void bad2() { + } + + @Test + public void badMulti1() { + } + + @Test + public void badMulti2() { + } + + @Run(test = "bad2") + public void runBadSingle() { + throw new RuntimeException("expected runBadSingle exception"); + } + + @Run(test = {"badMulti1", "badMulti2"}) + public void runBadMulti() { + throw new RuntimeException("expected runBadMulti exception"); + } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java index 0a5d631bc27..d43d8707895 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java @@ -48,6 +48,11 @@ public static void main(String[] args) { Arrays.stream(matches).forEach(m -> Asserts.assertTrue(e.getMessage().contains(m))); Asserts.assertEQ(e.getMessage().split("STANDALONE mode", -1).length - 1, 2); } + TestFramework.runWithFlags(SkipCompilation.class, "-XX:-UseCompiler"); + TestFramework.runWithFlags(SkipCompilation.class, "-Xint"); + TestFramework.runWithFlags(SkipC2Compilation.class, "-XX:TieredStopAtLevel=1"); + TestFramework.runWithFlags(SkipC2Compilation.class, "-XX:TieredStopAtLevel=2"); + TestFramework.runWithFlags(SkipC2Compilation.class, "-XX:TieredStopAtLevel=3"); } public int iFld; @@ -69,6 +74,7 @@ public int test2(int y) { public void run(RunInfo info) { test1(23); test2(42); + Asserts.assertTrue(info.isC2CompilationEnabled()); if (!info.isWarmUp()) { TestFramework.assertCompiledByC2(info.getTest("test1")); TestFramework.assertCompiledByC2(info.getTest("test2")); @@ -84,9 +90,34 @@ public int test3(int x) { @Run(test = "test3") public void run2(RunInfo info) { + Asserts.assertTrue(info.isC2CompilationEnabled()); test3(42); if (!info.isWarmUp()) { TestFramework.assertCompiledByC2(info.getTest()); + try { + info.getTest("test2"); + throw new RuntimeException("should not reach"); + } catch (TestRunException e) { + // Excepted, do not call this method for single associated test. + } + try { + info.isTestC1Compiled("test2"); + throw new RuntimeException("should not reach"); + } catch (TestRunException e) { + // Excepted, do not call this method for single associated test. + } + try { + info.isTestC2Compiled("test2"); + throw new RuntimeException("should not reach"); + } catch (TestRunException e) { + // Excepted, do not call this method for single associated test. + } + try { + info.isTestCompiledAtLevel("test2", CompLevel.C2); + throw new RuntimeException("should not reach"); + } catch (TestRunException e) { + // Excepted, do not call this method for single associated test. + } } } @@ -126,6 +157,30 @@ public void run4(RunInfo info) { if (!info.isWarmUp()) { TestFramework.assertCompiledByC2(info.getTest("test5")); TestFramework.assertCompiledByC2(info.getTest("test6")); + try { + info.getTest(); + throw new RuntimeException("should not reach"); + } catch (TestRunException e) { + // Excepted, do not call this method for single associated test. + } + try { + info.isTestC1Compiled(); + throw new RuntimeException("should not reach"); + } catch (TestRunException e) { + // Excepted, do not call this method for single associated test. + } + try { + info.isTestC2Compiled(); + throw new RuntimeException("should not reach"); + } catch (TestRunException e) { + // Excepted, do not call this method for single associated test. + } + try { + info.isTestCompiledAtLevel(CompLevel.C2); + throw new RuntimeException("should not reach"); + } catch (TestRunException e) { + // Excepted, do not call this method for single associated test. + } } } @@ -201,3 +256,148 @@ public int test2(int x) { public void run2(RunInfo info) { } } + +// Run with TieredStopAt=[1,3]. IR verification is skipped. +class SkipC2Compilation { + + int iFld; + @Test(compLevel = CompLevel.C2) + @IR(failOn = IRNode.STORE) // Would fail but not evaluated. + public void testC2() { + iFld = 34; + } + + @Check(test = "testC2") + public void checkC2(TestInfo info) { + Asserts.assertFalse(info.isC2CompilationEnabled()); + Asserts.assertTrue(info.isCompilationSkipped()); + } + + @Test(compLevel = CompLevel.C2) + @IR(failOn = IRNode.STORE) // Would fail but not evaluated. + public void test2C2() { + iFld = 34; + } + + + @Run(test = "test2C2") + public void run2C2(RunInfo info) { + Asserts.assertFalse(info.isC2CompilationEnabled()); + Asserts.assertTrue(info.isCompilationSkipped()); + test2C2(); + Asserts.assertTrue(info.isCompilationSkipped()); + try { + info.isCompilationSkipped("test2C2"); + throw new RuntimeException("should not reach"); + } catch (TestRunException e) { + // Excepted, do not call this method for single associated test. + } + } + + @Test(compLevel = CompLevel.C2) + @IR(failOn = IRNode.STORE) // Would fail but not evaluated. + public void test3C2() { + iFld = 34; + } + + @Test(compLevel = CompLevel.C2) + @IR(failOn = IRNode.STORE) // Would fail but not evaluated. + public void test4C2() { + iFld = 34; + } + + + @Test // Level any + @IR(failOn = IRNode.STORE) // Would fail but not evaluated. + public void testAny() { + iFld = 34; + } + + @Run(test = {"test3C2", "test4C2", "testAny"}) + public void runMulti(RunInfo info) { + Asserts.assertFalse(info.isC2CompilationEnabled()); + if (!info.isWarmUp()) { + TestFramework.assertCompiledByC1(info.getTest("testAny")); + } + Asserts.assertTrue(info.isCompilationSkipped("test3C2")); + Asserts.assertTrue(info.isCompilationSkipped("test4C2")); + Asserts.assertFalse(info.isCompilationSkipped("testAny")); + test2C2(); + Asserts.assertTrue(info.isCompilationSkipped("test3C2")); + Asserts.assertTrue(info.isCompilationSkipped("test4C2")); + Asserts.assertFalse(info.isCompilationSkipped("testAny")); + try { + info.isCompilationSkipped(); + throw new RuntimeException("should not reach"); + } catch (TestRunException e) { + // Excepted, do not call this method for multiple associated tests. + } + } +} + +// Run with -Xint and -XX:-Compiler. IR verification is skipped. +class SkipCompilation { + int iFld; + @Test(compLevel = CompLevel.C2) + @IR(failOn = IRNode.STORE) // Would fail but not evaluated. + public void testC2() { + iFld = 34; + } + + @Check(test = "testC2") + public void checkC2(TestInfo info) { + Asserts.assertTrue(info.isCompilationSkipped()); + Asserts.assertFalse(info.isC2CompilationEnabled()); + } + + @Test(compLevel = CompLevel.C2) + @IR(failOn = IRNode.STORE) // Would fail but not evaluated. + public void test2C2() { + iFld = 34; + } + + + @Run(test = "test2C2") + public void run2C2(RunInfo info) { + Asserts.assertFalse(info.isC2CompilationEnabled()); + Asserts.assertTrue(info.isCompilationSkipped()); + test2C2(); + Asserts.assertTrue(info.isCompilationSkipped()); + } + + @Test(compLevel = CompLevel.C2) + @IR(failOn = IRNode.STORE) // Would fail but not evaluated. + public void test3C2() { + iFld = 34; + } + + @Test(compLevel = CompLevel.C2) + @IR(failOn = IRNode.STORE) // Would fail but not evaluated. + public void test4C2() { + iFld = 34; + } + + + @Test // Level any + @IR(failOn = IRNode.STORE) // Would fail but not evaluated. + public void testAny() { + iFld = 34; + } + + @Run(test = {"test3C2", "test4C2", "testAny"}) + public void runMulti(RunInfo info) { + Asserts.assertFalse(info.isC2CompilationEnabled()); + if (!info.isWarmUp()) { + TestFramework.assertNotCompiled(info.getTest("testAny")); + TestFramework.assertNotCompiled(info.getTest("test3C2")); + TestFramework.assertNotCompiled(info.getTest("test4C2")); + } + Asserts.assertTrue(info.isCompilationSkipped("test3C2")); + Asserts.assertTrue(info.isCompilationSkipped("test4C2")); + Asserts.assertTrue(info.isCompilationSkipped("testAny")); + test2C2(); + Asserts.assertTrue(info.isCompilationSkipped("test3C2")); + Asserts.assertTrue(info.isCompilationSkipped("test4C2")); + Asserts.assertTrue(info.isCompilationSkipped("testAny")); + } +} From 3f4ea7cb04b6f06e8b3e343d626416212ddb2751 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 9 Apr 2021 18:41:03 +0200 Subject: [PATCH 098/131] Adding testlist logging through socket to reduce noise when just printing the entire stdout, also show rerun hint and command line when IR rules failed, fixing TestControl --- .../ir_framework/IRViolationException.java | 9 + .../hotspot/ir_framework/TestFramework.java | 162 +++++++++++++++--- .../ir_framework/TestFrameworkExecution.java | 74 ++++---- .../TestFrameworkPrepareFlags.java | 22 ++- .../hotspot/ir_framework/TestVMException.java | 31 +--- .../ir_framework/tests/TestControls.java | 2 +- 6 files changed, 201 insertions(+), 99 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java index 5995194ba2b..f4a0d3b4f30 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java @@ -33,6 +33,7 @@ */ public class IRViolationException extends RuntimeException { private final String compilations; + private String exceptionInfo; IRViolationException(String message, String compilations) { super(message); @@ -42,4 +43,12 @@ public class IRViolationException extends RuntimeException { String getCompilations() { return compilations; } + + void setExceptionInfo(String exceptionInfo) { + this.exceptionInfo = exceptionInfo; + } + + public String getExceptionInfo() { + return exceptionInfo; + } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 79c94362cb3..143f76616d8 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -128,6 +128,8 @@ public class TestFramework { ); static final boolean VERBOSE = Boolean.getBoolean("Verbose"); + static final boolean TESTLIST = !System.getProperty("Test", "").isEmpty(); + static final boolean EXCLUDELIST = !System.getProperty("Exclude", "").isEmpty(); static final String TEST_VM_FLAGS_START = "##### TestFrameworkPrepareFlags - used by TestFramework #####"; static final String TEST_VM_FLAGS_DELIMITER = " "; static final String TEST_VM_FLAGS_END = "----- END -----"; @@ -137,6 +139,7 @@ public class TestFramework { private static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); private static final boolean VERIFY_VM = Boolean.getBoolean("VerifyVM") && Platform.isDebugBuild(); private static boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); + private static final boolean REPORT_STDOUT = Boolean.getBoolean("ReportStdout"); private boolean shouldVerifyIR = true; // Should we perform IR matching? private static String lastTestVMOutput; @@ -146,6 +149,7 @@ public class TestFramework { private final List flags = new ArrayList<>(); private int defaultWarmup = -1; private TestFrameworkSocket socket; + private Scenario scenario; /* * Public interface methods @@ -403,6 +407,7 @@ public void start() { } catch (IRViolationException e) { System.out.println("Compilation(s) of failed match(es):"); System.out.println(e.getCompilations()); + System.err.println("\n" + e.getExceptionInfo()); throw e; } } else { @@ -647,11 +652,12 @@ private void reportScenarioFailures(Map exceptionMap) { errorMsg = getScenarioTitleAndFlags(scenario); } if (e instanceof IRViolationException) { + IRViolationException irException = (IRViolationException) e; // For IR violations, only show the actual violations and not the (uninteresting) stack trace. System.out.println((scenario != null ? "Scenario #" + scenario.getIndex() + " - " : "") + "Compilation(s) of failed matche(s):"); - System.out.println(((IRViolationException) e).getCompilations()); - builder.append(errorMsg).append(e.getMessage()); + System.out.println(irException.getCompilations()); + builder.append(errorMsg).append("\n").append(irException.getExceptionInfo()).append(e.getMessage()); } else if (e instanceof TestVMException) { builder.append(errorMsg).append("\n").append(((TestVMException) e).getExceptionInfo()); } else { @@ -663,6 +669,9 @@ private void reportScenarioFailures(Map exceptionMap) { builder.append("\n"); } System.err.println(builder.toString()); + if (!VERBOSE && !REPORT_STDOUT && !TESTLIST && !EXCLUDELIST) { + System.err.println(JVMOutput.getRerunHint()); + } TestRun.fail(failedScenarios + ". Please check stderr for more information."); } @@ -686,6 +695,7 @@ private void start(Scenario scenario) { return; } socket = TestFrameworkSocket.getSocket(); + this.scenario = scenario; try { // Use TestFramework flags and scenario flags for new VMs. List additionalFlags = new ArrayList<>(flags); @@ -706,7 +716,7 @@ private void start(Scenario scenario) { String flagsString = additionalFlags.isEmpty() ? "" : " - [" + String.join(", ", additionalFlags) + "]"; System.out.println("Run Test VM" + flagsString + ":"); - runTestVM(additionalFlags, scenario); + runTestVM(additionalFlags); } finally { System.out.println(); socket.close(); @@ -745,6 +755,7 @@ private void runFlagVM(List additionalFlags) { */ private ArrayList prepareFlagVMFlags(List additionalFlags) { ArrayList cmds = new ArrayList<>(); +// cmds.add( "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=y,server=y"); cmds.add("-Dtest.jdk=" + Utils.TEST_JDK); // Set java.library.path so JNI tests which rely on jtreg nativepath setting work cmds.add("-Djava.library.path=" + Utils.TEST_NATIVE_PATH); @@ -776,12 +787,9 @@ private void checkFlagVMExitCode(OutputAnalyzer oa) { } } - private void runTestVM(List additionalFlags, Scenario scenario) { + private void runTestVM(List additionalFlags) { List cmds = prepareTestVMFlags(additionalFlags); - if (shouldVerifyIR) { - // We only need the socket if we are doing IR verification. - socket.start(); - } + socket.start(); OutputAnalyzer oa; ProcessBuilder process = ProcessTools.createJavaProcessBuilder(cmds); @@ -799,14 +807,20 @@ private void runTestVM(List additionalFlags, Scenario scenario) { if (scenario != null) { scenario.setTestVMOutput(lastTestVMOutput); } + String socketOutput = socket.getOutputPrintStdout(); checkTestVMExitCode(output); if (shouldVerifyIR) { - new IRMatcher(output.getHotspotPidFileName(), socket.getOutput(), testClass); + try { + new IRMatcher(output.getHotspotPidFileName(), socketOutput, testClass); + } catch (IRViolationException e) { + e.setExceptionInfo(output.getExceptionInfo(scenario != null)); + throw e; + } } else { System.out.println("IR verification disabled either through explicitly setting -DVerify=false, due to " + "not running a debug build, using a non-whitelisted JTreg VM or Javaopts flag like " + "-Xint, or running the test VM with other VM flags added by user code that make the " + - "IR verification impossible (e.g. -Xint, -XX:TieredStopAtLevel=3, etc.)."); + "IR verification impossible (e.g. -XX:-UseCompile, -XX:TieredStopAtLevel=[1,2,3], etc.)."); } } @@ -835,10 +849,8 @@ private List prepareTestVMFlags(List additionalFlags) { cmds.add("-DWarmup=" + defaultWarmup); } - if (shouldVerifyIR) { - // Add server property flag that enables test VM to print encoding for IR verification last. - cmds.add(socket.getPortPropertyFlag()); - } + // Add server property flag that enables test VM to print encoding for IR verification last and debug messages. + cmds.add(socket.getPortPropertyFlag()); cmds.add(TestFrameworkExecution.class.getName()); cmds.add(testClass.getName()); @@ -853,8 +865,6 @@ private List prepareTestVMFlags(List additionalFlags) { * to determine if IR matching should be done or not. */ private List getTestVMFlags() { - String patternString = "(?<=" + TestFramework.TEST_VM_FLAGS_START + "\\R)" + "(.*DShouldDoIRVerification=(true|false).*)\\R" + "(?=" + IREncodingPrinter.END + ")"; - Pattern pattern = Pattern.compile(patternString); List flagList = new ArrayList<>(); if (VERIFY_VM) { @@ -869,17 +879,21 @@ private List getTestVMFlags() { System.out.println("Read sent data from flag VM from socket:"); System.out.println(flags); } + String patternString = "(?<=" + TestFramework.TEST_VM_FLAGS_START + "\\R)" + "(.*DShouldDoIRVerification=(true|false).*)\\R" + + "(?=" + IREncodingPrinter.END + ")"; + Pattern pattern = Pattern.compile(patternString); Matcher matcher = pattern.matcher(flags); check(matcher.find(), "Invalid flag encoding emitted by flag VM"); shouldVerifyIR = Boolean.parseBoolean(matcher.group(2)); flagList.addAll(Arrays.asList(matcher.group(1).split(TEST_VM_FLAGS_DELIMITER))); + flagList.add("-DShouldDoIRVerification=true"); } return flagList; } private void checkTestVMExitCode(JVMOutput vmOutput) { final int exitCode = vmOutput.getExitCode(); - if (EXCLUDE_RANDOM || (VERBOSE && exitCode == 0)) { + if (EXCLUDE_RANDOM || REPORT_STDOUT || (VERBOSE && exitCode == 0)) { System.out.println("--- OUTPUT TestFramework test VM ---"); System.out.println(vmOutput.getOutput()); } @@ -901,7 +915,7 @@ private void throwTestVMException(JVMOutput vmOutput) { throw new NoTestsRunException(">>> No tests run due to empty set specified with -DTest and/or -DExclude. " + "Make sure to define a set of at least one @Test method"); } else { - throw new TestVMException(vmOutput); + throw new TestVMException(vmOutput.getExceptionInfo(scenario != null)); } } @@ -924,6 +938,7 @@ static void fail(String failureMessage, Throwable e) { * Class to encapsulate information about the test VM output, the run process and the scenario. */ class JVMOutput { + private final Scenario scenario; private final OutputAnalyzer oa; private final ProcessBuilder process; @@ -941,7 +956,7 @@ public Scenario getScenario() { } public String getCommandLine() { - return String.join(" ", process.command()); + return "Command Line:\n" + String.join(" ", process.command()) + "\n\n"; } public int getExitCode() { @@ -963,6 +978,41 @@ public String getStderr() { public String getHotspotPidFileName() { return hotspotPidFileName; } + + /** + * Get more detailed information about the exception in a pretty format. + */ + public String getExceptionInfo(boolean stripRerunHint) { + int exitCode = getExitCode(); + String stdErr = getStderr(); + String rerunHint = ""; + String stdOut = ""; + if (exitCode == 134) { + stdOut = "\n\nStandard Output\n---------------\n" + getOutput(); + } else if (!stripRerunHint) { + rerunHint = getRerunHint(); + } + if (exitCode == 0) { + // IR exception + return getCommandLine() + rerunHint; + } else { + return "TestFramework test VM exited with code " + exitCode + "\n" + + stdOut + "\n" + getCommandLine() + "\n\nError Output\n------------\n" + stdErr + "\n\n" + rerunHint; + } + } + + public static String getRerunHint() { + return """ + ########################################################### + - To only run the failed tests use -DTest, -DExclude, + and/or -DScenarios. + - To also get the standard output of the test VM run with\s + -DReportStdout=true or for even more fine-grained logging + use -DVerbose=true. + ########################################################### + + """; + } } /** @@ -973,8 +1023,12 @@ class TestFrameworkSocket { // Static fields used by flag and test VM only. private static final int SERVER_PORT = Integer.getInteger(SERVER_PORT_PROPERTY, -1); + private static final boolean REPRODUCE = Boolean.getBoolean("Reproduce"); private static final String HOSTNAME = null; + private static final String STDOUT_PREFIX = "[STDOUT]"; + private static Socket clientSocket = null; + private static PrintWriter clientWriter = null; private final String serverPortPropertyFlag; private FutureTask socketTask; @@ -1043,16 +1097,27 @@ public void close() { * Only called by flag and test VM to write to server socket. */ public static void write(String msg, String type) { + write(msg, type, false); + } + /** + * Only called by flag and test VM to write to server socket. + */ + public static void write(String msg, String type, boolean stdout) { if (REPRODUCE) { System.out.println("Debugging Test VM: Skip writing due to -DReproduce"); return; } TestFramework.check(SERVER_PORT != -1, "Server port was not set correctly for flag and/or test VM " + "or method not called from flag or test VM"); - try (Socket socket = new Socket(HOSTNAME, SERVER_PORT); - PrintWriter out = new PrintWriter(socket.getOutputStream(), true) - ) { - out.print(msg); + try { + if (clientSocket == null) { + clientSocket = new Socket(HOSTNAME, SERVER_PORT); + clientWriter = new PrintWriter(clientSocket.getOutputStream(), true); + } + if (stdout) { + msg = STDOUT_PREFIX + msg; + } + clientWriter.println(msg); } catch (Exception e) { String failMsg = """ @@ -1070,9 +1135,60 @@ Did you directly run the test VM (TestFrameworkExecution) } } + /** + * Closes (and flushes) the printer to the socket and the socket itself. Is called as last thing before exiting + * the main() method of the flag and the test VM. + */ + public static void closeClientSocket() { + if (clientSocket != null) { + try { + clientWriter.close(); + clientSocket.close(); + } catch (IOException e) { + throw new RuntimeException("Could not close TestFrameworkExecution socket", e); + } + } + } + + /** + * Get the socket output of the flag VM. + */ public String getOutput() { try { return socketTask.get(); + + } catch (Exception e) { + TestFramework.fail("Could not read from socket task", e); + return null; + } + } + + /** + * Get the socket output from the test VM by stripping all lines starting with a [STDOUT] output and printing them + * to the standard output. + */ + public String getOutputPrintStdout() { + try { + String output = socketTask.get(); + if (TestFramework.TESTLIST || TestFramework.EXCLUDELIST) { + StringBuilder builder = new StringBuilder(); + Scanner scanner = new Scanner(output); + System.out.println("\nRun flag defined test list"); + System.out.println("--------------------------"); + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + if (line.startsWith(STDOUT_PREFIX)) { + line = "> " + line.substring(STDOUT_PREFIX.length()); + System.out.println(line); + } else { + builder.append(line).append("\n"); + } + } + System.out.println(); + return builder.toString(); + } + return output; + } catch (Exception e) { TestFramework.fail("Could not read from socket task", e); return null; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 00c9b9904b6..75173a78d9b 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -88,7 +88,7 @@ assertions from main() of your test! private static final boolean GC_AFTER = Boolean.getBoolean("GCAfter"); private static final boolean SHUFFLE_TESTS = Boolean.parseBoolean(System.getProperty("ShuffleTests", "true")); // Use separate flag as VERIFY_IR could have been set by user but due to other flags it was disabled by flag VM. - private static final boolean PRINT_VALID_IR_RULES = Integer.getInteger(TestFrameworkSocket.SERVER_PORT_PROPERTY, -1) != -1; + private static final boolean PRINT_VALID_IR_RULES = Boolean.getBoolean("ShouldDoIRVerification"); protected static final long PerMethodTrapLimit = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); protected static final boolean ProfileInterpreter = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); private static final boolean FLIP_C1_C2 = Boolean.getBoolean("FlipC1C2"); @@ -137,14 +137,18 @@ private static List createTestFilterList(String list, Class testClass } public static void main(String[] args) { - String testClassName = args[0]; - System.out.println("Framework main(), about to run tests in class " + testClassName); - Class testClass; - testClass = getClassObject(testClassName, "test"); - - TestFrameworkExecution framework = new TestFrameworkExecution(testClass); - framework.addHelperClasses(args); - framework.start(); + try { + String testClassName = args[0]; + System.out.println("Framework main(), about to run tests in class " + testClassName); + Class testClass; + testClass = getClassObject(testClassName, "test"); + + TestFrameworkExecution framework = new TestFrameworkExecution(testClass); + framework.addHelperClasses(args); + framework.start(); + } finally { + TestFrameworkSocket.closeClientSocket(); + } } protected static Class getClassObject(String className, String classType) { @@ -757,9 +761,10 @@ private void runTests() { Collections.shuffle(testList); } for (AbstractTest test : testList) { - if (testFilterPresent) { - System.out.print("Run "); - test.print(); + if (VERBOSE) { + System.out.println("Run " + test.toString()); + } else if (testFilterPresent) { + TestFrameworkSocket.write("Run " + test.toString(), "testfilter", true); } test.run(); if (PRINT_TIMES || VERBOSE) { @@ -906,8 +911,6 @@ abstract class AbstractTest { this.skip = skip; } - abstract void print(); - protected boolean shouldCompile(DeclaredTest test) { return test.getCompLevel() != CompLevel.SKIP; } @@ -947,7 +950,7 @@ public void run() { if (skip) { return; } - onRunStart(); + onStart(); for (int i = 0; i < warmupIterations; i++) { invokeTest(); } @@ -957,13 +960,15 @@ public void run() { invokeTest(); } - abstract void onRunStart(); + protected void onStart() { + // Do nothing by default + } - abstract void invokeTest(); + abstract protected void invokeTest(); - protected void onWarmupFinished() { } + abstract protected void onWarmupFinished(); - abstract void compileTest(); + abstract protected void compileTest(); protected void compileMethod(DeclaredTest test) { final Method testMethod = test.getTestMethod(); @@ -1083,8 +1088,8 @@ public BaseTest(DeclaredTest test, boolean skip) { } @Override - void print() { - System.out.println("Base Test: " + testMethod.getName()); + public String toString() { + return "Base Test: " + testMethod.getName(); } @Override @@ -1093,10 +1098,7 @@ public String getName() { } @Override - protected void onRunStart() { - if (TestFrameworkExecution.VERBOSE) { - System.out.println("Starting " + getName()); - } + protected void onStart() { test.printFixedRandomArguments(); } @@ -1168,8 +1170,8 @@ public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecificati } @Override - void print() { - System.out.println("Checked Test - @Test: " + testMethod.getName()); + public String toString() { + return "Checked Test - @Test: " + testMethod.getName(); } @Override @@ -1220,21 +1222,15 @@ public CustomRunTest(Method runMethod, Warmup warmUpAnno, Run runSpecification, } @Override - void print() { - System.out.print("Custom Run Test - @Test"); + public String toString() { + String s = "Custom Run Test - @Test"; if (tests.size() == 1) { - System.out.println(": " + tests.get(0).getTestMethod().getName()); + s += ": " + tests.get(0).getTestMethod().getName(); } else { - System.out.println("s: {" + tests.stream().map(t -> t.getTestMethod().getName()) - .collect(Collectors.joining(",")) + "}"); - } - } - - @Override - protected void onRunStart() { - if (TestFrameworkExecution.VERBOSE) { - System.out.println("Starting " + getName()); + s += "s: {" + tests.stream().map(t -> t.getTestMethod().getName()) + .collect(Collectors.joining(",")) + "}"; } + return s; } @Override diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java index f2753646d18..903a2475d52 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java @@ -66,17 +66,21 @@ private static String[] getPrintFlags() { } public static void main(String[] args) { - String testClassName = args[0]; - if (VERBOSE) { - System.out.println("TestFrameworkPrepareFlags main() called. Prepare test VM flags to run class " + testClassName); - } - Class testClass; try { - testClass = Class.forName(testClassName); - } catch (Exception e) { - throw new TestRunException("Could not find test class " + testClassName, e); + String testClassName = args[0]; + if (VERBOSE) { + System.out.println("TestFrameworkPrepareFlags main() called. Prepare test VM flags to run class " + testClassName); + } + Class testClass; + try { + testClass = Class.forName(testClassName); + } catch (Exception e) { + throw new TestRunException("Could not find test class " + testClassName, e); + } + emitTestVMFlags(prepareTestVmFlags(testClass)); + } finally { + TestFrameworkSocket.closeClientSocket(); } - emitTestVMFlags(prepareTestVmFlags(testClass)); } /** diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMException.java index 52de66423d4..00f41ed8f19 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMException.java @@ -27,37 +27,14 @@ * Exception that is thrown if the test VM has thrown any kind of exception (except for {@link TestFormatException}). */ public class TestVMException extends RuntimeException { - static final boolean REPORT_STDOUT = Boolean.parseBoolean(System.getProperty("ReportStdout", "false")); + private final String exceptionInfo; - private final JVMOutput vmOutput; - - TestVMException(JVMOutput vmOutput) { + TestVMException(String exceptionInfo) { super("There were one or multiple errors. Please check stderr for more information."); - this.vmOutput = vmOutput; + this.exceptionInfo = exceptionInfo; } - /** - * Get more detailed information about the exception in a pretty format. - */ public String getExceptionInfo() { - String errorMsg = "Command Line:\n" + vmOutput.getCommandLine() + "\n\n"; - int exitCode = vmOutput.getExitCode(); - String stdErr = vmOutput.getStderr(); - String hintStdout = ""; - String stdOut = ""; - if (REPORT_STDOUT || TestFramework.VERBOSE || exitCode == 134) { - stdOut = "\n\nStandard Output\n---------------\n" + vmOutput.getOutput(); - } else { - hintStdout = """ - ########################################################### - To also get the standard output of the test VM run with\s - -DReportStdout=true or for even more fine-grained logging - use -DVerbose=true. - ########################################################### - - """; - } - return errorMsg + "TestFramework test VM exited with code " + exitCode - + stdOut + "\n\nError Output\n------------\n" + stdErr + "\n\n" + hintStdout; + return exceptionInfo; } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java index 82f83db16dc..ebaa32c2e2c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java @@ -280,7 +280,7 @@ public void forceC2DontC1() { @Run(test = "testCompilation") @Warmup(0) public void runTestCompilation(RunInfo info) { - for (int i = 0; i < 10000; i++) { + for (int i = 0; i < 100000; i++) { dontCompileAny(); dontCompileC1(); dontCompileC2(i, i % 2 == 0); From d0b9ed1a7f34cf4459b771b18e3107d0919594f7 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 12 Apr 2021 11:16:30 +0200 Subject: [PATCH 099/131] Fix various Javadocs, especially of class headers --- .../hotspot/ir_framework/AbstractInfo.java | 9 +-- .../lib/hotspot/ir_framework/Argument.java | 4 +- .../hotspot/ir_framework/ArgumentValue.java | 57 +++++++++++++------ .../lib/hotspot/ir_framework/Arguments.java | 2 +- .../test/lib/hotspot/ir_framework/Check.java | 54 ++++++++++-------- .../lib/hotspot/ir_framework/CheckAt.java | 8 +-- .../lib/hotspot/ir_framework/DontCompile.java | 11 ++-- .../lib/hotspot/ir_framework/DontInline.java | 7 +-- .../hotspot/ir_framework/ForceCompile.java | 20 ++++--- .../ForceCompileClassInitializer.java | 17 ++++-- .../lib/hotspot/ir_framework/ForceInline.java | 5 +- .../jdk/test/lib/hotspot/ir_framework/IR.java | 24 +++++--- .../ir_framework/IRViolationException.java | 19 ++++--- .../test/lib/hotspot/ir_framework/IRs.java | 2 +- .../ir_framework/NoTestsRunException.java | 9 ++- .../test/lib/hotspot/ir_framework/Run.java | 46 ++++++++------- .../lib/hotspot/ir_framework/RunMode.java | 9 +-- .../lib/hotspot/ir_framework/Scenario.java | 12 ++-- .../test/lib/hotspot/ir_framework/Test.java | 37 ++++++------ .../hotspot/ir_framework/TestFramework.java | 19 ++++--- .../ir_framework/TestFrameworkException.java | 3 +- .../hotspot/ir_framework/TestVMException.java | 5 ++ 22 files changed, 227 insertions(+), 152 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java index 45638aa1305..dbaaba4c2d4 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java @@ -35,6 +35,7 @@ * * @see Test * @see Check + * @see Run */ abstract public class AbstractInfo { private static final Random random = new Random(); @@ -48,7 +49,7 @@ abstract public class AbstractInfo { } /** - * Returns a different boolean each time this method is invoked (switching between {@code false} and {@code true}. + * Returns a different boolean each time this method is invoked (switching between {@code false} and {@code true}). * The first invocation returns {@code false}. * * @return an inverted boolean of the result of the last invocation of this method. @@ -62,7 +63,7 @@ public boolean toggleBoolean() { /** * Get a random boolean. * - * @return a random boolean + * @return a random boolean. */ public boolean getRandomBoolean() { return random.nextBoolean(); @@ -71,7 +72,7 @@ public boolean getRandomBoolean() { /** * Get a random integer. * - * @return a random integer + * @return a random integer. */ public int getRandomInt() { return random.nextInt(); @@ -141,7 +142,7 @@ public Method getTestClassMethod(String name, Class... args) { * Returns a boolean indicating if the test VM runs with flags that allow C2 compilations. * * @return {@code true} if C2 compilations are allowed; - * {@code false} otherwise (run with {@code -XX:TieredStopAtLevel={1,2,3}, -XX:-Com}. + * {@code false} otherwise (run with {@code -XX:TieredStopAtLevel={1,2,3}, -XX:-UseCompiler}. */ public boolean isC2CompilationEnabled() { return TestFrameworkExecution.USE_COMPILER && !TestFrameworkExecution.TEST_C1; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java index bcbe958e822..fcfafeaa509 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java @@ -71,12 +71,12 @@ public enum Argument { BOOLEAN_TOGGLE_FIRST_TRUE, /** * Provides a random primitive value on the first test invocation and reuses the same value for all invocation of the test. - * Float and Double values are restricted to the range [-10000,10000]. + * Float and double values are restricted to the range [-10000,10000]. */ RANDOM_ONCE, /** * Provides a different random primitive value on each test invocation. - * Float and Double values are restricted to the range [-10000,10000]. + * Float and double values are restricted to the range [-10000,10000]. */ RANDOM_EACH } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java index b4519fd4040..60c66e7244f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java @@ -60,9 +60,10 @@ private ArgumentValue(Object argumentValue, Class randomClass) { /** * Return all arguments for the @Arguments annotation. - * @param m The @Test method - * @return Return array with Argument objects for each specified argument in the @Arguments annotation of m. - * Return null if method has no @Arguments annotation. + * + * @param m The @Test method. + * @return Returns an array with Argument objects for each specified argument in the @Arguments annotation of m. + * Returns null if method has no @Arguments annotation. */ public static ArgumentValue[] getArguments(Method m) { Arguments argumentsAnno = m.getAnnotation(Arguments.class); @@ -74,7 +75,9 @@ public static ArgumentValue[] getArguments(Method m) { Class[] declaredParameters = m.getParameterTypes(); Parameter[] declaredParameterObjects = m.getParameters(); try { - TestFormat.check(values.length == declaredParameters.length, "Number of argument values provided in @Arguments does not match the number of actual arguments in " + m); + TestFormat.check(values.length == declaredParameters.length, + "Number of argument values provided in @Arguments does not match the number " + + "of actual arguments in " + m); for (int i = 0; i < values.length; i++) { Argument specifiedArg = values[i]; @@ -86,49 +89,69 @@ public static ArgumentValue[] getArguments(Method m) { try { arguments[i] = createDefault(parameter); } catch (NoSuchMethodException e) { - TestFormat.fail("Cannot create new default instance of " + parameter + " for " + m + " due to missing default constructor"); + TestFormat.fail("Cannot create new default instance of " + parameter + + " for " + m + " due to missing default constructor"); } catch (Exception e) { - TestFormat.fail("Cannot create new default instance of " + parameter + " for " + m + ": " + e.getCause()); + TestFormat.fail("Cannot create new default instance of " + parameter + + " for " + m + ": " + e.getCause()); } } case NUMBER_42 -> { - TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_42 argument for non-number " + parameterObj + " for " + m); + TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_42 argument " + + "for non-number " + parameterObj + " for " + m); arguments[i] = create((byte) 42); } case NUMBER_MINUS_42 -> { - TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_MINUS_42 argument for non-number " + parameterObj + " for " + m); + TestFormat.check(isNumber(parameter), "Provided invalid NUMBER_MINUS_42 argument " + + "for non-number " + parameterObj + " for " + m); arguments[i] = create((byte) -42); } case MIN -> { - TestFormat.check(isNumber(parameter) || isChar(parameter), "Provided invalid MIN argument for non-number " + parameterObj + " for " + m); + TestFormat.check(isNumber(parameter) || isChar(parameter), + "Provided invalid MIN argument for non-number " + + parameterObj + " for " + m); arguments[i] = createMin(parameter); } case MAX -> { - TestFormat.check(isNumber(parameter) || isChar(parameter), "Provided invalid MAX argument for non-number " + parameterObj + " for " + m); + TestFormat.check(isNumber(parameter) || isChar(parameter), + "Provided invalid MAX argument for non-number " + + parameterObj + " for " + m); arguments[i] = createMax(parameter); } case FALSE -> { - TestFormat.check(ArgumentValue.isBoolean(parameter), "Provided invalid FALSE argument for non-boolean " + parameterObj + " for " + m); + TestFormat.check(ArgumentValue.isBoolean(parameter), + "Provided invalid FALSE argument for non-boolean " + + parameterObj + " for " + m); arguments[i] = create(false); } case TRUE -> { - TestFormat.check(ArgumentValue.isBoolean(parameter), "Provided invalid TRUE argument for non-boolean " + parameterObj + " for " + m); + TestFormat.check(ArgumentValue.isBoolean(parameter), + "Provided invalid TRUE argument for non-boolean " + + parameterObj + " for " + m); arguments[i] = create(true); } case BOOLEAN_TOGGLE_FIRST_FALSE -> { - TestFormat.check(isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + parameterObj + " for " + m); + TestFormat.check(isBoolean(parameter), + "Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + + parameterObj + " for " + m); arguments[i] = createToggleBoolean(false); } case BOOLEAN_TOGGLE_FIRST_TRUE -> { - TestFormat.check(ArgumentValue.isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + parameterObj + " for " + m); + TestFormat.check(ArgumentValue.isBoolean(parameter), + "Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + + parameterObj + " for " + m); arguments[i] = createToggleBoolean(true); } case RANDOM_ONCE -> { - TestFormat.check(isPrimitiveType(parameter), "Provided invalid RANDOM_ONCE argument for non-primitive type " + parameterObj + " for " + m); + TestFormat.check(isPrimitiveType(parameter), + "Provided invalid RANDOM_ONCE argument for non-primitive type " + + parameterObj + " for " + m); arguments[i] = createRandom(parameter); } case RANDOM_EACH -> { - TestFormat.check(isPrimitiveType(parameter), "Provided invalid RANDOM_EACH argument for non-primitive type " + parameterObj + " for " + m); + TestFormat.check(isPrimitiveType(parameter), + "Provided invalid RANDOM_EACH argument for non-primitive type " + + parameterObj + " for " + m); arguments[i] = createRandomEach(parameter); } } @@ -201,7 +224,7 @@ private static ArgumentValue createMax(Class c) { } else if (c.equals(double.class)) { argument = Double.MAX_VALUE; } else { - throw new TestFrameworkException("Invalid class passed to createMin()"); + throw new TestFrameworkException("Invalid class passed to createMax()"); } return new ArgumentValue(argument, null, false); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java index fd17ba67220..7e2e3e37e2f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java @@ -28,7 +28,7 @@ /** * This annotation is used to specify well-defined {@link Argument} values for test methods (specifying {@link Test}) when - * used as part of a base test or checked test. + * used as part of a base test or checked test. * * @see Argument * @see Test diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java index 4045536cc8f..e8dd7228764 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java @@ -23,8 +23,6 @@ package jdk.test.lib.hotspot.ir_framework; -import jdk.test.lib.hotspot.ir_framework.examples.CheckedTestExample; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -32,24 +30,25 @@ * Annotation for a check method of a checked test. * *

      - * Let {@code t} be a test method specifying the {@link Test} annotation and {@code c} be a check method specifying + * Let {@code t} be a test method specifying the {@link Test @Test} annotation and {@code c} be a check method specifying * the {@code @Check(test = "t")} annotation. These two methods represent a so-called checked test. The only * difference to a base test (see {@link Test}) is that the framework will invoke the check method {@code c} * directly after the invocation of the test method {@code t} which allows to do some additional verification, * including the return value of {@code t}. The framework does the following, similar as for base tests: *

        *
      1. The framework warms {@code t} up by invoking it for a predefined number of iterations (default: 2000) - * or any number specified by an additional {@link Warmup} annotation at {@code t} or by using - * {@link TestFramework#setDefaultWarmup(int)} (could also be 0 which skips the warm-up completely which is similar - * to simulating {@code -Xcomp}). After each invocation of {@code t}, the framework also invokes {@code c} if the - * {@code @Check} annotation specifies {@link CheckAt#EACH_INVOCATION} at {@link #when()}.

      2. + * or any number specified by an additional {@link Warmup @Warmup} annotation at {@code t} or by using + * {@link TestFramework#setDefaultWarmup(int)} (could also be 0 which skips the warm-up completely which is + * similar to simulating {@code -Xcomp}). After each invocation of {@code t}, the framework also invokes + * {@code c} if the {@code @Check} annotation specifies {@link CheckAt#EACH_INVOCATION} at {@link #when()}. + * More information about the warm-up in general can be found at {@link Warmup} *
      3. After the warm-up, the framework compiles {@code t} at the specified compilation level set by - * {@link Test#compLevel()} (default {@link CompLevel#ANY} will pick the highest available level which is usually - * {@link CompLevel#C2}).

      4. - *
      5. The framework invokes {@code t} one more time to check the compilation and immediately afterwards - * always invokes {@code c}.

      6. - *
      7. The framework checks any specified {@link IR} constraints at the test method {@code t}. - * More information about IR matching can be found in {@link IR}.

      8. + * {@link Test#compLevel()} (default {@link CompLevel#ANY} will pick the highest available level which is + * usually {@link CompLevel#C2}). + *
      9. The framework invokes {@code t} one more time to run the compilation. Afterwards, the framework will + * always invoke {@code c} again to be able perform additional checks after the compilation of {@code t}.

      10. + *
      11. The framework checks any specified {@link IR @IR} constraints at the test method {@code t}. + * More information about IR matching can be found at {@link IR}.

      12. *
      * *

      @@ -58,22 +57,23 @@ * The following additional constraints must be met for the test method {@code t} and check method {@code c}: *

        *
      • {@code c} must specify the method name {@code t} as property in {@code @Check(test = "t")} - * (see {@link #test()}. Specifying a non-{@code Test} annotated method or a {@code @Test} method that - * has already been used by another {@code @Check} or {@link Run} method results in a {@link TestFormatException}. + * (see {@link #test()}. Specifying a non-{@code @Test} annotated method or a {@code @Test} method that + * has already been used by another {@code @Check} or {@link Run @Run} method results in a {@link TestFormatException}. *

      • {@code c} can specify the following method parameter combinations: *

          *
        • void

        • - *
        • 1st parameter: {@link TestInfo} which provides some methods to check various things, including - * information about {@code t}.

        • - *
        • 1st parameter specifies the exact same type as the return value of {@code t}. When {@code c} is - * invoked by the framework, this parameter contains the return value of {@code t}.

        • - *
        • 1st parameter: {@link TestInfo}; 2nd parameter: return type of {@code t} (see above)

        • + *
        • One parameter: {@link TestInfo} which provides some information about {@code t} and utility methods.

        • + *
        • One parameter: the exact same type as the return value of {@code t}. When {@code c} is + * invoked by the framework, this parameter contains the return value of {@code t}.

        • + *
        • 1st parameter: {@link TestInfo}; 2nd parameter: the exact same type as the return value of + * {@code t} (see above)

        • *
        • Any other combination will result in a {@link TestFormatException}. *

        *
      • {@code c} is not compiled nor inlined. - *

      • {@code c} must be part of the test class. Using {@code @Check} in nested or other classes is not allowed. TODO write test for it

      • - *
      • {@code c} cannot specify any helper-method specific compile command annotations ({@link ForceCompile}, - * {@link DontCompile}, {@link ForceInline}, {@link DontInline}).

      • + *
      • {@code c} must be part of the test class. Using {@code @Check} in nested or other classes is not allowed.

      • + *
      • {@code c} cannot specify any helper-method-specific compile command annotations + * ({@link ForceCompile @ForceCompile}, {@link DontCompile @DontCompile}, {@link ForceInline @ForceInline}, + * {@link DontInline @DontInline}).

      • *
      * *

      @@ -84,6 +84,10 @@ *

      * Examples on how to write checked tests can be found in {@link jdk.test.lib.hotspot.ir_framework.examples.CheckedTestExample} * and also as part of the internal testing in the package {@link jdk.test.lib.hotspot.ir_framework.tests}. + * + * @see Test + * @see TestInfo + * @see CheckAt */ @Retention(RetentionPolicy.RUNTIME) public @interface Check { @@ -93,8 +97,8 @@ * invoke the {@code @Check} method after each invocation or only after the compilation of the associated {@code @Test} * method (depending on the value set with {@link #when()}). *

      - * If a non-{@code Test} annotated method is used or a {@code @Test} method that has already been used by another - * {@code @Check} or {@link Run} method, then a {@link TestFormatException} is thrown. + * If a non-{@code @Test} annotated method or a {@code @Test} method that has already been used by another + * {@code @Check} or {@link Run} method is specified, then a {@link TestFormatException} is thrown. * * @see Test */ diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java index cb1c059fe71..fbdc296f617 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java @@ -24,7 +24,7 @@ package jdk.test.lib.hotspot.ir_framework; /** - * Enum used at in the {@link Check} annotation of a checked test. It specifies when the framework will invoke the + * This enum is used in {@link Check#when()} of a checked test to specify when the framework will invoke the * check method after invoking the associated {@link Test} method. * * @see Check @@ -33,12 +33,12 @@ public enum CheckAt { /** - * Invoke the {@link Check} method each time after invoking the associated {@link Test} method. + * Default: Invoke the {@link Check} method each time after invoking the associated {@link Test} method. */ EACH_INVOCATION, /** - * Invoke the {@link Check} method only once after the warmup of the associated {@link Test} method completed has - * completed and test framework has compiled the test method. + * Invoke the {@link Check} method only once after the warm-up of the associated {@link Test} method had been completed + * and the framework has compiled the associated {@link Test} method. */ COMPILED } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/DontCompile.java b/test/lib/jdk/test/lib/hotspot/ir_framework/DontCompile.java index d7efaf5a59a..b3492dc0f39 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/DontCompile.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/DontCompile.java @@ -27,20 +27,23 @@ import java.lang.annotation.RetentionPolicy; /** - * Prevent compilation of the associated helper method (not specifying {@link Test @Test}, - * {@link Check @Check} or {@link Test @Run}): + * Prevent a compilation of the annotated helper method (not specifying {@link Test @Test}, + * {@link Check @Check} or {@link Run @Run}): * *

        *
      • {@link CompLevel#ANY} (default): No C1 or C2 compilation.

      • *
      • {@link CompLevel#C1}: No C1 compilation, C2 compilation still possible.

      • *
      • {@link CompLevel#C2}: No C2 compilation, C1 compilation still possible.

      • *
      • The usage of any other compilation level is forbidden and results in a - * {@link TestFormatException TestFormatException}.

      • + * {@link TestFormatException TestFormatException}. *
      *

      - * Using this annotation on non-helper methods results in a {@link TestFormatException TestFormatException}. + * Using this annotation on non-helper methods results in a {@link TestFormatException TestFormatException}. */ @Retention(RetentionPolicy.RUNTIME) public @interface DontCompile { + /** + * The excluded compilation level for the helper method. + */ CompLevel value() default CompLevel.ANY; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/DontInline.java b/test/lib/jdk/test/lib/hotspot/ir_framework/DontInline.java index 29fa6dcfe55..80149b89a12 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/DontInline.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/DontInline.java @@ -27,10 +27,9 @@ import java.lang.annotation.RetentionPolicy; /** - * Prevent inlining of the associated helper method (not specifying {@link Test @Test}, - * {@link Check @Check} or {@link Test @Run}). Non-helper methods are never inlined. - * Explicitly using this annotation on non-helper methods results in a - * {@link TestFormatException TestFormatException}. + * Prevent an inlining of the annotated helper method (not specifying {@link Test @Test}, {@link Check @Check}, + * or {@link Run @Run}). Non-helper methods are never inlined. Explicitly using this annotation on + * non-helper methods results in a {@link TestFormatException}. */ @Retention(RetentionPolicy.RUNTIME) public @interface DontInline { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java index dbc822bbc59..676251792a4 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java @@ -27,25 +27,29 @@ import java.lang.annotation.RetentionPolicy; /** - * Force compilation of the associated helper method (not specifying {@link Test @Test}, + * Force a compilation of the annotated helper method (not specifying {@link Test @Test}, * {@link Check @Check} or {@link Test @Run}) immediately at the specified level: *

        - *
      • {@link CompLevel#ANY} (default): Highest available compilation level which is usually C2.

      • - *
      • {@link CompLevel#C1}: Level 1: C1 compilation without any profile information.

      • + *
      • {@link CompLevel#ANY} (default): Highest available compilation level is selected which is usually + * {@link CompLevel#C2}

      • + *
      • {@link CompLevel#C1}: Level 1: C1 compilation without any profile information.

      • *
      • {@link CompLevel#C1_LIMITED_PROFILE}: Level 2: C1 compilation with limited profile information: - * Includes Invocation and backedge counters.

      • + * Includes Invocation and backedge counters. *
      • {@link CompLevel#C1_FULL_PROFILE}: Level 3: C1 compilation with full profile information: - * Includes Invocation and backedge counters with MDO.

      • + * Includes Invocation and backedge counters with MDO. *
      • {@link CompLevel#C2}: Level 4: C2 compilation with full optimizations.

      • *
      • {@link CompLevel#SKIP}: Does not apply to {@code @ForceCompile} and results in a - * {@link TestFormatException TestFormatException}.

      • + * {@link TestFormatException}. *
      • {@link CompLevel#WAIT_FOR_COMPILATION}: Does not apply to {@code @ForceCompile} and results in a - * {@link TestFormatException TestFormatException}.

      • + * {@link TestFormatException}. *
      *

      - * Using this annotation on non-helper methods results in a {@link TestFormatException TestFormatException}. + * Using this annotation on non-helper methods results in a {@link TestFormatException}. */ @Retention(RetentionPolicy.RUNTIME) public @interface ForceCompile { + /** + * The compilation level to compile the helper method at. + */ CompLevel value() default CompLevel.ANY; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompileClassInitializer.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompileClassInitializer.java index 6c48d8a1575..01daf5b7dd7 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompileClassInitializer.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompileClassInitializer.java @@ -27,24 +27,29 @@ import java.lang.annotation.RetentionPolicy; /** - * Force compilation of the annotated test or helper class immediately at the specified level: + * Force a compilation of the static class initializer method ({@code }) of the annotated test or helper class + * immediately at the specified level: *

        - *
      • {@link CompLevel#ANY} (default): Highest available compilation level which is usually C2.

      • - *
      • {@link CompLevel#C1}: Level 1: C1 compilation without any profile information.

      • + *
      • {@link CompLevel#ANY} (default): Highest available compilation level is selected which is usually + * {@link CompLevel#C2}

      • + *
      • {@link CompLevel#C1}: Level 1: C1 compilation without any profile information.

      • *
      • {@link CompLevel#C1_LIMITED_PROFILE}: Level 2: C1 compilation with limited profile information: * Includes Invocation and backedge counters.

      • *
      • {@link CompLevel#C1_FULL_PROFILE}: Level 3: C1 compilation with full profile information: * Includes Invocation and backedge counters with MDO.

      • *
      • {@link CompLevel#C2}: Level 4: C2 compilation with full optimizations.

      • *
      • {@link CompLevel#SKIP}: Does not apply to {@code @ForceCompileClassInitializer} and results in a - * {@link TestFormatException TestFormatException}.

      • + * {@link TestFormatException}. *
      • {@link CompLevel#WAIT_FOR_COMPILATION}: Does not apply to {@code @ForceCompileClassInitializer} and results in a - * {@link TestFormatException TestFormatException}.

      • + * {@link TestFormatException}. *
      *

      - * Using this annotation on non-classes results in a {@link TestFormatException TestFormatException}. + * Using this annotation on non-classes results in a {@link TestFormatException}. */ @Retention(RetentionPolicy.RUNTIME) public @interface ForceCompileClassInitializer { + /** + * The compilation level to compile the static class initializer method ({@code }) at. + */ CompLevel value() default CompLevel.ANY; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceInline.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceInline.java index 1bf57275824..703d02e72fb 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceInline.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceInline.java @@ -27,9 +27,8 @@ import java.lang.annotation.RetentionPolicy; /** - * Force inlining of the associated helper method (not specifying {@link Test @Test}, - * {@link Check @Check} or {@link Test @Run}). Using this annotation on non-helper methods - * results in a {@link TestFormatException TestFormatException}. + * Force an inlining of the annotated helper method (not specifying {@link Test @Test}, {@link Check @Check}, + * or {@link Test @Run}). Using this annotation on non-helper methods results in a {@link TestFormatException}. */ @Retention(RetentionPolicy.RUNTIME) public @interface ForceInline { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java index e2ed4ad4dba..0c3afe51944 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java @@ -28,23 +28,29 @@ import java.lang.annotation.RetentionPolicy; /** - * This annotation is used to define a constraint/rule/check on the resulting IR of a test method (method with {@link Test} - * annotation). A test method can define multiple {@code {@literal @}IR} rules. + * This annotation is used to define a constraint/rule/check on the resulting IR of a test method (method with + * {@link Test @Test} annotation). A test method can define multiple {@code @IR} rules. *

      * There are two kinds of checks that can be specified: *

        *
      • {@link #failOn()}: Specify a list of (node) regexes that should not be matched on the {@code PrintIdeal} or - * {@code PrintOptoAssembly} output.

      • + * {@code PrintOptoAssembly} output. *
      • {@link #counts()}: Specify a list of ({@code regex,count}) pairs: The (node) {@code regex} should be matched - * for the specified amount in {@code count} on the {@code PrintIdeal} or {@code PrintOptoAssembly} output.

      • + * for the specified amount in {@code count} on the {@code PrintIdeal} or {@code PrintOptoAssembly} output. *
      * An IR rule must specify either or both of these two checks. If one or both of the checks fails, an * {@link IRViolationException} is thrown. *

      - * Sometimes, the shape of an IR is changed by commonly used VM flags in such a way that an IR rule no longer applies. - * Generally, the framework does not apply any IR rules when any of the following flags are used: - * {@code -Xcomp, -XX:-UseCompiler, -XX:TieredStopAtLevel={1,2,3}, -XX:CompileThreshold=XX, -DStressCC=true} - * An IR rule can specify additional preconditions on the remaining flags that must hold when an IR rule is applied. + * Sometimes, the shape of the resulting IR is changed by commonly used VM flags in such a way that an IR rule no longer + * applies. Generally, the framework does not apply any IR rules when any of the following flags are used: + * {@code -Xint, -XX:-UseCompiler, -XX:TieredStopAtLevel={1,2,3}, -DExcludeRandom=true, -DFlipC1C2=true}. + * Furthermore, a JTreg test could be run with additional VM and Javaoptions flags. The IR verification is not + * performed if any flag is used that is not part of the whitelist specified by {@link TestFramework#JTREG_WHITELIST_FLAGS}. + *

      + * For any other flag specified either by user code (e.g. {@link Scenario#Scenario(int, String...)}, + * {@link TestFramework#runWithFlags(String...) etc.} or as part of the JTreg whitelist, IR verification is applied. + * To restrict the application of IR rules when certain flags are present that could change the IR, each {@code @IR} + * annotation can specify additional preconditions on the allowed test VM flags that must hold when an IR rule is applied. * If the specified preconditions fail, then the framework does not apply the IR rule. These preconditions can be * set with {@link #applyIf()}, {@link #applyIfNot()}, {@link #applyIfAnd()}, or {@link #applyIfOr()}. *

      @@ -127,7 +133,7 @@ * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). *

      - * Use {@link #applyIfOr()} for conjunction and for single precondition constraints use {@link #applyIf()} or + * Use {@link #applyIfAnd()} for conjunction and for single precondition constraints use {@link #applyIf()} or * {@link #applyIfNot()} depending on the use case. */ String[] applyIfOr() default {}; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java index f4a0d3b4f30..e5af203426d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java @@ -24,9 +24,9 @@ package jdk.test.lib.hotspot.ir_framework; /** - * Exception that is thrown if an {@link IR} constraint failed. The exception message contains a detailed list of - * all failures, including failing method, {@code IR} rule (the first {@code IR} constraint is rule 1) and the - * specific regex that could not be matched. + * Exception that is thrown if an {@link IR} rule/constraint failed. The exception message contains a detailed list of + * all failures, including failing method(s), {@code @IR} rule(s) (the first {@code @IR} constraint is rule 1) and the + * specific regex(es) that could not be matched. * * @see IR * @see Test @@ -40,6 +40,15 @@ public class IRViolationException extends RuntimeException { this.compilations = compilations; } + /** + * Get some more detailed information about the violated IR rule(s) and how to reproduce it. + * + * @return a formatted string containing information about the violated IR rule(s) and how to reproduce it. + */ + public String getExceptionInfo() { + return exceptionInfo; + } + String getCompilations() { return compilations; } @@ -47,8 +56,4 @@ String getCompilations() { void setExceptionInfo(String exceptionInfo) { this.exceptionInfo = exceptionInfo; } - - public String getExceptionInfo() { - return exceptionInfo; - } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRs.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRs.java index 8875d7c83ff..5f1305310c6 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRs.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRs.java @@ -27,7 +27,7 @@ import java.lang.annotation.RetentionPolicy; /** - * Annotation to allow to specify multiple {@link IR} annotations at a {@link Test} method. + * Annotation to allow to specify multiple {@link IR @IR} annotations at a {@link Test @Test} method. */ @Retention(RetentionPolicy.RUNTIME) public @interface IRs { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/NoTestsRunException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/NoTestsRunException.java index 5f4f492176c..3e5b7a47478 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/NoTestsRunException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/NoTestsRunException.java @@ -29,9 +29,14 @@ */ public class NoTestsRunException extends RuntimeException { - NoTestsRunException() { - } + /** + * Default constructor used by test VM + */ + NoTestsRunException() {} + /** + * Constructor used to eventually throw the exception in the driver VM. + */ NoTestsRunException(String message) { super(message); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java index c9934449c16..ded0d43e508 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java @@ -30,35 +30,36 @@ * Annotation for a run method of a custom run test. * *

      - * Let {@code t} be a test method specifying the {@link Test} annotation and {@code r} be a run method specifying + * Let {@code t} be a test method specifying the {@link Test @Test} annotation and {@code r} be a run method specifying * the {@code @Run(test = "t")} annotation. These two methods represent a so-called custom run test. The only * difference to a base test (see {@link Test}) is that the framework will not invoke the test method {@code t} - * but instead the run method {@code r} which is then responsible to invoke {@code t} and do any additional verification, - * (e.g. of the return value). If {@code Run} does not specify {@link RunMode#STANDALONE} as {@link #mode()} - * property, the framework does the following, similar as for base tests: + * but instead the run method {@code r} which is then responsible to invoke {@code t} in any way and optionally do any + * additional verification (e.g. of the return value). If {@code r} does not specify {@link RunMode#STANDALONE} as + * {@link #mode()} property, the framework does the following, similar as for base tests: *

        *
      1. The framework warms {@code r} up by invoking it for a predefined number of iterations (default: 2000) * or any number specified by an additional {@link Warmup} annotation at the run method {@code r} or by using - * {@link TestFramework#setDefaultWarmup(int)} (could also be 0 which skips the warm-up completely which is similar to - * simulating {@code -Xcomp}). More information about the warm-up in general can be found in {@link Warmup}

      2. + * {@link TestFramework#setDefaultWarmup(int)} (could also be 0 which skips the warm-up completely which is + * similar to simulating {@code -Xcomp}). More information about the warm-up in general can be found in + * {@link Warmup @Warmup}. *
      3. After the warm-up, the framework compiles the test method {@code t} at the specified compilation level set by * {@link Test#compLevel()} (default {@link CompLevel#ANY} will pick the highest available level which is usually * {@link CompLevel#C2}).

      4. *
      5. The framework invokes the run method {@code r} one more time to check the compilation.

      6. - *
      7. The framework checks any specified {@link IR} constraints at the test method {@code t}. - * More information about IR matching can be found in {@link IR}.

      8. + *
      9. The framework checks any specified {@link IR @IR} constraints at the test method {@code t}. + * More information about IR matching can be found at {@link IR}.

      10. *
      * *

      - * If {@code Run} specifies {@link RunMode#STANDALONE} as {@link #mode()} property, the framework gives complete + * If {@code r} specifies {@link RunMode#STANDALONE} as {@link #mode()} property, the framework gives complete * control to the run method {@code r}: *

        *
      1. The framework invokes the run method {@code r} only one time without any warm-up or compilation of - * {@code t} ({@link Warmup} is not allowed at {@code r} in this case).

      2. + * {@code t} ({@link Warmup @Warmup} is not allowed at {@code r} in this case). *
      3. After this single invocation, the framework directly checks any specified {@link IR} constraints at the test * method {@code t}. The run method {@code r} needs to make sure to reliably trigger a C2 compilation. Otherwise, - * IR matching will fail. More information about IR matching can be found in {@link IR}.

      4. - *
      * + * IR matching will fail. More information about IR matching can be found at {@link IR}. + *
    * *

    * The test method {@code t} and run method {@code r} have the following properties: @@ -71,31 +72,36 @@ *

  • {@code r} can specify the following method parameter combinations: *

      *
    • void

    • - *
    • 1st parameter: {@link RunInfo} which provides some methods to check various things, including - * information about {@code t}.

    • - *
    • Any other combination will result in a {@link TestFormatException}. + *

    • One parameter: {@link RunInfo} which provides some information about {@code t} and utility methods.

    • + *
    • Any other combination will result in a {@link TestFormatException}. *

    *
  • {@code t} and {@code r} must be part of the test class. Using {@code @Run} and {@code @Test} in nested or - * other classes is not allowed.

  • - *
  • {@code t} and {@code r} cannot specify any helper-method specific compile command annotations - * ({@link ForceCompile}, {@link DontCompile}, {@link ForceInline}, {@link DontInline}).

  • + * other helper classes is not allowed. + *
  • {@code t} and {@code r} cannot specify any helper-method-specific compile command annotations + * ({@link ForceCompile @ForceCompile}, {@link DontCompile @DontCompile}, {@link ForceInline @ForceInline}, + * {@link DontInline @DontInline}).

  • * * *

    * Examples on how to write custom run tests can be found in {@link jdk.test.lib.hotspot.ir_framework.examples.CustomRunTestExample} * and also as part of the internal testing in the package {@link jdk.test.lib.hotspot.ir_framework.tests}. + * + * @see Test + * @see RunInfo + * @see RunMode */ @Retention(RetentionPolicy.RUNTIME) public @interface Run { /** - * The associated {@link Test} methods (one or more) for for this {@code Run} annotated run method. - * The framework directly invokes the run method instead of the associated {@code Test} methods. + * The associated {@link Test @Test} methods (one or more) for for this {@code @Run} annotated run method. + * The framework directly invokes the run method instead of the associated {@code @Test} methods. */ String[] test(); /** * The mode of this custom run test. + * * @see RunMode */ RunMode mode() default RunMode.NORMAL; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java b/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java index 3bd65e9f308..6ad9ad25a2d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java @@ -30,13 +30,14 @@ */ public enum RunMode { /** - * Default mode: First warm up run method, then compile the associated - * test method and finally invoke the run method once more. + * Default mode: First warm up the run method (if a warm-up is done), then compile the associated {@link Test} + * method and finally invoke the run method once more. */ NORMAL, /** - * Standalone mode: There is no warm up and no forced compilation. - * The run method is responsible to trigger the compilation(s). + * Standalone mode: There is no warm-up and no compilation done by the framework. The run method is responsible to + * trigger the compilation(s), especially in regard of possible {@link IR} annotations at the associated {@link Test} + * method. */ STANDALONE } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java index 60031d3d574..e4e778f0437 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java @@ -29,10 +29,14 @@ * This class represents a scenario that can be executed by the {@link TestFramework}. *

    * A JTreg test should call the test framework with {@code @run driver}, not allowing to specify any additional flags. - * If a test should run with additional flags, use {@link TestFramework#addFlags(String...)}. If, however, the test - * should be run with different settings (equivalent to having multiple {@code @run} statements in a normal JTreg test), - * use scenarios. A scenario will be run with the scenario specific flags, if any, and the flags specified with - * {@link TestFramework#addFlags(String...)} whereas scenario flags will have precedence. + * If a test should run with additional flags, use {@link TestFramework#runWithFlags(String...)} or + * {@link TestFramework#addFlags(String...)}. If, however, the test should be run with different settings (equivalent + * to having multiple {@code @run} entries in a normal JTreg test), use scenarios. A scenario will be run with the + * scenario specific flags, if any, and the flags specified with + * {@link TestFramework#runWithFlags(String...)}/{@link TestFramework#addFlags(String...)} whereas scenario flags will + * have precedence. + * + * @see TestFramework */ public class Scenario { private static final String ADDITIONAL_SCENARIO_FLAGS = System.getProperty("ScenarioFlags", ""); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java index 9dbec3c74ac..d120b52655a 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java @@ -30,29 +30,29 @@ * Annotate all methods in your test class which the framework should test with {@code @Test}. *

    * Let {@code m} be a test method specifying the {@code @Test} annotation. If {@code m} is neither part of a - * checked test (an additional method specifying {@link Check} with (@code @Run(test = "m") nor part of a - * custom run test (an additional method specifying {@link Run} with (@code @Run(test = "m"))), + * checked test (an additional method specifying {@link Check @Check} with {@code @Check(test = "m")}) nor part + * of a custom run test (an additional method specifying {@link Run @Run} with {@code @Run(test = "m")}), * then {@code m} is a so-called base test and the the framework invokes {@code m} in the following way: *

      *
    1. The framework warms {@code m} up by invoking it for a predefined number of iterations (default: 2000) - * or any number specified by an additional {@link Warmup} annotation at {@code m} or by using + * or any number specified by an additional {@link Warmup @Warmup} annotation at {@code m} or by using * {@link TestFramework#setDefaultWarmup(int)} (could also be 0 which skips the warm-up completely which is similar - * to simulating {@code -Xcomp}). More information about the warm-up in general can be found in {@link Warmup}

    2. + * to simulating {@code -Xcomp}). More information about the warm-up in general can be found at {@link Warmup} *
    3. After the warm-up, the framework compiles {@code m} at the specified compilation level set by * {@link #compLevel()} (default {@link CompLevel#ANY} will pick the highest available level which is usually * {@link CompLevel#C2}).

    4. - *
    5. The framework invokes {@code m} one more time to check the compilation.

    6. - *
    7. The framework checks any specified {@link IR} constraints at {@code m}. More information about IR matching - * can be found in {@link IR}.

    8. + *
    9. The framework invokes {@code m} one more time to run the compilation.

    10. + *
    11. The framework checks any specified {@link IR @IR} constraints at {@code m}. More information about IR matching + * can be found at {@link IR}.

    12. *
    * *

    * {@code m} has the following properties: *

      - *
    • If {@code m} specifies no parameters, the framework can directly invoke it.

    • - *
    • If {@code m} specifies parameters, the framework needs to know how to call {@code m}. Use {@link Arguments} - * with {@link Argument} properties for each parameter to use some well-defined parameters. If the method requires - * a more specific argument value, use a custom run test (see {@link Run}).

    • + *
    • If {@code m} specifies no parameters, the framework can directly invoke {@code m}.

    • + *
    • If {@code m} specifies parameters, the framework needs to know how to invoke {@code m}. Use {@link Arguments} + * with {@link Argument} properties for each parameter to use well-defined parameters by the framework. If the method + * requires a more specific argument value, use a custom run test (see {@link Run}).

    • *
    • {@code m} cannot specify {@link AbstractInfo} or any of its subclasses as parameter or return type.

    • *
    • {@code m} is not inlined by the framework.

    • *
    • Verification of the return value of {@code m} can only be done in a checked test (see {@link Check}) or @@ -62,23 +62,26 @@ *

      * The following constraints must be met for the test method {@code m} specifying {@code @Test}: *

        - *
      • {@code m} must be part of the test class. Using {@code @Test} in nested or other classes is not allowed.

      • - *
      • {@code m} cannot have the same name as another {@code @Test} method. Method overloading is only allowed - * (but not encouraged) with other non-{@code @Test} methods.

      • - *
      • {@code m} cannot specify any helper-method specific compile command annotations ({@link ForceCompile}, - * {@link DontCompile}, {@link ForceInline}, {@link DontInline}).

      • + *
      • {@code m} must be part of the test class. Using {@code @Test} in nested or helper classes is not allowed.

      • + *
      • {@code m} cannot have the same name as another {@code @Test} method in the same test class. Method + * overloading is only allowed (but not encouraged) with other non-{@code @Test} methods.

      • + *
      • {@code m} cannot specify any helper-method-specific compile command annotations + * ({@link ForceCompile @ForceCompile}, {@link DontCompile @DontCompile}, {@link ForceInline @ForceInline}, + * {@link DontInline @DontInline}).

      • *
      * *

      * Examples on how to write base tests can be found in {@link jdk.test.lib.hotspot.ir_framework.examples.BaseTestExample} * and also as part of the internal testing in the package {@link jdk.test.lib.hotspot.ir_framework.tests}. + * + * @see Arguments */ @Retention(RetentionPolicy.RUNTIME) public @interface Test { /** * Specify at which compilation level the framework should eventually compile the test method after an optional - * warmup period. The default {@link CompLevel#ANY} will let the framework compile the method at the highest + * warm-up period. The default {@link CompLevel#ANY} will let the framework compile the method at the highest * available level which is usually {@link CompLevel#C2}. */ CompLevel compLevel() default CompLevel.ANY; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 143f76616d8..db62e6c2882 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -46,14 +46,14 @@ * be used for other non-IR matching (and non-compiler) tests by providing easy to use annotations for commonly used * testing patterns and compiler control flags. *

      - * The framework offers various annotations to control how your code should be invoked and being tested. There are + * The framework offers various annotations to control how your test code should be invoked and being checked. There are * three kinds of tests depending on how much control is needed over the test invocation: * Base tests (see {@link Test}), checked tests (see {@link Check}), and custom run tests - * (see {@link Run}). Each type of test needs to define a unique test method that specifies a {@link Test} + * (see {@link Run}). Each type of test needs to define a unique test method that specifies a {@link Test @Test} * annotation which represents the test code that is eventually executed by the test framework. More information about * the usage and how to write different tests can be found in {@link Test}, {@link Check}, and {@link Run}. *

      - * Each test method can specify an arbitrary number of IR rules. This is done by using {@link IR} annotations which + * Each test method can specify an arbitrary number of IR rules. This is done by using {@link IR @IR} annotations which * can define regex strings that are matched on the output of {@code -XX:+PrintIdeal} and {@code -XX:+PrintOptoAssembly}. * The matching is done after the test method was (optionally) warmed up and compiled. More information about the usage * and how to write different IR rules can be found at {@link IR}. @@ -66,8 +66,9 @@ * Note that even though the framework uses the Whitebox API internally, it is not required to build and enabel it in the * JTreg test if the test itself is not utilizing any Whitebox features directly. *

      - * To specify additional flags, use {@link #addFlags(String...)} or {@link #addScenarios(Scenario...)} where the latter - * can also be used to run different flag combinations (instead of specifying multiple {@code {@literal @}run} entries). + * To specify additional flags, use {@link #runWithFlags(String...)}, {@link #addFlags(String...)}, + * {@link #addScenarios(Scenario...)}, or {@link #runWithScenarios(Scenario...)} where the scenarios can also be used + * to run different flag combinations (instead of specifying multiple JTreg {@code @run} entries). *

      * After annotating your test code with the framework specific annotations, the framework needs to be invoked from the * {@code main()} method of your JTreg test. There are two ways to do so. The first way is by calling the various @@ -75,7 +76,7 @@ * {@code TestFramework} builder object on which {@link #start()} needs to be eventually called to start the testing. *

      * The framework is called from the driver VM in which the JTreg test is initially run by specifying {@code - * {@literal @}run driver} in the JTreg header. This strips all additionally specified JTreg VM and Java options. + * @run driver} in the JTreg header. This strips all additionally specified JTreg VM and Javaoptions. * The framework creates a new flag VM with all these flags added again in order to figure out which flags are * required to run the tests specified in the test class (e.g. {@code -XX:+PrintIdeal} and {@code -XX:+PrintOptoAssembly} * for IR matching). @@ -84,7 +85,7 @@ * tests in the test class as described in {@link Test}, {@link Check}, and {@link Run}. *

      * In a last step, once the test VM has terminated without exceptions, IR matching is performed if there are any IR - * rules and if no VM flags disable it (e.g. not running with {@code -Xcomp}, see {@link IR} for more details). + * rules and if no VM flags disable it (e.g. not running with {@code -Xint}, see {@link IR} for more details). * The IR regex matching is done on the output of {@code -XX:+PrintIdeal} and {@code -XX:+PrintOptoAssembly} by parsing * the hotspot_pid file of the test VM. Failing IR rules are reported by throwing a {@link IRViolationException}. * @@ -102,7 +103,7 @@ public class TestFramework { * A flag is whitelisted if it is a property flag (starting with -D), -ea, -esa, or if the flag name contains any of * the entries of this list as a substring. */ - private static final Set jtregWhitelistFlags = new HashSet<>( + public static final Set JTREG_WHITELIST_FLAGS = new HashSet<>( Arrays.asList( // The following substrings are part of more than one VM flag "RAM", @@ -729,7 +730,7 @@ private boolean onlyWhitelistedJTregVMAndJavaOptsFlags() { .collect(Collectors.toList()); for (String flag : flags) { // Property flags (prefix -D), -ea and -esa are whitelisted. - if (!flag.startsWith("-D") && !flag.startsWith("-e") && jtregWhitelistFlags.stream().noneMatch(flag::contains)) { + if (!flag.startsWith("-D") && !flag.startsWith("-e") && JTREG_WHITELIST_FLAGS.stream().noneMatch(flag::contains)) { // Found VM flag that is not whitelisted return false; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java index fe0a4024b2d..a6c3dd03efa 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java @@ -24,7 +24,8 @@ package jdk.test.lib.hotspot.ir_framework; /** - * Exception that is thrown if there is an internal error in the framework. This is most likely a bug in the framework. + * Exception that is thrown if there is an internal error in the framework. This is most likely an indicator of a bug + * in the framework. */ public class TestFrameworkException extends RuntimeException { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMException.java index 00f41ed8f19..20fa668320a 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMException.java @@ -34,6 +34,11 @@ public class TestVMException extends RuntimeException { this.exceptionInfo = exceptionInfo; } + /** + * Get some more detailed information about the exception thrown in the test VM and how to reproduce it. + * + * @return a formatted string containing information about the exception of the test VM and how to reproduce it. + */ public String getExceptionInfo() { return exceptionInfo; } From 40b3d42c27a64b12ce2cf77ff2f0f48998650562 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 12 Apr 2021 11:59:09 +0200 Subject: [PATCH 100/131] Re-add Valhalla helper classes and update converted JTreg tests accordingly --- .../valhalla/inlinetypes/InlineTypes.java | 571 +----------------- .../valhalla/inlinetypes/MyAbstract.java | 29 + .../valhalla/inlinetypes/MyInterface.java | 29 + .../valhalla/inlinetypes/MyValue1.java | 159 +++++ .../valhalla/inlinetypes/MyValue2.java | 135 +++++ .../valhalla/inlinetypes/MyValue3.java | 250 ++++++++ .../valhalla/inlinetypes/MyValue4.java | 73 +++ .../valhalla/inlinetypes/MyValueEmpty.java | 30 + .../valhalla/inlinetypes/NamedRectangle.java | 40 ++ .../compiler/valhalla/inlinetypes/Point.java | 29 + .../valhalla/inlinetypes/Rectangle.java | 29 + .../inlinetypes/SimpleInlineType.java | 35 ++ .../valhalla/inlinetypes/TestArrays.java | 12 +- .../inlinetypes/TestBasicFunctionality.java | 30 +- .../compiler/valhalla/inlinetypes/TestC1.java | 10 +- .../inlinetypes/TestCallingConvention.java | 22 +- .../inlinetypes/TestCallingConventionC1.java | 9 +- .../inlinetypes/TestGetfieldChains.java | 4 +- .../valhalla/inlinetypes/TestIntrinsics.java | 5 +- .../valhalla/inlinetypes/TestJNICalls.java | 3 +- .../valhalla/inlinetypes/TestLWorld.java | 19 +- .../inlinetypes/TestMethodHandles.java | 19 +- .../inlinetypes/TestNullableArrays.java | 15 +- .../inlinetypes/TestOnStackReplacement.java | 19 +- .../valhalla/inlinetypes/TestWithfieldC1.java | 3 +- 25 files changed, 922 insertions(+), 657 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyAbstract.java create mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyInterface.java create mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java create mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java create mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java create mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java create mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValueEmpty.java create mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/NamedRectangle.java create mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/Point.java create mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/Rectangle.java create mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/SimpleInlineType.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java index ae87e3aa9e2..821aa407aaf 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java @@ -23,27 +23,9 @@ package compiler.valhalla.inlinetypes; -import jdk.test.lib.Asserts; import jdk.test.lib.Utils; -import jdk.test.lib.hotspot.ir_framework.*; - -// This class should not be moved. -// TestGetfieldChains has hard codded line numbers for NamedRectangle methods -class NamedRectangle { - Rectangle rect = new Rectangle(); - String name = ""; - - static int getP1X(NamedRectangle nr) { - return nr.rect - .p1 - .x; - } - - static Point getP1(NamedRectangle nr) { - return nr.rect - .p1; - } -} +import jdk.test.lib.hotspot.ir_framework.Scenario; +import jdk.test.lib.hotspot.ir_framework.TestFramework; public class InlineTypes { public static final int rI = Utils.getRandomInstance().nextInt() % 1000; @@ -158,553 +140,4 @@ static class IRNode { protected static final String FIELD_ACCESS = "(.*Field: *" + END; protected static final String SUBSTITUTABILITY_TEST = START + "CallStaticJava" + MID + "java.lang.invoke.ValueBootstrapMethods::isSubstitutable" + END; } - -} - -interface MyInterface { - public long hash(); -} - -abstract class MyAbstract implements MyInterface { - -} - -final primitive class MyValueEmpty extends MyAbstract { - public long hash() { return 0; } - - public MyValueEmpty copy(MyValueEmpty other) { return other; } -} - -primitive class Point { - int x = 4; - int y = 7; } - -primitive class Rectangle { - Point p0 = new Point(); - Point p1 = new Point(); -} - -primitive class SimpleInlineType { - final int x; - - private SimpleInlineType() { - x = 0; - } - - static SimpleInlineType create() { - return SimpleInlineType.default; - } -} - -@ForceCompileClassInitializer -final primitive class MyValue1 extends MyAbstract { - static int s; - static final long sf = InlineTypes.rL; - final int x; - final long y; - final short z; - final Integer o; - final int[] oa; - final MyValue2 v1; - final MyValue2 v2; - static final MyValue2 v3 = MyValue2.createWithFieldsInline(InlineTypes.rI, InlineTypes.rD); - final int c; - - @ForceInline - public MyValue1(int x, long y, short z, Integer o, int[] oa, MyValue2 v1, MyValue2 v2, int c) { - s = 0; - this.x = x; - this.y = y; - this.z = z; - this.o = o; - this.oa = oa; - this.v1 = v1; - this.v2 = v2; - this.c = c; - } - - @DontInline - static MyValue1 createDefaultDontInline() { - return createDefaultInline(); - } - - @ForceInline - static MyValue1 createDefaultInline() { - return MyValue1.default; - } - - @DontInline - static MyValue1 createWithFieldsDontInline(int x, long y) { - return createWithFieldsInline(x, y); - } - - @ForceInline - static MyValue1 createWithFieldsInline(int x, long y) { - MyValue1 v = createDefaultInline(); - v = setX(v, x); - v = setY(v, y); - v = setZ(v, (short)x); - // Don't use Integer.valueOf here to avoid control flow added by Integer cache check - v = setO(v, new Integer(x)); - int[] oa = {x}; - v = setOA(v, oa); - v = setV1(v, MyValue2.createWithFieldsInline(x, y, InlineTypes.rD)); - v = setV2(v, MyValue2.createWithFieldsInline(x, y, InlineTypes.rD + x)); - v = setC(v, (int)(x+y)); - return v; - } - - // Hash only primitive and inline type fields to avoid NullPointerException - @ForceInline - public long hashPrimitive() { - return s + sf + x + y + z + c + v1.hash() + v2.hash() + v3.hash(); - } - - @ForceInline - public long hash() { - long res = hashPrimitive(); - try { - res += o; - } catch(NullPointerException npe) {} - try { - res += oa[0]; - } catch(NullPointerException npe) {} - return res; - } - - @DontCompile - public long hashInterpreted() { - return s + sf + x + y + z + o + oa[0] + c + v1.hashInterpreted() + v2.hashInterpreted() + v3.hashInterpreted(); - } - - @ForceInline - public void print() { - System.out.print("s=" + s + ", sf=" + sf + ", x=" + x + ", y=" + y + ", z=" + z + ", o=" + (o != null ? (Integer)o : "NULL") + ", oa=" + (oa != null ? oa[0] : "NULL") + ", v1["); - v1.print(); - System.out.print("], v2["); - v2.print(); - System.out.print("], v3["); - v3.print(); - System.out.print("], c=" + c); - } - - @ForceInline - static MyValue1 setX(MyValue1 v, int x) { - return new MyValue1(x, v.y, v.z, v.o, v.oa, v.v1, v.v2, v.c); - } - - @ForceInline - static MyValue1 setY(MyValue1 v, long y) { - return new MyValue1(v.x, y, v.z, v.o, v.oa, v.v1, v.v2, v.c); - } - - @ForceInline - static MyValue1 setZ(MyValue1 v, short z) { - return new MyValue1(v.x, v.y, z, v.o, v.oa, v.v1, v.v2, v.c); - } - - @ForceInline - static MyValue1 setO(MyValue1 v, Integer o) { - return new MyValue1(v.x, v.y, v.z, o, v.oa, v.v1, v.v2, v.c); - } - - @ForceInline - static MyValue1 setOA(MyValue1 v, int[] oa) { - return new MyValue1(v.x, v.y, v.z, v.o, oa, v.v1, v.v2, v.c); - } - - @ForceInline - static MyValue1 setC(MyValue1 v, int c) { - return new MyValue1(v.x, v.y, v.z, v.o, v.oa, v.v1, v.v2, c); - } - - @ForceInline - static MyValue1 setV1(MyValue1 v, MyValue2 v1) { - return new MyValue1(v.x, v.y, v.z, v.o, v.oa, v1, v.v2, v.c); - } - - @ForceInline - static MyValue1 setV2(MyValue1 v, MyValue2 v2) { - return new MyValue1(v.x, v.y, v.z, v.o, v.oa, v.v1, v2, v.c); - } -} - -final primitive class MyValue2Inline { - final double d; - final long l; - - @ForceInline - public MyValue2Inline(double d, long l) { - this.d = d; - this.l = l; - } - - @ForceInline - static MyValue2Inline setD(MyValue2Inline v, double d) { - return new MyValue2Inline(d, v.l); - } - - @ForceInline - static MyValue2Inline setL(MyValue2Inline v, long l) { - return new MyValue2Inline(v.d, l); - } - - @ForceInline - public static MyValue2Inline createDefault() { - return MyValue2Inline.default; - } - - @ForceInline - public static MyValue2Inline createWithFieldsInline(double d, long l) { - MyValue2Inline v = MyValue2Inline.createDefault(); - v = MyValue2Inline.setD(v, d); - v = MyValue2Inline.setL(v, l); - return v; - } -} - -final primitive class MyValue2 extends MyAbstract { - final int x; - final byte y; - final MyValue2Inline v; - - @ForceInline - public MyValue2(int x, byte y, MyValue2Inline v) { - this.x = x; - this.y = y; - this.v = v; - } - - @ForceInline - public static MyValue2 createDefaultInline() { - return MyValue2.default; - } - - @ForceInline - public static MyValue2 createWithFieldsInline(int x, long y, double d) { - MyValue2 v = createDefaultInline(); - v = setX(v, x); - v = setY(v, (byte)x); - v = setV(v, MyValue2Inline.createWithFieldsInline(d, y)); - return v; - } - - @ForceInline - public static MyValue2 createWithFieldsInline(int x, double d) { - MyValue2 v = createDefaultInline(); - v = setX(v, x); - v = setY(v, (byte)x); - v = setV(v, MyValue2Inline.createWithFieldsInline(d, InlineTypes.rL)); - return v; - } - - @DontInline - public static MyValue2 createWithFieldsDontInline(int x, double d) { - MyValue2 v = createDefaultInline(); - v = setX(v, x); - v = setY(v, (byte)x); - v = setV(v, MyValue2Inline.createWithFieldsInline(d, InlineTypes.rL)); - return v; - } - - @ForceInline - public long hash() { - return x + y + (long)v.d + v.l; - } - - @DontInline - public long hashInterpreted() { - return x + y + (long)v.d + v.l; - } - - @ForceInline - public void print() { - System.out.print("x=" + x + ", y=" + y + ", d=" + v.d + ", l=" + v.l); - } - - @ForceInline - static MyValue2 setX(MyValue2 v, int x) { - return new MyValue2(x, v.y, v.v); - } - - @ForceInline - static MyValue2 setY(MyValue2 v, byte y) { - return new MyValue2(v.x, y, v.v); - } - - @ForceInline - static MyValue2 setV(MyValue2 v, MyValue2Inline vi) { - return new MyValue2(v.x, v.y, vi); - } -} - -final primitive class MyValue3Inline { - final float f7; - final double f8; - - @ForceInline - public MyValue3Inline(float f7, double f8) { - this.f7 = f7; - this.f8 = f8; - } - - @ForceInline - static MyValue3Inline setF7(MyValue3Inline v, float f7) { - return new MyValue3Inline(f7, v.f8); - } - - @ForceInline - static MyValue3Inline setF8(MyValue3Inline v, double f8) { - return new MyValue3Inline(v.f7, f8); - } - - @ForceInline - public static MyValue3Inline createDefault() { - return MyValue3Inline.default; - } - - @ForceInline - public static MyValue3Inline createWithFieldsInline(float f7, double f8) { - MyValue3Inline v = createDefault(); - v = setF7(v, f7); - v = setF8(v, f8); - return v; - } -} - -// Inline type definition to stress test return of an inline type in registers -// (uses all registers of calling convention on x86_64) -final primitive class MyValue3 extends MyAbstract { - final char c; - final byte bb; - final short s; - final int i; - final long l; - final Object o; - final float f1; - final double f2; - final float f3; - final double f4; - final float f5; - final double f6; - final MyValue3Inline v1; - - @ForceInline - public MyValue3(char c, byte bb, short s, int i, long l, Object o, - float f1, double f2, float f3, double f4, float f5, double f6, - MyValue3Inline v1) { - this.c = c; - this.bb = bb; - this.s = s; - this.i = i; - this.l = l; - this.o = o; - this.f1 = f1; - this.f2 = f2; - this.f3 = f3; - this.f4 = f4; - this.f5 = f5; - this.f6 = f6; - this.v1 = v1; - } - - @ForceInline - static MyValue3 setC(MyValue3 v, char c) { - return new MyValue3(c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setBB(MyValue3 v, byte bb) { - return new MyValue3(v.c, bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setS(MyValue3 v, short s) { - return new MyValue3(v.c, v.bb, s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setI(MyValue3 v, int i) { - return new MyValue3(v.c, v.bb, v.s, i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setL(MyValue3 v, long l) { - return new MyValue3(v.c, v.bb, v.s, v.i, l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setO(MyValue3 v, Object o) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setF1(MyValue3 v, float f1) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setF2(MyValue3 v, double f2) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, f2, v.f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setF3(MyValue3 v, float f3) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, f3, v.f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setF4(MyValue3 v, double f4) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, f4, v.f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setF5(MyValue3 v, float f5) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, f5, v.f6, v.v1); - } - - @ForceInline - static MyValue3 setF6(MyValue3 v, double f6) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, f6, v.v1); - } - - @ForceInline - static MyValue3 setV1(MyValue3 v, MyValue3Inline v1) { - return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v1); - } - - @ForceInline - public static MyValue3 createDefault() { - return MyValue3.default; - } - - @ForceInline - public static MyValue3 create() { - java.util.Random r = Utils.getRandomInstance(); - MyValue3 v = createDefault(); - v = setC(v, (char)r.nextInt()); - v = setBB(v, (byte)r.nextInt()); - v = setS(v, (short)r.nextInt()); - v = setI(v, r.nextInt()); - v = setL(v, r.nextLong()); - v = setO(v, new Object()); - v = setF1(v, r.nextFloat()); - v = setF2(v, r.nextDouble()); - v = setF3(v, r.nextFloat()); - v = setF4(v, r.nextDouble()); - v = setF5(v, r.nextFloat()); - v = setF6(v, r.nextDouble()); - v = setV1(v, MyValue3Inline.createWithFieldsInline(r.nextFloat(), r.nextDouble())); - return v; - } - - @DontInline - public static MyValue3 createDontInline() { - return create(); - } - - @ForceInline - public static MyValue3 copy(MyValue3 other) { - MyValue3 v = createDefault(); - v = setC(v, other.c); - v = setBB(v, other.bb); - v = setS(v, other.s); - v = setI(v, other.i); - v = setL(v, other.l); - v = setO(v, other.o); - v = setF1(v, other.f1); - v = setF2(v, other.f2); - v = setF3(v, other.f3); - v = setF4(v, other.f4); - v = setF5(v, other.f5); - v = setF6(v, other.f6); - v = setV1(v, other.v1); - return v; - } - - @DontInline - public void verify(MyValue3 other) { - Asserts.assertEQ(c, other.c); - Asserts.assertEQ(bb, other.bb); - Asserts.assertEQ(s, other.s); - Asserts.assertEQ(i, other.i); - Asserts.assertEQ(l, other.l); - Asserts.assertEQ(o, other.o); - Asserts.assertEQ(f1, other.f1); - Asserts.assertEQ(f2, other.f2); - Asserts.assertEQ(f3, other.f3); - Asserts.assertEQ(f4, other.f4); - Asserts.assertEQ(f5, other.f5); - Asserts.assertEQ(f6, other.f6); - Asserts.assertEQ(v1.f7, other.v1.f7); - Asserts.assertEQ(v1.f8, other.v1.f8); - } - - @ForceInline - public long hash() { - return c + - bb + - s + - i + - l + - o.hashCode() + - Float.hashCode(f1) + - Double.hashCode(f2) + - Float.hashCode(f3) + - Double.hashCode(f4) + - Float.hashCode(f5) + - Double.hashCode(f6) + - Float.hashCode(v1.f7) + - Double.hashCode(v1.f8); - } -} - -// Inline type definition with too many fields to return in registers -final primitive class MyValue4 extends MyAbstract { - final MyValue3 v1; - final MyValue3 v2; - - @ForceInline - public MyValue4(MyValue3 v1, MyValue3 v2) { - this.v1 = v1; - this.v2 = v2; - } - - @ForceInline - static MyValue4 setV1(MyValue4 v, MyValue3 v1) { - return new MyValue4(v1, v.v2); - } - - @ForceInline - static MyValue4 setV2(MyValue4 v, MyValue3 v2) { - return new MyValue4(v.v1, v2); - } - - @ForceInline - public static MyValue4 createDefault() { - return MyValue4.default; - } - - @ForceInline - public static MyValue4 create() { - MyValue4 v = createDefault(); - MyValue3 v1 = MyValue3.create(); - v = setV1(v, v1); - MyValue3 v2 = MyValue3.create(); - v = setV2(v, v2); - return v; - } - - public void verify(MyValue4 other) { - v1.verify(other.v1); - v2.verify(other.v2); - } - - @ForceInline - public long hash() { - return v1.hash() + v2.hash(); - } -} - - diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyAbstract.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyAbstract.java new file mode 100644 index 00000000000..2b7718ffa62 --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyAbstract.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020, 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.valhalla.inlinetypes; + +public abstract class MyAbstract implements MyInterface { + +} + diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyInterface.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyInterface.java new file mode 100644 index 00000000000..20a09a5f774 --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyInterface.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018, 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.valhalla.inlinetypes; + +public interface MyInterface { + public long hash(); +} + diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java new file mode 100644 index 00000000000..28d180151f2 --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2017, 2021, 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.valhalla.inlinetypes; + +import jdk.test.lib.hotspot.ir_framework.*; + +@ForceCompileClassInitializer +public final primitive class MyValue1 extends MyAbstract { + static int s; + static final long sf = InlineTypes.rL; + final int x; + final long y; + final short z; + final Integer o; + final int[] oa; + final MyValue2 v1; + final MyValue2 v2; + static final MyValue2 v3 = MyValue2.createWithFieldsInline(InlineTypes.rI, InlineTypes.rD); + final int c; + + @ForceInline + public MyValue1(int x, long y, short z, Integer o, int[] oa, MyValue2 v1, MyValue2 v2, int c) { + s = 0; + this.x = x; + this.y = y; + this.z = z; + this.o = o; + this.oa = oa; + this.v1 = v1; + this.v2 = v2; + this.c = c; + } + + @DontInline + static MyValue1 createDefaultDontInline() { + return createDefaultInline(); + } + + @ForceInline + static MyValue1 createDefaultInline() { + return MyValue1.default; + } + + @DontInline + static MyValue1 createWithFieldsDontInline(int x, long y) { + return createWithFieldsInline(x, y); + } + + @ForceInline + static MyValue1 createWithFieldsInline(int x, long y) { + MyValue1 v = createDefaultInline(); + v = setX(v, x); + v = setY(v, y); + v = setZ(v, (short)x); + // Don't use Integer.valueOf here to avoid control flow added by Integer cache check + v = setO(v, new Integer(x)); + int[] oa = {x}; + v = setOA(v, oa); + v = setV1(v, MyValue2.createWithFieldsInline(x, y, InlineTypes.rD)); + v = setV2(v, MyValue2.createWithFieldsInline(x, y, InlineTypes.rD + x)); + v = setC(v, (int)(x+y)); + return v; + } + + // Hash only primitive and inline type fields to avoid NullPointerException + @ForceInline + public long hashPrimitive() { + return s + sf + x + y + z + c + v1.hash() + v2.hash() + v3.hash(); + } + + @ForceInline + public long hash() { + long res = hashPrimitive(); + try { + res += o; + } catch(NullPointerException npe) {} + try { + res += oa[0]; + } catch(NullPointerException npe) {} + return res; + } + + @DontCompile + public long hashInterpreted() { + return s + sf + x + y + z + o + oa[0] + c + v1.hashInterpreted() + v2.hashInterpreted() + v3.hashInterpreted(); + } + + @ForceInline + public void print() { + System.out.print("s=" + s + ", sf=" + sf + ", x=" + x + ", y=" + y + ", z=" + z + ", o=" + (o != null ? (Integer)o : "NULL") + ", oa=" + (oa != null ? oa[0] : "NULL") + ", v1["); + v1.print(); + System.out.print("], v2["); + v2.print(); + System.out.print("], v3["); + v3.print(); + System.out.print("], c=" + c); + } + + @ForceInline + static MyValue1 setX(MyValue1 v, int x) { + return new MyValue1(x, v.y, v.z, v.o, v.oa, v.v1, v.v2, v.c); + } + + @ForceInline + static MyValue1 setY(MyValue1 v, long y) { + return new MyValue1(v.x, y, v.z, v.o, v.oa, v.v1, v.v2, v.c); + } + + @ForceInline + static MyValue1 setZ(MyValue1 v, short z) { + return new MyValue1(v.x, v.y, z, v.o, v.oa, v.v1, v.v2, v.c); + } + + @ForceInline + static MyValue1 setO(MyValue1 v, Integer o) { + return new MyValue1(v.x, v.y, v.z, o, v.oa, v.v1, v.v2, v.c); + } + + @ForceInline + static MyValue1 setOA(MyValue1 v, int[] oa) { + return new MyValue1(v.x, v.y, v.z, v.o, oa, v.v1, v.v2, v.c); + } + + @ForceInline + static MyValue1 setC(MyValue1 v, int c) { + return new MyValue1(v.x, v.y, v.z, v.o, v.oa, v.v1, v.v2, c); + } + + @ForceInline + static MyValue1 setV1(MyValue1 v, MyValue2 v1) { + return new MyValue1(v.x, v.y, v.z, v.o, v.oa, v1, v.v2, v.c); + } + + @ForceInline + static MyValue1 setV2(MyValue1 v, MyValue2 v2) { + return new MyValue1(v.x, v.y, v.z, v.o, v.oa, v.v1, v2, v.c); + } +} diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java new file mode 100644 index 00000000000..80e6ec309b5 --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2017, 2021, 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.valhalla.inlinetypes; + +import jdk.test.lib.hotspot.ir_framework.*; + +final primitive class MyValue2Inline { + final double d; + final long l; + + @ForceInline + public MyValue2Inline(double d, long l) { + this.d = d; + this.l = l; + } + + @ForceInline + static MyValue2Inline setD(MyValue2Inline v, double d) { + return new MyValue2Inline(d, v.l); + } + + @ForceInline + static MyValue2Inline setL(MyValue2Inline v, long l) { + return new MyValue2Inline(v.d, l); + } + + @ForceInline + public static MyValue2Inline createDefault() { + return MyValue2Inline.default; + } + + @ForceInline + public static MyValue2Inline createWithFieldsInline(double d, long l) { + MyValue2Inline v = MyValue2Inline.createDefault(); + v = MyValue2Inline.setD(v, d); + v = MyValue2Inline.setL(v, l); + return v; + } +} + +public final primitive class MyValue2 extends MyAbstract { + final int x; + final byte y; + final MyValue2Inline v; + + @ForceInline + public MyValue2(int x, byte y, MyValue2Inline v) { + this.x = x; + this.y = y; + this.v = v; + } + + @ForceInline + public static MyValue2 createDefaultInline() { + return MyValue2.default; + } + + @ForceInline + public static MyValue2 createWithFieldsInline(int x, long y, double d) { + MyValue2 v = createDefaultInline(); + v = setX(v, x); + v = setY(v, (byte)x); + v = setV(v, MyValue2Inline.createWithFieldsInline(d, y)); + return v; + } + + @ForceInline + public static MyValue2 createWithFieldsInline(int x, double d) { + MyValue2 v = createDefaultInline(); + v = setX(v, x); + v = setY(v, (byte)x); + v = setV(v, MyValue2Inline.createWithFieldsInline(d, InlineTypes.rL)); + return v; + } + + @DontInline + public static MyValue2 createWithFieldsDontInline(int x, double d) { + MyValue2 v = createDefaultInline(); + v = setX(v, x); + v = setY(v, (byte)x); + v = setV(v, MyValue2Inline.createWithFieldsInline(d, InlineTypes.rL)); + return v; + } + + @ForceInline + public long hash() { + return x + y + (long)v.d + v.l; + } + + @DontInline + public long hashInterpreted() { + return x + y + (long)v.d + v.l; + } + + @ForceInline + public void print() { + System.out.print("x=" + x + ", y=" + y + ", d=" + v.d + ", l=" + v.l); + } + + @ForceInline + static MyValue2 setX(MyValue2 v, int x) { + return new MyValue2(x, v.y, v.v); + } + + @ForceInline + static MyValue2 setY(MyValue2 v, byte y) { + return new MyValue2(v.x, y, v.v); + } + + @ForceInline + static MyValue2 setV(MyValue2 v, MyValue2Inline vi) { + return new MyValue2(v.x, v.y, vi); + } +} diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java new file mode 100644 index 00000000000..12dafbc0c40 --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2017, 2020, 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.valhalla.inlinetypes; + +import jdk.test.lib.Asserts; +import jdk.test.lib.Utils; +import jdk.test.lib.hotspot.ir_framework.*; + +final primitive class MyValue3Inline { + final float f7; + final double f8; + + @ForceInline + public MyValue3Inline(float f7, double f8) { + this.f7 = f7; + this.f8 = f8; + } + + @ForceInline + static MyValue3Inline setF7(MyValue3Inline v, float f7) { + return new MyValue3Inline(f7, v.f8); + } + + @ForceInline + static MyValue3Inline setF8(MyValue3Inline v, double f8) { + return new MyValue3Inline(v.f7, f8); + } + + @ForceInline + public static MyValue3Inline createDefault() { + return MyValue3Inline.default; + } + + @ForceInline + public static MyValue3Inline createWithFieldsInline(float f7, double f8) { + MyValue3Inline v = createDefault(); + v = setF7(v, f7); + v = setF8(v, f8); + return v; + } +} + +// Inline type definition to stress test return of an inline type in registers +// (uses all registers of calling convention on x86_64) +public final primitive class MyValue3 extends MyAbstract { + final char c; + final byte bb; + final short s; + final int i; + final long l; + final Object o; + final float f1; + final double f2; + final float f3; + final double f4; + final float f5; + final double f6; + final MyValue3Inline v1; + + @ForceInline + public MyValue3(char c, byte bb, short s, int i, long l, Object o, + float f1, double f2, float f3, double f4, float f5, double f6, + MyValue3Inline v1) { + this.c = c; + this.bb = bb; + this.s = s; + this.i = i; + this.l = l; + this.o = o; + this.f1 = f1; + this.f2 = f2; + this.f3 = f3; + this.f4 = f4; + this.f5 = f5; + this.f6 = f6; + this.v1 = v1; + } + + @ForceInline + static MyValue3 setC(MyValue3 v, char c) { + return new MyValue3(c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setBB(MyValue3 v, byte bb) { + return new MyValue3(v.c, bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setS(MyValue3 v, short s) { + return new MyValue3(v.c, v.bb, s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setI(MyValue3 v, int i) { + return new MyValue3(v.c, v.bb, v.s, i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setL(MyValue3 v, long l) { + return new MyValue3(v.c, v.bb, v.s, v.i, l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setO(MyValue3 v, Object o) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setF1(MyValue3 v, float f1) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, f1, v.f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setF2(MyValue3 v, double f2) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, f2, v.f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setF3(MyValue3 v, float f3) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, f3, v.f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setF4(MyValue3 v, double f4) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, f4, v.f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setF5(MyValue3 v, float f5) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, f5, v.f6, v.v1); + } + + @ForceInline + static MyValue3 setF6(MyValue3 v, double f6) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, f6, v.v1); + } + + @ForceInline + static MyValue3 setV1(MyValue3 v, MyValue3Inline v1) { + return new MyValue3(v.c, v.bb, v.s, v.i, v.l, v.o, v.f1, v.f2, v.f3, v.f4, v.f5, v.f6, v1); + } + + @ForceInline + public static MyValue3 createDefault() { + return MyValue3.default; + } + + @ForceInline + public static MyValue3 create() { + java.util.Random r = Utils.getRandomInstance(); + MyValue3 v = createDefault(); + v = setC(v, (char)r.nextInt()); + v = setBB(v, (byte)r.nextInt()); + v = setS(v, (short)r.nextInt()); + v = setI(v, r.nextInt()); + v = setL(v, r.nextLong()); + v = setO(v, new Object()); + v = setF1(v, r.nextFloat()); + v = setF2(v, r.nextDouble()); + v = setF3(v, r.nextFloat()); + v = setF4(v, r.nextDouble()); + v = setF5(v, r.nextFloat()); + v = setF6(v, r.nextDouble()); + v = setV1(v, MyValue3Inline.createWithFieldsInline(r.nextFloat(), r.nextDouble())); + return v; + } + + @DontInline + public static MyValue3 createDontInline() { + return create(); + } + + @ForceInline + public static MyValue3 copy(MyValue3 other) { + MyValue3 v = createDefault(); + v = setC(v, other.c); + v = setBB(v, other.bb); + v = setS(v, other.s); + v = setI(v, other.i); + v = setL(v, other.l); + v = setO(v, other.o); + v = setF1(v, other.f1); + v = setF2(v, other.f2); + v = setF3(v, other.f3); + v = setF4(v, other.f4); + v = setF5(v, other.f5); + v = setF6(v, other.f6); + v = setV1(v, other.v1); + return v; + } + + @DontInline + public void verify(MyValue3 other) { + Asserts.assertEQ(c, other.c); + Asserts.assertEQ(bb, other.bb); + Asserts.assertEQ(s, other.s); + Asserts.assertEQ(i, other.i); + Asserts.assertEQ(l, other.l); + Asserts.assertEQ(o, other.o); + Asserts.assertEQ(f1, other.f1); + Asserts.assertEQ(f2, other.f2); + Asserts.assertEQ(f3, other.f3); + Asserts.assertEQ(f4, other.f4); + Asserts.assertEQ(f5, other.f5); + Asserts.assertEQ(f6, other.f6); + Asserts.assertEQ(v1.f7, other.v1.f7); + Asserts.assertEQ(v1.f8, other.v1.f8); + } + + @ForceInline + public long hash() { + return c + + bb + + s + + i + + l + + o.hashCode() + + Float.hashCode(f1) + + Double.hashCode(f2) + + Float.hashCode(f3) + + Double.hashCode(f4) + + Float.hashCode(f5) + + Double.hashCode(f6) + + Float.hashCode(v1.f7) + + Double.hashCode(v1.f8); + } +} + diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java new file mode 100644 index 00000000000..cbc87da8455 --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2017, 2020, 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.valhalla.inlinetypes; + +import jdk.test.lib.hotspot.ir_framework.*; + +// Inline type definition with too many fields to return in registers +final primitive class MyValue4 extends MyAbstract { + final MyValue3 v1; + final MyValue3 v2; + + @ForceInline + public MyValue4(MyValue3 v1, MyValue3 v2) { + this.v1 = v1; + this.v2 = v2; + } + + @ForceInline + static MyValue4 setV1(MyValue4 v, MyValue3 v1) { + return new MyValue4(v1, v.v2); + } + + @ForceInline + static MyValue4 setV2(MyValue4 v, MyValue3 v2) { + return new MyValue4(v.v1, v2); + } + + @ForceInline + public static MyValue4 createDefault() { + return MyValue4.default; + } + + @ForceInline + public static MyValue4 create() { + MyValue4 v = createDefault(); + MyValue3 v1 = MyValue3.create(); + v = setV1(v, v1); + MyValue3 v2 = MyValue3.create(); + v = setV2(v, v2); + return v; + } + + public void verify(MyValue4 other) { + v1.verify(other.v1); + v2.verify(other.v2); + } + + @ForceInline + public long hash() { + return v1.hash() + v2.hash(); + } +} diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValueEmpty.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValueEmpty.java new file mode 100644 index 00000000000..7396f0b42f8 --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValueEmpty.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, 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.valhalla.inlinetypes; + +public final primitive class MyValueEmpty extends MyAbstract { + public long hash() { return 0; } + + public MyValueEmpty copy(MyValueEmpty other) { return other; } +} diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/NamedRectangle.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/NamedRectangle.java new file mode 100644 index 00000000000..052c8402f5e --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/NamedRectangle.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020, 2020, 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.valhalla.inlinetypes; + +public class NamedRectangle { + Rectangle rect = new Rectangle(); + String name = ""; + + static int getP1X(NamedRectangle nr) { + return nr.rect + .p1 + .x; + } + + static Point getP1(NamedRectangle nr) { + return nr.rect + .p1; + } +} diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/Point.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/Point.java new file mode 100644 index 00000000000..0a57bc4e990 --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/Point.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020, 2020, 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.valhalla.inlinetypes; + +public primitive class Point { + int x = 4; + int y = 7; +} diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/Rectangle.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/Rectangle.java new file mode 100644 index 00000000000..8d2d3c9bf3e --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/Rectangle.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020, 2020, 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.valhalla.inlinetypes; + +public primitive class Rectangle { + Point p0 = new Point(); + Point p1 = new Point(); +} diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/SimpleInlineType.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/SimpleInlineType.java new file mode 100644 index 00000000000..c09cb8d599c --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/SimpleInlineType.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017, 2019, 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. + */ + +final primitive class SimpleInlineType { + final int x; + + private SimpleInlineType() { + x = 0; + } + + static SimpleInlineType create() { + return SimpleInlineType.default; + } +} + diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java index 9df69bac378..9df5fafeabd 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java @@ -38,17 +38,14 @@ * @test * @key randomness * @summary Test inline type arrays - * @library /test/lib + * @library /test/lib / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile InlineTypes.java * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestArrays */ @ForceCompileClassInitializer public class TestArrays { - static final TestFramework testFramework = InlineTypes.getFramework(); - public static void main(String[] args) { Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; scenarios[2].addFlags("-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode"); @@ -56,9 +53,10 @@ public static void main(String[] args) { scenarios[4].addFlags("-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast"); scenarios[5].addFlags("-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode"); - testFramework.addScenarios(scenarios) - .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class) - .start(); + InlineTypes.getFramework() + .addScenarios(scenarios) + .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class) + .start(); } // Helper methods and classes diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java index fbdd946d163..550be798671 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java @@ -26,6 +26,8 @@ import jdk.test.lib.Asserts; import jdk.test.lib.hotspot.ir_framework.*; +import java.lang.reflect.Method; + import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; import static compiler.valhalla.inlinetypes.InlineTypes.*; @@ -35,7 +37,7 @@ * @summary Test the basic inline type implementation in C2 * * @requires os.simpleArch == "x64" - * @library /test/lib + * @library /test/lib / * @compile InlineTypes.java * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestBasicFunctionality */ @@ -43,17 +45,19 @@ @ForceCompileClassInitializer public class TestBasicFunctionality { - static final TestFramework testFramework = InlineTypes.getFramework(); - public static void main(String[] args) { Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; scenarios[2].addFlags("-DVerifyIR=false"); scenarios[3].addFlags("-XX:FlatArrayElementMaxSize=0"); - testFramework.addScenarios(scenarios) - .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class, - MyValue3.class, MyValue3Inline.class) - .start(); + InlineTypes.getFramework() + .addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class, + MyValue3.class, + MyValue3Inline.class) + .start(); } // Helper methods @@ -465,12 +469,12 @@ public void test19_verifier() { @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"}, counts = {ALLOC, "= 1"}, failOn = LOAD) - public long test20(boolean deopt) { + public long test20(boolean deopt, Method m) { MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); MyValue2[] va = new MyValue2[3]; if (deopt) { // uncommon trap - testFramework.deoptimize("test20"); + TestFramework.deoptimize(m); } return v.hashInterpreted() + va[0].hashInterpreted() + @@ -480,7 +484,7 @@ public long test20(boolean deopt) { @Run(test = "test20") public void test20_verifier(RunInfo info) { MyValue2[] va = new MyValue2[42]; - long result = test20(!info.isWarmUp()); + long result = test20(!info.isWarmUp(), info.getTest()); Asserts.assertEQ(result, hash() + va[0].hash() + va[1].hash() + va[2].hash()); } @@ -601,19 +605,19 @@ class TestClass27 { // Test allocation elimination of unused object with initialized inline type field @Test @IR(failOn = {ALLOC, LOAD, STORE, LOOP}) - public void test27(boolean deopt) { + public void test27(boolean deopt, Method m) { TestClass27 unused = new TestClass27(); MyValue1 v = MyValue1.createWithFieldsInline(rI, rL); unused.v = v; if (deopt) { // uncommon trap - testFramework.deoptimize("test27"); + TestFramework.deoptimize(m); } } @Run(test = "test27") public void test27_verifier(RunInfo info) { - test27(!info.isWarmUp()); + test27(!info.isWarmUp(), info.getTest()); } static MyValue3 staticVal3; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java index e0853ea75eb..fb433329df1 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java @@ -32,9 +32,8 @@ * @test * @key randomness * @summary Various tests that are specific for C1. - * @library /test/lib + * @library /test/lib / * @requires os.simpleArch == "x64" - * @compile InlineTypes.java * @compile -XDallowWithFieldOperator TestC1.java * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestC1 */ @@ -61,8 +60,11 @@ public static void main(String[] args) { InlineTypes.getFramework() .addScenarios(scenarios) - .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class, - MyValue3.class, MyValue3Inline.class) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class, + MyValue3.class, + MyValue3Inline.class) .start(); } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java index af55eb08e1e..57cfd03ac6b 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java @@ -38,9 +38,8 @@ * @test * @key randomness * @summary Test inline type calling convention optimizations - * @library /test/lib + * @library /test/lib / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile InlineTypes.java * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestCallingConvention */ @@ -66,8 +65,6 @@ public class TestCallingConvention { } } - static final TestFramework testFramework = InlineTypes.getFramework(); - public static void main(String[] args) { Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; @@ -77,14 +74,15 @@ public static void main(String[] args) { scenarios[3].addFlags("-XX:FlatArrayElementMaxSize=0"); scenarios[4].addFlags("-XX:-UseTLAB"); - testFramework.addScenarios(scenarios) - .addHelperClasses(MyValue1.class, - MyValue2.class, - MyValue2Inline.class, - MyValue3.class, - MyValue3Inline.class, - MyValue4.class) - .start(); + InlineTypes.getFramework() + .addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class, + MyValue3.class, + MyValue3Inline.class, + MyValue4.class) + .start(); } // Helper methods and classes diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java index a84221f0a3d..74cf637f2b7 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java @@ -34,15 +34,13 @@ * @test * @key randomness * @summary Test calls from {C1} to {C2, Interpreter}, and vice versa. - * @library /test/lib + * @library /test/lib / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile InlineTypes.java * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestCallingConventionC1 */ @ForceCompileClassInitializer public class TestCallingConventionC1 { - static final TestFramework testFramework = InlineTypes.getFramework(); public static void main(String[] args) { final Scenario[] scenarios = { @@ -76,8 +74,9 @@ public static void main(String[] args) { System.gc(); // Resolve this call, to avoid C1 code patching in the test cases. - testFramework.addScenarios(scenarios) - .start(); + InlineTypes.getFramework() + .addScenarios(scenarios) + .start(); } // Helper methods and classes diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java index 56d3df2e95b..58d571e2fa8 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java @@ -30,9 +30,9 @@ * @test * @key randomness * @summary Verify that chains of getfields on flattened fields are correctly optimized - * @library /test/lib + * @library /test/lib / * @requires os.simpleArch == "x64" - * @compile InlineTypes.java GetfieldChains.jcod + * @compile GetfieldChains.jcod * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestGetfieldChains */ diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java index e560c4b2648..7d858d1c935 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java @@ -39,10 +39,9 @@ * @test * @key randomness * @summary Test intrinsic support for inline types - * @library /test/lib + * @library /test/lib / * @modules java.base/jdk.internal.misc * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile InlineTypes.java * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestIntrinsics */ @@ -63,7 +62,7 @@ public static void main(String[] args) { .addHelperClasses(MyValue1.class, MyValue2.class, MyValue2Inline.class) - .start(); + .start(); } // Test correctness of the Class::isAssignableFrom intrinsic diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java index a44d41deea8..b08466eb02b 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java @@ -33,9 +33,8 @@ * @test * @key randomness * @summary Test calling native methods with inline type arguments from compiled code. - * @library /test/lib + * @library /test/lib / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile InlineTypes.java * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestJNICalls */ diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java index eb59a4fd0a9..fc7b89bf9c3 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java @@ -40,16 +40,14 @@ * @test * @key randomness * @summary Test inline types in LWorld. - * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common + * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper - * @compile InlineTypes.java * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestLWorld */ @ForceCompileClassInitializer public class TestLWorld { - static final TestFramework testFramework = InlineTypes.getFramework(); public static void main(String[] args) { @@ -58,13 +56,14 @@ public static void main(String[] args) { scenarios[3].addFlags("-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"); scenarios[4].addFlags("-XX:-MonomorphicArrayCheck"); - testFramework.addScenarios(scenarios) - .addHelperClasses(MyValue1.class, - MyValue2.class, - MyValue2Inline.class, - MyValue3.class, - MyValue3Inline.class) - .start(); + InlineTypes.getFramework() + .addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class, + MyValue3.class, + MyValue3Inline.class) + .start(); } // Helper methods diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java index 479d43682ba..2b63160cc1a 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java @@ -38,15 +38,13 @@ * @test * @key randomness * @summary Test method handle support for inline types - * @library /test/lib + * @library /test/lib / * @requires os.simpleArch == "x64" - * @compile InlineTypes.java * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestMethodHandles */ @ForceCompileClassInitializer public class TestMethodHandles { - static final TestFramework testFramework = InlineTypes.getFramework(); static { try { @@ -135,13 +133,14 @@ public static void main(String[] args) { "-XX:CompileCommand=dontinline,java.lang.invoke.DirectMethodHandle::internalMemberName"); scenarios[4].addFlags("-XX:CompileCommand=dontinline,java.lang.invoke.DirectMethodHandle::internalMemberName"); - testFramework.addScenarios(scenarios) - .addHelperClasses(MyValue1.class, - MyValue2.class, - MyValue2Inline.class, - MyValue3.class, - MyValue3Inline.class) - .start(); + InlineTypes.getFramework() + .addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class, + MyValue3.class, + MyValue3Inline.class) + .start(); } // Everything inlined diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java index c46426d95ef..3806824fc85 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java @@ -37,15 +37,13 @@ * @test * @key randomness * @summary Test nullable inline type arrays - * @library /test/lib + * @library /test/lib / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile InlineTypes.java * @run driver compiler.valhalla.inlinetypes.TestNullableArrays */ @ForceCompileClassInitializer public class TestNullableArrays { - static final TestFramework testFramework = InlineTypes.getFramework(); public static void main(String[] args) { @@ -55,11 +53,12 @@ public static void main(String[] args) { scenarios[4].addFlags("-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast"); scenarios[5].addFlags("-XX:-MonomorphicArrayCheck", "-XX:-UncommonNullCast", "-XX:+StressArrayCopyMacroNode"); - testFramework.addScenarios(scenarios) - .addHelperClasses(MyValue1.class, - MyValue2.class, - MyValue2Inline.class) - .start(); + InlineTypes.getFramework() + .addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class) + .start(); } // Helper methods diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java index 794f6609979..a696dffa80d 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java @@ -36,27 +36,26 @@ * @test * @key randomness * @summary Test on stack replacement (OSR) with inline types - * @library /test/lib + * @library /test/lib / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile InlineTypes.java * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestOnStackReplacement */ public class TestOnStackReplacement { - static final TestFramework testFramework = InlineTypes.getFramework(); public static void main(String[] args) throws Throwable { Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; scenarios[3].addFlags("-XX:FlatArrayElementMaxSize=0"); - testFramework.addScenarios(scenarios) - .addHelperClasses(MyValue1.class, - MyValue2.class, - MyValue2Inline.class, - MyValue3.class, - MyValue3Inline.class) - .start(); + InlineTypes.getFramework() + .addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class, + MyValue3.class, + MyValue3Inline.class) + .start(); } // Helper methods diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java index dc98bc425a4..4229bfdbbf1 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java @@ -30,9 +30,8 @@ * @test * @key randomness * @summary Verify that C1 performs escape analysis before optimizing withfield bytecode to putfield. - * @library /test/lib + * @library /test/lib / * @requires os.simpleArch == "x64" - * @compile InlineTypes.java * @compile -XDallowWithFieldOperator TestWithfieldC1.java * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestWithfieldC1 */ From 0eaa6b18ce789c8c2de3f3398eff562b8793ffa4 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 12 Apr 2021 14:32:45 +0200 Subject: [PATCH 101/131] Fix more tests and clean up ArgumentValue and feedback from Tobias --- .../valhalla/inlinetypes/MyValue1.java | 5 +- .../valhalla/inlinetypes/MyValue2.java | 3 +- .../valhalla/inlinetypes/MyValue3.java | 3 +- .../valhalla/inlinetypes/MyValue4.java | 2 +- .../inlinetypes/TestGetfieldChains.java | 2 +- .../hotspot/ir_framework/AbstractInfo.java | 36 ++--------- .../hotspot/ir_framework/ArgumentValue.java | 60 ++++++++++++------- .../examples/CustomRunTestExample.java | 2 +- .../ir_framework/tests/TestBasics.java | 1 + 9 files changed, 54 insertions(+), 60 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java index 28d180151f2..ff90b6bc413 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java @@ -23,7 +23,10 @@ package compiler.valhalla.inlinetypes; -import jdk.test.lib.hotspot.ir_framework.*; +import jdk.test.lib.hotspot.ir_framework.DontCompile; +import jdk.test.lib.hotspot.ir_framework.DontInline; +import jdk.test.lib.hotspot.ir_framework.ForceCompileClassInitializer; +import jdk.test.lib.hotspot.ir_framework.ForceInline; @ForceCompileClassInitializer public final primitive class MyValue1 extends MyAbstract { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java index 80e6ec309b5..088d43a2dc7 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java @@ -23,7 +23,8 @@ package compiler.valhalla.inlinetypes; -import jdk.test.lib.hotspot.ir_framework.*; +import jdk.test.lib.hotspot.ir_framework.DontInline; +import jdk.test.lib.hotspot.ir_framework.ForceInline; final primitive class MyValue2Inline { final double d; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java index 12dafbc0c40..315c16d8746 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java @@ -25,7 +25,8 @@ import jdk.test.lib.Asserts; import jdk.test.lib.Utils; -import jdk.test.lib.hotspot.ir_framework.*; +import jdk.test.lib.hotspot.ir_framework.DontInline; +import jdk.test.lib.hotspot.ir_framework.ForceInline; final primitive class MyValue3Inline { final float f7; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java index cbc87da8455..9d6ad6c1005 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java @@ -23,7 +23,7 @@ package compiler.valhalla.inlinetypes; -import jdk.test.lib.hotspot.ir_framework.*; +import jdk.test.lib.hotspot.ir_framework.ForceInline; // Inline type definition with too many fields to return in registers final primitive class MyValue4 extends MyAbstract { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java index 58d571e2fa8..039b8591f67 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java @@ -115,7 +115,7 @@ public void test3_verifier() { Asserts.assertNE(npe, null); StackTraceElement st = npe.getStackTrace()[0]; Asserts.assertEQ(st.getMethodName(), "getP1X"); - Asserts.assertEQ(st.getLineNumber(), 37); // line number depends on file NamedRectangle.java + Asserts.assertEQ(st.getLineNumber(), 31); // line number depends on file NamedRectangle.java } // Chain of getfields but one getfield in the middle of the chain trigger an illegal access diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java index dbaaba4c2d4..c58a36ba74f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java @@ -59,41 +59,13 @@ public boolean toggleBoolean() { return toggleBool; } - - /** - * Get a random boolean. - * - * @return a random boolean. - */ - public boolean getRandomBoolean() { - return random.nextBoolean(); - } - - /** - * Get a random integer. - * - * @return a random integer. - */ - public int getRandomInt() { - return random.nextInt(); - } - - /** - * Get a random long value. - * - * @return a random long value. - */ - public long getRandomLong() { - return random.nextLong(); - } - /** - * Get a random double value in the range of [-10000,10000] + * Get the initialized {@link Random} object. * - * @return a random double value in the range of [-10000,10000]. + * @return the random object. */ - public double getRandomDouble() { - return random.nextDouble() * 20000 - 10000; + public Random getRandom() { + return random; } /** diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java index 60c66e7244f..5cf46e6c1ac 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java @@ -35,16 +35,19 @@ class ArgumentValue { private static final Random random = new Random(); private final Object argumentValue; - private final boolean isToggleBoolean; private final boolean isRandomEach; private final boolean isFixedRandom; private final Class randomClass; - private boolean previousBoolean; - private ArgumentValue(Object argumentValue, Boolean booleanToggle, boolean isFixedRandom) { + ArgumentValue() { + this.argumentValue = null; + this.isRandomEach = false; + this.randomClass = null; + this.isFixedRandom = false; + } + + private ArgumentValue(Object argumentValue, boolean isFixedRandom) { this.argumentValue = argumentValue; - this.isToggleBoolean = booleanToggle != null; - this.previousBoolean = isToggleBoolean && !booleanToggle; this.isRandomEach = false; this.randomClass = null; this.isFixedRandom = isFixedRandom; @@ -52,7 +55,6 @@ private ArgumentValue(Object argumentValue, Boolean booleanToggle, boolean isFix private ArgumentValue(Object argumentValue, Class randomClass) { this.argumentValue = argumentValue; - this.isToggleBoolean = false; this.isRandomEach = true; this.randomClass = randomClass; this.isFixedRandom = false; @@ -62,8 +64,8 @@ private ArgumentValue(Object argumentValue, Class randomClass) { * Return all arguments for the @Arguments annotation. * * @param m The @Test method. - * @return Returns an array with Argument objects for each specified argument in the @Arguments annotation of m. - * Returns null if method has no @Arguments annotation. + * @return Returns an array with Argument objects for each specified argument in the @Arguments annotation of m. + * Returns null if method has no @Arguments annotation. */ public static ArgumentValue[] getArguments(Method m) { Arguments argumentsAnno = m.getAnnotation(Arguments.class); @@ -134,13 +136,13 @@ public static ArgumentValue[] getArguments(Method m) { TestFormat.check(isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_FALSE argument for non-boolean " + parameterObj + " for " + m); - arguments[i] = createToggleBoolean(false); + arguments[i] = BooleanToggleValue.create(false); } case BOOLEAN_TOGGLE_FIRST_TRUE -> { TestFormat.check(ArgumentValue.isBoolean(parameter), "Provided invalid BOOLEAN_TOGGLE_FIRST_TRUE argument for non-boolean " + parameterObj + " for " + m); - arguments[i] = createToggleBoolean(true); + arguments[i] = BooleanToggleValue.create(true); } case RANDOM_ONCE -> { TestFormat.check(isPrimitiveType(parameter), @@ -167,7 +169,7 @@ public static ArgumentValue[] getArguments(Method m) { } private static ArgumentValue create(Object argumentValue) { - return new ArgumentValue(argumentValue, null, false); + return new ArgumentValue(argumentValue, false); } private static ArgumentValue createDefault(Class c) throws Exception { @@ -204,7 +206,7 @@ private static ArgumentValue createMin(Class c) { } else { throw new TestFrameworkException("Invalid class passed to createMin()"); } - return new ArgumentValue(argument, null, false); + return new ArgumentValue(argument, false); } private static ArgumentValue createMax(Class c) { @@ -226,15 +228,11 @@ private static ArgumentValue createMax(Class c) { } else { throw new TestFrameworkException("Invalid class passed to createMax()"); } - return new ArgumentValue(argument, null, false); - } - - private static ArgumentValue createToggleBoolean(boolean firstBoolean) { - return new ArgumentValue(null, firstBoolean, false); + return new ArgumentValue(argument, false); } private static ArgumentValue createRandom(Class c) { - return new ArgumentValue(getRandom(c), null, true); + return new ArgumentValue(getRandom(c), true); } private static ArgumentValue createRandomEach(Class c) { @@ -246,10 +244,7 @@ public boolean isFixedRandom() { } public Object getArgument() { - if (isToggleBoolean) { - previousBoolean = !previousBoolean; - return previousBoolean; - } else if (isRandomEach) { + if (isRandomEach) { return getRandom(randomClass); } else { return argumentValue; @@ -308,3 +303,24 @@ private static Object getRandom(Class c) { } } } + +/** + * Special class to handle boolean toggle argument values. + */ +class BooleanToggleValue extends ArgumentValue { + private boolean previousBoolean; + + BooleanToggleValue(boolean firstBoolean) { + this.previousBoolean = !firstBoolean; + } + + @Override + public Object getArgument() { + previousBoolean = !previousBoolean; + return previousBoolean; + } + + static BooleanToggleValue create(boolean firstBoolean) { + return new BooleanToggleValue(firstBoolean); + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java index 838e974332e..273bbc9c056 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java @@ -104,7 +104,7 @@ public int test2(int x) { @Run(test = "test2") public void runWithRunInfo(RunInfo info) { // We could also skip some invocations. This might have an influence on possible @IR rules, need to be careful. - if (info.getRandomBoolean()) { + if (info.getRandom().nextBoolean()) { int returnValue = test(34); if (returnValue != 34) { throw new RuntimeException("Must match"); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java index 9458ebf9b71..d583b4fe0d1 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java @@ -51,6 +51,7 @@ public class TestBasics { public static void main(String[] args) throws Exception { // Run on same VM to make this test easier as we are not interested in any output processing. + Class c = TestFramework.class; // Enable JTreg test to compile TestFramework Method runTestsOnSameVM = TestFrameworkExecution.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); runTestsOnSameVM.invoke(null, new Object[]{ null }); From 61f5b74232effcdbfc22d6465cc4431431e622d0 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 12 Apr 2021 14:56:28 +0200 Subject: [PATCH 102/131] Fix bug where socket was stuck after test VM --- .../jdk/test/lib/hotspot/ir_framework/TestFramework.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index db62e6c2882..c81290392ac 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -808,7 +808,11 @@ private void runTestVM(List additionalFlags) { if (scenario != null) { scenario.setTestVMOutput(lastTestVMOutput); } - String socketOutput = socket.getOutputPrintStdout(); + String socketOutput = ""; + if (shouldVerifyIR || TESTLIST || EXCLUDELIST) { + // Socket has only output to read if IR verification is done and/or if a test list was provided by user + socketOutput = socket.getOutputPrintStdout(); + } checkTestVMExitCode(output); if (shouldVerifyIR) { try { From 7faf865cde8ed9f77e15ceb7186f8e120a8274fa Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 12 Apr 2021 16:51:56 +0200 Subject: [PATCH 103/131] Clean up VERIFY_IR and finish Javadocs review/clean-up --- .../hotspot/ir_framework/AbstractInfo.java | 2 +- .../test/lib/hotspot/ir_framework/IRNode.java | 7 +- .../lib/hotspot/ir_framework/RunInfo.java | 52 +++--- .../lib/hotspot/ir_framework/Scenario.java | 47 +++--- .../hotspot/ir_framework/TestFramework.java | 158 ++++++++++-------- .../lib/hotspot/ir_framework/TestInfo.java | 13 +- .../test/lib/hotspot/ir_framework/Warmup.java | 5 +- .../ir_framework/tests/TestBadFormat.java | 16 +- 8 files changed, 162 insertions(+), 138 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java index c58a36ba74f..996f8c5c8a6 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java @@ -114,7 +114,7 @@ public Method getTestClassMethod(String name, Class... args) { * Returns a boolean indicating if the test VM runs with flags that allow C2 compilations. * * @return {@code true} if C2 compilations are allowed; - * {@code false} otherwise (run with {@code -XX:TieredStopAtLevel={1,2,3}, -XX:-UseCompiler}. + * {@code false} otherwise (run with {@code -XX:TieredStopAtLevel={1,2,3}, -XX:-UseCompiler}). */ public boolean isC2CompilationEnabled() { return TestFrameworkExecution.USE_COMPILER && !TestFrameworkExecution.TEST_C1; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java index 75a9fa1453e..fec15dd27ca 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java @@ -28,13 +28,14 @@ import java.util.regex.Pattern; /** - * This class provides default regex strings that can be used in {@link IR} annotations to specify IR constraints. + * This class provides default regex strings that can be used in {@link IR @IR} annotations to specify IR constraints. *

      * There are two types of default regexes: *

        *
      • Standalone regexes: Use them directly. - *

      • Composite regexes: They end with {@code _OF} and expect another string in a list in {@link IR#failOn()} and - * {@link IR#counts()}. Do not use them as standalone regex. Doing so will result in a {@link TestFormatException}
      • + *
      • Composite regexes: Their names contain "{@code _OF}" and expect another string in a list in + * {@link IR#failOn()} and {@link IR#counts()}. They cannot be use as standalone regex and will result in a + * {@link TestFormatException} when doing so.

      • *
      * * @see IR diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java index 58fbfcf3c48..ebba8d555f8 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java @@ -55,8 +55,8 @@ public class RunInfo extends AbstractInfo { } /** - * Get the associated test method object of this custom run test. This method can only be called if one test method - * is specified in the custom run test ({@link Run#test()}). Otherwise, use {@link #getTest(String)}. + * Get the associated test method object of this custom run test. This method can only be called if one test + * method is specified in the custom run test ({@link Run#test()}). Otherwise, use {@link #getTest(String)}. * * @return the associated test method object. * @throws TestRunException if called for a custom run test that specifies multiple test methods in {@link Run#test()}. @@ -72,8 +72,8 @@ public Method getTest() { * * @param testName the test method for which the method object should be returned. * @return the associated test method object with the name {@code testName}. - * @throws TestRunException if there is no test method with the name {@code testName} or if called with more than - * one associated test method. + * @throws TestRunException if there is no test method with the name {@code testName} or if called with only + * one associated test method. */ public Method getTest(String testName) { checkMultipleTests("getTest"); @@ -83,11 +83,11 @@ public Method getTest(String testName) { /** * Return a boolean indicating if the framework skipped a compilation of the associated test method after the warm-up * due to VM flags not allowing a compilation on the requested level in {@link Test#compLevel()}. This method can only - * be called if one test method is specified in the custom run test ({@link Run#test()}). Otherwise, use + * be called if one test method is specified in the custom run test ({@link Run#test()}). Otherwise, use * {@link #isCompilationSkipped(String)}. * * @return {@code true} if the framework compiled the test; - * {@code false} otherwise + * {@code false} otherwise. * @throws TestRunException if called for a custom run test that specifies multiple test methods in {@link Run#test()}. */ public boolean isCompilationSkipped() { @@ -103,17 +103,19 @@ public boolean isCompilationSkipped() { * * @param testName the test method for which the method object should be returned. * @return {@code true} if the framework compiled the test; - * {@code false} otherwise - * @throws TestRunException if there is no test method with the name {@code testName} or if called with more than - * one associated test method. */ + * {@code false} otherwise. + * @throws TestRunException if there is no test method with the name {@code testName} or if called with only + * one associated test method. + */ public boolean isCompilationSkipped(String testName) { checkMultipleTests("isCompilationSkipped"); return getDeclaredTest(testName).getCompLevel() == CompLevel.SKIP; } /** - * Returns a boolean indicating if the associated test method is C1 compiled. This method can only be called if one - * test method is specified in the custom run test ({@link Run#test()}). Otherwise, use {@link #isTestC1Compiled(String)}. + * Returns a boolean indicating if the associated test method is C1 compiled. This method can only be called if + * one test method is specified in the custom run test ({@link Run#test()}). Otherwise, use + * {@link #isTestC1Compiled(String)}. * * @return {@code true} if the associated test method is C1 compiled; * {@code false} otherwise. @@ -130,10 +132,10 @@ public boolean isTestC1Compiled() { * Otherwise, use {@link #isTestC1Compiled()}. * * @param testName the name of the test method. - * @return {@code true} if the test method with the name {@code testName} is C2 compiled; + * @return {@code true} if the test method with the name {@code testName} is C1 compiled; * {@code false} otherwise. - * @throws TestRunException if there is no test method with the name {@code testName} or if called with more than - * one associated test method. + * @throws TestRunException if there is no test method with the name {@code testName} or if called with only + * one associated test method. */ public boolean isTestC1Compiled(String testName) { checkMultipleTests("isTestC1Compiled"); @@ -141,8 +143,9 @@ public boolean isTestC1Compiled(String testName) { } /** - * Returns a boolean indicating if the associated test method is C2 compiled. This method can only be called if one - * test method is specified in the custom run test ({@link Run#test()}). Otherwise, use {@link #isTestC2Compiled(String)}. + * Returns a boolean indicating if the associated test method is C2 compiled. This method can only be called if + * one test method is specified in the custom run test ({@link Run#test()}). Otherwise, use + * {@link #isTestC2Compiled(String)}. * * @return {@code true} if the associated test method is C2 compiled; * {@code false} otherwise. @@ -154,15 +157,15 @@ public boolean isTestC2Compiled() { } /** - * Returns a boolean indicating if the associated test method with the name {@code testName} is C2 compiled. This - * method can only be called if the custom run test specifies more than one test method in ({@link Run#test()}). - * Otherwise, use {@link #isTestC1Compiled()}. + * Returns a boolean indicating if the associated test method with the name {@code testName} is C2 compiled. + * This method can only be called if the custom run test specifies more than one test method in ({@link Run#test()}). + * Otherwise, use {@link #isTestC2Compiled()}. * * @param testName the name of the test method. * @return {@code true} if the test method with the name {@code testName} is C2 compiled; * {@code false} otherwise. - * @throws TestRunException if there is no test method with the name {@code testName} or if called with more than - * one associated test method. + * @throws TestRunException if there is no test method with the name {@code testName} or if called with only + * one associated test method. */ public boolean isTestC2Compiled(String testName) { checkMultipleTests("isTestC2Compiled"); @@ -171,7 +174,7 @@ public boolean isTestC2Compiled(String testName) { /** * Returns a boolean indicating if the associated test method is compiled at {@code compLevel}. This method can only - * be called if one test method is specified in the custom run test ({@link Run#test()}). + * be called if one test method is specified in the custom run test ({@link Run#test()}). * Otherwise, use {@link #isTestCompiledAtLevel(String, CompLevel)}. * * @param compLevel the compilation level @@ -193,8 +196,8 @@ public boolean isTestCompiledAtLevel(CompLevel compLevel) { * @param compLevel the compilation level. * @return {@code true} if the test method with the name {@code testName} is compiled at {@code compLevel}; * {@code false} otherwise. - * @throws TestRunException if there is no test method with the name {@code testName} or if called with more than - * one associated test method. + * @throws TestRunException if there is no test method with the name {@code testName} oor if called with only + * one associated test method. */ public boolean isTestCompiledAtLevel(String testName, CompLevel compLevel) { checkMultipleTests("isTestCompiledAtLevel"); @@ -223,6 +226,7 @@ private DeclaredTest getDeclaredTest(String testName) { } return test; } + private Method getMethod(String testName) { return getDeclaredTest(testName).getTestMethod(); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java index e4e778f0437..ded24ec1649 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java @@ -28,13 +28,14 @@ /** * This class represents a scenario that can be executed by the {@link TestFramework}. *

      - * A JTreg test should call the test framework with {@code @run driver}, not allowing to specify any additional flags. + * A JTreg test should use the test framework with {@code @run driver} (without directly specify any additional flags). * If a test should run with additional flags, use {@link TestFramework#runWithFlags(String...)} or * {@link TestFramework#addFlags(String...)}. If, however, the test should be run with different settings (equivalent * to having multiple {@code @run} entries in a normal JTreg test), use scenarios. A scenario will be run with the - * scenario specific flags, if any, and the flags specified with - * {@link TestFramework#runWithFlags(String...)}/{@link TestFramework#addFlags(String...)} whereas scenario flags will - * have precedence. + * scenario specific VM flags, if any, and optionally specified VM flags with {@link TestFramework#addFlags(String...)} + * whereas scenario VM flags will have precedence. + *

      + * There is also the possibility to specify additional VM flags for all scenarios by using {@code DScenarioFlags}. * * @see TestFramework */ @@ -66,10 +67,10 @@ public class Scenario { } /** - * Create a scenario with index {@code index} that will be run with the additionally specified flags specified in - * {@code flags} (or without any additional flags if null or parameter not specified). + * Create a scenario with {@code index} that will be run with the additional VM flags specified in {@code flags} + * (or without any if null or parameter not provided). *

      - * The scenario index must be unique to be distinguishable in stdout and stderr output and when specifying + * The scenario {@code index} must be unique to be distinguishable in the stdout and stderr output and when specifying * {@code -DScenarios} (see {@link Scenario}). * * @param index the unique scenario index. @@ -87,9 +88,9 @@ public Scenario(int index, String... flags) { } /** - * Add additional flags to this scenario. + * Add additional VM flags to this scenario. * - * @param flags the additional scenario flags. + * @param flags the additional scenario VM flags. */ public void addFlags(String... flags) { if (flags != null) { @@ -98,9 +99,9 @@ public void addFlags(String... flags) { } /** - * Get all scenario specific flags as defined in {@link #Scenario(int, String...)}. + * Get all scenario specific VM flags as defined in {@link #Scenario(int, String...)}. * - * @return the scenario flags. + * @return the scenario VM flags. */ public List getFlags() { return flags; @@ -115,18 +116,6 @@ public int getIndex() { return index; } - /** - * Returns a boolean indicating if this scenario will be executed by the test framework. This only depends on - * the property flag {@code -DScenarios} (see {@link Scenario}). - * - * @return {@code true} if {@code -DScenarios} is either not set or if {@code -DScenarios} specifies the scenario - * index set by {@link #Scenario(int, String...)}. - * {@code false} otherwise. - */ - public boolean isEnabled() { - return enabled; - } - /** * Get the test VM output (stdout + stderr) of this scenario from the last execution of the framework. * @@ -142,4 +131,16 @@ public String getTestVMOutput() { void setTestVMOutput(String testVMOutput) { this.testVMOutput = testVMOutput; } + + /** + * Returns a boolean indicating if this scenario will be executed by the test framework. This only depends on + * the property flag {@code -DScenarios} (see {@link Scenario}). This is only used by the framework internally. + * + * @return {@code true} if {@code -DScenarios} is either not set or if {@code -DScenarios} specifies the scenario + * index set by {@link #Scenario(int, String...)}. + * {@code false} otherwise. + */ + boolean isEnabled() { + return enabled; + } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index c81290392ac..d86e3f9ad14 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -96,12 +96,12 @@ */ public class TestFramework { /** - * JTreg can define additional VM (-Dtest.vm.opts) and Javaoption (-Dtest.java.opts) flags. IR verification is only + * JTreg can define additional VM (-Dtest.vm.opts) and Javaoptions (-Dtest.java.opts) flags. IR verification is only * performed when all these additional JTreg flags (does not include additionally added framework and scenario flags * by user code) are whitelisted. * * A flag is whitelisted if it is a property flag (starting with -D), -ea, -esa, or if the flag name contains any of - * the entries of this list as a substring. + * the entries of this list as a substring (partial match). */ public static final Set JTREG_WHITELIST_FLAGS = new HashSet<>( Arrays.asList( @@ -113,7 +113,8 @@ public class TestFramework { "Print", "Verify", "TLAB", - // The following substrings are only part of one VM flag (= exact match) + "UseNewCode", + // The following substrings are only part of one VM flag (=exact match) "CreateCoredumpOnCrash", "UnlockDiagnosticVMOptions", "BackgroundCompilation", @@ -123,8 +124,7 @@ public class TestFramework { "UseParallelGC", "UseG1GC", "UseZGC", - "UseShenandoahGC", - "UseNewCode" + "UseShenandoahGC" ) ); @@ -138,10 +138,10 @@ public class TestFramework { private static final int WARMUP_ITERATIONS = Integer.getInteger("Warmup", -1); private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.getBoolean("PreferCommandLineFlags"); private static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); - private static final boolean VERIFY_VM = Boolean.getBoolean("VerifyVM") && Platform.isDebugBuild(); - private static boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); private static final boolean REPORT_STDOUT = Boolean.getBoolean("ReportStdout"); - private boolean shouldVerifyIR = true; // Should we perform IR matching? + private final boolean VERIFY_VM = Boolean.getBoolean("VerifyVM") && Platform.isDebugBuild(); + private final boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); + private boolean shouldVerifyIR = VERIFY_IR; // Should we perform IR matching? private static String lastTestVMOutput; private final Class testClass; @@ -157,11 +157,10 @@ public class TestFramework { */ /** - * Creates an instance of TestFramework to test the class from which this constructor was invoked from. + * Creates an instance acting as a builder to test the class from which this constructor was invoked from. * Use this constructor if you want to use multiple run options (flags, helper classes, scenarios). * Use the associated add methods ({@link #addFlags(String...)}, {@link #addScenarios(Scenario...)}, - * {@link #addHelperClasses(Class...)}) - * to set up everything and then start the testing by invoking {@link #start()}. + * {@link #addHelperClasses(Class...)}) to set up everything and then start the testing by invoking {@link #start()}. */ public TestFramework() { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); @@ -172,11 +171,10 @@ public TestFramework() { } /** - * Creates an instance of TestFramework to test {@code testClass}. + * Creates an instance acting as a builder to test {@code testClass}. * Use this constructor if you want to use multiple run options (flags, helper classes, scenarios). * Use the associated add methods ({@link #addFlags(String...)}, @link #addScenarios(Scenario...)}, - * {@link #addHelperClasses(Class...)}) - * to set up everything and then start the testing by invoking {@link #start()}. + * {@link #addHelperClasses(Class...)}) to set up everything and then start the testing by invoking {@link #start()}. * * @param testClass the class to be tested by the framework. * @see #TestFramework() @@ -228,11 +226,12 @@ public static void run(Class testClass) { /** * Tests the class from which this method was invoked from. The test VM is called with the specified {@code flags}. *

        - *
      • The {@code flags} override any set Java or VM options by JTreg by default.

        - * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the {@code flags}.

      • - *
      • If you want to run your JTreg test with additional flags, use this method.

      • - *
      • If you want to run your JTreg test with multiple flag combinations, - * use {@link #runWithScenarios(Scenario...)}

      • + *
      • The {@code flags} override any set VM or Javaoptions flags by JTreg by default.

        + * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the JTreg VM and Javaoptions flags over + * the specified {@code flags} of this method.

      • + *
      • If you want to run your entire JTreg test with additional flags, use this method.

      • + *
      • If you want to run your JTreg test with multiple flag combinations, use + * {@link #runWithScenarios(Scenario...)}

      • *
      * * @param flags VM flags to be used for the test VM. @@ -245,11 +244,12 @@ public static void runWithFlags(String... flags) { /** * Tests {@code testClass}. The test VM is called with the specified {@code flags}. *
        - *
      • The {@code flags} override any set Java or VM options by JTreg by default.

        - * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the {@code flags}.

      • - *
      • If you want to run your JTreg test with additional flags, use this method.

      • - *
      • If you want to run your JTreg test with multiple flag combinations, - * use {@link #runWithScenarios(Class, Scenario...)}

      • + *
      • The {@code flags} override any set VM or Javaoptions flags by JTreg by default.

        + * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the JTreg VM and Javaoptions flags over + * the specified {@code flags} of this method.

      • + *
      • If you want to run your entire JTreg test with additional flags, use this method.

      • + *
      • If you want to run your JTreg test with multiple flag combinations, use + * {@link #runWithScenarios(Scenario...)}

      • *
      * * @param testClass the class to be tested by the framework. @@ -265,13 +265,15 @@ public static void runWithFlags(Class testClass, String... flags) { /** * Tests {@code testClass} which uses {@code helperClasses} that can specify additional compile command annotations - * ({@link ForceCompile}, {@link DontCompile}, {@link ForceInline}, {@link DontInline}) to be applied while testing - * {@code testClass} (also see description of {@link TestFramework}). + * ({@link ForceCompile @ForceCompile}, {@link DontCompile @DontCompile}, {@link ForceInline @ForceInline}, + * {@link DontInline @DontInline}) to be applied while testing {@code testClass} (also see description of + * {@link TestFramework}). *
        *
      • If a helper class is not in the same file as the test class, make sure that JTreg compiles it by using * {@literal @}compile in the JTreg header comment block.

      • - *
      • If a helper class does not specify any compile command annotations, you do not need to include it. If - * no helper class specifies any compile commands, consider using {@link #run()} or {@link #run(Class)}.

      • + *
      • If a class is used by the test class that does not specify any compile command annotations, you do not + * need to include it in {@code helperClasses}. If no helper class specifies any compile commands, consider + * using {@link #run()} or {@link #run(Class)}.

      • *
      * * @param testClass the class to be tested by the framework. @@ -290,8 +292,9 @@ public static void runWithHelperClasses(Class testClass, Class... helperCl * by using the specified flags in the scenario. *
        *
      • If there is only one scenario, consider using {@link #runWithFlags(String...)}.

      • - *
      • The scenario flags override any Java or VM options set by JTreg by default.

        - * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the scenario flags.

      • + *
      • The scenario flags override any VM or Javaoptions set by JTreg by default.

        + * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the + * scenario flags.

      • *
      * * @param scenarios scenarios which specify specific flags for the test VM. @@ -306,8 +309,9 @@ public static void runWithScenarios(Scenario... scenarios) { * in the scenario. *
        *
      • If there is only one scenario, consider using {@link #runWithFlags(String...)}.

      • - *
      • The scenario flags override any Java or VM options set by JTreg by default.

        - * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the scenario flags.

      • + *
      • The scenario flags override any VM or Javaoptions set by JTreg by default.

        + * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the + * scenario flags.

      • *
      * * @param testClass the class to be tested by the framework. @@ -322,8 +326,8 @@ public static void runWithScenarios(Class testClass, Scenario... scenarios) { } /** - * Add VM flags to be used for the test VM. These flags override any Java or VM options set by JTreg by default.

      - * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the scenario flags. + * Add VM flags to be used for the test VM. These flags override any VM or Javaoptions set by JTreg by default.

      + * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the VM or Javaoptions over the scenario flags. * *

      * The testing can be started by invoking {@link #start()} @@ -338,14 +342,15 @@ public TestFramework addFlags(String... flags) { } /** - * Add helper classes that can specify additional compile command annotations ({@link ForceCompile}, {@link DontCompile}, - * {@link ForceInline}, {@link DontInline}) to be applied while testing{@code testClass} (also see description of - * {@link TestFramework}). + * Add helper classes that can specify additional compile command annotations ({@link ForceCompile @ForceCompile}, + * {@link DontCompile @DontCompile}, {@link ForceInline @ForceInline}, {@link DontInline @DontInline}) to be applied + * while testing {@code testClass} (also see description of {@link TestFramework}). *

        *
      • If a helper class is not in the same file as the test class, make sure that JTreg compiles it by using - * {@literal @}compile in the JTreg header comment block.

      • - *
      • If a helper class does not specify any compile command annotations, you do not need to include it. If - * no helper class specifies any compile commands, you do not need to use this method

      • + * {@code @compile} in the JTreg header comment block. + *
      • If a class is used by the test class that does not specify any compile command annotations, you do not + * need to include it with this method. If no helper class specifies any compile commands, you do + * not need to call this method at all.

      • *
      * *

      @@ -371,9 +376,9 @@ public TestFramework addHelperClasses(Class... helperClasses) { /** * Add scenarios to be used for the test VM. A test VM is called for each scenario in {@code scenarios} by using the - * specified flags in the scenario. The scenario flags override any flags set by {@link #addFlags(String...)} - * and thus also override any Java or VM options set by JTreg by default.

      - * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the scenario flags. + * specified VM flags in the scenario. The scenario flags override any flags set by {@link #addFlags(String...)} + * and thus also override any VM or Javaoptions set by JTreg by default.

      + * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the VM and Javaoptions over the scenario flags. * *

      * The testing can be started by invoking {@link #start()} @@ -392,8 +397,8 @@ public TestFramework addScenarios(Scenario... scenarios) { } /** - * Start the testing of the implicitely set test class by {@link #TestFramework()} - * or explicitly set by {@link #TestFramework(Class)}. + * Start the testing of the implicitly (by {@link #TestFramework()}) or explicitly (by {@link #TestFramework(Class)}) + * set test class. */ public void start() { installWhiteBox(); @@ -417,10 +422,11 @@ public void start() { } /** - * Set a new default warm-up (overriding the framework default of 2000) to be applied for all tests that do - * not specify an explicit warm-up with {@link Warmup}. + * Set a new default warm-up (overriding the framework default of 2000 at + * {@link TestFrameworkExecution#WARMUP_ITERATIONS}) to be applied for all tests that do not specify an explicit + * warm-up with {@link Warmup @Warmup}. * - * @param defaultWarmup a non-negative default warm-up + * @param defaultWarmup a new non-negative default warm-up. * @return the same framework instance. */ public TestFramework setDefaultWarmup(int defaultWarmup) { @@ -433,20 +439,20 @@ public TestFramework setDefaultWarmup(int defaultWarmup) { * Get the VM output of the test VM. Use {@code -DVerbose=true} to enable more debug information. If scenarios * were run, use {@link Scenario#getTestVMOutput()}. * - * @return the last test VM output + * @return the last test VM output. */ public static String getLastTestVMOutput() { return lastTestVMOutput; } /* - * The following methods can only be called from actual tests and not from the main() method of a test. - * Calling these methods from main() results in a linking exception (Whitebox not yet loaded and enabled). + * The following methods are only intended to be called from actual @Test methods and not from the main() method of + * a JTreg test. Calling these methods from main() results in a linking exception (Whitebox not yet loaded and enabled). */ /** - * Compile {@code m} at compilation level {@code compLevel}. {@code m} is first enqueued and might not be compiled - * yet upon returning from this method. + * Compile {@code m} at compilation level {@code compLevel}. {@code m} is first enqueued and might not be compiled, + * yet, upon returning from this method. * * @param m the method to be compiled. * @param compLevel the (valid) compilation level at which the method should be compiled. @@ -531,9 +537,9 @@ public static void assertNotCompiled(Method m) { } /** - * Checks if {@code m} is compiled with C1. + * Verifies that {@code m} is compiled with C1. * - * @param m the method to be checked. + * @param m the method to be verified. * @throws TestRunException if {@code m} is not compiled with C1. */ public static void assertCompiledByC1(Method m) { @@ -541,7 +547,7 @@ public static void assertCompiledByC1(Method m) { } /** - * Checks if {@code m} is compiled with C2. + * Verifies that {@code m} is compiled with C2. * * @param m the method to be checked. * @throws TestRunException if {@code m} is not compiled with C2. @@ -551,7 +557,7 @@ public static void assertCompiledByC2(Method m) { } /** - * Checks if {@code m} is compiled with at the specified {@code compLevel}. + * Verifies that {@code m} is compiled at the specified {@code compLevel}. * * @param m the method to be checked. * @param compLevel the compilation level. @@ -562,7 +568,7 @@ public static void assertCompiledAtLevel(Method m, CompLevel compLevel) { } /** - * Checks if {@code m} was deoptimized after being C1 compiled. + * Verifies that {@code m} was deoptimized after being C1 compiled. * * @param m the method to be checked. * @throws TestRunException if {@code m} is was not deoptimized after being C1 compiled. @@ -572,7 +578,7 @@ public static void assertDeoptimizedByC1(Method m) { } /** - * Checks if {@code m} was deoptimized after being C2 compiled. + * Verifies that {@code m} was deoptimized after being C2 compiled. * * @param m the method to be checked. * @throws TestRunException if {@code m} is was not deoptimized after being C2 compiled. @@ -601,16 +607,22 @@ private void installWhiteBox() { */ private void maybeDisableIRVerification() { if (VERIFY_IR) { - VERIFY_IR = Platform.isDebugBuild() && !Platform.isInt() && !Platform.isComp(); - if (!VERIFY_IR) { + shouldVerifyIR = hasIRAnnotations(); + if (!shouldVerifyIR) { + System.out.println("IR verification disabled due to test " + testClass + " not specifying any @IR annotations"); + return; + } + + shouldVerifyIR = Platform.isDebugBuild() && !Platform.isInt() && !Platform.isComp(); + if (!shouldVerifyIR) { System.out.println("IR verification disabled due to not running a debug build (required for PrintIdeal" + "and PrintOptoAssembly), running with -Xint, or -Xcomp (use warm-up of 0 instead)"); return; } // No IR verification is done if additional non-whitelisted JTreg VM or Javaoptions flag is specified. - VERIFY_IR = onlyWhitelistedJTregVMAndJavaOptsFlags(); - if (!VERIFY_IR) { + shouldVerifyIR = onlyWhitelistedJTregVMAndJavaOptsFlags(); + if (!shouldVerifyIR) { System.out.println("IR verification disabled due to using non-whitelisted JTreg VM or Javaoptions flag(s).\n"); } } @@ -707,11 +719,10 @@ private void start(Scenario scenario) { additionalFlags.addAll(scenarioFlags); } socket.start(); - if (VERIFY_IR) { + if (shouldVerifyIR) { System.out.println("Run Flag VM:"); runFlagVM(additionalFlags); } else { - shouldVerifyIR = false; System.out.println("Skip Flag VM due to not performing IR verification."); } @@ -724,6 +735,10 @@ private void start(Scenario scenario) { } } + private boolean hasIRAnnotations() { + return Arrays.stream(testClass.getDeclaredMethods()).anyMatch(m -> m.getAnnotationsByType(IR.class) != null); + } + private boolean onlyWhitelistedJTregVMAndJavaOptsFlags() { List flags = Arrays.stream(Utils.getTestJavaOpts()) .map(s -> s.replaceFirst("-XX:[+|-]?|-(?=[^D|^e])", "")) @@ -756,7 +771,6 @@ private void runFlagVM(List additionalFlags) { */ private ArrayList prepareFlagVMFlags(List additionalFlags) { ArrayList cmds = new ArrayList<>(); -// cmds.add( "-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:44444,suspend=y,server=y"); cmds.add("-Dtest.jdk=" + Utils.TEST_JDK); // Set java.library.path so JNI tests which rely on jtreg nativepath setting work cmds.add("-Djava.library.path=" + Utils.TEST_NATIVE_PATH); @@ -822,10 +836,11 @@ private void runTestVM(List additionalFlags) { throw e; } } else { - System.out.println("IR verification disabled either through explicitly setting -DVerify=false, due to " + - "not running a debug build, using a non-whitelisted JTreg VM or Javaopts flag like " + - "-Xint, or running the test VM with other VM flags added by user code that make the " + - "IR verification impossible (e.g. -XX:-UseCompile, -XX:TieredStopAtLevel=[1,2,3], etc.)."); + System.out.println("IR verification disabled either due to no @IR annotations, through explicitly setting " + + "-DVerify=false, due to not running a debug build, using a non-whitelisted JTreg VM or " + + "Javaopts flag like -Xint, or running the test VM with other VM flags added by user code " + + "that make the IR verification impossible (e.g. -XX:-UseCompile, " + + "-XX:TieredStopAtLevel=[1,2,3], etc.)."); } } @@ -878,7 +893,7 @@ private List getTestVMFlags() { flagList.addAll(Arrays.asList(getDefaultFlags())); - if (VERIFY_IR) { + if (shouldVerifyIR) { String flags = socket.getOutput(); if (VERBOSE) { System.out.println("Read sent data from flag VM from socket:"); @@ -889,6 +904,7 @@ private List getTestVMFlags() { Pattern pattern = Pattern.compile(patternString); Matcher matcher = pattern.matcher(flags); check(matcher.find(), "Invalid flag encoding emitted by flag VM"); + // Maybe we run with flags that make IR verification impossible shouldVerifyIR = Boolean.parseBoolean(matcher.group(2)); flagList.addAll(Arrays.asList(matcher.group(1).split(TEST_VM_FLAGS_DELIMITER))); flagList.add("-DShouldDoIRVerification=true"); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java index 85593587ae0..58cc5074e71 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java @@ -26,8 +26,7 @@ import java.lang.reflect.Method; /** - * Test info class which provides some useful utility methods and information about a base test - * or a checked test. + * Test info class which provides some useful utility methods and information about a checked test. * * @see Test * @see Check @@ -45,7 +44,7 @@ public class TestInfo extends AbstractInfo { /** * Get the associated test method object. * - * @return the associated test method object + * @return the associated test method object. */ public Method getTest() { return testMethod; @@ -53,10 +52,10 @@ public Method getTest() { /** * Return a boolean indicating if the framework skipped a compilation after the warm-up due to VM flags not - * allowing a compilation on the requested level in {@link Test#compLevel()} + * allowing a compilation on the requested level in {@link Test#compLevel()}. * * @return {@code true} if the framework compiled the test; - * {@code false} otherwise + * {@code false} otherwise. */ public boolean isCompilationSkipped() { return compilationSkipped; @@ -73,7 +72,7 @@ public boolean isC1Compiled() { } /** - * Returns a boolean indicating if the associated test method is C1 compiled. + * Returns a boolean indicating if the associated test method is C2 compiled. * * @return {@code true} if the test method is C2 compiled; * {@code false} otherwise. @@ -85,7 +84,7 @@ public boolean isC2Compiled() { /** * Returns a boolean indicating if the associated test method is compiled at {@code compLevel}. * - * @param compLevel the compilation level + * @param compLevel the compilation level. * @return {@code true} if the test method is compiled at {@code compLevel}; * {@code false} otherwise. */ diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java index 82140cd4478..5e6962b1273 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java @@ -32,7 +32,7 @@ *

    • Any positive value or zero is permitted. A warm-up of zero allows a simulation of {@code -Xcomp}.

    • *
    • Custom run tests (see {@link Run}) must specify a {@code @Warmup} annotation at the run method.

    • *
    • Base and checked tests (see {@link Test}, {@link Check}) must specify a {@code @Warmup} annotation at - * the test method.

    • + * the test method. *
    * * @see Test @@ -41,5 +41,8 @@ */ @Retention(RetentionPolicy.RUNTIME) public @interface Warmup { + /** + * The warm-up iterations for the test. + */ int value(); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java index 9e8b6b05e55..130524073dc 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java @@ -46,14 +46,14 @@ public class TestBadFormat { public static void main(String[] args) { - expectTestFormatException(BadNoTests.class); - expectTestFormatException(BadArgumentsAnnotation.class); - expectTestFormatException(BadOverloadedMethod.class); - expectTestFormatException(BadCompilerControl.class); - expectTestFormatException(BadWarmup.class); - expectTestFormatException(BadBaseTests.class); - expectTestFormatException(BadRunTests.class); - expectTestFormatException(BadCheckTest.class); +// expectTestFormatException(BadNoTests.class); +// expectTestFormatException(BadArgumentsAnnotation.class); +// expectTestFormatException(BadOverloadedMethod.class); +// expectTestFormatException(BadCompilerControl.class); +// expectTestFormatException(BadWarmup.class); +// expectTestFormatException(BadBaseTests.class); +// expectTestFormatException(BadRunTests.class); +// expectTestFormatException(BadCheckTest.class); expectTestFormatException(BadIRAnnotations.class); expectTestFormatException(BadInnerClassTest.class); expectTestFormatException(BadCompileClassInitializer.class, BadCompileClassInitializerHelper1.class, From 6c0d713dac98859ce4235e6ccd37be36b071bbd6 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 12 Apr 2021 17:11:08 +0200 Subject: [PATCH 104/131] Fix compileAtLevel and assertCompiled interface methods --- .../ir_framework/TestFrameworkExecution.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 75173a78d9b..9ff56b66f17 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -827,7 +827,8 @@ static boolean isCompiledAtLevel(Method m, CompLevel compLevel) { } static void assertDeoptimizedByC1(Method m) { - TestRun.check(compiledByC1(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized by C1"); + TestRun.check(compiledByC1(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, + m + " should have been deoptimized by C1"); } static void assertDeoptimizedByC2(Method m) { @@ -852,7 +853,7 @@ static void assertNotCompiled(Method m) { } static void assertCompiled(Method m) { - TestRun.check(isC1Compiled(m) || isC2Compiled(m), m + " should have been compiled"); + TestRun.check(compiledByC1(m) != TriState.No || compiledByC2(m) != TriState.No, m + " should have been compiled"); } private static TriState compiledByC1(Method m) { @@ -873,17 +874,11 @@ private static TriState compiledByC2(Method m) { } private static TriState compiledAtLevel(Method m, CompLevel level) { - if (!USE_COMPILER || XCOMP || TEST_C1 || - (EXCLUDE_RANDOM && !WHITE_BOX.isMethodCompilable(m, level.getValue(), false))) { - return TriState.Maybe; - } if (WHITE_BOX.isMethodCompiled(m, false)) { switch (level) { case C1, C1_LIMITED_PROFILE, C1_FULL_PROFILE, C2 -> { if (WHITE_BOX.getMethodCompilationLevel(m, false) == level.getValue()) { return TriState.Yes; - } else { - return TriState.No; } } case ANY -> { @@ -892,6 +887,10 @@ private static TriState compiledAtLevel(Method m, CompLevel level) { default -> TestRun.fail("compiledAtLevel() should not be called with " + level); } } + if (!USE_COMPILER || XCOMP || TEST_C1 || + (EXCLUDE_RANDOM && !WHITE_BOX.isMethodCompilable(m, level.getValue(), false))) { + return TriState.Maybe; + } return TriState.No; } } From ac22c94790b5a3a9485786c575f8d13a351059e3 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 12 Apr 2021 17:56:14 +0200 Subject: [PATCH 105/131] Fix default scenarios in Valhalla tests to also run with product version --- .../valhalla/inlinetypes/InlineTypes.java | 6 ++++++ .../ir_framework/tests/TestBadFormat.java | 16 ++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java index 821aa407aaf..69e84cf52e0 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java @@ -34,6 +34,7 @@ public class InlineTypes { public static final Scenario[] DEFAULT_SCENARIOS = { new Scenario(0, + "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UseACmpProfile", "-XX:+AlwaysIncrementalInline", "-XX:FlatArrayElementMaxOops=5", @@ -44,6 +45,7 @@ public class InlineTypes { "-XX:+InlineTypeReturnedAsFields" ), new Scenario(1, + "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UseACmpProfile", "-XX:-UseCompressedOops", "-XX:FlatArrayElementMaxOops=5", @@ -54,6 +56,7 @@ public class InlineTypes { "-XX:-InlineTypeReturnedAsFields" ), new Scenario(2, + "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UseACmpProfile", "-XX:-UseCompressedOops", "-XX:FlatArrayElementMaxOops=0", @@ -65,6 +68,7 @@ public class InlineTypes { "-XX:+StressInlineTypeReturnedAsFields" ), new Scenario(3, + "-XX:+IgnoreUnrecognizedVMOptions", "-DVerifyIR=false", "-XX:+AlwaysIncrementalInline", "-XX:FlatArrayElementMaxOops=0", @@ -74,6 +78,7 @@ public class InlineTypes { "-XX:+InlineTypeReturnedAsFields" ), new Scenario(4, + "-XX:+IgnoreUnrecognizedVMOptions", "-DVerifyIR=false", "-XX:FlatArrayElementMaxOops=-1", "-XX:FlatArrayElementMaxSize=-1", @@ -83,6 +88,7 @@ public class InlineTypes { "-XX:-ReduceInitialCardMarks" ), new Scenario(5, + "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UseACmpProfile", "-XX:+AlwaysIncrementalInline", "-XX:FlatArrayElementMaxOops=5", diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java index 130524073dc..9e8b6b05e55 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java @@ -46,14 +46,14 @@ public class TestBadFormat { public static void main(String[] args) { -// expectTestFormatException(BadNoTests.class); -// expectTestFormatException(BadArgumentsAnnotation.class); -// expectTestFormatException(BadOverloadedMethod.class); -// expectTestFormatException(BadCompilerControl.class); -// expectTestFormatException(BadWarmup.class); -// expectTestFormatException(BadBaseTests.class); -// expectTestFormatException(BadRunTests.class); -// expectTestFormatException(BadCheckTest.class); + expectTestFormatException(BadNoTests.class); + expectTestFormatException(BadArgumentsAnnotation.class); + expectTestFormatException(BadOverloadedMethod.class); + expectTestFormatException(BadCompilerControl.class); + expectTestFormatException(BadWarmup.class); + expectTestFormatException(BadBaseTests.class); + expectTestFormatException(BadRunTests.class); + expectTestFormatException(BadCheckTest.class); expectTestFormatException(BadIRAnnotations.class); expectTestFormatException(BadInnerClassTest.class); expectTestFormatException(BadCompileClassInitializer.class, BadCompileClassInitializerHelper1.class, From 2d5db906ceaef7de2fd2e6109752df9f3cfcc393 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 12 Apr 2021 19:15:24 +0200 Subject: [PATCH 106/131] Fix bug with VERIFY_IR which disabled IR verifications for scenarios, restore ClassFileInstaller, fix TestCallingConventionC1 --- .../inlinetypes/TestCallingConventionC1.java | 31 +-- test/lib/ClassFileInstaller.java | 190 +++++++++++++++++- .../hotspot/ir_framework/TestFramework.java | 23 ++- 3 files changed, 207 insertions(+), 37 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java index 74cf637f2b7..1e6ee9501ae 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java @@ -46,30 +46,31 @@ public static void main(String[] args) { final Scenario[] scenarios = { // Default: both C1 and C2 are enabled, tiered compilation enabled new Scenario(0, - "-XX:CICompilerCount=2", - "-XX:TieredStopAtLevel=4", - "-XX:+TieredCompilation"), + "-XX:CICompilerCount=2", + "-XX:TieredStopAtLevel=4", + "-XX:+TieredCompilation"), // Default: both C1 and C2 are enabled, tiered compilation enabled new Scenario(1, - "-XX:CICompilerCount=2", - "-XX:TieredStopAtLevel=4", - "-XX:+TieredCompilation", - "-XX:+StressInlineTypeReturnedAsFields"), + "-XX:CICompilerCount=2", + "-XX:TieredStopAtLevel=4", + "-XX:+TieredCompilation", + "-XX:+IgnoreUnrecognizedVMOptions", + "-XX:+StressInlineTypeReturnedAsFields"), // Same as above, but flip all the compLevel=CompLevel.C1 and compLevel=CompLevel.C2, so we test // the compliment of the above scenario. new Scenario(2, - "-XX:CICompilerCount=2", - "-XX:TieredStopAtLevel=4", - "-XX:+TieredCompilation", - "-DFlipC1C2=true"), + "-XX:CICompilerCount=2", + "-XX:TieredStopAtLevel=4", + "-XX:+TieredCompilation", + "-DFlipC1C2=true"), // Only C1. Tiered compilation disabled. new Scenario(3, - "-XX:TieredStopAtLevel=1", - "-XX:+TieredCompilation"), + "-XX:TieredStopAtLevel=1", + "-XX:+TieredCompilation"), // Only C2. new Scenario(4, - "-XX:TieredStopAtLevel=4", - "-XX:-TieredCompilation") + "-XX:TieredStopAtLevel=4", + "-XX:-TieredCompilation") }; System.gc(); // Resolve this call, to avoid C1 code patching in the test cases. diff --git a/test/lib/ClassFileInstaller.java b/test/lib/ClassFileInstaller.java index e88014b4afa..0d1335a14cd 100644 --- a/test/lib/ClassFileInstaller.java +++ b/test/lib/ClassFileInstaller.java @@ -21,7 +21,20 @@ * questions. */ -import jdk.test.lib.util.ClassFileInstaller.Manifest; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.io.ByteArrayInputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; /** * Dump a class file for a class on the class path in the current directory, or @@ -55,13 +68,112 @@ * @run driver ClassFileInstaller -jar myjar.jar sun.hotspot.WhiteBox */ public class ClassFileInstaller { - /** + /** + * You can enable debug tracing of ClassFileInstaller by running JTREG with + * jtreg -DClassFileInstaller.debug=true ... + */ + public static boolean DEBUG = Boolean.getBoolean("ClassFileInstaller.debug"); + + /** * @param args The names of the classes to dump * @throws Exception - * @deprecated use {@link jdk.test.lib.util.ClassFileInstaller} instead */ public static void main(String... args) throws Exception { - jdk.test.lib.util.ClassFileInstaller.main(args); + if (args.length > 1 && args[0].equals("-jar")) { + if (args.length < 2) { + throw new RuntimeException("Usage: ClassFileInstaller \n" + + "where possible options include:\n" + + " -jar Write to the JAR file "); + } + String jarFile = args[1]; + String[] classes = addInnerClasses(args, 2); + writeJar_impl(jarFile, null, classes); + } else { + if (DEBUG) { + System.out.println("ClassFileInstaller: Writing to " + System.getProperty("user.dir")); + } + String[] classes = addInnerClasses(args, 0); + for (String cls : classes) { + writeClassToDisk(cls); + } + } + } + + // Add commonly used inner classes that are often omitted by mistake. Currently + // we support only sun.hotspot.WhiteBox$WhiteBoxPermission. See JDK-8199290 + private static String[] addInnerClasses(String[] classes, int startIdx) { + boolean seenWB = false; + boolean seenWBInner = false; + final String wb = "sun.hotspot.WhiteBox"; + final String wbInner = "sun.hotspot.WhiteBox$WhiteBoxPermission"; + + ArrayList list = new ArrayList<>(); + + for (int i = startIdx; i < classes.length; i++) { + String cls = classes[i]; + list.add(cls); + switch (cls) { + case wb: seenWB = true; break; + case wbInner: seenWBInner = true; break; + } + } + if (seenWB && !seenWBInner) { + list.add(wbInner); + } + + String[] array = new String[list.size()]; + list.toArray(array); + return array; + } + + public static class Manifest { + private InputStream in; + + private Manifest(InputStream in) { + this.in = in; + } + + static Manifest fromSourceFile(String fileName) throws Exception { + String pathName = System.getProperty("test.src") + File.separator + fileName; + return new Manifest(new FileInputStream(pathName)); + } + + // Example: + // String manifest = "Premain-Class: RedefineClassHelper\n" + + // "Can-Redefine-Classes: true\n"; + // ClassFileInstaller.writeJar("redefineagent.jar", + // ClassFileInstaller.Manifest.fromString(manifest), + // "RedefineClassHelper"); + static Manifest fromString(String manifest) throws Exception { + return new Manifest(new ByteArrayInputStream(manifest.getBytes())); + } + + public InputStream getInputStream() { + return in; + } + } + + private static void writeJar_impl(String jarFile, Manifest manifest, String classes[]) throws Exception { + if (DEBUG) { + System.out.println("ClassFileInstaller: Writing to " + getJarPath(jarFile)); + } + + (new File(jarFile)).delete(); + FileOutputStream fos = new FileOutputStream(jarFile); + ZipOutputStream zos = new ZipOutputStream(fos); + + // The manifest must be the first or second entry. See comments in JarInputStream + // constructor and JDK-5046178. + if (manifest != null) { + writeToDisk(zos, "META-INF/MANIFEST.MF", manifest.getInputStream()); + } + + for (String cls : classes) { + writeClassToDisk(zos, cls); + } + + zos.close(); + fos.close(); } /* @@ -76,11 +188,15 @@ public static void main(String... args) throws Exception { * @build ClassFileInstaller */ public static String writeJar(String jarFile, String... classes) throws Exception { - return jdk.test.lib.util.ClassFileInstaller.writeJar(jarFile, classes); + classes = addInnerClasses(classes, 0); + writeJar_impl(jarFile, null, classes); + return getJarPath(jarFile); } public static String writeJar(String jarFile, Manifest manifest, String... classes) throws Exception { - return jdk.test.lib.util.ClassFileInstaller.writeJar(jarFile, manifest, classes); + classes = addInnerClasses(classes, 0); + writeJar_impl(jarFile, manifest, classes); + return getJarPath(jarFile); } /** @@ -101,22 +217,74 @@ public static String writeJar(String jarFile, Manifest manifest, String... class * */ public static String getJarPath(String jarFileName) { - return jdk.test.lib.util.ClassFileInstaller.getJarPath(jarFileName); + return new File(jarFileName).getAbsolutePath(); } public static void writeClassToDisk(String className) throws Exception { - jdk.test.lib.util.ClassFileInstaller.writeClassToDisk(className); + writeClassToDisk((ZipOutputStream)null, className); + } + private static void writeClassToDisk(ZipOutputStream zos, String className) throws Exception { + writeClassToDisk(zos, className, ""); } public static void writeClassToDisk(String className, String prependPath) throws Exception { - jdk.test.lib.util.ClassFileInstaller.writeClassToDisk(className, prependPath); + writeClassToDisk(null, className, prependPath); + } + private static void writeClassToDisk(ZipOutputStream zos, String className, String prependPath) throws Exception { + ClassLoader cl = ClassFileInstaller.class.getClassLoader(); + + // Convert dotted class name to a path to a class file + String pathName = className.replace('.', '/').concat(".class"); + InputStream is = cl.getResourceAsStream(pathName); + if (is == null) { + throw new RuntimeException("Failed to find " + pathName); + } + if (prependPath.length() > 0) { + pathName = prependPath + "/" + pathName; + } + writeToDisk(zos, pathName, is); } public static void writeClassToDisk(String className, byte[] bytecode) throws Exception { - jdk.test.lib.util.ClassFileInstaller.writeClassToDisk(className, bytecode); + writeClassToDisk(null, className, bytecode); + } + private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode) throws Exception { + writeClassToDisk(zos, className, bytecode, ""); } public static void writeClassToDisk(String className, byte[] bytecode, String prependPath) throws Exception { - jdk.test.lib.util.ClassFileInstaller.writeClassToDisk(className, bytecode, prependPath); + writeClassToDisk(null, className, bytecode, prependPath); + } + private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode, String prependPath) throws Exception { + // Convert dotted class name to a path to a class file + String pathName = className.replace('.', '/').concat(".class"); + if (prependPath.length() > 0) { + pathName = prependPath + "/" + pathName; + } + writeToDisk(zos, pathName, new ByteArrayInputStream(bytecode)); + } + + private static void writeToDisk(ZipOutputStream zos, String pathName, InputStream is) throws Exception { + if (DEBUG) { + System.out.println("ClassFileInstaller: Writing " + pathName); + } + if (zos != null) { + ZipEntry ze = new ZipEntry(pathName); + zos.putNextEntry(ze); + byte[] buf = new byte[1024]; + int len; + while ((len = is.read(buf))>0){ + zos.write(buf, 0, len); + } + } else { + // Create the class file's package directory + Path p = Paths.get(pathName); + if (pathName.contains("/")) { + Files.createDirectories(p.getParent()); + } + // Create the class file + Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING); + } + is.close(); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index d86e3f9ad14..50e5d9a3103 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -140,8 +140,8 @@ public class TestFramework { private static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); private static final boolean REPORT_STDOUT = Boolean.getBoolean("ReportStdout"); private final boolean VERIFY_VM = Boolean.getBoolean("VerifyVM") && Platform.isDebugBuild(); - private final boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); - private boolean shouldVerifyIR = VERIFY_IR; // Should we perform IR matching? + private boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); + private boolean shouldVerifyIR; // Should we perform IR matching? private static String lastTestVMOutput; private final Class testClass; @@ -402,7 +402,7 @@ public TestFramework addScenarios(Scenario... scenarios) { */ public void start() { installWhiteBox(); - maybeDisableIRVerification(); + maybeDisableIRVerificationCompletely(); if (scenarios == null) { try { @@ -603,26 +603,26 @@ private void installWhiteBox() { } /** - * Disable IR verification in certain cases. + * Disable IR verification completely in certain cases. */ - private void maybeDisableIRVerification() { + private void maybeDisableIRVerificationCompletely() { if (VERIFY_IR) { - shouldVerifyIR = hasIRAnnotations(); - if (!shouldVerifyIR) { + VERIFY_IR = hasIRAnnotations(); + if (!VERIFY_IR) { System.out.println("IR verification disabled due to test " + testClass + " not specifying any @IR annotations"); return; } - shouldVerifyIR = Platform.isDebugBuild() && !Platform.isInt() && !Platform.isComp(); - if (!shouldVerifyIR) { + VERIFY_IR = Platform.isDebugBuild() && !Platform.isInt() && !Platform.isComp(); + if (!VERIFY_IR) { System.out.println("IR verification disabled due to not running a debug build (required for PrintIdeal" + "and PrintOptoAssembly), running with -Xint, or -Xcomp (use warm-up of 0 instead)"); return; } // No IR verification is done if additional non-whitelisted JTreg VM or Javaoptions flag is specified. - shouldVerifyIR = onlyWhitelistedJTregVMAndJavaOptsFlags(); - if (!shouldVerifyIR) { + VERIFY_IR = onlyWhitelistedJTregVMAndJavaOptsFlags(); + if (!VERIFY_IR) { System.out.println("IR verification disabled due to using non-whitelisted JTreg VM or Javaoptions flag(s).\n"); } } @@ -707,6 +707,7 @@ private void start(Scenario scenario) { "-DScenarios and is therefore not executed."); return; } + shouldVerifyIR = VERIFY_IR; socket = TestFrameworkSocket.getSocket(); this.scenario = scenario; try { From 65ad9b618d5e2d8c9522c92d419af7e4ed17298a Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 13 Apr 2021 12:23:38 +0200 Subject: [PATCH 107/131] Fix assertDeoptimizedByCx and improve error reporting when tests throw exceptions --- .../hotspot/ir_framework/TestFramework.java | 8 ++-- .../ir_framework/TestFrameworkExecution.java | 48 +++++++++++++++---- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 50e5d9a3103..405d15751bb 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -1025,13 +1025,13 @@ public String getExceptionInfo(boolean stripRerunHint) { public static String getRerunHint() { return """ - ########################################################### + ############################################################# - To only run the failed tests use -DTest, -DExclude, and/or -DScenarios. - To also get the standard output of the test VM run with\s - -DReportStdout=true or for even more fine-grained logging - use -DVerbose=true. - ########################################################### + -DReportStdout=true or for even more fine-grained logging + use -DVerbose=true. + ############################################################# """; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 9ff56b66f17..3e91bf16106 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -27,6 +27,8 @@ import jdk.test.lib.Utils; import sun.hotspot.WhiteBox; +import java.io.PrintWriter; +import java.io.StringWriter; import java.lang.annotation.Annotation; import java.lang.reflect.*; import java.util.*; @@ -760,13 +762,24 @@ private void runTests() { // Execute tests in random order (execution sequence affects profiling) Collections.shuffle(testList); } + StringBuilder builder = new StringBuilder(); + int failures = 0; + for (AbstractTest test : testList) { if (VERBOSE) { System.out.println("Run " + test.toString()); } else if (testFilterPresent) { TestFrameworkSocket.write("Run " + test.toString(), "testfilter", true); } - test.run(); + try { + test.run(); + } catch (TestRunException e) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + builder.append(test.toString()).append(":\n").append(sw.toString()).append("\n\n"); + failures++; + } if (PRINT_TIMES || VERBOSE) { long endTime = System.nanoTime(); long duration = (endTime - startTime); @@ -788,6 +801,12 @@ private void runTests() { System.out.format("%-10s%15d ns\n", entry.getValue() + ":", entry.getKey()); } } + + if (failures > 0) { + String msg = "\n\nTest Failures (" + failures + ")\n" + + "----------------" + "-".repeat(String.valueOf(failures).length()); + throw new TestRunException(msg + "\n" + builder.toString()); + } } private boolean testFilterPresent() { @@ -827,12 +846,25 @@ static boolean isCompiledAtLevel(Method m, CompLevel compLevel) { } static void assertDeoptimizedByC1(Method m) { - TestRun.check(compiledByC1(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, - m + " should have been deoptimized by C1"); + if (notUnstableDeoptAssertion(m, CompLevel.C1)) { + TestRun.check(compiledByC1(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, + m + " should have been deoptimized by C1"); + } } static void assertDeoptimizedByC2(Method m) { - TestRun.check(compiledByC2(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, m + " should have been deoptimized by C2"); + if (notUnstableDeoptAssertion(m, CompLevel.C2)) { + TestRun.check(compiledByC2(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, + m + " should have been deoptimized by C2"); + } + } + + /** + * Some VM flags could make the deopt assertions unstable. + */ + private static boolean notUnstableDeoptAssertion(Method m, CompLevel level) { + return (USE_COMPILER && !XCOMP && !TEST_C1 && + (!EXCLUDE_RANDOM || WHITE_BOX.isMethodCompilable(m, level.getValue(), false))); } static void assertCompiledByC1(Method m) { @@ -1028,7 +1060,7 @@ final protected void waitForCompilation(DeclaredTest test) { final boolean maybeCodeBufferOverflow = (TestFrameworkExecution.TEST_C1 && VERIFY_OOPS); final long started = System.currentTimeMillis(); boolean stateCleared = false; - long elapsed = 0; + long elapsed; do { elapsed = System.currentTimeMillis() - started; int level = WHITE_BOX.getMethodCompilationLevel(testMethod); @@ -1088,7 +1120,7 @@ public BaseTest(DeclaredTest test, boolean skip) { @Override public String toString() { - return "Base Test: " + testMethod.getName(); + return "Base Test: @Test " + testMethod.getName(); } @Override @@ -1170,7 +1202,7 @@ public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecificati @Override public String toString() { - return "Checked Test - @Test: " + testMethod.getName(); + return "Checked Test: @Check " + checkMethod.getName() + " - @Test: " + testMethod.getName(); } @Override @@ -1222,7 +1254,7 @@ public CustomRunTest(Method runMethod, Warmup warmUpAnno, Run runSpecification, @Override public String toString() { - String s = "Custom Run Test - @Test"; + String s = "Custom Run Test: @Run: " + runMethod.getName() + " - @Test"; if (tests.size() == 1) { s += ": " + tests.get(0).getTestMethod().getName(); } else { From 60c06adf2f9cbb0ef7ba8eef96c71214a1998b4a Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Tue, 13 Apr 2021 18:52:18 -0700 Subject: [PATCH 108/131] Converted tests to new IR framework --- .../inlinetypes/TestLWorldProfiling.java | 830 +++++++++++------- .../inlinetypes/TestNullableInlineTypes.java | 224 ++--- .../TestUnloadedInlineTypeField.java | 171 ++-- 3 files changed, 690 insertions(+), 535 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java index 813049b4dbc..a2ba1918550 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java @@ -23,66 +23,77 @@ package compiler.valhalla.inlinetypes; -import jdk.test.lib.Asserts; import java.lang.reflect.Method; +import sun.hotspot.WhiteBox; + +import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; /* * @test * @key randomness * @summary Test inline type specific profiling - * @library /testlibrary /test/lib /compiler/whitebox / + * @library /test/lib / * @requires (os.simpleArch == "x64") - * @compile TestLWorldProfiling.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:FlatArrayElementMaxSize=-1 - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestLWorldProfiling + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestLWorldProfiling */ -public class TestLWorldProfiling extends InlineTypeTest { - - static final String[][] scenarios = { - {"-XX:-UseArrayLoadStoreProfile", - "-XX:-UseACmpProfile", - "-XX:TypeProfileLevel=0", - "-XX:-MonomorphicArrayCheck" }, - { "-XX:+UseArrayLoadStoreProfile", - "-XX:+UseACmpProfile", - "-XX:TypeProfileLevel=0" }, - { "-XX:-UseArrayLoadStoreProfile", - "-XX:-UseACmpProfile", - "-XX:TypeProfileLevel=222", - "-XX:-MonomorphicArrayCheck" }, - { "-XX:-UseArrayLoadStoreProfile", - "-XX:-UseACmpProfile", - "-XX:TypeProfileLevel=0", - "-XX:-MonomorphicArrayCheck", - "-XX:TieredStopAtLevel=4", - "-XX:-TieredCompilation" }, - { "-XX:+UseArrayLoadStoreProfile", - "-XX:+UseACmpProfile", - "-XX:TypeProfileLevel=0", - "-XX:TieredStopAtLevel=4", - "-XX:-TieredCompilation" }, - { "-XX:-UseArrayLoadStoreProfile", - "-XX:-UseACmpProfile", - "-XX:TypeProfileLevel=222", - "-XX:-MonomorphicArrayCheck", - "-XX:TieredStopAtLevel=4", - "-XX:-TieredCompilation" } - }; - - public int getNumScenarios() { - return scenarios.length; - } - - public String[] getVMParameters(int scenario) { - return scenarios[scenario]; - } - - public static void main(String[] args) throws Throwable { - TestLWorldProfiling test = new TestLWorldProfiling(); - test.run(args, MyValue1.class, MyValue2.class); + +@ForceCompileClassInitializer +public class TestLWorldProfiling { + + public static void main(String[] args) { + final Scenario[] scenarios = { + new Scenario(0, + "-XX:FlatArrayElementMaxSize=-1", + "-XX:-UseArrayLoadStoreProfile", + "-XX:-UseACmpProfile", + "-XX:TypeProfileLevel=0", + "-XX:-MonomorphicArrayCheck"), + new Scenario(1, + "-XX:FlatArrayElementMaxSize=-1", + "-XX:+UseArrayLoadStoreProfile", + "-XX:+UseACmpProfile", + "-XX:TypeProfileLevel=0"), + new Scenario(2, + "-XX:FlatArrayElementMaxSize=-1", + "-XX:-UseArrayLoadStoreProfile", + "-XX:-UseACmpProfile", + "-XX:TypeProfileLevel=222", + "-XX:-MonomorphicArrayCheck"), + new Scenario(3, + "-XX:FlatArrayElementMaxSize=-1", + "-XX:-UseArrayLoadStoreProfile", + "-XX:-UseACmpProfile", + "-XX:TypeProfileLevel=0", + "-XX:-MonomorphicArrayCheck", + "-XX:TieredStopAtLevel=4", + "-XX:-TieredCompilation"), + new Scenario(4, + "-XX:FlatArrayElementMaxSize=-1", + "-XX:+UseArrayLoadStoreProfile", + "-XX:+UseACmpProfile", + "-XX:TypeProfileLevel=0", + "-XX:TieredStopAtLevel=4", + "-XX:-TieredCompilation"), + new Scenario(5, + "-XX:FlatArrayElementMaxSize=-1", + "-XX:-UseArrayLoadStoreProfile", + "-XX:-UseACmpProfile", + "-XX:TypeProfileLevel=222", + "-XX:-MonomorphicArrayCheck", + "-XX:TieredStopAtLevel=4", + "-XX:-TieredCompilation") + }; + + InlineTypes.getFramework() + .addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class) + .start(); } private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(rI, rL); @@ -95,19 +106,31 @@ public static void main(String[] args) throws Throwable { private static final MyValue1.ref[] testValue1NotFlatArray = new MyValue1.ref[] {testValue1}; private static final MyValue1[][] testValue1ArrayArray = new MyValue1[][] {testValue1Array}; + // Wrap these variables into helper class because + // WhiteBox API needs to be initialized by TestFramework first. + static class WBFlags { + static final boolean UseACmpProfile = (Boolean) WhiteBox.getWhiteBox().getVMFlag("UseACmpProfile"); + static final boolean TieredCompilation = (Boolean) WhiteBox.getWhiteBox().getVMFlag("TieredCompilation"); + static final boolean ProfileInterpreter = (Boolean) WhiteBox.getWhiteBox().getVMFlag("ProfileInterpreter"); + static final boolean UseArrayLoadStoreProfile = (Boolean) WhiteBox.getWhiteBox().getVMFlag("UseArrayLoadStoreProfile"); + static final long TypeProfileLevel = (Long) WhiteBox.getWhiteBox().getVMFlag("TypeProfileLevel"); + } + // aaload - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, failOn = LOAD_UNKNOWN_INLINE) - @Test(valid = TypeProfileOn, failOn = LOAD_UNKNOWN_INLINE) - @Test(match = { LOAD_UNKNOWN_INLINE }, matchCount = { 1 }) + @Test + @IR(applyIfOr = {"UseArrayLoadStoreProfile", "true", "TypeProfileLevel", "= 222"}, + failOn = {LOAD_UNKNOWN_INLINE}) + @IR(applyIfAnd={"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, + counts = {LOAD_UNKNOWN_INLINE, "= 1"}) public Object test1(Object[] array) { return array[0]; } - @DontCompile - public void test1_verifier(boolean warmup) { - if (warmup) { + @Run(test = "test1") + @Warmup(10000) + public void test1_verifier(RunInfo info) { + if (info.isWarmUp()) { Object o = test1(testValue1Array); Asserts.assertEQ(((MyValue1)o).hash(), testValue1.hash()); } else { @@ -116,17 +139,19 @@ public void test1_verifier(boolean warmup) { } } - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, failOn = LOAD_UNKNOWN_INLINE) - @Test(valid = TypeProfileOn, failOn = LOAD_UNKNOWN_INLINE) - @Test(match = { LOAD_UNKNOWN_INLINE }, matchCount = { 1 }) + @Test + @IR(applyIfOr = {"UseArrayLoadStoreProfile", "true", "TypeProfileLevel", "= 222"}, + failOn = {LOAD_UNKNOWN_INLINE}) + @IR(applyIfAnd = {"UseArrayLoadStoreProfile", "false", "TypeProfileLevel", "!= 222"}, + counts = {LOAD_UNKNOWN_INLINE, "= 1"}) public Object test2(Object[] array) { return array[0]; } - @DontCompile - public void test2_verifier(boolean warmup) { - if (warmup) { + @Run(test = "test2") + @Warmup(10000) + public void test2_verifier(RunInfo info) { + if (info.isWarmUp()) { Object o = test2(testIntegerArray); Asserts.assertEQ(o, 42); } else { @@ -135,30 +160,34 @@ public void test2_verifier(boolean warmup) { } } - @Warmup(10000) - @Test(match = { LOAD_UNKNOWN_INLINE }, matchCount = { 1 }) + @Test + @IR(counts = {LOAD_UNKNOWN_INLINE, "= 1"}) public Object test3(Object[] array) { return array[0]; } - @DontCompile - public void test3_verifier(boolean warmup) { + @Run(test = "test3") + @Warmup(10000) + public void test3_verifier() { Object o = test3(testValue1Array); Asserts.assertEQ(((MyValue1)o).hash(), testValue1.hash()); o = test3(testValue2Array); Asserts.assertEQ(((MyValue2)o).hash(), testValue2.hash()); } - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, failOn = LOAD_UNKNOWN_INLINE) - @Test(match = { LOAD_UNKNOWN_INLINE }, matchCount = { 1 }) + @Test + @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, + failOn = {LOAD_UNKNOWN_INLINE}) + @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, + counts = {LOAD_UNKNOWN_INLINE, "= 1"}) public Object test4(Object[] array) { return array[0]; } - @DontCompile - public void test4_verifier(boolean warmup) { - if (warmup) { + @Run(test = "test4") + @Warmup(10000) + public void test4_verifier(RunInfo info) { + if (info.isWarmUp()) { Object o = test4(testIntegerArray); Asserts.assertEQ(o, 42); o = test4(testLongArray); @@ -169,14 +198,15 @@ public void test4_verifier(boolean warmup) { } } - @Warmup(10000) - @Test(match = { LOAD_UNKNOWN_INLINE }, matchCount = { 1 }) + @Test + @IR(counts = {LOAD_UNKNOWN_INLINE, "= 1"}) public Object test5(Object[] array) { return array[0]; } - @DontCompile - public void test5_verifier(boolean warmup) { + @Run(test = "test5") + @Warmup(10000) + public void test5_verifier() { Object o = test5(testValue1Array); Asserts.assertEQ(((MyValue1)o).hash(), testValue1.hash()); o = test5(testValue1NotFlatArray); @@ -196,19 +226,21 @@ public void test6_helper(Number[] arg) { } } - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, match = { CALL, CLASS_CHECK_TRAP, NULL_CHECK_TRAP, RANGE_CHECK_TRAP }, matchCount = { 3, 1, 1, 1 }) - @Test(valid = TypeProfileOn, match = { CALL, CLASS_CHECK_TRAP, NULL_CHECK_TRAP, RANGE_CHECK_TRAP }, matchCount = { 3, 1, 1, 1 }) - @Test(match = { CALL, RANGE_CHECK_TRAP, NULL_CHECK_TRAP }, matchCount = { 5, 1, 1 }) + @Test + @IR(applyIfOr = {"UseArrayLoadStoreProfile", "true", "TypeProfileLevel", "= 222"}, + counts = {CALL, "= 3", CLASS_CHECK_TRAP, "= 1", NULL_CHECK_TRAP, "= 1", RANGE_CHECK_TRAP, "= 1"}) + @IR(applyIfAnd = {"UseArrayLoadStoreProfile", "false", "TypeProfileLevel", "!= 222"}, + counts = {CALL, "= 5", RANGE_CHECK_TRAP, "= 1", NULL_CHECK_TRAP, "= 1"}) public Object test6(Number[] array) { Number v = array[0]; test6_helper(array); return v; } - @DontCompile - public void test6_verifier(boolean warmup) { - if (warmup) { + @Run(test = "test6") + @Warmup(10000) + public void test6_verifier(RunInfo info) { + if (info.isWarmUp()) { // pollute profile test6_helper(testLongArray); test6_helper(testDoubleArray); @@ -227,19 +259,21 @@ public void test7_helper(Number arg) { } } - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, match = { CALL, CLASS_CHECK_TRAP, NULL_CHECK_TRAP, RANGE_CHECK_TRAP }, matchCount = { 4, 1, 2, 1 }) - @Test(valid = TypeProfileOn, match = { CALL, CLASS_CHECK_TRAP, NULL_CHECK_TRAP, RANGE_CHECK_TRAP }, matchCount = { 4, 1, 2, 1 }) - @Test(match = { CALL, RANGE_CHECK_TRAP, NULL_CHECK_TRAP }, matchCount = { 6, 1, 2 }) + @Test + @IR(applyIfOr = {"UseArrayLoadStoreProfile", "true", "TypeProfileLevel", "= 222"}, + counts = {CALL, "= 4", CLASS_CHECK_TRAP, "= 1", NULL_CHECK_TRAP, "= 2", RANGE_CHECK_TRAP, "= 1"}) + @IR(applyIfAnd = {"UseArrayLoadStoreProfile", "false", "TypeProfileLevel", "!= 222"}, + counts = {CALL, "= 6", RANGE_CHECK_TRAP, "= 1", NULL_CHECK_TRAP, "= 2"}) public Object test7(Number[] array) { Number v = array[0]; test7_helper(v); return v; } - @DontCompile - public void test7_verifier(boolean warmup) { - if (warmup) { + @Run(test = "test7") + @Warmup(10000) + public void test7_verifier(RunInfo info) { + if (info.isWarmUp()) { // pollute profile test7_helper(42L); test7_helper(42.0D); @@ -258,18 +292,23 @@ public void test8_helper(Object arg) { } } - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, match = { CALL, CLASS_CHECK_TRAP, NULL_CHECK_TRAP, RANGE_CHECK_TRAP, UNHANDLED_TRAP, ALLOC_G }, matchCount = { 6, 1, 2, 1, 1, 1 }) - @Test(match = { CALL, RANGE_CHECK_TRAP, NULL_CHECK_TRAP, UNHANDLED_TRAP, ALLOC_G }, matchCount = { 6, 1, 2, 1, 1 }) + @Test + @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, + counts = {CALL, "= 6", CLASS_CHECK_TRAP, "= 1", NULL_CHECK_TRAP, "= 2", + RANGE_CHECK_TRAP, "= 1", UNHANDLED_TRAP, "= 1", ALLOC_G, "= 1"}) + @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, + counts = {CALL, "= 6", RANGE_CHECK_TRAP, "= 1", NULL_CHECK_TRAP, "= 2", + UNHANDLED_TRAP, "= 1", ALLOC_G, "= 1"}) public Object test8(Object[] array) { Object v = array[0]; test8_helper(v); return v; } - @DontCompile - public void test8_verifier(boolean warmup) { - if (warmup) { + @Run(test = "test8") + @Warmup(10000) + public void test8_verifier(RunInfo info) { + if (info.isWarmUp()) { // pollute profile test8_helper(42L); test8_helper(42.0D); @@ -280,91 +319,104 @@ public void test8_verifier(boolean warmup) { // aastore - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, failOn = STORE_UNKNOWN_INLINE) - @Test(valid = TypeProfileOn, failOn = STORE_UNKNOWN_INLINE) - @Test(match = { STORE_UNKNOWN_INLINE }, matchCount = { 1 }) + @Test + @IR(applyIfOr = {"UseArrayLoadStoreProfile", "true", "TypeProfileLevel", "= 222"}, + failOn = {STORE_UNKNOWN_INLINE}) + @IR(applyIfAnd = {"UseArrayLoadStoreProfile", "false", "TypeProfileLevel", "!= 222"}, + counts = {STORE_UNKNOWN_INLINE, "= 1"}) public void test9(Object[] array, Object v) { array[0] = v; } - @DontCompile - public void test9_verifier(boolean warmup) { + @Run(test = "test9") + @Warmup(10000) + public void test9_verifier() { test9(testValue1Array, testValue1); Asserts.assertEQ(testValue1Array[0].hash(), testValue1.hash()); } - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, failOn = STORE_UNKNOWN_INLINE) - @Test(valid = TypeProfileOn, failOn = STORE_UNKNOWN_INLINE) - @Test(match = { STORE_UNKNOWN_INLINE }, matchCount = { 1 }) + + @Test + @IR(applyIfOr = {"UseArrayLoadStoreProfile", "true", "TypeProfileLevel", "= 222"}, + failOn = {STORE_UNKNOWN_INLINE}) + @IR(applyIfAnd = {"UseArrayLoadStoreProfile", "false", "TypeProfileLevel", "!= 222"}, + counts = {STORE_UNKNOWN_INLINE, "= 1"}) public void test10(Object[] array, Object v) { array[0] = v; } - @DontCompile - public void test10_verifier(boolean warmup) { + @Run(test = "test10") + @Warmup(10000) + public void test10_verifier() { test10(testIntegerArray, 42); } - @Warmup(10000) - @Test(match = { STORE_UNKNOWN_INLINE }, matchCount = { 1 }) + @Test + @IR(counts = {STORE_UNKNOWN_INLINE, "= 1"}) public void test11(Object[] array, Object v) { array[0] = v; } - @DontCompile - public void test11_verifier(boolean warmup) { + @Run(test = "test11") + @Warmup(10000) + public void test11_verifier() { test11(testValue1Array, testValue1); test11(testValue2Array, testValue2); } - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, failOn = STORE_UNKNOWN_INLINE) - @Test(match = { STORE_UNKNOWN_INLINE }, matchCount = { 1 }) + @Test + @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, + failOn = {STORE_UNKNOWN_INLINE}) + @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, + counts = {STORE_UNKNOWN_INLINE, "= 1"}) public void test12(Object[] array, Object v) { array[0] = v; } - @DontCompile - public void test12_verifier(boolean warmup) { + @Run(test = "test12") + @Warmup(10000) + public void test12_verifier() { test12(testIntegerArray, 42); test12(testLongArray, 42L); } - @Warmup(10000) - @Test(match = { STORE_UNKNOWN_INLINE }, matchCount = { 1 }) + @Test + @IR(counts = {STORE_UNKNOWN_INLINE, "= 1"}) public void test13(Object[] array, Object v) { array[0] = v; } - @DontCompile - public void test13_verifier(boolean warmup) { + @Run(test = "test13") + @Warmup(10000) + public void test13_verifier() { test13(testValue1Array, testValue1); test13(testValue1NotFlatArray, testValue1); } + // MonomorphicArrayCheck - @Warmup(10000) @Test public void test14(Number[] array, Number v) { array[0] = v; } - @DontCompile - public void test14_verifier(boolean warmup) { - if (warmup) { + @Run(test = "test14") + @Warmup(10000) + public void test14_verifier(RunInfo info) { + if (info.isWarmUp()) { test14(testIntegerArray, 42); } else { - Method m = tests.get("TestLWorldProfiling::test14"); + Method m = info.getTest(); boolean deopt = false; for (int i = 0; i < 100; i++) { test14(testIntegerArray, 42); - if (!WHITE_BOX.isMethodCompiled(m, false)) { + if (!info.isCompilationSkipped() && !TestFramework.isCompiled(m)) { deopt = true; } } - if (deopt && !TieredCompilation && !STRESS_CC && ProfileInterpreter && (UseArrayLoadStoreProfile || TypeProfileLevel == 222)) { + + if (deopt && !WBFlags.TieredCompilation && WBFlags.ProfileInterpreter && + (WBFlags.UseArrayLoadStoreProfile || WBFlags.TypeProfileLevel == 222)) { throw new RuntimeException("Monomorphic array check should rely on profiling and be accurate"); } } @@ -384,16 +436,19 @@ primitive static class NotFlattenable { private static final NotFlattenable notFlattenable = new NotFlattenable(); private static final NotFlattenable[] testNotFlattenableArray = new NotFlattenable[] { notFlattenable }; - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, match = { NULL_CHECK_TRAP }, matchCount = { 2 }, failOn = STORE_UNKNOWN_INLINE) - @Test(valid = TypeProfileOn, match = { NULL_CHECK_TRAP }, matchCount = { 2 }, failOn = STORE_UNKNOWN_INLINE) - @Test(match = { NULL_CHECK_TRAP, STORE_UNKNOWN_INLINE }, matchCount = { 3, 1 }) + @Test + @IR(applyIfOr = {"UseArrayLoadStoreProfile", "true", "TypeProfileLevel", "= 222"}, + counts = {NULL_CHECK_TRAP, "= 2"}, + failOn = {STORE_UNKNOWN_INLINE}) + @IR(applyIfAnd = {"UseArrayLoadStoreProfile", "false", "TypeProfileLevel", "!= 222"}, + counts = {NULL_CHECK_TRAP, "= 3", STORE_UNKNOWN_INLINE, "= 1"}) public void test15(Object[] array, Object v) { array[0] = v; } - @DontCompile - public void test15_verifier(boolean warmup) { + @Run(test = "test15") + @Warmup(10000) + public void test15_verifier() { test15(testNotFlattenableArray, notFlattenable); try { test15(testNotFlattenableArray, null); @@ -403,15 +458,19 @@ public void test15_verifier(boolean warmup) { } } - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, match = { NULL_CHECK_TRAP }, matchCount = { 2 }, failOn = STORE_UNKNOWN_INLINE) - @Test(match = { NULL_CHECK_TRAP, STORE_UNKNOWN_INLINE }, matchCount = { 3, 1 }) + @Test + @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, + counts = {NULL_CHECK_TRAP, "= 2"}, + failOn = {STORE_UNKNOWN_INLINE}) + @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, + counts = {NULL_CHECK_TRAP, "= 3", STORE_UNKNOWN_INLINE, "= 1"}) public void test16(Object[] array, Object v) { array[0] = v; } - @DontCompile - public void test16_verifier(boolean warmup) { + @Run(test = "test16") + @Warmup(10000) + public void test16_verifier() { test16(testNotFlattenableArray, notFlattenable); try { test16(testNotFlattenableArray, null); @@ -422,15 +481,19 @@ public void test16_verifier(boolean warmup) { test16(testIntegerArray, 42); } - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, match = { NULL_CHECK_TRAP }, matchCount = { 1 }, failOn = STORE_UNKNOWN_INLINE) - @Test(match = { NULL_CHECK_TRAP, STORE_UNKNOWN_INLINE }, matchCount = { 3, 1 }) + @Test + @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, + counts = {NULL_CHECK_TRAP, "= 1"}, + failOn = {STORE_UNKNOWN_INLINE}) + @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, + counts = {NULL_CHECK_TRAP, "= 3", STORE_UNKNOWN_INLINE, "= 1"}) public void test17(Object[] array, Object v) { array[0] = v; } - @DontCompile - public void test17_verifier(boolean warmup) { + @Run(test = "test17") + @Warmup(10000) + public void test17_verifier() { test17(testIntegerArray, 42); test17(testIntegerArray, null); testIntegerArray[0] = 42; @@ -441,17 +504,21 @@ public void test18_helper(Object[] array, Object v) { array[0] = v; } - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, match = { NULL_CHECK_TRAP }, matchCount = { 1 }, failOn = STORE_UNKNOWN_INLINE) - @Test(match = { NULL_CHECK_TRAP, STORE_UNKNOWN_INLINE }, matchCount = { 3, 1 }) + @Test + @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, + counts = {NULL_CHECK_TRAP, "= 1"}, + failOn = {STORE_UNKNOWN_INLINE}) + @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, + counts = {NULL_CHECK_TRAP, "= 3", STORE_UNKNOWN_INLINE, "= 1"}) public Object test18(Object[] array, Object v1) { Object v2 = array[0]; test18_helper(array, v1); return v2; } - @DontCompile - public void test18_verifier(boolean warmup) { + @Run(test = "test18") + @Warmup(10000) + public void test18_verifier() { test18_helper(testValue1Array, testValue1); // pollute profile test18(testIntegerArray, 42); test18(testIntegerArray, null); @@ -461,30 +528,36 @@ public void test18_verifier(boolean warmup) { // maybe null free, not flat - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, failOn = LOAD_UNKNOWN_INLINE) - @Test(match = { LOAD_UNKNOWN_INLINE }, matchCount = { 1 }) + @Test + @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, + failOn = {LOAD_UNKNOWN_INLINE}) + @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, + counts = {LOAD_UNKNOWN_INLINE, "= 1"}) public Object test19(Object[] array) { return array[0]; } - @DontCompile - public void test19_verifier(boolean warmup) { + @Run(test = "test19") + @Warmup(10000) + public void test19_verifier() { Object o = test19(testIntegerArray); Asserts.assertEQ(o, 42); o = test19(testNotFlattenableArray); Asserts.assertEQ(o, notFlattenable); } - @Warmup(10000) - @Test(valid = ArrayLoadStoreProfileOn, failOn = STORE_UNKNOWN_INLINE) - @Test(match = { STORE_UNKNOWN_INLINE }, matchCount = { 1 }) + @Test + @IR(applyIf = {"UseArrayLoadStoreProfile", "true"}, + failOn = {STORE_UNKNOWN_INLINE}) + @IR(applyIf = {"UseArrayLoadStoreProfile", "false"}, + counts = {STORE_UNKNOWN_INLINE, "= 1"}) public void test20(Object[] array, Object o) { array[0] = o; } - @DontCompile - public void test20_verifier(boolean warmup) { + @Run(test = "test20") + @Warmup(10000) + public void test20_verifier() { test20(testIntegerArray, 42); test20(testNotFlattenableArray, notFlattenable); } @@ -492,384 +565,460 @@ public void test20_verifier(boolean warmup) { // acmp tests // branch frequency profiling causes not equal branch to be optimized out - @Warmup(10000) - @Test(failOn = SUBSTITUTABILITY_TEST) + @Test + @IR(failOn = {SUBSTITUTABILITY_TEST}) public boolean test21(Object o1, Object o2) { return o1 == o2; } - @DontCompile - public void test21_verifier(boolean warmup) { + @Run(test = "test21") + @Warmup(10000) + public void test21_verifier() { test21(42, 42); test21(testValue1, testValue1); } // Input profiled non null - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_ASSERT_TRAP }, matchCount = { 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIf = {"UseACmpProfile", "true"}, + failOn = {SUBSTITUTABILITY_TEST}, + counts = {NULL_ASSERT_TRAP, "= 1"}) + @IR(applyIf = {"UseACmpProfile", "false"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test22(Object o1, Object o2) { return o1 == o2; } - @DontCompile - public void test22_verifier(boolean warmup) { + @Run(test = "test22") + @Warmup(10000) + public void test22_verifier(RunInfo info) { test22(42, null); test22(42.0, null); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test22")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); test22(42, 42.0); - if (UseACmpProfile) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test22")); + if (WBFlags.UseACmpProfile) { + TestFramework.assertDeoptimizedByC2(m); } } } - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_ASSERT_TRAP }, matchCount = { 1}) - @Test(valid = TypeProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_ASSERT_TRAP }, matchCount = { 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIfOr = {"UseACmpProfile", "true", "TypeProfileLevel", "= 222"}, + failOn = {SUBSTITUTABILITY_TEST}, + counts = {NULL_ASSERT_TRAP, "= 1"}) + @IR(applyIfAnd = {"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test23(Object o1, Object o2) { return o1 == o2; } - @DontCompile - public void test23_verifier(boolean warmup) { + @Run(test = "test23") + @Warmup(10000) + public void test23_verifier(RunInfo info) { test23(null, 42); test23(null, 42.0); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test23")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); test23(42, 42.0); - if (UseACmpProfile || TypeProfileLevel != 0) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test23")); + if (WBFlags.UseACmpProfile || WBFlags.TypeProfileLevel != 0) { + TestFramework.assertDeoptimizedByC2(m); } } } - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_ASSERT_TRAP }, matchCount = { 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIf = {"UseACmpProfile", "true"}, + failOn = {SUBSTITUTABILITY_TEST}, + counts = {NULL_ASSERT_TRAP, "= 1"}) + @IR(applyIf = {"UseACmpProfile", "false"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test24(Object o1, Object o2) { return o1 != o2; } - @DontCompile - public void test24_verifier(boolean warmup) { + @Run(test = "test24") + @Warmup(10000) + public void test24_verifier(RunInfo info) { test24(42, null); test24(42.0, null); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test24")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); test24(42, 42.0); - if (UseACmpProfile) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test24")); + if (WBFlags.UseACmpProfile) { + TestFramework.assertDeoptimizedByC2(m); } } } - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_ASSERT_TRAP }, matchCount = { 1}) - @Test(valid = TypeProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_ASSERT_TRAP }, matchCount = { 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIfOr = {"UseACmpProfile", "true", "TypeProfileLevel", "= 222"}, + failOn = {SUBSTITUTABILITY_TEST}, + counts = {NULL_ASSERT_TRAP, "= 1"}) + @IR(applyIfAnd = {"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test25(Object o1, Object o2) { return o1 != o2; } - @DontCompile - public void test25_verifier(boolean warmup) { + @Run(test = "test25") + @Warmup(10000) + public void test25_verifier(RunInfo info) { test25(null, 42); test25(null, 42.0); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test25")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); test25(42, 42.0); - if (UseACmpProfile || TypeProfileLevel != 0) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test25")); + if (WBFlags.UseACmpProfile || WBFlags.TypeProfileLevel != 0) { + TestFramework.assertDeoptimizedByC2(m); } } } // Input profiled not inline type with known type - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_CHECK_TRAP, CLASS_CHECK_TRAP }, matchCount = { 1, 1}) - @Test(valid = TypeProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_CHECK_TRAP, CLASS_CHECK_TRAP }, matchCount = { 1, 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIfOr = {"UseACmpProfile", "true", "TypeProfileLevel", "= 222"}, + failOn = {SUBSTITUTABILITY_TEST}, + counts = {NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) + @IR(applyIfAnd = {"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test26(Object o1, Object o2) { return o1 == o2; } - @DontCompile - public void test26_verifier(boolean warmup) { + @Run(test = "test26") + @Warmup(10000) + public void test26_verifier(RunInfo info) { test26(42, 42); test26(42, 42.0); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test26")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); for (int i = 0; i < 10; i++) { test26(42.0, 42); } - if (UseACmpProfile || TypeProfileLevel != 0) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test26")); + if (WBFlags.UseACmpProfile || WBFlags.TypeProfileLevel != 0) { + TestFramework.assertDeoptimizedByC2(m); } } } - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_CHECK_TRAP, CLASS_CHECK_TRAP }, matchCount = { 1, 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIf = {"UseACmpProfile", "true"}, + failOn = {SUBSTITUTABILITY_TEST}, + counts = { NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) + @IR(applyIf = {"UseACmpProfile", "false"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test27(Object o1, Object o2) { return o1 == o2; } - @DontCompile - public void test27_verifier(boolean warmup) { + @Run(test = "test27") + @Warmup(10000) + public void test27_verifier(RunInfo info) { test27(42, 42); test27(42.0, 42); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test27")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); for (int i = 0; i < 10; i++) { test27(42, 42.0); } - if (UseACmpProfile) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test27")); + if (WBFlags.UseACmpProfile) { + TestFramework.assertDeoptimizedByC2(m); } } } - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_CHECK_TRAP, CLASS_CHECK_TRAP }, matchCount = { 1, 1}) - @Test(valid = TypeProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_CHECK_TRAP, CLASS_CHECK_TRAP }, matchCount = { 1, 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIfOr = {"UseACmpProfile", "true", "TypeProfileLevel", "= 222"}, + failOn = {SUBSTITUTABILITY_TEST}, + counts = {NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) + @IR(applyIfAnd = {"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test28(Object o1, Object o2) { return o1 != o2; } - @DontCompile - public void test28_verifier(boolean warmup) { + @Run(test = "test28") + @Warmup(10000) + public void test28_verifier(RunInfo info) { test28(42, 42); test28(42, 42.0); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test28")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); for (int i = 0; i < 10; i++) { test28(42.0, 42); } - if (UseACmpProfile || TypeProfileLevel != 0) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test28")); + if (WBFlags.UseACmpProfile || WBFlags.TypeProfileLevel != 0) { + TestFramework.assertDeoptimizedByC2(m); } } } - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_CHECK_TRAP, CLASS_CHECK_TRAP }, matchCount = { 1, 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIf = {"UseACmpProfile", "true"}, + failOn = {SUBSTITUTABILITY_TEST}, + counts = {NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) + @IR(applyIf = {"UseACmpProfile", "false"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test29(Object o1, Object o2) { return o1 != o2; } - @DontCompile - public void test29_verifier(boolean warmup) { + @Run(test = "test29") + @Warmup(10000) + public void test29_verifier(RunInfo info) { test29(42, 42); test29(42.0, 42); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test29")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); for (int i = 0; i < 10; i++) { test29(42, 42.0); } - if (UseACmpProfile) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test29")); + if (WBFlags.UseACmpProfile) { + TestFramework.assertDeoptimizedByC2(m); } } } - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST + NULL_CHECK_TRAP, match = { CLASS_CHECK_TRAP }, matchCount = { 1}) - @Test(valid = TypeProfileOn, failOn = SUBSTITUTABILITY_TEST + NULL_CHECK_TRAP, match = { CLASS_CHECK_TRAP }, matchCount = { 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIfOr = {"UseACmpProfile", "true", "TypeProfileLevel", "= 222"}, + failOn = {SUBSTITUTABILITY_TEST, NULL_CHECK_TRAP}, + counts = {CLASS_CHECK_TRAP, "= 1"}) + @IR(applyIfAnd = {"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test30(Object o1, Object o2) { return o1 == o2; } - @DontCompile - public void test30_verifier(boolean warmup) { + @Run(test = "test30") + @Warmup(10000) + public void test30_verifier(RunInfo info) { test30(42, 42); test30(42, 42.0); test30(null, 42); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test30")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); for (int i = 0; i < 10; i++) { test30(42.0, 42); } - if (UseACmpProfile || TypeProfileLevel != 0) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test30")); + if (WBFlags.UseACmpProfile || WBFlags.TypeProfileLevel != 0) { + TestFramework.assertDeoptimizedByC2(m); } } } - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST + NULL_CHECK_TRAP) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIf = {"UseACmpProfile", "true"}, + failOn = {SUBSTITUTABILITY_TEST, NULL_CHECK_TRAP}) + @IR(applyIf = {"UseACmpProfile", "false"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test31(Object o1, Object o2) { return o1 == o2; } - @DontCompile - public void test31_verifier(boolean warmup) { + @Run(test = "test31") + @Warmup(10000) + public void test31_verifier(RunInfo info) { test31(42, 42); test31(42.0, 42); test31(42, null); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test31")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); for (int i = 0; i < 10; i++) { test31(42, 42.0); } - if (UseACmpProfile) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test31")); + if (WBFlags.UseACmpProfile) { + TestFramework.assertDeoptimizedByC2(m); } } } // Input profiled not inline type with unknown type - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_CHECK_TRAP, CLASS_CHECK_TRAP }, matchCount = { 1, 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIf = {"UseACmpProfile", "true"}, + failOn = {SUBSTITUTABILITY_TEST}, + counts = {NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) + @IR(applyIf = {"UseACmpProfile", "false"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test32(Object o1, Object o2) { return o1 == o2; } - @DontCompile - public void test32_verifier(boolean warmup) { + @Run(test = "test32") + @Warmup(10000) + public void test32_verifier(RunInfo info) { test32(42, 42); test32(42, testValue1); test32(42.0, 42); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test32")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); for (int i = 0; i < 10; i++) { test32(testValue1, 42); } - if (UseACmpProfile) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test32")); + if (WBFlags.UseACmpProfile) { + TestFramework.assertDeoptimizedByC2(m); } } } - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_CHECK_TRAP, CLASS_CHECK_TRAP }, matchCount = { 1, 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIf = {"UseACmpProfile", "true"}, + failOn = {SUBSTITUTABILITY_TEST}, + counts = {NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) + @IR(applyIf = {"UseACmpProfile", "false"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test33(Object o1, Object o2) { return o1 == o2; } - @DontCompile - public void test33_verifier(boolean warmup) { + @Run(test = "test33") + @Warmup(10000) + public void test33_verifier(RunInfo info) { test33(42, 42); test33(testValue1, 42); test33(42, 42.0); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test33")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); for (int i = 0; i < 10; i++) { test33(42, testValue1); } - if (UseACmpProfile) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test33")); + if (WBFlags.UseACmpProfile) { + TestFramework.assertDeoptimizedByC2(m); } } } - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_CHECK_TRAP, CLASS_CHECK_TRAP }, matchCount = { 1, 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIf = {"UseACmpProfile", "true"}, + failOn = {SUBSTITUTABILITY_TEST}, + counts = {NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) + @IR(applyIf = {"UseACmpProfile", "false"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test34(Object o1, Object o2) { return o1 != o2; } - @DontCompile - public void test34_verifier(boolean warmup) { + @Run(test = "test34") + @Warmup(10000) + public void test34_verifier(RunInfo info) { test34(42, 42); test34(42, testValue1); test34(42.0, 42); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test34")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); for (int i = 0; i < 10; i++) { test34(testValue1, 42); } - if (UseACmpProfile) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test34")); + if (WBFlags.UseACmpProfile) { + TestFramework.assertDeoptimizedByC2(m); } } } - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { NULL_CHECK_TRAP, CLASS_CHECK_TRAP }, matchCount = { 1, 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIf = {"UseACmpProfile", "true"}, + failOn = {SUBSTITUTABILITY_TEST}, + counts = {NULL_CHECK_TRAP, "= 1", CLASS_CHECK_TRAP, "= 1"}) + @IR(applyIf = {"UseACmpProfile", "false"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test35(Object o1, Object o2) { return o1 != o2; } - @DontCompile - public void test35_verifier(boolean warmup) { + @Run(test = "test35") + @Warmup(10000) + public void test35_verifier(RunInfo info) { test35(42, 42); test35(testValue1, 42); test35(42, 42.0); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test35")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); for (int i = 0; i < 10; i++) { test35(42, testValue1); } - if (UseACmpProfile) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test35")); + if (WBFlags.UseACmpProfile) { + TestFramework.assertDeoptimizedByC2(m); } } } - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST + NULL_CHECK_TRAP, match = { CLASS_CHECK_TRAP }, matchCount = { 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIf = {"UseACmpProfile", "true"}, + failOn = {SUBSTITUTABILITY_TEST, NULL_CHECK_TRAP}, + counts = {CLASS_CHECK_TRAP, "= 1"}) + @IR(applyIf = {"UseACmpProfile", "false"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test36(Object o1, Object o2) { return o1 == o2; } - @DontCompile - public void test36_verifier(boolean warmup) { + @Run(test = "test36") + @Warmup(10000) + public void test36_verifier(RunInfo info) { test36(42, 42.0); test36(42.0, testValue1); test36(null, 42); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test36")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); for (int i = 0; i < 10; i++) { test36(testValue1, 42); } - if (UseACmpProfile) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test36")); + if (WBFlags.UseACmpProfile) { + TestFramework.assertDeoptimizedByC2(m); } } } - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST + NULL_CHECK_TRAP) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1}) + @Test + @IR(applyIf = {"UseACmpProfile", "true"}, + failOn = {SUBSTITUTABILITY_TEST, NULL_CHECK_TRAP}) + @IR(applyIf = {"UseACmpProfile", "false"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public boolean test37(Object o1, Object o2) { return o1 == o2; } - @DontCompile - public void test37_verifier(boolean warmup) { + @Run(test = "test37") + @Warmup(10000) + public void test37_verifier(RunInfo info) { test37(42.0, 42); test37(testValue1, 42.0); test37(42, null); - if (!warmup) { - assertCompiledByC2(tests.get("TestLWorldProfiling::test37")); + if (!info.isWarmUp()) { + Method m = info.getTest(); + TestFramework.assertCompiledByC2(m); for (int i = 0; i < 10; i++) { test37(42, testValue1); } - if (UseACmpProfile) { - assertDeoptimizedByC2(tests.get("TestLWorldProfiling::test37")); + if (WBFlags.UseACmpProfile) { + TestFramework.assertDeoptimizedByC2(m); } } } // Test that acmp profile data that's unused at the acmp is fed to // speculation and leverage later - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { CLASS_CHECK_TRAP }, matchCount = { 1}) - @Test(valid = TypeProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { CLASS_CHECK_TRAP }, matchCount = { 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1 }) + @Test + @IR(applyIfOr = {"UseACmpProfile", "true", "TypeProfileLevel", "= 222"}, + failOn = {SUBSTITUTABILITY_TEST}, + counts = {CLASS_CHECK_TRAP, "= 1"}) + @IR(applyIfAnd = {"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public void test38(Object o1, Object o2, Object o3) { if (o1 == o2) { test38_helper2(); @@ -885,16 +1034,20 @@ public void test38_helper(Object o1, Object o2) { public void test38_helper2() { } - @DontCompile - public void test38_verifier(boolean warmup) { + @Run(test = "test38") + @Warmup(10000) + public void test38_verifier() { test38(42, 42, 42); test38_helper(testValue1, testValue2); } - @Warmup(10000) - @Test(valid = ACmpProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { CLASS_CHECK_TRAP }, matchCount = { 1}) - @Test(valid = TypeProfileOn, failOn = SUBSTITUTABILITY_TEST, match = { CLASS_CHECK_TRAP }, matchCount = { 1}) - @Test(match = { SUBSTITUTABILITY_TEST }, matchCount = { 1 }) + + @Test + @IR(applyIfOr = {"UseACmpProfile", "true", "TypeProfileLevel", "= 222"}, + failOn = {SUBSTITUTABILITY_TEST}, + counts = {CLASS_CHECK_TRAP, "= 1"}) + @IR(applyIfAnd = {"UseACmpProfile", "false", "TypeProfileLevel", "!= 222"}, + counts = {SUBSTITUTABILITY_TEST, "= 1"}) public void test39(Object o1, Object o2, Object o3) { if (o1 == o2) { test39_helper2(); @@ -910,8 +1063,9 @@ public void test39_helper(Object o1, Object o2) { public void test39_helper2() { } - @DontCompile - public void test39_verifier(boolean warmup) { + @Run(test = "test39") + @Warmup(10000) + public void test39_verifier() { test39(42, 42, 42); test39_helper(testValue1, testValue2); } @@ -926,18 +1080,18 @@ public Object test40_access(Object[] array) { return array[0]; } - @Warmup(10000) - @Test() + @Test public Object test40(Test40Abstract[] array) { return test40_access(array); } - @DontCompile - public void test40_verifier(boolean warmup) { + @Run(test = "test40") + @Warmup(10000) + public void test40_verifier(RunInfo info) { // Make sure multiple implementors of Test40Abstract are loaded Test40Inline tmp1 = new Test40Inline(); Test40Class tmp2 = new Test40Class(); - if (warmup) { + if (info.isWarmUp()) { // Pollute profile with Object[] (exact) test40_access(new Object[1]); } else { @@ -952,18 +1106,18 @@ public void test41_access(Object[] array, Object val) { array[0] = val; } - @Warmup(10000) - @Test() + @Test public void test41(Test40Inline[] array, Object val) { test41_access(array, val); } - @DontCompile - public void test41_verifier(boolean warmup) { + @Run(test = "test41") + @Warmup(10000) + public void test41_verifier(RunInfo info) { // Make sure multiple implementors of Test40Abstract are loaded Test40Inline tmp1 = new Test40Inline(); Test40Class tmp2 = new Test40Class(); - if (warmup) { + if (info.isWarmUp()) { // Pollute profile with exact Object[] test41_access(new Object[1], new Object()); } else { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java index 98ab9441294..5db57afc5f7 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, 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 @@ -27,34 +27,36 @@ import java.lang.reflect.Method; import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; /* * @test * @key randomness * @summary Test correct handling of nullable inline types. - * @library /testlibrary /test/lib /compiler/whitebox / + * @library /test/lib / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @compile TestNullableInlineTypes.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=300 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestNullableInlineTypes + * @run driver compiler.valhalla.inlinetypes.TestNullableInlineTypes */ -public class TestNullableInlineTypes extends InlineTypeTest { - // Extra VM parameters for some test scenarios. See InlineTypeTest.getVMParameters() - @Override - public String[] getExtraVMParameters(int scenario) { - switch (scenario) { - case 3: return new String[] {"-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"}; - case 4: return new String[] {"-XX:-MonomorphicArrayCheck"}; - } - return null; - } - public static void main(String[] args) throws Throwable { - TestNullableInlineTypes test = new TestNullableInlineTypes(); - test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, Test17Value.class, Test21Value.class); +@ForceCompileClassInitializer +public class TestNullableInlineTypes { + + public static void main(String[] args) { + + Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; + scenarios[3].addFlags("-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"); + scenarios[4].addFlags("-XX:-MonomorphicArrayCheck"); + + InlineTypes.getFramework() + .addScenarios(scenarios) + .addHelperClasses(MyValue1.class, + MyValue2.class, + MyValue2Inline.class) + .start(); } static { @@ -95,8 +97,8 @@ public long test1(MyValue1.ref vt) { return result; } - @DontCompile - public void test1_verifier(boolean warmup) throws Throwable { + @Run(test = "test1") + public void test1_verifier() throws Throwable { long result = test1(null); Asserts.assertEquals(result, 0L); } @@ -113,8 +115,8 @@ public long test2(MyValue1.ref vt) { return result; } - @DontCompile - public void test2_verifier(boolean warmup) { + @Run(test = "test2") + public void test2_verifier() { long result = test2(nullField); Asserts.assertEquals(result, 0L); } @@ -134,8 +136,8 @@ public long test3() { return result; } - @DontCompile - public void test3_verifier(boolean warmup) { + @Run(test = "test3") + public void test3_verifier() { long result = test3(); Asserts.assertEquals(result, 0L); } @@ -150,8 +152,8 @@ public void test4() { } } - @DontCompile - public void test4_verifier(boolean warmup) { + @Run(test = "test4") + public void test4_verifier() { test4(); } @@ -171,8 +173,8 @@ public MyValue1.ref test5(MyValue1.ref vt) { return vt; } - @DontCompile - public void test5_verifier(boolean warmup) { + @Run(test = "test5") + public void test5_verifier() { MyValue1.ref vt = test5(nullField); Asserts.assertEquals((Object)vt, null); } @@ -199,8 +201,8 @@ public MyValue1 test6(Object obj) { return vt; } - @DontCompile - public void test6_verifier(boolean warmup) { + @Run(test = "test6") + public void test6_verifier() { MyValue1 vt = test6(null); Asserts.assertEquals(vt.hash(), testValue1.hash()); } @@ -233,8 +235,8 @@ public void test7() throws Throwable { } } - @DontCompile - public void test7_verifier(boolean warmup) throws Throwable { + @Run(test = "test7") + public void test7_verifier() throws Throwable { test7(); } @@ -248,8 +250,8 @@ public void test8() throws Throwable { } } - @DontCompile - public void test8_verifier(boolean warmup) throws Throwable { + @Run(test = "test8") + public void test8_verifier() throws Throwable { test8(); } @@ -265,8 +267,8 @@ public void test9(boolean flag1) { valueField1 = v; } - @DontCompile - public void test9_verifier(boolean warmup) { + @Run(test = "test9") + public void test9_verifier() { test9(true); try { test9(false); @@ -283,8 +285,8 @@ public void test10(boolean flag) throws Throwable { valueField1 = (MyValue1) val; } - @DontCompile - public void test10_verifier(boolean warmup) throws Throwable { + @Run(test = "test10") + public void test10_verifier() throws Throwable { test10(true); try { test10(false); @@ -301,8 +303,8 @@ public void test11(boolean flag) throws Throwable { valueField1 = (MyValue1) val; } - @DontCompile - public void test11_verifier(boolean warmup) throws Throwable { + @Run(test = "test11") + public void test11_verifier() throws Throwable { test11(false); try { test11(true); @@ -326,8 +328,8 @@ public void test12() { valueField1 = (MyValue1) test12_helper(); } - @DontCompile - public void test12_verifier(boolean warmup) { + @Run(test = "test12") + public void test12_verifier() { try { test12_cnt = 0; test12(); @@ -370,8 +372,8 @@ public void test13(A a) { valueField1 = (MyValue1) a.test13_helper(); } - @DontCompile - public void test13_verifier(boolean warmup) { + @Run(test = "test13") + public void test13_verifier() { A a = new A(); A b = new B(); A c = new C(); @@ -413,8 +415,8 @@ public void test14(MyValue1[] va, int index) { test14_inline(va, nullField, index); } - @DontCompile - public void test14_verifier(boolean warmup) { + @Run(test = "test14") + public void test14_verifier() { int index = Math.abs(rI) % 3; try { test14(testValue1Array, index); @@ -452,8 +454,8 @@ public void test15() { } } - @DontCompile - public void test15_verifier(boolean warmup) { + @Run(test = "test15") + public void test15_verifier() { test15(); } @@ -464,14 +466,14 @@ public boolean test16_dontinline(MyValue1.ref vt) { // Test c2c call passing null for an inline type @Test - @Warmup(10000) // Warmup to make sure 'test17_dontinline' is compiled public boolean test16(Object arg) throws Exception { Method test16method = getClass().getMethod("test16_dontinline", MyValue1.ref.class); return (boolean)test16method.invoke(this, arg); } - @DontCompile - public void test16_verifier(boolean warmup) throws Exception { + @Run(test = "test16") + @Warmup(10000) // Warmup to make sure 'test17_dontinline' is compiled + public void test16_verifier() throws Exception { boolean res = test16(null); Asserts.assertTrue(res); } @@ -496,8 +498,8 @@ public Test17Value test17(boolean b) { return b ? vt1 : vt2; } - @DontCompile - public void test17_verifier(boolean warmup) { + @Run(test = "test17") + public void test17_verifier() { test17(true); test17(false); } @@ -519,14 +521,14 @@ static void test18_target2(MyValue1.ref vt) { // Test passing null for an inline type @Test - @Warmup(11000) // Make sure lambda forms get compiled public void test18() throws Throwable { test18_mh1.invokeExact(nullValue); test18_mh2.invokeExact(nullValue); } - @DontCompile - public void test18_verifier(boolean warmup) { + @Run(test = "test18") + @Warmup(11000) // Make sure lambda forms get compiled + public void test18_verifier() { try { test18(); } catch (Throwable t) { @@ -549,14 +551,14 @@ static void test19_target2(MyValue1.ref vt) { // Same as test12 but with non-final mh @Test - @Warmup(11000) // Make sure lambda forms get compiled public void test19() throws Throwable { test19_mh1.invokeExact(nullValue); test19_mh2.invokeExact(nullValue); } - @DontCompile - public void test19_verifier(boolean warmup) { + @Run(test = "test19") + @Warmup(11000) // Make sure lambda forms get compiled + public void test19_verifier() { try { test19(); } catch (Throwable t) { @@ -566,13 +568,13 @@ public void test19_verifier(boolean warmup) { // Same as test12/13 but with constant null @Test - @Warmup(11000) // Make sure lambda forms get compiled public void test20(MethodHandle mh) throws Throwable { mh.invoke(null); } - @DontCompile - public void test20_verifier(boolean warmup) { + @Run(test = "test20") + @Warmup(11000) // Make sure lambda forms get compiled + public void test20_verifier() { try { test20(test18_mh1); test20(test18_mh2); @@ -618,8 +620,8 @@ public Test21Value test21(Test21Value vt) { return vt; } - @DontCompile - public void test21_verifier(boolean warmup) { + @Run(test = "test21") + public void test21_verifier() { test21(Test21Value.default); } @@ -633,8 +635,8 @@ public void test22() { valueField1 = test22_helper(); } - @DontCompile - public void test22_verifier(boolean warmup) { + @Run(test = "test22") + public void test22_verifier() { try { test22(); throw new RuntimeException("NullPointerException expected"); @@ -648,8 +650,8 @@ public void test23(MyValue1[] arr, MyValue1.ref b) { arr[0] = (MyValue1) b; } - @DontCompile - public void test23_verifier(boolean warmup) { + @Run(test = "test23") + public void test23_verifier() { MyValue1[] arr = new MyValue1[2]; MyValue1.ref b = null; try { @@ -667,8 +669,8 @@ public MyValue1 test24() { return (MyValue1) nullBox; } - @DontCompile - public void test24_verifier(boolean warmup) { + @Run(test = "test24") + public void test24_verifier() { try { test24(); throw new RuntimeException("NullPointerException expected"); @@ -682,7 +684,8 @@ public void test25_callee(MyValue1 val) { } // Test that when checkcasting from null-ok to null-free and back to null-ok we // keep track of the information that the inline type can never be null. - @Test(failOn = ALLOC + STORE) + @Test + @IR(failOn = {ALLOC, STORE}) public int test25(boolean b, MyValue1.ref vt1, MyValue1 vt2) { vt1 = (MyValue1)vt1; Object obj = b ? vt1 : vt2; // We should not allocate here @@ -690,8 +693,8 @@ public int test25(boolean b, MyValue1.ref vt1, MyValue1 vt2) { return ((MyValue1)obj).x; } - @DontCompile - public void test25_verifier(boolean warmup) { + @Run(test = "test25") + public void test25_verifier() { int res = test25(true, testValue1, testValue1); Asserts.assertEquals(res, testValue1.x); res = test25(false, testValue1, testValue1); @@ -699,25 +702,27 @@ public void test25_verifier(boolean warmup) { } // Test that chains of casts are folded and don't trigger an allocation - @Test(failOn = ALLOC + STORE) + @Test + @IR(failOn = {ALLOC, STORE}) public MyValue3 test26(MyValue3 vt) { return ((MyValue3)((Object)((MyValue3.ref)(MyValue3)((MyValue3.ref)((Object)vt))))); } - @DontCompile - public void test26_verifier(boolean warmup) { + @Run(test = "test26") + public void test26_verifier() { MyValue3 vt = MyValue3.create(); MyValue3 result = test26(vt); Asserts.assertEquals(result, vt); } - @Test(failOn = ALLOC + STORE) + @Test + @IR(failOn = {ALLOC, STORE}) public MyValue3.ref test27(MyValue3.ref vt) { return ((MyValue3.ref)((Object)((MyValue3)(MyValue3.ref)((MyValue3)((Object)vt))))); } - @DontCompile - public void test27_verifier(boolean warmup) { + @Run(test = "test27") + public void test27_verifier() { MyValue3 vt = MyValue3.create(); MyValue3 result = (MyValue3) test27(vt); Asserts.assertEquals(result, vt); @@ -738,8 +743,8 @@ public MyValue1.ref test28(MyValue1 vt, MyValue1.ref vtBox, int i) { return result; } - @DontCompile - public void test28_verifier(boolean warmup) { + @Run(test = "test28") + public void test28_verifier() { MyValue1.ref result = test28(testValue1, null, 0); Asserts.assertEquals(result, null); result = test28(testValue1, testValue1, 1); @@ -770,8 +775,8 @@ public long test29(MyValue1 vt, MyValue1.ref vtBox) { return result; } - @DontCompile - public void test29_verifier(boolean warmup) { + @Run(test = "test29") + public void test29_verifier() { long result = test29(testValue1, null); Asserts.assertEquals(result, testValue1.hash()*98); result = test29(testValue1, testValue1); @@ -795,8 +800,8 @@ public long test30() { return test30_callee(nullField); } - @DontCompile - public void test30_verifier(boolean warmup) { + @Run(test = "test30") + public void test30_verifier() { long result = test30(); Asserts.assertEquals(result, 0L); } @@ -816,8 +821,8 @@ public void test31(Object o) { } } - @DontCompile - public void test31_verifier(boolean warmup) { + @Run(test = "test31") + public void test31_verifier() { test31(null); } @@ -828,8 +833,8 @@ public MyValue1.ref test32() { return constNullField; } - @DontCompile - public void test32_verifier(boolean warmup) { + @Run(test = "test32") + public void test32_verifier() { MyValue1.ref result = test32(); Asserts.assertEquals(result, null); } @@ -853,8 +858,8 @@ public Test33Value2 test33() { return test33Val; } - @DontCompile - public void test33_verifier(boolean warmup) { + @Run(test = "test33") + public void test33_verifier() { Test33Value2 result = test33(); Asserts.assertEquals(result, test33Val); } @@ -870,10 +875,10 @@ public void test34(MyValue1 vt) { } } - @DontCompile - public void test34_verifier(boolean warmup) { + @Run(test = "test34") + public void test34_verifier(RunInfo info) { test34(testValue1); - if (!warmup) { + if (!info.isWarmUp()) { test34Val = null; test34(testValue1); Asserts.assertEquals(test34Val, testValue1); @@ -892,15 +897,16 @@ public Test17Value test35(boolean b) { return b ? vt1 : vt2; } - @DontCompile - public void test35_verifier(boolean warmup) { + @Run(test = "test35") + public void test35_verifier() { test35(true); test35(false); } // Test that when explicitly null checking an inline type, we keep // track of the information that the inline type can never be null. - @Test(failOn = ALLOC + STORE) + @Test + @IR(failOn = {ALLOC, STORE}) public int test37(boolean b, MyValue1.ref vt1, MyValue1.val vt2) { if (vt1 == null) { return 0; @@ -911,8 +917,8 @@ public int test37(boolean b, MyValue1.ref vt1, MyValue1.val vt2) { return ((MyValue1)obj).x; } - @DontCompile - public void test37_verifier(boolean warmup) { + @Run(test = "test37") + public void test37_verifier() { int res = test37(true, testValue1, testValue1); Asserts.assertEquals(res, testValue1.x); res = test37(false, testValue1, testValue1); @@ -921,7 +927,8 @@ public void test37_verifier(boolean warmup) { // Test that when explicitly null checking an inline type receiver, // we keep track of the information that the inline type can never be null. - @Test(failOn = ALLOC + STORE) + @Test + @IR(failOn = {ALLOC, STORE}) public int test38(boolean b, MyValue1.ref vt1, MyValue1.val vt2) { vt1.hash(); // Inlined - Explicit null check // vt1 should be scalarized because it's always non-null @@ -930,8 +937,8 @@ public int test38(boolean b, MyValue1.ref vt1, MyValue1.val vt2) { return ((MyValue1)obj).x; } - @DontCompile - public void test38_verifier(boolean warmup) { + @Run(test = "test38") + public void test38_verifier() { int res = test38(true, testValue1, testValue1); Asserts.assertEquals(res, testValue1.x); res = test38(false, testValue1, testValue1); @@ -940,7 +947,8 @@ public void test38_verifier(boolean warmup) { // Test that when implicitly null checking an inline type receiver, // we keep track of the information that the inline type can never be null. - @Test(failOn = ALLOC + STORE) + @Test + @IR(failOn = {ALLOC, STORE}) public int test39(boolean b, MyValue1.ref vt1, MyValue1.val vt2) { vt1.hashInterpreted(); // Not inlined - Implicit null check // vt1 should be scalarized because it's always non-null @@ -949,8 +957,8 @@ public int test39(boolean b, MyValue1.ref vt1, MyValue1.val vt2) { return ((MyValue1)obj).x; } - @DontCompile - public void test39_verifier(boolean warmup) { + @Run(test = "test39") + public void test39_verifier() { int res = test39(true, testValue1, testValue1); Asserts.assertEquals(res, testValue1.x); res = test39(false, testValue1, testValue1); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java index d5f7e803ae5..2423a301c92 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, 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 @@ -22,49 +22,42 @@ */ package compiler.valhalla.inlinetypes; + import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.rI; +import static compiler.valhalla.inlinetypes.InlineTypes.rL; +import static compiler.valhalla.inlinetypes.InlineTypes.rD; -/** +/* * @test * @key randomness - * @library /testlibrary /test/lib /compiler/whitebox / * @summary Test the handling of fields of unloaded inline classes. + * @library /test/lib / + * @requires os.simpleArch == "x64" * @compile hack/GetUnresolvedInlineFieldWrongSignature.java * @compile TestUnloadedInlineTypeField.java - * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform - * @run main/othervm/timeout=120 -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI - * compiler.valhalla.inlinetypes.InlineTypeTest - * compiler.valhalla.inlinetypes.TestUnloadedInlineTypeField + * @run driver/timeout=120 compiler.valhalla.inlinetypes.TestUnloadedInlineTypeField */ -public class TestUnloadedInlineTypeField extends InlineTypeTest { - // Only prevent loading of classes when testing with C1. Load classes +public class TestUnloadedInlineTypeField { + // The test only prevent loading of classes when testing with C1. Load classes // early when executing with C2 to prevent uncommon traps. It's still // beneficial to execute this test with C2 because it also checks handling // of type mismatches. - private static final boolean PREVENT_LOADING = TEST_C1; - - public static void main(String[] args) throws Throwable { - TestUnloadedInlineTypeField test = new TestUnloadedInlineTypeField(); - test.run(args); - } - - static final String[][] scenarios = { - {}, - {"-XX:InlineFieldMaxFlatSize=0"}, - {"-XX:+PatchALot"}, - {"-XX:InlineFieldMaxFlatSize=0", "-XX:+PatchALot"} - }; - @Override - public int getNumScenarios() { - return scenarios.length; - } + public static void main(String[] args) { + final Scenario[] scenarios = { + new Scenario(0), + new Scenario(1, "-XX:InlineFieldMaxFlatSize=0"), + new Scenario(2, "-XX:+PatchALot"), + new Scenario(3, "-XX:InlineFieldMaxFlatSize=0", + "-XX:+PatchALot") + }; - @Override - public String[] getVMParameters(int scenario) { - return scenarios[scenario]; + InlineTypes.getFramework() + .addScenarios(scenarios) + .start(); } // Test case 1: @@ -106,9 +99,9 @@ public int test1(Object holder) { } } - @DontCompile - public void test1_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test1") + public void test1_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test1(null); } else { MyValue1Holder holder = new MyValue1Holder(); @@ -151,9 +144,9 @@ public int test2(Object holder) { } } - @DontCompile - public void test2_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test2") + public void test2_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test2(null); } else { MyValue2Holder holder = new MyValue2Holder(); @@ -200,9 +193,9 @@ public int test3(Object holder) { return GetUnresolvedInlineFieldWrongSignature.test3(holder); } - @DontCompile - public void test3_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test3") + public void test3_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test3(null); } else { // Make sure klass is resolved @@ -244,10 +237,10 @@ public void test4(Object holder, MyValue4 v) { } } - @DontCompile - public void test4_verifier(boolean warmup) { + @Run(test = "test4") + public void test4_verifier(RunInfo info) { MyValue4 v = new MyValue4(rI); - if (warmup && PREVENT_LOADING) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test4(null, v); } else { MyValue4Holder holder = new MyValue4Holder(); @@ -287,9 +280,9 @@ public void test5(Object holder, Object o) { } } - @DontCompile - public void test5_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test5") + public void test5_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test5(null, null); } else { MyValue5Holder holder = new MyValue5Holder(); @@ -333,9 +326,9 @@ public int test6(int n) { } } - @DontCompile - public void test6_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test6") + public void test6_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test6(0); } else { Asserts.assertEQ(test6(rI), 2*rI); @@ -372,9 +365,9 @@ public int test7(int n) { } } - @DontCompile - public void test7_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test7") + public void test7_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test7(0); } else { Asserts.assertEQ(test7(rI), 2*rI); @@ -413,9 +406,9 @@ public int test8(boolean warmup) { } } - @DontCompile - public void test8_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test8") + public void test8_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test8(true); } else { Asserts.assertEQ(test8(false), rI); @@ -450,9 +443,9 @@ public int test9(boolean warmup) { } } - @DontCompile - public void test9_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test9") + public void test9_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test9(true); } else { Asserts.assertEQ(test9(false), rI); @@ -489,9 +482,9 @@ public void test10(Object holder) { GetUnresolvedInlineFieldWrongSignature.test10(holder); } - @DontCompile - public void test10_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test10") + public void test10_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test10(null); } else { // Make sure klass is resolved @@ -536,10 +529,10 @@ public Object test11(boolean warmup, MyValue11 v) { } } - @DontCompile - public void test11_verifier(boolean warmup) { + @Run(test = "test11") + public void test11_verifier(RunInfo info) { MyValue11 v = new MyValue11(rI); - if (warmup && PREVENT_LOADING) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test11(true, v); } else { MyValue11Holder holder = (MyValue11Holder)test11(false, v); @@ -577,9 +570,9 @@ public Object test12(boolean warmup, Object o) { } } - @DontCompile - public void test12_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test12") + public void test12_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test12(true, null); } else { MyValue12 v = new MyValue12(rI); @@ -616,9 +609,9 @@ public void test13(Object holder) { GetUnresolvedInlineFieldWrongSignature.test13(holder); } - @DontCompile - public void test13_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test13") + public void test13_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test13(null); } else { // Make sure klass is resolved @@ -662,9 +655,9 @@ public void test14(Object holder) { GetUnresolvedInlineFieldWrongSignature.test14(holder); } - @DontCompile - public void test14_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test14") + public void test14_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test14(null); } else { // Make sure klass is resolved @@ -704,9 +697,9 @@ public void test15(Object holder) { GetUnresolvedInlineFieldWrongSignature.test15(holder); } - @DontCompile - public void test15_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test15") + public void test15_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test15(null); } else { // Make sure klass is resolved @@ -741,9 +734,9 @@ public Object test16(boolean warmup) { return GetUnresolvedInlineFieldWrongSignature.test16(warmup); } - @DontCompile - public void test16_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test16") + public void test16_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test16(true); } else { // Make sure klass is resolved @@ -773,9 +766,9 @@ public Object test17(boolean warmup) { return GetUnresolvedInlineFieldWrongSignature.test17(warmup); } - @DontCompile - public void test17_verifier(boolean warmup) { - if (warmup && PREVENT_LOADING) { + @Run(test = "test17") + public void test17_verifier(RunInfo info) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test17(true); } else { // Make sure klass is resolved @@ -813,11 +806,11 @@ public int test18(int n) { } } - @DontCompile - public void test18_verifier(boolean warmup) { + @Run(test = "test18") + public void test18_verifier(RunInfo info) { // Make sure MyValue18Holder is loaded MyValue18Holder holder = new MyValue18Holder(); - if (warmup && PREVENT_LOADING) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test18(0); } else { Asserts.assertEQ(test18(rI), 2*rI); @@ -847,11 +840,11 @@ public int test19(int n) { } } - @DontCompile - public void test19_verifier(boolean warmup) { + @Run(test = "test19") + public void test19_verifier(RunInfo info) { // Make sure MyValue19Holder is loaded MyValue19Holder holder = new MyValue19Holder(); - if (warmup && PREVENT_LOADING) { + if (info.isWarmUp() && !info.isC2CompilationEnabled()) { test19(0); } else { Asserts.assertEQ(test19(rI), rI); @@ -877,8 +870,8 @@ public MyValue20 test20() { return new MyValue20(); } - @DontCompile - public void test20_verifier(boolean warmup) { + @Run(test = "test20") + public void test20_verifier(RunInfo info) { MyValue20 vt = test20(); Asserts.assertEQ(vt.obj, null); } From 1a4720b218c1888aff74b061d98f634665b2efc2 Mon Sep 17 00:00:00 2001 From: Ekaterina Pavlova Date: Tue, 13 Apr 2021 22:24:14 -0700 Subject: [PATCH 109/131] Code style fixes --- .../valhalla/inlinetypes/TestIntrinsics.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java index 7d858d1c935..4524b96bfe2 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java @@ -123,7 +123,7 @@ public void test3_verifier() { // Verify that Class::getSuperclass checks with statically known classes are folded @Test - @IR(failOn = LOADK) + @IR(failOn = {LOADK}) public boolean test4() { boolean check1 = Object.class.getSuperclass() == null; // TODO 8244562: Remove cast as workaround once javac is fixed @@ -383,7 +383,7 @@ public void test20_verifier() { protected static final String CALL_Unsafe = START + "CallStaticJava" + MID + "# Static jdk.internal.misc.Unsafe::" + END; @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public int test21(MyValue1 v) { return U.getInt(v, X_OFFSET); } @@ -413,7 +413,7 @@ public void test22_verifier() { } @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public int test23(MyValue1 v, long offset) { return U.getInt(v, offset); } @@ -428,7 +428,7 @@ public void test23_verifier() { MyValue1 test24_vt = MyValue1.createWithFieldsInline(rI, rL); @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public int test24(long offset) { return U.getInt(test24_vt, offset); } @@ -491,7 +491,7 @@ public void test26_verifier() { } @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public MyValue1 test27() { return (MyValue1)U.getReference(this, TEST27_OFFSET); } @@ -504,7 +504,7 @@ public void test27_verifier() { // Mismatched type @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public int test28(MyValue1 v) { return U.getByte(v, X_OFFSET); } @@ -522,7 +522,7 @@ public void test28_verifier() { // Wrong alignment @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public long test29(MyValue1 v) { // Read the field that's guaranteed to not be last in the // inline type so we don't read out of bounds. @@ -553,7 +553,7 @@ public void test29_verifier() { // getValue to retrieve flattened field from inline type @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public MyValue2 test30(MyValue1 v) { if (V1_FLATTENED) { return U.getValue(v, V1_OFFSET, MyValue2.val.class); @@ -583,7 +583,7 @@ public void test30_verifier() { // getValue to retrieve flattened field from object @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public MyValue1 test31() { if (TEST31_VT_FLATTENED) { return U.getValue(this, TEST31_VT_OFFSET, MyValue1.val.class); @@ -600,7 +600,7 @@ public void test31_verifier() { // putValue to set flattened field in object @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public void test32(MyValue1 vt) { if (TEST31_VT_FLATTENED) { U.putValue(this, TEST31_VT_OFFSET, MyValue1.val.class, vt); @@ -631,7 +631,7 @@ public void test32_verifier() { } // getValue to retrieve flattened field from array @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public MyValue1 test33(MyValue1[] arr) { if (TEST33_FLATTENED_ARRAY) { return U.getValue(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE, MyValue1.val.class); @@ -650,7 +650,7 @@ public void test33_verifier() { // putValue to set flattened field in array @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public void test34(MyValue1[] arr, MyValue1 vt) { if (TEST33_FLATTENED_ARRAY) { U.putValue(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE, MyValue1.val.class, vt); @@ -670,7 +670,7 @@ public void test34_verifier() { // getValue to retrieve flattened field from object with unknown // container type @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public MyValue1 test35(Object o) { if (TEST31_VT_FLATTENED) { return U.getValue(o, TEST31_VT_OFFSET, MyValue1.val.class); @@ -688,7 +688,7 @@ public void test35_verifier() { // getValue to retrieve flattened field from object at unknown // offset @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public MyValue1 test36(long offset) { if (TEST31_VT_FLATTENED) { return U.getValue(this, offset, MyValue1.val.class); @@ -706,7 +706,7 @@ public void test36_verifier() { // putValue to set flattened field in object with unknown // container @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public void test37(Object o, MyValue1 vt) { if (TEST31_VT_FLATTENED) { U.putValue(o, TEST31_VT_OFFSET, MyValue1.val.class, vt); @@ -744,7 +744,7 @@ public void test38_verifier() { } @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public MyValue1 test39(MyValue1 v) { v = U.makePrivateBuffer(v); U.putInt(v, X_OFFSET, rI); @@ -1058,7 +1058,7 @@ public void test54_verifier() { // Same as test30 but with constant field holder @Test - @IR(failOn = CALL_Unsafe) + @IR(failOn = {CALL_Unsafe}) public MyValue2 test55() { if (V1_FLATTENED) { return U.getValue(test55_vt, V1_OFFSET, MyValue2.val.class); From d9de2f9e4a4141a9393a23e29afd35f558068698 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 14 Apr 2021 13:21:09 +0200 Subject: [PATCH 110/131] Cleanup Javadocs and README file, fix TestUnloadedInlineTypeField --- .../TestUnloadedInlineTypeField.java | 8 +- .../lib/hotspot/ir_framework/Arguments.java | 3 + .../jdk/test/lib/hotspot/ir_framework/IR.java | 7 +- .../lib/hotspot/ir_framework/IRMatcher.java | 4 +- .../test/lib/hotspot/ir_framework/IRNode.java | 2 +- .../hotspot/ir_framework/TestFramework.java | 18 +- .../ir_framework/TestFrameworkExecution.java | 175 +++++++++++++----- .../TestFrameworkPrepareFlags.java | 6 +- .../examples/BaseTestExample.java | 8 +- .../examples/CustomRunTestExample.java | 10 +- .../ir_framework/examples/IRExample.java | 6 +- .../lib/hotspot/ir_framework/tests/README.md | 3 + .../ir_framework/tests/TestDFlags.java | 3 + .../ir_framework/tests/TestDScenarios.java | 4 +- .../ir_framework/tests/TestRunTests.java | 4 +- 15 files changed, 185 insertions(+), 76 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java index 2423a301c92..27b2e58ebfb 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java @@ -50,9 +50,11 @@ public static void main(String[] args) { final Scenario[] scenarios = { new Scenario(0), new Scenario(1, "-XX:InlineFieldMaxFlatSize=0"), - new Scenario(2, "-XX:+PatchALot"), - new Scenario(3, "-XX:InlineFieldMaxFlatSize=0", - "-XX:+PatchALot") + new Scenario(2, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-XX:+PatchALot"), + new Scenario(3, + "-XX:InlineFieldMaxFlatSize=0", + "-XX:+IgnoreUnrecognizedVMOptions", + "-XX:+PatchALot") }; InlineTypes.getFramework() diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java index 7e2e3e37e2f..64e73b83a7f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java @@ -36,5 +36,8 @@ */ @Retention(RetentionPolicy.RUNTIME) public @interface Arguments { + /** + * Get the argument value. + */ Argument[] value(); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java index 0c3afe51944..d2d2446c939 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java @@ -39,13 +39,15 @@ * for the specified amount in {@code count} on the {@code PrintIdeal} or {@code PrintOptoAssembly} output. * * An IR rule must specify either or both of these two checks. If one or both of the checks fails, an - * {@link IRViolationException} is thrown. + * {@link IRViolationException} is thrown. A user can provide a custom regex string or specify any of the default node + * regexes defined in {@link IRNode}. *

    * Sometimes, the shape of the resulting IR is changed by commonly used VM flags in such a way that an IR rule no longer * applies. Generally, the framework does not apply any IR rules when any of the following flags are used: * {@code -Xint, -XX:-UseCompiler, -XX:TieredStopAtLevel={1,2,3}, -DExcludeRandom=true, -DFlipC1C2=true}. * Furthermore, a JTreg test could be run with additional VM and Javaoptions flags. The IR verification is not - * performed if any flag is used that is not part of the whitelist specified by {@link TestFramework#JTREG_WHITELIST_FLAGS}. + * performed in this case if any of these JTreg flags is used that is not part of the whitelist specified by + * {@link TestFramework#JTREG_WHITELIST_FLAGS}. *

    * For any other flag specified either by user code (e.g. {@link Scenario#Scenario(int, String...)}, * {@link TestFramework#runWithFlags(String...) etc.} or as part of the JTreg whitelist, IR verification is applied. @@ -58,6 +60,7 @@ * and also as part of the internal testing in {@link jdk.test.lib.hotspot.ir_framework.tests.TestIRMatching}. * * @see Test + * @see IRNode */ @Retention(RetentionPolicy.RUNTIME) @Repeatable(IRs.class) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java index c91eb846966..0cafa5f164d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java @@ -57,7 +57,9 @@ public IRMatcher(String hotspotPidFileName, String irEncoding, Class testClas applyRules(); } - + /** + * Sets up a map testname -> IRMethod (containing the PrintIdeal and PrintOptoAssembly output for testname). + */ private void setupTestMethods(String irEncoding) { Map irRulesMap = parseIREncoding(irEncoding); for (Method m : testClass.getDeclaredMethods()) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java index fec15dd27ca..972030a46ab 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java @@ -32,7 +32,7 @@ *

    * There are two types of default regexes: *

      - *
    • Standalone regexes: Use them directly. + *

    • Standalone regexes: Use them directly.

    • *
    • Composite regexes: Their names contain "{@code _OF}" and expect another string in a list in * {@link IR#failOn()} and {@link IR#counts()}. They cannot be use as standalone regex and will result in a * {@link TestFormatException} when doing so.

    • diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 405d15751bb..cf19284fc2f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -42,8 +42,8 @@ /** * This class represents the main entry point to the test framework whose main purpose is to perform regex-based checks on - * the IR shape emitted by the VM flags {@code -XX:+PrintIdeal} and {@code -XX:+PrintOptoAssembly}. The framework can also - * be used for other non-IR matching (and non-compiler) tests by providing easy to use annotations for commonly used + * the C2 IR shape emitted by the VM flags {@code -XX:+PrintIdeal} and {@code -XX:+PrintOptoAssembly}. The framework can + * also be used for other non-IR matching (and non-compiler) tests by providing easy to use annotations for commonly used * testing patterns and compiler control flags. *

      * The framework offers various annotations to control how your test code should be invoked and being checked. There are @@ -628,6 +628,11 @@ private void maybeDisableIRVerificationCompletely() { } } + /** + * For scenarios: Run the tests with the scenario settings and collect all exceptions to be able to run all + * scenarios without prematurely throwing an exception. Format violations, however, are wrong for all scenarios + * and thus is reported immediately on the first scenario execution. + */ private void startWithScenarios() { Map exceptionMap = new TreeMap<>(Comparator.comparingInt(Scenario::getIndex)); Set scenarioIndices = new HashSet<>(); @@ -683,6 +688,7 @@ private void reportScenarioFailures(Map exceptionMap) { } System.err.println(builder.toString()); if (!VERBOSE && !REPORT_STDOUT && !TESTLIST && !EXCLUDELIST) { + // Provide a hint to the user how to get additional output/debugging information. System.err.println(JVMOutput.getRerunHint()); } TestRun.fail(failedScenarios + ". Please check stderr for more information."); @@ -1089,6 +1095,9 @@ public void start() { socketThread.start(); } + /** + * Waits for client sockets (created by flag or test VM) to connect. Return the messages received by the clients. + */ private FutureTask initSocketTask() { return new FutureTask<>(() -> { try (Socket clientSocket = serverSocket.accept(); @@ -1121,6 +1130,7 @@ public void close() { public static void write(String msg, String type) { write(msg, type, false); } + /** * Only called by flag and test VM to write to server socket. */ @@ -1132,6 +1142,8 @@ public static void write(String msg, String type, boolean stdout) { TestFramework.check(SERVER_PORT != -1, "Server port was not set correctly for flag and/or test VM " + "or method not called from flag or test VM"); try { + // Keep the client socket open until the flag or test VM terminates (calls closeClientSocket before exiting + // main()). if (clientSocket == null) { clientSocket = new Socket(HOSTNAME, SERVER_PORT); clientWriter = new PrintWriter(clientSocket.getOutputStream(), true); @@ -1141,6 +1153,8 @@ public static void write(String msg, String type, boolean stdout) { } clientWriter.println(msg); } catch (Exception e) { + // When the test VM is directly run, we should ignore all messages that would normally be sent to the + // driver VM. String failMsg = """ ########################################################### diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 3e91bf16106..3e9422d32d0 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -96,11 +96,11 @@ assertions from main() of your test! private static final boolean FLIP_C1_C2 = Boolean.getBoolean("FlipC1C2"); private final HashMap declaredTests = new HashMap<>(); - private final List allTests = new ArrayList<>(); // Keep order + private final List allTests = new ArrayList<>(); private final HashMap testMethodMap = new HashMap<>(); private final List excludeList; private final List testList; - private Set> helperClasses = null; + private Set> helperClasses = null; // Helper classes that contain framework annotations to be processed. private final IREncodingPrinter irMatchRulePrinter; private final Class testClass; private final Map forceCompileMap = new HashMap<>(); @@ -118,6 +118,9 @@ private TestFrameworkExecution(Class testClass) { } } + /** + * Parse "test1,test2,test3" into a list. + */ private static List createTestFilterList(String list, Class testClass) { List filterList = null; if (!list.isEmpty()) { @@ -138,6 +141,9 @@ private static List createTestFilterList(String list, Class testClass return filterList; } + /** + * Main entry point of the test VM. + */ public static void main(String[] args) { try { String testClassName = args[0]; @@ -164,6 +170,9 @@ protected static Class getClassObject(String className, String classType) { return c; } + /** + * Set up all helper classes and verify they are specified correctly. + */ private void addHelperClasses(String[] args) { Class[] helperClasses = getHelperClasses(args); if (helperClasses != null) { @@ -195,22 +204,6 @@ private static Class[] getHelperClasses(String[] args) { return helperClasses; } - // Only called by internal tests testing the framework itself. Accessed by reflection. Not exposed to normal users. - private static void runTestsOnSameVM(Class testClass) { - if (testClass == null) { - StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - testClass = walker.getCallerClass(); - } - TestFrameworkExecution framework = new TestFrameworkExecution(testClass); - framework.start(); - } - - private void start() { - parseTests(); - checkForcedCompilationsCompleted(); - runTests(); - } - private void checkHelperClass(Class clazz) { checkAnnotationsInClass(clazz, "helper"); for (Class c : clazz.getDeclaredClasses()) { @@ -230,16 +223,39 @@ private void checkAnnotationsInClass(Class c, String clazzType) { } } - private void parseTests() { + /** + * Only called by internal tests testing the framework itself. Accessed by reflection. Not exposed to normal users. + */ + private static void runTestsOnSameVM(Class testClass) { + if (testClass == null) { + StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + testClass = walker.getCallerClass(); + } + TestFrameworkExecution framework = new TestFrameworkExecution(testClass); + framework.start(); + } + + /** + * Once everything is initialized and set up, start collecting tests and executing them afterwards. + */ + private void start() { + setupTests(); + checkForcedCompilationsCompleted(); + runTests(); + } + + private void setupTests() { for (Class clazz : testClass.getDeclaredClasses()) { checkAnnotationsInClass(clazz, "inner"); } - addReplay(); - // Make sure to first parse tests and make them non-inlineable and only then process compile commands. - setupTests(); + if (DUMP_REPLAY) { + addReplay(); + } + // Make sure to first setup test methods and make them non-inlineable and only then process compile commands. + setupDeclaredTests(); processControlAnnotations(testClass); processHelperClasses(); - setupCheckAndRunMethods(); + setupCheckedAndCustomRunTests(); // All remaining tests are simple base tests without check or specific way to run them. addBaseTests(); @@ -283,12 +299,12 @@ private boolean shouldExcludeTest(String testName) { return false; } + /** + * Generate replay compilation files. + */ private void addReplay() { - if (DUMP_REPLAY) { - // Generate replay compilation files - String directive = "[{ match: \"*.*\", DumpReplay: true }]"; - TestFramework.check(WHITE_BOX.addCompilerDirective(directive) == 1, "Failed to add DUMP_REPLAY directive"); - } + String directive = "[{ match: \"*.*\", DumpReplay: true }]"; + TestFramework.check(WHITE_BOX.addCompilerDirective(directive) == 1, "Failed to add DUMP_REPLAY directive"); } private void processControlAnnotations(Class clazz) { @@ -435,7 +451,10 @@ private void checkCompilationCommandAnnotations(Executable ex, ForceInline force } } - private void dontCompileMethod(Method m) { + /** + * Exlude the method from compilation and make sure it is not inlined. + */ + private void dontCompileAndDontInlineMethod(Method m) { WHITE_BOX.makeMethodNotCompilable(m, CompLevel.ANY.getValue(), true); WHITE_BOX.makeMethodNotCompilable(m, CompLevel.ANY.getValue(), false); WHITE_BOX.testSetDontInlineMethod(m, true); @@ -484,7 +503,11 @@ static void enqueueForCompilation(Executable ex, CompLevel requestedCompLevel) { } } - private void setupTests() { + /** + * Setup @Test annotated method an add them to the declaredTests map to have a convenient way of accessing them + * once setting up a framework test (base checked, or custom run test). + */ + private void setupDeclaredTests() { for (Method m : testClass.getDeclaredMethods()) { Test testAnno = getAnnotation(m, Test.class); try { @@ -548,7 +571,9 @@ private void checkTestAnnotations(Method m, Test testAnno) { } - // Get the appropriate level as permitted by the test scenario and VM options. + /** + * Get the appropriate level as permitted by the test scenario and VM flags. + */ private static CompLevel restrictCompLevel(CompLevel compLevel) { if (!USE_COMPILER) { return CompLevel.SKIP; @@ -578,6 +603,10 @@ private static CompLevel flipCompLevel(CompLevel compLevel) { return compLevel; } + /** + * Verify that the helper classes do not contain illegal framework annotations and then apply the actions as + * specified by the different helper class annotations. + */ private void processHelperClasses() { if (helperClasses != null) { for (Class helperClass : helperClasses) { @@ -590,13 +619,18 @@ private void processHelperClasses() { } } - private void setupCheckAndRunMethods() { + /** + * First set up checked (with @Check) and custom run tests (with @Run). All remaining unmatched/unused @Test methods + * are treated as base tests and set up as such later. + */ + private void setupCheckedAndCustomRunTests() { for (Method m : testClass.getDeclaredMethods()) { Check checkAnno = getAnnotation(m, Check.class); Run runAnno = getAnnotation(m, Run.class); Arguments argumentsAnno = getAnnotation(m, Arguments.class); try { - TestFormat.check(argumentsAnno == null || (checkAnno == null && runAnno == null), "Cannot have @Argument annotation in combination with @Run or @Check at " + m); + TestFormat.check(argumentsAnno == null || (checkAnno == null && runAnno == null), + "Cannot have @Argument annotation in combination with @Run or @Check at " + m); if (checkAnno != null) { addCheckedTest(m, checkAnno, runAnno); } else if (runAnno != null) { @@ -608,18 +642,21 @@ private void setupCheckAndRunMethods() { } } + /** + * Set up a checked test by first verifying the correct format of the @Test and @Check method and then adding it + * to the allTests list which keeps track of all framework tests that are eventually executed. + */ private void addCheckedTest(Method m, Check checkAnno, Run runAnno) { Method testMethod = testMethodMap.get(checkAnno.test()); DeclaredTest test = declaredTests.get(testMethod); checkCheckedTest(m, checkAnno, runAnno, testMethod, test); test.setAttachedMethod(m); CheckedTest.Parameter parameter = getCheckedTestParameter(m, testMethod); - dontCompileMethod(m); - // Don't inline check methods - WHITE_BOX.testSetDontInlineMethod(m, true); + dontCompileAndDontInlineMethod(m); CheckedTest checkedTest = new CheckedTest(test, m, checkAnno, parameter, shouldExcludeTest(testMethod.getName())); allTests.add(checkedTest); if (PRINT_VALID_IR_RULES) { + // Only need to emit IR verification information if IR verification is actually performed. irMatchRulePrinter.emitRuleEncoding(m, checkedTest.isSkipped()); } } @@ -634,6 +671,9 @@ private void checkCheckedTest(Method m, Check checkAnno, Run runAnno, Method tes "Cannot use @Test " + testMethod + " for more than one @Run or one @Check method. Found: " + m + ", " + attachedMethod); } + /** + * Only allow parameters as specified in {@link Check}. + */ private CheckedTest.Parameter getCheckedTestParameter(Method m, Method testMethod) { boolean firstParameterTestInfo = m.getParameterCount() > 0 && m.getParameterTypes()[0].equals(TestInfo.class); boolean secondParameterTestInfo = m.getParameterCount() > 1 && m.getParameterTypes()[1].equals(TestInfo.class); @@ -657,6 +697,10 @@ private CheckedTest.Parameter getCheckedTestParameter(Method m, Method testMetho return parameter; } + /** + * Set up a custom run test by first verifying the correct format of the @Test and @Run method and then adding it + * to the allTests list which keeps track of all framework tests that are eventually executed. + */ private void addCustomRunTest(Method m, Run runAnno) { checkRunMethod(m, runAnno); List tests = new ArrayList<>(); @@ -677,9 +721,7 @@ private void addCustomRunTest(Method m, Run runAnno) { if (tests.isEmpty()) { return; // There was a format violation. Return. } - dontCompileMethod(m); - // Don't inline run methods - WHITE_BOX.testSetDontInlineMethod(m, true); + dontCompileAndDontInlineMethod(m); CustomRunTest customRunTest = new CustomRunTest(m, getAnnotation(m, Warmup.class), runAnno, tests, shouldExcludeTest); allTests.add(customRunTest); if (PRINT_VALID_IR_RULES) { @@ -687,6 +729,9 @@ private void addCustomRunTest(Method m, Run runAnno) { } } + /** + * Only allow parameters as specified in {@link Run}. + */ private void checkCustomRunTest(Method m, String testName, Method testMethod, DeclaredTest test, RunMode runMode) { TestFormat.check(testMethod != null, "Did not find associated @Test method \"" + m.getDeclaringClass().getName() + "." + testName + "\" specified in @Run at " + m); @@ -723,6 +768,10 @@ private static T getAnnotation(AnnotatedElement element, return Arrays.stream(annos).findFirst().orElse(null); } + /** + * Ensure that all compilations that were enforced (added to compilation queue) by framework annotations are + * completed. Wait if necessary for a short amount of time for their completion. + */ private void checkForcedCompilationsCompleted() { if (forceCompileMap.isEmpty()) { return; @@ -744,14 +793,19 @@ private void checkForcedCompilationsCompleted() { TestRun.fail("Could not force compile the following @ForceCompile methods:\n" + builder.toString()); } + /** + * Once all framework tests are collected, they are run in this method. + */ private void runTests() { TreeMap durations = (PRINT_TIMES || VERBOSE) ? new TreeMap<>() : null; long startTime = System.nanoTime(); List testList; boolean testFilterPresent = testFilterPresent(); if (testFilterPresent) { + // Only run the specified tests by the user filters -DTest and/or -DExclude. testList = allTests.stream().filter(test -> !test.isSkipped()).collect(Collectors.toList()); if (testList.isEmpty()) { + // Throw an exception to inform the user about an empty specified test set with -DTest and/or -DExclude throw new NoTestsRunException(); } } else { @@ -759,12 +813,14 @@ private void runTests() { } if (SHUFFLE_TESTS) { - // Execute tests in random order (execution sequence affects profiling) + // Execute tests in random order (execution sequence affects profiling). This is done by default. Collections.shuffle(testList); } StringBuilder builder = new StringBuilder(); int failures = 0; + // Execute all tests and keep track of each exception that is thrown. These are then reported once all tests + // are executing. This prevents a premature exit without running all tests. for (AbstractTest test : testList) { if (VERBOSE) { System.out.println("Run " + test.toString()); @@ -795,7 +851,7 @@ private void runTests() { } // Print execution times - if (PRINT_TIMES) { + if (VERBOSE || PRINT_TIMES) { System.out.println("\n\nTest execution times:"); for (Map.Entry entry : durations.entrySet()) { System.out.format("%-10s%15d ns\n", entry.getValue() + ":", entry.getKey()); @@ -803,6 +859,7 @@ private void runTests() { } if (failures > 0) { + // Finally, report all occurred exceptions in a nice format. String msg = "\n\nTest Failures (" + failures + ")\n" + "----------------" + "-".repeat(String.valueOf(failures).length()); throw new TestRunException(msg + "\n" + builder.toString()); @@ -927,7 +984,9 @@ private static TriState compiledAtLevel(Method m, CompLevel level) { } } - +/** + * Abstract super class for base, checked and custom run tests. + */ abstract class AbstractTest { protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); protected static final int TEST_COMPILATION_TIMEOUT = Integer.parseInt(System.getProperty("TestCompilationTimeout", "10000")); @@ -948,10 +1007,16 @@ protected boolean shouldCompile(DeclaredTest test) { abstract String getName(); + /** + * Should test be executed? + */ public boolean isSkipped() { return skip; } + /** + * See {@link CompLevel#WAIT_FOR_COMPILATION}. + */ protected static boolean isWaitForCompilation(DeclaredTest test) { return test.getCompLevel() == CompLevel.WAIT_FOR_COMPILATION; } @@ -975,7 +1040,7 @@ protected static Object createInvocationTarget(Method method) { } /** - * Run the associated test + * Run the associated test. */ public void run() { if (skip) { @@ -987,12 +1052,12 @@ public void run() { } onWarmupFinished(); compileTest(); - // Always run method. + // Always run the test as a last step of the test execution. invokeTest(); } protected void onStart() { - // Do nothing by default + // Do nothing by default. } abstract protected void invokeTest(); @@ -1022,7 +1087,8 @@ protected void compileMethod(DeclaredTest test) { if (!WHITE_BOX.isMethodQueuedForCompilation(testMethod)) { if (elapsed > 0) { if (TestFrameworkExecution.VERBOSE) { - System.out.println(testMethod + " is not in queue anymore due to compiling it simultaneously on a different level. Enqueue again."); + System.out.println(testMethod + " is not in queue anymore due to compiling it simultaneously on " + + "a different level. Enqueue again."); } enqueueMethodForCompilation(test); } @@ -1084,6 +1150,9 @@ final protected void waitForCompilation(DeclaredTest test) { TestRun.fail(testMethod + " not compiled after waiting for " + WAIT_FOR_COMPILATION_TIMEOUT/1000 + " s"); } + /** + * If it takes too long, try to disable Verify Oops. + */ private void retryDisabledVerifyOops(Method testMethod, boolean stateCleared) { System.out.println("Temporarily disabling VerifyOops"); try { @@ -1099,7 +1168,9 @@ private void retryDisabledVerifyOops(Method testMethod, boolean stateCleared) { } } - +/** + * A base test only consists of a single @Test method. See {@link Test} for more details and its precise definition. + */ class BaseTest extends AbstractTest { private final DeclaredTest test; protected final Method testMethod; @@ -1173,7 +1244,10 @@ protected void compileTest() { public void verify(Object result) { /* no verification in BaseTests */ } } - +/** + * A checked test is an extension of a base test with additional verification done in a @Check method. + * See {@link Check} for more details and its precise definition. + */ class CheckedTest extends BaseTest { private final Method checkMethod; private final CheckAt checkAt; @@ -1232,7 +1306,10 @@ public void verify(Object result) { } } - +/** + * A custom run test allows the user to have full control over how the @Test method is invoked by specifying + * a dedicated @Run method. See {@link Run} for more details and its precise definition. + */ class CustomRunTest extends AbstractTest { private final Method runMethod; private final RunMode mode; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java index 903a2475d52..ac26ba8784e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java @@ -23,13 +23,10 @@ package jdk.test.lib.hotspot.ir_framework; -import jdk.test.lib.Platform; -import jdk.test.lib.management.InputArguments; import sun.hotspot.WhiteBox; import java.util.ArrayList; import java.util.Arrays; -import java.util.function.Predicate; /** * This class' main method is called from {@link TestFramework} and represents the so-called "flag VM". It uses the @@ -65,6 +62,9 @@ private static String[] getPrintFlags() { return new String[] {"-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions"}; } + /** + * Main entry point of the flag VM. + */ public static void main(String[] args) { try { String testClassName = args[0]; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java index 263376a1c72..b429803f4f9 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java @@ -43,13 +43,13 @@ * * Configurable things for simple tests (no @Run or @Check) at @Test method: *

        - *
      • compLevel: Specify at which compilation level the test should be compiled by the framework at step (**). + *

      • compLevel: Specify at which compilation level the test should be compiled by the framework at step (**).

      • * If {@link CompLevel#WAIT_FOR_COMPILATION} is specified, the framework will continue invoke the * method until HotSpot compiles it. If it is not compiled after 10s, an exception is thrown. - *
      • @Warmup: Change warm-up iterations of test (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS) + *

      • @Warmup: Change warm-up iterations of test (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS)

      • *
      • @Arguments: If a @Test method specifies arguments, you need to provide arguments by using @Arguments such - * that the framework knows how to call the method. If you need more complex values, use @Run. - *

      • @IR: Arbitrary number of @IR rules. + * that the framework knows how to call the method. If you need more complex values, use @Run.

      • + *
      • @IR: Arbitrary number of @IR rules.

      • *
      * * @see Test diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java index 273bbc9c056..001622fc40d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java @@ -40,7 +40,7 @@ * invoking a @Test method will result in an -Xcomp like compilation of the method as there is no profile * information for it. The @Run method can do any arbitrary argument setup and return value verification and * can invoke the @Test methods multiple times in a single invocation of the @Run method or even skip some - * test invocations. + * test invocations. *
    • After the warm-up, the @Test methods are compiled (there can be multiple @Test methods).

    • *
    • Invoke the @Run method once again.

    • * @@ -57,14 +57,14 @@ *
    • At @Run method:

    • *
        *
      • @Warmup: Change warm-up iterations of @Run method (defined by default by - * TestFrameworkExecution.WARMUP_ITERATIONS) - *

      • {@link Run#test}: Specify any number of @Test methods. They cannot be shared with other @Check or - * @Run methods. + * TestFrameworkExecution.WARMUP_ITERATIONS)

      • + *
      • {@link Run#test}: Specify any number of @Test methods. They cannot be shared with other @Check or @Run + * methods.

      • *
      • {@link Run#mode}: Choose between normal invocation as described above or {@link RunMode#STANDALONE}. * STANDALONE only invokes the @Run method once without warm-up or a compilation by the * Test Framework. The only thing done by the framework is the verification of any @IR * rules afterwards. The STANDALONE @Run method needs to make sure that a C2 compilation - * is reliably triggered if there are any @IR rules. + * is reliably triggered if there are any @IR rules.

      • *
      • No @IR annotations

      • *
      *
    diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java index b09abf73a63..7268f6884f3 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java @@ -81,7 +81,6 @@ public static void main(String[] args) { TestFramework.run(FailingExamples.class); // Secondly, run tests from FailingExamples } catch (IRViolationException e) { // Expected. Check output to see how IR failures are reported. - throw e; } } @@ -93,6 +92,11 @@ public static void main(String[] args) { // Rule with special configurable default regexes. All regexes with a "_OF" postfix in IR node expect a // second string specifying an additional required information. @IR(failOn = {IRNode.STORE_OF_FIELD, "iFld2", IRNode.LOAD, IRNode.STORE_OF_CLASS, "Foo"}) + // Only apply this rule if the VM flag UseZGC is true + @IR(applyIf = {"UseZGC", "true"}, failOn = IRNode.LOAD) + // We can also use comparators (<, <=, >, >=, !=, =) to restrict the rules. + // This rule is only applied if the loop unroll limit is 10 or greater. + @IR(applyIf = {"LoopUnrollLimit", ">= 10"}, failOn = IRNode.LOAD) public void goodFailOn() { iFld = 42; // No load, no loop, no store to iFld2, no store to class Foo } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/README.md b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/README.md index 83dd2b98b59..6837bdf8802 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/README.md +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/README.md @@ -2,3 +2,6 @@ This folder contains tests which test the functionality of the framework. These should be run with JTreg and without additional VM and Javaopts flags whenever the framework is modified. These tests are not part of the normal tier testing as they only should be run when the framework is changed in any way. + +Additional testing should be performed with the converted Valhalla tests (see [JDK-8263024](https://bugs.openjdk.java.net/browse/JDK-8263024)) to make sure a changeset is correct (these are part of the Valhalla CI). + diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDFlags.java index 077fb36845d..46ea62cb38d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDFlags.java @@ -39,6 +39,9 @@ * @run main/othervm -DShuffleTests=false jdk.test.lib.hotspot.ir_framework.tests.TestDFlags * @run main/othervm -DReproduce=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags * @run main/othervm -DReportStdout=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags + * @run main/othervm -DGCAfter=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags + * @run main/othervm -DPrintTimes=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags + * @run main/othervm -DVerifyIR=false jdk.test.lib.hotspot.ir_framework.tests.TestDFlags */ public class TestDFlags { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDScenarios.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDScenarios.java index 5070263c8b1..a5dc6cf3178 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDScenarios.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDScenarios.java @@ -32,9 +32,7 @@ /* * @test * @requires vm.debug == true - - * @summary Test -DScenarios property flag. Run with othervm which should not be done when writing tests using - * the framework. + * @summary Test -DScenarios property flag. Run with othervm which should not be done when writing tests using the framework. * @library /test/lib * @run main/othervm -DScenarios=1,5,10 jdk.test.lib.hotspot.ir_framework.tests.TestDScenarios test * @run main/othervm -DScenarios=1,4 jdk.test.lib.hotspot.ir_framework.tests.TestDScenarios test diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java index d43d8707895..5deeb511ab6 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java @@ -188,7 +188,7 @@ public void run4(RunInfo info) { @Test @IR(counts = {IRNode.STORE_I, "1"}) public int test7(int x) { - for (int i = 0; i < 100; i++); + for (int i = 0; i < 100; i++) {} iFld = x; return x; } @@ -197,7 +197,7 @@ public int test7(int x) { @Test @IR(counts = {IRNode.STORE_I, "1"}) public int test8(int x) { - for (int i = 0; i < 100; i++); + for (int i = 0; i < 100; i++) {} iFld = x; return x; } From e56df009a63c9a16eb0b1608d1ac2547e1d72c28 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 14 Apr 2021 16:11:42 +0200 Subject: [PATCH 111/131] Fix timeout of TestNullableArrays and TestNullableInlineTypes --- .../jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java | 2 +- .../compiler/valhalla/inlinetypes/TestNullableInlineTypes.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java index 3806824fc85..28b43911ad3 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java @@ -39,7 +39,7 @@ * @summary Test nullable inline type arrays * @library /test/lib / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @run driver compiler.valhalla.inlinetypes.TestNullableArrays + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestNullableArrays */ @ForceCompileClassInitializer diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java index 5db57afc5f7..3ddc11c2369 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java @@ -39,7 +39,7 @@ * @summary Test correct handling of nullable inline types. * @library /test/lib / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @run driver compiler.valhalla.inlinetypes.TestNullableInlineTypes + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestNullableInlineTypes */ @ForceCompileClassInitializer From 6a2aae6358f139b7cb9dd2ef615511d349ba2b81 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 14 Apr 2021 17:40:19 +0200 Subject: [PATCH 112/131] Fix TestLWorldProfiling when run with product build --- .../valhalla/inlinetypes/TestLWorldProfiling.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java index a2ba1918550..8c645c55227 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java @@ -90,10 +90,11 @@ public static void main(String[] args) { }; InlineTypes.getFramework() - .addScenarios(scenarios) - .addHelperClasses(MyValue1.class, - MyValue2.class) - .start(); + .addScenarios(scenarios) + .addFlags("-XX:+IgnoreUnrecognizedVMOptions") + .addHelperClasses(MyValue1.class, + MyValue2.class) + .start(); } private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(rI, rL); From bc6924e861c3fa25d5d0282db7c1b2d1972aa2e6 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 15 Apr 2021 11:07:43 +0200 Subject: [PATCH 113/131] Fix whitespaces + timeout of TestCallingConvention --- .../inlinetypes/TestCallingConvention.java | 2 +- .../hotspot/ir_framework/AbstractInfo.java | 4 +- .../lib/hotspot/ir_framework/Argument.java | 2 +- .../lib/hotspot/ir_framework/RunInfo.java | 2 +- .../hotspot/ir_framework/TestFramework.java | 22 +++++----- .../ir_framework/TestFrameworkExecution.java | 12 +++-- .../lib/hotspot/ir_framework/TestInfo.java | 4 +- .../lib/hotspot/ir_framework/TestRun.java | 2 +- .../examples/BaseTestExample.java | 8 ++-- .../examples/CheckedTestExample.java | 4 +- .../examples/CustomRunTestExample.java | 12 ++--- .../ir_framework/examples/IRExample.java | 1 + .../tests/TestAccessModifiers.java | 44 +++++++++---------- .../ir_framework/tests/TestBasics.java | 2 +- .../ir_framework/tests/TestCompLevels.java | 2 +- .../ir_framework/tests/TestControls.java | 6 +-- 16 files changed, 63 insertions(+), 66 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java index 57cfd03ac6b..677a612d0d7 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java @@ -40,7 +40,7 @@ * @summary Test inline type calling convention optimizations * @library /test/lib / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") - * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestCallingConvention + * @run driver/timeout=450 compiler.valhalla.inlinetypes.TestCallingConvention */ @ForceCompileClassInitializer diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java index 996f8c5c8a6..3eb720a46fa 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java @@ -32,7 +32,7 @@ * Base info class which provides some useful utility methods and information about a test. *

    * Base tests and checked tests use {@link TestInfo} while custom run tests use {@link RunInfo}. - * + * * @see Test * @see Check * @see Run @@ -47,7 +47,7 @@ abstract public class AbstractInfo { AbstractInfo(Class testClass) { this.testClass = testClass; } - + /** * Returns a different boolean each time this method is invoked (switching between {@code false} and {@code true}). * The first invocation returns {@code false}. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java index fcfafeaa509..f5d65399c6f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java @@ -26,7 +26,7 @@ /** * Well-defined argument values that can be used in the {@link Arguments} annotation at a {@link Test} method for a * base test or a checked test. - * + * * @see Arguments * @see Test * @see Check diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java index ebba8d555f8..beb580d4a4d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java @@ -30,7 +30,7 @@ /** * Test info class which provides some useful utility methods and information about a custom run test. - * + * * @see Run */ public class RunInfo extends AbstractInfo { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index cf19284fc2f..cdb1a265999 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -175,7 +175,7 @@ public TestFramework() { * Use this constructor if you want to use multiple run options (flags, helper classes, scenarios). * Use the associated add methods ({@link #addFlags(String...)}, @link #addScenarios(Scenario...)}, * {@link #addHelperClasses(Class...)}) to set up everything and then start the testing by invoking {@link #start()}. - * + * * @param testClass the class to be tested by the framework. * @see #TestFramework() */ @@ -251,10 +251,10 @@ public static void runWithFlags(String... flags) { *

  • If you want to run your JTreg test with multiple flag combinations, use * {@link #runWithScenarios(Scenario...)}

  • * - * + * * @param testClass the class to be tested by the framework. * @param flags VM flags to be used for the test VM. - * + * * @see #runWithFlags(String...) */ public static void runWithFlags(Class testClass, String... flags) { @@ -914,7 +914,7 @@ private List getTestVMFlags() { // Maybe we run with flags that make IR verification impossible shouldVerifyIR = Boolean.parseBoolean(matcher.group(2)); flagList.addAll(Arrays.asList(matcher.group(1).split(TEST_VM_FLAGS_DELIMITER))); - flagList.add("-DShouldDoIRVerification=true"); + System.out.println(matcher.group(1)); } return flagList; } @@ -1032,14 +1032,13 @@ public String getExceptionInfo(boolean stripRerunHint) { public static String getRerunHint() { return """ ############################################################# - - To only run the failed tests use -DTest, -DExclude, + - To only run the failed tests use -DTest, -DExclude, and/or -DScenarios. - To also get the standard output of the test VM run with\s -DReportStdout=true or for even more fine-grained logging use -DVerbose=true. ############################################################# - - """; + """ + "\n"; } } @@ -1155,12 +1154,11 @@ public static void write(String msg, String type, boolean stdout) { } catch (Exception e) { // When the test VM is directly run, we should ignore all messages that would normally be sent to the // driver VM. - String failMsg = """ - + String failMsg = "\n\n" + """ ########################################################### - Did you directly run the test VM (TestFrameworkExecution) - to reproduce a bug? - => Append the flag -DReproduce=true and try again! + Did you directly run the test VM (TestFrameworkExecution) + to reproduce a bug? + => Append the flag -DReproduce=true and try again! ########################################################### """; TestRun.fail(failMsg, e); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 3e9422d32d0..b29f8376590 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -50,15 +50,15 @@ public class TestFrameworkExecution { try { WHITE_BOX = WhiteBox.getWhiteBox(); } catch (UnsatisfiedLinkError e) { - System.err.println(""" + System.err.println("\n" + """ ########################################################## - - Did you call a test-related interface method from - TestFramework in main() of your test? Make sure to - only call setup/run methods and no checks or + - Did you call a test-related interface method from + TestFramework in main() of your test? Make sure to + only call setup/run methods and no checks or assertions from main() of your test! - Are you rerunning the test VM (TestFrameworkExecution) directly after a JTreg run? Make sure to start it - from within JTwork/scratch and with the flag + from within JTwork/scratch and with the flag -DReproduce=true! ########################################################## """); @@ -1447,5 +1447,3 @@ protected void checkCompilationLevel(DeclaredTest test) { } } } - - diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java index 58cc5074e71..59ed345471c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java @@ -27,7 +27,7 @@ /** * Test info class which provides some useful utility methods and information about a checked test. - * + * * @see Test * @see Check */ @@ -83,7 +83,7 @@ public boolean isC2Compiled() { /** * Returns a boolean indicating if the associated test method is compiled at {@code compLevel}. - * + * * @param compLevel the compilation level. * @return {@code true} if the test method is compiled at {@code compLevel}; * {@code false} otherwise. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java index c95560be73d..753333d8f84 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java @@ -33,7 +33,7 @@ public static void check(boolean test, String failureMessage) { throw new TestRunException(failureMessage); } } - + public static void fail(String failureMessage) { throw new TestRunException(failureMessage); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java index b429803f4f9..b36630bbb1e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java @@ -43,15 +43,15 @@ * * Configurable things for simple tests (no @Run or @Check) at @Test method: *
      - *
    • compLevel: Specify at which compilation level the test should be compiled by the framework at step (**).

    • - * If {@link CompLevel#WAIT_FOR_COMPILATION} is specified, the framework will continue invoke the - * method until HotSpot compiles it. If it is not compiled after 10s, an exception is thrown. + *
    • compLevel: Specify at which compilation level the test should be compiled by the framework at step (**). + * If {@link CompLevel#WAIT_FOR_COMPILATION} is specified, the framework will continue invoke the + * method until HotSpot compiles it. If it is not compiled after 10s, an exception is thrown.

    • *
    • @Warmup: Change warm-up iterations of test (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS)

    • *
    • @Arguments: If a @Test method specifies arguments, you need to provide arguments by using @Arguments such * that the framework knows how to call the method. If you need more complex values, use @Run.

    • *
    • @IR: Arbitrary number of @IR rules.

    • *
    - * + * * @see Test * @see Arguments * @see Warmup diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java index 0c84e564c63..527a7c036af 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - + package jdk.test.lib.hotspot.ir_framework.examples; import jdk.test.lib.hotspot.ir_framework.*; @@ -42,7 +42,7 @@ *
  • Invoke @Test method once again and then always invoke the @Check method once again.

  • * *

    - * + * * Configurable things for checked tests: *

      *
    • At @Test method:

    • diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java index 001622fc40d..d431515f1a9 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java @@ -29,7 +29,7 @@ * @test * @summary Example test to use the new test framework. * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.examples.RunExample + * @run driver jdk.test.lib.hotspot.ir_framework.examples.CustomRunTestExample */ /** @@ -56,19 +56,19 @@ *
    *
  • At @Run method:

  • *
      - *
    • @Warmup: Change warm-up iterations of @Run method (defined by default by + *

    • @Warmup: Change warm-up iterations of @Run method (defined by default by * TestFrameworkExecution.WARMUP_ITERATIONS)

    • *
    • {@link Run#test}: Specify any number of @Test methods. They cannot be shared with other @Check or @Run * methods.

    • - *
    • {@link Run#mode}: Choose between normal invocation as described above or {@link RunMode#STANDALONE}. - * STANDALONE only invokes the @Run method once without warm-up or a compilation by the - * Test Framework. The only thing done by the framework is the verification of any @IR + *

    • {@link Run#mode}: Choose between normal invocation as described above or {@link RunMode#STANDALONE}. + * STANDALONE only invokes the @Run method once without warm-up or a compilation by the + * Test Framework. The only thing done by the framework is the verification of any @IR * rules afterwards. The STANDALONE @Run method needs to make sure that a C2 compilation * is reliably triggered if there are any @IR rules.

    • *
    • No @IR annotations

    • *
    * - * + * * @see Run * @see Test * @see RunMode diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java index 7268f6884f3..71bae08683c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java @@ -81,6 +81,7 @@ public static void main(String[] args) { TestFramework.run(FailingExamples.class); // Secondly, run tests from FailingExamples } catch (IRViolationException e) { // Expected. Check output to see how IR failures are reported. + throw e; } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestAccessModifiers.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestAccessModifiers.java index 0672cdeb3c7..d60745daa67 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestAccessModifiers.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestAccessModifiers.java @@ -47,7 +47,7 @@ public void test() { @Arguments(Argument.DEFAULT) public void test2(int x) { } - + @Test public static int staticPublicPrivate() { return 42; @@ -59,7 +59,7 @@ private void staticPublicPrivateCheck(int retValue) { throw new RuntimeException("Needs to be 42"); } } - + @Test protected static int staticProtectedPrivate() { return 42; @@ -83,7 +83,7 @@ private void staticDefaultPrivateCheck(int retValue) { throw new RuntimeException("Needs to be 42"); } } - + @Test private static int staticPrivatePrivate() { return 42; @@ -95,7 +95,7 @@ private void staticPrivatePrivateCheck(int retValue) { throw new RuntimeException("Needs to be 42"); } } - + @Test public static int staticPublicDefault() { return 42; @@ -107,7 +107,7 @@ void staticPublicDefaultCheck(int retValue) { throw new RuntimeException("Needs to be 42"); } } - + @Test protected static int staticProtectedDefault() { return 42; @@ -131,7 +131,7 @@ void staticDefaultDefaultCheck(int retValue) { throw new RuntimeException("Needs to be 42"); } } - + @Test private static int staticPrivateDefault() { return 42; @@ -143,7 +143,7 @@ void staticPrivateDefaultCheck(int retValue) { throw new RuntimeException("Needs to be 42"); } } - + @Test public static int staticPublicProtected() { return 42; @@ -155,7 +155,7 @@ protected void staticPublicProtectedCheck(int retValue) { throw new RuntimeException("Needs to be 42"); } } - + @Test protected static int staticProtectedProtected() { return 42; @@ -179,7 +179,7 @@ protected void staticDefaultProtectedCheck(int retValue) { throw new RuntimeException("Needs to be 42"); } } - + @Test private static int staticPrivateProtected() { return 42; @@ -191,7 +191,7 @@ protected void staticPrivateProtectedCheck(int retValue) { throw new RuntimeException("Needs to be 42"); } } - + @Test public static int staticPublicPublic() { return 42; @@ -203,7 +203,7 @@ public void staticPublicPublicCheck(int retValue) { throw new RuntimeException("Needs to be 42"); } } - + @Test protected static int staticProtectedPublic() { return 42; @@ -227,7 +227,7 @@ public void staticDefaultPublicCheck(int retValue) { throw new RuntimeException("Needs to be 42"); } } - + @Test private static int staticPrivatePublic() { return 42; @@ -252,7 +252,7 @@ private void staticDefaultPrivateRun() { throw new RuntimeException("Needs to be 42"); } } - + @Test private static int staticPrivatePrivate2() { return 42; @@ -265,7 +265,7 @@ private void staticPrivatePrivateRun() { throw new RuntimeException("Needs to be 42"); } } - + @Test public static int staticPublicDefault2() { return 42; @@ -278,7 +278,7 @@ void staticPublicDefaultRun() { throw new RuntimeException("Needs to be 42"); } } - + @Test protected static int staticProtectedDefault2() { return 42; @@ -304,7 +304,7 @@ void staticDefaultDefaultRun() { throw new RuntimeException("Needs to be 42"); } } - + @Test private static int staticPrivateDefault2() { return 42; @@ -317,7 +317,7 @@ void staticPrivateDefaultRun() { throw new RuntimeException("Needs to be 42"); } } - + @Test public static int staticPublicProtected2() { return 42; @@ -330,7 +330,7 @@ protected void staticPublicProtectedRun() { throw new RuntimeException("Needs to be 42"); } } - + @Test protected static int staticProtectedProtected2() { return 42; @@ -356,7 +356,7 @@ protected void staticDefaultProtectedRun() { throw new RuntimeException("Needs to be 42"); } } - + @Test private static int staticPrivateProtected2() { return 42; @@ -369,7 +369,7 @@ protected void staticPrivateProtectedRun() { throw new RuntimeException("Needs to be 42"); } } - + @Test public static int staticPublicPublic2() { return 42; @@ -382,7 +382,7 @@ public void staticPublicPublicRun() { throw new RuntimeException("Needs to be 42"); } } - + @Test protected static int staticProtectedPublic2() { return 42; @@ -408,7 +408,7 @@ public void staticDefaultPublicRun() { throw new RuntimeException("Needs to be 42"); } } - + @Test private static int staticPrivatePublic2() { return 42; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java index d583b4fe0d1..732924338ff 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java @@ -35,7 +35,7 @@ * @summary Test basics of the framework. This test runs directly the test VM which normally does not happen. * @library /test/lib * @build sun.hotspot.WhiteBox - * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * jdk.test.lib.hotspot.ir_framework.tests.TestBasics */ diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java index bd1d9fc9105..0d83298204a 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java @@ -34,7 +34,7 @@ * This test runs directly the test VM which normally does not happen. * @library /test/lib * @build sun.hotspot.WhiteBox - * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * jdk.test.lib.hotspot.ir_framework.tests.TestCompLevels */ diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java index ebaa32c2e2c..f40213a376c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java @@ -38,7 +38,7 @@ * This test runs directly the test VM which normally does not happen. * @library /test/lib * @build sun.hotspot.WhiteBox - * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * jdk.test.lib.hotspot.ir_framework.tests.TestControls */ @@ -148,12 +148,12 @@ public void checkOverload() { public void testDontCompile() { executed[2]++; } - + @DontCompile public static void dontCompile() { executed[3]++; } - + @Run(test = "testDontCompile", mode = RunMode.STANDALONE) public void runTestDontCompile() throws NoSuchMethodException { for (int i = 0; i < 10000; i++) { From 00e05a03eda3d8ce2022def1b0cbade215778bc0 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 19 Apr 2021 09:22:03 +0200 Subject: [PATCH 114/131] Adjust whitelist --- .../test/lib/hotspot/ir_framework/TestFramework.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index cdb1a265999..06eab75f53f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -107,7 +107,6 @@ public class TestFramework { Arrays.asList( // The following substrings are part of more than one VM flag "RAM", - "G1", "Heap", "Trace", "Print", @@ -116,15 +115,12 @@ public class TestFramework { "UseNewCode", // The following substrings are only part of one VM flag (=exact match) "CreateCoredumpOnCrash", + "IgnoreUnrecognizedVMOptions", "UnlockDiagnosticVMOptions", + "UnlockExperimentalVMOptions", "BackgroundCompilation", "Xbatch", - "TieredCompilation", - "UseSerialGC", - "UseParallelGC", - "UseG1GC", - "UseZGC", - "UseShenandoahGC" + "TieredCompilation" ) ); @@ -914,7 +910,6 @@ private List getTestVMFlags() { // Maybe we run with flags that make IR verification impossible shouldVerifyIR = Boolean.parseBoolean(matcher.group(2)); flagList.addAll(Arrays.asList(matcher.group(1).split(TEST_VM_FLAGS_DELIMITER))); - System.out.println(matcher.group(1)); } return flagList; } From 13382864d1671dccfd3002b507daf00ad614bb20 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 19 Apr 2021 13:55:44 +0200 Subject: [PATCH 115/131] Apply review comments in code from Igor I. and Vladimir K. --- .../hotspot/ir_framework/AbstractInfo.java | 4 +- .../hotspot/ir_framework/ArgumentValue.java | 8 +- .../ir_framework/IREncodingPrinter.java | 15 +- .../lib/hotspot/ir_framework/IRMatcher.java | 136 ++------ .../lib/hotspot/ir_framework/IRMethod.java | 115 +++++++ .../hotspot/ir_framework/TestFramework.java | 314 ++++-------------- .../ir_framework/TestFrameworkSocket.java | 222 +++++++++++++ .../hotspot/ir_framework/examples/TEST.ROOT | 23 ++ .../lib/hotspot/ir_framework/tests/README.md | 2 +- .../lib/hotspot/ir_framework/tests/TEST.ROOT | 23 ++ 10 files changed, 487 insertions(+), 375 deletions(-) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/IRMethod.java create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java index 3eb720a46fa..1c43335694f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java @@ -23,6 +23,8 @@ package jdk.test.lib.hotspot.ir_framework; +import jdk.test.lib.Utils; + import java.lang.reflect.Method; import java.util.Arrays; import java.util.Random; @@ -38,7 +40,7 @@ * @see Run */ abstract public class AbstractInfo { - private static final Random random = new Random(); + private static final Random random = Utils.getRandomInstance(); protected final Class testClass; private boolean toggleBool = false; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java index 5cf46e6c1ac..8e718990c39 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java @@ -23,6 +23,8 @@ package jdk.test.lib.hotspot.ir_framework; +import jdk.test.lib.Utils; + import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Parameter; @@ -32,7 +34,7 @@ * This class represents an argument value specified by {@link Argument} in {@link Arguments}. */ class ArgumentValue { - private static final Random random = new Random(); + private static final Random random = Utils.getRandomInstance(); private final Object argumentValue; private final boolean isRandomEach; @@ -292,10 +294,10 @@ private static Object getRandom(Class c) { } else if (c.equals(long.class)) { return random.nextLong(); } else if (c.equals(float.class)) { - // Get number between 0 and 1000. + // Get float between -10000 and 10000. return random.nextFloat() * 20000 - 10000; } else if (c.equals(double.class)) { - // Get number between 0 and 1000. + // Get double between -10000 and 10000. return random.nextDouble() * 20000 - 10000; } else { TestFormat.fail("Cannot generate random value for non-primitive type"); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java index cf7132e83fd..a15ef3f1bf2 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java @@ -209,8 +209,7 @@ private boolean check(String flag, String value) { return false; } - private boolean checkBooleanFlag(String flag, String value, Boolean actualFlagValue) { - boolean actualBooleanFlagValue = actualFlagValue; + private boolean checkBooleanFlag(String flag, String value, boolean actualFlagValue) { boolean booleanValue = false; if ("true".equalsIgnoreCase(value)) { booleanValue = true; @@ -218,11 +217,10 @@ private boolean checkBooleanFlag(String flag, String value, Boolean actualFlagVa TestFormat.failNoThrow("Invalid value \"" + value + "\" for boolean flag " + flag + failAt()); return false; } - return booleanValue == actualBooleanFlagValue; + return booleanValue == actualFlagValue; } - private boolean checkLongFlag(String flag, String value, Long actualFlagValue) { - long actualLongFlagValue = actualFlagValue; + private boolean checkLongFlag(String flag, String value, long actualFlagValue) { long longValue; ParsedComparator parsedComparator; try { @@ -245,11 +243,10 @@ private boolean checkLongFlag(String flag, String value, Long actualFlagValue) { + comparator + " for integer based flag " + flag + failAt()); return false; } - return parsedComparator.getPredicate().test(actualLongFlagValue, longValue); + return parsedComparator.getPredicate().test(actualFlagValue, longValue); } - private boolean checkDoubleFlag(String flag, String value, Double actualFlagValue) { - double actualDoubleFlagValue = actualFlagValue; + private boolean checkDoubleFlag(String flag, String value, double actualFlagValue) { double doubleValue; ParsedComparator parsedComparator; try { @@ -272,7 +269,7 @@ private boolean checkDoubleFlag(String flag, String value, Double actualFlagValu + comparator + " for floating point based flag " + flag + failAt()); return false; } - return parsedComparator.getPredicate().test(actualDoubleFlagValue, doubleValue); + return parsedComparator.getPredicate().test(actualFlagValue, doubleValue); } private String failAt() { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java index 0cafa5f164d..d27551de2fe 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java @@ -25,6 +25,8 @@ import java.io.*; import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -34,9 +36,14 @@ */ class IRMatcher { private static final boolean PRINT_IR_ENCODING = Boolean.parseBoolean(System.getProperty("PrintIREncoding", "false")); + private static final Pattern irEncodingPattern = + Pattern.compile("(?<=" + IREncodingPrinter.START + "\\R)[\\s\\S]*(?=" + IREncodingPrinter.END + ")"); + private static final Pattern compileIdPattern = Pattern.compile("compile_id='(\\d+)'"); + private final Map compilations; private final Class testClass; private final Map> fails; + private final Pattern compileIdPatternForTestClass; private final String hotspotPidFileName; private IRMethod irMethod; // Current IR method to which rules are applied private Method method; // Current method to which rules are applied @@ -44,9 +51,11 @@ class IRMatcher { private int irRuleIndex; // Current IR rule index; public IRMatcher(String hotspotPidFileName, String irEncoding, Class testClass) { - this.compilations = new LinkedHashMap<>(); + this.compilations = new HashMap<>(); this.fails = new HashMap<>(); this.testClass = testClass; + this.compileIdPatternForTestClass = Pattern.compile("compile_id='(\\d+)'.*" + Pattern.quote(testClass.getCanonicalName()) + + " (\\S+)"); this.hotspotPidFileName = hotspotPidFileName; setupTestMethods(irEncoding); if (TestFramework.VERBOSE || PRINT_IR_ENCODING) { @@ -61,13 +70,13 @@ public IRMatcher(String hotspotPidFileName, String irEncoding, Class testClas * Sets up a map testname -> IRMethod (containing the PrintIdeal and PrintOptoAssembly output for testname). */ private void setupTestMethods(String irEncoding) { - Map irRulesMap = parseIREncoding(irEncoding); + Map irRulesMap = parseIREncoding(irEncoding); for (Method m : testClass.getDeclaredMethods()) { method = m; 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. - Integer[] ids = irRulesMap.get(m.getName()); + int[] ids = irRulesMap.get(m.getName()); TestFramework.check(ids != null, "Should find method name in validIrRulesMap for " + m); TestFramework.check(ids.length > 0, "Did not find any rule indices for " + m); TestFramework.check(ids[ids.length - 1] < irAnnos.length, "Invalid IR rule index found in validIrRulesMap for " + m); @@ -82,11 +91,9 @@ private void setupTestMethods(String irEncoding) { /** * Read the IR encoding emitted by the test VM to decide if an @IR rule must be checked for a method. */ - private Map parseIREncoding(String irEncoding) { - Map irRulesMap = new HashMap<>(); - String patternString = "(?<=" + IREncodingPrinter.START + "\\R)[\\s\\S]*(?=" + IREncodingPrinter.END + ")"; - Pattern pattern = Pattern.compile(patternString); - Matcher matcher = pattern.matcher(irEncoding); + private Map parseIREncoding(String irEncoding) { + Map irRulesMap = new HashMap<>(); + Matcher matcher = irEncodingPattern.matcher(irEncoding); TestFramework.check(matcher.find(), "Did not find IR encoding"); String[] lines = matcher.group(0).split("\\R"); @@ -95,12 +102,16 @@ private Map parseIREncoding(String irEncoding) { String line = lines[i].trim(); String[] splitComma = line.split(","); if (splitComma.length < 2) { - throw new TestFrameworkException("Invalid IR match rule encoding"); + TestFramework.fail("Invalid IR match rule encoding. No comma found: " + splitComma[0]); } String testName = splitComma[0]; - Integer[] irRulesIdx = new Integer[splitComma.length - 1]; + int[] irRulesIdx = new int[splitComma.length - 1]; for (int j = 1; j < splitComma.length; j++) { - irRulesIdx[j - 1] = Integer.valueOf(splitComma[j]); + try { + irRulesIdx[j - 1] = Integer.parseInt(splitComma[j]); + } catch (NumberFormatException e) { + TestFramework.fail("Invalid IR match rule encoding. No number found: " + splitComma[j]); + } } irRulesMap.put(testName, irRulesIdx); } @@ -113,7 +124,7 @@ private Map parseIREncoding(String irEncoding) { */ private void parseHotspotPidFile() { Map compileIdMap = new HashMap<>(); - try (BufferedReader br = new BufferedReader(new FileReader(new File(System.getProperty("user.dir") + File.separator + hotspotPidFileName)))) { + try (BufferedReader br = Files.newBufferedReader(Paths.get("", hotspotPidFileName))) { String line; StringBuilder builder = new StringBuilder(); boolean append = false; @@ -203,8 +214,7 @@ private static int getCompileId(Matcher matcher) { * and IR encoding from the test VM specifies that this method has @IR rules to be checked). */ private void addTestMethodCompileId(Map compileIdMap, String line) { - Pattern pattern = Pattern.compile("compile_id='(\\d+)'.*" + Pattern.quote(testClass.getCanonicalName()) + " (\\S+)"); - Matcher matcher = pattern.matcher(line); + Matcher matcher = compileIdPatternForTestClass.matcher(line); if (matcher.find()) { // Only care about test class entries. Might have non-class entries as well if user specified additional // compile commands. Ignore these. @@ -239,8 +249,7 @@ private static boolean isPrintOptoAssemblyStart(String line) { * Returns null if not an interesting method (i.e. from test class). */ private String getMethodName(Map compileIdMap, String line) { - Pattern pattern = Pattern.compile("compile_id='(\\d+)'"); - Matcher matcher = pattern.matcher(line); + Matcher matcher = compileIdPattern.matcher(line); TestFramework.check(matcher.find(), "Is " + hotspotPidFileName + " corrupted?"); int compileId = getCompileId(matcher); return compileIdMap.get(compileId); @@ -270,15 +279,13 @@ private void applyRulesForMethod(IRMethod irMethod) { System.out.println("Output of " + method + ":"); System.out.println(testOutput); } - for (Integer id : irMethod.getRuleIds()) { - applyIRRule(id); - } + Arrays.stream(irMethod.getRuleIds()).forEach(this::applyIRRule); } /** * Apply a single @IR rule as part of a method. */ - private void applyIRRule(Integer id) { + private void applyIRRule(int id) { irAnno = irMethod.getIrAnno(id); irRuleIndex = id; StringBuilder failMsg = new StringBuilder(); @@ -471,92 +478,3 @@ private void reportFailuresIfAny() { } } } - -/** - * Helper class to store information about a method that needs to be IR matched. - */ -class IRMethod { - final private Method method; - final private Integer[] ruleIds; - final private IR[] irAnnos; - final private StringBuilder outputBuilder; - private String output; - private String idealOutput; - private String optoAssemblyOutput; - private boolean needsIdeal; - private boolean needsOptoAssembly; - - public IRMethod(Method method, Integer[] ruleIds, IR[] irAnnos) { - this.method = method; - this.ruleIds = ruleIds; - this.irAnnos = irAnnos; - this.outputBuilder = new StringBuilder(); - this.output = ""; - this.idealOutput = ""; - this.optoAssemblyOutput = ""; - } - - public Method getMethod() { - return method; - } - - public Integer[] getRuleIds() { - return ruleIds; - } - - public IR getIrAnno(int idx) { - return irAnnos[idx]; - } - - /** - * The Ideal output comes always before the Opto Assembly output. We might parse multiple C2 compilations of this method. - * Only keep the very last one by overriding 'output'. - */ - public void appendIdealOutput(String idealOutput) { - outputBuilder.setLength(0); - this.idealOutput = "PrintIdeal:\n" + idealOutput; - outputBuilder.append(this.idealOutput); - } - - /** - * The Opto Assembly output comes after the Ideal output. Simply append to 'output'. - */ - public void appendOptoAssemblyOutput(String optoAssemblyOutput) { - this.optoAssemblyOutput = "PrintOptoAssembly:\n" + optoAssemblyOutput; - outputBuilder.append("\n\n").append(this.optoAssemblyOutput); - output = outputBuilder.toString(); - } - - public String getOutput() { - return output; - } - - public String getIdealOutput() { - return idealOutput; - } - - public String getOptoAssemblyOutput() { - return optoAssemblyOutput; - } - - public void needsAllOutput() { - needsIdeal(); - needsOptoAssembly(); - } - - public void needsIdeal() { - needsIdeal = true; - } - - public boolean usesIdeal() { - return needsIdeal; - } - - public void needsOptoAssembly() { - needsOptoAssembly = true; - } - - public boolean usesOptoAssembly() { - return needsOptoAssembly; - } -} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMethod.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMethod.java new file mode 100644 index 00000000000..b8f2be9ad50 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMethod.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +import java.lang.reflect.Method; + +/** + * Helper class to store information about a method that needs to be IR matched. + */ +class IRMethod { + final private Method method; + final private int[] ruleIds; + final private IR[] irAnnos; + final private StringBuilder outputBuilder; + private String output; + private String idealOutput; + private String optoAssemblyOutput; + private boolean needsIdeal; + private boolean needsOptoAssembly; + + public IRMethod(Method method, int[] ruleIds, IR[] irAnnos) { + this.method = method; + this.ruleIds = ruleIds; + this.irAnnos = irAnnos; + this.outputBuilder = new StringBuilder(); + this.output = ""; + this.idealOutput = ""; + this.optoAssemblyOutput = ""; + } + + public Method getMethod() { + return method; + } + + public int[] getRuleIds() { + return ruleIds; + } + + public IR getIrAnno(int idx) { + return irAnnos[idx]; + } + + /** + * The Ideal output comes always before the Opto Assembly output. We might parse multiple C2 compilations of this method. + * Only keep the very last one by overriding 'output'. + */ + public void appendIdealOutput(String idealOutput) { + outputBuilder.setLength(0); + this.idealOutput = "PrintIdeal:\n" + idealOutput; + outputBuilder.append(this.idealOutput); + } + + /** + * The Opto Assembly output comes after the Ideal output. Simply append to 'output'. + */ + public void appendOptoAssemblyOutput(String optoAssemblyOutput) { + this.optoAssemblyOutput = "PrintOptoAssembly:\n" + optoAssemblyOutput; + outputBuilder.append("\n\n").append(this.optoAssemblyOutput); + output = outputBuilder.toString(); + } + + public String getOutput() { + return output; + } + + public String getIdealOutput() { + return idealOutput; + } + + public String getOptoAssemblyOutput() { + return optoAssemblyOutput; + } + + public void needsAllOutput() { + needsIdeal(); + needsOptoAssembly(); + } + + public void needsIdeal() { + needsIdeal = true; + } + + public boolean usesIdeal() { + return needsIdeal; + } + + public void needsOptoAssembly() { + needsOptoAssembly = true; + } + + public boolean usesOptoAssembly() { + return needsOptoAssembly; + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 06eab75f53f..bc9854b7e45 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -30,12 +30,10 @@ import jdk.test.lib.util.ClassFileInstaller; import sun.hotspot.WhiteBox; -import java.io.*; +import java.io.PrintWriter; +import java.io.StringWriter; import java.lang.reflect.Method; -import java.net.ServerSocket; -import java.net.Socket; import java.util.*; -import java.util.concurrent.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -130,6 +128,15 @@ public class TestFramework { static final String TEST_VM_FLAGS_START = "##### TestFrameworkPrepareFlags - used by TestFramework #####"; static final String TEST_VM_FLAGS_DELIMITER = " "; static final String TEST_VM_FLAGS_END = "----- END -----"; + static final String RERUN_HINT = """ + ############################################################# + - To only run the failed tests use -DTest, -DExclude, + and/or -DScenarios. + - To also get the standard output of the test VM run with\s + -DReportStdout=true or for even more fine-grained logging + use -DVerbose=true. + ############################################################# + """ + "\n"; private static final int WARMUP_ITERATIONS = Integer.getInteger("Warmup", -1); private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.getBoolean("PreferCommandLineFlags"); @@ -141,9 +148,10 @@ public class TestFramework { private static String lastTestVMOutput; private final Class testClass; - private List> helperClasses = null; + private Set> helperClasses = null; private List scenarios = null; - private final List flags = new ArrayList<>(); + private Set scenarioIndices = null; + private List flags = null; private int defaultWarmup = -1; private TestFrameworkSocket socket; private Scenario scenario; @@ -159,11 +167,7 @@ public class TestFramework { * {@link #addHelperClasses(Class...)}) to set up everything and then start the testing by invoking {@link #start()}. */ public TestFramework() { - StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - this.testClass = walker.getCallerClass(); - if (VERBOSE) { - System.out.println("Test class: " + testClass); - } + this(StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).getCallerClass()); } /** @@ -264,13 +268,11 @@ public static void runWithFlags(Class testClass, String... flags) { * ({@link ForceCompile @ForceCompile}, {@link DontCompile @DontCompile}, {@link ForceInline @ForceInline}, * {@link DontInline @DontInline}) to be applied while testing {@code testClass} (also see description of * {@link TestFramework}). - *
      - *
    • If a helper class is not in the same file as the test class, make sure that JTreg compiles it by using - * {@literal @}compile in the JTreg header comment block.

    • - *
    • If a class is used by the test class that does not specify any compile command annotations, you do not - * need to include it in {@code helperClasses}. If no helper class specifies any compile commands, consider - * using {@link #run()} or {@link #run(Class)}.

    • - *
    + * + *

    + * If a class is used by the test class that does not specify any compile command annotations, you do not + * need to include it in {@code helperClasses}. If no helper class specifies any compile commands, consider + * using {@link #run()} or {@link #run(Class)}. * * @param testClass the class to be tested by the framework. * @param helperClasses helper classes containing compile command annotations ({@link ForceCompile}, @@ -333,6 +335,9 @@ public static void runWithScenarios(Class testClass, Scenario... scenarios) { */ public TestFramework addFlags(String... flags) { TestRun.check(flags != null && Arrays.stream(flags).noneMatch(Objects::isNull), "A flag cannot be null"); + if (this.flags == null) { + this.flags = new ArrayList<>(); + } this.flags.addAll(Arrays.asList(flags)); return this; } @@ -341,16 +346,14 @@ public TestFramework addFlags(String... flags) { * Add helper classes that can specify additional compile command annotations ({@link ForceCompile @ForceCompile}, * {@link DontCompile @DontCompile}, {@link ForceInline @ForceInline}, {@link DontInline @DontInline}) to be applied * while testing {@code testClass} (also see description of {@link TestFramework}). - *

      - *
    • If a helper class is not in the same file as the test class, make sure that JTreg compiles it by using - * {@code @compile} in the JTreg header comment block.

    • - *
    • If a class is used by the test class that does not specify any compile command annotations, you do not - * need to include it with this method. If no helper class specifies any compile commands, you do - * not need to call this method at all.

    • - *
    * *

    - * The testing can be started by invoking {@link #start()} + * If a class is used by the test class that does not specify any compile command annotations, you do not need + * to include it with this method. If no helper class specifies any compile commands, you do not need to call + * this method at all. + * + *

    + * The testing can be started by invoking {@link #start()}. * * @param helperClasses helper classes containing compile command annotations ({@link ForceCompile}, * {@link DontCompile}, {@link ForceInline}, {@link DontInline}) to be applied @@ -358,13 +361,15 @@ public TestFramework addFlags(String... flags) { * @return the same framework instance. */ public TestFramework addHelperClasses(Class... helperClasses) { - TestRun.check(helperClasses != null && Arrays.stream(helperClasses).noneMatch(Objects::isNull), "A Helper class cannot be null"); + TestRun.check(helperClasses != null && Arrays.stream(helperClasses).noneMatch(Objects::isNull), + "A Helper class cannot be null"); if (this.helperClasses == null) { - this.helperClasses = new ArrayList<>(); + this.helperClasses = new HashSet<>(); } - for (Class helperClass : helperClasses) { - TestRun.check(!this.helperClasses.contains(helperClass), "Cannot add the same class twice: " + helperClass); + for (var helperClass : helperClasses) { + TestRun.check(!this.helperClasses.contains(helperClass), + "Cannot add the same class twice: " + helperClass); this.helperClasses.add(helperClass); } return this; @@ -383,11 +388,18 @@ public TestFramework addHelperClasses(Class... helperClasses) { * @return the same framework instance. */ public TestFramework addScenarios(Scenario... scenarios) { - TestRun.check(scenarios != null && Arrays.stream(scenarios).noneMatch(Objects::isNull), "A scenario cannot be null"); + TestFormat.check(scenarios != null && Arrays.stream(scenarios).noneMatch(Objects::isNull), + "A scenario cannot be null"); if (this.scenarios == null) { - this.scenarios = new ArrayList<>(Arrays.asList(scenarios)); - } else { - this.scenarios.addAll(Arrays.asList(scenarios)); + this.scenarios = new ArrayList<>(); + this.scenarioIndices = new HashSet<>(); + } + + for (Scenario scenario : scenarios) { + int scenarioIndex = scenario.getIndex(); + TestFormat.check(scenarioIndices.add(scenarioIndex), + "Cannot define two scenarios with the same index " + scenarioIndex); + this.scenarios.add(scenario); } return this; } @@ -398,7 +410,7 @@ public TestFramework addScenarios(Scenario... scenarios) { */ public void start() { installWhiteBox(); - maybeDisableIRVerificationCompletely(); + disableIRVerificationIfNotFeasible(); if (scenarios == null) { try { @@ -601,18 +613,18 @@ private void installWhiteBox() { /** * Disable IR verification completely in certain cases. */ - private void maybeDisableIRVerificationCompletely() { + private void disableIRVerificationIfNotFeasible() { if (VERIFY_IR) { - VERIFY_IR = hasIRAnnotations(); + VERIFY_IR = Platform.isDebugBuild() && !Platform.isInt() && !Platform.isComp(); if (!VERIFY_IR) { - System.out.println("IR verification disabled due to test " + testClass + " not specifying any @IR annotations"); + System.out.println("IR verification disabled due to not running a debug build (required for PrintIdeal" + + "and PrintOptoAssembly), running with -Xint, or -Xcomp (use warm-up of 0 instead)"); return; } - VERIFY_IR = Platform.isDebugBuild() && !Platform.isInt() && !Platform.isComp(); + VERIFY_IR = hasIRAnnotations(); if (!VERIFY_IR) { - System.out.println("IR verification disabled due to not running a debug build (required for PrintIdeal" + - "and PrintOptoAssembly), running with -Xint, or -Xcomp (use warm-up of 0 instead)"); + System.out.println("IR verification disabled due to test " + testClass + " not specifying any @IR annotations"); return; } @@ -631,12 +643,8 @@ private void maybeDisableIRVerificationCompletely() { */ private void startWithScenarios() { Map exceptionMap = new TreeMap<>(Comparator.comparingInt(Scenario::getIndex)); - Set scenarioIndices = new HashSet<>(); for (Scenario scenario : scenarios) { int scenarioIndex = scenario.getIndex(); - TestFormat.check(!scenarioIndices.contains(scenarioIndex), - "Cannot define two scenarios with the same index " + scenarioIndex); - scenarioIndices.add(scenarioIndex); try { start(scenario); } catch (TestFormatException e) { @@ -665,8 +673,7 @@ private void reportScenarioFailures(Map exceptionMap) { if (scenario != null) { errorMsg = getScenarioTitleAndFlags(scenario); } - if (e instanceof IRViolationException) { - IRViolationException irException = (IRViolationException) e; + if (e instanceof IRViolationException irException) { // For IR violations, only show the actual violations and not the (uninteresting) stack trace. System.out.println((scenario != null ? "Scenario #" + scenario.getIndex() + " - " : "") + "Compilation(s) of failed matche(s):"); @@ -685,7 +692,7 @@ private void reportScenarioFailures(Map exceptionMap) { System.err.println(builder.toString()); if (!VERBOSE && !REPORT_STDOUT && !TESTLIST && !EXCLUDELIST) { // Provide a hint to the user how to get additional output/debugging information. - System.err.println(JVMOutput.getRerunHint()); + System.err.println(RERUN_HINT); } TestRun.fail(failedScenarios + ". Please check stderr for more information."); } @@ -714,7 +721,10 @@ private void start(Scenario scenario) { this.scenario = scenario; try { // Use TestFramework flags and scenario flags for new VMs. - List additionalFlags = new ArrayList<>(flags); + List additionalFlags = new ArrayList<>(); + if (flags != null) { + additionalFlags.addAll(flags); + } if (scenario != null) { List scenarioFlags = scenario.getFlags(); String scenarioFlagsString = scenarioFlags.isEmpty() ? "" : " - [" + String.join(", ", scenarioFlags) + "]"; @@ -792,7 +802,7 @@ private ArrayList prepareFlagVMFlags(List additionalFlags) { private void checkFlagVMExitCode(OutputAnalyzer oa) { String flagVMOutput = oa.getOutput(); - final int exitCode = oa.getExitValue(); + int exitCode = oa.getExitValue(); if (VERBOSE && exitCode == 0) { System.out.println("--- OUTPUT TestFramework flag VM ---"); System.out.println(flagVMOutput); @@ -801,7 +811,7 @@ private void checkFlagVMExitCode(OutputAnalyzer oa) { if (exitCode != 0) { System.err.println("--- OUTPUT TestFramework flag VM ---"); System.err.println(flagVMOutput); - throw new RuntimeException("\nTestFramework flag VM exited with " + exitCode); + throw new RuntimeException("TestFramework flag VM exited with " + exitCode); } } @@ -1013,7 +1023,7 @@ public String getExceptionInfo(boolean stripRerunHint) { if (exitCode == 134) { stdOut = "\n\nStandard Output\n---------------\n" + getOutput(); } else if (!stripRerunHint) { - rerunHint = getRerunHint(); + rerunHint = TestFramework.RERUN_HINT; } if (exitCode == 0) { // IR exception @@ -1023,204 +1033,4 @@ public String getExceptionInfo(boolean stripRerunHint) { + stdOut + "\n" + getCommandLine() + "\n\nError Output\n------------\n" + stdErr + "\n\n" + rerunHint; } } - - public static String getRerunHint() { - return """ - ############################################################# - - To only run the failed tests use -DTest, -DExclude, - and/or -DScenarios. - - To also get the standard output of the test VM run with\s - -DReportStdout=true or for even more fine-grained logging - use -DVerbose=true. - ############################################################# - """ + "\n"; - } -} - -/** - * Dedicated socket to send data from the flag and test VM back to the driver VM. - */ -class TestFrameworkSocket { - static final String SERVER_PORT_PROPERTY = "ir.framework.server.port"; - - // Static fields used by flag and test VM only. - private static final int SERVER_PORT = Integer.getInteger(SERVER_PORT_PROPERTY, -1); - - private static final boolean REPRODUCE = Boolean.getBoolean("Reproduce"); - private static final String HOSTNAME = null; - private static final String STDOUT_PREFIX = "[STDOUT]"; - private static Socket clientSocket = null; - private static PrintWriter clientWriter = null; - - private final String serverPortPropertyFlag; - private FutureTask socketTask; - private ServerSocket serverSocket; - - private static TestFrameworkSocket singleton = null; - - private TestFrameworkSocket() { - try { - serverSocket = new ServerSocket(0); - } catch (IOException e) { - TestFramework.fail("Failed to create TestFramework server socket", e); - } - int port = serverSocket.getLocalPort(); - if (TestFramework.VERBOSE) { - System.out.println("TestFramework server socket uses port " + port); - } - serverPortPropertyFlag = "-D" + SERVER_PORT_PROPERTY + "=" + port; - } - - public static TestFrameworkSocket getSocket() { - if (singleton == null || singleton.serverSocket.isClosed()) { - singleton = new TestFrameworkSocket(); - return singleton; - } - return singleton; - } - - public String getPortPropertyFlag() { - return serverPortPropertyFlag; - } - - public void start() { - socketTask = initSocketTask(); - Thread socketThread = new Thread(socketTask); - socketThread.start(); - } - - /** - * Waits for client sockets (created by flag or test VM) to connect. Return the messages received by the clients. - */ - private FutureTask initSocketTask() { - return new FutureTask<>(() -> { - try (Socket clientSocket = serverSocket.accept(); - BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())) - ) { - StringBuilder builder = new StringBuilder(); - String next; - while ((next = in.readLine()) != null) { - builder.append(next).append("\n"); - } - return builder.toString(); - } catch (IOException e) { - TestFramework.fail("Server socket error", e); - return null; - } - }); - } - - public void close() { - try { - serverSocket.close(); - } catch (IOException e) { - TestFramework.fail("Could not close socket", e); - } - } - - /** - * Only called by flag and test VM to write to server socket. - */ - public static void write(String msg, String type) { - write(msg, type, false); - } - - /** - * Only called by flag and test VM to write to server socket. - */ - public static void write(String msg, String type, boolean stdout) { - if (REPRODUCE) { - System.out.println("Debugging Test VM: Skip writing due to -DReproduce"); - return; - } - TestFramework.check(SERVER_PORT != -1, "Server port was not set correctly for flag and/or test VM " - + "or method not called from flag or test VM"); - try { - // Keep the client socket open until the flag or test VM terminates (calls closeClientSocket before exiting - // main()). - if (clientSocket == null) { - clientSocket = new Socket(HOSTNAME, SERVER_PORT); - clientWriter = new PrintWriter(clientSocket.getOutputStream(), true); - } - if (stdout) { - msg = STDOUT_PREFIX + msg; - } - clientWriter.println(msg); - } catch (Exception e) { - // When the test VM is directly run, we should ignore all messages that would normally be sent to the - // driver VM. - String failMsg = "\n\n" + """ - ########################################################### - Did you directly run the test VM (TestFrameworkExecution) - to reproduce a bug? - => Append the flag -DReproduce=true and try again! - ########################################################### - """; - TestRun.fail(failMsg, e); - } - if (TestFramework.VERBOSE) { - System.out.println("Written " + type + " to socket:"); - System.out.println(msg); - } - } - - /** - * Closes (and flushes) the printer to the socket and the socket itself. Is called as last thing before exiting - * the main() method of the flag and the test VM. - */ - public static void closeClientSocket() { - if (clientSocket != null) { - try { - clientWriter.close(); - clientSocket.close(); - } catch (IOException e) { - throw new RuntimeException("Could not close TestFrameworkExecution socket", e); - } - } - } - - /** - * Get the socket output of the flag VM. - */ - public String getOutput() { - try { - return socketTask.get(); - - } catch (Exception e) { - TestFramework.fail("Could not read from socket task", e); - return null; - } - } - - /** - * Get the socket output from the test VM by stripping all lines starting with a [STDOUT] output and printing them - * to the standard output. - */ - public String getOutputPrintStdout() { - try { - String output = socketTask.get(); - if (TestFramework.TESTLIST || TestFramework.EXCLUDELIST) { - StringBuilder builder = new StringBuilder(); - Scanner scanner = new Scanner(output); - System.out.println("\nRun flag defined test list"); - System.out.println("--------------------------"); - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - if (line.startsWith(STDOUT_PREFIX)) { - line = "> " + line.substring(STDOUT_PREFIX.length()); - System.out.println(line); - } else { - builder.append(line).append("\n"); - } - } - System.out.println(); - return builder.toString(); - } - return output; - - } catch (Exception e) { - TestFramework.fail("Could not read from socket task", e); - return null; - } - } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java new file mode 100644 index 00000000000..4bf0583b5ab --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Scanner; +import java.util.concurrent.FutureTask; + +/** + * Dedicated socket to send data from the flag and test VM back to the driver VM. + */ +class TestFrameworkSocket implements AutoCloseable { + static final String SERVER_PORT_PROPERTY = "ir.framework.server.port"; + + // Static fields used by flag and test VM only. + private static final int SERVER_PORT = Integer.getInteger(SERVER_PORT_PROPERTY, -1); + + private static final boolean REPRODUCE = Boolean.getBoolean("Reproduce"); + private static final String HOSTNAME = null; + private static final String STDOUT_PREFIX = "[STDOUT]"; + private static Socket clientSocket = null; + private static PrintWriter clientWriter = null; + + private final String serverPortPropertyFlag; + private FutureTask socketTask; + private ServerSocket serverSocket; + + private static TestFrameworkSocket singleton = null; + + private TestFrameworkSocket() { + try { + serverSocket = new ServerSocket(0); + } catch (IOException e) { + TestFramework.fail("Failed to create TestFramework server socket", e); + } + int port = serverSocket.getLocalPort(); + if (TestFramework.VERBOSE) { + System.out.println("TestFramework server socket uses port " + port); + } + serverPortPropertyFlag = "-D" + SERVER_PORT_PROPERTY + "=" + port; + } + + public static TestFrameworkSocket getSocket() { + if (singleton == null || singleton.serverSocket.isClosed()) { + singleton = new TestFrameworkSocket(); + return singleton; + } + return singleton; + } + + public String getPortPropertyFlag() { + return serverPortPropertyFlag; + } + + public void start() { + socketTask = initSocketTask(); + Thread socketThread = new Thread(socketTask); + socketThread.start(); + } + + /** + * Waits for client sockets (created by flag or test VM) to connect. Return the messages received by the clients. + */ + private FutureTask initSocketTask() { + return new FutureTask<>(() -> { + try (Socket clientSocket = serverSocket.accept(); + BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())) + ) { + StringBuilder builder = new StringBuilder(); + String next; + while ((next = in.readLine()) != null) { + builder.append(next).append("\n"); + } + return builder.toString(); + } catch (IOException e) { + TestFramework.fail("Server socket error", e); + return null; + } + }); + } + + @Override + public void close() { + try { + serverSocket.close(); + } catch (IOException e) { + TestFramework.fail("Could not close socket", e); + } + } + + /** + * Only called by flag and test VM to write to server socket. + */ + public static void write(String msg, String type) { + write(msg, type, false); + } + + /** + * Only called by flag and test VM to write to server socket. + */ + public static void write(String msg, String type, boolean stdout) { + if (REPRODUCE) { + System.out.println("Debugging Test VM: Skip writing due to -DReproduce"); + return; + } + TestFramework.check(SERVER_PORT != -1, "Server port was not set correctly for flag and/or test VM " + + "or method not called from flag or test VM"); + try { + // Keep the client socket open until the flag or test VM terminates (calls closeClientSocket before exiting + // main()). + if (clientSocket == null) { + clientSocket = new Socket(HOSTNAME, SERVER_PORT); + clientWriter = new PrintWriter(clientSocket.getOutputStream(), true); + } + if (stdout) { + msg = STDOUT_PREFIX + msg; + } + clientWriter.println(msg); + } catch (Exception e) { + // When the test VM is directly run, we should ignore all messages that would normally be sent to the + // driver VM. + String failMsg = "\n\n" + """ + ########################################################### + Did you directly run the test VM (TestFrameworkExecution) + to reproduce a bug? + => Append the flag -DReproduce=true and try again! + ########################################################### + """; + TestRun.fail(failMsg, e); + } + if (TestFramework.VERBOSE) { + System.out.println("Written " + type + " to socket:"); + System.out.println(msg); + } + } + + /** + * Closes (and flushes) the printer to the socket and the socket itself. Is called as last thing before exiting + * the main() method of the flag and the test VM. + */ + public static void closeClientSocket() { + if (clientSocket != null) { + try { + clientWriter.close(); + clientSocket.close(); + } catch (IOException e) { + throw new RuntimeException("Could not close TestFrameworkExecution socket", e); + } + } + } + + /** + * Get the socket output of the flag VM. + */ + public String getOutput() { + try { + return socketTask.get(); + + } catch (Exception e) { + TestFramework.fail("Could not read from socket task", e); + return null; + } + } + + /** + * Get the socket output from the test VM by stripping all lines starting with a [STDOUT] output and printing them + * to the standard output. + */ + public String getOutputPrintStdout() { + try { + String output = socketTask.get(); + if (TestFramework.TESTLIST || TestFramework.EXCLUDELIST) { + StringBuilder builder = new StringBuilder(); + Scanner scanner = new Scanner(output); + System.out.println("\nRun flag defined test list"); + System.out.println("--------------------------"); + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + if (line.startsWith(STDOUT_PREFIX)) { + line = "> " + line.substring(STDOUT_PREFIX.length()); + System.out.println(line); + } else { + builder.append(line).append("\n"); + } + } + System.out.println(); + return builder.toString(); + } + return output; + + } catch (Exception e) { + TestFramework.fail("Could not read from socket task", e); + return null; + } + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TEST.ROOT b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TEST.ROOT index 13b866e68e3..ce89576ef26 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TEST.ROOT +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TEST.ROOT @@ -1,3 +1,26 @@ +# +# Copyright (c) 2021, 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. +# + # Minimal TEST.ROOT file to run the examples tests as if the examples would have been placed inside # /test/hotspot/jtreg external.lib.roots = ../../../../../../../.. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/README.md b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/README.md index 6837bdf8802..0d05c28cc3d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/README.md +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/README.md @@ -3,5 +3,5 @@ This folder contains tests which test the functionality of the framework. These These tests are not part of the normal tier testing as they only should be run when the framework is changed in any way. -Additional testing should be performed with the converted Valhalla tests (see [JDK-8263024](https://bugs.openjdk.java.net/browse/JDK-8263024)) to make sure a changeset is correct (these are part of the Valhalla CI). +Additional testing should be performed with the converted Valhalla tests to make sure a changeset is correct (these are part of the Valhalla CI). diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TEST.ROOT b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TEST.ROOT index a5c2b99e4df..862dc229d2a 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TEST.ROOT +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TEST.ROOT @@ -1,3 +1,26 @@ +# +# Copyright (c) 2021, 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. +# + # Minimal TEST.ROOT file to run the internal framework tests as if they would have been placed inside # /test/hotspot/jtreg external.lib.roots = ../../../../../../../.. From 22ae413e529daaabac9358cedf87fa3879082b98 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 20 Apr 2021 15:56:26 +0200 Subject: [PATCH 116/131] Update and fixes from review comments --- .../hotspot/ir_framework/AbstractInfo.java | 12 --- .../ir_framework/IREncodingPrinter.java | 6 +- .../lib/hotspot/ir_framework/IRMatcher.java | 64 ++++++++------- .../lib/hotspot/ir_framework/IRMethod.java | 18 ++--- .../lib/hotspot/ir_framework/Scenario.java | 4 +- .../lib/hotspot/ir_framework/TestFormat.java | 15 ++-- .../hotspot/ir_framework/TestFramework.java | 80 ++++++++++--------- .../ir_framework/TestFrameworkException.java | 4 +- .../ir_framework/TestFrameworkExecution.java | 45 ++++++----- .../TestFrameworkPrepareFlags.java | 8 +- .../ir_framework/TestFrameworkSocket.java | 25 +++--- .../lib/hotspot/ir_framework/TestRun.java | 8 -- .../examples/BaseTestExample.java | 2 +- .../examples/CheckedTestExample.java | 2 +- .../examples/CustomRunTestExample.java | 2 +- .../ir_framework/examples/IRExample.java | 2 +- .../ir_framework/tests/TestBadFormat.java | 6 +- .../ir_framework/tests/TestIRMatching.java | 16 ++-- 18 files changed, 161 insertions(+), 158 deletions(-) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java index 1c43335694f..270deafa769 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java @@ -43,24 +43,12 @@ abstract public class AbstractInfo { private static final Random random = Utils.getRandomInstance(); protected final Class testClass; - private boolean toggleBool = false; private boolean onWarmUp = true; AbstractInfo(Class testClass) { this.testClass = testClass; } - /** - * Returns a different boolean each time this method is invoked (switching between {@code false} and {@code true}). - * The first invocation returns {@code false}. - * - * @return an inverted boolean of the result of the last invocation of this method. - */ - public boolean toggleBoolean() { - toggleBool = !toggleBool; - return toggleBool; - } - /** * Get the initialized {@link Random} object. * diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java index a15ef3f1bf2..6ed4e244323 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java @@ -49,8 +49,8 @@ class IREncodingPrinter { private int ruleIndex; public IREncodingPrinter() { - output.append(START).append("\n"); - output.append(",{comma separated applied @IR rule ids}\n"); + output.append(START).append(System.lineSeparator()); + output.append(",{comma separated applied @IR rule ids}").append(System.lineSeparator()); } /** @@ -85,7 +85,7 @@ public void emitRuleEncoding(Method m, boolean skipped) { output.append(",").append(validRules.get(i)); } } - output.append("\n"); + output.append(System.lineSeparator()); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java index d27551de2fe..ca54f065edf 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java @@ -102,7 +102,7 @@ private Map parseIREncoding(String irEncoding) { String line = lines[i].trim(); String[] splitComma = line.split(","); if (splitComma.length < 2) { - TestFramework.fail("Invalid IR match rule encoding. No comma found: " + splitComma[0]); + throw new TestFrameworkException("Invalid IR match rule encoding. No comma found: " + splitComma[0]); } String testName = splitComma[0]; int[] irRulesIdx = new int[splitComma.length - 1]; @@ -110,7 +110,7 @@ private Map parseIREncoding(String irEncoding) { try { irRulesIdx[j - 1] = Integer.parseInt(splitComma[j]); } catch (NumberFormatException e) { - TestFramework.fail("Invalid IR match rule encoding. No number found: " + splitComma[j]); + throw new TestFrameworkException("Invalid IR match rule encoding. No number found: " + splitComma[j]); } } irRulesMap.put(testName, irRulesIdx); @@ -124,7 +124,7 @@ private Map parseIREncoding(String irEncoding) { */ private void parseHotspotPidFile() { Map compileIdMap = new HashMap<>(); - try (BufferedReader br = Files.newBufferedReader(Paths.get("", hotspotPidFileName))) { + try (BufferedReader br = Files.newBufferedReader(Paths.get(hotspotPidFileName))) { String line; StringBuilder builder = new StringBuilder(); boolean append = false; @@ -158,7 +158,7 @@ private void parseHotspotPidFile() { } } } catch (IOException e) { - TestFramework.fail("Error while reading " + hotspotPidFileName, e); + throw new TestFrameworkException("Error while reading " + hotspotPidFileName, e); } } @@ -170,10 +170,10 @@ private void flushOutput(String line, StringBuilder builder, String currentMetho IRMethod irMethod = compilations.get(currentMethod); if (line.startsWith(""); line = line.replace(""", "\""); line = line.replace("'", "'"); + line = line.replace("&", "&"); } - builder.append(line).append("\n"); + builder.append(line).append(System.lineSeparator()); } private static int getCompileId(Matcher matcher) { - int compileId = -1; + int compileId; try { compileId = Integer.parseInt(matcher.group(1)); } catch (NumberFormatException e) { - TestRun.fail("Could not parse compile id", e); + throw new TestRunException("Could not parse compile id", e); } return compileId; } @@ -296,7 +296,7 @@ private void applyIRRule(int id) { // Logged. Continue to check other rules. } if (!failMsg.isEmpty()) { - failMsg.insert(0, "@IR rule " + (id + 1) + ": \"" + irAnno + "\"\n"); + failMsg.insert(0, "@IR rule " + (id + 1) + ": \"" + irAnno + "\"" + System.lineSeparator()); fails.computeIfAbsent(method, k -> new ArrayList<>()).add(failMsg.toString()); } } @@ -345,7 +345,7 @@ private void addFailOnFailsForOutput(StringBuilder failMsg, String testOutput) { List failOnNodes = IRNode.mergeNodes(irAnno.failOn()); Pattern pattern; Matcher matcher; - failMsg.append("- failOn: Graph contains forbidden nodes:\n"); + failMsg.append("- failOn: Graph contains forbidden nodes:").append(System.lineSeparator()); int nodeId = 1; for (String nodeRegex : failOnNodes) { pattern = Pattern.compile(nodeRegex); @@ -353,9 +353,10 @@ private void addFailOnFailsForOutput(StringBuilder failMsg, String testOutput) { long matchCount = matcher.results().count(); if (matchCount > 0) { matcher.reset(); - failMsg.append(" Regex ").append(nodeId).append(") ").append(nodeRegex).append("\n"); - failMsg.append(" Matched forbidden node").append(matchCount > 1 ? "s (" + matchCount + ")" : "").append(":\n"); - matcher.results().forEach(r -> failMsg.append(" ").append(r.group()).append("\n")); + failMsg.append(" Regex ").append(nodeId).append(": ").append(nodeRegex).append(System.lineSeparator()); + failMsg.append(" Matched forbidden node").append(matchCount > 1 ? "s (" + matchCount + ")" : "") + .append(":").append(System.lineSeparator()); + matcher.results().forEach(r -> failMsg.append(" ").append(r.group()).append(System.lineSeparator())); } nodeId++; } @@ -396,7 +397,7 @@ private void applyCounts(StringBuilder failMsg) { long actualCount = matcher.results().count(); if (!parsedComparator.getPredicate().test(actualCount, expectedCount)) { if (!hasFails) { - failMsg.append("- counts: Graph contains wrong number of nodes:\n"); + failMsg.append("- counts: Graph contains wrong number of nodes:").append(System.lineSeparator()); hasFails = true; } addCountsFail(failMsg, node, pattern, expectedCount, actualCount, countsId); @@ -415,7 +416,7 @@ private String getPostfixErrorMsg(String node) { * to the user. */ private void addCountsFail(StringBuilder failMsg, String node, Pattern pattern, long expectedCount, long actualCount, int countsId) { - failMsg.append(" Regex ").append(countsId).append(") ").append(node).append("\n"); + failMsg.append(" Regex ").append(countsId).append(": ").append(node).append(System.lineSeparator()); failMsg.append(" Expected ").append(expectedCount).append(" but found ").append(actualCount); if (actualCount > 0) { @@ -429,11 +430,11 @@ private void addCountsFail(StringBuilder failMsg, String node, Pattern pattern, } else { irMethod.needsOptoAssembly(); } - failMsg.append(" node").append(actualCount > 1 ? "s" : "").append(":\n"); - matcher.results().forEach(r -> failMsg.append(" ").append(r.group()).append("\n")); + failMsg.append(" node").append(actualCount > 1 ? "s" : "").append(":").append(System.lineSeparator()); + matcher.results().forEach(r -> failMsg.append(" ").append(r.group()).append(System.lineSeparator())); } else { irMethod.needsAllOutput(); - failMsg.append(" nodes.\n"); + failMsg.append(" nodes.").append(System.lineSeparator()); } } @@ -452,7 +453,7 @@ private void reportFailuresIfAny() { int failures = 0; for (Map.Entry> entry : fails.entrySet()) { Method method = entry.getKey(); - compilationsBuilder.append(">>> Compilation of ").append(method).append(":\n"); + compilationsBuilder.append(">>> Compilation of ").append(method).append(":").append(System.lineSeparator()); IRMethod irMethod = compilations.get(method.getName()); String output; if (irMethod.usesIdeal() && irMethod.usesOptoAssembly()) { @@ -464,16 +465,23 @@ private void reportFailuresIfAny() { } else { output = ""; } - compilationsBuilder.append(output).append("\n\n"); + compilationsBuilder.append(output).append(System.lineSeparator()).append(System.lineSeparator()); List list = entry.getValue(); - failuresBuilder.append("- Method \"").append(method).append("\":\n"); + failuresBuilder.append("- Method \"").append(method).append("\":").append(System.lineSeparator()); failures += list.size(); - list.forEach(s -> failuresBuilder.append(" * ").append(s.replace("\n", "\n ").trim()).append("\n")); - failuresBuilder.append("\n"); + list.forEach(s -> failuresBuilder.append(" * ") + .append(s.replace(System.lineSeparator(), + System.lineSeparator() + " ").trim()) + .append(System.lineSeparator())); + failuresBuilder.append(System.lineSeparator()); } - failuresBuilder.insert(0, ("\nOne or more @IR rules failed:\n\n" + "Failed IR Rules (" + failures + ")\n") - + "-----------------" + "-".repeat(String.valueOf(failures).length()) + "\n"); - failuresBuilder.append(">>> Check stdout for compilation output of the failed methods\n\n"); + failuresBuilder.insert(0, (System.lineSeparator() + System.lineSeparator() + + "One or more @IR rules failed:" + System.lineSeparator() + + System.lineSeparator() + "Failed IR Rules (" + failures + ")" + + System.lineSeparator()) + "-----------------" + + "-".repeat(String.valueOf(failures).length()) + System.lineSeparator()); + failuresBuilder.append(">>> Check stdout for compilation output of the failed methods") + .append(System.lineSeparator()).append(System.lineSeparator()); throw new IRViolationException(failuresBuilder.toString(), compilationsBuilder.toString()); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMethod.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMethod.java index b8f2be9ad50..3d144961212 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMethod.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMethod.java @@ -29,10 +29,10 @@ * Helper class to store information about a method that needs to be IR matched. */ class IRMethod { - final private Method method; - final private int[] ruleIds; - final private IR[] irAnnos; - final private StringBuilder outputBuilder; + private final Method method; + private final int[] ruleIds; + private final IR[] irAnnos; + private final StringBuilder outputBuilder; private String output; private String idealOutput; private String optoAssemblyOutput; @@ -65,18 +65,18 @@ public IR getIrAnno(int idx) { * The Ideal output comes always before the Opto Assembly output. We might parse multiple C2 compilations of this method. * Only keep the very last one by overriding 'output'. */ - public void appendIdealOutput(String idealOutput) { + public void setIdealOutput(String idealOutput) { outputBuilder.setLength(0); - this.idealOutput = "PrintIdeal:\n" + idealOutput; + this.idealOutput = "PrintIdeal:" + System.lineSeparator() + idealOutput; outputBuilder.append(this.idealOutput); } /** * The Opto Assembly output comes after the Ideal output. Simply append to 'output'. */ - public void appendOptoAssemblyOutput(String optoAssemblyOutput) { - this.optoAssemblyOutput = "PrintOptoAssembly:\n" + optoAssemblyOutput; - outputBuilder.append("\n\n").append(this.optoAssemblyOutput); + public void setOptoAssemblyOutput(String optoAssemblyOutput) { + this.optoAssemblyOutput = "PrintOptoAssembly:" + System.lineSeparator() + optoAssemblyOutput; + outputBuilder.append(System.lineSeparator()).append(System.lineSeparator()).append(this.optoAssemblyOutput); output = outputBuilder.toString(); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java index ded24ec1649..929fa74ab84 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java @@ -56,8 +56,8 @@ public class Scenario { try { Arrays.stream(SCENARIOS.split("\\s*,\\s*")).map(Integer::parseInt).forEachOrdered(enabledScenarios::add); } catch (NumberFormatException e) { - TestRun.fail("Provided a scenario index in the -DScenario comma-separated list which is not " + - "a number: " + SCENARIOS); + throw new TestRunException("Provided a scenario index in the -DScenario comma-separated list which is not " + + "a number: " + SCENARIOS); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java index 83e5dc6d833..29ceff7fd9e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java @@ -34,14 +34,13 @@ class TestFormat { public static void check(boolean test, String failureMessage) { if (!test) { - FAILURES.add(failureMessage); - throw new TestFormatException(failureMessage); + fail(failureMessage); } } public static void checkNoThrow(boolean test, String failureMessage) { if (!test) { - FAILURES.add(failureMessage); + failNoThrow(failureMessage); } } @@ -60,11 +59,13 @@ public static void reportIfAnyFailures() { return; } StringBuilder builder = new StringBuilder(); - builder.append("\nOne or more format violations have been detected:\n\n"); - builder.append("Violations (").append(FAILURES.size()).append(")\n"); - builder.append("-------------").append("-".repeat(String.valueOf(FAILURES.size()).length())).append("\n"); + builder.append(System.lineSeparator()).append("One or more format violations have been detected:") + .append(System.lineSeparator()).append(System.lineSeparator()); + builder.append("Violations (").append(FAILURES.size()).append(")").append(System.lineSeparator()); + builder.append("-------------").append("-".repeat(String.valueOf(FAILURES.size()).length())) + .append(System.lineSeparator()); for (String failure : FAILURES) { - builder.append(" - ").append(failure).append("\n"); + builder.append(" - ").append(failure).append(System.lineSeparator()); } builder.append("/============/"); FAILURES.clear(); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index bc9854b7e45..67eeebfb905 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -136,7 +136,7 @@ public class TestFramework { -DReportStdout=true or for even more fine-grained logging use -DVerbose=true. ############################################################# - """ + "\n"; + """ + System.lineSeparator(); private static final int WARMUP_ITERATIONS = Integer.getInteger("Warmup", -1); private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.getBoolean("PreferCommandLineFlags"); @@ -146,6 +146,7 @@ public class TestFramework { private boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); private boolean shouldVerifyIR; // Should we perform IR matching? private static String lastTestVMOutput; + private static boolean toggleBool; private final Class testClass; private Set> helperClasses = null; @@ -348,9 +349,9 @@ public TestFramework addFlags(String... flags) { * while testing {@code testClass} (also see description of {@link TestFramework}). * *

    - * If a class is used by the test class that does not specify any compile command annotations, you do not need - * to include it with this method. If no helper class specifies any compile commands, you do not need to call - * this method at all. + * Duplicates in {@code helperClasses} are ignored. If a class is used by the test class that does not specify any + * compile command annotations, you do not need to include it with this method. If no helper class specifies any + * compile commands, you do not need to call this method at all. * *

    * The testing can be started by invoking {@link #start()}. @@ -367,11 +368,7 @@ public TestFramework addHelperClasses(Class... helperClasses) { this.helperClasses = new HashSet<>(); } - for (var helperClass : helperClasses) { - TestRun.check(!this.helperClasses.contains(helperClass), - "Cannot add the same class twice: " + helperClass); - this.helperClasses.add(helperClass); - } + this.helperClasses.addAll(Arrays.asList(helperClasses)); return this; } @@ -416,12 +413,12 @@ public void start() { try { start(null); } catch (TestVMException e) { - System.err.println("\n" + e.getExceptionInfo()); + System.err.println(System.lineSeparator() + e.getExceptionInfo()); throw e; } catch (IRViolationException e) { System.out.println("Compilation(s) of failed match(es):"); System.out.println(e.getCompilations()); - System.err.println("\n" + e.getExceptionInfo()); + System.err.println(System.lineSeparator() + e.getExceptionInfo()); throw e; } } else { @@ -595,6 +592,19 @@ public static void assertDeoptimizedByC2(Method m) { TestFrameworkExecution.assertDeoptimizedByC2(m); } + /** + * Returns a different boolean each time this method is invoked (switching between {@code false} and {@code true}). + * The very first invocation returns {@code false}. Note that this method could be used by different tests and + * thus the first invocation for a test could be {@code true} or {@code false} depending on how many times + * other tests have already invoked this method. + * + * @return an inverted boolean of the result of the last invocation of this method. + */ + public static boolean toggleBoolean() { + toggleBool = !toggleBool; + return toggleBool; + } + /* * End of public interface methods */ @@ -631,7 +641,8 @@ private void disableIRVerificationIfNotFeasible() { // No IR verification is done if additional non-whitelisted JTreg VM or Javaoptions flag is specified. VERIFY_IR = onlyWhitelistedJTregVMAndJavaOptsFlags(); if (!VERIFY_IR) { - System.out.println("IR verification disabled due to using non-whitelisted JTreg VM or Javaoptions flag(s).\n"); + System.out.println("IR verification disabled due to using non-whitelisted JTreg VM or Javaoptions flag(s)." + + System.lineSeparator()); } } } @@ -644,7 +655,6 @@ private void disableIRVerificationIfNotFeasible() { private void startWithScenarios() { Map exceptionMap = new TreeMap<>(Comparator.comparingInt(Scenario::getIndex)); for (Scenario scenario : scenarios) { - int scenarioIndex = scenario.getIndex(); try { start(scenario); } catch (TestFormatException e) { @@ -665,7 +675,7 @@ private void reportScenarioFailures(Map exceptionMap) { .map(s -> String.valueOf(s.getIndex())) .collect(Collectors.joining(", #")); StringBuilder builder = new StringBuilder(failedScenarios); - builder.append("\n\n"); + builder.append(System.lineSeparator()).append(System.lineSeparator()); for (Map.Entry entry : exceptionMap.entrySet()) { Exception e = entry.getValue(); Scenario scenario = entry.getKey(); @@ -678,30 +688,33 @@ private void reportScenarioFailures(Map exceptionMap) { System.out.println((scenario != null ? "Scenario #" + scenario.getIndex() + " - " : "") + "Compilation(s) of failed matche(s):"); System.out.println(irException.getCompilations()); - builder.append(errorMsg).append("\n").append(irException.getExceptionInfo()).append(e.getMessage()); + builder.append(errorMsg).append(System.lineSeparator()).append(irException.getExceptionInfo()) + .append(e.getMessage()); } else if (e instanceof TestVMException) { - builder.append(errorMsg).append("\n").append(((TestVMException) e).getExceptionInfo()); + builder.append(errorMsg).append(System.lineSeparator()).append(((TestVMException) e).getExceptionInfo()); } else { // Print stack trace otherwise StringWriter errors = new StringWriter(); e.printStackTrace(new PrintWriter(errors)); builder.append(errors.toString()); } - builder.append("\n"); + builder.append(System.lineSeparator()); } System.err.println(builder.toString()); if (!VERBOSE && !REPORT_STDOUT && !TESTLIST && !EXCLUDELIST) { // Provide a hint to the user how to get additional output/debugging information. System.err.println(RERUN_HINT); } - TestRun.fail(failedScenarios + ". Please check stderr for more information."); + throw new TestRunException(failedScenarios + ". Please check stderr for more information."); } private static String getScenarioTitleAndFlags(Scenario scenario) { StringBuilder builder = new StringBuilder(); String title = "Scenario #" + scenario.getIndex(); - builder.append(title).append("\n").append("=".repeat(title.length())).append("\n"); - builder.append("Scenario flags: [").append(String.join(", ", scenario.getFlags())).append("]\n"); + builder.append(title).append(System.lineSeparator()).append("=".repeat(title.length())) + .append(System.lineSeparator()); + builder.append("Scenario flags: [").append(String.join(", ", scenario.getFlags())).append("]") + .append(System.lineSeparator()); return builder.toString(); } @@ -827,8 +840,7 @@ private void runTestVM(List additionalFlags) { // Java options in prepareTestVMFlags(). oa = ProcessTools.executeProcess(process); } catch (Exception e) { - fail("Error while executing Test VM", e); - return; + throw new TestFrameworkException("Error while executing Test VM", e); } JVMOutput output = new JVMOutput(oa, scenario, process); lastTestVMOutput = oa.getOutput(); @@ -942,7 +954,7 @@ private void throwTestVMException(JVMOutput vmOutput) { Pattern pattern = Pattern.compile("Violations \\(\\d+\\)[\\s\\S]*(?=/============/)"); Matcher matcher = pattern.matcher(stdErr); TestFramework.check(matcher.find(), "Must find violation matches"); - throw new TestFormatException("\n\n" + matcher.group()); + throw new TestFormatException(System.lineSeparator() + System.lineSeparator() + matcher.group()); } else if (stdErr.contains("NoTestsRunException")) { shouldVerifyIR = false; throw new NoTestsRunException(">>> No tests run due to empty set specified with -DTest and/or -DExclude. " + @@ -954,17 +966,9 @@ private void throwTestVMException(JVMOutput vmOutput) { static void check(boolean test, String failureMessage) { if (!test) { - fail(failureMessage); + throw new TestFrameworkException(failureMessage); } } - - static void fail(String failureMessage) { - throw new TestFrameworkException("Internal Test Framework exception - please file a bug:\n" + failureMessage); - } - - static void fail(String failureMessage, Throwable e) { - throw new TestFrameworkException("Internal Test Framework exception - please file a bug:\n" + failureMessage, e); - } } /** @@ -989,7 +993,8 @@ public Scenario getScenario() { } public String getCommandLine() { - return "Command Line:\n" + String.join(" ", process.command()) + "\n\n"; + return "Command Line:" + System.lineSeparator() + String.join(" ", process.command()) + + System.lineSeparator(); } public int getExitCode() { @@ -1021,7 +1026,8 @@ public String getExceptionInfo(boolean stripRerunHint) { String rerunHint = ""; String stdOut = ""; if (exitCode == 134) { - stdOut = "\n\nStandard Output\n---------------\n" + getOutput(); + stdOut = System.lineSeparator() + System.lineSeparator() + "Standard Output" + System.lineSeparator() + + "---------------" + System.lineSeparator() + getOutput(); } else if (!stripRerunHint) { rerunHint = TestFramework.RERUN_HINT; } @@ -1029,8 +1035,10 @@ public String getExceptionInfo(boolean stripRerunHint) { // IR exception return getCommandLine() + rerunHint; } else { - return "TestFramework test VM exited with code " + exitCode + "\n" - + stdOut + "\n" + getCommandLine() + "\n\nError Output\n------------\n" + stdErr + "\n\n" + rerunHint; + return "TestFramework test VM exited with code " + exitCode + System.lineSeparator() + stdOut + + System.lineSeparator() + getCommandLine() + System.lineSeparator() + System.lineSeparator() + + "Error Output" + System.lineSeparator() + "------------" + System.lineSeparator() + stdErr + + System.lineSeparator() + System.lineSeparator() + rerunHint; } } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java index a6c3dd03efa..9f2e07f9f93 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java @@ -30,10 +30,10 @@ public class TestFrameworkException extends RuntimeException { TestFrameworkException(String message) { - super(message); + super("Internal Test Framework exception - please file a bug:" + System.lineSeparator() + message); } TestFrameworkException(String message, Throwable e) { - super(message, e); + super("Internal Test Framework exception - please file a bug:" + System.lineSeparator() + message, e); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index b29f8376590..63f0a30a651 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -50,7 +50,7 @@ public class TestFrameworkExecution { try { WHITE_BOX = WhiteBox.getWhiteBox(); } catch (UnsatisfiedLinkError e) { - System.err.println("\n" + """ + System.err.println(System.lineSeparator() + """ ########################################################## - Did you call a test-related interface method from TestFramework in main() of your test? Make sure to @@ -164,8 +164,7 @@ protected static Class getClassObject(String className, String classType) { try { c = Class.forName(className); } catch (Exception e) { - TestRun.fail("Could not find " + classType + " class", e); - return null; + throw new TestRunException("Could not find " + classType + " class", e); } return c; } @@ -430,7 +429,7 @@ private void checkCompilationCommandAnnotations(Executable ex, ForceInline force Run runAnno = getAnnotation(ex, Run.class); Check checkAnno = getAnnotation(ex, Check.class); TestFormat.check((testAnno == null && runAnno == null && checkAnno == null) || Stream.of(forceCompileAnno, dontCompileAnno, forceInlineAnno, dontInlineAnno).noneMatch(Objects::nonNull), - "Cannot use explicit compile command annotations (@ForceInline, @DontInline," + + "Cannot use explicit compile command annotations (@ForceInline, @DontInline, " + "@ForceCompile or @DontCompile) together with @Test, @Check or @Run: " + ex + ". Use compLevel in @Test for fine tuning."); if (Stream.of(forceInlineAnno, dontCompileAnno, dontInlineAnno).filter(Objects::nonNull).count() > 1) { // Failure @@ -789,8 +788,10 @@ private void checkForcedCompilationsCompleted() { elapsed = System.currentTimeMillis() - started; } while (elapsed < 5000); StringBuilder builder = new StringBuilder(); - forceCompileMap.forEach((key, value) -> builder.append("- ").append(key).append(" at CompLevel.").append(value).append("\n")); - TestRun.fail("Could not force compile the following @ForceCompile methods:\n" + builder.toString()); + forceCompileMap.forEach((key, value) -> builder.append("- ").append(key).append(" at CompLevel.").append(value) + .append(System.lineSeparator())); + throw new TestRunException("Could not force compile the following @ForceCompile methods:" + + System.lineSeparator() + builder.toString()); } /** @@ -814,7 +815,7 @@ private void runTests() { if (SHUFFLE_TESTS) { // Execute tests in random order (execution sequence affects profiling). This is done by default. - Collections.shuffle(testList); + Collections.shuffle(testList, Utils.getRandomInstance()); } StringBuilder builder = new StringBuilder(); int failures = 0; @@ -833,7 +834,8 @@ private void runTests() { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); - builder.append(test.toString()).append(":\n").append(sw.toString()).append("\n\n"); + builder.append(test.toString()).append(":").append(System.lineSeparator()).append(sw.toString()) + .append(System.lineSeparator()).append(System.lineSeparator()); failures++; } if (PRINT_TIMES || VERBOSE) { @@ -852,17 +854,17 @@ private void runTests() { // Print execution times if (VERBOSE || PRINT_TIMES) { - System.out.println("\n\nTest execution times:"); + System.out.println(System.lineSeparator() + System.lineSeparator() + "Test execution times:"); for (Map.Entry entry : durations.entrySet()) { - System.out.format("%-10s%15d ns\n", entry.getValue() + ":", entry.getKey()); + System.out.format("%-10s%15d ns" + System.lineSeparator(), entry.getValue() + ":", entry.getKey()); } } if (failures > 0) { // Finally, report all occurred exceptions in a nice format. - String msg = "\n\nTest Failures (" + failures + ")\n" + - "----------------" + "-".repeat(String.valueOf(failures).length()); - throw new TestRunException(msg + "\n" + builder.toString()); + String msg = System.lineSeparator() + System.lineSeparator() + "Test Failures (" + failures + ")" + + System.lineSeparator() + "----------------" + "-".repeat(String.valueOf(failures).length()); + throw new TestRunException(msg + System.lineSeparator() + builder.toString()); } } @@ -973,7 +975,7 @@ private static TriState compiledAtLevel(Method m, CompLevel level) { case ANY -> { return TriState.Yes; } - default -> TestRun.fail("compiledAtLevel() should not be called with " + level); + default -> throw new TestRunException("compiledAtLevel() should not be called with " + level); } } if (!USE_COMPILER || XCOMP || TEST_C1 || @@ -1147,7 +1149,8 @@ final protected void waitForCompilation(DeclaredTest test) { return; } } while (elapsed < WAIT_FOR_COMPILATION_TIMEOUT); - TestRun.fail(testMethod + " not compiled after waiting for " + WAIT_FOR_COMPILATION_TIMEOUT/1000 + " s"); + throw new TestRunException(testMethod + " not compiled after waiting for " + + WAIT_FOR_COMPILATION_TIMEOUT/1000 + " s"); } /** @@ -1412,7 +1415,8 @@ private void compileMultipleTests() { try { executor.awaitTermination(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - TestRun.fail("Some compilations did not complete after " + timeout + "ms for @Run method " + runMethod); + throw new TestRunException("Some compilations did not complete after " + timeout + + "ms for @Run method " + runMethod); } } @@ -1439,11 +1443,12 @@ protected void checkCompilationLevel(DeclaredTest test) { String message = "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " + level.name() + " for " + test.getTestMethod() + "."; switch (mode) { - case STANDALONE -> TestFramework.fail("Should not be called for STANDALONE method " + runMethod); - case NORMAL -> message = message + "\nCheck your @Run method " + runMethod + " to ensure that " - + test.getTestMethod() + " is called at least once in each iteration."; + case STANDALONE -> throw new TestFrameworkException("Should not be called for STANDALONE method " + runMethod); + case NORMAL -> message = message + System.lineSeparator() + "Check your @Run method " + runMethod + + " to ensure that " + test.getTestMethod() + + " is called at least once in each iteration."; } - TestRun.fail(message); + throw new TestRunException(message); } } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java index ac26ba8784e..75785af0b93 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java @@ -40,8 +40,7 @@ class TestFrameworkPrepareFlags { try { WHITE_BOX = WhiteBox.getWhiteBox(); } catch (UnsatisfiedLinkError e) { - TestFramework.fail("Could not load WhiteBox", e); - throw e; // Not reached + throw new TestFrameworkException("Could not load WhiteBox", e); } } @@ -87,8 +86,9 @@ public static void main(String[] args) { * Emit test VM flags to standard output to parse them from the TestFramework "driver" VM again which adds them to the test VM. */ private static void emitTestVMFlags(ArrayList flags) { - String encoding = TestFramework.TEST_VM_FLAGS_START + "\n" + String.join(TestFramework.TEST_VM_FLAGS_DELIMITER, flags) - + "\n" + TestFramework.TEST_VM_FLAGS_END; + String encoding = TestFramework.TEST_VM_FLAGS_START + System.lineSeparator() + + String.join(TestFramework.TEST_VM_FLAGS_DELIMITER, flags) + + System.lineSeparator() + TestFramework.TEST_VM_FLAGS_END; TestFrameworkSocket.write(encoding, "flag encoding"); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java index 4bf0583b5ab..24049f1722e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java @@ -49,7 +49,7 @@ class TestFrameworkSocket implements AutoCloseable { private final String serverPortPropertyFlag; private FutureTask socketTask; - private ServerSocket serverSocket; + private final ServerSocket serverSocket; private static TestFrameworkSocket singleton = null; @@ -57,7 +57,7 @@ private TestFrameworkSocket() { try { serverSocket = new ServerSocket(0); } catch (IOException e) { - TestFramework.fail("Failed to create TestFramework server socket", e); + throw new TestFrameworkException("Failed to create TestFramework server socket", e); } int port = serverSocket.getLocalPort(); if (TestFramework.VERBOSE) { @@ -95,12 +95,11 @@ private FutureTask initSocketTask() { StringBuilder builder = new StringBuilder(); String next; while ((next = in.readLine()) != null) { - builder.append(next).append("\n"); + builder.append(next).append(System.lineSeparator()); } return builder.toString(); } catch (IOException e) { - TestFramework.fail("Server socket error", e); - return null; + throw new TestFrameworkException("Server socket error", e); } }); } @@ -110,7 +109,7 @@ public void close() { try { serverSocket.close(); } catch (IOException e) { - TestFramework.fail("Could not close socket", e); + throw new TestFrameworkException("Could not close socket", e); } } @@ -145,14 +144,14 @@ public static void write(String msg, String type, boolean stdout) { } catch (Exception e) { // When the test VM is directly run, we should ignore all messages that would normally be sent to the // driver VM. - String failMsg = "\n\n" + """ + String failMsg = System.lineSeparator() + System.lineSeparator() + """ ########################################################### Did you directly run the test VM (TestFrameworkExecution) to reproduce a bug? => Append the flag -DReproduce=true and try again! ########################################################### """; - TestRun.fail(failMsg, e); + throw new TestRunException(failMsg, e); } if (TestFramework.VERBOSE) { System.out.println("Written " + type + " to socket:"); @@ -183,8 +182,7 @@ public String getOutput() { return socketTask.get(); } catch (Exception e) { - TestFramework.fail("Could not read from socket task", e); - return null; + throw new TestFrameworkException("Could not read from socket task", e); } } @@ -198,7 +196,7 @@ public String getOutputPrintStdout() { if (TestFramework.TESTLIST || TestFramework.EXCLUDELIST) { StringBuilder builder = new StringBuilder(); Scanner scanner = new Scanner(output); - System.out.println("\nRun flag defined test list"); + System.out.println(System.lineSeparator() + "Run flag defined test list"); System.out.println("--------------------------"); while (scanner.hasNextLine()) { String line = scanner.nextLine(); @@ -206,7 +204,7 @@ public String getOutputPrintStdout() { line = "> " + line.substring(STDOUT_PREFIX.length()); System.out.println(line); } else { - builder.append(line).append("\n"); + builder.append(line).append(System.lineSeparator()); } } System.out.println(); @@ -215,8 +213,7 @@ public String getOutputPrintStdout() { return output; } catch (Exception e) { - TestFramework.fail("Could not read from socket task", e); - return null; + throw new TestFrameworkException("Could not read from socket task", e); } } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java index 753333d8f84..39d1fa49c74 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java @@ -33,12 +33,4 @@ public static void check(boolean test, String failureMessage) { throw new TestRunException(failureMessage); } } - - public static void fail(String failureMessage) { - throw new TestRunException(failureMessage); - } - - public static void fail(String failureMessage, Exception e) { - throw new TestRunException(failureMessage, e); - } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java index b36630bbb1e..4ea33815248 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java @@ -62,7 +62,7 @@ public class BaseTestExample { int iFld; public static void main(String[] args) { - TestFramework.run(); // equivalent to TestFramework.run(TestSimpleTest.class) + TestFramework.run(); // equivalent to TestFramework.run(BaseTestExample.class) } // Test without arguments. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java index 527a7c036af..92887211dcd 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java @@ -69,7 +69,7 @@ public class CheckedTestExample { public static void main(String[] args) { - TestFramework.run(); // equivalent to TestFramework.run(TestSimpleTest.class) + TestFramework.run(); // equivalent to TestFramework.run(CheckedTestExample.class) } @Test diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java index d431515f1a9..18c826e12bc 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java @@ -77,7 +77,7 @@ public class CustomRunTestExample { public static void main(String[] args) { - TestFramework.run(); // equivalent to TestFramework.run(TestSimpleTest.class) + TestFramework.run(); // equivalent to TestFramework.run(CustomRunTestExample.class) } @Test diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java index 71bae08683c..6a5e758398c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java @@ -142,7 +142,7 @@ class FailingExamples { @IR(failOn = IRNode.STORE) @IR(failOn = {IRNode.STORE, IRNode.LOOP}) // LOOP regex not found but STORE regex, letting the rule fail @IR(failOn = {IRNode.LOOP, IRNode.STORE}) // Order does not matter - @IR(failOn = {IRNode.STORE, IRNode.LOAD}) // LOOP and STORE regex, letting the rule fail + @IR(failOn = {IRNode.STORE, IRNode.LOAD}) // STORE and LOAD regex found, letting the rule fail @IR(failOn = {"LoadI"}) // LoadI can be found in PrintIdeal letting the rule fail // Store to iFld, store, and store to class IRExample, all 3 regexes found letting the rule fail @IR(failOn = {IRNode.STORE_OF_FIELD, "iFld", IRNode.STORE, IRNode.STORE_OF_CLASS, "IRExample"}) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java index 9e8b6b05e55..35229f46386 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java @@ -74,10 +74,12 @@ private static void expectTestFormatException(Class clazz, Class... helper } String msg = e.getMessage(); Violations violations = getViolations(clazz, helpers); - violations.getFailedMethods().forEach(f -> Asserts.assertTrue(msg.contains(f), "Could not find " + f + " in violations\n" + msg)); + violations.getFailedMethods().forEach( + f -> Asserts.assertTrue(msg.contains(f), + "Could not find " + f + " in violations" + System.lineSeparator() + msg)); Pattern pattern = Pattern.compile("Violations \\((\\d+)\\)"); Matcher matcher = pattern.matcher(msg); - Asserts.assertTrue(matcher.find(), "Could not find violations in\n" + msg); + Asserts.assertTrue(matcher.find(), "Could not find violations in" + System.lineSeparator() + msg); int violationCount = Integer.parseInt(matcher.group(1)); Asserts.assertEQ(violationCount, violations.getViolationCount(), msg); return; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java index b978e3b8cc9..77fd08b9d92 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java @@ -309,7 +309,8 @@ public static void findIrIds(String output, String method, int... numbers) { builder.append(j); } } - Asserts.assertTrue(output.contains(builder.toString()), "Could not find encoding: \"" + builder.toString() + "\n"); + Asserts.assertTrue(output.contains(builder.toString()), "Could not find encoding: \"" + builder.toString() + + System.lineSeparator()); } } @@ -1421,7 +1422,7 @@ public static GoodRuleConstraint create(Class klass, String methodName, int r @Override protected void checkIRRule(String irRule) { - Asserts.fail(errorPrefix() + " should not fail:\n" + irRule); + Asserts.fail(errorPrefix() + " should not fail:" + System.lineSeparator() + irRule); } } @@ -1438,7 +1439,7 @@ public static GoodFailOnConstraint create(Class klass, String methodName, int @Override protected void checkIRRule(String irRule) { - Asserts.assertFalse(irRule.contains("- failOn"), errorPrefix() + " should not have failed:\n" + irRule); + Asserts.assertFalse(irRule.contains("- failOn"), errorPrefix() + " should not have failed:" + System.lineSeparator() + irRule); } } @@ -1455,7 +1456,8 @@ public static GoodCountsConstraint create(Class klass, String methodName, int @Override protected void checkIRRule(String irRule) { - Asserts.assertFalse(irRule.contains("- counts"), errorPrefix() + " should not have failed with counts:\n" + irRule); + Asserts.assertFalse(irRule.contains("- counts"), errorPrefix() + " should not have failed with counts:" + + System.lineSeparator() + irRule); } } @@ -1500,10 +1502,10 @@ protected String errorPrefix() { private static Pattern initIRPattern(String category, int ruleIdx) { if (category.equals("failOn")) { return Pattern.compile("rule " + ruleIdx + ":.*\\R.*- failOn: Graph contains forbidden nodes.*\\R" + - ".*Regex \\d+\\).*\\R.*Matched forbidden node.*"); + ".*Regex \\d+:.*\\R.*Matched forbidden node.*"); } else { return Pattern.compile("rule " + ruleIdx + ":.*\\R.*- counts: Graph contains wrong number of nodes:\\R" + - ".*Regex \\d+\\).*\\R.*Expected.*"); + ".*Regex \\d+:.*\\R.*Expected.*"); } } @@ -1523,7 +1525,7 @@ protected void checkIRRule(String irRule) { Pattern pattern; Matcher matcher; for (int regexIndex : this.regexIndexes) { - pattern = Pattern.compile("Regex " + regexIndex + "\\).*"); + pattern = Pattern.compile("Regex " + regexIndex + ":.*"); matcher = pattern.matcher(categoryString); if (isGood) { Asserts.assertFalse(matcher.find(), errorPrefix() + " failed with Regex " + regexIndex); From 52a0474bf921f00198b260950b9122e33a3d4a0c Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 27 Apr 2021 17:46:23 +0200 Subject: [PATCH 117/131] Apply review comments and fix converted tests --- .../compiler/valhalla/inlinetypes/TestC1.java | 24 +- .../inlinetypes/TestCallingConventionC1.java | 138 +++++------ .../inlinetypes/TestGetfieldChains.java | 14 +- .../valhalla/inlinetypes/TestWithfieldC1.java | 18 +- .../hotspot/ir_framework/AbstractInfo.java | 6 +- .../lib/hotspot/ir_framework/Argument.java | 3 +- .../hotspot/ir_framework/ArgumentValue.java | 18 +- .../test/lib/hotspot/ir_framework/Check.java | 1 - .../lib/hotspot/ir_framework/CheckAt.java | 3 +- .../CheckedTestFrameworkException.java | 1 - .../lib/hotspot/ir_framework/CompLevel.java | 76 ++++-- .../lib/hotspot/ir_framework/Compiler.java | 63 +++++ .../hotspot/ir_framework/DeclaredTest.java | 6 +- .../lib/hotspot/ir_framework/DontCompile.java | 14 +- .../hotspot/ir_framework/ForceCompile.java | 22 +- .../ForceCompileClassInitializer.java | 20 +- .../jdk/test/lib/hotspot/ir_framework/IR.java | 1 - .../ir_framework/IREncodingPrinter.java | 11 +- .../lib/hotspot/ir_framework/IRMatcher.java | 14 +- .../test/lib/hotspot/ir_framework/IRNode.java | 2 +- .../ir_framework/NoTestsRunException.java | 1 - .../test/lib/hotspot/ir_framework/Run.java | 3 +- .../lib/hotspot/ir_framework/RunMode.java | 2 +- .../lib/hotspot/ir_framework/Scenario.java | 28 ++- .../test/lib/hotspot/ir_framework/Test.java | 1 - .../ir_framework/TestFormatException.java | 1 - .../hotspot/ir_framework/TestFramework.java | 30 +-- .../ir_framework/TestFrameworkException.java | 1 - .../ir_framework/TestFrameworkExecution.java | 234 ++++++++---------- .../ir_framework/TestFrameworkSocket.java | 3 +- .../lib/hotspot/ir_framework/TestRun.java | 1 - .../ir_framework/TestRunException.java | 1 - .../examples/BaseTestExample.java | 1 - .../ir_framework/examples/IRExample.java | 1 - .../ir_framework/tests/TestBadFormat.java | 25 +- .../ir_framework/tests/TestCompLevels.java | 9 +- .../ir_framework/tests/TestControls.java | 21 +- .../tests/TestDIgnoreCompilerControls.java | 89 +++++++ 38 files changed, 506 insertions(+), 401 deletions(-) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/Compiler.java create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDIgnoreCompilerControls.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java index fb433329df1..3c6e57ed02d 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java @@ -69,7 +69,7 @@ public static void main(String[] args) { } // JDK-8229799 - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public long test1(Object a, Object b, long n) { long r; n += (a == b) ? 0x5678123456781234L : 0x1234567812345678L; @@ -97,7 +97,7 @@ static primitive class SimpleValue2 { // JDK-8231961 // Test that the value numbering optimization does not remove // the second load from the buffered array element. - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test2(SimpleValue2[] array) { return array[0].value + array[0].value; } @@ -115,7 +115,7 @@ public void test2_verifier() { // sub-elements of a flattened array without copying the element first // Test access to a null array - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test3(MyValue2[] array, int index) { return array[index].x; } @@ -132,7 +132,7 @@ public void test3_verifier() { } // Test out of bound accesses - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test4(MyValue2[] array, int index) { return array[index].x; } @@ -157,7 +157,7 @@ public void test4_verifier() { } // Test 1st level sub-element access to primitive field - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test5(MyValue2[] array, int index) { return array[index].x; } @@ -172,7 +172,7 @@ public void test5_verifier() { } // Test 1st level sub-element access to flattened field - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public MyValue2Inline test6(MyValue2[] array, int index) { return array[index].v; } @@ -231,7 +231,7 @@ static primitive class TestValue { } } - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public Big test7(TestValue[] array, int index) { return array[index].big; } @@ -248,7 +248,7 @@ public void test7_verifier() { } // Test 2nd level sub-element access to primitive field - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public byte test8(MyValue1[] array, int index) { return array[index].v2.y; } @@ -271,7 +271,7 @@ public void test8_verifier() { // (OOB, null pointer) static primitive class EmptyType {} - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public EmptyType test9() { EmptyType[] array = new EmptyType[10]; return array[4]; @@ -283,7 +283,7 @@ public void test9_verifier() { Asserts.assertEQ(et, EmptyType.default); } - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public EmptyType test10(EmptyType[] array) { return array[0]; } @@ -295,7 +295,7 @@ public void test10_verifier() { Asserts.assertEQ(et, EmptyType.default); } - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public EmptyType test11(EmptyType[] array, int index) { return array[index]; } @@ -326,7 +326,7 @@ public void test11_verifier() { Asserts.assertNotNull(e); } - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public void test12(EmptyType[] array, int index, EmptyType value) { array[index] = value; } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java index 1e6ee9501ae..2b6b13b87d3 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java @@ -56,7 +56,7 @@ public static void main(String[] args) { "-XX:+TieredCompilation", "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+StressInlineTypeReturnedAsFields"), - // Same as above, but flip all the compLevel=CompLevel.C1 and compLevel=CompLevel.C2, so we test + // Same as above, but flip all the compLevel=CompLevel.C1_SIMPLE and compLevel=CompLevel.C2, so we test // the compliment of the above scenario. new Scenario(2, "-XX:CICompilerCount=2", @@ -95,7 +95,7 @@ public int func() { return x + y; } - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) public int func_c1(Point p) { return x + y + p.x + p.y; } @@ -173,9 +173,9 @@ static class MyImplPojo0 implements Intf { static class MyImplPojo1 implements Intf { int field = 1000; - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) public int func1(int a, int b) { return field + a + b + 20; } - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 20; } } @@ -203,10 +203,10 @@ static primitive class MyImplVal1 implements Intf { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) public int func1(int a, int b) { return field + a + b + 300; } - @DontInline @ForceCompile(CompLevel.C1) + @DontInline @ForceCompile(CompLevel.C1_SIMPLE) public int func2(int a, int b, Point p) { return field + a + b + p.x + p.y + 300; } } @@ -335,19 +335,19 @@ public RefPoint(Number x, Number y) { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) public final int final_func(RefPoint rp2) { // opt_virtual_call return this.x.n + this.y.n + rp2.x.n + rp2.y.n; } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) public int func1(RefPoint rp2) { return this.x.n + this.y.n + rp2.x.n + rp2.y.n; } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return x.n + y.n + rp1.x.n + rp1.y.n + @@ -365,7 +365,7 @@ public int func1(RefPoint rp2) { return rp2.x.n + rp2.y.n + 1111111; } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return 111111 + rp1.x.n + rp1.y.n + @@ -383,7 +383,7 @@ public int func1(RefPoint rp2) { return rp2.x.n + rp2.y.n + 2222222; } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) public int func2(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return 222222 + rp1.x.n + rp1.y.n + @@ -432,7 +432,7 @@ static primitive class TooBigToReturnAsFields { //********************************************************************** //** C1 passes inline type to interpreter (static) - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test1() { return test1_helper(pointField); } @@ -452,7 +452,7 @@ public void test1_verifier(RunInfo info) { } //** C1 passes inline type to interpreter (monomorphic) - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test2() { return test2_helper(pointField); } @@ -472,7 +472,7 @@ public void test2_verifier(RunInfo info) { } // C1 passes inline type to interpreter (megamorphic: vtable) - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test3(Functor functor) { return functor.apply_interp(pointField); } @@ -504,7 +504,7 @@ public void test3b_verifier(RunInfo info) { } // C1 passes inline type to interpreter (megamorphic: itable) - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test4(FunctorInterface fi) { return fi.apply_interp(pointField); } @@ -524,7 +524,7 @@ public void test4_verifier(RunInfo info) { //********************************************************************** // Interpreter passes inline type to C1 (static) - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) static public int test20(Point p1, long l, Point p2) { return p1.x + p2.y; } @@ -566,7 +566,7 @@ public int test30() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test30_helper(Point p) { return p.x + p.y; } @@ -588,7 +588,7 @@ public int test31() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test31_helper(Point p1, Point p2) { return p1.x + p2.y; } @@ -610,7 +610,7 @@ public int test32() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test32_helper(int x, Point p1, int y, Point p2) { return p1.x + p2.y + x + y; } @@ -664,7 +664,7 @@ public int test35() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test35_helper(int a1, int a2, int a3, int a4, int a5, Point p) { return a1 + a2 + a3 + a4 + a5 + p.x + p.y; } @@ -686,7 +686,7 @@ public int test36() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test36_helper(Point p, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { return a6 + a8; } @@ -708,7 +708,7 @@ public int test37() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test37_helper(Point p, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8) { return (int)(a6 + a8); } @@ -730,7 +730,7 @@ public int test38() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test38_helper(Point p, boolean a0, byte a1, char a2, short a3, int a4, long a5, byte a6, short a7, int a8) { if (a0) { return (int)(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8); @@ -756,7 +756,7 @@ public long test39() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static long test39_helper(int a1, FixedPoints f1, int a2, FixedPoints f2) { if (f1.Z0 == false && f1.Z1 == true && f2.Z0 == false && f2.Z1 == true) { return f1.B + f2.C + f1.S + f2.I + f1.J; @@ -782,7 +782,7 @@ public double test40() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static double test40_helper(float a1, double a2, FloatPoint fp, DoublePoint dp, float a3, double a4, float a5, double a6, double a7, double a8, double a9, double a10, double a11, double a12) { return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12 + fp.x + fp.y - dp.x - dp.y; } @@ -804,7 +804,7 @@ public double test41() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static double test41_helper(int a1, double a2, Point p, FloatPoint fp, DoublePoint dp, float a3, int a4, float a5, double a6, double a7, double a8, long a9, double a10, double a11, double a12) { return a1 + a2 + fp.x + fp.y - dp.x - dp.y + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11 + a12; } @@ -826,7 +826,7 @@ public float test42() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static float test42_helper(EightFloats ep1, // (xmm0 ... xmm7) -> rsi Point p2, // (rsi, rdx) -> rdx int i3, // rcx -> rcx @@ -856,7 +856,7 @@ public float test43() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static float test43_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) { // On x64: // Scalarized entry -- all parameters are passed in registers @@ -881,7 +881,7 @@ public float test44() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static float test44_helper(FloatPoint fp1, FloatPoint fp2, int a1, int a2, int a3, int a4, int a5, int a6) { // On x64: // Scalarized entry -- all parameters are passed in registers @@ -909,7 +909,7 @@ public float test45() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static float test45_helper(FloatPoint fp1, FloatPoint fp2, FloatPoint fp3, FloatPoint fp4, FloatPoint fp5, int a1, int a2, int a3, int a4, int a5, int a6, int a7) { return fp1.x + fp1.y + fp2.x + fp2.y + @@ -936,7 +936,7 @@ public float test46() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static float test46_helper(FloatPoint fp1, FloatPoint fp2, Point p1, FloatPoint fp3, FloatPoint fp4, Point p2, FloatPoint fp5, int a1, int a2, int a3, int a4, int a5, int a6, int a7) { return p1.x + p1.y + p2.x + p2.y + @@ -990,7 +990,7 @@ public void test47(int n) { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static float test47_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5) { test47_thrower(); return 0.0f; @@ -1028,7 +1028,7 @@ public int test48(int n) { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static float test48_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5) { test48_thrower(); return 0.0f; @@ -1099,7 +1099,7 @@ public int test50(int n) { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static float test50_helper(FloatPoint fp, int a1, int a2, int a3, int a4, int a5, int a6) { test50_thrower(); return 0.0f; @@ -1129,7 +1129,7 @@ public int test51() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test51_helper(RefPoint rp1) { return rp1.x.n + rp1.y.n; } @@ -1151,7 +1151,7 @@ public int test52() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test52_helper(Point p1, RefPoint rp1) { return p1.x + p1.y + rp1.x.n + rp1.y.n; } @@ -1173,7 +1173,7 @@ public int test53() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test53_helper(RefPoint rp1, RefPoint rp2, RefPoint rp3, RefPoint rp4) { return rp1.x.n + rp1.y.n + rp2.x.n + rp2.y.n + @@ -1198,7 +1198,7 @@ public int test54() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test54_helper(RefPoint rp1, RefPoint rp2, float f, int i, RefPoint rp3, RefPoint rp4) { return rp1.x.n + rp1.y.n + rp2.x.n + rp2.y.n + @@ -1247,7 +1247,7 @@ public int test55(Point p1) { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test55_helper(Point p1) { return p1.x + p1.y; } @@ -1273,7 +1273,7 @@ public int test56(RefPoint rp1) { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test56_helper(RefPoint rp1) { return rp1.x.n + rp1.y.n; } @@ -1324,7 +1324,7 @@ public int test58(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test58_helper(RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return rp1.x.n + rp1.y.n + rp2.x.n + rp2.y.n + @@ -1360,7 +1360,7 @@ public int test59(RefPoint rp1, boolean doGC) { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test59_helper(RefPoint rp1, int a1, int a2, int a3, int a4, boolean doGC) { if (doGC) { System.gc(); @@ -1388,7 +1388,7 @@ public int test60(RefPoint rp1, RefPoint rp2, boolean doGC) { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static int test60_helper(int x0, int x1, int x2, RefPoint rp1, RefPoint rp2,int a1, int a2, int a3, int a4, boolean doGC) { // On x64, C2 passes: reg0=x1, reg1=x1, reg2=x2, reg3=rp1.x, reg4=rp1.y, reg5=rp2.x stack0=rp2.y .... // C1 expects: reg0=x1, reg1=x1, reg2=x2, reg3=rp1, reg4=rp2, reg5=a1 stack0=a2 ... @@ -1484,7 +1484,7 @@ public int test64(RefPoint_Access rpa, RefPoint rp1, RefPoint rp2, Number n1, Re } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) public static int test64_helper(RefPoint_Access rpa, RefPoint rp1, RefPoint rp2, Number n1, RefPoint rp3, RefPoint rp4, Number n2) { return rp3.y.n; } @@ -1560,7 +1560,7 @@ public int test78(Point p) { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static Point test78_helper(Point p) { return p; } @@ -1580,7 +1580,7 @@ public int test79(RefPoint p) { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static RefPoint test79_helper(RefPoint p) { return p; } @@ -1593,7 +1593,7 @@ public void test79_verifier() { } // C1->C2 invokestatic with InlineTypeReturnedAsFields (RefPoint) - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test80(RefPoint p) { RefPoint np = test80_helper(p); return np.x.n + np.y.n; @@ -1613,7 +1613,7 @@ public void test80_verifier() { } // Interpreter->C1 invokestatic with InlineTypeReturnedAsFields (Point) - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public Point test81(Point p) { return p; } @@ -1629,7 +1629,7 @@ public void test81_verifier() { } // C1->Interpreter invokestatic with InlineTypeReturnedAsFields (RefPoint) - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test82(RefPoint p) { RefPoint np = test82_helper(p); return np.x.n + np.y.n; @@ -1659,7 +1659,7 @@ public int test83(TooBigToReturnAsFields p) { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static TooBigToReturnAsFields test83_helper(TooBigToReturnAsFields p) { return p; } @@ -1672,7 +1672,7 @@ public void test83_verifier() { } // C1->C2 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test84(TooBigToReturnAsFields p) { TooBigToReturnAsFields np = test84_helper(p); return p.a0 + p.a5; @@ -1692,7 +1692,7 @@ public void test84_verifier() { } // Interpreter->C1 invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public TooBigToReturnAsFields test85(TooBigToReturnAsFields p) { return p; } @@ -1705,7 +1705,7 @@ public void test85_verifier() { } // C1->Interpreter invokestatic with InlineTypeReturnedAsFields (TooBigToReturnAsFields) - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test86(TooBigToReturnAsFields p) { TooBigToReturnAsFields np = test86_helper(p); return p.a0 + p.a5; @@ -1734,7 +1734,7 @@ public RefPoint.ref test87(RefPoint.ref p) { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static RefPoint.ref test87_helper(RefPoint.ref p) { return p; } @@ -1752,7 +1752,7 @@ public RefPoint.ref test88() { } @DontInline - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) private static RefPoint.ref test88_helper() { return null; } @@ -1764,7 +1764,7 @@ public void test88_verifier() { } // C1->C2 invokestatic with InlineTypeReturnedAsFields (RefPoint.ref) - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public RefPoint.ref test89(RefPoint.ref p) { return test89_helper(p); } @@ -1792,7 +1792,7 @@ public void test89_verifier() { //---------------------------------------------------------------------------------- // C1->C1 invokeinterface -- call Unverified Value Entry of MyImplPojo1.func2 (compiled by C1) - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test90(Intf intf, int a, int b) { return intf.func2(a, b, pointField); } @@ -1813,7 +1813,7 @@ public void test90_verifier(RunInfo info) { } // C1->C2 invokeinterface -- call Unverified Value Entry of MyImplPojo2.func2 (compiled by C2) - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test91(Intf intf, int a, int b) { return intf.func2(a, b, pointField); } @@ -1918,7 +1918,7 @@ public void test95_verifier(RunInfo info) { } // C1->C2 GC handling in StubRoutines::store_inline_type_fields_to_buf() - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public RefPoint test96(RefPoint rp, boolean b) { RefPoint p = test96_helper(rp); if (b) { @@ -1952,7 +1952,7 @@ public void test96_verifier(RunInfo info) { // callee is executed by the interpreter. Then, callee is compiled // and SharedRuntime::fixup_callers_callsite is called to fix up the // callsite from test97_verifier->test97. - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test97(Point p1, Point p2) { return test97_helper(p1, p2); } @@ -1962,7 +1962,7 @@ public int test97_helper(Point p1, Point p2) { return p1.x + p1.y + p2.x + p2.y; } - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) public void test97_verifier(RunInfo info) { int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC2 - same as test97, except the callee is a static method. - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public static int test99(Point p1, Point p2) { return test99_helper(p1, p2); } @@ -2014,7 +2014,7 @@ public static int test99_helper(Point p1, Point p2) { return p1.x + p1.y + p2.x + p2.y; } - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) public void test99_verifier(RunInfo info) { int count = info.isWarmUp() ? 1 : 20; for (int i=0; iC2 force GC for every allocation when storing the returned // fields back into a buffered object. - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public RefPoint test101(RefPoint rp) { return test101_helper(rp); } @@ -2110,7 +2110,7 @@ public void test101_verifier(RunInfo info) { } // Same as test101, except we have Interpreter->C2 instead. - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public RefPoint test102(RefPoint rp) { return test102_interp(rp); } @@ -2144,7 +2144,7 @@ public void test102_verifier(RunInfo info) { } } - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public void test103() { // when this method is compiled by C1, the Test103Value class is not yet loaded. test103_v = new Test103Value(); // invokestatic "Test103Value.()QTest103Value;" @@ -2169,7 +2169,7 @@ public void test103_verifier(RunInfo info) { // Same as test103, but with an inline class that's too big to return as fields. - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public void test104() { // when this method is compiled by C1, the Test104Value class is not yet loaded. test104_v = new Test104Value(); // invokestatic "Test104Value.()QTest104Value;" diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java index 039b8591f67..7765efe7ffc 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java @@ -73,7 +73,7 @@ public static void main(String[] args) { // Simple chain of getfields ending with primitive field - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int test1() { return NamedRectangle.getP1X(new NamedRectangle()); } @@ -85,7 +85,7 @@ public void test1_verifier() { } // Simple chain of getfields ending with a flattened field - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public Point test2() { return NamedRectangle.getP1(new NamedRectangle()); } @@ -98,7 +98,7 @@ public void test2_verifier() { } // Chain of getfields but the initial receiver is null - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public NullPointerException test3() { NullPointerException npe = null; try { @@ -119,7 +119,7 @@ public void test3_verifier() { } // Chain of getfields but one getfield in the middle of the chain trigger an illegal access - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public IllegalAccessError test4() { IllegalAccessError iae = null; try { @@ -141,7 +141,7 @@ public void test4_verifier() { } // Chain of getfields but the last getfield trigger a NoSuchFieldError - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public NoSuchFieldError test5() { NoSuchFieldError nsfe = null; try { @@ -172,7 +172,7 @@ static primitive class Container { EmptyContainer container1 = new EmptyContainer(); } - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public EmptyType test6() { Container c = new Container(); return c.container1.et; @@ -184,7 +184,7 @@ public void test6_verifier() { Asserts.assertEQ(et, EmptyType.default); } - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public EmptyType test7() { Container[] ca = new Container[10]; return ca[3].container0.et; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java index 4229bfdbbf1..eb8a437828f 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java @@ -191,7 +191,7 @@ static void validate_foo_static_and(FooValue v) { } // escape with putstatic - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public FooValue test1() { return FooValue.test1(); } @@ -203,7 +203,7 @@ public void test1_verifier() { } // escape with putfield - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public FooValue test2() { FooValue v = FooValue.default; @@ -227,7 +227,7 @@ public void test2_verifier() { } // escape with function call - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public FooValue test3() { return FooValue.test3(); } @@ -240,7 +240,7 @@ public void test3_verifier() { } // escape and then branch backwards - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public FooValue test4() { return FooValue.test4(); } @@ -253,7 +253,7 @@ public void test4_verifier() { } // escape using a different local variable - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public FooValue test5() { return FooValue.test5(); } @@ -266,7 +266,7 @@ public void test5_verifier() { } // escape using aastore - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public FooValue test6() { return FooValue.test6(); } @@ -282,7 +282,7 @@ public void test6_verifier() { } // Copying a value into different local slots -- disable withfield optimization - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public FooValue test7() { return FooValue.test7(); } @@ -295,7 +295,7 @@ public void test7_verifier() { } // escape by invoking non-static method - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public FooValue test8() { return FooValue.test8(); } @@ -308,7 +308,7 @@ public void test8_verifier() { } // duplicate reference with local variables - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public FooValue test9() { FooValue v = FooValue.default; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java index 270deafa769..311f720387e 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java @@ -40,7 +40,7 @@ * @see Run */ abstract public class AbstractInfo { - private static final Random random = Utils.getRandomInstance(); + private static final Random RANDOM = Utils.getRandomInstance(); protected final Class testClass; private boolean onWarmUp = true; @@ -55,7 +55,7 @@ abstract public class AbstractInfo { * @return the random object. */ public Random getRandom() { - return random; + return RANDOM; } /** @@ -84,7 +84,7 @@ public Method getMethod(Class c, String name, Class... args) { } catch (NoSuchMethodException e) { String parameters = args == null || args.length == 0 ? "" : " with arguments [" + Arrays.stream(args).map(Class::getName).collect(Collectors.joining(",")) + "]"; - throw new TestRunException("Could not find method " + name + " in " + c + parameters); + throw new TestRunException("Could not find method " + name + " in " + c + parameters, e); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java index f5d65399c6f..4c8d18a922c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java @@ -32,7 +32,6 @@ * @see Check */ public enum Argument { - /** * Provides the default value for any kind of primitive type and object type if the class provides a default constructor. */ @@ -78,5 +77,5 @@ public enum Argument { * Provides a different random primitive value on each test invocation. * Float and double values are restricted to the range [-10000,10000]. */ - RANDOM_EACH + RANDOM_EACH, } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java index 8e718990c39..e0ccc1741dc 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java @@ -34,7 +34,7 @@ * This class represents an argument value specified by {@link Argument} in {@link Arguments}. */ class ArgumentValue { - private static final Random random = Utils.getRandomInstance(); + private static final Random RANDOM = Utils.getRandomInstance(); private final Object argumentValue; private final boolean isRandomEach; @@ -282,23 +282,23 @@ private static boolean isFloatNumber(Class c) { private static Object getRandom(Class c) { if (isBoolean(c)) { - return random.nextBoolean(); + return RANDOM.nextBoolean(); } else if (c.equals(byte.class)) { - return (byte)random.nextInt(256); + return (byte) RANDOM.nextInt(256); } else if (isChar(c)) { - return (char)random.nextInt(65536); + return (char) RANDOM.nextInt(65536); } else if (c.equals(short.class)) { - return (short)random.nextInt(65536); + return (short) RANDOM.nextInt(65536); } else if (c.equals(int.class)) { - return random.nextInt(); + return RANDOM.nextInt(); } else if (c.equals(long.class)) { - return random.nextLong(); + return RANDOM.nextLong(); } else if (c.equals(float.class)) { // Get float between -10000 and 10000. - return random.nextFloat() * 20000 - 10000; + return RANDOM.nextFloat() * 20000 - 10000; } else if (c.equals(double.class)) { // Get double between -10000 and 10000. - return random.nextDouble() * 20000 - 10000; + return RANDOM.nextDouble() * 20000 - 10000; } else { TestFormat.fail("Cannot generate random value for non-primitive type"); return null; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java index e8dd7228764..fddff00a61b 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java @@ -91,7 +91,6 @@ */ @Retention(RetentionPolicy.RUNTIME) public @interface Check { - /** * The unique associated {@link Test} method for this {@code @Check} annotated check method. The framework will directly * invoke the {@code @Check} method after each invocation or only after the compilation of the associated {@code @Test} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java index fbdc296f617..55ea9d95245 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java @@ -31,7 +31,6 @@ * @see Test */ public enum CheckAt { - /** * Default: Invoke the {@link Check} method each time after invoking the associated {@link Test} method. */ @@ -40,5 +39,5 @@ public enum CheckAt { * Invoke the {@link Check} method only once after the warm-up of the associated {@link Test} method had been completed * and the framework has compiled the associated {@link Test} method. */ - COMPILED + COMPILED, } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java index 7596b963050..4639f3589b7 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java @@ -27,7 +27,6 @@ * Checked internal exceptions in the framework to propagate error handling. */ class CheckedTestFrameworkException extends Exception { - CheckedTestFrameworkException(String msg) { super(msg); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java index 2f846905da7..ec4653fa0f2 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java @@ -23,28 +23,32 @@ package jdk.test.lib.hotspot.ir_framework; +import jdk.test.lib.Utils; + +import java.lang.reflect.Executable; import java.util.HashMap; import java.util.Map; /** - * Compilation levels used by the framework. The compilation levels map to the used levels in HotSpot (apart from the - * framework specific values {@link #SKIP} and {@link #WAIT_FOR_COMPILATION} that cannot be found in HotSpot). + * Compilation levels used by the framework to initiate a compilation of a method. The compilation levels map to the used + * levels in HotSpot (apart from the framework specific values {@link #SKIP} and {@link #WAIT_FOR_COMPILATION} that cannot + * be found in HotSpot). The HotSpot specific levels must be in sync with hotspot/share/compiler/compilerDefinitions.hpp. * *

    - * The compilation levels can be specified in the {@link Test}, {@link ForceCompile} and {@link DontCompile} annotation. - * + * The compilation levels can be specified in the {@link Test}, {@link ForceCompile}, and + * {@link ForceCompileClassInitializer} annotation. * * @see Test * @see ForceCompile - * @see DontCompile + * @see ForceCompileClassInitializer */ public enum CompLevel { - /** * Can only be used at {@link Test#compLevel()}. After the warm-up, the framework keeps invoking the test over a span * of 10s (configurable by setting the property flag {@code -DWaitForCompilationTimeout}) until HotSpot compiles the * {@link Test} method. If the method was not compiled after 10s, an exception is thrown. The framework does not wait - * for the compilation if the test VM is run with {@code -Xcomp}, {@code -XX:-UseCompiler} or {@code -DStressCC=true}. + * for the compilation if the test VM is run with {@code -Xcomp}, {@code -XX:-UseCompiler}, or + * {@code -DExcludeRandom=true}. */ WAIT_FOR_COMPILATION(-4), /** @@ -63,7 +67,7 @@ public enum CompLevel { /** * Compilation level 1: C1 compilation without any profile information. */ - C1(1), + C1_SIMPLE(1), /** * Compilation level 2: C1 compilation with limited profile information: Includes Invocation and backedge counters. */ @@ -75,14 +79,16 @@ public enum CompLevel { /** * Compilation level 4: C2 compilation with full optimizations. */ - C2(4); + C2(4), + + ; - private static final Map typesByValue = new HashMap<>(); + private static final Map TYPES_BY_VALUE = new HashMap<>(); private final int value; static { for (CompLevel level : CompLevel.values()) { - typesByValue.put(level.value, level); + TYPES_BY_VALUE.put(level.value, level); } } @@ -107,28 +113,54 @@ public int getValue() { * @return the compilation level enum for {@code value}. */ public static CompLevel forValue(int value) { - CompLevel level = typesByValue.get(value); + CompLevel level = TYPES_BY_VALUE.get(value); TestRun.check(level != null, "Invalid compilation level " + value); return level; } /** - * Checks if two compilation levels are overlapping. + * Checks if this compilation level is not part of the compiler. */ - static boolean overlapping(CompLevel l1, CompLevel l2) { - return l1.isC1() == l2.isC1() || (l1 == C2 && l2 == C2); + boolean isNotCompilationLevelOfCompiler(Compiler c) { + return switch (c) { + case C1 -> !isC1(); + case C2 -> this != C2; + default -> throw new TestFrameworkException("Should not be called with compiler " + c); + }; } - static CompLevel join(CompLevel l1, CompLevel l2) { - return switch (l1) { - case ANY -> l2; - case C1, C1_LIMITED_PROFILE, C1_FULL_PROFILE -> l2.isC1() || l2 == ANY ? C1 : SKIP; - case C2 -> l2 == C2 || l2 == ANY ? C2 : SKIP; - default -> SKIP; + /** + * Flip the compilation levels. + */ + CompLevel flipCompLevel() { + switch (this) { + case C1_SIMPLE, C1_LIMITED_PROFILE, C1_FULL_PROFILE -> { + return CompLevel.C2; + } + case C2 -> { + return CompLevel.C1_SIMPLE; + } + } + return this; + } + + /** + * Return the compilation level when only allowing a compilation with the specified compiler. + */ + CompLevel excludeCompilationRandomly(Executable ex) { + if (Utils.getRandomInstance().nextBoolean()) { + // No exclusion + return this; + } + Compiler compiler = TestFrameworkExecution.excludeRandomly(ex); + return switch (compiler) { + case ANY -> SKIP; + case C1 -> isC1() ? SKIP : this; + case C2 -> this == C2 ? SKIP : this; }; } private boolean isC1() { - return this == C1 || this == C1_LIMITED_PROFILE || this == C1_FULL_PROFILE; + return this == C1_SIMPLE || this == C1_LIMITED_PROFILE || this == C1_FULL_PROFILE; } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Compiler.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Compiler.java new file mode 100644 index 00000000000..a0710e79935 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Compiler.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +/** + * Compilers to select for {@link DontCompile}. HotSpot does not handle the exclusion of a C1 method at a specific level. + * It can only exclude a method for the entire C1 compilation. Thus, this annotation is provided for {@link DontCompile} + * instead of {@link CompLevel}. + * + * @see DontCompile + */ +public enum Compiler { + /** + * Selecting both the C1 and C2 compiler. This must be in sync with hotspot/share/compiler/compilerDefinitions.hpp. + */ + ANY(-2), + /** + * The C1 compiler. + */ + C1(1), + /** + * The C2 compiler. + */ + C2(4), + + ; + + private final int value; + + Compiler(int level) { + this.value = level; + } + + /** + * Get the compilation level as integer value. These will match the levels specified in HotSpot (if available). + * + * @return the compilation level as integer. + */ + public int getValue() { + return value; + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/DeclaredTest.java b/test/lib/jdk/test/lib/hotspot/ir_framework/DeclaredTest.java index 2b040c98e2b..27abe4793bf 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/DeclaredTest.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/DeclaredTest.java @@ -83,11 +83,11 @@ public void printFixedRandomArguments() { if (argument.isFixedRandom()) { hasRandomArgs = true; Object argumentVal = argument.getArgument(); - String argumentValString = argumentVal.toString(); + builder.append("arg ").append(i).append(": ").append(argumentVal.toString()); if (argumentVal instanceof Character) { - argumentValString += " (" + (int)(Character)argumentVal + ")"; + builder.append(" (").append((int)(Character)argumentVal).append(")"); } - builder.append("arg ").append(i).append(": ").append(argumentValString).append(", "); + builder.append(", "); } } if (hasRandomArgs) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/DontCompile.java b/test/lib/jdk/test/lib/hotspot/ir_framework/DontCompile.java index b3492dc0f39..cae8706eca3 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/DontCompile.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/DontCompile.java @@ -28,14 +28,12 @@ /** * Prevent a compilation of the annotated helper method (not specifying {@link Test @Test}, - * {@link Check @Check} or {@link Run @Run}): + * {@link Check @Check} or {@link Run @Run}) with the specified compiler. * *

      - *
    • {@link CompLevel#ANY} (default): No C1 or C2 compilation.

    • - *
    • {@link CompLevel#C1}: No C1 compilation, C2 compilation still possible.

    • - *
    • {@link CompLevel#C2}: No C2 compilation, C1 compilation still possible.

    • - *
    • The usage of any other compilation level is forbidden and results in a - * {@link TestFormatException TestFormatException}.

    • + *
    • {@link Compiler#ANY} (default): No C1 or C2 compilation.

    • + *
    • {@link Compiler#C1}: No C1 compilation, C2 compilation still possible.

    • + *
    • {@link Compiler#C2}: No C2 compilation, C1 compilation still possible.

    • *
    *

    * Using this annotation on non-helper methods results in a {@link TestFormatException TestFormatException}. @@ -43,7 +41,7 @@ @Retention(RetentionPolicy.RUNTIME) public @interface DontCompile { /** - * The excluded compilation level for the helper method. + * The compiler with which a compilation of a helper method is excluded. */ - CompLevel value() default CompLevel.ANY; + Compiler value() default Compiler.ANY; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java index 676251792a4..aabac5229b8 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java @@ -27,24 +27,12 @@ import java.lang.annotation.RetentionPolicy; /** - * Force a compilation of the annotated helper method (not specifying {@link Test @Test}, - * {@link Check @Check} or {@link Test @Run}) immediately at the specified level: - *

      - *
    • {@link CompLevel#ANY} (default): Highest available compilation level is selected which is usually - * {@link CompLevel#C2}

    • - *
    • {@link CompLevel#C1}: Level 1: C1 compilation without any profile information.

    • - *
    • {@link CompLevel#C1_LIMITED_PROFILE}: Level 2: C1 compilation with limited profile information: - * Includes Invocation and backedge counters.

    • - *
    • {@link CompLevel#C1_FULL_PROFILE}: Level 3: C1 compilation with full profile information: - * Includes Invocation and backedge counters with MDO.

    • - *
    • {@link CompLevel#C2}: Level 4: C2 compilation with full optimizations.

    • - *
    • {@link CompLevel#SKIP}: Does not apply to {@code @ForceCompile} and results in a - * {@link TestFormatException}.

    • - *
    • {@link CompLevel#WAIT_FOR_COMPILATION}: Does not apply to {@code @ForceCompile} and results in a - * {@link TestFormatException}.

    • - *
    + * Force a compilation of the annotated helper method (not specifying {@link Test @Test}, {@link Check @Check}, + * or {@link Test @Run}) immediately at the specified level. {@link CompLevel#SKIP} and + * {@link CompLevel#WAIT_FOR_COMPILATION} do not apply and result in a {@link TestFormatException}. + * *

    - * Using this annotation on non-helper methods results in a {@link TestFormatException}. + * Using this annotation on non-helper methods also results in a {@link TestFormatException}. */ @Retention(RetentionPolicy.RUNTIME) public @interface ForceCompile { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompileClassInitializer.java b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompileClassInitializer.java index 01daf5b7dd7..9951b14a722 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompileClassInitializer.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompileClassInitializer.java @@ -28,23 +28,11 @@ /** * Force a compilation of the static class initializer method ({@code }) of the annotated test or helper class - * immediately at the specified level: - *

      - *
    • {@link CompLevel#ANY} (default): Highest available compilation level is selected which is usually - * {@link CompLevel#C2}

    • - *
    • {@link CompLevel#C1}: Level 1: C1 compilation without any profile information.

    • - *
    • {@link CompLevel#C1_LIMITED_PROFILE}: Level 2: C1 compilation with limited profile information: - * Includes Invocation and backedge counters.

    • - *
    • {@link CompLevel#C1_FULL_PROFILE}: Level 3: C1 compilation with full profile information: - * Includes Invocation and backedge counters with MDO.

    • - *
    • {@link CompLevel#C2}: Level 4: C2 compilation with full optimizations.

    • - *
    • {@link CompLevel#SKIP}: Does not apply to {@code @ForceCompileClassInitializer} and results in a - * {@link TestFormatException}.

    • - *
    • {@link CompLevel#WAIT_FOR_COMPILATION}: Does not apply to {@code @ForceCompileClassInitializer} and results in a - * {@link TestFormatException}.

    • - *
    + * immediately at the specified level. {@link CompLevel#SKIP} and {@link CompLevel#WAIT_FOR_COMPILATION} do not apply + * and result in a {@link TestFormatException}. + *

    - * Using this annotation on non-classes results in a {@link TestFormatException}. + * Using this annotation on non-classes also results in a {@link TestFormatException}. */ @Retention(RetentionPolicy.RUNTIME) public @interface ForceCompileClassInitializer { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java index d2d2446c939..9bdd62b6db5 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java @@ -65,7 +65,6 @@ @Retention(RetentionPolicy.RUNTIME) @Repeatable(IRs.class) public @interface IR { - /** * Define a list of (node) regexes. If any of these regexes are matched on the PrintIdeal or PrintOptoAssembly, the * IR rule fails and an {@link IRViolationException} is thrown. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java index 6ed4e244323..f2226086f6c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java @@ -33,18 +33,21 @@ import java.util.function.Function; /** - * Prints an encoding of all @Test methods whether an @IR rules should be applied to the dedicated test framework socket. + * Prints an encoding to the dedicated test framework socket whether @IR rules of @Test methods should be applied or not. + * This is done during the execution of the test VM by checking the active VM flags. This encoding is eventually parsed + * and checked by the IRMatcher class in the driver VM after the termination of the test VM. */ class IREncodingPrinter { public static final String START = "##### IRMatchRulesEncoding - used by TestFramework #####"; public static final String END = "----- END -----"; public static final int NO_RULE_APPLIED = -1; + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); - private static final List> longGetters = Arrays.asList( + private static final List> LONG_GETTERS = Arrays.asList( WHITE_BOX::getIntVMFlag, WHITE_BOX::getUintVMFlag, WHITE_BOX::getIntxVMFlag, WHITE_BOX::getUintxVMFlag, WHITE_BOX::getUint64VMFlag, WHITE_BOX::getSizeTVMFlag); - private final StringBuilder output = new StringBuilder(); + private final StringBuilder output = new StringBuilder(); private Method method; private int ruleIndex; @@ -182,7 +185,7 @@ private boolean check(String flag, String value) { if (actualFlagValue != null) { return checkBooleanFlag(flag, value, (Boolean) actualFlagValue); } - actualFlagValue = longGetters.stream().map(f -> f.apply(flag)).filter(Objects::nonNull).findAny().orElse(null); + actualFlagValue = LONG_GETTERS.stream().map(f -> f.apply(flag)).filter(Objects::nonNull).findAny().orElse(null); if (actualFlagValue != null) { return checkLongFlag(flag, value, (Long) actualFlagValue); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java index ca54f065edf..eb1a272c186 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java @@ -23,7 +23,7 @@ package jdk.test.lib.hotspot.ir_framework; -import java.io.*; +import java.io.IOException; import java.lang.reflect.Method; import java.nio.file.Files; import java.nio.file.Paths; @@ -36,9 +36,9 @@ */ class IRMatcher { private static final boolean PRINT_IR_ENCODING = Boolean.parseBoolean(System.getProperty("PrintIREncoding", "false")); - private static final Pattern irEncodingPattern = + private static final Pattern IR_ENCODING_PATTERN = Pattern.compile("(?<=" + IREncodingPrinter.START + "\\R)[\\s\\S]*(?=" + IREncodingPrinter.END + ")"); - private static final Pattern compileIdPattern = Pattern.compile("compile_id='(\\d+)'"); + private static final Pattern COMPILE_ID_PATTERN = Pattern.compile("compile_id='(\\d+)'"); private final Map compilations; private final Class testClass; @@ -51,7 +51,7 @@ class IRMatcher { private int irRuleIndex; // Current IR rule index; public IRMatcher(String hotspotPidFileName, String irEncoding, Class testClass) { - this.compilations = new HashMap<>(); + this.compilations = new HashMap<>(); this.fails = new HashMap<>(); this.testClass = testClass; this.compileIdPatternForTestClass = Pattern.compile("compile_id='(\\d+)'.*" + Pattern.quote(testClass.getCanonicalName()) @@ -93,7 +93,7 @@ private void setupTestMethods(String irEncoding) { */ private Map parseIREncoding(String irEncoding) { Map irRulesMap = new HashMap<>(); - Matcher matcher = irEncodingPattern.matcher(irEncoding); + Matcher matcher = IR_ENCODING_PATTERN.matcher(irEncoding); TestFramework.check(matcher.find(), "Did not find IR encoding"); String[] lines = matcher.group(0).split("\\R"); @@ -124,7 +124,7 @@ private Map parseIREncoding(String irEncoding) { */ private void parseHotspotPidFile() { Map compileIdMap = new HashMap<>(); - try (BufferedReader br = Files.newBufferedReader(Paths.get(hotspotPidFileName))) { + try (var br = Files.newBufferedReader(Paths.get(hotspotPidFileName))) { String line; StringBuilder builder = new StringBuilder(); boolean append = false; @@ -249,7 +249,7 @@ private static boolean isPrintOptoAssemblyStart(String line) { * Returns null if not an interesting method (i.e. from test class). */ private String getMethodName(Map compileIdMap, String line) { - Matcher matcher = compileIdPattern.matcher(line); + Matcher matcher = COMPILE_ID_PATTERN.matcher(line); TestFramework.check(matcher.find(), "Is " + hotspotPidFileName + " corrupted?"); int compileId = getCompileId(matcher); return compileIdMap.get(compileId); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java index 972030a46ab..520591e3361 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java @@ -129,7 +129,7 @@ public class IRNode { private static final String LOAD_OF_FIELD_POSTFIX = ",.*" + END; static List mergeNodes(String[] nodes) { - final List mergedNodes = new ArrayList<>(); + List mergedNodes = new ArrayList<>(); for (int i = 0; i < nodes.length; i += 2) { String node = nodes[i]; switch (node) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/NoTestsRunException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/NoTestsRunException.java index 3e5b7a47478..bf50eca4ede 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/NoTestsRunException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/NoTestsRunException.java @@ -28,7 +28,6 @@ * {@code -DExclude} defining an empty set with the used test VM flags. */ public class NoTestsRunException extends RuntimeException { - /** * Default constructor used by test VM */ diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java index ded0d43e508..08519afdc3b 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java @@ -92,9 +92,8 @@ */ @Retention(RetentionPolicy.RUNTIME) public @interface Run { - /** - * The associated {@link Test @Test} methods (one or more) for for this {@code @Run} annotated run method. + * The associated {@link Test @Test} methods (one or more) for this {@code @Run} annotated run method. * The framework directly invokes the run method instead of the associated {@code @Test} methods. */ String[] test(); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java b/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java index 6ad9ad25a2d..ad892fc30a0 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java @@ -39,5 +39,5 @@ public enum RunMode { * trigger the compilation(s), especially in regard of possible {@link IR} annotations at the associated {@link Test} * method. */ - STANDALONE + STANDALONE, } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java index 929fa74ab84..6ce6f5b2bf7 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java @@ -24,6 +24,7 @@ package jdk.test.lib.hotspot.ir_framework; import java.util.*; +import java.util.stream.Collectors; /** * This class represents a scenario that can be executed by the {@link TestFramework}. @@ -40,10 +41,10 @@ * @see TestFramework */ public class Scenario { - private static final String ADDITIONAL_SCENARIO_FLAGS = System.getProperty("ScenarioFlags", ""); - private static final String SCENARIOS = System.getProperty("Scenarios", ""); - private static final List additionalScenarioFlags = new ArrayList<>(); - private static final Set enabledScenarios = new HashSet<>(); + private static final String ADDITIONAL_SCENARIO_FLAGS_PROPERTY = System.getProperty("ScenarioFlags", ""); + private static final String SCENARIOS_PROPERTY = System.getProperty("Scenarios", ""); + private static final List ADDITIONAL_SCENARIO_FLAGS; + private static final Set ENABLED_SCENARIOS; private final List flags; private final int index; @@ -51,19 +52,20 @@ public class Scenario { private String testVMOutput; static { - if (!SCENARIOS.isEmpty()) { - System.out.println(Arrays.toString(SCENARIOS.split("\\s*,\\s*"))); + if (!SCENARIOS_PROPERTY.isEmpty()) { + var split = SCENARIOS_PROPERTY.split("\\s*,\\s*"); try { - Arrays.stream(SCENARIOS.split("\\s*,\\s*")).map(Integer::parseInt).forEachOrdered(enabledScenarios::add); + ENABLED_SCENARIOS = Arrays.stream(split).map(Integer::parseInt).collect(Collectors.toSet()); } catch (NumberFormatException e) { throw new TestRunException("Provided a scenario index in the -DScenario comma-separated list which is not " - + "a number: " + SCENARIOS); + + "a number: " + SCENARIOS_PROPERTY); } + } else { + ENABLED_SCENARIOS = Collections.emptySet(); } - if (!ADDITIONAL_SCENARIO_FLAGS.isEmpty()) { - additionalScenarioFlags.addAll(Arrays.asList(ADDITIONAL_SCENARIO_FLAGS.split("\\s*,\\s*"))); - } + ADDITIONAL_SCENARIO_FLAGS = ADDITIONAL_SCENARIO_FLAGS_PROPERTY.isEmpty() ? Collections.emptyList() : + Arrays.asList(ADDITIONAL_SCENARIO_FLAGS_PROPERTY.split("\\s*,\\s*")); } /** @@ -80,11 +82,11 @@ public Scenario(int index, String... flags) { this.index = index; if (flags != null) { this.flags = new ArrayList<>(Arrays.asList(flags)); - this.flags.addAll(additionalScenarioFlags); + this.flags.addAll(ADDITIONAL_SCENARIO_FLAGS); } else { this.flags = new ArrayList<>(); } - this.enabled = enabledScenarios.isEmpty() || enabledScenarios.contains(index); + this.enabled = ENABLED_SCENARIOS.isEmpty() || ENABLED_SCENARIOS.contains(index); } /** diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java index d120b52655a..0ec0552c9c7 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java @@ -78,7 +78,6 @@ */ @Retention(RetentionPolicy.RUNTIME) public @interface Test { - /** * Specify at which compilation level the framework should eventually compile the test method after an optional * warm-up period. The default {@link CompLevel#ANY} will let the framework compile the method at the highest diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java index 2e27bde553c..684b36d384a 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java @@ -27,7 +27,6 @@ * Exception that is thrown if a JTreg test violates the supported format by the test framework. */ public class TestFormatException extends RuntimeException { - TestFormatException(String message) { super(message); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 67eeebfb905..016c79b8ec0 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -142,17 +142,18 @@ public class TestFramework { private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.getBoolean("PreferCommandLineFlags"); private static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); private static final boolean REPORT_STDOUT = Boolean.getBoolean("ReportStdout"); - private final boolean VERIFY_VM = Boolean.getBoolean("VerifyVM") && Platform.isDebugBuild(); - private boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); + private static final boolean VERIFY_VM = Boolean.getBoolean("VerifyVM") && Platform.isDebugBuild(); + + private boolean irVerificationPossible = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); private boolean shouldVerifyIR; // Should we perform IR matching? private static String lastTestVMOutput; private static boolean toggleBool; private final Class testClass; - private Set> helperClasses = null; - private List scenarios = null; - private Set scenarioIndices = null; - private List flags = null; + private Set> helperClasses; + private List scenarios; + private Set scenarioIndices; + private List flags; private int defaultWarmup = -1; private TestFrameworkSocket socket; private Scenario scenario; @@ -624,23 +625,23 @@ private void installWhiteBox() { * Disable IR verification completely in certain cases. */ private void disableIRVerificationIfNotFeasible() { - if (VERIFY_IR) { - VERIFY_IR = Platform.isDebugBuild() && !Platform.isInt() && !Platform.isComp(); - if (!VERIFY_IR) { + if (irVerificationPossible) { + irVerificationPossible = Platform.isDebugBuild() && !Platform.isInt() && !Platform.isComp(); + if (!irVerificationPossible) { System.out.println("IR verification disabled due to not running a debug build (required for PrintIdeal" + "and PrintOptoAssembly), running with -Xint, or -Xcomp (use warm-up of 0 instead)"); return; } - VERIFY_IR = hasIRAnnotations(); - if (!VERIFY_IR) { + irVerificationPossible = hasIRAnnotations(); + if (!irVerificationPossible) { System.out.println("IR verification disabled due to test " + testClass + " not specifying any @IR annotations"); return; } // No IR verification is done if additional non-whitelisted JTreg VM or Javaoptions flag is specified. - VERIFY_IR = onlyWhitelistedJTregVMAndJavaOptsFlags(); - if (!VERIFY_IR) { + irVerificationPossible = onlyWhitelistedJTregVMAndJavaOptsFlags(); + if (!irVerificationPossible) { System.out.println("IR verification disabled due to using non-whitelisted JTreg VM or Javaoptions flag(s)." + System.lineSeparator()); } @@ -729,7 +730,7 @@ private void start(Scenario scenario) { "-DScenarios and is therefore not executed."); return; } - shouldVerifyIR = VERIFY_IR; + shouldVerifyIR = irVerificationPossible; socket = TestFrameworkSocket.getSocket(); this.scenario = scenario; try { @@ -975,7 +976,6 @@ static void check(boolean test, String failureMessage) { * Class to encapsulate information about the test VM output, the run process and the scenario. */ class JVMOutput { - private final Scenario scenario; private final OutputAnalyzer oa; private final ProcessBuilder process; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java index 9f2e07f9f93..b8571c35ebb 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java @@ -28,7 +28,6 @@ * in the framework. */ public class TestFrameworkException extends RuntimeException { - TestFrameworkException(String message) { super("Internal Test Framework exception - please file a bug:" + System.lineSeparator() + message); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java index 63f0a30a651..290143dab2a 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java @@ -77,11 +77,9 @@ assertions from main() of your test! private static final CompLevel TIERED_COMPILATION_STOP_AT_LEVEL = CompLevel.forValue(((Long)WHITE_BOX.getVMFlag("TieredStopAtLevel")).intValue()); static final boolean TEST_C1 = TIERED_COMPILATION && TIERED_COMPILATION_STOP_AT_LEVEL.getValue() < CompLevel.C2.getValue(); - // User defined settings static final boolean XCOMP = Platform.isComp(); static final boolean VERBOSE = Boolean.getBoolean("Verbose"); private static final boolean PRINT_TIMES = Boolean.getBoolean("PrintTimes"); - static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); private static final String TESTLIST = System.getProperty("Test", ""); @@ -91,9 +89,10 @@ assertions from main() of your test! private static final boolean SHUFFLE_TESTS = Boolean.parseBoolean(System.getProperty("ShuffleTests", "true")); // Use separate flag as VERIFY_IR could have been set by user but due to other flags it was disabled by flag VM. private static final boolean PRINT_VALID_IR_RULES = Boolean.getBoolean("ShouldDoIRVerification"); - protected static final long PerMethodTrapLimit = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); - protected static final boolean ProfileInterpreter = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); + protected static final long PER_METHOD_TRAP_LIMIT = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); + protected static final boolean PROFILE_INTERPRETER = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); private static final boolean FLIP_C1_C2 = Boolean.getBoolean("FlipC1C2"); + private static final boolean IGNORE_COMPILER_CONTROLS = Boolean.getBoolean("IgnoreCompilerControls"); private final HashMap declaredTests = new HashMap<>(); private final List allTests = new ArrayList<>(); @@ -148,8 +147,7 @@ public static void main(String[] args) { try { String testClassName = args[0]; System.out.println("Framework main(), about to run tests in class " + testClassName); - Class testClass; - testClass = getClassObject(testClassName, "test"); + Class testClass = getClassObject(testClassName, "test"); TestFrameworkExecution framework = new TestFrameworkExecution(testClass); framework.addHelperClasses(args); @@ -160,25 +158,23 @@ public static void main(String[] args) { } protected static Class getClassObject(String className, String classType) { - Class c; try { - c = Class.forName(className); + return Class.forName(className); } catch (Exception e) { throw new TestRunException("Could not find " + classType + " class", e); } - return c; } /** * Set up all helper classes and verify they are specified correctly. */ private void addHelperClasses(String[] args) { - Class[] helperClasses = getHelperClasses(args); - if (helperClasses != null) { - TestRun.check(Arrays.stream(helperClasses).noneMatch(Objects::isNull), "A Helper class cannot be null"); + Class[] helperClassesList = getHelperClasses(args); + if (helperClassesList != null) { + TestRun.check(Arrays.stream(helperClassesList).noneMatch(Objects::isNull), "A Helper class cannot be null"); this.helperClasses = new HashSet<>(); - for (Class helperClass : helperClasses) { + for (Class helperClass : helperClassesList) { if (Arrays.stream(testClass.getDeclaredClasses()).anyMatch(c -> c == helperClass)) { // Nested class of test class is automatically treated as helper class TestFormat.failNoThrow("Nested " + helperClass + " inside test " + testClass + " is implicitly" @@ -307,31 +303,31 @@ private void addReplay() { } private void processControlAnnotations(Class clazz) { - if (!XCOMP) { - // Don't control compilations if -Xcomp is enabled. - // Also apply compile commands to all inner classes of 'clazz'. - ArrayList> classes = new ArrayList<>(Arrays.asList(clazz.getDeclaredClasses())); - classes.add(clazz); - for (Class c : classes) { - applyClassAnnotations(c); - List executables = new ArrayList<>(Arrays.asList(c.getDeclaredMethods())); - Collections.addAll(executables, c.getDeclaredConstructors()); - for (Executable ex : executables) { - checkClassAnnotations(ex); - try { - applyIndependentCompilationCommands(ex); - } catch (TestFormatException e) { - // Failure logged. Continue and report later. - } + if (IGNORE_COMPILER_CONTROLS) { + return; + } + // Also apply compile commands to all inner classes of 'clazz'. + ArrayList> classes = new ArrayList<>(Arrays.asList(clazz.getDeclaredClasses())); + classes.add(clazz); + for (Class c : classes) { + applyClassAnnotations(c); + List executables = new ArrayList<>(Arrays.asList(c.getDeclaredMethods())); + Collections.addAll(executables, c.getDeclaredConstructors()); + for (Executable ex : executables) { + checkClassAnnotations(ex); + try { + applyIndependentCompilationCommands(ex); + } catch (TestFormatException e) { + // Failure logged. Continue and report later. } + } - // Only force compilation now because above annotations affect inlining - for (Executable ex : executables) { - try { - applyForceCompileCommand(ex); - } catch (TestFormatException e) { - // Failure logged. Continue and report later. - } + // Only force compilation now because above annotations affect inlining + for (Executable ex : executables) { + try { + applyForceCompileCommand(ex); + } catch (TestFormatException e) { + // Failure logged. Continue and report later. } } } @@ -339,23 +335,25 @@ private void processControlAnnotations(Class clazz) { private void applyClassAnnotations(Class c) { ForceCompileClassInitializer anno = getAnnotation(c, ForceCompileClassInitializer.class); - if (anno != null) { - // Compile class initializer - CompLevel level = anno.value(); - if (level == CompLevel.SKIP || level == CompLevel.WAIT_FOR_COMPILATION) { - TestFormat.failNoThrow("Cannot define compilation level SKIP or WAIT_FOR_COMPILATION in " + - "@ForceCompileClassInitializer at " + c); - return; - } - level = restrictCompLevel(anno.value()); - if (level != CompLevel.SKIP) { - // Make sure class is initialized to avoid compilation bailout of - getClassObject(c.getName(), "nested"); // calls Class.forName() to initialize 'c' - TestFormat.checkNoThrow(WHITE_BOX.enqueueInitializerForCompilation(c, level.getValue()), - "Failed to enqueue of " + c + " for compilation. Did you specify " - + "@ForceCompileClassInitializer without providing a static class initialization? " - + "Make sure to provide any form of static initialization or remove the annotation."); - } + if (anno == null) { + return; + } + + // Compile class initializer + CompLevel level = anno.value(); + if (level == CompLevel.SKIP || level == CompLevel.WAIT_FOR_COMPILATION) { + TestFormat.failNoThrow("Cannot define compilation level SKIP or WAIT_FOR_COMPILATION in " + + "@ForceCompileClassInitializer at " + c); + return; + } + level = restrictCompLevel(anno.value()); + if (level != CompLevel.SKIP) { + // Make sure class is initialized to avoid compilation bailout of + getClassObject(c.getName(), "nested"); // calls Class.forName() to initialize 'c' + TestFormat.checkNoThrow(WHITE_BOX.enqueueInitializerForCompilation(c, level.getValue()), + "Failed to enqueue of " + c + " for compilation. Did you specify " + + "@ForceCompileClassInitializer without providing a static class initialization? " + + "Make sure to provide any form of static initialization or remove the annotation."); } } @@ -365,38 +363,20 @@ private void checkClassAnnotations(Executable ex) { } /** - * Exclude a method from compilation randomly and returns the compilation level on which a compilation is still - * possible. + * Exclude a method from compilation with a compiler randomly. Return the compiler for which the method was made + * not compilable. */ - static CompLevel excludeRandomly(Executable ex) { - Random random = Utils.getRandomInstance(); - boolean exclude = random.nextBoolean(); - CompLevel level = CompLevel.ANY; - if (exclude) { - String levelName; - switch (random.nextInt() % 3) { - case 1 -> { - level = CompLevel.C1; - WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.C2.getValue(), false); - WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.C2.getValue(), true); - levelName = "C2"; - } - case 2 -> { - level = CompLevel.C2; - WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.C1.getValue(), false); - WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.C1.getValue(), true); - levelName = "C1"; - } - default -> { - level = CompLevel.SKIP; - WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.ANY.getValue(), false); - WHITE_BOX.makeMethodNotCompilable(ex, CompLevel.ANY.getValue(), true); - levelName = "C1 and C2"; - } - } - System.out.println("Excluding from " + levelName + " compilation: " + ex); + static Compiler excludeRandomly(Executable ex) { + Compiler compiler; + switch (Utils.getRandomInstance().nextInt() % 3) { + case 1 -> compiler = Compiler.C1; + case 2 -> compiler = Compiler.C2; + default -> compiler = Compiler.ANY; } - return level; + WHITE_BOX.makeMethodNotCompilable(ex, compiler.getValue(), false); + WHITE_BOX.makeMethodNotCompilable(ex, compiler.getValue(), true); + System.out.println("Excluding from " + compiler.name() + " compilation: " + ex); + return compiler; } private void applyIndependentCompilationCommands(Executable ex) { @@ -412,15 +392,13 @@ private void applyIndependentCompilationCommands(Executable ex) { WHITE_BOX.testSetForceInlineMethod(ex, true); } if (dontCompileAnno != null) { - CompLevel compLevel = dontCompileAnno.value(); - TestFormat.check(compLevel == CompLevel.C1 || compLevel == CompLevel.C2 || compLevel == CompLevel.ANY, - "Can only specify compilation level C1 (no individual C1 levels), " + - "C2 or ANY (no compilation, same as specifying anything) in @DontCompile at " + ex); - dontCompileAtLevel(ex, compLevel); + dontCompileWithCompiler(ex, dontCompileAnno.value()); } if (EXCLUDE_RANDOM && getAnnotation(ex, Test.class) == null && forceCompileAnno == null && dontCompileAnno == null) { // Randomly exclude helper methods from compilation - excludeRandomly(ex); + if (Utils.getRandomInstance().nextBoolean()) { + excludeRandomly(ex); + } } } @@ -439,14 +417,14 @@ private void checkCompilationCommandAnnotations(Executable ex, ForceInline force } TestFormat.check(forceInlineAnno == null || dontInlineAnno == null, "Cannot have @ForceInline and @DontInline at the same time at " + ex); if (forceCompileAnno != null && dontCompileAnno != null) { - CompLevel forceCompile = forceCompileAnno.value(); - CompLevel dontCompile = dontCompileAnno.value(); - TestFormat.check(dontCompile != CompLevel.ANY, - "Cannot have @DontCompile(CompLevel.ANY) and @ForceCompile at the same time at " + ex); - TestFormat.check(forceCompile != CompLevel.ANY, + CompLevel forceCompileLevel = forceCompileAnno.value(); + Compiler dontCompileCompiler = dontCompileAnno.value(); + TestFormat.check(dontCompileCompiler != Compiler.ANY, + "Cannot have @DontCompile(Compiler.ANY) and @ForceCompile at the same time at " + ex); + TestFormat.check(forceCompileLevel != CompLevel.ANY, "Cannot have @ForceCompile(CompLevel.ANY) and @DontCompile at the same time at " + ex); - TestFormat.check(!CompLevel.overlapping(dontCompile, forceCompile), - "Overlapping compilation levels with @ForceCompile and @DontCompile at " + ex); + TestFormat.check(forceCompileLevel.isNotCompilationLevelOfCompiler(dontCompileCompiler), + "Overlapping compilation level and compiler with @ForceCompile and @DontCompile at " + ex); } } @@ -454,18 +432,20 @@ private void checkCompilationCommandAnnotations(Executable ex, ForceInline force * Exlude the method from compilation and make sure it is not inlined. */ private void dontCompileAndDontInlineMethod(Method m) { - WHITE_BOX.makeMethodNotCompilable(m, CompLevel.ANY.getValue(), true); - WHITE_BOX.makeMethodNotCompilable(m, CompLevel.ANY.getValue(), false); - WHITE_BOX.testSetDontInlineMethod(m, true); + if (!IGNORE_COMPILER_CONTROLS) { + WHITE_BOX.makeMethodNotCompilable(m, CompLevel.ANY.getValue(), true); + WHITE_BOX.makeMethodNotCompilable(m, CompLevel.ANY.getValue(), false); + WHITE_BOX.testSetDontInlineMethod(m, true); + } } - private void dontCompileAtLevel(Executable ex, CompLevel compLevel) { + private void dontCompileWithCompiler(Executable ex, Compiler compiler) { if (VERBOSE) { - System.out.println("dontCompileAtLevel " + ex + " , level = " + compLevel.name()); + System.out.println("dontCompileWithCompiler " + ex + " , compiler = " + compiler.name()); } - WHITE_BOX.makeMethodNotCompilable(ex, compLevel.getValue(), true); - WHITE_BOX.makeMethodNotCompilable(ex, compLevel.getValue(), false); - if (compLevel == CompLevel.ANY) { + WHITE_BOX.makeMethodNotCompilable(ex, compiler.getValue(), true); + WHITE_BOX.makeMethodNotCompilable(ex, compiler.getValue(), false); + if (compiler == Compiler.ANY) { WHITE_BOX.testSetDontInlineMethod(ex, true); } } @@ -477,11 +457,11 @@ private void applyForceCompileCommand(Executable ex) { TestFormat.check(complevel != CompLevel.SKIP && complevel != CompLevel.WAIT_FOR_COMPILATION, "Cannot define compilation level SKIP or WAIT_FOR_COMPILATION in @ForceCompile at " + ex); complevel = restrictCompLevel(forceCompileAnno.value()); - if (EXCLUDE_RANDOM) { - complevel = CompLevel.join(complevel, excludeRandomly(ex)); - } if (FLIP_C1_C2) { - complevel = flipCompLevel(complevel); + complevel = complevel.flipCompLevel(); + } + if (EXCLUDE_RANDOM) { + complevel = complevel.excludeCompilationRandomly(ex); } if (complevel != CompLevel.SKIP) { enqueueForCompilation(ex, complevel); @@ -534,16 +514,16 @@ private void addDeclaredTest(Method m) { TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + m); } - if (!XCOMP) { - // Don't inline test methods. Don't care when -Xcomp set. + if (!IGNORE_COMPILER_CONTROLS) { + // Don't inline test methods by default. Do not apply this when -DIgnoreCompilerControls=true is set. WHITE_BOX.testSetDontInlineMethod(m, true); } CompLevel compLevel = restrictCompLevel(testAnno.compLevel()); if (FLIP_C1_C2) { - compLevel = flipCompLevel(compLevel); + compLevel = compLevel.flipCompLevel(); } if (EXCLUDE_RANDOM) { - compLevel = CompLevel.join(compLevel, excludeRandomly(m)); + compLevel = compLevel.excludeCompilationRandomly(m); } DeclaredTest test = new DeclaredTest(m, ArgumentValue.getArguments(m), compLevel, warmupIterations); declaredTests.put(m, test); @@ -590,18 +570,6 @@ private static CompLevel restrictCompLevel(CompLevel compLevel) { return compLevel; } - private static CompLevel flipCompLevel(CompLevel compLevel) { - switch (compLevel) { - case C1, C1_LIMITED_PROFILE, C1_FULL_PROFILE -> { - return CompLevel.C2; - } - case C2 -> { - return CompLevel.C1; - } - } - return compLevel; - } - /** * Verify that the helper classes do not contain illegal framework annotations and then apply the actions as * specified by the different helper class annotations. @@ -905,15 +873,15 @@ static boolean isCompiledAtLevel(Method m, CompLevel compLevel) { } static void assertDeoptimizedByC1(Method m) { - if (notUnstableDeoptAssertion(m, CompLevel.C1)) { - TestRun.check(compiledByC1(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, + if (notUnstableDeoptAssertion(m, CompLevel.C1_SIMPLE)) { + TestRun.check(compiledByC1(m) != TriState.Yes || PER_METHOD_TRAP_LIMIT == 0 || !PROFILE_INTERPRETER, m + " should have been deoptimized by C1"); } } static void assertDeoptimizedByC2(Method m) { if (notUnstableDeoptAssertion(m, CompLevel.C2)) { - TestRun.check(compiledByC2(m) != TriState.Yes || PerMethodTrapLimit == 0 || !ProfileInterpreter, + TestRun.check(compiledByC2(m) != TriState.Yes || PER_METHOD_TRAP_LIMIT == 0 || !PROFILE_INTERPRETER, m + " should have been deoptimized by C2"); } } @@ -922,7 +890,7 @@ static void assertDeoptimizedByC2(Method m) { * Some VM flags could make the deopt assertions unstable. */ private static boolean notUnstableDeoptAssertion(Method m, CompLevel level) { - return (USE_COMPILER && !XCOMP && !TEST_C1 && + return (USE_COMPILER && !XCOMP && !IGNORE_COMPILER_CONTROLS && !TEST_C1 && (!EXCLUDE_RANDOM || WHITE_BOX.isMethodCompilable(m, level.getValue(), false))); } @@ -948,7 +916,7 @@ static void assertCompiled(Method m) { } private static TriState compiledByC1(Method m) { - TriState triState = compiledAtLevel(m, CompLevel.C1); + TriState triState = compiledAtLevel(m, CompLevel.C1_SIMPLE); if (triState != TriState.No) { return triState; } @@ -967,7 +935,7 @@ private static TriState compiledByC2(Method m) { private static TriState compiledAtLevel(Method m, CompLevel level) { if (WHITE_BOX.isMethodCompiled(m, false)) { switch (level) { - case C1, C1_LIMITED_PROFILE, C1_FULL_PROFILE, C2 -> { + case C1_SIMPLE, C1_LIMITED_PROFILE, C1_FULL_PROFILE, C2 -> { if (WHITE_BOX.getMethodCompilationLevel(m, false) == level.getValue()) { return TriState.Yes; } @@ -978,7 +946,7 @@ private static TriState compiledAtLevel(Method m, CompLevel level) { default -> throw new TestRunException("compiledAtLevel() should not be called with " + level); } } - if (!USE_COMPILER || XCOMP || TEST_C1 || + if (!USE_COMPILER || XCOMP || TEST_C1 || IGNORE_COMPILER_CONTROLS || (EXCLUDE_RANDOM && !WHITE_BOX.isMethodCompilable(m, level.getValue(), false))) { return TriState.Maybe; } @@ -1144,8 +1112,8 @@ final protected void waitForCompilation(DeclaredTest test) { if (TestFrameworkExecution.VERBOSE) { System.out.println("Is " + testMethod + " compiled? " + isCompiled); } - if (isCompiled || TestFrameworkExecution.XCOMP) { - // Don't wait for compilation if -Xcomp is enabled. + if (isCompiled || TestFrameworkExecution.XCOMP || TestFrameworkExecution.EXCLUDE_RANDOM) { + // Don't wait for compilation if -Xcomp is enabled or if we are randomly excluding methods from compilation. return; } } while (elapsed < WAIT_FOR_COMPILATION_TIMEOUT); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java index 24049f1722e..18c87395251 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java @@ -36,9 +36,8 @@ * Dedicated socket to send data from the flag and test VM back to the driver VM. */ class TestFrameworkSocket implements AutoCloseable { - static final String SERVER_PORT_PROPERTY = "ir.framework.server.port"; - // Static fields used by flag and test VM only. + private static final String SERVER_PORT_PROPERTY = "ir.framework.server.port"; private static final int SERVER_PORT = Integer.getInteger(SERVER_PORT_PROPERTY, -1); private static final boolean REPRODUCE = Boolean.getBoolean("Reproduce"); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java index 39d1fa49c74..6ff9bb134f2 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java @@ -27,7 +27,6 @@ * Utility class to report a {@link TestRunException}. */ class TestRun { - public static void check(boolean test, String failureMessage) { if (!test) { throw new TestRunException(failureMessage); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java index e45b61d9ca9..812e85c0027 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java @@ -28,7 +28,6 @@ * test class. */ public class TestRunException extends RuntimeException { - TestRunException(String message) { super(message); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java index 4ea33815248..43845689e7f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java @@ -58,7 +58,6 @@ * @see TestFramework */ public class BaseTestExample { - int iFld; public static void main(String[] args) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java index 6a5e758398c..64e4e57728b 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java @@ -72,7 +72,6 @@ */ // This test is expected to fail when run with JTreg. public class IRExample { - int iFld, iFld2, iFld3; public static void main(String[] args) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java index 35229f46386..b7d2d83dfad 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java @@ -25,6 +25,7 @@ import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.Compiler; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -345,40 +346,28 @@ public void notAtCheck5() {} @ForceCompile(CompLevel.SKIP) public void invalidSkip1() {} - @DontCompile(CompLevel.SKIP) - public void invalidSkip2() {} - @ForceCompile(CompLevel.WAIT_FOR_COMPILATION) public void invalidWaitForCompilation() {} - @DontCompile(CompLevel.WAIT_FOR_COMPILATION) - public void invalidWaitForCompilation2() {} - - @ForceCompile(CompLevel.C1) - @DontCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) + @DontCompile(Compiler.C1) public void overlappingCompile1() {} @ForceCompile(CompLevel.C2) - @DontCompile(CompLevel.C2) + @DontCompile(Compiler.C2) public void overlappingCompile2() {} @ForceCompile(CompLevel.ANY) - @DontCompile(CompLevel.C1) + @DontCompile(Compiler.C1) public void invalidMix1() {} @ForceCompile(CompLevel.ANY) - @DontCompile(CompLevel.C2) + @DontCompile(Compiler.C2) public void invalidMix2() {} @ForceCompile(CompLevel.ANY) @DontCompile public void invalidMix3() {} - - @DontCompile(CompLevel.C1_LIMITED_PROFILE) - public void invalidDontCompile1() {} - - @DontCompile(CompLevel.C1_FULL_PROFILE) - public void invalidDontCompile2() {} } class BadWarmup { @@ -416,7 +405,7 @@ public void someTest3() {} @Warmup(-1) public void noWarmupAtStandalone() {} - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public void testNoCompLevelStandalone() {} @Test(compLevel = CompLevel.WAIT_FOR_COMPILATION) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java index 0d83298204a..c0a0d70e860 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java @@ -24,7 +24,6 @@ package jdk.test.lib.hotspot.ir_framework.tests; import jdk.test.lib.hotspot.ir_framework.*; -import jdk.test.lib.Asserts; import java.lang.reflect.Method; @@ -64,14 +63,14 @@ public static void main(String[] args) throws Exception { framework.setDefaultWarmup(10).addScenarios(new Scenario(0, "-XX:TieredStopAtLevel=1")).start(); } - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public void testC1() { testExecuted[0]++; } @Check(test = "testC1", when = CheckAt.COMPILED) public void checkTestC1(TestInfo info) { - TestFramework.assertCompiledAtLevel(info.getTest(), CompLevel.C1); + TestFramework.assertCompiledAtLevel(info.getTest(), CompLevel.C1_SIMPLE); } @Test(compLevel = CompLevel.C1_LIMITED_PROFILE) @@ -111,7 +110,7 @@ public void testSkip() { } class TestNoTiered { - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public void level1() { } @@ -165,7 +164,7 @@ public void checkSkip(TestInfo info) { } class TestStopAtLevel1 { - @Test(compLevel = CompLevel.C1) + @Test(compLevel = CompLevel.C1_SIMPLE) public int level1() { return 34; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java index f40213a376c..70cd4a9bedd 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java @@ -25,6 +25,7 @@ import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; +import jdk.test.lib.hotspot.ir_framework.Compiler; import sun.hotspot.WhiteBox; import java.lang.reflect.Method; @@ -168,7 +169,7 @@ public void testCompileAtLevel1() { executed[6]++; } - @DontCompile(CompLevel.ANY) + @DontCompile(Compiler.ANY) public static void dontCompile2() { executed[7]++; } @@ -212,21 +213,21 @@ public void testCompilation() { wasExecuted = true; } - @DontCompile(CompLevel.ANY) + @DontCompile(Compiler.ANY) public void dontCompileAny() { for (int i = 0; i < 10; i++) { iFld = i; } } - @DontCompile(CompLevel.C1) + @DontCompile(Compiler.C1) public void dontCompileC1() { for (int i = 0; i < 10; i++) { iFld = 3; } } - @DontCompile(CompLevel.C2) + @DontCompile(Compiler.C2) public void dontCompileC2(int x, boolean b) { for (int i = 0; i < 10; i++) { iFld = x; @@ -245,7 +246,7 @@ public void forceCompileAny() { wasExecuted = true; } - @ForceCompile(CompLevel.C1) + @ForceCompile(CompLevel.C1_SIMPLE) public void forceCompileC1() { wasExecuted = true; } @@ -265,14 +266,14 @@ public void forceCompileC2() { wasExecuted = true; } - @ForceCompile(CompLevel.C1) - @DontCompile(CompLevel.C2) + @ForceCompile(CompLevel.C1_SIMPLE) + @DontCompile(Compiler.C2) public void forceC1DontC2() { wasExecuted = true; } @ForceCompile(CompLevel.C2) - @DontCompile(CompLevel.C1) + @DontCompile(Compiler.C1) public void forceC2DontC1() { wasExecuted = true; } @@ -293,11 +294,11 @@ public void runTestCompilation(RunInfo info) { TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileDefault"), CompLevel.C2); TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileAny"), CompLevel.C2); TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileC2"), CompLevel.C2); - TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileC1"), CompLevel.C1); + TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileC1"), CompLevel.C1_SIMPLE); TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileC1Limited"), CompLevel.C1_LIMITED_PROFILE); TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceCompileC1Full"), CompLevel.C1_FULL_PROFILE); - TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceC1DontC2"), CompLevel.C1); + TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceC1DontC2"), CompLevel.C1_SIMPLE); TestFramework.assertCompiledAtLevel(info.getTestClassMethod("forceC2DontC1"), CompLevel.C2); executed[13]++; } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDIgnoreCompilerControls.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDIgnoreCompilerControls.java new file mode 100644 index 00000000000..d909fbfc36c --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDIgnoreCompilerControls.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework.tests; + +import jdk.test.lib.Utils; +import jdk.test.lib.hotspot.ir_framework.*; +import jdk.test.lib.Asserts; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import sun.hotspot.WhiteBox; + +/* + * @test + * @requires vm.debug == true + * @summary Test -DIgnoreCompilerControls property flag. + * @library /test/lib + * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestDIgnoreCompilerControls + */ + +public class TestDIgnoreCompilerControls { + public static void main(String[] args) throws Exception { + if (args.length != 0) { + TestFramework.run(); + } else { + OutputAnalyzer oa = run("true"); + oa.shouldHaveExitValue(0); + oa = run("false"); + oa.shouldNotHaveExitValue(0); + Asserts.assertTrue(oa.getOutput().contains("fail run"), "did not find run: " + oa.getOutput()); + Asserts.assertTrue(oa.getOutput().contains("fail check"), "did not find check" + oa.getOutput()); + } + } + + private static OutputAnalyzer run(String flagValue) throws Exception { + OutputAnalyzer oa; + ProcessBuilder process = ProcessTools.createJavaProcessBuilder( + "-Dtest.class.path=" + Utils.TEST_CLASS_PATH, "-Dtest.jdk=" + Utils.TEST_JDK, + "-Dtest.vm.opts=-DIgnoreCompilerControls=" + flagValue, + "jdk.test.lib.hotspot.ir_framework.tests.TestDIgnoreCompilerControls", flagValue); + oa = ProcessTools.executeProcess(process); + return oa; + } + + @Test + public void test() { } + + @Run(test = "test") + @Warmup(10000) + public void run(RunInfo info) throws NoSuchMethodException { + if (!info.isWarmUp()) { + // Should be compiled with -DIgnoreCompilerControls=true + Asserts.assertTrue(WhiteBox.getWhiteBox().isMethodCompiled(getClass().getDeclaredMethod("run", RunInfo.class)), "fail run"); + } + } + + @Test + @Warmup(10000) + public void test2() {} + + + @Check(test = "test2") + public void check(TestInfo info) throws NoSuchMethodException { + if (!info.isWarmUp()) { + // Should be compiled with -DIgnoreCompilerControls=true + Asserts.assertTrue(WhiteBox.getWhiteBox().isMethodCompiled(getClass().getDeclaredMethod("check", TestInfo.class)), "fail check"); + } + } +} From 2c0967f8ee16125eba47aa11070d995e478d2680 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 3 May 2021 20:00:46 +0200 Subject: [PATCH 118/131] Apply review comments and refactorings --- .../hotspot/ir_framework/AbstractInfo.java | 2 +- .../hotspot/ir_framework/AbstractTest.java | 215 ++++++++ .../lib/hotspot/ir_framework/BaseTest.java | 102 ++++ .../lib/hotspot/ir_framework/CheckedTest.java | 89 ++++ .../lib/hotspot/ir_framework/CompLevel.java | 2 +- .../hotspot/ir_framework/CustomRunTest.java | 177 ++++++ ...FrameworkPrepareFlags.java => FlagVM.java} | 49 +- .../hotspot/ir_framework/FlagVMProcess.java | 142 +++++ .../lib/hotspot/ir_framework/IRMatcher.java | 9 +- .../ir_framework/IRViolationException.java | 7 +- .../lib/hotspot/ir_framework/RunInfo.java | 16 +- .../hotspot/ir_framework/TestFramework.java | 435 ++------------- .../ir_framework/TestFrameworkSocket.java | 67 +-- .../lib/hotspot/ir_framework/TestInfo.java | 8 +- ...estFrameworkExecution.java => TestVM.java} | 504 +----------------- .../hotspot/ir_framework/TestVMProcess.java | 230 ++++++++ .../examples/BaseTestExample.java | 4 +- .../examples/CheckedTestExample.java | 4 +- .../examples/CustomRunTestExample.java | 4 +- .../ir_framework/tests/TestBadFormat.java | 2 +- .../ir_framework/tests/TestBasics.java | 10 +- .../ir_framework/tests/TestCompLevels.java | 6 +- .../ir_framework/tests/TestControls.java | 4 +- .../ir_framework/tests/TestDScenarios.java | 2 +- .../ir_framework/tests/TestIRMatching.java | 14 +- .../ir_framework/tests/TestRunTests.java | 14 +- .../ir_framework/tests/TestSanity.java | 21 +- .../ir_framework/tests/TestScenarios.java | 11 +- .../tests/TestWithHelperClasses.java | 10 +- 29 files changed, 1139 insertions(+), 1021 deletions(-) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/AbstractTest.java create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/BaseTest.java create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTest.java create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/CustomRunTest.java rename test/lib/jdk/test/lib/hotspot/ir_framework/{TestFrameworkPrepareFlags.java => FlagVM.java} (74%) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/FlagVMProcess.java rename test/lib/jdk/test/lib/hotspot/ir_framework/{TestFrameworkExecution.java => TestVM.java} (70%) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/TestVMProcess.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java index 311f720387e..d4b11df0b98 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java @@ -107,7 +107,7 @@ public Method getTestClassMethod(String name, Class... args) { * {@code false} otherwise (run with {@code -XX:TieredStopAtLevel={1,2,3}, -XX:-UseCompiler}). */ public boolean isC2CompilationEnabled() { - return TestFrameworkExecution.USE_COMPILER && !TestFrameworkExecution.TEST_C1; + return TestVM.USE_COMPILER && !TestVM.TEST_C1; } /** diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractTest.java b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractTest.java new file mode 100644 index 00000000000..5bf84828602 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractTest.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +import sun.hotspot.WhiteBox; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +/** + * Abstract super class for base, checked and custom run tests. + */ +abstract class AbstractTest { + protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + protected static final int TEST_COMPILATION_TIMEOUT = Integer.parseInt(System.getProperty("TestCompilationTimeout", "10000")); + protected static final int WAIT_FOR_COMPILATION_TIMEOUT = Integer.parseInt(System.getProperty("WaitForCompilationTimeout", "10000")); + protected static final boolean VERIFY_OOPS = (Boolean)WHITE_BOX.getVMFlag("VerifyOops"); + + protected final int warmupIterations; + protected final boolean skip; + + AbstractTest(int warmupIterations, boolean skip) { + this.warmupIterations = warmupIterations; + this.skip = skip; + } + + protected boolean shouldCompile(DeclaredTest test) { + return test.getCompLevel() != CompLevel.SKIP; + } + + abstract String getName(); + + /** + * Should test be executed? + */ + public boolean isSkipped() { + return skip; + } + + /** + * See {@link CompLevel#WAIT_FOR_COMPILATION}. + */ + protected static boolean isWaitForCompilation(DeclaredTest test) { + return test.getCompLevel() == CompLevel.WAIT_FOR_COMPILATION; + } + + protected static Object createInvocationTarget(Method method) { + Class clazz = method.getDeclaringClass(); + Object invocationTarget; + if (Modifier.isStatic(method.getModifiers())) { + invocationTarget = null; + } else { + try { + Constructor constructor = clazz.getDeclaredConstructor(); + constructor.setAccessible(true); + invocationTarget = constructor.newInstance(); + } catch (Exception e) { + throw new TestRunException("Could not create instance of " + clazz + + ". Make sure there is a constructor without arguments.", e); + } + } + return invocationTarget; + } + + /** + * Run the associated test. + */ + public void run() { + if (skip) { + return; + } + onStart(); + for (int i = 0; i < warmupIterations; i++) { + invokeTest(); + } + onWarmupFinished(); + compileTest(); + // Always run the test as a last step of the test execution. + invokeTest(); + } + + protected void onStart() { + // Do nothing by default. + } + + abstract protected void invokeTest(); + + abstract protected void onWarmupFinished(); + + abstract protected void compileTest(); + + protected void compileMethod(DeclaredTest test) { + final Method testMethod = test.getTestMethod(); + TestRun.check(WHITE_BOX.isMethodCompilable(testMethod, test.getCompLevel().getValue(), false), + "Method " + testMethod + " not compilable at level " + test.getCompLevel() + + ". Did you use compileonly without including all @Test methods?"); + TestRun.check(WHITE_BOX.isMethodCompilable(testMethod), + "Method " + testMethod + " not compilable at level " + test.getCompLevel() + + ". Did you use compileonly without including all @Test methods?"); + if (TestFramework.VERBOSE) { + System.out.println("Compile method " + testMethod + " after warm-up..."); + } + + final boolean maybeCodeBufferOverflow = (TestVM.TEST_C1 && VERIFY_OOPS); + final long started = System.currentTimeMillis(); + long elapsed = 0; + enqueueMethodForCompilation(test); + + do { + if (!WHITE_BOX.isMethodQueuedForCompilation(testMethod)) { + if (elapsed > 0) { + if (TestVM.VERBOSE) { + System.out.println(testMethod + " is not in queue anymore due to compiling it simultaneously on " + + "a different level. Enqueue again."); + } + enqueueMethodForCompilation(test); + } + } + if (maybeCodeBufferOverflow && elapsed > 1000 && !WHITE_BOX.isMethodCompiled(testMethod, false)) { + // Let's disable VerifyOops temporarily and retry. + WHITE_BOX.setBooleanVMFlag("VerifyOops", false); + WHITE_BOX.clearMethodState(testMethod); + enqueueMethodForCompilation(test); + WHITE_BOX.setBooleanVMFlag("VerifyOops", true); + } + + if (WHITE_BOX.getMethodCompilationLevel(testMethod, false) == test.getCompLevel().getValue()) { + break; + } + elapsed = System.currentTimeMillis() - started; + } while (elapsed < TEST_COMPILATION_TIMEOUT); + TestRun.check(elapsed < TEST_COMPILATION_TIMEOUT, + "Could not compile " + testMethod + " after " + TEST_COMPILATION_TIMEOUT/1000 + "s"); + checkCompilationLevel(test); + } + + private void enqueueMethodForCompilation(DeclaredTest test) { + TestVM.enqueueForCompilation(test.getTestMethod(), test.getCompLevel()); + } + + protected void checkCompilationLevel(DeclaredTest test) { + CompLevel level = CompLevel.forValue(WHITE_BOX.getMethodCompilationLevel(test.getTestMethod())); + TestRun.check(level == test.getCompLevel(), "Compilation level should be " + test.getCompLevel().name() + + " (requested) but was " + level.name() + " for " + test.getTestMethod()); + } + + final protected void waitForCompilation(DeclaredTest test) { + final Method testMethod = test.getTestMethod(); + final boolean maybeCodeBufferOverflow = (TestVM.TEST_C1 && VERIFY_OOPS); + final long started = System.currentTimeMillis(); + boolean stateCleared = false; + long elapsed; + do { + elapsed = System.currentTimeMillis() - started; + int level = WHITE_BOX.getMethodCompilationLevel(testMethod); + if (maybeCodeBufferOverflow && elapsed > 5000 + && (!WHITE_BOX.isMethodCompiled(testMethod, false) || level != test.getCompLevel().getValue())) { + retryDisabledVerifyOops(testMethod, stateCleared); + stateCleared = true; + } else { + invokeTest(); + } + + boolean isCompiled = WHITE_BOX.isMethodCompiled(testMethod, false); + if (TestVM.VERBOSE) { + System.out.println("Is " + testMethod + " compiled? " + isCompiled); + } + if (isCompiled || TestVM.XCOMP || TestVM.EXCLUDE_RANDOM) { + // Don't wait for compilation if -Xcomp is enabled or if we are randomly excluding methods from compilation. + return; + } + } while (elapsed < WAIT_FOR_COMPILATION_TIMEOUT); + throw new TestRunException(testMethod + " not compiled after waiting for " + + WAIT_FOR_COMPILATION_TIMEOUT/1000 + " s"); + } + + /** + * If it takes too long, try to disable Verify Oops. + */ + private void retryDisabledVerifyOops(Method testMethod, boolean stateCleared) { + System.out.println("Temporarily disabling VerifyOops"); + try { + WHITE_BOX.setBooleanVMFlag("VerifyOops", false); + if (!stateCleared) { + WHITE_BOX.clearMethodState(testMethod); + } + invokeTest(); + } finally { + WHITE_BOX.setBooleanVMFlag("VerifyOops", true); + System.out.println("Re-enabled VerifyOops"); + } + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/BaseTest.java b/test/lib/jdk/test/lib/hotspot/ir_framework/BaseTest.java new file mode 100644 index 00000000000..8d442ad7b54 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/BaseTest.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +import java.lang.reflect.Method; + +/** + * A base test only consists of a single @Test method. See {@link Test} for more details and its precise definition. + */ +class BaseTest extends AbstractTest { + private final DeclaredTest test; + protected final Method testMethod; + protected final TestInfo testInfo; + protected final Object invocationTarget; + private final boolean shouldCompile; + private final boolean waitForCompilation; + + public BaseTest(DeclaredTest test, boolean skip) { + super(test.getWarmupIterations(), skip); + this.test = test; + this.testMethod = test.getTestMethod(); + this.testInfo = new TestInfo(test); + this.invocationTarget = createInvocationTarget(testMethod); + this.shouldCompile = shouldCompile(test); + this.waitForCompilation = isWaitForCompilation(test); + } + + @Override + public String toString() { + return "Base Test: @Test " + testMethod.getName(); + } + + @Override + public String getName() { + return testMethod.getName(); + } + + @Override + protected void onStart() { + test.printFixedRandomArguments(); + } + + @Override + public void onWarmupFinished() { + testInfo.setWarmUpFinished(); + } + + @Override + protected void invokeTest() { + verify(invokeTestMethod()); + } + + private Object invokeTestMethod() { + try { + if (test.hasArguments()) { + return testMethod.invoke(invocationTarget, test.getArguments()); + } else { + return testMethod.invoke(invocationTarget); + } + } catch (Exception e) { + throw new TestRunException("There was an error while invoking @Test method " + testMethod + + ". Used arguments: " + test.getArgumentsString(), e); + } + } + + @Override + protected void compileTest() { + if (shouldCompile) { + if (waitForCompilation) { + waitForCompilation(test); + } else { + compileMethod(test); + } + } + } + + /** + * Verify the result + */ + public void verify(Object result) { /* no verification in BaseTests */ } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTest.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTest.java new file mode 100644 index 00000000000..b638f09f1ea --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +/** + * A checked test is an extension of a base test with additional verification done in a @Check method. + * See {@link Check} for more details and its precise definition. + */ +class CheckedTest extends BaseTest { + private final Method checkMethod; + private final CheckAt checkAt; + private final Parameter parameter; + private final Object checkInvocationTarget; + + enum Parameter { + NONE, RETURN_ONLY, TEST_INFO_ONLY, BOTH + } + + public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecification, Parameter parameter, boolean excludedByUser) { + super(test, excludedByUser); + // Make sure we can also call non-public or public methods in package private classes + checkMethod.setAccessible(true); + this.checkMethod = checkMethod; + this.checkAt = checkSpecification.when(); + this.parameter = parameter; + // Use the same invocation target + if (Modifier.isStatic(checkMethod.getModifiers())) { + this.checkInvocationTarget = null; + } else { + // Use the same invocation target as the test method if check method is non-static. + this.checkInvocationTarget = this.invocationTarget != null ? this.invocationTarget : createInvocationTarget(checkMethod); + } + } + + @Override + public String toString() { + return "Checked Test: @Check " + checkMethod.getName() + " - @Test: " + testMethod.getName(); + } + + @Override + public String getName() { + return checkMethod.getName(); + } + + @Override + public void verify(Object result) { + boolean shouldVerify = false; + switch (checkAt) { + case EACH_INVOCATION -> shouldVerify = true; + case COMPILED -> shouldVerify = !testInfo.isWarmUp(); + } + if (shouldVerify) { + try { + switch (parameter) { + case NONE -> checkMethod.invoke(checkInvocationTarget); + case RETURN_ONLY -> checkMethod.invoke(checkInvocationTarget, result); + case TEST_INFO_ONLY -> checkMethod.invoke(checkInvocationTarget, testInfo); + case BOTH -> checkMethod.invoke(checkInvocationTarget, result, testInfo); + } + } catch (Exception e) { + throw new TestRunException("There was an error while invoking @Check method " + checkMethod, e); + } + } + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java index ec4653fa0f2..0ecf4e91172 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java @@ -152,7 +152,7 @@ CompLevel excludeCompilationRandomly(Executable ex) { // No exclusion return this; } - Compiler compiler = TestFrameworkExecution.excludeRandomly(ex); + Compiler compiler = TestVM.excludeRandomly(ex); return switch (compiler) { case ANY -> SKIP; case C1 -> isC1() ? SKIP : this; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CustomRunTest.java b/test/lib/jdk/test/lib/hotspot/ir_framework/CustomRunTest.java new file mode 100644 index 00000000000..3391f3b9a23 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/CustomRunTest.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +import sun.hotspot.WhiteBox; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * A custom run test allows the user to have full control over how the @Test method is invoked by specifying + * a dedicated @Run method. See {@link Run} for more details and its precise definition. + */ +class CustomRunTest extends AbstractTest { + private final Method runMethod; + private final RunMode mode; + private final Object runInvocationTarget; + private final List tests; + private final RunInfo runInfo; + + public CustomRunTest(Method runMethod, Warmup warmUpAnno, Run runSpecification, List tests, boolean skip) { + // Make sure we can also call non-public or public methods in package private classes + super(warmUpAnno != null ? warmUpAnno.value() : TestVM.WARMUP_ITERATIONS, skip); + TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + runMethod); + runMethod.setAccessible(true); + this.runMethod = runMethod; + this.runInvocationTarget = createInvocationTarget(runMethod); + this.mode = runSpecification.mode(); + this.tests = tests; + this.runInfo = new RunInfo(tests); + } + + @Override + public String toString() { + String s = "Custom Run Test: @Run: " + runMethod.getName() + " - @Test"; + if (tests.size() == 1) { + s += ": " + tests.get(0).getTestMethod().getName(); + } else { + s += "s: {" + tests.stream().map(t -> t.getTestMethod().getName()) + .collect(Collectors.joining(",")) + "}"; + } + return s; + } + + @Override + String getName() { + return runMethod.getName(); + } + + @Override + public void run() { + if (skip) { + return; + } + switch (mode) { + case STANDALONE -> { + runInfo.setWarmUpFinished(); + invokeTest(); + }// Invoke once but do not apply anything else. + case NORMAL -> super.run(); + } + } + + @Override + public void onWarmupFinished() { + runInfo.setWarmUpFinished(); + } + + @Override + protected void compileTest() { + if (tests.size() == 1) { + compileSingleTest(); + } else { + compileMultipleTests(); + } + } + + private void compileSingleTest() { + DeclaredTest test = tests.get(0); + if (shouldCompile(test)) { + if (isWaitForCompilation(test)) { + waitForCompilation(test); + } else { + compileMethod(test); + } + } + } + + private void compileMultipleTests() { + boolean anyWaitForCompilation = false; + boolean anyCompileMethod = false; + ExecutorService executor = Executors.newFixedThreadPool(tests.size()); + for (DeclaredTest test : tests) { + if (shouldCompile(test)) { + if (isWaitForCompilation(test)) { + anyWaitForCompilation = true; + executor.execute(() -> waitForCompilation(test)); + } else { + anyCompileMethod = true; + executor.execute(() -> compileMethod(test)); + } + } + } + executor.shutdown(); + int timeout; + if (anyCompileMethod && anyWaitForCompilation) { + timeout = Math.max(WAIT_FOR_COMPILATION_TIMEOUT, TEST_COMPILATION_TIMEOUT) + 5000; + } else if (anyWaitForCompilation) { + timeout = WAIT_FOR_COMPILATION_TIMEOUT + 5000; + } else { + timeout = TEST_COMPILATION_TIMEOUT + 5000; + } + try { + executor.awaitTermination(timeout, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + throw new TestRunException("Some compilations did not complete after " + timeout + + "ms for @Run method " + runMethod); + } + } + + /** + * Do not directly run the test but rather the run method that is responsible for invoking the actual test. + */ + @Override + protected void invokeTest() { + try { + if (runMethod.getParameterCount() == 1) { + runMethod.invoke(runInvocationTarget, runInfo); + } else { + runMethod.invoke(runInvocationTarget); + } + } catch (Exception e) { + throw new TestRunException("There was an error while invoking @Run method " + runMethod, e); + } + } + + @Override + protected void checkCompilationLevel(DeclaredTest test) { + CompLevel level = CompLevel.forValue(WhiteBox.getWhiteBox().getMethodCompilationLevel(test.getTestMethod())); + if (level != test.getCompLevel()) { + String message = "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " + + level.name() + " for " + test.getTestMethod() + "."; + switch (mode) { + case STANDALONE -> throw new TestFrameworkException("Should not be called for STANDALONE method " + runMethod); + case NORMAL -> message = message + System.lineSeparator() + "Check your @Run method " + runMethod + + " to ensure that " + test.getTestMethod() + + " is called at least once in each iteration."; + } + throw new TestRunException(message); + } + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java b/test/lib/jdk/test/lib/hotspot/ir_framework/FlagVM.java similarity index 74% rename from test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/FlagVM.java index 75785af0b93..9ad65eccbec 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkPrepareFlags.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/FlagVM.java @@ -23,8 +23,12 @@ package jdk.test.lib.hotspot.ir_framework; +import jdk.test.lib.process.ProcessTools; import sun.hotspot.WhiteBox; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; @@ -33,17 +37,26 @@ * Whitebox API to determine the necessary additional flags to run the test VM (e.g. to do IR matching). It returns * the flags over the dedicated TestFramework socket. */ -class TestFrameworkPrepareFlags { +class FlagVM { private static final WhiteBox WHITE_BOX; + static final String TEST_VM_FLAGS_FILE_PREFIX = "test-vm-flags-pid-"; + static final String TEST_VM_FLAGS_FILE_POSTFIX = ".log"; static { try { WHITE_BOX = WhiteBox.getWhiteBox(); + TEST_VM_FLAGS_FILE = TEST_VM_FLAGS_FILE_PREFIX + ProcessTools.getProcessId() + TEST_VM_FLAGS_FILE_POSTFIX; } catch (UnsatisfiedLinkError e) { throw new TestFrameworkException("Could not load WhiteBox", e); + } catch (Exception e) { + throw new TestFrameworkException("Could not get process id", e); } } + private static final String TEST_VM_FLAGS_FILE; + + static final String TEST_VM_FLAGS_DELIMITER = " "; + private static final boolean TIERED_COMPILATION = (Boolean)WHITE_BOX.getVMFlag("TieredCompilation"); private static final CompLevel TIERED_COMPILATION_STOP_AT_LEVEL = CompLevel.forValue(((Long)WHITE_BOX.getVMFlag("TieredStopAtLevel")).intValue()); @@ -65,31 +78,29 @@ private static String[] getPrintFlags() { * Main entry point of the flag VM. */ public static void main(String[] args) { + String testClassName = args[0]; + if (VERBOSE) { + System.out.println("FlagVM main() called. Prepare test VM flags to run class " + testClassName); + } + Class testClass; try { - String testClassName = args[0]; - if (VERBOSE) { - System.out.println("TestFrameworkPrepareFlags main() called. Prepare test VM flags to run class " + testClassName); - } - Class testClass; - try { - testClass = Class.forName(testClassName); - } catch (Exception e) { - throw new TestRunException("Could not find test class " + testClassName, e); - } - emitTestVMFlags(prepareTestVmFlags(testClass)); - } finally { - TestFrameworkSocket.closeClientSocket(); + testClass = Class.forName(testClassName); + } catch (Exception e) { + throw new TestRunException("Could not find test class " + testClassName, e); } + emitTestVMFlags(prepareTestVmFlags(testClass)); } /** - * Emit test VM flags to standard output to parse them from the TestFramework "driver" VM again which adds them to the test VM. + * Emit test VM flags to the dedicated test VM flags file to parse them from the TestFramework "driver" VM again + * which adds them to the test VM. */ private static void emitTestVMFlags(ArrayList flags) { - String encoding = TestFramework.TEST_VM_FLAGS_START + System.lineSeparator() - + String.join(TestFramework.TEST_VM_FLAGS_DELIMITER, flags) - + System.lineSeparator() + TestFramework.TEST_VM_FLAGS_END; - TestFrameworkSocket.write(encoding, "flag encoding"); + try (var bw = Files.newBufferedWriter(Paths.get(TEST_VM_FLAGS_FILE))) { + bw.write(String.join(TEST_VM_FLAGS_DELIMITER, flags)); + } catch (IOException e) { + throw new TestFrameworkException("Error while writing to file " + TEST_VM_FLAGS_FILE, e); + } } private static ArrayList prepareTestVmFlags(Class testClass) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/FlagVMProcess.java b/test/lib/jdk/test/lib/hotspot/ir_framework/FlagVMProcess.java new file mode 100644 index 00000000000..689e0db6e58 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/FlagVMProcess.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +import jdk.test.lib.Utils; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * This class prepares, creates, and runs the "flag" VM with verification of proper termination. The flag VM determines + * the flags required for the "test" VM. The flag VM writes these flags to a dedicated file which is then parsed by this + * class after the termination of the flag VM. + * + * @see FlagVM + */ +class FlagVMProcess { + private static final boolean VERBOSE = Boolean.getBoolean("Verbose"); + + private final List cmds; + private final List testVMFlags; + private boolean shouldVerifyIR; + private String testVMFlagsFile; + private OutputAnalyzer oa; + + FlagVMProcess(Class testClass, List additionalFlags) { + cmds = new ArrayList<>(); + testVMFlags = new ArrayList<>(); + prepareVMFlags(testClass, additionalFlags); + start(); + parseTestVMFlags(); + } + + private void parseTestVMFlags() { + String flags = readFlagsFromFile(); + if (VERBOSE) { + System.out.println("Read data from " + testVMFlagsFile + ":"); + System.out.println(flags); + } + String patternString = "(.*DShouldDoIRVerification=(true|false).*)"; + Pattern pattern = Pattern.compile(patternString); + Matcher matcher = pattern.matcher(flags); + TestFramework.check(matcher.find(), "Invalid flag encoding emitted by flag VM"); + // Maybe we run with flags that make IR verification impossible + shouldVerifyIR = Boolean.parseBoolean(matcher.group(2)); + testVMFlags.addAll(Arrays.asList(matcher.group(1).split(FlagVM.TEST_VM_FLAGS_DELIMITER))); + } + + private String readFlagsFromFile() { + try (var br = Files.newBufferedReader(Paths.get(testVMFlagsFile))) { + String flags = br.readLine(); + TestFramework.check(br.readLine() == null, testVMFlagsFile + " should only contain one line."); + return flags; + + } catch (IOException e) { + throw new TestFrameworkException("Error while reading from file " + testVMFlagsFile, e); + } + } + + /** + * The flag VM needs White Box access to prepare all test VM flags. The flag VM will write the test VM flags to + * a dedicated file which is afterwards parsed by the driver VM and added as flags to the test VM. + */ + private void prepareVMFlags(Class testClass, List additionalFlags) { + cmds.add("-Dtest.jdk=" + Utils.TEST_JDK); + // Set java.library.path so JNI tests which rely on jtreg nativepath setting work + cmds.add("-Djava.library.path=" + Utils.TEST_NATIVE_PATH); + cmds.add("-cp"); + cmds.add(Utils.TEST_CLASS_PATH); + cmds.add("-Xbootclasspath/a:."); + cmds.add("-XX:+UnlockDiagnosticVMOptions"); + cmds.add("-XX:+WhiteBoxAPI"); + // TestFramework and scenario flags might have an influence on the later used test VM flags. Add them as well. + cmds.addAll(additionalFlags); + cmds.add(FlagVM.class.getCanonicalName()); + cmds.add(testClass.getCanonicalName()); + } + + private void start() { + try { + // Run "flag" VM with White Box access to determine the test VM flags and if IR verification should be done. + oa = ProcessTools.executeTestJvm(cmds); + } catch (Exception e) { + throw new TestRunException("Failed to execute TestFramework flag VM", e); + } + testVMFlagsFile = FlagVM.TEST_VM_FLAGS_FILE_PREFIX + oa.pid() + + FlagVM.TEST_VM_FLAGS_FILE_POSTFIX; + checkFlagVMExitCode(); + } + + private void checkFlagVMExitCode() { + String flagVMOutput = oa.getOutput(); + int exitCode = oa.getExitValue(); + if (VERBOSE && exitCode == 0) { + System.out.println("--- OUTPUT TestFramework flag VM ---"); + System.out.println(flagVMOutput); + } + + if (exitCode != 0) { + System.err.println("--- OUTPUT TestFramework flag VM ---"); + System.err.println(flagVMOutput); + throw new RuntimeException("TestFramework flag VM exited with " + exitCode); + } + } + + public List getTestVMFlags() { + return testVMFlags; + } + + public boolean shouldVerifyIR() { + return shouldVerifyIR; + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java index eb1a272c186..99a2682786d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java @@ -62,8 +62,10 @@ public IRMatcher(String hotspotPidFileName, String irEncoding, Class testClas System.out.println("Read IR encoding from test VM:"); System.out.println(irEncoding); } - parseHotspotPidFile(); - applyRules(); + if (!compilations.isEmpty()) { + parseHotspotPidFile(); + applyRules(); + } } /** @@ -475,8 +477,7 @@ private void reportFailuresIfAny() { .append(System.lineSeparator())); failuresBuilder.append(System.lineSeparator()); } - failuresBuilder.insert(0, (System.lineSeparator() + System.lineSeparator() - + "One or more @IR rules failed:" + System.lineSeparator() + failuresBuilder.insert(0, ("One or more @IR rules failed:" + System.lineSeparator() + System.lineSeparator() + "Failed IR Rules (" + failures + ")" + System.lineSeparator()) + "-----------------" + "-".repeat(String.valueOf(failures).length()) + System.lineSeparator()); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java b/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java index e5af203426d..014e7f27023 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java @@ -36,7 +36,8 @@ public class IRViolationException extends RuntimeException { private String exceptionInfo; IRViolationException(String message, String compilations) { - super(message); + super("There were one or multiple IR rule failures. Please check stderr for more information."); + this.exceptionInfo = message; this.compilations = compilations; } @@ -53,7 +54,7 @@ String getCompilations() { return compilations; } - void setExceptionInfo(String exceptionInfo) { - this.exceptionInfo = exceptionInfo; + void addCommandLine(String commandLine) { + this.exceptionInfo = commandLine + System.lineSeparator() + exceptionInfo; } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java index beb580d4a4d..469b3177d45 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java @@ -86,7 +86,7 @@ public Method getTest(String testName) { * be called if one test method is specified in the custom run test ({@link Run#test()}). Otherwise, use * {@link #isCompilationSkipped(String)}. * - * @return {@code true} if the framework compiled the test; + * @return {@code true} if the framework skipped compilation of the test; * {@code false} otherwise. * @throws TestRunException if called for a custom run test that specifies multiple test methods in {@link Run#test()}. */ @@ -102,7 +102,7 @@ public boolean isCompilationSkipped() { * in ({@link Run#test()}). Otherwise, use {@link #isCompilationSkipped()}. * * @param testName the test method for which the method object should be returned. - * @return {@code true} if the framework compiled the test; + * @return {@code true} if the framework skipped compilation of the test; * {@code false} otherwise. * @throws TestRunException if there is no test method with the name {@code testName} or if called with only * one associated test method. @@ -123,7 +123,7 @@ public boolean isCompilationSkipped(String testName) { */ public boolean isTestC1Compiled() { checkSingleTest("isTestC1Compiled"); - return TestFrameworkExecution.isC1Compiled(testMethod); + return TestVM.isC1Compiled(testMethod); } /** @@ -139,7 +139,7 @@ public boolean isTestC1Compiled() { */ public boolean isTestC1Compiled(String testName) { checkMultipleTests("isTestC1Compiled"); - return TestFrameworkExecution.isC1Compiled(getMethod(testName)); + return TestVM.isC1Compiled(getMethod(testName)); } /** @@ -153,7 +153,7 @@ public boolean isTestC1Compiled(String testName) { */ public boolean isTestC2Compiled() { checkSingleTest("isTestC2Compiled"); - return TestFrameworkExecution.isC2Compiled(testMethod); + return TestVM.isC2Compiled(testMethod); } /** @@ -169,7 +169,7 @@ public boolean isTestC2Compiled() { */ public boolean isTestC2Compiled(String testName) { checkMultipleTests("isTestC2Compiled"); - return TestFrameworkExecution.isC2Compiled(getMethod(testName)); + return TestVM.isC2Compiled(getMethod(testName)); } /** @@ -184,7 +184,7 @@ public boolean isTestC2Compiled(String testName) { */ public boolean isTestCompiledAtLevel(CompLevel compLevel) { checkSingleTest("isTestCompiledAtLevel"); - return TestFrameworkExecution.isCompiledAtLevel(testMethod, compLevel); + return TestVM.isCompiledAtLevel(testMethod, compLevel); } /** @@ -201,7 +201,7 @@ public boolean isTestCompiledAtLevel(CompLevel compLevel) { */ public boolean isTestCompiledAtLevel(String testName, CompLevel compLevel) { checkMultipleTests("isTestCompiledAtLevel"); - return TestFrameworkExecution.isCompiledAtLevel(getMethod(testName), compLevel); + return TestVM.isCompiledAtLevel(getMethod(testName), compLevel); } private void checkSingleTest(String calledMethod) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java index 016c79b8ec0..9774f2e9c15 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java @@ -25,8 +25,6 @@ import jdk.test.lib.Platform; import jdk.test.lib.Utils; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.process.ProcessTools; import jdk.test.lib.util.ClassFileInstaller; import sun.hotspot.WhiteBox; @@ -34,8 +32,6 @@ import java.io.StringWriter; import java.lang.reflect.Method; import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -64,9 +60,9 @@ * Note that even though the framework uses the Whitebox API internally, it is not required to build and enabel it in the * JTreg test if the test itself is not utilizing any Whitebox features directly. *

    - * To specify additional flags, use {@link #runWithFlags(String...)}, {@link #addFlags(String...)}, - * {@link #addScenarios(Scenario...)}, or {@link #runWithScenarios(Scenario...)} where the scenarios can also be used - * to run different flag combinations (instead of specifying multiple JTreg {@code @run} entries). + * To specify additional flags, use {@link #runWithFlags(String...)}, {@link #addFlags(String...)}, or + * {@link #addScenarios(Scenario...)} where the scenarios can also be used to run different flag combinations + * (instead of specifying multiple JTreg {@code @run} entries). *

    * After annotating your test code with the framework specific annotations, the framework needs to be invoked from the * {@code main()} method of your JTreg test. There are two ways to do so. The first way is by calling the various @@ -125,28 +121,20 @@ public class TestFramework { static final boolean VERBOSE = Boolean.getBoolean("Verbose"); static final boolean TESTLIST = !System.getProperty("Test", "").isEmpty(); static final boolean EXCLUDELIST = !System.getProperty("Exclude", "").isEmpty(); - static final String TEST_VM_FLAGS_START = "##### TestFrameworkPrepareFlags - used by TestFramework #####"; - static final String TEST_VM_FLAGS_DELIMITER = " "; - static final String TEST_VM_FLAGS_END = "----- END -----"; + private static final boolean REPORT_STDOUT = Boolean.getBoolean("ReportStdout"); + static final String RERUN_HINT = """ ############################################################# - To only run the failed tests use -DTest, -DExclude, and/or -DScenarios. - - To also get the standard output of the test VM run with\s + - To also get the standard output of the test VM run with -DReportStdout=true or for even more fine-grained logging use -DVerbose=true. ############################################################# """ + System.lineSeparator(); - private static final int WARMUP_ITERATIONS = Integer.getInteger("Warmup", -1); - private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.getBoolean("PreferCommandLineFlags"); - private static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); - private static final boolean REPORT_STDOUT = Boolean.getBoolean("ReportStdout"); - private static final boolean VERIFY_VM = Boolean.getBoolean("VerifyVM") && Platform.isDebugBuild(); - private boolean irVerificationPossible = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); private boolean shouldVerifyIR; // Should we perform IR matching? - private static String lastTestVMOutput; private static boolean toggleBool; private final Class testClass; @@ -155,8 +143,6 @@ public class TestFramework { private Set scenarioIndices; private List flags; private int defaultWarmup = -1; - private TestFrameworkSocket socket; - private Scenario scenario; /* * Public interface methods @@ -189,23 +175,6 @@ public TestFramework(Class testClass) { } } - /** - * Default flags that are added used for the test VM. - */ - private static String[] getDefaultFlags() { - return new String[] {"-XX:-BackgroundCompilation", "-XX:CompileCommand=quiet"}; - } - - /** - * Additional verification flags that are used if -DVerifyVM=true is with a debug build. - */ - private static String[] getVerifyFlags() { - return new String[] { - "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", - "-XX:+VerifyBeforeGC", "-XX:+VerifyAfterGC", "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing" - }; - } - /** * Tests the class from which this method was invoked from. */ @@ -232,99 +201,21 @@ public static void run(Class testClass) { * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the JTreg VM and Javaoptions flags over * the specified {@code flags} of this method. *

  • If you want to run your entire JTreg test with additional flags, use this method.

  • + *
  • If you want to run your entire JTreg test with additional flags but for another test class then the one + * from which this method was called from, use {@link #addFlags(String...)}, use this method.

  • *
  • If you want to run your JTreg test with multiple flag combinations, use - * {@link #runWithScenarios(Scenario...)}

  • + * {@link #addScenarios(Scenario...)} * * * @param flags VM flags to be used for the test VM. */ public static void runWithFlags(String... flags) { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - runWithFlags(walker.getCallerClass(), flags); - } - - /** - * Tests {@code testClass}. The test VM is called with the specified {@code flags}. - *
      - *
    • The {@code flags} override any set VM or Javaoptions flags by JTreg by default.

      - * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the JTreg VM and Javaoptions flags over - * the specified {@code flags} of this method.

    • - *
    • If you want to run your entire JTreg test with additional flags, use this method.

    • - *
    • If you want to run your JTreg test with multiple flag combinations, use - * {@link #runWithScenarios(Scenario...)}

    • - *
    - * - * @param testClass the class to be tested by the framework. - * @param flags VM flags to be used for the test VM. - * - * @see #runWithFlags(String...) - */ - public static void runWithFlags(Class testClass, String... flags) { - TestFramework framework = new TestFramework(testClass); + TestFramework framework = new TestFramework(walker.getCallerClass()); framework.addFlags(flags); framework.start(); } - /** - * Tests {@code testClass} which uses {@code helperClasses} that can specify additional compile command annotations - * ({@link ForceCompile @ForceCompile}, {@link DontCompile @DontCompile}, {@link ForceInline @ForceInline}, - * {@link DontInline @DontInline}) to be applied while testing {@code testClass} (also see description of - * {@link TestFramework}). - * - *

    - * If a class is used by the test class that does not specify any compile command annotations, you do not - * need to include it in {@code helperClasses}. If no helper class specifies any compile commands, consider - * using {@link #run()} or {@link #run(Class)}. - * - * @param testClass the class to be tested by the framework. - * @param helperClasses helper classes containing compile command annotations ({@link ForceCompile}, - * {@link DontCompile}, {@link ForceInline}, {@link DontInline}) to be applied - * while testing {@code testClass} (also see description of {@link TestFramework}). - */ - public static void runWithHelperClasses(Class testClass, Class... helperClasses) { - TestFramework framework = new TestFramework(testClass); - framework.addHelperClasses(helperClasses); - framework.start(); - } - - /** - * Tests the class from which this method was invoked from. A test VM is called for each scenario in {@code scenarios} - * by using the specified flags in the scenario. - *

      - *
    • If there is only one scenario, consider using {@link #runWithFlags(String...)}.

    • - *
    • The scenario flags override any VM or Javaoptions set by JTreg by default.

      - * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the - * scenario flags.

    • - *
    - * - * @param scenarios scenarios which specify specific flags for the test VM. - */ - public static void runWithScenarios(Scenario... scenarios) { - StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - runWithScenarios(walker.getCallerClass(), scenarios); - } - - /** - * Tests {@code testClass} A test VM is called for each scenario in {@code scenarios} by using the specified flags - * in the scenario. - *
      - *
    • If there is only one scenario, consider using {@link #runWithFlags(String...)}.

    • - *
    • The scenario flags override any VM or Javaoptions set by JTreg by default.

      - * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the Java and VM options over the - * scenario flags.

    • - *
    - * - * @param testClass the class to be tested by the framework. - * @param scenarios scenarios which specify specific flags for the test VM. - * - * @see #runWithScenarios(Scenario...) - */ - public static void runWithScenarios(Class testClass, Scenario... scenarios) { - TestFramework framework = new TestFramework(testClass); - framework.addScenarios(scenarios); - framework.start(); - } - /** * Add VM flags to be used for the test VM. These flags override any VM or Javaoptions set by JTreg by default.

    * Use {@code -DPreferCommandLineFlags=true} if you want to prefer the VM or Javaoptions over the scenario flags. @@ -414,12 +305,12 @@ public void start() { try { start(null); } catch (TestVMException e) { - System.err.println(System.lineSeparator() + e.getExceptionInfo()); + System.err.println(System.lineSeparator() + e.getExceptionInfo() + RERUN_HINT); throw e; } catch (IRViolationException e) { System.out.println("Compilation(s) of failed match(es):"); System.out.println(e.getCompilations()); - System.err.println(System.lineSeparator() + e.getExceptionInfo()); + System.err.println(System.lineSeparator() + e.getExceptionInfo() + System.lineSeparator() + RERUN_HINT); throw e; } } else { @@ -429,7 +320,7 @@ public void start() { /** * Set a new default warm-up (overriding the framework default of 2000 at - * {@link TestFrameworkExecution#WARMUP_ITERATIONS}) to be applied for all tests that do not specify an explicit + * {@link TestVM#WARMUP_ITERATIONS}) to be applied for all tests that do not specify an explicit * warm-up with {@link Warmup @Warmup}. * * @param defaultWarmup a new non-negative default warm-up. @@ -448,7 +339,7 @@ public TestFramework setDefaultWarmup(int defaultWarmup) { * @return the last test VM output. */ public static String getLastTestVMOutput() { - return lastTestVMOutput; + return TestVMProcess.getLastTestVMOutput(); } /* @@ -465,7 +356,7 @@ public static String getLastTestVMOutput() { * @throws TestRunException if compilation level is {@link CompLevel#SKIP} or {@link CompLevel#WAIT_FOR_COMPILATION}. */ public static void compile(Method m, CompLevel compLevel) { - TestFrameworkExecution.compile(m, compLevel); + TestVM.compile(m, compLevel); } /** @@ -474,7 +365,7 @@ public static void compile(Method m, CompLevel compLevel) { * @param m the method to be deoptimized. */ public static void deoptimize(Method m) { - TestFrameworkExecution.deoptimize(m); + TestVM.deoptimize(m); } /** @@ -485,7 +376,7 @@ public static void deoptimize(Method m) { * {@code false} otherwise. */ public static boolean isCompiled(Method m) { - return TestFrameworkExecution.isCompiled(m); + return TestVM.isCompiled(m); } /** @@ -496,7 +387,7 @@ public static boolean isCompiled(Method m) { * {@code false} otherwise. */ public static boolean isC1Compiled(Method m) { - return TestFrameworkExecution.isC1Compiled(m); + return TestVM.isC1Compiled(m); } /** @@ -507,7 +398,7 @@ public static boolean isC1Compiled(Method m) { * {@code false} otherwise. */ public static boolean isC2Compiled(Method m) { - return TestFrameworkExecution.isC2Compiled(m); + return TestVM.isC2Compiled(m); } /** @@ -519,7 +410,7 @@ public static boolean isC2Compiled(Method m) { * {@code false} otherwise. */ public static boolean isCompiledAtLevel(Method m, CompLevel compLevel) { - return TestFrameworkExecution.isCompiledAtLevel(m, compLevel); + return TestVM.isCompiledAtLevel(m, compLevel); } /** @@ -529,7 +420,7 @@ public static boolean isCompiledAtLevel(Method m, CompLevel compLevel) { * @throws TestRunException if {@code m} is not compiled at any level. */ public static void assertCompiled(Method m) { - TestFrameworkExecution.assertCompiled(m); + TestVM.assertCompiled(m); } /** @@ -539,7 +430,7 @@ public static void assertCompiled(Method m) { * @throws TestRunException if {@code m} is compiled at any level. */ public static void assertNotCompiled(Method m) { - TestFrameworkExecution.assertNotCompiled(m); + TestVM.assertNotCompiled(m); } /** @@ -549,7 +440,7 @@ public static void assertNotCompiled(Method m) { * @throws TestRunException if {@code m} is not compiled with C1. */ public static void assertCompiledByC1(Method m) { - TestFrameworkExecution.assertCompiledByC1(m); + TestVM.assertCompiledByC1(m); } /** @@ -559,7 +450,7 @@ public static void assertCompiledByC1(Method m) { * @throws TestRunException if {@code m} is not compiled with C2. */ public static void assertCompiledByC2(Method m) { - TestFrameworkExecution.assertCompiledByC2(m); + TestVM.assertCompiledByC2(m); } /** @@ -570,7 +461,7 @@ public static void assertCompiledByC2(Method m) { * @throws TestRunException if {@code m} is not compiled at {@code compLevel}. */ public static void assertCompiledAtLevel(Method m, CompLevel compLevel) { - TestFrameworkExecution.assertCompiledAtLevel(m, compLevel); + TestVM.assertCompiledAtLevel(m, compLevel); } /** @@ -580,7 +471,7 @@ public static void assertCompiledAtLevel(Method m, CompLevel compLevel) { * @throws TestRunException if {@code m} is was not deoptimized after being C1 compiled. */ public static void assertDeoptimizedByC1(Method m) { - TestFrameworkExecution.assertDeoptimizedByC1(m); + TestVM.assertDeoptimizedByC1(m); } /** @@ -590,7 +481,7 @@ public static void assertDeoptimizedByC1(Method m) { * @throws TestRunException if {@code m} is was not deoptimized after being C2 compiled. */ public static void assertDeoptimizedByC2(Method m) { - TestFrameworkExecution.assertDeoptimizedByC2(m); + TestVM.assertDeoptimizedByC2(m); } /** @@ -689,10 +580,9 @@ private void reportScenarioFailures(Map exceptionMap) { System.out.println((scenario != null ? "Scenario #" + scenario.getIndex() + " - " : "") + "Compilation(s) of failed matche(s):"); System.out.println(irException.getCompilations()); - builder.append(errorMsg).append(System.lineSeparator()).append(irException.getExceptionInfo()) - .append(e.getMessage()); - } else if (e instanceof TestVMException) { - builder.append(errorMsg).append(System.lineSeparator()).append(((TestVMException) e).getExceptionInfo()); + builder.append(errorMsg).append(System.lineSeparator()).append(irException.getExceptionInfo()); + } else if (e instanceof TestVMException testVMException) { + builder.append(errorMsg).append(System.lineSeparator()).append(testVMException.getExceptionInfo()); } else { // Print stack trace otherwise StringWriter errors = new StringWriter(); @@ -731,8 +621,6 @@ private void start(Scenario scenario) { return; } shouldVerifyIR = irVerificationPossible; - socket = TestFrameworkSocket.getSocket(); - this.scenario = scenario; try { // Use TestFramework flags and scenario flags for new VMs. List additionalFlags = new ArrayList<>(); @@ -745,20 +633,29 @@ private void start(Scenario scenario) { System.out.println("Scenario #" + scenario.getIndex() + scenarioFlagsString + ":"); additionalFlags.addAll(scenarioFlags); } - socket.start(); + String frameworkAndScenarioFlags = additionalFlags.isEmpty() ? + "" : " - [" + String.join(", ", additionalFlags) + "]"; + if (shouldVerifyIR) { + // Only need to use flag VM if an IR verification is possibly done. System.out.println("Run Flag VM:"); - runFlagVM(additionalFlags); + FlagVMProcess flagVMProcess = new FlagVMProcess(testClass, additionalFlags); + shouldVerifyIR = flagVMProcess.shouldVerifyIR(); + if (shouldVerifyIR) { + // Add more flags for the test VM which are required to do IR verification. + additionalFlags.addAll(flagVMProcess.getTestVMFlags()); + } // else: Flag VM found a reason to not do IR verification. } else { System.out.println("Skip Flag VM due to not performing IR verification."); } - String flagsString = additionalFlags.isEmpty() ? "" : " - [" + String.join(", ", additionalFlags) + "]"; - System.out.println("Run Test VM" + flagsString + ":"); + System.out.println("Run Test VM" + frameworkAndScenarioFlags + ":"); runTestVM(additionalFlags); } finally { + if (scenario != null) { + scenario.setTestVMOutput(TestVMProcess.getLastTestVMOutput()); + } System.out.println(); - socket.close(); } } @@ -780,85 +677,13 @@ private boolean onlyWhitelistedJTregVMAndJavaOptsFlags() { return true; } - private void runFlagVM(List additionalFlags) { - ArrayList cmds = prepareFlagVMFlags(additionalFlags); - OutputAnalyzer oa; - try { - // Run "flag" VM with White Box access to determine the test VM flags and if IR verification should be done. - oa = ProcessTools.executeTestJvm(cmds); - } catch (Exception e) { - throw new TestRunException("Failed to execute TestFramework flag VM", e); - } - checkFlagVMExitCode(oa); - } - - /** - * The "flag" VM needs White Box access to prepare all test VM flags. It sends these as encoding over a socket to the - * driver VM which afterwards parses the flags and adds them to the test VM. - */ - private ArrayList prepareFlagVMFlags(List additionalFlags) { - ArrayList cmds = new ArrayList<>(); - cmds.add("-Dtest.jdk=" + Utils.TEST_JDK); - // Set java.library.path so JNI tests which rely on jtreg nativepath setting work - cmds.add("-Djava.library.path=" + Utils.TEST_NATIVE_PATH); - cmds.add("-cp"); - cmds.add(Utils.TEST_CLASS_PATH); - cmds.add("-Xbootclasspath/a:."); - cmds.add("-XX:+UnlockDiagnosticVMOptions"); - cmds.add("-XX:+WhiteBoxAPI"); - cmds.add(socket.getPortPropertyFlag()); - // TestFramework and scenario flags might have an influence on the later used test VM flags. Add them as well. - cmds.addAll(additionalFlags); - cmds.add(TestFrameworkPrepareFlags.class.getCanonicalName()); - cmds.add(testClass.getCanonicalName()); - return cmds; - } - - private void checkFlagVMExitCode(OutputAnalyzer oa) { - String flagVMOutput = oa.getOutput(); - int exitCode = oa.getExitValue(); - if (VERBOSE && exitCode == 0) { - System.out.println("--- OUTPUT TestFramework flag VM ---"); - System.out.println(flagVMOutput); - } - - if (exitCode != 0) { - System.err.println("--- OUTPUT TestFramework flag VM ---"); - System.err.println(flagVMOutput); - throw new RuntimeException("TestFramework flag VM exited with " + exitCode); - } - } - private void runTestVM(List additionalFlags) { - List cmds = prepareTestVMFlags(additionalFlags); - socket.start(); - - OutputAnalyzer oa; - ProcessBuilder process = ProcessTools.createJavaProcessBuilder(cmds); - try { - // Calls 'main' of TestFrameworkExecution to run all specified tests with commands 'cmds'. - // Use executeProcess instead of executeTestJvm as we have already added the JTreg VM and - // Java options in prepareTestVMFlags(). - oa = ProcessTools.executeProcess(process); - } catch (Exception e) { - throw new TestFrameworkException("Error while executing Test VM", e); - } - JVMOutput output = new JVMOutput(oa, scenario, process); - lastTestVMOutput = oa.getOutput(); - if (scenario != null) { - scenario.setTestVMOutput(lastTestVMOutput); - } - String socketOutput = ""; - if (shouldVerifyIR || TESTLIST || EXCLUDELIST) { - // Socket has only output to read if IR verification is done and/or if a test list was provided by user - socketOutput = socket.getOutputPrintStdout(); - } - checkTestVMExitCode(output); + TestVMProcess testVMProcess = new TestVMProcess(additionalFlags, testClass, helperClasses, defaultWarmup); if (shouldVerifyIR) { try { - new IRMatcher(output.getHotspotPidFileName(), socketOutput, testClass); + new IRMatcher(testVMProcess.getHotspotPidFileName(), testVMProcess.getIrEncoding(), testClass); } catch (IRViolationException e) { - e.setExceptionInfo(output.getExceptionInfo(scenario != null)); + e.addCommandLine(testVMProcess.getCommandLine()); throw e; } } else { @@ -870,175 +695,9 @@ private void runTestVM(List additionalFlags) { } } - private List prepareTestVMFlags(List additionalFlags) { - ArrayList cmds = new ArrayList<>(); - // Set java.library.path so JNI tests which rely on jtreg nativepath setting work - cmds.add("-Djava.library.path=" + Utils.TEST_NATIVE_PATH); - // Need White Box access in test VM. - cmds.add("-Xbootclasspath/a:."); - cmds.add("-XX:+UnlockDiagnosticVMOptions"); - cmds.add("-XX:+WhiteBoxAPI"); - String[] jtregVMFlags = Utils.getTestJavaOpts(); - if (!PREFER_COMMAND_LINE_FLAGS) { - cmds.addAll(Arrays.asList(jtregVMFlags)); - } - cmds.addAll(additionalFlags); - cmds.addAll(getTestVMFlags()); - - if (PREFER_COMMAND_LINE_FLAGS) { - // Prefer flags set via the command line over the ones set by scenarios. - cmds.addAll(Arrays.asList(jtregVMFlags)); - } - - if (WARMUP_ITERATIONS < 0 && defaultWarmup != -1) { - // Only use the set warmup for the framework if not overridden by a valid -DWarmup property set by a test. - cmds.add("-DWarmup=" + defaultWarmup); - } - - // Add server property flag that enables test VM to print encoding for IR verification last and debug messages. - cmds.add(socket.getPortPropertyFlag()); - - cmds.add(TestFrameworkExecution.class.getName()); - cmds.add(testClass.getName()); - if (helperClasses != null) { - helperClasses.forEach(c -> cmds.add(c.getName())); - } - return cmds; - } - - /** - * Parse the test VM flags as prepared by the flag VM. Additionally check the property flag DShouldDoIRVerification - * to determine if IR matching should be done or not. - */ - private List getTestVMFlags() { - List flagList = new ArrayList<>(); - - if (VERIFY_VM) { - flagList.addAll(Arrays.asList(getVerifyFlags())); - } - - flagList.addAll(Arrays.asList(getDefaultFlags())); - - if (shouldVerifyIR) { - String flags = socket.getOutput(); - if (VERBOSE) { - System.out.println("Read sent data from flag VM from socket:"); - System.out.println(flags); - } - String patternString = "(?<=" + TestFramework.TEST_VM_FLAGS_START + "\\R)" + "(.*DShouldDoIRVerification=(true|false).*)\\R" - + "(?=" + IREncodingPrinter.END + ")"; - Pattern pattern = Pattern.compile(patternString); - Matcher matcher = pattern.matcher(flags); - check(matcher.find(), "Invalid flag encoding emitted by flag VM"); - // Maybe we run with flags that make IR verification impossible - shouldVerifyIR = Boolean.parseBoolean(matcher.group(2)); - flagList.addAll(Arrays.asList(matcher.group(1).split(TEST_VM_FLAGS_DELIMITER))); - } - return flagList; - } - - private void checkTestVMExitCode(JVMOutput vmOutput) { - final int exitCode = vmOutput.getExitCode(); - if (EXCLUDE_RANDOM || REPORT_STDOUT || (VERBOSE && exitCode == 0)) { - System.out.println("--- OUTPUT TestFramework test VM ---"); - System.out.println(vmOutput.getOutput()); - } - - if (exitCode != 0) { - throwTestVMException(vmOutput); - } - } - - private void throwTestVMException(JVMOutput vmOutput) { - String stdErr = vmOutput.getStderr(); - if (stdErr.contains("TestFormat.reportIfAnyFailures")) { - Pattern pattern = Pattern.compile("Violations \\(\\d+\\)[\\s\\S]*(?=/============/)"); - Matcher matcher = pattern.matcher(stdErr); - TestFramework.check(matcher.find(), "Must find violation matches"); - throw new TestFormatException(System.lineSeparator() + System.lineSeparator() + matcher.group()); - } else if (stdErr.contains("NoTestsRunException")) { - shouldVerifyIR = false; - throw new NoTestsRunException(">>> No tests run due to empty set specified with -DTest and/or -DExclude. " + - "Make sure to define a set of at least one @Test method"); - } else { - throw new TestVMException(vmOutput.getExceptionInfo(scenario != null)); - } - } - static void check(boolean test, String failureMessage) { if (!test) { throw new TestFrameworkException(failureMessage); } } } - -/** - * Class to encapsulate information about the test VM output, the run process and the scenario. - */ -class JVMOutput { - private final Scenario scenario; - private final OutputAnalyzer oa; - private final ProcessBuilder process; - private final String hotspotPidFileName; - - JVMOutput(OutputAnalyzer oa, Scenario scenario, ProcessBuilder process) { - this.oa = oa; - this.scenario = scenario; - this.process = process; - this.hotspotPidFileName = String.format("hotspot_pid%d.log", oa.pid()); - } - - public Scenario getScenario() { - return scenario; - } - - public String getCommandLine() { - return "Command Line:" + System.lineSeparator() + String.join(" ", process.command()) - + System.lineSeparator(); - } - - public int getExitCode() { - return oa.getExitValue(); - } - - public String getOutput() { - return oa.getOutput(); - } - - public String getStdout() { - return oa.getStdout(); - } - - public String getStderr() { - return oa.getStderr(); - } - - public String getHotspotPidFileName() { - return hotspotPidFileName; - } - - /** - * Get more detailed information about the exception in a pretty format. - */ - public String getExceptionInfo(boolean stripRerunHint) { - int exitCode = getExitCode(); - String stdErr = getStderr(); - String rerunHint = ""; - String stdOut = ""; - if (exitCode == 134) { - stdOut = System.lineSeparator() + System.lineSeparator() + "Standard Output" + System.lineSeparator() - + "---------------" + System.lineSeparator() + getOutput(); - } else if (!stripRerunHint) { - rerunHint = TestFramework.RERUN_HINT; - } - if (exitCode == 0) { - // IR exception - return getCommandLine() + rerunHint; - } else { - return "TestFramework test VM exited with code " + exitCode + System.lineSeparator() + stdOut - + System.lineSeparator() + getCommandLine() + System.lineSeparator() + System.lineSeparator() - + "Error Output" + System.lineSeparator() + "------------" + System.lineSeparator() + stdErr - + System.lineSeparator() + System.lineSeparator() + rerunHint; - } - } -} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java index 18c87395251..825727c1c2d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java @@ -29,7 +29,7 @@ import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; -import java.util.Scanner; +import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** @@ -40,9 +40,9 @@ class TestFrameworkSocket implements AutoCloseable { private static final String SERVER_PORT_PROPERTY = "ir.framework.server.port"; private static final int SERVER_PORT = Integer.getInteger(SERVER_PORT_PROPERTY, -1); + static final String STDOUT_PREFIX = "[STDOUT]"; private static final boolean REPRODUCE = Boolean.getBoolean("Reproduce"); private static final String HOSTNAME = null; - private static final String STDOUT_PREFIX = "[STDOUT]"; private static Socket clientSocket = null; private static PrintWriter clientWriter = null; @@ -50,9 +50,7 @@ class TestFrameworkSocket implements AutoCloseable { private FutureTask socketTask; private final ServerSocket serverSocket; - private static TestFrameworkSocket singleton = null; - - private TestFrameworkSocket() { + TestFrameworkSocket() { try { serverSocket = new ServerSocket(0); } catch (IOException e) { @@ -63,28 +61,21 @@ private TestFrameworkSocket() { System.out.println("TestFramework server socket uses port " + port); } serverPortPropertyFlag = "-D" + SERVER_PORT_PROPERTY + "=" + port; - } - - public static TestFrameworkSocket getSocket() { - if (singleton == null || singleton.serverSocket.isClosed()) { - singleton = new TestFrameworkSocket(); - return singleton; - } - return singleton; + start(); } public String getPortPropertyFlag() { return serverPortPropertyFlag; } - public void start() { + private void start() { socketTask = initSocketTask(); Thread socketThread = new Thread(socketTask); socketThread.start(); } /** - * Waits for client sockets (created by flag or test VM) to connect. Return the messages received by the clients. + * Waits for a client (created by flag or test VM) to connect. Return the messages received from the client. */ private FutureTask initSocketTask() { return new FutureTask<>(() -> { @@ -113,14 +104,14 @@ public void close() { } /** - * Only called by flag and test VM to write to server socket. + * Only called by test VM to write to server socket. */ public static void write(String msg, String type) { write(msg, type, false); } /** - * Only called by flag and test VM to write to server socket. + * Only called by test VM to write to server socket. */ public static void write(String msg, String type, boolean stdout) { if (REPRODUCE) { @@ -130,8 +121,7 @@ public static void write(String msg, String type, boolean stdout) { TestFramework.check(SERVER_PORT != -1, "Server port was not set correctly for flag and/or test VM " + "or method not called from flag or test VM"); try { - // Keep the client socket open until the flag or test VM terminates (calls closeClientSocket before exiting - // main()). + // Keep the client socket open until the test VM terminates (calls closeClientSocket before exiting main()). if (clientSocket == null) { clientSocket = new Socket(HOSTNAME, SERVER_PORT); clientWriter = new PrintWriter(clientSocket.getOutputStream(), true); @@ -145,7 +135,7 @@ public static void write(String msg, String type, boolean stdout) { // driver VM. String failMsg = System.lineSeparator() + System.lineSeparator() + """ ########################################################### - Did you directly run the test VM (TestFrameworkExecution) + Did you directly run the test VM (TestVM class) to reproduce a bug? => Append the flag -DReproduce=true and try again! ########################################################### @@ -168,7 +158,7 @@ public static void closeClientSocket() { clientWriter.close(); clientSocket.close(); } catch (IOException e) { - throw new RuntimeException("Could not close TestFrameworkExecution socket", e); + throw new RuntimeException("Could not close TestVM socket", e); } } } @@ -179,38 +169,9 @@ public static void closeClientSocket() { public String getOutput() { try { return socketTask.get(); - - } catch (Exception e) { - throw new TestFrameworkException("Could not read from socket task", e); - } - } - - /** - * Get the socket output from the test VM by stripping all lines starting with a [STDOUT] output and printing them - * to the standard output. - */ - public String getOutputPrintStdout() { - try { - String output = socketTask.get(); - if (TestFramework.TESTLIST || TestFramework.EXCLUDELIST) { - StringBuilder builder = new StringBuilder(); - Scanner scanner = new Scanner(output); - System.out.println(System.lineSeparator() + "Run flag defined test list"); - System.out.println("--------------------------"); - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - if (line.startsWith(STDOUT_PREFIX)) { - line = "> " + line.substring(STDOUT_PREFIX.length()); - System.out.println(line); - } else { - builder.append(line).append(System.lineSeparator()); - } - } - System.out.println(); - return builder.toString(); - } - return output; - + } catch (ExecutionException e) { + // Thrown when socket task was not finished, yet (i.e. no client sent data) but socket was already closed. + return ""; } catch (Exception e) { throw new TestFrameworkException("Could not read from socket task", e); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java index 59ed345471c..c7d8e2d22bc 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java @@ -54,7 +54,7 @@ public Method getTest() { * Return a boolean indicating if the framework skipped a compilation after the warm-up due to VM flags not * allowing a compilation on the requested level in {@link Test#compLevel()}. * - * @return {@code true} if the framework compiled the test; + * @return {@code true} if the framework skipped compilation of the test; * {@code false} otherwise. */ public boolean isCompilationSkipped() { @@ -68,7 +68,7 @@ public boolean isCompilationSkipped() { * {@code false} otherwise. */ public boolean isC1Compiled() { - return TestFrameworkExecution.isC1Compiled(testMethod); + return TestVM.isC1Compiled(testMethod); } /** @@ -78,7 +78,7 @@ public boolean isC1Compiled() { * {@code false} otherwise. */ public boolean isC2Compiled() { - return TestFrameworkExecution.isC2Compiled(testMethod); + return TestVM.isC2Compiled(testMethod); } /** @@ -89,6 +89,6 @@ public boolean isC2Compiled() { * {@code false} otherwise. */ public boolean isCompiledAtLevel(CompLevel compLevel) { - return TestFrameworkExecution.isCompiledAtLevel(testMethod, compLevel); + return TestVM.isCompiledAtLevel(testMethod, compLevel); } } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestVM.java similarity index 70% rename from test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java rename to test/lib/jdk/test/lib/hotspot/ir_framework/TestVM.java index 290143dab2a..56b8575d54a 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkExecution.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestVM.java @@ -32,9 +32,6 @@ import java.lang.annotation.Annotation; import java.lang.reflect.*; import java.util.*; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -43,7 +40,7 @@ * the heart of the framework and is responsible for executing all the specified tests in the test class. It uses the * Whitebox API and reflection to achieve this task. */ -public class TestFrameworkExecution { +public class TestVM { private static final WhiteBox WHITE_BOX; static { @@ -56,7 +53,7 @@ public class TestFrameworkExecution { TestFramework in main() of your test? Make sure to only call setup/run methods and no checks or assertions from main() of your test! - - Are you rerunning the test VM (TestFrameworkExecution) + - Are you rerunning the test VM (TestVM class) directly after a JTreg run? Make sure to start it from within JTwork/scratch and with the flag -DReproduce=true! @@ -104,7 +101,7 @@ assertions from main() of your test! private final Class testClass; private final Map forceCompileMap = new HashMap<>(); - private TestFrameworkExecution(Class testClass) { + private TestVM(Class testClass) { TestRun.check(testClass != null, "Test class cannot be null"); this.testClass = testClass; this.testList = createTestFilterList(TESTLIST, testClass); @@ -146,10 +143,10 @@ private static List createTestFilterList(String list, Class testClass public static void main(String[] args) { try { String testClassName = args[0]; - System.out.println("Framework main(), about to run tests in class " + testClassName); + System.out.println("TestVM main() called - about to run tests in class " + testClassName); Class testClass = getClassObject(testClassName, "test"); - TestFrameworkExecution framework = new TestFrameworkExecution(testClass); + TestVM framework = new TestVM(testClass); framework.addHelperClasses(args); framework.start(); } finally { @@ -226,7 +223,7 @@ private static void runTestsOnSameVM(Class testClass) { StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); testClass = walker.getCallerClass(); } - TestFrameworkExecution framework = new TestFrameworkExecution(testClass); + TestVM framework = new TestVM(testClass); framework.start(); } @@ -367,12 +364,11 @@ private void checkClassAnnotations(Executable ex) { * not compilable. */ static Compiler excludeRandomly(Executable ex) { - Compiler compiler; - switch (Utils.getRandomInstance().nextInt() % 3) { - case 1 -> compiler = Compiler.C1; - case 2 -> compiler = Compiler.C2; - default -> compiler = Compiler.ANY; - } + Compiler compiler = switch (Utils.getRandomInstance().nextInt() % 3) { + case 1 -> Compiler.C1; + case 2 -> Compiler.C2; + default -> Compiler.ANY; + }; WHITE_BOX.makeMethodNotCompilable(ex, compiler.getValue(), false); WHITE_BOX.makeMethodNotCompilable(ex, compiler.getValue(), true); System.out.println("Excluding from " + compiler.name() + " compilation: " + ex); @@ -471,7 +467,7 @@ private void applyForceCompileCommand(Executable ex) { } static void enqueueForCompilation(Executable ex, CompLevel requestedCompLevel) { - if (TestFrameworkExecution.VERBOSE) { + if (TestVM.VERBOSE) { System.out.println("enqueueForCompilation " + ex + ", level = " + requestedCompLevel); } CompLevel compLevel = restrictCompLevel(requestedCompLevel); @@ -752,7 +748,7 @@ private void checkForcedCompilationsCompleted() { return; } // Retry again if not yet compiled. - forceCompileMap.forEach(TestFrameworkExecution::enqueueForCompilation); + forceCompileMap.forEach(TestVM::enqueueForCompilation); elapsed = System.currentTimeMillis() - started; } while (elapsed < 5000); StringBuilder builder = new StringBuilder(); @@ -793,7 +789,8 @@ private void runTests() { for (AbstractTest test : testList) { if (VERBOSE) { System.out.println("Run " + test.toString()); - } else if (testFilterPresent) { + } + if (testFilterPresent) { TestFrameworkSocket.write("Run " + test.toString(), "testfilter", true); } try { @@ -816,7 +813,7 @@ private void runTests() { } if (GC_AFTER) { System.out.println("doing GC"); - System.gc(); + WHITE_BOX.fullGC(); } } @@ -824,7 +821,7 @@ private void runTests() { if (VERBOSE || PRINT_TIMES) { System.out.println(System.lineSeparator() + System.lineSeparator() + "Test execution times:"); for (Map.Entry entry : durations.entrySet()) { - System.out.format("%-10s%15d ns" + System.lineSeparator(), entry.getValue() + ":", entry.getKey()); + System.out.format("%-10s%15d ns%n", entry.getValue() + ":", entry.getKey()); } } @@ -953,470 +950,3 @@ private static TriState compiledAtLevel(Method m, CompLevel level) { return TriState.No; } } - -/** - * Abstract super class for base, checked and custom run tests. - */ -abstract class AbstractTest { - protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); - protected static final int TEST_COMPILATION_TIMEOUT = Integer.parseInt(System.getProperty("TestCompilationTimeout", "10000")); - protected static final int WAIT_FOR_COMPILATION_TIMEOUT = Integer.parseInt(System.getProperty("WaitForCompilationTimeout", "10000")); - protected static final boolean VERIFY_OOPS = (Boolean)WHITE_BOX.getVMFlag("VerifyOops"); - - protected final int warmupIterations; - protected final boolean skip; - - AbstractTest(int warmupIterations, boolean skip) { - this.warmupIterations = warmupIterations; - this.skip = skip; - } - - protected boolean shouldCompile(DeclaredTest test) { - return test.getCompLevel() != CompLevel.SKIP; - } - - abstract String getName(); - - /** - * Should test be executed? - */ - public boolean isSkipped() { - return skip; - } - - /** - * See {@link CompLevel#WAIT_FOR_COMPILATION}. - */ - protected static boolean isWaitForCompilation(DeclaredTest test) { - return test.getCompLevel() == CompLevel.WAIT_FOR_COMPILATION; - } - - protected static Object createInvocationTarget(Method method) { - Class clazz = method.getDeclaringClass(); - Object invocationTarget; - if (Modifier.isStatic(method.getModifiers())) { - invocationTarget = null; - } else { - try { - Constructor constructor = clazz.getDeclaredConstructor(); - constructor.setAccessible(true); - invocationTarget = constructor.newInstance(); - } catch (Exception e) { - throw new TestRunException("Could not create instance of " + clazz - + ". Make sure there is a constructor without arguments.", e); - } - } - return invocationTarget; - } - - /** - * Run the associated test. - */ - public void run() { - if (skip) { - return; - } - onStart(); - for (int i = 0; i < warmupIterations; i++) { - invokeTest(); - } - onWarmupFinished(); - compileTest(); - // Always run the test as a last step of the test execution. - invokeTest(); - } - - protected void onStart() { - // Do nothing by default. - } - - abstract protected void invokeTest(); - - abstract protected void onWarmupFinished(); - - abstract protected void compileTest(); - - protected void compileMethod(DeclaredTest test) { - final Method testMethod = test.getTestMethod(); - TestRun.check(WHITE_BOX.isMethodCompilable(testMethod, test.getCompLevel().getValue(), false), - "Method " + testMethod + " not compilable at level " + test.getCompLevel() - + ". Did you use compileonly without including all @Test methods?"); - TestRun.check(WHITE_BOX.isMethodCompilable(testMethod), - "Method " + testMethod + " not compilable at level " + test.getCompLevel() - + ". Did you use compileonly without including all @Test methods?"); - if (TestFramework.VERBOSE) { - System.out.println("Compile method " + testMethod + " after warm-up..."); - } - - final boolean maybeCodeBufferOverflow = (TestFrameworkExecution.TEST_C1 && VERIFY_OOPS); - final long started = System.currentTimeMillis(); - long elapsed = 0; - enqueueMethodForCompilation(test); - - do { - if (!WHITE_BOX.isMethodQueuedForCompilation(testMethod)) { - if (elapsed > 0) { - if (TestFrameworkExecution.VERBOSE) { - System.out.println(testMethod + " is not in queue anymore due to compiling it simultaneously on " + - "a different level. Enqueue again."); - } - enqueueMethodForCompilation(test); - } - } - if (maybeCodeBufferOverflow && elapsed > 1000 && !WHITE_BOX.isMethodCompiled(testMethod, false)) { - // Let's disable VerifyOops temporarily and retry. - WHITE_BOX.setBooleanVMFlag("VerifyOops", false); - WHITE_BOX.clearMethodState(testMethod); - enqueueMethodForCompilation(test); - WHITE_BOX.setBooleanVMFlag("VerifyOops", true); - } - - if (WHITE_BOX.getMethodCompilationLevel(testMethod, false) == test.getCompLevel().getValue()) { - break; - } - elapsed = System.currentTimeMillis() - started; - } while (elapsed < TEST_COMPILATION_TIMEOUT); - TestRun.check(elapsed < TEST_COMPILATION_TIMEOUT, - "Could not compile " + testMethod + " after " + TEST_COMPILATION_TIMEOUT/1000 + "s"); - checkCompilationLevel(test); - } - - private void enqueueMethodForCompilation(DeclaredTest test) { - TestFrameworkExecution.enqueueForCompilation(test.getTestMethod(), test.getCompLevel()); - } - - protected void checkCompilationLevel(DeclaredTest test) { - CompLevel level = CompLevel.forValue(WHITE_BOX.getMethodCompilationLevel(test.getTestMethod())); - TestRun.check(level == test.getCompLevel(), "Compilation level should be " + test.getCompLevel().name() - + " (requested) but was " + level.name() + " for " + test.getTestMethod()); - } - - final protected void waitForCompilation(DeclaredTest test) { - final Method testMethod = test.getTestMethod(); - final boolean maybeCodeBufferOverflow = (TestFrameworkExecution.TEST_C1 && VERIFY_OOPS); - final long started = System.currentTimeMillis(); - boolean stateCleared = false; - long elapsed; - do { - elapsed = System.currentTimeMillis() - started; - int level = WHITE_BOX.getMethodCompilationLevel(testMethod); - if (maybeCodeBufferOverflow && elapsed > 5000 - && (!WHITE_BOX.isMethodCompiled(testMethod, false) || level != test.getCompLevel().getValue())) { - retryDisabledVerifyOops(testMethod, stateCleared); - stateCleared = true; - } else { - invokeTest(); - } - - boolean isCompiled = WHITE_BOX.isMethodCompiled(testMethod, false); - if (TestFrameworkExecution.VERBOSE) { - System.out.println("Is " + testMethod + " compiled? " + isCompiled); - } - if (isCompiled || TestFrameworkExecution.XCOMP || TestFrameworkExecution.EXCLUDE_RANDOM) { - // Don't wait for compilation if -Xcomp is enabled or if we are randomly excluding methods from compilation. - return; - } - } while (elapsed < WAIT_FOR_COMPILATION_TIMEOUT); - throw new TestRunException(testMethod + " not compiled after waiting for " - + WAIT_FOR_COMPILATION_TIMEOUT/1000 + " s"); - } - - /** - * If it takes too long, try to disable Verify Oops. - */ - private void retryDisabledVerifyOops(Method testMethod, boolean stateCleared) { - System.out.println("Temporarily disabling VerifyOops"); - try { - WHITE_BOX.setBooleanVMFlag("VerifyOops", false); - if (!stateCleared) { - WHITE_BOX.clearMethodState(testMethod); - } - invokeTest(); - } finally { - WHITE_BOX.setBooleanVMFlag("VerifyOops", true); - System.out.println("Re-enabled VerifyOops"); - } - } -} - -/** - * A base test only consists of a single @Test method. See {@link Test} for more details and its precise definition. - */ -class BaseTest extends AbstractTest { - private final DeclaredTest test; - protected final Method testMethod; - protected final TestInfo testInfo; - protected final Object invocationTarget; - private final boolean shouldCompile; - private final boolean waitForCompilation; - - public BaseTest(DeclaredTest test, boolean skip) { - super(test.getWarmupIterations(), skip); - this.test = test; - this.testMethod = test.getTestMethod(); - this.testInfo = new TestInfo(test); - this.invocationTarget = createInvocationTarget(testMethod); - this.shouldCompile = shouldCompile(test); - this.waitForCompilation = isWaitForCompilation(test); - } - - @Override - public String toString() { - return "Base Test: @Test " + testMethod.getName(); - } - - @Override - public String getName() { - return testMethod.getName(); - } - - @Override - protected void onStart() { - test.printFixedRandomArguments(); - } - - @Override - public void onWarmupFinished() { - testInfo.setWarmUpFinished(); - } - - @Override - protected void invokeTest() { - verify(invokeTestMethod()); - } - - private Object invokeTestMethod() { - try { - if (test.hasArguments()) { - return testMethod.invoke(invocationTarget, test.getArguments()); - } else { - return testMethod.invoke(invocationTarget); - } - } catch (Exception e) { - throw new TestRunException("There was an error while invoking @Test method " + testMethod - + ". Used arguments: " + test.getArgumentsString(), e); - } - } - - @Override - protected void compileTest() { - if (shouldCompile) { - if (waitForCompilation) { - waitForCompilation(test); - } else { - compileMethod(test); - } - } - } - - /** - * Verify the result - */ - public void verify(Object result) { /* no verification in BaseTests */ } -} - -/** - * A checked test is an extension of a base test with additional verification done in a @Check method. - * See {@link Check} for more details and its precise definition. - */ -class CheckedTest extends BaseTest { - private final Method checkMethod; - private final CheckAt checkAt; - private final Parameter parameter; - private final Object checkInvocationTarget; - - enum Parameter { - NONE, RETURN_ONLY, TEST_INFO_ONLY, BOTH - } - - public CheckedTest(DeclaredTest test, Method checkMethod, Check checkSpecification, Parameter parameter, boolean excludedByUser) { - super(test, excludedByUser); - // Make sure we can also call non-public or public methods in package private classes - checkMethod.setAccessible(true); - this.checkMethod = checkMethod; - this.checkAt = checkSpecification.when(); - this.parameter = parameter; - // Use the same invocation target - if (Modifier.isStatic(checkMethod.getModifiers())) { - this.checkInvocationTarget = null; - } else { - // Use the same invocation target as the test method if check method is non-static. - this.checkInvocationTarget = this.invocationTarget != null ? this.invocationTarget : createInvocationTarget(checkMethod); - } - } - - @Override - public String toString() { - return "Checked Test: @Check " + checkMethod.getName() + " - @Test: " + testMethod.getName(); - } - - @Override - public String getName() { - return checkMethod.getName(); - } - - @Override - public void verify(Object result) { - boolean shouldVerify = false; - switch (checkAt) { - case EACH_INVOCATION -> shouldVerify = true; - case COMPILED -> shouldVerify = !testInfo.isWarmUp(); - } - if (shouldVerify) { - try { - switch (parameter) { - case NONE -> checkMethod.invoke(checkInvocationTarget); - case RETURN_ONLY -> checkMethod.invoke(checkInvocationTarget, result); - case TEST_INFO_ONLY -> checkMethod.invoke(checkInvocationTarget, testInfo); - case BOTH -> checkMethod.invoke(checkInvocationTarget, result, testInfo); - } - } catch (Exception e) { - throw new TestRunException("There was an error while invoking @Check method " + checkMethod, e); - } - } - } -} - -/** - * A custom run test allows the user to have full control over how the @Test method is invoked by specifying - * a dedicated @Run method. See {@link Run} for more details and its precise definition. - */ -class CustomRunTest extends AbstractTest { - private final Method runMethod; - private final RunMode mode; - private final Object runInvocationTarget; - private final List tests; - private final RunInfo runInfo; - - public CustomRunTest(Method runMethod, Warmup warmUpAnno, Run runSpecification, List tests, boolean skip) { - // Make sure we can also call non-public or public methods in package private classes - super(warmUpAnno != null ? warmUpAnno.value() : TestFrameworkExecution.WARMUP_ITERATIONS, skip); - TestFormat.checkNoThrow(warmupIterations >= 0, "Cannot have negative value for @Warmup at " + runMethod); - runMethod.setAccessible(true); - this.runMethod = runMethod; - this.runInvocationTarget = createInvocationTarget(runMethod); - this.mode = runSpecification.mode(); - this.tests = tests; - this.runInfo = new RunInfo(tests); - } - - @Override - public String toString() { - String s = "Custom Run Test: @Run: " + runMethod.getName() + " - @Test"; - if (tests.size() == 1) { - s += ": " + tests.get(0).getTestMethod().getName(); - } else { - s += "s: {" + tests.stream().map(t -> t.getTestMethod().getName()) - .collect(Collectors.joining(",")) + "}"; - } - return s; - } - - @Override - String getName() { - return runMethod.getName(); - } - - @Override - public void run() { - if (skip) { - return; - } - switch (mode) { - case STANDALONE -> { - runInfo.setWarmUpFinished(); - invokeTest(); - }// Invoke once but do not apply anything else. - case NORMAL -> super.run(); - } - } - - @Override - public void onWarmupFinished() { - runInfo.setWarmUpFinished(); - } - - @Override - protected void compileTest() { - if (tests.size() == 1) { - compileSingleTest(); - } else { - compileMultipleTests(); - } - } - - private void compileSingleTest() { - DeclaredTest test = tests.get(0); - if (shouldCompile(test)) { - if (isWaitForCompilation(test)) { - waitForCompilation(test); - } else { - compileMethod(test); - } - } - } - - private void compileMultipleTests() { - boolean anyWaitForCompilation = false; - boolean anyCompileMethod = false; - ExecutorService executor = Executors.newFixedThreadPool(tests.size()); - for (DeclaredTest test : tests) { - if (shouldCompile(test)) { - if (isWaitForCompilation(test)) { - anyWaitForCompilation = true; - executor.execute(() -> waitForCompilation(test)); - } else { - anyCompileMethod = true; - executor.execute(() -> compileMethod(test)); - } - } - } - executor.shutdown(); - int timeout; - if (anyCompileMethod && anyWaitForCompilation) { - timeout = Math.max(WAIT_FOR_COMPILATION_TIMEOUT, TEST_COMPILATION_TIMEOUT) + 5000; - } else if (anyWaitForCompilation) { - timeout = WAIT_FOR_COMPILATION_TIMEOUT + 5000; - } else { - timeout = TEST_COMPILATION_TIMEOUT + 5000; - } - try { - executor.awaitTermination(timeout, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - throw new TestRunException("Some compilations did not complete after " + timeout - + "ms for @Run method " + runMethod); - } - } - - /** - * Do not directly run the test but rather the run method that is responsible for invoking the actual test. - */ - @Override - protected void invokeTest() { - try { - if (runMethod.getParameterCount() == 1) { - runMethod.invoke(runInvocationTarget, runInfo); - } else { - runMethod.invoke(runInvocationTarget); - } - } catch (Exception e) { - throw new TestRunException("There was an error while invoking @Run method " + runMethod, e); - } - } - - @Override - protected void checkCompilationLevel(DeclaredTest test) { - CompLevel level = CompLevel.forValue(WhiteBox.getWhiteBox().getMethodCompilationLevel(test.getTestMethod())); - if (level != test.getCompLevel()) { - String message = "Compilation level should be " + test.getCompLevel().name() + " (requested) but was " - + level.name() + " for " + test.getTestMethod() + "."; - switch (mode) { - case STANDALONE -> throw new TestFrameworkException("Should not be called for STANDALONE method " + runMethod); - case NORMAL -> message = message + System.lineSeparator() + "Check your @Run method " + runMethod - + " to ensure that " + test.getTestMethod() - + " is called at least once in each iteration."; - } - throw new TestRunException(message); - } - } -} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMProcess.java b/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMProcess.java new file mode 100644 index 00000000000..045e77392f5 --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMProcess.java @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2021, 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 jdk.test.lib.hotspot.ir_framework; + +import jdk.test.lib.Platform; +import jdk.test.lib.Utils; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * This class prepares, creates, and runs the "test" VM with verification of proper termination. The class also stores + * information about the test VM which is later queried for IR matching. The communication between this driver VM + * and the test VM is done over a dedicated socket. + * + * @see TestVM + * @see TestFrameworkSocket + */ +class TestVMProcess { + private static final boolean VERBOSE = Boolean.getBoolean("Verbose"); + private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.getBoolean("PreferCommandLineFlags"); + private static final int WARMUP_ITERATIONS = Integer.getInteger("Warmup", -1); + private static final boolean VERIFY_VM = Boolean.getBoolean("VerifyVM") && Platform.isDebugBuild(); + private static final boolean REPORT_STDOUT = Boolean.getBoolean("ReportStdout"); + private static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); + + private static String lastTestVMOutput = ""; + + private final ArrayList cmds; + private String hotspotPidFileName; + private String commandLine; + private OutputAnalyzer oa; + private String irEncoding; + + TestVMProcess(List additionalFlags, Class testClass, Set> helperClasses, int defaultWarmup) { + this.cmds = new ArrayList<>(); + TestFrameworkSocket socket = new TestFrameworkSocket(); + try (socket) { + prepareTestVMFlags(additionalFlags, socket, testClass, helperClasses, defaultWarmup); + start(); + } + processSocketOutput(socket.getOutput()); + checkTestVMExitCode(); + } + + public String getCommandLine() { + return commandLine; + } + + public String getIrEncoding() { + return irEncoding; + } + + public String getHotspotPidFileName() { + return hotspotPidFileName; + } + + public static String getLastTestVMOutput() { + return lastTestVMOutput; + } + + private void prepareTestVMFlags(List additionalFlags, TestFrameworkSocket socket, Class testClass, + Set> helperClasses, int defaultWarmup) { + // Set java.library.path so JNI tests which rely on jtreg nativepath setting work + cmds.add("-Djava.library.path=" + Utils.TEST_NATIVE_PATH); + // Need White Box access in test VM. + cmds.add("-Xbootclasspath/a:."); + cmds.add("-XX:+UnlockDiagnosticVMOptions"); + cmds.add("-XX:+WhiteBoxAPI"); + String[] jtregVMFlags = Utils.getTestJavaOpts(); + if (!PREFER_COMMAND_LINE_FLAGS) { + cmds.addAll(Arrays.asList(jtregVMFlags)); + } + // Add server property flag that enables test VM to print encoding for IR verification last and debug messages. + cmds.add(socket.getPortPropertyFlag()); + cmds.addAll(additionalFlags); + cmds.addAll(Arrays.asList(getDefaultFlags())); + if (VERIFY_VM) { + cmds.addAll(Arrays.asList(getVerifyFlags())); + } + + if (PREFER_COMMAND_LINE_FLAGS) { + // Prefer flags set via the command line over the ones set by scenarios. + cmds.addAll(Arrays.asList(jtregVMFlags)); + } + + if (WARMUP_ITERATIONS < 0 && defaultWarmup != -1) { + // Only use the set warmup for the framework if not overridden by a valid -DWarmup property set by a test. + cmds.add("-DWarmup=" + defaultWarmup); + } + + cmds.add(TestVM.class.getName()); + cmds.add(testClass.getName()); + if (helperClasses != null) { + helperClasses.forEach(c -> cmds.add(c.getName())); + } + } + + /** + * Default flags that are added used for the test VM. + */ + private static String[] getDefaultFlags() { + return new String[] {"-XX:-BackgroundCompilation", "-XX:CompileCommand=quiet"}; + } + + /** + * Additional verification flags that are used if -DVerifyVM=true is with a debug build. + */ + private static String[] getVerifyFlags() { + return new String[] { + "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyOops", "-XX:+VerifyStack", "-XX:+VerifyLastFrame", + "-XX:+VerifyBeforeGC", "-XX:+VerifyAfterGC", "-XX:+VerifyDuringGC", "-XX:+VerifyAdapterSharing" + }; + } + + private void start() { + ProcessBuilder process = ProcessTools.createJavaProcessBuilder(cmds); + try { + // Calls 'main' of TestVM to run all specified tests with commands 'cmds'. + // Use executeProcess instead of executeTestJvm as we have already added the JTreg VM and + // Java options in prepareTestVMFlags(). + oa = ProcessTools.executeProcess(process); + } catch (Exception e) { + throw new TestFrameworkException("Error while executing Test VM", e); + } + commandLine = "Command Line:" + System.lineSeparator() + String.join(" ", process.command()) + + System.lineSeparator(); + hotspotPidFileName = String.format("hotspot_pid%d.log", oa.pid()); + lastTestVMOutput = oa.getOutput(); + } + + /** + * Process the socket output: All prefixed lines are dumped to the standard output while the remaining lines + * represent the IR encoding used for IR matching later. + */ + private void processSocketOutput(String output) { + if (TestFramework.TESTLIST || TestFramework.EXCLUDELIST) { + StringBuilder builder = new StringBuilder(); + Scanner scanner = new Scanner(output); + System.out.println(System.lineSeparator() + "Run flag defined test list"); + System.out.println("--------------------------"); + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + if (line.startsWith(TestFrameworkSocket.STDOUT_PREFIX)) { + line = "> " + line.substring(TestFrameworkSocket.STDOUT_PREFIX.length()); + System.out.println(line); + } else { + builder.append(line).append(System.lineSeparator()); + } + } + System.out.println(); + irEncoding = builder.toString(); + } else { + irEncoding = output; + } + } + + private void checkTestVMExitCode() { + final int exitCode = oa.getExitValue(); + if (EXCLUDE_RANDOM || REPORT_STDOUT || (VERBOSE && exitCode == 0)) { + System.out.println("--- OUTPUT TestFramework test VM ---"); + System.out.println(oa.getOutput()); + } + + if (exitCode != 0) { + throwTestVMException(); + } + } + + /** + * Exit code was non-zero of test VM. Check the stderr to determine what kind of exception that should be thrown to + * react accordingly later. + */ + private void throwTestVMException() { + String stdErr = oa.getStderr(); + if (stdErr.contains("TestFormat.reportIfAnyFailures")) { + Pattern pattern = Pattern.compile("Violations \\(\\d+\\)[\\s\\S]*(?=/============/)"); + Matcher matcher = pattern.matcher(stdErr); + TestFramework.check(matcher.find(), "Must find violation matches"); + throw new TestFormatException(System.lineSeparator() + System.lineSeparator() + matcher.group()); + } else if (stdErr.contains("NoTestsRunException")) { + throw new NoTestsRunException(">>> No tests run due to empty set specified with -DTest and/or -DExclude. " + + "Make sure to define a set of at least one @Test method"); + } else { + throw new TestVMException(getExceptionInfo()); + } + } + + /** + * Get more detailed information about the exception in a pretty format. + */ + private String getExceptionInfo() { + int exitCode = oa.getExitValue(); + String stdErr = oa.getStderr(); + String stdOut = ""; + if (exitCode == 134) { + // Also dump the stdout if we experience a JVM error (e.g. to show hit assertions etc.). + stdOut = System.lineSeparator() + System.lineSeparator() + "Standard Output" + System.lineSeparator() + + "---------------" + System.lineSeparator() + oa.getOutput(); + } + return "TestFramework test VM exited with code " + exitCode + System.lineSeparator() + stdOut + + System.lineSeparator() + commandLine + System.lineSeparator() + System.lineSeparator() + + "Error Output" + System.lineSeparator() + "------------" + System.lineSeparator() + stdErr + + System.lineSeparator() + System.lineSeparator(); + } +} diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java index 43845689e7f..6810b1d9da2 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java @@ -35,7 +35,7 @@ /** * If there is no warm up specified the Test Framework will do the following: *

      - *
    1. Invoke @Test method {@link TestFrameworkExecution#WARMUP_ITERATIONS} many times.

    2. + *
    3. Invoke @Test method {@link TestVM#WARMUP_ITERATIONS} many times.

    4. *
    5. Then do compilation of @Test method. (**)

    6. *
    7. Invoke @Test method once again

    8. *
    @@ -46,7 +46,7 @@ *
  • compLevel: Specify at which compilation level the test should be compiled by the framework at step (**). * If {@link CompLevel#WAIT_FOR_COMPILATION} is specified, the framework will continue invoke the * method until HotSpot compiles it. If it is not compiled after 10s, an exception is thrown.

  • - *
  • @Warmup: Change warm-up iterations of test (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS)

  • + *
  • @Warmup: Change warm-up iterations of test (defined by default by TestVM.WARMUP_ITERATIONS)

  • *
  • @Arguments: If a @Test method specifies arguments, you need to provide arguments by using @Arguments such * that the framework knows how to call the method. If you need more complex values, use @Run.

  • *
  • @IR: Arbitrary number of @IR rules.

  • diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java index 92887211dcd..ed904642515 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java @@ -35,7 +35,7 @@ /** * If there is no non-default warm-up specified, the Test Framework will do the following: *
      - *
    1. Invoke @Test method {@link TestFrameworkExecution#WARMUP_ITERATIONS} many times.

    2. + *
    3. Invoke @Test method {@link TestVM#WARMUP_ITERATIONS} many times.

    4. *
    5. By default, after each invocation, the @Check method of the @Test method is invoked. This can be disabled * by using {@link CheckAt#COMPILED}

    6. *
    7. After the warm-up, the @Test method is compiled.

    8. @@ -47,7 +47,7 @@ *
        *
      • At @Test method:

      • *
          - *
        • @Warmup: Change warm-up iterations of test (defined by default by TestFrameworkExecution.WARMUP_ITERATIONS)

        • + *
        • @Warmup: Change warm-up iterations of test (defined by default by TestVM.WARMUP_ITERATIONS)

        • *
        • @Arguments: If a @Test method specifies arguments, you need to provide arguments by using @Arguments * such that the framework knows how to call the method. If you need more complex values, use a * custom run test with @Run.

        • diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java index 18c826e12bc..af5ce9fb7a9 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java @@ -35,7 +35,7 @@ /** * If there is no warm-up specified, the Test Framework will do the following: *
            - *
          1. Invoke @Run method {#link TestFrameworkExecution#WARMUP_ITERATIONS} many times. Note that the @Run method + *

          2. Invoke @Run method {@link TestVM#WARMUP_ITERATIONS} many times. Note that the @Run method * is responsible to invoke the @Test methods to warm it up properly. This is not done by the framework. Not * invoking a @Test method will result in an -Xcomp like compilation of the method as there is no profile * information for it. The @Run method can do any arbitrary argument setup and return value verification and @@ -57,7 +57,7 @@ *

          3. At @Run method:

          4. *
              *
            • @Warmup: Change warm-up iterations of @Run method (defined by default by - * TestFrameworkExecution.WARMUP_ITERATIONS)

            • + * TestVM.WARMUP_ITERATIONS) *
            • {@link Run#test}: Specify any number of @Test methods. They cannot be shared with other @Check or @Run * methods.

            • *
            • {@link Run#mode}: Choose between normal invocation as described above or {@link RunMode#STANDALONE}. diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java index b7d2d83dfad..1aa4dfdca10 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java @@ -66,7 +66,7 @@ private static void expectTestFormatException(Class clazz, Class... helper if (helpers == null) { TestFramework.run(clazz); } else { - TestFramework.runWithHelperClasses(clazz, helpers); + new TestFramework(clazz).addHelperClasses(helpers).start(); } } catch (Exception e) { if (!(e instanceof TestFormatException)) { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java index 732924338ff..40e216b1a1f 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java @@ -52,7 +52,7 @@ public class TestBasics { public static void main(String[] args) throws Exception { // Run on same VM to make this test easier as we are not interested in any output processing. Class c = TestFramework.class; // Enable JTreg test to compile TestFramework - Method runTestsOnSameVM = TestFrameworkExecution.class.getDeclaredMethod("runTestsOnSameVM", Class.class); + Method runTestsOnSameVM = TestVM.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); runTestsOnSameVM.invoke(null, new Object[]{ null }); @@ -61,10 +61,10 @@ public static void main(String[] args) throws Exception { } for (int i = 0; i < executed.length; i++) { int value = executed[i]; - if (value != TestFrameworkExecution.WARMUP_ITERATIONS + 1) { + if (value != TestVM.WARMUP_ITERATIONS + 1) { // Warmups + 1 C2 compiled invocation throw new RuntimeException("Test " + i + " was executed " + value + " times instead stead of " - + (TestFrameworkExecution.WARMUP_ITERATIONS + 1) + " times." ); + + (TestVM.WARMUP_ITERATIONS + 1) + " times." ); } } @@ -1029,7 +1029,7 @@ public void testRunOnce2() { @Run(test = "testRunOnce2", mode = RunMode.STANDALONE) public void runTestRunOnce2(RunInfo info) { - for (int i = 0; i < TestFrameworkExecution.WARMUP_ITERATIONS + 1; i++) { + for (int i = 0; i < TestVM.WARMUP_ITERATIONS + 1; i++) { testRunOnce2(); } } @@ -1073,7 +1073,7 @@ public void testRunMultipleNotExecuted2() { @Run(test = {"testRunMultiple3", "testRunMultiple4", "testRunMultipleNotExecuted2"}, mode = RunMode.STANDALONE) public void runTestRunMultipl2(RunInfo info) { - for (int i = 0; i < TestFrameworkExecution.WARMUP_ITERATIONS + 1; i++) { + for (int i = 0; i < TestVM.WARMUP_ITERATIONS + 1; i++) { testRunMultiple3(); testRunMultiple4(); } diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java index c0a0d70e860..b935a6cc96c 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java @@ -42,15 +42,15 @@ public class TestCompLevels { static int[] testExecuted = new int[5]; public static void main(String[] args) throws Exception { - Method runTestsOnSameVM = TestFrameworkExecution.class.getDeclaredMethod("runTestsOnSameVM", Class.class); + Method runTestsOnSameVM = TestVM.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); runTestsOnSameVM.invoke(null, new Object[]{null}); for (int i = 0; i < testExecuted.length; i++) { int value = testExecuted[i]; - if (value != TestFrameworkExecution.WARMUP_ITERATIONS + 1) { + if (value != TestVM.WARMUP_ITERATIONS + 1) { // Warmups + 1 compiled invocation throw new RuntimeException("Test " + i + " was executed " + value + " times stead of " - + TestFrameworkExecution.WARMUP_ITERATIONS + 1 + " times." ); + + TestVM.WARMUP_ITERATIONS + 1 + " times." ); } } TestFramework framework = new TestFramework(TestNoTiered.class); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java index 70cd4a9bedd..e3dfa26541d 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java @@ -52,10 +52,10 @@ public class TestControls { public int iFld; public static void main(String[] args) throws Exception { - Method runTestsOnSameVM = TestFrameworkExecution.class.getDeclaredMethod("runTestsOnSameVM", Class.class); + Method runTestsOnSameVM = TestVM.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); runTestsOnSameVM.invoke(null, new Object[]{ null }); - final int defaultIterations = TestFrameworkExecution.WARMUP_ITERATIONS + 1; + final int defaultIterations = TestVM.WARMUP_ITERATIONS + 1; Asserts.assertEQ(executed[0], 1001); Asserts.assertEQ(executed[1], 101); Asserts.assertEQ(executed[2], 10000); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDScenarios.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDScenarios.java index a5dc6cf3178..f19d1caff85 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDScenarios.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDScenarios.java @@ -50,7 +50,7 @@ public static void main(String[] args) throws Exception { Scenario s2 = new Scenario(5); Scenario s3 = new Scenario(10); Scenario bad = new Scenario(0, "-Flagdoesnotexist"); // not executed - TestFramework.runWithScenarios(bad, s1, s2, s3); + new TestFramework().addScenarios(bad, s1, s2, s3).start(); } case "test2" -> { try { diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java index 77fd08b9d92..174c006d0cd 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java @@ -250,12 +250,12 @@ public static void main(String[] args) { } private static void runWithArguments(Class clazz, String... args) { - TestFramework.runWithFlags(clazz, args); + new TestFramework(clazz).addFlags(args).start(); } private static void runCheck(String[] args , Constraint... constraints) { try { - TestFramework.runWithFlags(constraints[0].getKlass(), args); // All constraints have the same class. + new TestFramework(constraints[0].getKlass()).addFlags(args).start(); // All constraints have the same class. shouldNotReach(); } catch (IRViolationException e) { checkConstraints(e, constraints); @@ -271,8 +271,8 @@ private static void runCheck(Constraint... constraints) { } } - private static void checkConstraints(RuntimeException e, Constraint[] constraints) { - String message = e.getMessage(); + private static void checkConstraints(IRViolationException e, Constraint[] constraints) { + String message = e.getExceptionInfo(); try { for (Constraint constraint : constraints) { constraint.checkConstraint(e); @@ -287,7 +287,7 @@ private static void checkConstraints(RuntimeException e, Constraint[] constraint // Single constraint private static void runFailOnTestsArgs(Constraint constraint, String... args) { try { - TestFramework.runWithFlags(constraint.getKlass(), args); // All constraints have the same class. + new TestFramework(constraint.getKlass()).addFlags(args).start(); // All constraints have the same class. shouldNotReach(); } catch (IRViolationException e) { constraint.checkConstraint(e); @@ -1385,8 +1385,8 @@ protected String errorPrefix() { return "Method " + methodName + ", Rule " + ruleIdx; } - public void checkConstraint(RuntimeException e) { - String message = e.getMessage(); + public void checkConstraint(IRViolationException e) { + String message = e.getExceptionInfo(); String[] splitMethods = message.split("Method"); for (int i = 1; i < splitMethods.length; i++) { String method = splitMethods[i]; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java index 5deeb511ab6..81dae555eac 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java @@ -45,14 +45,14 @@ public static void main(String[] args) { throw new RuntimeException("Should not reach"); } catch (IRViolationException e) { String[] matches = { "test(int)", "test2(int)", "Failed IR Rules (2)"}; - Arrays.stream(matches).forEach(m -> Asserts.assertTrue(e.getMessage().contains(m))); - Asserts.assertEQ(e.getMessage().split("STANDALONE mode", -1).length - 1, 2); + Arrays.stream(matches).forEach(m -> Asserts.assertTrue(e.getExceptionInfo().contains(m))); + Asserts.assertEQ(e.getExceptionInfo().split("STANDALONE mode", -1).length - 1, 2); } - TestFramework.runWithFlags(SkipCompilation.class, "-XX:-UseCompiler"); - TestFramework.runWithFlags(SkipCompilation.class, "-Xint"); - TestFramework.runWithFlags(SkipC2Compilation.class, "-XX:TieredStopAtLevel=1"); - TestFramework.runWithFlags(SkipC2Compilation.class, "-XX:TieredStopAtLevel=2"); - TestFramework.runWithFlags(SkipC2Compilation.class, "-XX:TieredStopAtLevel=3"); + new TestFramework(SkipCompilation.class).addFlags("-XX:-UseCompiler").start(); + new TestFramework(SkipCompilation.class).addFlags("-Xint").start(); + new TestFramework(SkipC2Compilation.class).addFlags("-XX:TieredStopAtLevel=1").start(); + new TestFramework(SkipC2Compilation.class).addFlags("-XX:TieredStopAtLevel=2").start(); + new TestFramework(SkipC2Compilation.class).addFlags("-XX:TieredStopAtLevel=3").start(); } public int iFld; diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java index e68e5cae2de..b8bf9aa17df 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java @@ -40,19 +40,20 @@ public static void main(String[] args) { TestFramework.run(); TestFramework.run(TestSanity.class); TestFramework.runWithFlags("-XX:+TieredCompilation"); - TestFramework.runWithFlags(TestSanity.class, "-XX:SuspendRetryCount=51", "-XX:+UseTLAB"); - TestFramework.runWithHelperClasses(TestSanity.class, HelperA.class); - TestFramework.runWithHelperClasses(TestSanity.class, HelperA.class, HelperB.class); + new TestFramework().addFlags("-XX:SuspendRetryCount=51", "-XX:+UseTLAB").start(); + new TestFramework(TestSanity.class).addFlags("-XX:SuspendRetryCount=51", "-XX:+UseTLAB").start(); + new TestFramework().addHelperClasses(HelperA.class).start(); + new TestFramework(TestSanity.class).addHelperClasses(HelperA.class, HelperB.class).start(); Scenario sDefault = new Scenario(0); Scenario s1 = new Scenario(1, "-XX:SuspendRetryCount=52", "-XX:+UseTLAB"); Scenario s2 = new Scenario(2, "-XX:SuspendRetryCount=53", "-XX:+UseTLAB"); - TestFramework.runWithScenarios(s1); - TestFramework.runWithScenarios(s1, s2); - TestFramework.runWithScenarios(TestSanity.class, s1, s2); - TestFramework.runWithScenarios(sDefault, s1); - TestFramework.runWithScenarios(sDefault, s1, s2); - TestFramework.runWithScenarios(TestSanity.class, sDefault, s1); - TestFramework.runWithScenarios(TestSanity.class, sDefault, s1, s2); + new TestFramework(TestSanity.class).addScenarios(s1).start(); + new TestFramework().addScenarios(s1, s2).start(); + new TestFramework(TestSanity.class).addScenarios(s1, s2).start(); + new TestFramework().addScenarios(sDefault, s1).start(); + new TestFramework().addScenarios(sDefault, s1, s2).start(); + new TestFramework(TestSanity.class).addScenarios(sDefault, s1).start(); + new TestFramework(TestSanity.class).addScenarios(sDefault, s1, s2).start(); TestFramework testFramework = new TestFramework(); testFramework.start(); testFramework.addFlags("-XX:SuspendRetryCount=54").start(); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java index 69ad312cfc5..7a097ca0181 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java @@ -42,27 +42,26 @@ public static void main(String[] args) { Scenario s3 = new Scenario(3, "-XX:SuspendRetryCount=53"); Scenario s3dup = new Scenario(3, "-XX:SuspendRetryCount=53"); try { - TestFramework.runWithScenarios(sDefault, s1, s2, s3); + new TestFramework().addScenarios(sDefault, s1, s2, s3).start(); Asserts.fail("Should not reach"); } catch (TestRunException e) { Asserts.assertTrue(e.getMessage().contains("The following scenarios have failed: #0, #1, #3"), e.getMessage()); } try { - TestFramework.runWithScenarios(s1, s2, s3); + new TestFramework().addScenarios(s1, s2, s3).start(); Asserts.fail("Should not reach"); } catch (TestRunException e) { Asserts.assertTrue(e.getMessage().contains("The following scenarios have failed: #1, #3"), e.getMessage()); } - - TestFramework.runWithScenarios(ScenarioTest.class, s1, s2, s3); + new TestFramework(ScenarioTest.class).addScenarios(s1, s2, s3).start(); try { - TestFramework.runWithScenarios(s1, s3dup, s2, s3); + new TestFramework().addScenarios(s1, s3dup, s2, s3).start(); Asserts.fail("Should not reach"); } catch (RuntimeException e) { Asserts.assertTrue(e.getMessage().contains("Cannot define two scenarios with the same index 3"), e.getMessage()); } try { - TestFramework.runWithScenarios(MyExceptionTest.class, s1, s2, s3); + new TestFramework(MyExceptionTest.class).addScenarios(s1, s2, s3).start(); Asserts.fail("Should not reach"); } catch (TestRunException e) { Asserts.assertTrue(s1.getTestVMOutput().contains("Caused by: jdk.test.lib.hotspot.ir_framework.tests.MyScenarioException")); diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java index c9c13928465..c1065607545 100644 --- a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java @@ -36,9 +36,9 @@ public class TestWithHelperClasses { public static void main(String[] args) { - TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class, Helper2.class); + new TestFramework().addHelperClasses(Helper1.class, Helper2.class).start(); try { - TestFramework.runWithHelperClasses(TestWithHelperClasses.class, Helper1.class); + new TestFramework().addHelperClasses(Helper1.class).start(); shouldNotReach(); } catch (TestVMException e) { Asserts.assertFalse(e.getExceptionInfo().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper1.foo() should have been C2 compiled")); @@ -50,7 +50,7 @@ public static void main(String[] args) { } try { - TestFramework.runWithHelperClasses(BadHelperClass.class, BadHelper.class); + new TestFramework(BadHelperClass.class).addHelperClasses(BadHelper.class).start(); shouldNotReach(); } catch (TestFormatException e) { Asserts.assertTrue(e.getMessage().contains("Cannot use @Test annotation in helper class")); @@ -64,7 +64,7 @@ public static void main(String[] args) { } try { - TestFramework.runWithHelperClasses(TestAsHelper.class, TestAsHelper.class); + new TestFramework(TestAsHelper.class).addHelperClasses(TestAsHelper.class).start(); shouldNotReach(); } catch (TestFormatException e) { Asserts.assertTrue(e.getMessage().contains("Cannot specify test class jdk.test.lib.hotspot.ir_framework." + @@ -72,7 +72,7 @@ public static void main(String[] args) { } try { - TestFramework.runWithHelperClasses(TestWithHelperClasses.class, NestedHelper.class); + new TestFramework().addHelperClasses(NestedHelper.class).start(); shouldNotReach(); } catch (TestFormatException e) { Asserts.assertTrue(e.getMessage().contains("Nested class")); From cb4570176da6d18591506bf851f7a35d1fd552a6 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 1 Jun 2021 16:18:46 +0200 Subject: [PATCH 119/131] Add README.md file --- .../test/lib/hotspot/ir_framework/README.md | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 test/lib/jdk/test/lib/hotspot/ir_framework/README.md diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/README.md b/test/lib/jdk/test/lib/hotspot/ir_framework/README.md new file mode 100644 index 00000000000..bc8dec705da --- /dev/null +++ b/test/lib/jdk/test/lib/hotspot/ir_framework/README.md @@ -0,0 +1,126 @@ +# IR Test Framework +This folder contains a test framework whose main purpose is to perform regex-based checks on the C2 IR shape of test methods emitted by the VM flags _-XX:+PrintIdeal_ and _-XX:+PrintOptoAssembly_. The framework can also be used for other non-IR matching (and non-compiler) tests by providing easy to use annotations for commonly used testing patterns and compiler control flags. + +## 1. How to Use the Framework +The framework is intended to be used in JTreg tests. The JTreg header of the test must contain `@library /test/lib` and should be run as a driver with `@run driver`. Annotate the test code with the supported framework annotations and call the framework from within the test's `main()` method. A simple example is shown below: + + /* + * @test + * @summary A simple test using the test framework. + * @library /test/lib + * @run driver my.package.MySimpleTest + */ + + package my.package; + + import jdk.test.lib.hotspot.ir_framework.*; + + public class MySimpleTest { + + public static void main(String[] args) { + TestFramework.run(); // The framework runs all tests of this class. + } + + @Test + @IR(failOn = IRNode.STORE) // Fail if the IR of myTest() contains any stores. + public void myTest() { + /* ... */ + } + } + +There are various ways how to set up and run a test within the `main()` method of a JTreg test. These are described and can be found in the [TestFramework](./TestFramework.java) class. + +## 2. Features + The framework offers various annotations and flags to control how your test code should be invoked and being checked. This section gives an overview over all these features. + +### 2.1 Different Tests +There are three kinds of tests depending on how much control is needed over the test invocation. +#### Base Tests +The simplest form of testing provides a single `@Test` annotated method which the framework will invoke as part of the testing. The test method has no or well-defined arguments that the framework can automatically provide. + +More information on base tests with a precise definition can be found in the Javadocs of [Test](./Test.java). Concrete examples on how to specify a base test can be found in [BaseTestsExample](./examples/BaseTestExample.java). + +#### Checked Tests +The base tests do not provide any way of verification by user code. A checked test enables this by allowing the user to define an additional `@Check` annotated method which is invoked directly after the `@Test` annotated method. This allows the user to perform various checks about the test method including return value verification. + +More information on checked tests with a precise definition can be found in the Javadocs of [Check](./Check.java). Concrete examples on how to specify a checked test can be found in [CheckedTestsExample](./examples/CheckedTestExample.java). + +#### Custom Run Tests +Neither the base nor the checked tests provide any control over how a `@Test` annotated method is invoked in terms of customized argument values and/or conditions for the invocation itself. A custom run test gives full control over the invocation of the `@Test` annotated method to the user. The framework calls a dedicated `@Run` annotated method from which the user can invoke the `@Test` method according to his/her needs. + +More information on checked tests with a precise definition can be found in the Javadocs of [Run](./Run.java). Concrete examples on how to specify a custom run test can be found in [CustomRunTestsExample](./examples/CustomRunTestExample.java). + +### 2.2 IR Verification +The main feature of this framework is to perform a simple but yet powerful regex-based C2 IR matching on the output of _-XX:+PrintIdeal_ and _-XX:+PrintOptoAssembly_. For simplicity, we will refer to the "IR" or "IR matching" when actually meaning the combined output of _-XX:+PrintIdeal_ and _-XX:+PrintOptoAssembly_ for a C2 compilation. + +The user has the possibility to add an additional `@IR` annotation to any `@Test` annotated method (regardless of the kind of test mentioned in section 2.1) to specify a constraint/rule on the compiled IR shape. The `@IR` annotation provides two kinds of regex checks: + + - A `failOn` check that verifies that the provided regex is not matched in the C2 IR. + - A `counts` check that verifies that the provided regex is matched a user defined number of times in the C2 IR. + +A regex can either be a custom string or any of the default regexes provided by the framework in [IRNode](IRNode.java) for some commonly used IR nodes (also provides the possibility of composite regexes). + +An IR verification cannot always be performed. For example, a JTreg test could be run with _-Xint_ or not a debug build (_-XX:+PrintIdeal_ and _-XX:+PrintOptoAssembly_ are debug build flags). But also CI tier testing could add additional JTreg VM and Javaoptions flags which could make an IR rule unstable. + +In general, the framework will only perform IR verification if the used VM flags allow a C2 compilation and if non-critical additional JTreg VM and Javaoptions are provided (see whiteflag list in [TestFramework](./TestFramework.java)). The user test code, however, can specify any flags which still allow an IR verification to be performed if a C2 compilation is done (expected flags by user defined `@IR` annotations). + +An `@IR` annotation allows additional preconditions/restrictions on the currently present VM flags to enable or disable rules when certain flags are present or have a specific value (see `applyIfXX` properties of an `@IR` annotation). + +More information about IR matching can be found in the Javadocs of [IR](./IR.java). Concrete examples on how to specify IR constraint/rules can be found in [IRExample](./examples/IRExample.java) and [TestIRMatching](./tests/TestIRMatching.java) (an internal framework test). + +### 2.3 Test VM Flags and Scenarios +The recommended way to use the framework is by defining a single `@run driver` statement in the JTreg header which, however, does not allow the specification of additional test VM flags. Instead, the user has the possibility to provide VM flags by calling `TestFramework.runWithFlags()` or by creating a `TestFramework` builder object on which `addFlags()` can be called. + +If a user wants to provide multiple flag combinations for a single test, he or she has the option to provide different scenarios. A scenario based flag will always have precedence over other user defined flags. More information about scenarios can be found in the Javadocs of [Scenario](./Scenario.java). + +### 2.4 Compiler Controls +The framework allows the use of additional compiler control annotations for helper method and classes in the same fashion as JMH does. The following annotations are supported and described in the referenced Javadocs for the annotation class: + +- [@DontInline](./DontInline.java) +- [@ForceInline](./ForceInline.java) +- [@DontCompile](./DontCompile.java) +- [@ForceCompile](./DontCompile.java) +- [@ForceCompileClassInitializer](./ForceCompileClassInitializer.java) + +### 2.5 Framework Debug and Stress Flags +The framework provides various stress and debug flags. They should mainly be used as JTreg VM and/or Javaoptions (apart from `VerifyIR`). The following (property) flags are supported: + +- `-DVerifyIR=false`: Explicitly disable IR verification. This is useful, for example, if some scenarios use VM flags that let `@IR` annotation rules fail and the user does not want to provide separate IR rules or add flag preconditions to the already existing IR rules. +- `-DTest=test1,test2`: Provide a list of `@Test` method names which should be executed. +- `-DExclude=test3`: Provide a list of `@Test` method names which should be excluded from execution. +- `-DScenarios=1,2`: Provide a list of scenario indexes to specify which scenarios should be executed. +- `-DWarmup=200`: Provide a new default value of the number of warm-up iterations (framework default is 2000). This might have an influence on the resulting IR and could lead to matching failures (the user can also set a fixed default warm-up value in a test with `testFrameworkObject.setDefaultWarmup(200)`). +- `-DVerbose=true`: Enable more fain-grained logging (slows the execution down). +- `-DReproduce=true`: Flag to use when directly running a test VM to bypass dependencies to the driver VM state (for example, when reproducing an issue). +- `-DPrintTimes=true`: Print the execution time measurements of each executed test. +- `-DVerifyVM=true`: The framework runs the test VM with additional verification flags (slows the execution down). +- `-DExcluceRandom=true`: The framework randomly excludes some methods from compilation. IR verification is disabled completely with this flag. +- `-DFlipC1C2=true`: The framework compiles all `@Test` annotated method with C1 if a C2 compilation would have been applied and vice versa. IR verification is disabled completely with this flag. +- `-DShuffleTests=false`: Disables the random execution order of all tests (such a shuffling is always done by default). +- `-DDumpReplay=true`: Add the `DumpReplay` directive to the test VM. +- `-DGCAfter=true`: Perform `System.gc()` after each test (slows the execution down). +- `-DWaitForCompilationTimeout=20`: Change the default waiting time (default: 10s) for a compilation of a `@Test` annotated method with compilation level [WAIT_FOR_COMPILATION](./CompLevel.java). +- `-DIgnoreCompilerControls=false`: Ignore all compiler controls applied in the framework. This includes any compiler control annotations (`@DontCompile`, `@DontInline`, `@ForceCompile`, `@ForceInline`, `@ForceCompileStaticInitializer`), the exclusion of `@Run` and `@Check` methods from compilation, and the directive to not inline `@Test` annotated methods. + + +## 3. Test Framework Execution +This section gives an overview of how the framework is executing a JTreg test that calls the framework from within its `main()` method. + +The framework will spawn a new "test VM" to execute the user defined tests. The test VM collects all tests of the test class specified by the user code in `main()` and ensures that there is no violation of the required format by the framework. In a next step, the framework does the following for each test in general: +1. Warm the test up for a predefined number of times (default 2000). This can also be adapted for all tests by using `testFrameworkobject.setDefaultWarmup(100)` or for individual tests with an additional [@Warmup](./Warmup.java) annotation. +2. After the warm-up is finished, the framework compiles the associated `@Test` annotated method at the specified compilation level (default: C2). +3. After the compilation, the test is invoked one more time. + +Once the test VM terminates, IR verification (if possible) is performed on the output of the test VM. If any test throws an exception during its execution or if IR matching fails, the failures are collected and reported in a pretty format. Check the standard error and output for more information and how to reproduce these failures. + +Some of the steps above can be different due to the kind of the test or due to using non-default annotation properties. These details and differences are described in the Javadocs for the three tests (see section 2.1 Different Tests). + +More information about the internals and the workflow of the framework can be found in the Javadocs of [TestFramework](./TestFramework.java). + +## 4. Internal Framework Tests +There are various tests to verify the correctness of the test framework. These tests can be found in [tests](tests) and can directly be run with JTreg. The tests are not part of the normal JTreg tests of HotSpot and should only be run upon changing the framework code as a minimal form of testing. + +Additional testing was performed by converting all compiler Inline Types tests that used the currently present IR test framework in Valhalla (see [JDK-8263024](https://bugs.openjdk.java.net/browse/JDK-8263024)). It is strongly advised to make sure a change to the framework still lets these converted tests in Valhalla pass as part of an additional testing step. + +## 5. Summary + The initial design and feature set was kept simple and straight forward and serves well for small to medium sized tests. There are a lot of possibilities to further enhance the framework and make it more powerful. This can be tackled in additional RFEs. A few ideas can be found as subtasks of the [initial RFE](https://bugs.openjdk.java.net/browse/JDK-8254129) for this framework. From 217a6268f4b4bac91af5f5c667fe86a2cf31c58b Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 4 May 2021 11:26:42 +0200 Subject: [PATCH 120/131] Move framework to test/hotspot/jtreg/compiler/lib and tests to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework --- .../jtreg/compiler/lib}/ir_framework/AbstractInfo.java | 0 .../jtreg/compiler/lib}/ir_framework/AbstractTest.java | 0 .../jtreg/compiler/lib}/ir_framework/Argument.java | 0 .../jtreg/compiler/lib}/ir_framework/ArgumentValue.java | 0 .../jtreg/compiler/lib}/ir_framework/Arguments.java | 0 .../jtreg/compiler/lib}/ir_framework/BaseTest.java | 0 .../jtreg/compiler/lib}/ir_framework/Check.java | 0 .../jtreg/compiler/lib}/ir_framework/CheckAt.java | 0 .../jtreg/compiler/lib}/ir_framework/CheckedTest.java | 0 .../compiler/lib}/ir_framework/CheckedTestFrameworkException.java | 0 .../jtreg/compiler/lib}/ir_framework/CompLevel.java | 0 .../jtreg/compiler/lib}/ir_framework/Compiler.java | 0 .../jtreg/compiler/lib}/ir_framework/CustomRunTest.java | 0 .../jtreg/compiler/lib}/ir_framework/DeclaredTest.java | 0 .../jtreg/compiler/lib}/ir_framework/DontCompile.java | 0 .../jtreg/compiler/lib}/ir_framework/DontInline.java | 0 .../jtreg/compiler/lib}/ir_framework/FlagVM.java | 0 .../jtreg/compiler/lib}/ir_framework/FlagVMProcess.java | 0 .../jtreg/compiler/lib}/ir_framework/ForceCompile.java | 0 .../compiler/lib}/ir_framework/ForceCompileClassInitializer.java | 0 .../jtreg/compiler/lib}/ir_framework/ForceInline.java | 0 .../hotspot => hotspot/jtreg/compiler/lib}/ir_framework/IR.java | 0 .../jtreg/compiler/lib}/ir_framework/IREncodingPrinter.java | 0 .../jtreg/compiler/lib}/ir_framework/IRMatcher.java | 0 .../jtreg/compiler/lib}/ir_framework/IRMethod.java | 0 .../jtreg/compiler/lib}/ir_framework/IRNode.java | 0 .../jtreg/compiler/lib}/ir_framework/IRViolationException.java | 0 .../hotspot => hotspot/jtreg/compiler/lib}/ir_framework/IRs.java | 0 .../jtreg/compiler/lib}/ir_framework/NoTestsRunException.java | 0 .../jtreg/compiler/lib}/ir_framework/ParsedComparator.java | 0 .../hotspot => hotspot/jtreg/compiler/lib}/ir_framework/README.md | 0 .../hotspot => hotspot/jtreg/compiler/lib}/ir_framework/Run.java | 0 .../jtreg/compiler/lib}/ir_framework/RunInfo.java | 0 .../jtreg/compiler/lib}/ir_framework/RunMode.java | 0 .../jtreg/compiler/lib}/ir_framework/Scenario.java | 0 .../hotspot => hotspot/jtreg/compiler/lib}/ir_framework/Test.java | 0 .../jtreg/compiler/lib}/ir_framework/TestFormat.java | 0 .../jtreg/compiler/lib}/ir_framework/TestFormatException.java | 0 .../jtreg/compiler/lib}/ir_framework/TestFramework.java | 0 .../jtreg/compiler/lib}/ir_framework/TestFrameworkException.java | 0 .../jtreg/compiler/lib}/ir_framework/TestFrameworkSocket.java | 0 .../jtreg/compiler/lib}/ir_framework/TestInfo.java | 0 .../jtreg/compiler/lib}/ir_framework/TestRun.java | 0 .../jtreg/compiler/lib}/ir_framework/TestRunException.java | 0 .../jtreg/compiler/lib}/ir_framework/TestVM.java | 0 .../jtreg/compiler/lib}/ir_framework/TestVMException.java | 0 .../jtreg/compiler/lib}/ir_framework/TestVMProcess.java | 0 .../jtreg/compiler/lib}/ir_framework/Warmup.java | 0 .../compiler/lib}/ir_framework/examples/BaseTestExample.java | 0 .../compiler/lib}/ir_framework/examples/CheckedTestExample.java | 0 .../compiler/lib}/ir_framework/examples/CustomRunTestExample.java | 0 .../jtreg/compiler/lib}/ir_framework/examples/IRExample.java | 0 .../jtreg/compiler/lib}/ir_framework/examples/TEST.ROOT | 0 .../jtreg/testlibrary_tests/compiler/lib/ir_framework}/README.md | 0 .../jtreg/testlibrary_tests/compiler/lib/ir_framework}/TEST.ROOT | 0 .../compiler/lib/ir_framework}/TestAccessModifiers.java | 0 .../compiler/lib/ir_framework}/TestBadFormat.java | 0 .../testlibrary_tests/compiler/lib/ir_framework}/TestBasics.java | 0 .../compiler/lib/ir_framework}/TestCompLevels.java | 0 .../compiler/lib/ir_framework}/TestControls.java | 0 .../testlibrary_tests/compiler/lib/ir_framework}/TestDFlags.java | 0 .../compiler/lib/ir_framework}/TestDIgnoreCompilerControls.java | 0 .../compiler/lib/ir_framework}/TestDScenarios.java | 0 .../compiler/lib/ir_framework}/TestDTestAndExclude.java | 0 .../compiler/lib/ir_framework}/TestIRMatching.java | 0 .../compiler/lib/ir_framework}/TestRunTests.java | 0 .../testlibrary_tests/compiler/lib/ir_framework}/TestSanity.java | 0 .../compiler/lib/ir_framework}/TestScenarios.java | 0 .../compiler/lib/ir_framework}/TestWithHelperClasses.java | 0 69 files changed, 0 insertions(+), 0 deletions(-) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/AbstractInfo.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/AbstractTest.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/Argument.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/ArgumentValue.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/Arguments.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/BaseTest.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/Check.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/CheckAt.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/CheckedTest.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/CheckedTestFrameworkException.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/CompLevel.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/Compiler.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/CustomRunTest.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/DeclaredTest.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/DontCompile.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/DontInline.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/FlagVM.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/FlagVMProcess.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/ForceCompile.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/ForceCompileClassInitializer.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/ForceInline.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/IR.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/IREncodingPrinter.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/IRMatcher.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/IRMethod.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/IRNode.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/IRViolationException.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/IRs.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/NoTestsRunException.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/ParsedComparator.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/README.md (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/Run.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/RunInfo.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/RunMode.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/Scenario.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/Test.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/TestFormat.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/TestFormatException.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/TestFramework.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/TestFrameworkException.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/TestFrameworkSocket.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/TestInfo.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/TestRun.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/TestRunException.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/TestVM.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/TestVMException.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/TestVMProcess.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/Warmup.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/examples/BaseTestExample.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/examples/CheckedTestExample.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/examples/CustomRunTestExample.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/examples/IRExample.java (100%) rename test/{lib/jdk/test/lib/hotspot => hotspot/jtreg/compiler/lib}/ir_framework/examples/TEST.ROOT (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/README.md (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TEST.ROOT (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TestAccessModifiers.java (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TestBadFormat.java (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TestBasics.java (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TestCompLevels.java (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TestControls.java (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TestDFlags.java (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TestDIgnoreCompilerControls.java (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TestDScenarios.java (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TestDTestAndExclude.java (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TestIRMatching.java (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TestRunTests.java (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TestSanity.java (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TestScenarios.java (100%) rename test/{lib/jdk/test/lib/hotspot/ir_framework/tests => hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework}/TestWithHelperClasses.java (100%) diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java b/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractInfo.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/AbstractInfo.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/AbstractInfo.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/AbstractTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractTest.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/AbstractTest.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/AbstractTest.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Argument.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/Argument.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/Argument.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java b/test/hotspot/jtreg/compiler/lib/ir_framework/ArgumentValue.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/ArgumentValue.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/ArgumentValue.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Arguments.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/Arguments.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/Arguments.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/BaseTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/BaseTest.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/BaseTest.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/BaseTest.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Check.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Check.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/Check.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/Check.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CheckAt.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/CheckAt.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/CheckAt.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTest.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTest.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTest.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTestFrameworkException.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/CheckedTestFrameworkException.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTestFrameworkException.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/CompLevel.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Compiler.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Compiler.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/Compiler.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/Compiler.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/CustomRunTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CustomRunTest.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/CustomRunTest.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/CustomRunTest.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/DeclaredTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/DeclaredTest.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/DeclaredTest.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/DeclaredTest.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/DontCompile.java b/test/hotspot/jtreg/compiler/lib/ir_framework/DontCompile.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/DontCompile.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/DontCompile.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/DontInline.java b/test/hotspot/jtreg/compiler/lib/ir_framework/DontInline.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/DontInline.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/DontInline.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/FlagVM.java b/test/hotspot/jtreg/compiler/lib/ir_framework/FlagVM.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/FlagVM.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/FlagVM.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/FlagVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/FlagVMProcess.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/FlagVMProcess.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/FlagVMProcess.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompile.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompile.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompile.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompileClassInitializer.java b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompileClassInitializer.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/ForceCompileClassInitializer.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompileClassInitializer.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ForceInline.java b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceInline.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/ForceInline.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/ForceInline.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IR.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IR.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/IR.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/IR.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IREncodingPrinter.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/IREncodingPrinter.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/IREncodingPrinter.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRMatcher.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/IRMatcher.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/IRMatcher.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRMethod.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRMethod.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/IRMethod.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/IRMethod.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/IRNode.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRViolationException.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/IRViolationException.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/IRViolationException.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/IRs.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRs.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/IRs.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/IRs.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/NoTestsRunException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/NoTestsRunException.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/NoTestsRunException.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/NoTestsRunException.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java b/test/hotspot/jtreg/compiler/lib/ir_framework/ParsedComparator.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/ParsedComparator.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/ParsedComparator.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/README.md b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/README.md rename to test/hotspot/jtreg/compiler/lib/ir_framework/README.md diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Run.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Run.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/Run.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/Run.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java b/test/hotspot/jtreg/compiler/lib/ir_framework/RunInfo.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/RunInfo.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/RunInfo.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/RunMode.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/RunMode.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/RunMode.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Scenario.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/Scenario.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/Scenario.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Test.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Test.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/Test.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/Test.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFormat.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/TestFormat.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/TestFormat.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFormatException.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/TestFormatException.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/TestFormatException.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/TestFramework.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkException.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkException.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkException.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkSocket.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/TestFrameworkSocket.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkSocket.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestInfo.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/TestInfo.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/TestInfo.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestRun.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/TestRun.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/TestRun.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestRunException.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/TestRunException.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/TestRunException.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestVM.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestVM.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/TestVM.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/TestVM.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestVMException.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/TestVMException.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/TestVMException.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/TestVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestVMProcess.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/TestVMProcess.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/TestVMProcess.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Warmup.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/Warmup.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/Warmup.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java b/test/hotspot/jtreg/compiler/lib/ir_framework/examples/BaseTestExample.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/examples/BaseTestExample.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/examples/BaseTestExample.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java b/test/hotspot/jtreg/compiler/lib/ir_framework/examples/CheckedTestExample.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/examples/CheckedTestExample.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/examples/CheckedTestExample.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java b/test/hotspot/jtreg/compiler/lib/ir_framework/examples/CustomRunTestExample.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/examples/CustomRunTestExample.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/examples/CustomRunTestExample.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java b/test/hotspot/jtreg/compiler/lib/ir_framework/examples/IRExample.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/examples/IRExample.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/examples/IRExample.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/examples/TEST.ROOT b/test/hotspot/jtreg/compiler/lib/ir_framework/examples/TEST.ROOT similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/examples/TEST.ROOT rename to test/hotspot/jtreg/compiler/lib/ir_framework/examples/TEST.ROOT diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/README.md b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/README.md similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/README.md rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/README.md diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TEST.ROOT b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TEST.ROOT similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TEST.ROOT rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TEST.ROOT diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestAccessModifiers.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestAccessModifiers.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestAccessModifiers.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestAccessModifiers.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBadFormat.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBasics.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestBasics.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBasics.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestCompLevels.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestControls.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDFlags.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDFlags.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDFlags.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDFlags.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDIgnoreCompilerControls.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDIgnoreCompilerControls.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDIgnoreCompilerControls.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDIgnoreCompilerControls.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDScenarios.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDScenarios.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDScenarios.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDScenarios.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDTestAndExclude.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDTestAndExclude.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestDTestAndExclude.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDTestAndExclude.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestIRMatching.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestRunTests.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestRunTests.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestRunTests.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestSanity.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestSanity.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestSanity.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestScenarios.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java diff --git a/test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestWithHelperClasses.java similarity index 100% rename from test/lib/jdk/test/lib/hotspot/ir_framework/tests/TestWithHelperClasses.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestWithHelperClasses.java From f2a8aad807d0b1c7519c951596346ad4e380585a Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 4 May 2021 13:56:47 +0200 Subject: [PATCH 121/131] Fix package names and fixing internal tests, examples and README file accordingly --- .../lib/ir_framework/AbstractInfo.java | 2 +- .../lib/ir_framework/AbstractTest.java | 2 +- .../compiler/lib/ir_framework/Argument.java | 2 +- .../lib/ir_framework/ArgumentValue.java | 2 +- .../compiler/lib/ir_framework/Arguments.java | 2 +- .../compiler/lib/ir_framework/BaseTest.java | 2 +- .../compiler/lib/ir_framework/Check.java | 2 +- .../compiler/lib/ir_framework/CheckAt.java | 2 +- .../lib/ir_framework/CheckedTest.java | 2 +- .../CheckedTestFrameworkException.java | 2 +- .../compiler/lib/ir_framework/CompLevel.java | 2 +- .../compiler/lib/ir_framework/Compiler.java | 2 +- .../lib/ir_framework/CustomRunTest.java | 2 +- .../lib/ir_framework/DeclaredTest.java | 2 +- .../lib/ir_framework/DontCompile.java | 2 +- .../compiler/lib/ir_framework/DontInline.java | 2 +- .../compiler/lib/ir_framework/FlagVM.java | 2 +- .../lib/ir_framework/FlagVMProcess.java | 2 +- .../lib/ir_framework/ForceCompile.java | 2 +- .../ForceCompileClassInitializer.java | 2 +- .../lib/ir_framework/ForceInline.java | 2 +- .../jtreg/compiler/lib/ir_framework/IR.java | 2 +- .../lib/ir_framework/IREncodingPrinter.java | 2 +- .../compiler/lib/ir_framework/IRMatcher.java | 2 +- .../compiler/lib/ir_framework/IRMethod.java | 2 +- .../compiler/lib/ir_framework/IRNode.java | 2 +- .../ir_framework/IRViolationException.java | 2 +- .../jtreg/compiler/lib/ir_framework/IRs.java | 2 +- .../lib/ir_framework/NoTestsRunException.java | 2 +- .../lib/ir_framework/ParsedComparator.java | 2 +- .../jtreg/compiler/lib/ir_framework/README.md | 14 ++++---- .../jtreg/compiler/lib/ir_framework/Run.java | 2 +- .../compiler/lib/ir_framework/RunInfo.java | 2 +- .../compiler/lib/ir_framework/RunMode.java | 2 +- .../compiler/lib/ir_framework/Scenario.java | 2 +- .../jtreg/compiler/lib/ir_framework/Test.java | 2 +- .../compiler/lib/ir_framework/TestFormat.java | 2 +- .../lib/ir_framework/TestFormatException.java | 2 +- .../lib/ir_framework/TestFramework.java | 2 +- .../ir_framework/TestFrameworkException.java | 2 +- .../lib/ir_framework/TestFrameworkSocket.java | 2 +- .../compiler/lib/ir_framework/TestInfo.java | 2 +- .../compiler/lib/ir_framework/TestRun.java | 2 +- .../lib/ir_framework/TestRunException.java | 2 +- .../compiler/lib/ir_framework/TestVM.java | 2 +- .../lib/ir_framework/TestVMException.java | 2 +- .../lib/ir_framework/TestVMProcess.java | 2 +- .../compiler/lib/ir_framework/Warmup.java | 2 +- .../lib/ir_framework/examples/TEST.ROOT | 26 -------------- .../compiler/lib/ir_framework/TEST.ROOT | 35 ------------------- .../lib/ir_framework/TestAccessModifiers.java | 9 +++-- .../lib/ir_framework/TestBadFormat.java | 10 +++--- .../compiler/lib/ir_framework/TestBasics.java | 10 +++--- .../lib/ir_framework/TestCompLevels.java | 9 +++-- .../lib/ir_framework/TestControls.java | 10 +++--- .../compiler/lib/ir_framework/TestDFlags.java | 31 ++++++++-------- .../TestDIgnoreCompilerControls.java | 13 ++++--- .../lib/ir_framework/TestDScenarios.java | 19 +++++----- .../lib/ir_framework/TestDTestAndExclude.java | 10 +++--- .../lib/ir_framework/TestIRMatching.java | 31 ++++++++-------- .../lib/ir_framework/TestRunTests.java | 9 +++-- .../compiler/lib/ir_framework/TestSanity.java | 11 +++--- .../lib/ir_framework/TestScenarios.java | 15 ++++---- .../ir_framework/TestWithHelperClasses.java | 20 +++++------ .../examples/BaseTestExample.java | 9 +++-- .../examples/CheckedTestExample.java | 8 ++--- .../examples/CustomRunTestExample.java | 8 ++--- .../lib/ir_framework/examples/IRExample.java | 15 ++++---- 68 files changed, 167 insertions(+), 249 deletions(-) delete mode 100644 test/hotspot/jtreg/compiler/lib/ir_framework/examples/TEST.ROOT delete mode 100644 test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TEST.ROOT rename test/hotspot/jtreg/{ => testlibrary_tests}/compiler/lib/ir_framework/examples/BaseTestExample.java (94%) rename test/hotspot/jtreg/{ => testlibrary_tests}/compiler/lib/ir_framework/examples/CheckedTestExample.java (96%) rename test/hotspot/jtreg/{ => testlibrary_tests}/compiler/lib/ir_framework/examples/CustomRunTestExample.java (96%) rename test/hotspot/jtreg/{ => testlibrary_tests}/compiler/lib/ir_framework/examples/IRExample.java (95%) diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractInfo.java b/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractInfo.java index d4b11df0b98..77074ae525d 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractInfo.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractInfo.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import jdk.test.lib.Utils; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractTest.java index 5bf84828602..b8d3c64867b 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractTest.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractTest.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import sun.hotspot.WhiteBox; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/Argument.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Argument.java index 4c8d18a922c..7435e04df9d 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/Argument.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/Argument.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; /** * Well-defined argument values that can be used in the {@link Arguments} annotation at a {@link Test} method for a diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/ArgumentValue.java b/test/hotspot/jtreg/compiler/lib/ir_framework/ArgumentValue.java index e0ccc1741dc..e6cf414d9cf 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/ArgumentValue.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/ArgumentValue.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import jdk.test.lib.Utils; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/Arguments.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Arguments.java index 64e73b83a7f..35a5a4aa894 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/Arguments.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/Arguments.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/BaseTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/BaseTest.java index 8d442ad7b54..cf2f0741a4b 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/BaseTest.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/BaseTest.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.reflect.Method; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/Check.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Check.java index fddff00a61b..e59244666e0 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/Check.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/Check.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/CheckAt.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CheckAt.java index 55ea9d95245..a007ebd7c00 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/CheckAt.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/CheckAt.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; /** * This enum is used in {@link Check#when()} of a checked test to specify when the framework will invoke the diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTest.java index b638f09f1ea..1643af51f18 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTest.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTest.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.reflect.Method; import java.lang.reflect.Modifier; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTestFrameworkException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTestFrameworkException.java index 4639f3589b7..bc16db00cce 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTestFrameworkException.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTestFrameworkException.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; /** * Checked internal exceptions in the framework to propagate error handling. diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java index 0ecf4e91172..a91809794e1 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import jdk.test.lib.Utils; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/Compiler.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Compiler.java index a0710e79935..bcbfe116925 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/Compiler.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/Compiler.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; /** * Compilers to select for {@link DontCompile}. HotSpot does not handle the exclusion of a C1 method at a specific level. diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/CustomRunTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CustomRunTest.java index 3391f3b9a23..e08f407b08b 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/CustomRunTest.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/CustomRunTest.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import sun.hotspot.WhiteBox; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/DeclaredTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/DeclaredTest.java index 27abe4793bf..9bd9532e393 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/DeclaredTest.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/DeclaredTest.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.reflect.Method; import java.util.Arrays; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/DontCompile.java b/test/hotspot/jtreg/compiler/lib/ir_framework/DontCompile.java index cae8706eca3..4e475d0e698 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/DontCompile.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/DontCompile.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/DontInline.java b/test/hotspot/jtreg/compiler/lib/ir_framework/DontInline.java index 80149b89a12..294829e4ca5 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/DontInline.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/DontInline.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/FlagVM.java b/test/hotspot/jtreg/compiler/lib/ir_framework/FlagVM.java index 9ad65eccbec..449d9dada92 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/FlagVM.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/FlagVM.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import jdk.test.lib.process.ProcessTools; import sun.hotspot.WhiteBox; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/FlagVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/FlagVMProcess.java index 689e0db6e58..4aea2640d3d 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/FlagVMProcess.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/FlagVMProcess.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import jdk.test.lib.Utils; import jdk.test.lib.process.OutputAnalyzer; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompile.java b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompile.java index aabac5229b8..065395dcc6d 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompile.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompile.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompileClassInitializer.java b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompileClassInitializer.java index 9951b14a722..cdc2039dbdb 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompileClassInitializer.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompileClassInitializer.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/ForceInline.java b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceInline.java index 703d02e72fb..6f262208fdc 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/ForceInline.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceInline.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IR.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IR.java index 9bdd62b6db5..5f2a642b86e 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IR.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IR.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IREncodingPrinter.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IREncodingPrinter.java index f2226086f6c..12db7b2512f 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IREncodingPrinter.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IREncodingPrinter.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import sun.hotspot.WhiteBox; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRMatcher.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRMatcher.java index 99a2682786d..a851856b27f 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRMatcher.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRMatcher.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.io.IOException; import java.lang.reflect.Method; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRMethod.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRMethod.java index 3d144961212..4d083847a5e 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRMethod.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRMethod.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.reflect.Method; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index 520591e3361..cd901210213 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.util.ArrayList; import java.util.List; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRViolationException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRViolationException.java index 014e7f27023..90071e2ed2a 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRViolationException.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRViolationException.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; /** * Exception that is thrown if an {@link IR} rule/constraint failed. The exception message contains a detailed list of diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRs.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRs.java index 5f1305310c6..b64d46710ed 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRs.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRs.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/NoTestsRunException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/NoTestsRunException.java index bf50eca4ede..2d4b5ebbb04 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/NoTestsRunException.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/NoTestsRunException.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; /** * Exception that is thrown by the test VM if no tests are run as a result of specifying {@code -DTest} and/or diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/ParsedComparator.java b/test/hotspot/jtreg/compiler/lib/ir_framework/ParsedComparator.java index 61777bf94df..9b00e6f3465 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/ParsedComparator.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/ParsedComparator.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.util.function.BiPredicate; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/README.md b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md index bc8dec705da..63f85edf55a 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/README.md +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md @@ -2,18 +2,18 @@ This folder contains a test framework whose main purpose is to perform regex-based checks on the C2 IR shape of test methods emitted by the VM flags _-XX:+PrintIdeal_ and _-XX:+PrintOptoAssembly_. The framework can also be used for other non-IR matching (and non-compiler) tests by providing easy to use annotations for commonly used testing patterns and compiler control flags. ## 1. How to Use the Framework -The framework is intended to be used in JTreg tests. The JTreg header of the test must contain `@library /test/lib` and should be run as a driver with `@run driver`. Annotate the test code with the supported framework annotations and call the framework from within the test's `main()` method. A simple example is shown below: +The framework is intended to be used in JTreg tests. The JTreg header of the test must contain `@library /test/lib /` (2 paths) and should be run as a driver with `@run driver`. Annotate the test code with the supported framework annotations and call the framework from within the test's `main()` method. A simple example is shown below: /* * @test * @summary A simple test using the test framework. - * @library /test/lib + * @library /test/lib / * @run driver my.package.MySimpleTest */ package my.package; - import jdk.test.lib.hotspot.ir_framework.*; + import compiler.lib.ir_framework.*; public class MySimpleTest { @@ -38,17 +38,17 @@ There are three kinds of tests depending on how much control is needed over the #### Base Tests The simplest form of testing provides a single `@Test` annotated method which the framework will invoke as part of the testing. The test method has no or well-defined arguments that the framework can automatically provide. -More information on base tests with a precise definition can be found in the Javadocs of [Test](./Test.java). Concrete examples on how to specify a base test can be found in [BaseTestsExample](./examples/BaseTestExample.java). +More information on base tests with a precise definition can be found in the Javadocs of [Test](./Test.java). Concrete examples on how to specify a base test can be found in [BaseTestsExample](../../../testlibrary_tests/compiler/lib/ir_framework/examples/BaseTestExample.java). #### Checked Tests The base tests do not provide any way of verification by user code. A checked test enables this by allowing the user to define an additional `@Check` annotated method which is invoked directly after the `@Test` annotated method. This allows the user to perform various checks about the test method including return value verification. -More information on checked tests with a precise definition can be found in the Javadocs of [Check](./Check.java). Concrete examples on how to specify a checked test can be found in [CheckedTestsExample](./examples/CheckedTestExample.java). +More information on checked tests with a precise definition can be found in the Javadocs of [Check](./Check.java). Concrete examples on how to specify a checked test can be found in [CheckedTestsExample](../../../testlibrary_tests/compiler/lib/ir_framework/examples/CheckedTestExample.java). #### Custom Run Tests Neither the base nor the checked tests provide any control over how a `@Test` annotated method is invoked in terms of customized argument values and/or conditions for the invocation itself. A custom run test gives full control over the invocation of the `@Test` annotated method to the user. The framework calls a dedicated `@Run` annotated method from which the user can invoke the `@Test` method according to his/her needs. -More information on checked tests with a precise definition can be found in the Javadocs of [Run](./Run.java). Concrete examples on how to specify a custom run test can be found in [CustomRunTestsExample](./examples/CustomRunTestExample.java). +More information on checked tests with a precise definition can be found in the Javadocs of [Run](./Run.java). Concrete examples on how to specify a custom run test can be found in [CustomRunTestsExample](../../../testlibrary_tests/compiler/lib/ir_framework/examples/CustomRunTestExample.java). ### 2.2 IR Verification The main feature of this framework is to perform a simple but yet powerful regex-based C2 IR matching on the output of _-XX:+PrintIdeal_ and _-XX:+PrintOptoAssembly_. For simplicity, we will refer to the "IR" or "IR matching" when actually meaning the combined output of _-XX:+PrintIdeal_ and _-XX:+PrintOptoAssembly_ for a C2 compilation. @@ -66,7 +66,7 @@ In general, the framework will only perform IR verification if the used VM flags An `@IR` annotation allows additional preconditions/restrictions on the currently present VM flags to enable or disable rules when certain flags are present or have a specific value (see `applyIfXX` properties of an `@IR` annotation). -More information about IR matching can be found in the Javadocs of [IR](./IR.java). Concrete examples on how to specify IR constraint/rules can be found in [IRExample](./examples/IRExample.java) and [TestIRMatching](./tests/TestIRMatching.java) (an internal framework test). +More information about IR matching can be found in the Javadocs of [IR](./IR.java). Concrete examples on how to specify IR constraint/rules can be found in [IRExample](../../../testlibrary_tests/compiler/lib/ir_framework/examples/IRExample.java) and [TestIRMatching](../../../testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java) (an internal framework test). ### 2.3 Test VM Flags and Scenarios The recommended way to use the framework is by defining a single `@run driver` statement in the JTreg header which, however, does not allow the specification of additional test VM flags. Instead, the user has the possibility to provide VM flags by calling `TestFramework.runWithFlags()` or by creating a `TestFramework` builder object on which `addFlags()` can be called. diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/Run.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Run.java index 08519afdc3b..47a1268aa4e 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/Run.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/Run.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/RunInfo.java b/test/hotspot/jtreg/compiler/lib/ir_framework/RunInfo.java index 469b3177d45..0ed8d8571b8 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/RunInfo.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/RunInfo.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.reflect.Method; import java.util.HashMap; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/RunMode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/RunMode.java index ad892fc30a0..f6402dfe6ac 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/RunMode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/RunMode.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; /** * The run mode for a custom run test specified in {@link Run#mode}. diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/Scenario.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Scenario.java index 6ce6f5b2bf7..7d1f48f20a6 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/Scenario.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/Scenario.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.util.*; import java.util.stream.Collectors; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/Test.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Test.java index 0ec0552c9c7..b15a0f273b7 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/Test.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/Test.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFormat.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFormat.java index 29ceff7fd9e..e1c604d6331 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFormat.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFormat.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.util.ArrayList; import java.util.List; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFormatException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFormatException.java index 684b36d384a..b8327c1a635 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFormatException.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFormatException.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; /** * Exception that is thrown if a JTreg test violates the supported format by the test framework. diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java index 9774f2e9c15..07cc608e438 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import jdk.test.lib.Platform; import jdk.test.lib.Utils; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkException.java index b8571c35ebb..0a7472d4a8b 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkException.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkException.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; /** * Exception that is thrown if there is an internal error in the framework. This is most likely an indicator of a bug diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkSocket.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkSocket.java index 825727c1c2d..d379420a560 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkSocket.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkSocket.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.io.BufferedReader; import java.io.IOException; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestInfo.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestInfo.java index c7d8e2d22bc..0d9f229e406 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestInfo.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestInfo.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.reflect.Method; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestRun.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestRun.java index 6ff9bb134f2..73528fdc37e 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestRun.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestRun.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; /** * Utility class to report a {@link TestRunException}. diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestRunException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestRunException.java index 812e85c0027..92b30cdc595 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestRunException.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestRunException.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; /** * Exception that is thrown if the JTreg test throws an exception during the execution of individual tests of the diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestVM.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestVM.java index 56b8575d54a..3d269581ded 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestVM.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestVM.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import jdk.test.lib.Platform; import jdk.test.lib.Utils; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestVMException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestVMException.java index 20fa668320a..dee71dc8c87 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestVMException.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestVMException.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; /** * Exception that is thrown if the test VM has thrown any kind of exception (except for {@link TestFormatException}). diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestVMProcess.java index 045e77392f5..4af1670a037 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestVMProcess.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestVMProcess.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import jdk.test.lib.Platform; import jdk.test.lib.Utils; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/Warmup.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Warmup.java index 5e6962b1273..af17acb0719 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/Warmup.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/Warmup.java @@ -21,7 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework; +package compiler.lib.ir_framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/examples/TEST.ROOT b/test/hotspot/jtreg/compiler/lib/ir_framework/examples/TEST.ROOT deleted file mode 100644 index ce89576ef26..00000000000 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/examples/TEST.ROOT +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright (c) 2021, 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. -# - -# Minimal TEST.ROOT file to run the examples tests as if the examples would have been placed inside -# /test/hotspot/jtreg -external.lib.roots = ../../../../../../../.. diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TEST.ROOT b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TEST.ROOT deleted file mode 100644 index 862dc229d2a..00000000000 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TEST.ROOT +++ /dev/null @@ -1,35 +0,0 @@ -# -# Copyright (c) 2021, 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. -# - -# Minimal TEST.ROOT file to run the internal framework tests as if they would have been placed inside -# /test/hotspot/jtreg -external.lib.roots = ../../../../../../../.. -requires.extraPropDefns = ../../../../../../../jtreg-ext/requires/VMProps.java -requires.extraPropDefns.bootlibs = ../../../../../../../lib/sun -requires.extraPropDefns.libs = \ - ../../../../../../../lib/jdk/test/lib/Platform.java \ - ../../../../../../../lib/jdk/test/lib/Container.java -requires.extraPropDefns.vmOpts = -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -requires.properties= \ - vm.debug \ - vm.compiler2.enabled \ diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestAccessModifiers.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestAccessModifiers.java index d60745daa67..f31e13653b1 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestAccessModifiers.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestAccessModifiers.java @@ -21,15 +21,14 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.tests; - -import jdk.test.lib.hotspot.ir_framework.*; +package compiler.lib.ir_framework; /* * @test + * @requires vm.flagless * @summary Test different access modifiers an make sure, the framework can access all methods. - * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestAccessModifiers + * @library /test/lib / + * @run driver compiler.lib.ir_framework.TestAccessModifiers */ public class TestAccessModifiers { diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java index 1aa4dfdca10..d4c8b93061f 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java @@ -21,11 +21,9 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.tests; +package compiler.lib.ir_framework; -import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.Compiler; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -38,10 +36,10 @@ /* * @test - * @requires vm.compiler2.enabled + * @requires vm.compiler2.enabled & vm.flagless * @summary Test test format violations. - * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestBadFormat + * @library /test/lib / + * @run driver compiler.lib.ir_framework.TestBadFormat */ public class TestBadFormat { diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBasics.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBasics.java index 40e216b1a1f..29a6b7f6a12 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBasics.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBasics.java @@ -21,9 +21,7 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.tests; - -import jdk.test.lib.hotspot.ir_framework.*; +package compiler.lib.ir_framework; import java.lang.reflect.Method; import java.util.Arrays; @@ -31,13 +29,13 @@ /* * @test - * @requires vm.compiler2.enabled + * @requires vm.compiler2.enabled & vm.flagless * @summary Test basics of the framework. This test runs directly the test VM which normally does not happen. - * @library /test/lib + * @library /test/lib / * @build sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI - * jdk.test.lib.hotspot.ir_framework.tests.TestBasics + * compiler.lib.ir_framework.TestBasics */ public class TestBasics { diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java index b935a6cc96c..7a531960a1d 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java @@ -21,21 +21,20 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.tests; - -import jdk.test.lib.hotspot.ir_framework.*; +package compiler.lib.ir_framework; import java.lang.reflect.Method; /* * @test + * @requires vm.flagless * @summary Test if compilation levels are used correctly in the framework. * This test runs directly the test VM which normally does not happen. - * @library /test/lib + * @library /test/lib / * @build sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI - * jdk.test.lib.hotspot.ir_framework.tests.TestCompLevels + * compiler.lib.ir_framework.TestCompLevels */ public class TestCompLevels { diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java index e3dfa26541d..3161dcd7904 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java @@ -21,11 +21,9 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.tests; +package compiler.lib.ir_framework; -import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.Compiler; import sun.hotspot.WhiteBox; import java.lang.reflect.Method; @@ -34,14 +32,14 @@ /* * @test - * @requires vm.debug == true & vm.compMode != "Xint" & vm.compiler2.enabled + * @requires vm.debug == true & vm.compMode != "Xint" & vm.compiler2.enabled & vm.flagless * @summary Test if compilation control annotaions are handled correctly in the framework. * This test runs directly the test VM which normally does not happen. - * @library /test/lib + * @library /test/lib / * @build sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI - * jdk.test.lib.hotspot.ir_framework.tests.TestControls + * compiler.lib.ir_framework.TestControls */ public class TestControls { diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDFlags.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDFlags.java index 46ea62cb38d..3ec0da5c372 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDFlags.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDFlags.java @@ -21,27 +21,24 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.tests; - -import jdk.test.lib.hotspot.ir_framework.Test; -import jdk.test.lib.hotspot.ir_framework.TestFramework; +package compiler.lib.ir_framework; /* * @test - * @requires vm.debug == true & vm.compMode != "Xint" & vm.compiler2.enabled + * @requires vm.debug == true & vm.compMode != "Xint" & vm.compiler2.enabled & vm.flagless * @summary Sanity test remaining framework property flags. - * @library /test/lib - * @run main/othervm -DFlipC1C2=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags - * @run main/othervm -DExcludeRandom=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags - * @run main/othervm -DVerifyVM=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags - * @run main/othervm -DDumpReplay=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags - * @run main/othervm -DVerbose=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags - * @run main/othervm -DShuffleTests=false jdk.test.lib.hotspot.ir_framework.tests.TestDFlags - * @run main/othervm -DReproduce=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags - * @run main/othervm -DReportStdout=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags - * @run main/othervm -DGCAfter=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags - * @run main/othervm -DPrintTimes=true jdk.test.lib.hotspot.ir_framework.tests.TestDFlags - * @run main/othervm -DVerifyIR=false jdk.test.lib.hotspot.ir_framework.tests.TestDFlags + * @library /test/lib / + * @run main/othervm -DFlipC1C2=true compiler.lib.ir_framework.TestDFlags + * @run main/othervm -DExcludeRandom=true compiler.lib.ir_framework.TestDFlags + * @run main/othervm -DVerifyVM=true compiler.lib.ir_framework.TestDFlags + * @run main/othervm -DDumpReplay=true compiler.lib.ir_framework.TestDFlags + * @run main/othervm -DVerbose=true compiler.lib.ir_framework.TestDFlags + * @run main/othervm -DShuffleTests=false compiler.lib.ir_framework.TestDFlags + * @run main/othervm -DReproduce=true compiler.lib.ir_framework.TestDFlags + * @run main/othervm -DReportStdout=true compiler.lib.ir_framework.TestDFlags + * @run main/othervm -DGCAfter=true compiler.lib.ir_framework.TestDFlags + * @run main/othervm -DPrintTimes=true compiler.lib.ir_framework.TestDFlags + * @run main/othervm -DVerifyIR=false compiler.lib.ir_framework.TestDFlags */ public class TestDFlags { diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDIgnoreCompilerControls.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDIgnoreCompilerControls.java index d909fbfc36c..e33e5552525 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDIgnoreCompilerControls.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDIgnoreCompilerControls.java @@ -21,21 +21,20 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.tests; +package compiler.lib.ir_framework; -import jdk.test.lib.Utils; -import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; +import jdk.test.lib.Utils; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import sun.hotspot.WhiteBox; /* * @test - * @requires vm.debug == true + * @requires vm.debug == true & vm.flagless * @summary Test -DIgnoreCompilerControls property flag. - * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestDIgnoreCompilerControls + * @library /test/lib / + * @run driver compiler.lib.ir_framework.TestDIgnoreCompilerControls */ public class TestDIgnoreCompilerControls { @@ -57,7 +56,7 @@ private static OutputAnalyzer run(String flagValue) throws Exception { ProcessBuilder process = ProcessTools.createJavaProcessBuilder( "-Dtest.class.path=" + Utils.TEST_CLASS_PATH, "-Dtest.jdk=" + Utils.TEST_JDK, "-Dtest.vm.opts=-DIgnoreCompilerControls=" + flagValue, - "jdk.test.lib.hotspot.ir_framework.tests.TestDIgnoreCompilerControls", flagValue); + "compiler.lib.ir_framework.TestDIgnoreCompilerControls", flagValue); oa = ProcessTools.executeProcess(process); return oa; } diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDScenarios.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDScenarios.java index f19d1caff85..fce1ec1b8ef 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDScenarios.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDScenarios.java @@ -21,24 +21,23 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.tests; +package compiler.lib.ir_framework; import jdk.test.lib.Utils; -import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; /* * @test - * @requires vm.debug == true + * @requires vm.debug == true & vm.flagless * @summary Test -DScenarios property flag. Run with othervm which should not be done when writing tests using the framework. - * @library /test/lib - * @run main/othervm -DScenarios=1,5,10 jdk.test.lib.hotspot.ir_framework.tests.TestDScenarios test - * @run main/othervm -DScenarios=1,4 jdk.test.lib.hotspot.ir_framework.tests.TestDScenarios test - * @run main/othervm -DScenarios=3,4,9 jdk.test.lib.hotspot.ir_framework.tests.TestDScenarios test - * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestDScenarios test2 - * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestDScenarios + * @library /test/lib / + * @run main/othervm -DScenarios=1,5,10 compiler.lib.ir_framework.TestDScenarios test + * @run main/othervm -DScenarios=1,4 compiler.lib.ir_framework.TestDScenarios test + * @run main/othervm -DScenarios=3,4,9 compiler.lib.ir_framework.TestDScenarios test + * @run driver compiler.lib.ir_framework.TestDScenarios test2 + * @run driver compiler.lib.ir_framework.TestDScenarios */ public class TestDScenarios { @@ -72,7 +71,7 @@ public static void main(String[] args) throws Exception { OutputAnalyzer oa; ProcessBuilder process = ProcessTools.createJavaProcessBuilder( "-Dtest.jdk=" + Utils.TEST_JDK, "-DScenarios=a,1,b,10", - "jdk.test.lib.hotspot.ir_framework.tests.TestDScenarios", " test3"); + "compiler.lib.ir_framework.TestDScenarios", " test3"); oa = ProcessTools.executeProcess(process); oa.shouldNotHaveExitValue(0); System.out.println(oa.getOutput()); diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDTestAndExclude.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDTestAndExclude.java index 5551bddb67e..1fc16bac956 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDTestAndExclude.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDTestAndExclude.java @@ -21,19 +21,19 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.tests; +package compiler.lib.ir_framework; import jdk.test.lib.Utils; -import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; /* * @test + * @requires vm.flagless * @summary Test -DTest and -DExclude property flag. - * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestDTestAndExclude + * @library /test/lib / + * @run driver compiler.lib.ir_framework.TestDTestAndExclude */ public class TestDTestAndExclude { @@ -94,7 +94,7 @@ protected static void run(String dTest, String dExclude, String arg) throws Exce ProcessBuilder process = ProcessTools.createJavaProcessBuilder( "-Dtest.class.path=" + Utils.TEST_CLASS_PATH, "-Dtest.jdk=" + Utils.TEST_JDK, "-Dtest.vm.opts=-DTest=" + dTest + " -DExclude=" + dExclude, - "jdk.test.lib.hotspot.ir_framework.tests.TestDTestAndExclude", arg); + "compiler.lib.ir_framework.TestDTestAndExclude", arg); oa = ProcessTools.executeProcess(process); oa.shouldHaveExitValue(0); } diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java index 174c006d0cd..a3a7857da3e 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java @@ -21,9 +21,8 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.tests; +package compiler.lib.ir_framework; -import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; import java.io.ByteArrayOutputStream; @@ -36,11 +35,11 @@ /* * @test - * @requires vm.debug == true & vm.compMode != "Xint" & vm.compiler2.enabled + * @requires vm.debug == true & vm.compMode != "Xint" & vm.compiler2.enabled & vm.flagless * @summary Test IR matcher with different default IR node regexes. Use -DPrintIREncoding. * Normally, the framework should be called with driver. - * @library /test/lib - * @run main/othervm -DPrintIREncoding=true jdk.test.lib.hotspot.ir_framework.tests.TestIRMatching + * @library /test/lib / + * @run main/othervm -DPrintIREncoding=true compiler.lib.ir_framework.TestIRMatching */ public class TestIRMatching { @@ -185,7 +184,7 @@ public static void main(String[] args) { runCheck(BadFailOnConstraint.create(Membar.class, "membar()", 1, "MemBar")); runCheck(BadFailOnConstraint.create(CheckCastArray.class, "array()", 1, "cmp", "precise klass"), BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 1,"cmp", "precise klass", "MyClass"), - BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 2,"cmp", "precise klass", "tests/MyClass"), + BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 2,"cmp", "precise klass", "ir_framework/MyClass"), GoodFailOnConstraint.create(CheckCastArray.class, "array()", 3), BadFailOnConstraint.create(CheckCastArray.class, "arrayCopy(java.lang.Object[],java.lang.Class)", 1, "checkcast_arraycopy") ); @@ -413,7 +412,7 @@ public void fail3() { } @Test - @IR(failOn = {IRNode.STORE_OF_CLASS, "jdk/test/lib/hotspot/ir_framework/tests/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "compiler/lib/ir_framework/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) public void fail4() { iFld = 42; } @@ -437,7 +436,7 @@ public void fail7() { } @Test - @IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "jdk/test/lib/hotspot/ir_framework/tests/MyClassSub"}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "compiler/lib/ir_framework/MyClassSub"}) public void fail8() { myClass = new MyClassSub(); } @@ -635,10 +634,10 @@ public void good4() { @Test @IR(counts = {IRNode.STORE, "2", IRNode.STORE_I, "1", IRNode.STORE_L, "1", IRNode.STORE_OF_CLASS, "GoodCount", "1", IRNode.STORE_L_OF_CLASS, "GoodCount", "1", - IRNode.STORE_OF_CLASS, "jdk/test/lib/hotspot/ir_framework/tests/MyClass", "1", - IRNode.STORE_I_OF_CLASS, "jdk/test/lib/hotspot/ir_framework/tests/MyClass", "1", - IRNode.STORE_OF_CLASS, "jdk/test/lib/hotspot/ir_framework/tests/GoodCount", "1", - IRNode.STORE_L_OF_CLASS, "jdk/test/lib/hotspot/ir_framework/tests/GoodCount", "1", + IRNode.STORE_OF_CLASS, "compiler/lib/ir_framework/MyClass", "1", + IRNode.STORE_I_OF_CLASS, "compiler/lib/ir_framework/MyClass", "1", + IRNode.STORE_OF_CLASS, "compiler/lib/ir_framework/GoodCount", "1", + IRNode.STORE_L_OF_CLASS, "compiler/lib/ir_framework/GoodCount", "1", IRNode.STORE_OF_FIELD, "x", "2"}) public void good5() { x = 3; // long @@ -803,8 +802,8 @@ class AllocArray { @IR(failOn = {IRNode.ALLOC_ARRAY}) @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClass"}) @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClasss"}) // Does not fail - @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "jdk/test/lib/hotspot/ir_framework/tests/MySubClass"}) // Does not fail - @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "jdk/test/lib/hotspot/ir_framework/tests/MyClass"}) + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/lib/ir_framework/MySubClass"}) // Does not fail + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/lib/ir_framework/MyClass"}) public void allocArray() { myClassArray = new MyClass[2]; } @@ -820,7 +819,7 @@ class Loads { @IR(failOn = {IRNode.LOOP, IRNode.LOOP}, counts = {IRNode.LOOP, "0", IRNode.LOAD, "1"}) // Does not fail @IR(failOn = {IRNode.LOOP, IRNode.LOOP}, counts = {IRNode.LOOP, "0", IRNode.STORE, "1"}) @IR(failOn = {IRNode.LOOP, IRNode.STORE}, counts = {IRNode.LOOP, "0", IRNode.LOAD, "1"}) - @IR(failOn = {IRNode.LOAD_OF_CLASS, "jdk/test/lib/hotspot/ir_framework/tests/Loads"}) + @IR(failOn = {IRNode.LOAD_OF_CLASS, "compiler/lib/ir_framework/Loads"}) @IR(failOn = {IRNode.LOAD_OF_CLASS, "Loads"}) @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld"}) @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld2", IRNode.LOAD_OF_CLASS, "Load"}) // Does not fail @@ -1105,7 +1104,7 @@ class CheckCastArray { @Test @IR(failOn = IRNode.CHECKCAST_ARRAY) // fails @IR(failOn = {IRNode.CHECKCAST_ARRAY_OF, "MyClass", // fails - IRNode.CHECKCAST_ARRAY_OF, "tests/MyClass"}) // fails + IRNode.CHECKCAST_ARRAY_OF, "ir_framework/MyClass"}) // fails @IR(failOn = {IRNode.CHECKCAST_ARRAY_OF, "MyClasss", IRNode.CHECKCAST_ARRAY_OF, "Object"}) public boolean array() { return oArr instanceof MyClass[]; diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestRunTests.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestRunTests.java index 81dae555eac..947dd88286e 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestRunTests.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestRunTests.java @@ -21,19 +21,18 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.tests; +package compiler.lib.ir_framework; import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; import java.util.Arrays; /* * @test - * @requires vm.compMode != "Xint" & vm.compiler2.enabled + * @requires vm.compMode != "Xint" & vm.compiler2.enabled & vm.flagless * @summary Test different custom run tests. - * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestRunTests + * @library /test/lib / + * @run driver compiler.lib.ir_framework.TestRunTests */ public class TestRunTests { diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestSanity.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestSanity.java index b8bf9aa17df..4cf6923ed56 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestSanity.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestSanity.java @@ -21,17 +21,14 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.tests; - -import jdk.test.lib.hotspot.ir_framework.Scenario; -import jdk.test.lib.hotspot.ir_framework.Test; -import jdk.test.lib.hotspot.ir_framework.TestFramework; +package compiler.lib.ir_framework; /* * @test + * @requires vm.flagless * @summary Sanity test the different ways to start the test framework. - * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestSanity + * @library /test/lib / + * @run driver compiler.lib.ir_framework.TestSanity */ public class TestSanity { diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java index 7a097ca0181..e833337c14a 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java @@ -21,17 +21,16 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.tests; +package compiler.lib.ir_framework; -import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; /* * @test - * @requires vm.compMode != "Xint" & vm.compiler2.enabled + * @requires vm.compMode != "Xint" & vm.compiler2.enabled & vm.flagless * @summary Test scenarios with the framework. - * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestScenarios + * @library /test/lib / + * @run driver compiler.lib.ir_framework.TestScenarios */ public class TestScenarios { @@ -64,9 +63,9 @@ public static void main(String[] args) { new TestFramework(MyExceptionTest.class).addScenarios(s1, s2, s3).start(); Asserts.fail("Should not reach"); } catch (TestRunException e) { - Asserts.assertTrue(s1.getTestVMOutput().contains("Caused by: jdk.test.lib.hotspot.ir_framework.tests.MyScenarioException")); - Asserts.assertTrue(s2.getTestVMOutput().contains("Caused by: jdk.test.lib.hotspot.ir_framework.tests.MyScenarioException")); - Asserts.assertTrue(s3.getTestVMOutput().contains("Caused by: jdk.test.lib.hotspot.ir_framework.tests.MyScenarioException")); + Asserts.assertTrue(s1.getTestVMOutput().contains("Caused by: compiler.lib.ir_framework.MyScenarioException")); + Asserts.assertTrue(s2.getTestVMOutput().contains("Caused by: compiler.lib.ir_framework.MyScenarioException")); + Asserts.assertTrue(s3.getTestVMOutput().contains("Caused by: compiler.lib.ir_framework.MyScenarioException")); } catch (Exception e) { Asserts.fail("Should not catch other exceptions"); } diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestWithHelperClasses.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestWithHelperClasses.java index c1065607545..8a30228f7e5 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestWithHelperClasses.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestWithHelperClasses.java @@ -21,16 +21,16 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.tests; +package compiler.lib.ir_framework; -import jdk.test.lib.hotspot.ir_framework.*; import jdk.test.lib.Asserts; /* * @test + * @requires vm.flagless * @summary Test the framework with helper classes. - * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.tests.TestWithHelperClasses + * @library /test/lib / + * @run driver compiler.lib.ir_framework.TestWithHelperClasses */ public class TestWithHelperClasses { @@ -41,10 +41,10 @@ public static void main(String[] args) { new TestFramework().addHelperClasses(Helper1.class).start(); shouldNotReach(); } catch (TestVMException e) { - Asserts.assertFalse(e.getExceptionInfo().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper1.foo() should have been C2 compiled")); - Asserts.assertFalse(TestFramework.getLastTestVMOutput().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper1.foo() should have been C2 compiled")); - Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper2.foo() should have been C2 compiled")); - Asserts.assertTrue(e.getExceptionInfo().contains("public static void jdk.test.lib.hotspot.ir_framework.tests.Helper2.foo() should have been C2 compiled")); + Asserts.assertFalse(e.getExceptionInfo().contains("public static void compiler.lib.ir_framework.Helper1.foo() should have been C2 compiled")); + Asserts.assertFalse(TestFramework.getLastTestVMOutput().contains("public static void compiler.lib.ir_framework.Helper1.foo() should have been C2 compiled")); + Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("public static void compiler.lib.ir_framework.Helper2.foo() should have been C2 compiled")); + Asserts.assertTrue(e.getExceptionInfo().contains("public static void compiler.lib.ir_framework.Helper2.foo() should have been C2 compiled")); Asserts.assertFalse(TestFramework.getLastTestVMOutput().contains("Should not be executed")); Asserts.assertFalse(e.getExceptionInfo().contains("Should not be executed")); } @@ -67,8 +67,8 @@ public static void main(String[] args) { new TestFramework(TestAsHelper.class).addHelperClasses(TestAsHelper.class).start(); shouldNotReach(); } catch (TestFormatException e) { - Asserts.assertTrue(e.getMessage().contains("Cannot specify test class jdk.test.lib.hotspot.ir_framework." + - "tests.TestAsHelper as helper class, too")); + Asserts.assertTrue(e.getMessage().contains("Cannot specify test class compiler.lib.ir_framework." + + "TestAsHelper as helper class, too")); } try { diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/examples/BaseTestExample.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/BaseTestExample.java similarity index 94% rename from test/hotspot/jtreg/compiler/lib/ir_framework/examples/BaseTestExample.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/BaseTestExample.java index 6810b1d9da2..99aabecb36a 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/examples/BaseTestExample.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/BaseTestExample.java @@ -21,15 +21,14 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.examples; - -import jdk.test.lib.hotspot.ir_framework.*; +package compiler.lib.ir_framework.examples; +import compiler.lib.ir_framework.*; /* * @test * @summary Example test to use the new test framework. - * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.examples.BaseTestExample + * @library /test/lib / + * @run driver compiler.lib.ir_framework.examples.BaseTestExample */ /** diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/examples/CheckedTestExample.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CheckedTestExample.java similarity index 96% rename from test/hotspot/jtreg/compiler/lib/ir_framework/examples/CheckedTestExample.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CheckedTestExample.java index ed904642515..7eb82ded03d 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/examples/CheckedTestExample.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CheckedTestExample.java @@ -21,15 +21,15 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.examples; +package compiler.lib.ir_framework.examples; -import jdk.test.lib.hotspot.ir_framework.*; +import compiler.lib.ir_framework.*; /* * @test * @summary Example test to use the new test framework. - * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.examples.CheckedTestExample + * @library /test/lib / + * @run driver compiler.lib.ir_framework.examples.CheckedTestExample */ /** diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/examples/CustomRunTestExample.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CustomRunTestExample.java similarity index 96% rename from test/hotspot/jtreg/compiler/lib/ir_framework/examples/CustomRunTestExample.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CustomRunTestExample.java index af5ce9fb7a9..7c8fa50997c 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/examples/CustomRunTestExample.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CustomRunTestExample.java @@ -21,15 +21,15 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.examples; +package compiler.lib.ir_framework.examples; -import jdk.test.lib.hotspot.ir_framework.*; +import compiler.lib.ir_framework.*; /* * @test * @summary Example test to use the new test framework. - * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.examples.CustomRunTestExample + * @library /test/lib / + * @run driver compiler.lib.ir_framework.examples.CustomRunTestExample */ /** diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/examples/IRExample.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/IRExample.java similarity index 95% rename from test/hotspot/jtreg/compiler/lib/ir_framework/examples/IRExample.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/IRExample.java index 64e4e57728b..41f5ab048f7 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/examples/IRExample.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/IRExample.java @@ -21,18 +21,17 @@ * questions. */ -package jdk.test.lib.hotspot.ir_framework.examples; +package compiler.lib.ir_framework.examples; -import jdk.test.lib.hotspot.ir_framework.*; +import compiler.lib.ir_framework.*; /* * @test * @summary Example test to use the new test framework. - * @library /test/lib - * @run driver jdk.test.lib.hotspot.ir_framework.examples.IRExample + * @library /test/lib / + * @run driver compiler.lib.ir_framework.examples.IRExample */ - /** * Multiple @IR rules can be specified at @Test methods. The framework performs a regex based match on the PrintIdeal * and PrintOptoAssembly of the run test VM. Some default string regexes for IR nodes are defined in the framework @@ -73,14 +72,14 @@ // This test is expected to fail when run with JTreg. public class IRExample { int iFld, iFld2, iFld3; - public static void main(String[] args) { TestFramework.run(); // First run tests from IRExample try { TestFramework.run(FailingExamples.class); // Secondly, run tests from FailingExamples } catch (IRViolationException e) { - // Expected. Check output to see how IR failures are reported. - throw e; + // Expected. Check stderr/stdout to see how IR failures are reported (always printed, regardless if + // exception is thrown or not). Uncomment the "throw" statement below to get a completely failing test. + //throw e; } } From 4dd14695566223440f4555f73df80de866729415 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 1 Jun 2021 16:23:45 +0200 Subject: [PATCH 122/131] Update ClassFileInstaller import --- test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java index 07cc608e438..6adfddd30c1 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java @@ -25,7 +25,7 @@ import jdk.test.lib.Platform; import jdk.test.lib.Utils; -import jdk.test.lib.util.ClassFileInstaller; +import jdk.test.lib.helpers.ClassFileInstaller; import sun.hotspot.WhiteBox; import java.io.PrintWriter; From 9c3bcc460234426f094906a7247ae04a1dc93586 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Tue, 4 May 2021 17:14:15 +0200 Subject: [PATCH 123/131] Splitting classes into subpackages and updating README accordingly, fix bug with new line matching in lookbehind on Windows --- .../lib/ir_framework/AbstractInfo.java | 6 ++- .../compiler/lib/ir_framework/Check.java | 2 + .../compiler/lib/ir_framework/CompLevel.java | 17 ++++++--- .../lib/ir_framework/DontCompile.java | 2 + .../compiler/lib/ir_framework/DontInline.java | 2 + .../lib/ir_framework/ForceCompile.java | 2 + .../ForceCompileClassInitializer.java | 2 + .../lib/ir_framework/ForceInline.java | 2 + .../jtreg/compiler/lib/ir_framework/IR.java | 2 + .../compiler/lib/ir_framework/IRNode.java | 9 ++++- .../jtreg/compiler/lib/ir_framework/README.md | 16 ++++++-- .../jtreg/compiler/lib/ir_framework/Run.java | 2 + .../compiler/lib/ir_framework/RunInfo.java | 6 ++- .../compiler/lib/ir_framework/Scenario.java | 2 + .../lib/ir_framework/TestFramework.java | 29 ++++++++------- .../compiler/lib/ir_framework/TestInfo.java | 11 ++++-- .../{ => driver}/FlagVMProcess.java | 10 +++-- .../ir_framework/{ => driver}/IRMatcher.java | 16 +++++--- .../ir_framework/{ => driver}/IRMethod.java | 4 +- .../{ => driver}/IRViolationException.java | 9 +++-- .../{ => driver}/TestVMException.java | 4 +- .../{ => driver}/TestVMProcess.java | 14 +++++-- .../lib/ir_framework/{ => flag}/FlagVM.java | 18 +++++---- .../CheckedTestFrameworkException.java | 6 +-- .../{ => shared}/NoTestsRunException.java | 6 +-- .../{ => shared}/ParsedComparator.java | 4 +- .../ir_framework/{ => shared}/TestFormat.java | 4 +- .../{ => shared}/TestFormatException.java | 4 +- .../{ => shared}/TestFrameworkException.java | 6 +-- .../{ => shared}/TestFrameworkSocket.java | 12 +++--- .../ir_framework/{ => shared}/TestRun.java | 4 +- .../{ => shared}/TestRunException.java | 6 +-- .../ir_framework/{ => test}/AbstractTest.java | 5 ++- .../{ => test}/ArgumentValue.java | 7 +++- .../lib/ir_framework/{ => test}/BaseTest.java | 7 +++- .../ir_framework/{ => test}/CheckedTest.java | 6 ++- .../{ => test}/CustomRunTest.java | 6 ++- .../ir_framework/{ => test}/DeclaredTest.java | 7 +++- .../{ => test}/IREncodingPrinter.java | 6 ++- .../lib/ir_framework/{ => test}/TestVM.java | 37 ++++++++++--------- .../lib/ir_framework/TestBadFormat.java | 1 + .../compiler/lib/ir_framework/TestBasics.java | 2 + .../lib/ir_framework/TestCompLevels.java | 2 + .../lib/ir_framework/TestControls.java | 1 + .../lib/ir_framework/TestDScenarios.java | 1 + .../lib/ir_framework/TestDTestAndExclude.java | 2 + .../lib/ir_framework/TestIRMatching.java | 1 + .../lib/ir_framework/TestRunTests.java | 2 + .../lib/ir_framework/TestScenarios.java | 1 + .../ir_framework/TestWithHelperClasses.java | 2 + .../examples/BaseTestExample.java | 1 + .../examples/CheckedTestExample.java | 1 + .../examples/CustomRunTestExample.java | 1 + .../lib/ir_framework/examples/IRExample.java | 1 + 54 files changed, 231 insertions(+), 108 deletions(-) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => driver}/FlagVMProcess.java (93%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => driver}/IRMatcher.java (98%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => driver}/IRMethod.java (97%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => driver}/IRViolationException.java (91%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => driver}/TestVMException.java (94%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => driver}/TestVMProcess.java (94%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => flag}/FlagVM.java (91%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => shared}/CheckedTestFrameworkException.java (87%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => shared}/NoTestsRunException.java (92%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => shared}/ParsedComparator.java (97%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => shared}/TestFormat.java (97%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => shared}/TestFormatException.java (93%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => shared}/TestFrameworkException.java (90%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => shared}/TestFrameworkSocket.java (95%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => shared}/TestRun.java (95%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => shared}/TestRunException.java (89%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => test}/AbstractTest.java (97%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => test}/ArgumentValue.java (97%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => test}/BaseTest.java (93%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => test}/CheckedTest.java (95%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => test}/CustomRunTest.java (96%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => test}/DeclaredTest.java (96%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => test}/IREncodingPrinter.java (98%) rename test/hotspot/jtreg/compiler/lib/ir_framework/{ => test}/TestVM.java (97%) diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractInfo.java b/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractInfo.java index 77074ae525d..cbaa5361589 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractInfo.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractInfo.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.shared.TestRunException; +import compiler.lib.ir_framework.test.TestVM; import jdk.test.lib.Utils; import java.lang.reflect.Method; @@ -111,9 +113,9 @@ public boolean isC2CompilationEnabled() { } /** - * Called by framework when the warm-up is finished. Not exposed to users. + * Called by {@link TestFramework} when the warm-up is finished. Should not be called by user code. */ - void setWarmUpFinished() { + public void setWarmUpFinished() { onWarmUp = false; } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/Check.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Check.java index e59244666e0..ca7f4a43da2 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/Check.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/Check.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.shared.TestFormatException; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java index a91809794e1..4c3384ce966 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java @@ -23,6 +23,10 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.shared.TestFrameworkException; +import compiler.lib.ir_framework.shared.TestRun; +import compiler.lib.ir_framework.shared.TestRunException; +import compiler.lib.ir_framework.test.TestVM; import jdk.test.lib.Utils; import java.lang.reflect.Executable; @@ -119,9 +123,9 @@ public static CompLevel forValue(int value) { } /** - * Checks if this compilation level is not part of the compiler. + * Called by {@link TestFramework} to check if this compilation level is not part of the compiler. */ - boolean isNotCompilationLevelOfCompiler(Compiler c) { + public boolean isNotCompilationLevelOfCompiler(Compiler c) { return switch (c) { case C1 -> !isC1(); case C2 -> this != C2; @@ -130,9 +134,9 @@ boolean isNotCompilationLevelOfCompiler(Compiler c) { } /** - * Flip the compilation levels. + * Called by {@link TestFramework} to flip compilation levels. */ - CompLevel flipCompLevel() { + public CompLevel flipCompLevel() { switch (this) { case C1_SIMPLE, C1_LIMITED_PROFILE, C1_FULL_PROFILE -> { return CompLevel.C2; @@ -145,9 +149,10 @@ CompLevel flipCompLevel() { } /** - * Return the compilation level when only allowing a compilation with the specified compiler. + * Called by {@link TestFramework}. Return the compilation level when only allowing a compilation with the specified + * compiler. */ - CompLevel excludeCompilationRandomly(Executable ex) { + public CompLevel excludeCompilationRandomly(Executable ex) { if (Utils.getRandomInstance().nextBoolean()) { // No exclusion return this; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/DontCompile.java b/test/hotspot/jtreg/compiler/lib/ir_framework/DontCompile.java index 4e475d0e698..618858a4343 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/DontCompile.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/DontCompile.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.shared.TestFormatException; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/DontInline.java b/test/hotspot/jtreg/compiler/lib/ir_framework/DontInline.java index 294829e4ca5..700ca86f0d8 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/DontInline.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/DontInline.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.shared.TestFormatException; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompile.java b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompile.java index 065395dcc6d..2cfe1a8e7d4 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompile.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompile.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.shared.TestFormatException; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompileClassInitializer.java b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompileClassInitializer.java index cdc2039dbdb..0f8a9bc4b45 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompileClassInitializer.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceCompileClassInitializer.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.shared.TestFormatException; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/ForceInline.java b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceInline.java index 6f262208fdc..aba7f057b17 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/ForceInline.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/ForceInline.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.shared.TestFormatException; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IR.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IR.java index 5f2a642b86e..166bfe21867 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IR.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IR.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.driver.IRViolationException; + import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index cd901210213..a5b72599668 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -23,6 +23,10 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.driver.IRMatcher; +import compiler.lib.ir_framework.shared.TestFormat; +import compiler.lib.ir_framework.shared.TestFormatException; + import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; @@ -128,7 +132,10 @@ public class IRNode { private static final String LOAD_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; private static final String LOAD_OF_FIELD_POSTFIX = ",.*" + END; - static List mergeNodes(String[] nodes) { + /** + * Called by {@link IRMatcher} to merge special composite nodes together with additional user-defined input. + */ + public static List mergeNodes(String[] nodes) { List mergedNodes = new ArrayList<>(); for (int i = 0; i < nodes.length; i += 2) { String node = nodes[i]; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/README.md b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md index 63f85edf55a..474519f8aeb 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/README.md +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md @@ -58,7 +58,7 @@ The user has the possibility to add an additional `@IR` annotation to any `@Test - A `failOn` check that verifies that the provided regex is not matched in the C2 IR. - A `counts` check that verifies that the provided regex is matched a user defined number of times in the C2 IR. -A regex can either be a custom string or any of the default regexes provided by the framework in [IRNode](IRNode.java) for some commonly used IR nodes (also provides the possibility of composite regexes). +A regex can either be a custom string or any of the default regexes provided by the framework in [IRNode](./IRNode.java) for some commonly used IR nodes (also provides the possibility of composite regexes). An IR verification cannot always be performed. For example, a JTreg test could be run with _-Xint_ or not a debug build (_-XX:+PrintIdeal_ and _-XX:+PrintOptoAssembly_ are debug build flags). But also CI tier testing could add additional JTreg VM and Javaoptions flags which could make an IR rule unstable. @@ -99,7 +99,7 @@ The framework provides various stress and debug flags. They should mainly be use - `-DShuffleTests=false`: Disables the random execution order of all tests (such a shuffling is always done by default). - `-DDumpReplay=true`: Add the `DumpReplay` directive to the test VM. - `-DGCAfter=true`: Perform `System.gc()` after each test (slows the execution down). -- `-DWaitForCompilationTimeout=20`: Change the default waiting time (default: 10s) for a compilation of a `@Test` annotated method with compilation level [WAIT_FOR_COMPILATION](./CompLevel.java). +- `-DWaitForCompilationTimeout=20`: Change the default waiting time (default: 10s) for a compilation of a `@Test` annotated method with compilation level [WAIT\_FOR\_COMPILATION](./CompLevel.java). - `-DIgnoreCompilerControls=false`: Ignore all compiler controls applied in the framework. This includes any compiler control annotations (`@DontCompile`, `@DontInline`, `@ForceCompile`, `@ForceInline`, `@ForceCompileStaticInitializer`), the exclusion of `@Run` and `@Check` methods from compilation, and the directive to not inline `@Test` annotated methods. @@ -118,9 +118,17 @@ Some of the steps above can be different due to the kind of the test or due to u More information about the internals and the workflow of the framework can be found in the Javadocs of [TestFramework](./TestFramework.java). ## 4. Internal Framework Tests -There are various tests to verify the correctness of the test framework. These tests can be found in [tests](tests) and can directly be run with JTreg. The tests are not part of the normal JTreg tests of HotSpot and should only be run upon changing the framework code as a minimal form of testing. +There are various tests to verify the correctness of the test framework. These tests can be found in [ir_framework](../../../testlibrary_tests/compiler/lib/ir_framework) and can directly be run with JTreg. The tests are part of the normal JTreg tests of HotSpot and should be run upon changing the framework code as a minimal form of testing. Additional testing was performed by converting all compiler Inline Types tests that used the currently present IR test framework in Valhalla (see [JDK-8263024](https://bugs.openjdk.java.net/browse/JDK-8263024)). It is strongly advised to make sure a change to the framework still lets these converted tests in Valhalla pass as part of an additional testing step. -## 5. Summary +## 5. Framework Package Structure +A user only needs to import classes from the package `compiler.lib.ir_framework` (e.g. `import compiler.lib.ir_framework.*;`) which represents the interface classes to the framework. The remaining framework internal classes are kept in separate subpackages and should not directly be imported: + +- `compiler.lib.ir_framework.driver`: These classes are used while running the driver VM (same VM as the one running the user code's `main()` method of a JTreg test). +- `compiler.lib.ir_framework.flag`: These classes are used while running the flag VM to determine additional flags for the test VM which are required for IR verification. +- `compiler.lib.ir_framework.test`: These classes are used while running the test VM (i.e. the actual execution of the user tests as described in section 3). +- `compiler.lib.ir_framework.shared`: These classes can be called from either the driver, flag, or test VM. + +## 6. Summary The initial design and feature set was kept simple and straight forward and serves well for small to medium sized tests. There are a lot of possibilities to further enhance the framework and make it more powerful. This can be tackled in additional RFEs. A few ideas can be found as subtasks of the [initial RFE](https://bugs.openjdk.java.net/browse/JDK-8254129) for this framework. diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/Run.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Run.java index 47a1268aa4e..ea83104449c 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/Run.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/Run.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.shared.TestFormatException; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/RunInfo.java b/test/hotspot/jtreg/compiler/lib/ir_framework/RunInfo.java index 0ed8d8571b8..902e2d54774 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/RunInfo.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/RunInfo.java @@ -23,6 +23,10 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.test.DeclaredTest; +import compiler.lib.ir_framework.shared.TestRunException; +import compiler.lib.ir_framework.test.TestVM; + import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; @@ -39,7 +43,7 @@ public class RunInfo extends AbstractInfo { private final Map tests; private final boolean hasMultipleTests; - RunInfo(List tests) { + public RunInfo(List tests) { super(tests.get(0).getTestMethod().getDeclaringClass()); this.test = tests.get(0); this.testMethod = test.getTestMethod(); diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/Scenario.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Scenario.java index 7d1f48f20a6..17776f7285c 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/Scenario.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/Scenario.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.shared.TestRunException; + import java.util.*; import java.util.stream.Collectors; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java index 6adfddd30c1..898d68d5c78 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java @@ -23,6 +23,9 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.driver.*; +import compiler.lib.ir_framework.shared.*; +import compiler.lib.ir_framework.test.*; import jdk.test.lib.Platform; import jdk.test.lib.Utils; import jdk.test.lib.helpers.ClassFileInstaller; @@ -118,20 +121,20 @@ public class TestFramework { ) ); - static final boolean VERBOSE = Boolean.getBoolean("Verbose"); - static final boolean TESTLIST = !System.getProperty("Test", "").isEmpty(); - static final boolean EXCLUDELIST = !System.getProperty("Exclude", "").isEmpty(); + public static final boolean VERBOSE = Boolean.getBoolean("Verbose"); + public static final boolean TESTLIST = !System.getProperty("Test", "").isEmpty(); + public static final boolean EXCLUDELIST = !System.getProperty("Exclude", "").isEmpty(); private static final boolean REPORT_STDOUT = Boolean.getBoolean("ReportStdout"); - static final String RERUN_HINT = """ - ############################################################# - - To only run the failed tests use -DTest, -DExclude, - and/or -DScenarios. - - To also get the standard output of the test VM run with - -DReportStdout=true or for even more fine-grained logging - use -DVerbose=true. - ############################################################# - """ + System.lineSeparator(); + private static final String RERUN_HINT = """ + ############################################################# + - To only run the failed tests use -DTest, -DExclude, + and/or -DScenarios. + - To also get the standard output of the test VM run with + -DReportStdout=true or for even more fine-grained logging + use -DVerbose=true. + ############################################################# + """ + System.lineSeparator(); private boolean irVerificationPossible = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")); private boolean shouldVerifyIR; // Should we perform IR matching? @@ -695,7 +698,7 @@ private void runTestVM(List additionalFlags) { } } - static void check(boolean test, String failureMessage) { + public static void check(boolean test, String failureMessage) { if (!test) { throw new TestFrameworkException(failureMessage); } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestInfo.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestInfo.java index 0d9f229e406..1e06ade3d80 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestInfo.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestInfo.java @@ -23,6 +23,9 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.test.DeclaredTest; +import compiler.lib.ir_framework.test.TestVM; + import java.lang.reflect.Method; /** @@ -35,10 +38,10 @@ public class TestInfo extends AbstractInfo { private final Method testMethod; private final boolean compilationSkipped; - TestInfo(DeclaredTest test) { - super(test.getTestMethod().getDeclaringClass()); - this.testMethod = test.getTestMethod(); - this.compilationSkipped = test.getCompLevel() == CompLevel.SKIP; + public TestInfo(Method testMethod, CompLevel testCmpLevel) { + super(testMethod.getDeclaringClass()); + this.testMethod = testMethod; + this.compilationSkipped = testCmpLevel == CompLevel.SKIP; } /** diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/FlagVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java similarity index 93% rename from test/hotspot/jtreg/compiler/lib/ir_framework/FlagVMProcess.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java index 4aea2640d3d..c39b045b07f 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/FlagVMProcess.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/FlagVMProcess.java @@ -21,8 +21,12 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.driver; +import compiler.lib.ir_framework.TestFramework; +import compiler.lib.ir_framework.shared.TestFrameworkException; +import compiler.lib.ir_framework.flag.FlagVM; +import compiler.lib.ir_framework.shared.TestRunException; import jdk.test.lib.Utils; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; @@ -43,7 +47,7 @@ * * @see FlagVM */ -class FlagVMProcess { +public class FlagVMProcess { private static final boolean VERBOSE = Boolean.getBoolean("Verbose"); private final List cmds; @@ -52,7 +56,7 @@ class FlagVMProcess { private String testVMFlagsFile; private OutputAnalyzer oa; - FlagVMProcess(Class testClass, List additionalFlags) { + public FlagVMProcess(Class testClass, List additionalFlags) { cmds = new ArrayList<>(); testVMFlags = new ArrayList<>(); prepareVMFlags(testClass, additionalFlags); diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRMatcher.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/IRMatcher.java similarity index 98% rename from test/hotspot/jtreg/compiler/lib/ir_framework/IRMatcher.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/driver/IRMatcher.java index a851856b27f..8fb94eb4a64 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRMatcher.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/IRMatcher.java @@ -21,7 +21,11 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.driver; + +import compiler.lib.ir_framework.*; +import compiler.lib.ir_framework.shared.*; +import compiler.lib.ir_framework.test.*; import java.io.IOException; import java.lang.reflect.Method; @@ -34,10 +38,10 @@ /** * Parse the hotspot pid file of the test VM to match all @IR rules. */ -class IRMatcher { +public class IRMatcher { private static final boolean PRINT_IR_ENCODING = Boolean.parseBoolean(System.getProperty("PrintIREncoding", "false")); private static final Pattern IR_ENCODING_PATTERN = - Pattern.compile("(?<=" + IREncodingPrinter.START + "\\R)[\\s\\S]*(?=" + IREncodingPrinter.END + ")"); + Pattern.compile("(?<=" + IREncodingPrinter.START + "\r?\n)[\\s\\S]*(?=" + IREncodingPrinter.END + ")"); private static final Pattern COMPILE_ID_PATTERN = Pattern.compile("compile_id='(\\d+)'"); private final Map compilations; @@ -75,7 +79,7 @@ private void setupTestMethods(String irEncoding) { Map irRulesMap = parseIREncoding(irEncoding); for (Method m : testClass.getDeclaredMethods()) { method = m; - IR[] irAnnos = m.getAnnotationsByType(IR.class); + 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. int[] ids = irRulesMap.get(m.getName()); @@ -93,7 +97,7 @@ private void setupTestMethods(String irEncoding) { /** * Read the IR encoding emitted by the test VM to decide if an @IR rule must be checked for a method. */ - private Map parseIREncoding(String irEncoding) { + private Map parseIREncoding(String irEncoding) { Map irRulesMap = new HashMap<>(); Matcher matcher = IR_ENCODING_PATTERN.matcher(irEncoding); TestFramework.check(matcher.find(), "Did not find IR encoding"); @@ -375,7 +379,7 @@ private void applyCounts(StringBuilder failMsg) { final List nodesWithCount = IRNode.mergeNodes(irAnno.counts()); for (int i = 0; i < nodesWithCount.size(); i += 2) { String node = nodesWithCount.get(i); - TestFormat.check(i + 1 < nodesWithCount.size(), "Missing count" + getPostfixErrorMsg(node)); + TestFormat.check(i + 1 < nodesWithCount.size(), "Missing count" + getPostfixErrorMsg(node)); String countString = nodesWithCount.get(i + 1); long expectedCount; ParsedComparator parsedComparator; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRMethod.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/IRMethod.java similarity index 97% rename from test/hotspot/jtreg/compiler/lib/ir_framework/IRMethod.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/driver/IRMethod.java index 4d083847a5e..dbad17034af 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRMethod.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/IRMethod.java @@ -21,7 +21,9 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.driver; + +import compiler.lib.ir_framework.IR; import java.lang.reflect.Method; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRViolationException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/IRViolationException.java similarity index 91% rename from test/hotspot/jtreg/compiler/lib/ir_framework/IRViolationException.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/driver/IRViolationException.java index 90071e2ed2a..bacf3536dad 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRViolationException.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/IRViolationException.java @@ -21,7 +21,10 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.driver; + +import compiler.lib.ir_framework.IR; +import compiler.lib.ir_framework.Test; /** * Exception that is thrown if an {@link IR} rule/constraint failed. The exception message contains a detailed list of @@ -50,11 +53,11 @@ public String getExceptionInfo() { return exceptionInfo; } - String getCompilations() { + public String getCompilations() { return compilations; } - void addCommandLine(String commandLine) { + public void addCommandLine(String commandLine) { this.exceptionInfo = commandLine + System.lineSeparator() + exceptionInfo; } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestVMException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMException.java similarity index 94% rename from test/hotspot/jtreg/compiler/lib/ir_framework/TestVMException.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMException.java index dee71dc8c87..63b3d522b86 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestVMException.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMException.java @@ -21,7 +21,9 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.driver; + +import compiler.lib.ir_framework.shared.TestFormatException; /** * Exception that is thrown if the test VM has thrown any kind of exception (except for {@link TestFormatException}). diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java similarity index 94% rename from test/hotspot/jtreg/compiler/lib/ir_framework/TestVMProcess.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java index 4af1670a037..ed8484e54bc 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestVMProcess.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java @@ -21,8 +21,14 @@ * questions. */ -package compiler.lib.ir_framework; - +package compiler.lib.ir_framework.driver; + +import compiler.lib.ir_framework.TestFramework; +import compiler.lib.ir_framework.shared.TestFrameworkException; +import compiler.lib.ir_framework.shared.TestFrameworkSocket; +import compiler.lib.ir_framework.shared.NoTestsRunException; +import compiler.lib.ir_framework.shared.TestFormatException; +import compiler.lib.ir_framework.test.TestVM; import jdk.test.lib.Platform; import jdk.test.lib.Utils; import jdk.test.lib.process.OutputAnalyzer; @@ -40,7 +46,7 @@ * @see TestVM * @see TestFrameworkSocket */ -class TestVMProcess { +public class TestVMProcess { private static final boolean VERBOSE = Boolean.getBoolean("Verbose"); private static final boolean PREFER_COMMAND_LINE_FLAGS = Boolean.getBoolean("PreferCommandLineFlags"); private static final int WARMUP_ITERATIONS = Integer.getInteger("Warmup", -1); @@ -56,7 +62,7 @@ class TestVMProcess { private OutputAnalyzer oa; private String irEncoding; - TestVMProcess(List additionalFlags, Class testClass, Set> helperClasses, int defaultWarmup) { + public TestVMProcess(List additionalFlags, Class testClass, Set> helperClasses, int defaultWarmup) { this.cmds = new ArrayList<>(); TestFrameworkSocket socket = new TestFrameworkSocket(); try (socket) { diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/FlagVM.java b/test/hotspot/jtreg/compiler/lib/ir_framework/flag/FlagVM.java similarity index 91% rename from test/hotspot/jtreg/compiler/lib/ir_framework/FlagVM.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/flag/FlagVM.java index 449d9dada92..52e3b93fbcb 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/FlagVM.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/flag/FlagVM.java @@ -21,8 +21,12 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.flag; +import compiler.lib.ir_framework.CompLevel; +import compiler.lib.ir_framework.TestFramework; +import compiler.lib.ir_framework.shared.TestFrameworkException; +import compiler.lib.ir_framework.shared.TestRunException; import jdk.test.lib.process.ProcessTools; import sun.hotspot.WhiteBox; @@ -37,10 +41,13 @@ * Whitebox API to determine the necessary additional flags to run the test VM (e.g. to do IR matching). It returns * the flags over the dedicated TestFramework socket. */ -class FlagVM { +public class FlagVM { + public static final String TEST_VM_FLAGS_FILE_PREFIX = "test-vm-flags-pid-"; + public static final String TEST_VM_FLAGS_FILE_POSTFIX = ".log"; + public static final String TEST_VM_FLAGS_DELIMITER = " "; + + private static final String TEST_VM_FLAGS_FILE; private static final WhiteBox WHITE_BOX; - static final String TEST_VM_FLAGS_FILE_PREFIX = "test-vm-flags-pid-"; - static final String TEST_VM_FLAGS_FILE_POSTFIX = ".log"; static { try { @@ -53,9 +60,6 @@ class FlagVM { } } - private static final String TEST_VM_FLAGS_FILE; - - static final String TEST_VM_FLAGS_DELIMITER = " "; private static final boolean TIERED_COMPILATION = (Boolean)WHITE_BOX.getVMFlag("TieredCompilation"); private static final CompLevel TIERED_COMPILATION_STOP_AT_LEVEL = diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTestFrameworkException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/CheckedTestFrameworkException.java similarity index 87% rename from test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTestFrameworkException.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/shared/CheckedTestFrameworkException.java index bc16db00cce..d18584abaa1 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTestFrameworkException.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/CheckedTestFrameworkException.java @@ -21,13 +21,13 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.shared; /** * Checked internal exceptions in the framework to propagate error handling. */ -class CheckedTestFrameworkException extends Exception { - CheckedTestFrameworkException(String msg) { +public class CheckedTestFrameworkException extends Exception { + public CheckedTestFrameworkException(String msg) { super(msg); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/NoTestsRunException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/NoTestsRunException.java similarity index 92% rename from test/hotspot/jtreg/compiler/lib/ir_framework/NoTestsRunException.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/shared/NoTestsRunException.java index 2d4b5ebbb04..02afdd4ee4f 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/NoTestsRunException.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/NoTestsRunException.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.shared; /** * Exception that is thrown by the test VM if no tests are run as a result of specifying {@code -DTest} and/or @@ -31,12 +31,12 @@ public class NoTestsRunException extends RuntimeException { /** * Default constructor used by test VM */ - NoTestsRunException() {} + public NoTestsRunException() {} /** * Constructor used to eventually throw the exception in the driver VM. */ - NoTestsRunException(String message) { + public NoTestsRunException(String message) { super(message); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/ParsedComparator.java b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/ParsedComparator.java similarity index 97% rename from test/hotspot/jtreg/compiler/lib/ir_framework/ParsedComparator.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/shared/ParsedComparator.java index 9b00e6f3465..9d574bc50a4 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/ParsedComparator.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/ParsedComparator.java @@ -21,14 +21,14 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.shared; import java.util.function.BiPredicate; /** * Utility class to parse a comparator either in the applyIf* or in the counts properties of an @IR rules. */ -class ParsedComparator> { +public class ParsedComparator> { private final String strippedString; private final BiPredicate predicate; private final String comparator; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFormat.java b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFormat.java similarity index 97% rename from test/hotspot/jtreg/compiler/lib/ir_framework/TestFormat.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFormat.java index e1c604d6331..624753fee2f 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFormat.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFormat.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.shared; import java.util.ArrayList; import java.util.List; @@ -29,7 +29,7 @@ /** * Utility class to report a {@link TestFormatException}. */ -class TestFormat { +public class TestFormat { private static final List FAILURES = new ArrayList<>(); public static void check(boolean test, String failureMessage) { diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFormatException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFormatException.java similarity index 93% rename from test/hotspot/jtreg/compiler/lib/ir_framework/TestFormatException.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFormatException.java index b8327c1a635..cb44f624bfb 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFormatException.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFormatException.java @@ -21,13 +21,13 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.shared; /** * Exception that is thrown if a JTreg test violates the supported format by the test framework. */ public class TestFormatException extends RuntimeException { - TestFormatException(String message) { + public TestFormatException(String message) { super(message); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFrameworkException.java similarity index 90% rename from test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkException.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFrameworkException.java index 0a7472d4a8b..050aecf09db 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkException.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFrameworkException.java @@ -21,18 +21,18 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.shared; /** * Exception that is thrown if there is an internal error in the framework. This is most likely an indicator of a bug * in the framework. */ public class TestFrameworkException extends RuntimeException { - TestFrameworkException(String message) { + public TestFrameworkException(String message) { super("Internal Test Framework exception - please file a bug:" + System.lineSeparator() + message); } - TestFrameworkException(String message, Throwable e) { + public TestFrameworkException(String message, Throwable e) { super("Internal Test Framework exception - please file a bug:" + System.lineSeparator() + message, e); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkSocket.java b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFrameworkSocket.java similarity index 95% rename from test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkSocket.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFrameworkSocket.java index d379420a560..aa4f3ec1c6b 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFrameworkSocket.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestFrameworkSocket.java @@ -21,7 +21,9 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.shared; + +import compiler.lib.ir_framework.TestFramework; import java.io.BufferedReader; import java.io.IOException; @@ -35,12 +37,12 @@ /** * Dedicated socket to send data from the flag and test VM back to the driver VM. */ -class TestFrameworkSocket implements AutoCloseable { - // Static fields used by flag and test VM only. +public class TestFrameworkSocket implements AutoCloseable { + public static final String STDOUT_PREFIX = "[STDOUT]"; + // Static fields used for test VM only. private static final String SERVER_PORT_PROPERTY = "ir.framework.server.port"; private static final int SERVER_PORT = Integer.getInteger(SERVER_PORT_PROPERTY, -1); - static final String STDOUT_PREFIX = "[STDOUT]"; private static final boolean REPRODUCE = Boolean.getBoolean("Reproduce"); private static final String HOSTNAME = null; private static Socket clientSocket = null; @@ -50,7 +52,7 @@ class TestFrameworkSocket implements AutoCloseable { private FutureTask socketTask; private final ServerSocket serverSocket; - TestFrameworkSocket() { + public TestFrameworkSocket() { try { serverSocket = new ServerSocket(0); } catch (IOException e) { diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestRun.java b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestRun.java similarity index 95% rename from test/hotspot/jtreg/compiler/lib/ir_framework/TestRun.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestRun.java index 73528fdc37e..ebf5fc80c9a 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestRun.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestRun.java @@ -21,12 +21,12 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.shared; /** * Utility class to report a {@link TestRunException}. */ -class TestRun { +public class TestRun { public static void check(boolean test, String failureMessage) { if (!test) { throw new TestRunException(failureMessage); diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestRunException.java b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestRunException.java similarity index 89% rename from test/hotspot/jtreg/compiler/lib/ir_framework/TestRunException.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestRunException.java index 92b30cdc595..1969a755704 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestRunException.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/shared/TestRunException.java @@ -21,18 +21,18 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.shared; /** * Exception that is thrown if the JTreg test throws an exception during the execution of individual tests of the * test class. */ public class TestRunException extends RuntimeException { - TestRunException(String message) { + public TestRunException(String message) { super(message); } - TestRunException(String message, Exception e) { + public TestRunException(String message, Exception e) { super(message, e); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/test/AbstractTest.java similarity index 97% rename from test/hotspot/jtreg/compiler/lib/ir_framework/AbstractTest.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/test/AbstractTest.java index b8d3c64867b..ce28b543ed3 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/AbstractTest.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/test/AbstractTest.java @@ -21,8 +21,11 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.test; +import compiler.lib.ir_framework.*; +import compiler.lib.ir_framework.shared.TestRun; +import compiler.lib.ir_framework.shared.TestRunException; import sun.hotspot.WhiteBox; import java.lang.reflect.Constructor; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/ArgumentValue.java b/test/hotspot/jtreg/compiler/lib/ir_framework/test/ArgumentValue.java similarity index 97% rename from test/hotspot/jtreg/compiler/lib/ir_framework/ArgumentValue.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/test/ArgumentValue.java index e6cf414d9cf..7c5a9edec71 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/ArgumentValue.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/test/ArgumentValue.java @@ -21,8 +21,13 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.test; +import compiler.lib.ir_framework.Argument; +import compiler.lib.ir_framework.Arguments; +import compiler.lib.ir_framework.shared.TestFrameworkException; +import compiler.lib.ir_framework.shared.TestFormat; +import compiler.lib.ir_framework.shared.TestFormatException; import jdk.test.lib.Utils; import java.lang.reflect.Constructor; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/BaseTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/test/BaseTest.java similarity index 93% rename from test/hotspot/jtreg/compiler/lib/ir_framework/BaseTest.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/test/BaseTest.java index cf2f0741a4b..a17eb91884d 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/BaseTest.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/test/BaseTest.java @@ -21,7 +21,10 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.test; + +import compiler.lib.ir_framework.*; +import compiler.lib.ir_framework.shared.TestRunException; import java.lang.reflect.Method; @@ -40,7 +43,7 @@ public BaseTest(DeclaredTest test, boolean skip) { super(test.getWarmupIterations(), skip); this.test = test; this.testMethod = test.getTestMethod(); - this.testInfo = new TestInfo(test); + this.testInfo = new TestInfo(testMethod, test.getCompLevel()); this.invocationTarget = createInvocationTarget(testMethod); this.shouldCompile = shouldCompile(test); this.waitForCompilation = isWaitForCompilation(test); diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/test/CheckedTest.java similarity index 95% rename from test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTest.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/test/CheckedTest.java index 1643af51f18..8959dbac2ee 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/CheckedTest.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/test/CheckedTest.java @@ -21,7 +21,11 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.test; + +import compiler.lib.ir_framework.Check; +import compiler.lib.ir_framework.CheckAt; +import compiler.lib.ir_framework.shared.TestRunException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/CustomRunTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/test/CustomRunTest.java similarity index 96% rename from test/hotspot/jtreg/compiler/lib/ir_framework/CustomRunTest.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/test/CustomRunTest.java index e08f407b08b..f82a2ca4abf 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/CustomRunTest.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/test/CustomRunTest.java @@ -21,8 +21,12 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.test; +import compiler.lib.ir_framework.*; +import compiler.lib.ir_framework.shared.TestFormat; +import compiler.lib.ir_framework.shared.TestFrameworkException; +import compiler.lib.ir_framework.shared.TestRunException; import sun.hotspot.WhiteBox; import java.lang.reflect.Method; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/DeclaredTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/test/DeclaredTest.java similarity index 96% rename from test/hotspot/jtreg/compiler/lib/ir_framework/DeclaredTest.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/test/DeclaredTest.java index 9bd9532e393..3f1bfbba8b5 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/DeclaredTest.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/test/DeclaredTest.java @@ -21,7 +21,10 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.test; + +import compiler.lib.ir_framework.CompLevel; +import compiler.lib.ir_framework.shared.TestRunException; import java.lang.reflect.Method; import java.util.Arrays; @@ -29,7 +32,7 @@ /** * This class represents a @Test method. */ -class DeclaredTest { +public class DeclaredTest { private final Method testMethod; private final ArgumentValue[] arguments; private final int warmupIterations; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IREncodingPrinter.java b/test/hotspot/jtreg/compiler/lib/ir_framework/test/IREncodingPrinter.java similarity index 98% rename from test/hotspot/jtreg/compiler/lib/ir_framework/IREncodingPrinter.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/test/IREncodingPrinter.java index 12db7b2512f..57e8bd4f2d3 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IREncodingPrinter.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/test/IREncodingPrinter.java @@ -21,8 +21,10 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.test; +import compiler.lib.ir_framework.*; +import compiler.lib.ir_framework.shared.*; import sun.hotspot.WhiteBox; import java.lang.reflect.Method; @@ -37,7 +39,7 @@ * This is done during the execution of the test VM by checking the active VM flags. This encoding is eventually parsed * and checked by the IRMatcher class in the driver VM after the termination of the test VM. */ -class IREncodingPrinter { +public class IREncodingPrinter { public static final String START = "##### IRMatchRulesEncoding - used by TestFramework #####"; public static final String END = "----- END -----"; public static final int NO_RULE_APPLIED = -1; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestVM.java b/test/hotspot/jtreg/compiler/lib/ir_framework/test/TestVM.java similarity index 97% rename from test/hotspot/jtreg/compiler/lib/ir_framework/TestVM.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/test/TestVM.java index 3d269581ded..414cbc84fa5 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestVM.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/test/TestVM.java @@ -21,8 +21,11 @@ * questions. */ -package compiler.lib.ir_framework; +package compiler.lib.ir_framework.test; +import compiler.lib.ir_framework.*; +import compiler.lib.ir_framework.Compiler; +import compiler.lib.ir_framework.shared.*; import jdk.test.lib.Platform; import jdk.test.lib.Utils; import sun.hotspot.WhiteBox; @@ -72,12 +75,12 @@ assertions from main() of your test! private static final boolean TIERED_COMPILATION = (Boolean)WHITE_BOX.getVMFlag("TieredCompilation"); private static final CompLevel TIERED_COMPILATION_STOP_AT_LEVEL = CompLevel.forValue(((Long)WHITE_BOX.getVMFlag("TieredStopAtLevel")).intValue()); - static final boolean TEST_C1 = TIERED_COMPILATION && TIERED_COMPILATION_STOP_AT_LEVEL.getValue() < CompLevel.C2.getValue(); + public static final boolean TEST_C1 = TIERED_COMPILATION && TIERED_COMPILATION_STOP_AT_LEVEL.getValue() < CompLevel.C2.getValue(); static final boolean XCOMP = Platform.isComp(); static final boolean VERBOSE = Boolean.getBoolean("Verbose"); private static final boolean PRINT_TIMES = Boolean.getBoolean("PrintTimes"); - static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); + public static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); static final boolean EXCLUDE_RANDOM = Boolean.getBoolean("ExcludeRandom"); private static final String TESTLIST = System.getProperty("Test", ""); private static final String EXCLUDELIST = System.getProperty("Exclude", ""); @@ -363,7 +366,7 @@ private void checkClassAnnotations(Executable ex) { * Exclude a method from compilation with a compiler randomly. Return the compiler for which the method was made * not compilable. */ - static Compiler excludeRandomly(Executable ex) { + public static Compiler excludeRandomly(Executable ex) { Compiler compiler = switch (Utils.getRandomInstance().nextInt() % 3) { case 1 -> Compiler.C1; case 2 -> Compiler.C2; @@ -843,40 +846,40 @@ enum TriState { No } - static void compile(Method m, CompLevel compLevel) { + public static void compile(Method m, CompLevel compLevel) { TestRun.check(compLevel != CompLevel.SKIP && compLevel != CompLevel.WAIT_FOR_COMPILATION, "Invalid compilation request with level " + compLevel); enqueueForCompilation(m, compLevel); } - static void deoptimize(Method m) { + public static void deoptimize(Method m) { WHITE_BOX.deoptimizeMethod(m); } - static boolean isCompiled(Method m) { + public static boolean isCompiled(Method m) { return compiledAtLevel(m, CompLevel.ANY) == TriState.Yes; } - static boolean isC1Compiled(Method m) { + public static boolean isC1Compiled(Method m) { return compiledByC1(m) == TriState.Yes; } - static boolean isC2Compiled(Method m) { + public static boolean isC2Compiled(Method m) { return compiledByC2(m) == TriState.Yes; } - static boolean isCompiledAtLevel(Method m, CompLevel compLevel) { + public static boolean isCompiledAtLevel(Method m, CompLevel compLevel) { return compiledAtLevel(m, compLevel) == TriState.Yes; } - static void assertDeoptimizedByC1(Method m) { + public static void assertDeoptimizedByC1(Method m) { if (notUnstableDeoptAssertion(m, CompLevel.C1_SIMPLE)) { TestRun.check(compiledByC1(m) != TriState.Yes || PER_METHOD_TRAP_LIMIT == 0 || !PROFILE_INTERPRETER, m + " should have been deoptimized by C1"); } } - static void assertDeoptimizedByC2(Method m) { + public static void assertDeoptimizedByC2(Method m) { if (notUnstableDeoptAssertion(m, CompLevel.C2)) { TestRun.check(compiledByC2(m) != TriState.Yes || PER_METHOD_TRAP_LIMIT == 0 || !PROFILE_INTERPRETER, m + " should have been deoptimized by C2"); @@ -891,24 +894,24 @@ private static boolean notUnstableDeoptAssertion(Method m, CompLevel level) { (!EXCLUDE_RANDOM || WHITE_BOX.isMethodCompilable(m, level.getValue(), false))); } - static void assertCompiledByC1(Method m) { + public static void assertCompiledByC1(Method m) { TestRun.check(compiledByC1(m) != TriState.No, m + " should have been C1 compiled"); } - static void assertCompiledByC2(Method m) { + public static void assertCompiledByC2(Method m) { TestRun.check(compiledByC2(m) != TriState.No, m + " should have been C2 compiled"); } - static void assertCompiledAtLevel(Method m, CompLevel level) { + public static void assertCompiledAtLevel(Method m, CompLevel level) { TestRun.check(compiledAtLevel(m, level) != TriState.No, m + " should have been compiled at level " + level.name()); } - static void assertNotCompiled(Method m) { + public static void assertNotCompiled(Method m) { TestRun.check(!isC1Compiled(m), m + " should not have been compiled by C1"); TestRun.check(!isC2Compiled(m), m + " should not have been compiled by C2"); } - static void assertCompiled(Method m) { + public static void assertCompiled(Method m) { TestRun.check(compiledByC1(m) != TriState.No || compiledByC2(m) != TriState.No, m + " should have been compiled"); } diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java index d4c8b93061f..f326ad908bc 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java @@ -23,6 +23,7 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.shared.TestFormatException; import jdk.test.lib.Asserts; import java.lang.annotation.Retention; diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBasics.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBasics.java index 29a6b7f6a12..5f71367d6e6 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBasics.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBasics.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.test.TestVM; + import java.lang.reflect.Method; import java.util.Arrays; import java.util.stream.Stream; diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java index 7a531960a1d..2ad976ff90e 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.test.TestVM; + import java.lang.reflect.Method; /* diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java index 3161dcd7904..5543d24f68d 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java @@ -23,6 +23,7 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.test.TestVM; import jdk.test.lib.Asserts; import sun.hotspot.WhiteBox; diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDScenarios.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDScenarios.java index fce1ec1b8ef..f0369851395 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDScenarios.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDScenarios.java @@ -23,6 +23,7 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.driver.TestVMException; import jdk.test.lib.Utils; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDTestAndExclude.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDTestAndExclude.java index 1fc16bac956..c0d2bb062bc 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDTestAndExclude.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDTestAndExclude.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.driver.TestVMException; +import compiler.lib.ir_framework.shared.NoTestsRunException; import jdk.test.lib.Utils; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java index a3a7857da3e..8c27033eefd 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java @@ -23,6 +23,7 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.driver.IRViolationException; import jdk.test.lib.Asserts; import java.io.ByteArrayOutputStream; diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestRunTests.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestRunTests.java index 947dd88286e..a9522fcdeab 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestRunTests.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestRunTests.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.driver.IRViolationException; +import compiler.lib.ir_framework.shared.TestRunException; import jdk.test.lib.Asserts; import java.util.Arrays; diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java index e833337c14a..c6680fc408c 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java @@ -23,6 +23,7 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.shared.TestRunException; import jdk.test.lib.Asserts; /* diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestWithHelperClasses.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestWithHelperClasses.java index 8a30228f7e5..9f04e95c042 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestWithHelperClasses.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestWithHelperClasses.java @@ -23,6 +23,8 @@ package compiler.lib.ir_framework; +import compiler.lib.ir_framework.driver.TestVMException; +import compiler.lib.ir_framework.shared.TestFormatException; import jdk.test.lib.Asserts; /* diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/BaseTestExample.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/BaseTestExample.java index 99aabecb36a..9f8cc1eb135 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/BaseTestExample.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/BaseTestExample.java @@ -24,6 +24,7 @@ package compiler.lib.ir_framework.examples; import compiler.lib.ir_framework.*; +import compiler.lib.ir_framework.test.TestVM; /* * @test * @summary Example test to use the new test framework. diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CheckedTestExample.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CheckedTestExample.java index 7eb82ded03d..c01f0671daf 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CheckedTestExample.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CheckedTestExample.java @@ -24,6 +24,7 @@ package compiler.lib.ir_framework.examples; import compiler.lib.ir_framework.*; +import compiler.lib.ir_framework.test.TestVM; /* * @test diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CustomRunTestExample.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CustomRunTestExample.java index 7c8fa50997c..90e15abc439 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CustomRunTestExample.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CustomRunTestExample.java @@ -24,6 +24,7 @@ package compiler.lib.ir_framework.examples; import compiler.lib.ir_framework.*; +import compiler.lib.ir_framework.test.TestVM; /* * @test diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/IRExample.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/IRExample.java index 41f5ab048f7..44b3fb6bf50 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/IRExample.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/IRExample.java @@ -24,6 +24,7 @@ package compiler.lib.ir_framework.examples; import compiler.lib.ir_framework.*; +import compiler.lib.ir_framework.driver.IRViolationException; /* * @test From e2583432ed743eb1ae50e6d74a0d8318b1886878 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Mon, 31 May 2021 17:37:00 +0200 Subject: [PATCH 124/131] Fix Compiler and CompLevel ANY and fix tests after merge --- .../compiler/lib/ir_framework/CompLevel.java | 2 +- .../compiler/lib/ir_framework/Compiler.java | 2 +- .../lib/ir_framework/TestBadFormat.java | 118 +++++++-------- .../lib/ir_framework/TestIRMatching.java | 134 +++++++++--------- .../compiler/lib/ir_framework/TestSanity.java | 12 +- .../lib/ir_framework/TestScenarios.java | 16 +-- 6 files changed, 142 insertions(+), 142 deletions(-) diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java index 4c3384ce966..b6e55c0f617 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java @@ -67,7 +67,7 @@ public enum CompLevel { *

            • {@link DontCompile @DontCompile}: Prevents any compilation of the associated helper method.

            • *
            */ - ANY(-2), + ANY(-1), /** * Compilation level 1: C1 compilation without any profile information. */ diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/Compiler.java b/test/hotspot/jtreg/compiler/lib/ir_framework/Compiler.java index bcbfe116925..53fe50a2fbb 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/Compiler.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/Compiler.java @@ -34,7 +34,7 @@ public enum Compiler { /** * Selecting both the C1 and C2 compiler. This must be in sync with hotspot/share/compiler/compilerDefinitions.hpp. */ - ANY(-2), + ANY(-1), /** * The C1 compiler. */ diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java index f326ad908bc..c47c5542cb6 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java @@ -673,29 +673,29 @@ public void mustSpecifyAtLeastOneConstraint2() { } @Test - @IR(applyIf = {"SuspendRetryCount", "50"}) + @IR(applyIf = {"TLABRefillWasteFraction", "50"}) public void mustSpecifyAtLeastOneConstraint3() { } @FailCount(3) @Test - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "50"}, applyIfNot = {"UseTLAB", "true"}) - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "50", "UseTLAB", "true"}, - applyIfOr = {"SuspendRetryCount", "50", "UseTLAB", "true"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "50"}, applyIfNot = {"SuspendRetryCount", "50"}, - applyIfAnd = {"SuspendRetryCount", "50", "UseTLAB", "true"}, - applyIfOr = {"SuspendRetryCount", "50", "UseTLAB", "true"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "50"}, applyIfNot = {"UseTLAB", "true"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "50", "UseTLAB", "true"}, + applyIfOr = {"TLABRefillWasteFraction", "50", "UseTLAB", "true"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "50"}, applyIfNot = {"TLABRefillWasteFraction", "50"}, + applyIfAnd = {"TLABRefillWasteFraction", "50", "UseTLAB", "true"}, + applyIfOr = {"TLABRefillWasteFraction", "50", "UseTLAB", "true"}) public void onlyOneApply() {} @FailCount(3) @Test - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "50", "UseTLAB", "true"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "51", "UseTLAB"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "50", "UseTLAB", "true"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "51", "UseTLAB"}) public void applyIfTooManyFlags() {} @FailCount(2) @Test - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction"}) @IR(failOn = IRNode.CALL, applyIf = {"Bla"}) public void applyIfMissingValue() {} @@ -716,22 +716,22 @@ public void applyIfEmptyValue() {} @FailCount(5) @Test - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "! 34"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!== 34"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<<= 34"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "=<34"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "! 34"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!== 34"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<<= 34"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "=<34"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<"}) public void applyIfFaultyComparator() {} @FailCount(3) @Test - @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount", "50", "UseTLAB", "true"}) - @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount", "50", "UseTLAB"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction", "50", "UseTLAB", "true"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction", "50", "UseTLAB"}) public void applyIfNotTooManyFlags() {} @FailCount(2) @Test - @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction"}) @IR(failOn = IRNode.CALL, applyIfNot = {"Bla"}) public void applyIfNotMissingValue() {} @@ -752,31 +752,31 @@ public void applyIfNotEmptyValue() {} @FailCount(5) @Test - @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount", "! 34"}) - @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount", "!== 34"}) - @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount", "<<= 34"}) - @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount", "=<34"}) - @IR(failOn = IRNode.CALL, applyIfNot = {"SuspendRetryCount", "<"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction", "! 34"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction", "!== 34"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction", "<<= 34"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction", "=<34"}) + @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction", "<"}) public void applyIfNotFaultyComparator() {} @FailCount(2) @Test - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "50"}) - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "51", "UseTLAB"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "50"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "51", "UseTLAB"}) public void applyIfAndNotEnoughFlags() {} @FailCount(5) @Test - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount"}) - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "51", "UseTLAB"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "51", "UseTLAB"}) @IR(failOn = IRNode.CALL, applyIfAnd = {"Bla"}) public void applyIfAndMissingValue() {} @FailCount(3) @Test - @IR(failOn = IRNode.CALL, applyIfAnd = {"PrintIdealGraphFilee", "true", "SuspendRetryCount", "< 34"}) - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "!= 50", "Bla", "bla", "Bla2", "bla2"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"PrintIdealGraphFilee", "true", "TLABRefillWasteFraction", "< 34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "!= 50", "Bla", "bla", "Bla2", "bla2"}) public void applyIfAndUnknownFlag() {} @FailCount(18) @@ -794,35 +794,35 @@ public void applyIfAndEmptyValue() {} @FailCount(20) @Test - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "! 34"}) - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "! 34", "SuspendRetryCount", "! 34"}) - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "!== 34"}) - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "!== 34", "SuspendRetryCount", "=== 34"}) - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "<<= 34"}) - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "<<= 34", "SuspendRetryCount", ">>= 34"}) - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "=<34"}) - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "=<34", "SuspendRetryCount", "=<34"}) - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "<"}) - @IR(failOn = IRNode.CALL, applyIfAnd = {"SuspendRetryCount", "<", "SuspendRetryCount", "!="}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "! 34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "! 34", "TLABRefillWasteFraction", "! 34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "!== 34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "!== 34", "TLABRefillWasteFraction", "=== 34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "<<= 34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "<<= 34", "TLABRefillWasteFraction", ">>= 34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "=<34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "=<34", "TLABRefillWasteFraction", "=<34"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "<"}) + @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "<", "TLABRefillWasteFraction", "!="}) public void applyIfAndFaultyComparator() {} @FailCount(2) @Test - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "50"}) - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "51", "UseTLAB"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction", "50"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction", "51", "UseTLAB"}) public void applyIfOrNotEnoughFlags() {} @FailCount(5) @Test - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount"}) - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "51", "UseTLAB"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction", "51", "UseTLAB"}) @IR(failOn = IRNode.CALL, applyIfOr = {"Bla"}) public void applyIfOrMissingValue() {} @FailCount(3) @Test - @IR(failOn = IRNode.CALL, applyIfOr = {"PrintIdealGraphFilee", "true", "SuspendRetryCount", "< 34"}) - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "!= 50", "Bla", "bla", "Bla2", "bla2"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"PrintIdealGraphFilee", "true", "TLABRefillWasteFraction", "< 34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction", "!= 50", "Bla", "bla", "Bla2", "bla2"}) public void applyIfOrUnknownFlag() {} @FailCount(18) @@ -840,25 +840,25 @@ public void applyIfOrEmptyValue() {} @FailCount(20) @Test - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "! 34"}) - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "! 34", "SuspendRetryCount", "! 34"}) - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "!== 34"}) - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "!== 34", "SuspendRetryCount", "=== 34"}) - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "<<= 34"}) - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "<<= 34", "SuspendRetryCount", ">>= 34"}) - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "=<34"}) - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "=<34", "SuspendRetryCount", "=<34"}) - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "<"}) - @IR(failOn = IRNode.CALL, applyIfOr = {"SuspendRetryCount", "<", "SuspendRetryCount", "!="}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction", "! 34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction", "! 34", "TLABRefillWasteFraction", "! 34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction", "!== 34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction", "!== 34", "TLABRefillWasteFraction", "=== 34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction", "<<= 34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction", "<<= 34", "TLABRefillWasteFraction", ">>= 34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction", "=<34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction", "=<34", "TLABRefillWasteFraction", "=<34"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction", "<"}) + @IR(failOn = IRNode.CALL, applyIfOr = {"TLABRefillWasteFraction", "<", "TLABRefillWasteFraction", "!="}) public void applyIfOrFaultyComparator() {} @Test @FailCount(3) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "true"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "SomeString"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "48"}) // valid - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "48.5"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "true"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "SomeString"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "48"}) // valid + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "48.5"}) public void wrongFlagValueLongFlag() {} @Test diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java index 8c27033eefd..fb066bbd84c 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java @@ -46,13 +46,13 @@ public class TestIRMatching { public static void main(String[] args) { - runFailOnTestsArgs(BadFailOnConstraint.create(AndOr1.class, "test1(int)", 1, "CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:+UsePerfData", "-XX:+UseTLAB"); - runFailOnTestsArgs(BadFailOnConstraint.create(AndOr1.class, "test2()", 1, "CallStaticJava"), "-XX:SuspendRetryCount=50", "-XX:-UsePerfData", "-XX:+UseTLAB"); + runFailOnTestsArgs(BadFailOnConstraint.create(AndOr1.class, "test1(int)", 1, "CallStaticJava"), "-XX:TLABRefillWasteFraction=50", "-XX:+UsePerfData", "-XX:+UseTLAB"); + runFailOnTestsArgs(BadFailOnConstraint.create(AndOr1.class, "test2()", 1, "CallStaticJava"), "-XX:TLABRefillWasteFraction=50", "-XX:-UsePerfData", "-XX:+UseTLAB"); - runWithArguments(AndOr1.class, "-XX:SuspendRetryCount=52", "-XX:+UsePerfData", "-XX:+UseTLAB"); - runWithArguments(CountComparisons.class, "-XX:SuspendRetryCount=50"); - runWithArguments(GoodCount.class, "-XX:SuspendRetryCount=50"); - runWithArguments(MultipleFailOnGood.class, "-XX:SuspendRetryCount=50"); + runWithArguments(AndOr1.class, "-XX:TLABRefillWasteFraction=52", "-XX:+UsePerfData", "-XX:+UseTLAB"); + runWithArguments(CountComparisons.class, "-XX:TLABRefillWasteFraction=50"); + runWithArguments(GoodCount.class, "-XX:TLABRefillWasteFraction=50"); + runWithArguments(MultipleFailOnGood.class, "-XX:TLABRefillWasteFraction=50"); String[] allocMatches = { "MyClass", "call,static wrapper for: _new_instance_Java" }; runCheck(BadFailOnConstraint.create(MultipleFailOnBad.class, "fail1()", 1, 1, "Store"), @@ -226,21 +226,21 @@ public static void main(String[] args) { Asserts.assertEQ(count, 7, "Could not find all opto methods"); } - runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=50"); + runWithArguments(FlagComparisons.class, "-XX:TLABRefillWasteFraction=50"); System.out.flush(); String output = baos.toString(); baos.reset(); findIrIds(output, "testMatchAllIf50", 0, 21); findIrIds(output, "testMatchNoneIf50", -1, -1); - runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=49"); + runWithArguments(FlagComparisons.class, "-XX:TLABRefillWasteFraction=49"); System.out.flush(); output = baos.toString(); baos.reset(); findIrIds(output, "testMatchAllIf50", 4, 6, 13, 18); findIrIds(output, "testMatchNoneIf50", 0, 3, 8, 10, 17, 22); - runWithArguments(FlagComparisons.class, "-XX:SuspendRetryCount=51"); + runWithArguments(FlagComparisons.class, "-XX:TLABRefillWasteFraction=51"); System.out.flush(); output = baos.toString(); baos.reset(); @@ -317,13 +317,13 @@ public static void findIrIds(String output, String method, int... numbers) { class AndOr1 { @Test @Arguments(Argument.DEFAULT) - @IR(applyIfAnd = {"UsePerfData", "true", "SuspendRetryCount", "50", "UseTLAB", "true"}, failOn = {IRNode.CALL}) + @IR(applyIfAnd = {"UsePerfData", "true", "TLABRefillWasteFraction", "50", "UseTLAB", "true"}, failOn = {IRNode.CALL}) public void test1(int i) { dontInline(); } @Test - @IR(applyIfOr = {"UsePerfData", "false", "SuspendRetryCount", "51", "UseTLAB", "false"}, failOn = {IRNode.CALL}) + @IR(applyIfOr = {"UsePerfData", "false", "TLABRefillWasteFraction", "51", "UseTLAB", "false"}, failOn = {IRNode.CALL}) public void test2() { dontInline(); } @@ -338,25 +338,25 @@ class MultipleFailOnGood { private MyClassSub myClassSub = new MyClassSub(); @Test - @IR(applyIf = {"SuspendRetryCount", "50"}, failOn = {IRNode.STORE, IRNode.CALL}) + @IR(applyIf = {"TLABRefillWasteFraction", "50"}, failOn = {IRNode.STORE, IRNode.CALL}) @IR(failOn = {IRNode.STORE, IRNode.CALL}) - @IR(applyIfOr = {"SuspendRetryCount", "99", "SuspendRetryCount", "100"}, failOn = {IRNode.LOOP, IRNode.CALL}) // Not applied + @IR(applyIfOr = {"TLABRefillWasteFraction", "99", "TLABRefillWasteFraction", "100"}, failOn = {IRNode.LOOP, IRNode.CALL}) // Not applied public void good1() { forceInline(); } @Test @IR(failOn = {IRNode.STORE, IRNode.CALL}) - @IR(applyIfNot = {"SuspendRetryCount", "20"}, failOn = {IRNode.ALLOC}) - @IR(applyIfNot = {"SuspendRetryCount", "< 100"}, failOn = {IRNode.ALLOC_OF, "Test"}) + @IR(applyIfNot = {"TLABRefillWasteFraction", "20"}, failOn = {IRNode.ALLOC}) + @IR(applyIfNot = {"TLABRefillWasteFraction", "< 100"}, failOn = {IRNode.ALLOC_OF, "Test"}) public void good2() { forceInline(); } @Test @IR(failOn = {IRNode.STORE_OF_CLASS, "Test", IRNode.CALL}) - @IR(applyIfNot = {"SuspendRetryCount", "20"}, failOn = {IRNode.ALLOC}) - @IR(applyIfNot = {"SuspendRetryCount", "< 100"}, failOn = {IRNode.ALLOC_OF, "Test"}) + @IR(applyIfNot = {"TLABRefillWasteFraction", "20"}, failOn = {IRNode.ALLOC}) + @IR(applyIfNot = {"TLABRefillWasteFraction", "< 100"}, failOn = {IRNode.ALLOC_OF, "Test"}) public void good3() { forceInline(); } @@ -460,59 +460,59 @@ public void fail10() { private void dontInline() {} } -// Called with -XX:SuspendRetryCount=X. +// Called with -XX:TLABRefillWasteFraction=X. class FlagComparisons { - // Applies all IR rules if SuspendRetryCount=50 - @Test - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "50"}) // Index 0 - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "=50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "= 50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " = 50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<=50"}) // Index 4 - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<= 50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " <= 50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", ">=50"}) // Index 7 - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", ">= 50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " >= 50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", ">49"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "> 49"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " > 49"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<51"}) // Index 13 - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "< 51"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " < 51"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!=51"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!= 51"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " != 51"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!=49"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!= 49"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " != 49"}) // Index 21 + // Applies all IR rules if TLABRefillWasteFraction=50 + @Test + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "50"}) // Index 0 + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "=50"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "= 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " = 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<=50"}) // Index 4 + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<= 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " <= 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">=50"}) // Index 7 + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">= 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " >= 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">49"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "> 49"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " > 49"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<51"}) // Index 13 + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "< 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " < 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!=51"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!= 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " != 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!=49"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!= 49"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " != 49"}) // Index 21 public void testMatchAllIf50() {} - // Applies no IR rules if SuspendRetryCount=50 - @Test - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "49"}) // Index 0 - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "=49"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "= 49"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " = 49"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "51"}) // Index 4 - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "=51"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "= 51"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " = 51"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<=49"}) // Index 8 - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<= 49"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " <= 49"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", ">=51"}) // Index 11 - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", ">= 51"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " >= 51"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", ">50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "> 50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " > 50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "<50"}) // Index 17 - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "< 50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " < 50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!=50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", "!= 50"}) - @IR(failOn = IRNode.CALL, applyIf = {"SuspendRetryCount", " != 50"}) // Index 22 + // Applies no IR rules if TLABRefillWasteFraction=50 + @Test + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "49"}) // Index 0 + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "=49"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "= 49"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " = 49"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "51"}) // Index 4 + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "=51"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "= 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " = 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<=49"}) // Index 8 + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<= 49"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " <= 49"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">=51"}) // Index 11 + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">= 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " >= 51"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", ">50"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "> 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " > 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<50"}) // Index 17 + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "< 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " < 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!=50"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "!= 50"}) + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", " != 50"}) // Index 22 public void testMatchNoneIf50() {} } diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestSanity.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestSanity.java index 4cf6923ed56..582f80c994b 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestSanity.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestSanity.java @@ -37,13 +37,13 @@ public static void main(String[] args) { TestFramework.run(); TestFramework.run(TestSanity.class); TestFramework.runWithFlags("-XX:+TieredCompilation"); - new TestFramework().addFlags("-XX:SuspendRetryCount=51", "-XX:+UseTLAB").start(); - new TestFramework(TestSanity.class).addFlags("-XX:SuspendRetryCount=51", "-XX:+UseTLAB").start(); + new TestFramework().addFlags("-XX:TLABRefillWasteFraction=51", "-XX:+UseTLAB").start(); + new TestFramework(TestSanity.class).addFlags("-XX:TLABRefillWasteFraction=51", "-XX:+UseTLAB").start(); new TestFramework().addHelperClasses(HelperA.class).start(); new TestFramework(TestSanity.class).addHelperClasses(HelperA.class, HelperB.class).start(); Scenario sDefault = new Scenario(0); - Scenario s1 = new Scenario(1, "-XX:SuspendRetryCount=52", "-XX:+UseTLAB"); - Scenario s2 = new Scenario(2, "-XX:SuspendRetryCount=53", "-XX:+UseTLAB"); + Scenario s1 = new Scenario(1, "-XX:TLABRefillWasteFraction=52", "-XX:+UseTLAB"); + Scenario s2 = new Scenario(2, "-XX:TLABRefillWasteFraction=53", "-XX:+UseTLAB"); new TestFramework(TestSanity.class).addScenarios(s1).start(); new TestFramework().addScenarios(s1, s2).start(); new TestFramework(TestSanity.class).addScenarios(s1, s2).start(); @@ -53,9 +53,9 @@ public static void main(String[] args) { new TestFramework(TestSanity.class).addScenarios(sDefault, s1, s2).start(); TestFramework testFramework = new TestFramework(); testFramework.start(); - testFramework.addFlags("-XX:SuspendRetryCount=54").start(); + testFramework.addFlags("-XX:TLABRefillWasteFraction=54").start(); testFramework = new TestFramework(); - testFramework.addFlags("-XX:SuspendRetryCount=55").addFlags("-XX:+UseTLAB").start(); + testFramework.addFlags("-XX:TLABRefillWasteFraction=55").addFlags("-XX:+UseTLAB").start(); testFramework = new TestFramework(); testFramework.addHelperClasses(HelperA.class, HelperB.class).start(); testFramework = new TestFramework(); diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java index c6680fc408c..bc8217cb7d2 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java @@ -37,10 +37,10 @@ public class TestScenarios { public static void main(String[] args) { Scenario sDefault = new Scenario(0); - Scenario s1 = new Scenario(1, "-XX:SuspendRetryCount=51"); - Scenario s2 = new Scenario(2, "-XX:SuspendRetryCount=52"); - Scenario s3 = new Scenario(3, "-XX:SuspendRetryCount=53"); - Scenario s3dup = new Scenario(3, "-XX:SuspendRetryCount=53"); + Scenario s1 = new Scenario(1, "-XX:TLABRefillWasteFraction=51"); + Scenario s2 = new Scenario(2, "-XX:TLABRefillWasteFraction=52"); + Scenario s3 = new Scenario(3, "-XX:TLABRefillWasteFraction=53"); + Scenario s3dup = new Scenario(3, "-XX:TLABRefillWasteFraction=53"); try { new TestFramework().addScenarios(sDefault, s1, s2, s3).start(); Asserts.fail("Should not reach"); @@ -74,20 +74,20 @@ public static void main(String[] args) { } @Test - @IR(applyIf = {"SuspendRetryCount", "50"}, counts = {IRNode.CALL, "1"}) + @IR(applyIf = {"TLABRefillWasteFraction", "64"}, counts = {IRNode.CALL, "1"}) public void failDefault() { } @Test - @IR(applyIf = {"SuspendRetryCount", "51"}, counts = {IRNode.CALL, "1"}) - @IR(applyIf = {"SuspendRetryCount", "53"}, counts = {IRNode.CALL, "1"}) + @IR(applyIf = {"TLABRefillWasteFraction", "51"}, counts = {IRNode.CALL, "1"}) + @IR(applyIf = {"TLABRefillWasteFraction", "53"}, counts = {IRNode.CALL, "1"}) public void failS3() { } } class ScenarioTest { @Test - @IR(applyIf = {"SuspendRetryCount", "54"}, counts = {IRNode.CALL, "1"}) + @IR(applyIf = {"TLABRefillWasteFraction", "54"}, counts = {IRNode.CALL, "1"}) public void doesNotFail() { } } From f59b7e2a20235810e1495a0b8845ecd94c90ae73 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 2 Jun 2021 10:46:38 +0200 Subject: [PATCH 125/131] Fix tests (imports, conversion mistakes etc.) --- .../valhalla/inlinetypes/InlineTypes.java | 4 +- .../valhalla/inlinetypes/MyValue1.java | 8 +- .../valhalla/inlinetypes/MyValue2.java | 4 +- .../valhalla/inlinetypes/MyValue3.java | 4 +- .../valhalla/inlinetypes/MyValue4.java | 2 +- .../valhalla/inlinetypes/TestArrays.java | 11 +- .../inlinetypes/TestBasicFunctionality.java | 2 +- .../compiler/valhalla/inlinetypes/TestC1.java | 6 +- .../inlinetypes/TestCallingConvention.java | 11 +- .../inlinetypes/TestCallingConventionC1.java | 2 +- .../inlinetypes/TestGetfieldChains.java | 6 +- .../valhalla/inlinetypes/TestIntrinsics.java | 2 +- .../valhalla/inlinetypes/TestJNICalls.java | 2 +- .../valhalla/inlinetypes/TestLWorld.java | 173 +++++++++--------- .../inlinetypes/TestLWorldProfiling.java | 11 +- .../inlinetypes/TestMethodHandles.java | 15 +- .../inlinetypes/TestNullableArrays.java | 2 +- .../inlinetypes/TestNullableInlineTypes.java | 19 +- .../inlinetypes/TestOnStackReplacement.java | 8 +- .../TestUnloadedInlineTypeField.java | 8 +- 20 files changed, 156 insertions(+), 144 deletions(-) diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java index 69e84cf52e0..c2b0934e418 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypes.java @@ -24,8 +24,8 @@ package compiler.valhalla.inlinetypes; import jdk.test.lib.Utils; -import jdk.test.lib.hotspot.ir_framework.Scenario; -import jdk.test.lib.hotspot.ir_framework.TestFramework; +import compiler.lib.ir_framework.Scenario; +import compiler.lib.ir_framework.TestFramework; public class InlineTypes { public static final int rI = Utils.getRandomInstance().nextInt() % 1000; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java index ff90b6bc413..4634e9e8b89 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue1.java @@ -23,10 +23,10 @@ package compiler.valhalla.inlinetypes; -import jdk.test.lib.hotspot.ir_framework.DontCompile; -import jdk.test.lib.hotspot.ir_framework.DontInline; -import jdk.test.lib.hotspot.ir_framework.ForceCompileClassInitializer; -import jdk.test.lib.hotspot.ir_framework.ForceInline; +import compiler.lib.ir_framework.DontCompile; +import compiler.lib.ir_framework.DontInline; +import compiler.lib.ir_framework.ForceCompileClassInitializer; +import compiler.lib.ir_framework.ForceInline; @ForceCompileClassInitializer public final primitive class MyValue1 extends MyAbstract { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java index 088d43a2dc7..7496c20e0c5 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue2.java @@ -23,8 +23,8 @@ package compiler.valhalla.inlinetypes; -import jdk.test.lib.hotspot.ir_framework.DontInline; -import jdk.test.lib.hotspot.ir_framework.ForceInline; +import compiler.lib.ir_framework.DontInline; +import compiler.lib.ir_framework.ForceInline; final primitive class MyValue2Inline { final double d; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java index 315c16d8746..4b6ef9df780 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue3.java @@ -25,8 +25,8 @@ import jdk.test.lib.Asserts; import jdk.test.lib.Utils; -import jdk.test.lib.hotspot.ir_framework.DontInline; -import jdk.test.lib.hotspot.ir_framework.ForceInline; +import compiler.lib.ir_framework.DontInline; +import compiler.lib.ir_framework.ForceInline; final primitive class MyValue3Inline { final float f7; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java index 9d6ad6c1005..a0e7ad47e68 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/MyValue4.java @@ -23,7 +23,7 @@ package compiler.valhalla.inlinetypes; -import jdk.test.lib.hotspot.ir_framework.ForceInline; +import compiler.lib.ir_framework.ForceInline; // Inline type definition with too many fields to return in registers final primitive class MyValue4 extends MyAbstract { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java index 18c3c63d4e4..a0a639ce3d3 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestArrays.java @@ -23,16 +23,17 @@ package compiler.valhalla.inlinetypes; +import compiler.lib.ir_framework.*; import jdk.test.lib.Asserts; -import java.lang.invoke.*; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.lang.reflect.Method; import java.util.Arrays; -import jdk.test.lib.hotspot.ir_framework.*; -import static compiler.valhalla.inlinetypes.InlineTypes.rI; -import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; +import static compiler.valhalla.inlinetypes.InlineTypes.*; /* * @test diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java index 550be798671..505ccb14224 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestBasicFunctionality.java @@ -23,8 +23,8 @@ package compiler.valhalla.inlinetypes; +import compiler.lib.ir_framework.*; import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; import java.lang.reflect.Method; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java index 3c6e57ed02d..5a8d03bf8af 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java @@ -23,8 +23,12 @@ package compiler.valhalla.inlinetypes; +import compiler.lib.ir_framework.CompLevel; +import compiler.lib.ir_framework.Run; +import compiler.lib.ir_framework.Scenario; +import compiler.lib.ir_framework.Test; import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; + import static compiler.valhalla.inlinetypes.InlineTypes.rI; import static compiler.valhalla.inlinetypes.InlineTypes.rL; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java index 672a06eb7f1..139b469b19e 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConvention.java @@ -23,16 +23,16 @@ package compiler.valhalla.inlinetypes; +import compiler.lib.ir_framework.*; import jdk.test.lib.Asserts; -import java.lang.invoke.*; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.lang.reflect.Method; -import jdk.test.lib.hotspot.ir_framework.*; -import static compiler.valhalla.inlinetypes.InlineTypes.rI; -import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; +import static compiler.valhalla.inlinetypes.InlineTypes.*; /* * @test @@ -45,7 +45,6 @@ @ForceCompileClassInitializer public class TestCallingConvention { - case 4: return new String[] {"-XX:-UseTLAB"}; static { try { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java index 2b6b13b87d3..05b2f27cf43 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestCallingConventionC1.java @@ -23,8 +23,8 @@ package compiler.valhalla.inlinetypes; +import compiler.lib.ir_framework.*; import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; import sun.hotspot.WhiteBox; import static compiler.valhalla.inlinetypes.InlineTypes.rI; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java index 7765efe7ffc..d2183100fea 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java @@ -23,8 +23,12 @@ package compiler.valhalla.inlinetypes; +import compiler.lib.ir_framework.CompLevel; +import compiler.lib.ir_framework.Run; +import compiler.lib.ir_framework.Scenario; +import compiler.lib.ir_framework.Test; import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; + /* * @test diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java index 4524b96bfe2..e8e6e09b985 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestIntrinsics.java @@ -25,7 +25,7 @@ import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; +import compiler.lib.ir_framework.*; import java.lang.reflect.Array; import java.lang.reflect.Field; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java index b08466eb02b..7e39353ebab 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestJNICalls.java @@ -24,7 +24,7 @@ package compiler.valhalla.inlinetypes; import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; +import compiler.lib.ir_framework.*; import static compiler.valhalla.inlinetypes.InlineTypes.rI; import static compiler.valhalla.inlinetypes.InlineTypes.rL; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java index e4165483034..3fdfb211963 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java @@ -23,18 +23,18 @@ package compiler.valhalla.inlinetypes; -import java.lang.invoke.*; +import compiler.lib.ir_framework.*; +import jdk.test.lib.Asserts; +import test.java.lang.invoke.lib.InstructionHelper; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.lang.reflect.Method; import java.util.Arrays; -import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; -import static compiler.valhalla.inlinetypes.InlineTypes.rI; -import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; - -import test.java.lang.invoke.lib.InstructionHelper; +import static compiler.valhalla.inlinetypes.InlineTypes.*; /* * @test @@ -55,7 +55,7 @@ public static void main(String[] args) { // Make sure Test141Value is linked but not initialized Class class2 = Test141Value.class; class2.getDeclaredFields(); - + Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS; scenarios[2].addFlags("-DVerifyIR=false"); scenarios[3].addFlags("-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1"); @@ -101,7 +101,7 @@ public MyValue1 test1_inline2(Object o) { return (MyValue1)o; } - @Test() + @Test public MyValue1 test1() { MyValue1 vt = testValue1; vt = (MyValue1)test1_dontinline1(vt); @@ -145,7 +145,7 @@ public Object readStaticValueField4() { return (Object)staticValueField4; } - @Test() + @Test public long test2(MyValue1 vt1, Object vt2) { objectField1 = vt1; objectField2 = (MyValue1)vt2; @@ -178,7 +178,7 @@ public void test2_verifier() { } // Test merging inline types and objects - @Test() + @Test public Object test3(int state) { Object res = null; if (state == 0) { @@ -224,7 +224,7 @@ public void test3_verifier() { } // Test merging inline types and objects in loops - @Test() + @Test public Object test4(int iters) { Object res = Integer.valueOf(rI); for (int i = 0; i < iters; ++i) { @@ -384,7 +384,7 @@ public MyValue1 test11_inline2(MyInterface o) { return (MyValue1)o; } - @Test() + @Test public MyValue1 test11() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); vt = (MyValue1)test11_dontinline1(vt); @@ -417,7 +417,7 @@ public MyInterface readStaticValueField4AsInterface() { return (MyInterface)staticValueField4; } - @Test() + @Test public long test12(MyValue1 vt1, MyInterface vt2) { interfaceField1 = vt1; interfaceField2 = (MyValue1)vt2; @@ -463,7 +463,7 @@ public long hash() { } // Test merging inline types and interfaces - @Test() + @Test public MyInterface test13(int state) { MyInterface res = null; if (state == 0) { @@ -501,7 +501,7 @@ public void test13_verifier() { } // Test merging inline types and interfaces in loops - @Test() + @Test public MyInterface test14(int iters) { MyInterface res = new MyObject1(rI); for (int i = 0; i < iters; ++i) { @@ -646,7 +646,7 @@ public void test20_verifier() { private static final Integer[] testIntegerArray = new Integer[42]; // Test load from (flattened) inline type array disguised as object array - @Test() + @Test public Object test21(Object[] oa, int index) { return oa[index]; } @@ -658,7 +658,7 @@ public void test21_verifier() { } // Test load from (flattened) inline type array disguised as interface array - @Test() + @Test public Object test22Interface(MyInterface[] ia, int index) { return ia[index]; } @@ -670,7 +670,7 @@ public void test22Interface_verifier() { } // Test load from (flattened) inline type array disguised as abstract array - @Test() + @Test public Object test22Abstract(MyAbstract[] ia, int index) { return ia[index]; } @@ -687,7 +687,7 @@ public void test23_inline(Object[] oa, Object o, int index) { oa[index] = o; } - @Test() + @Test public void test23(Object[] oa, MyValue1 vt, int index) { test23_inline(oa, vt, index); } @@ -713,7 +713,7 @@ public void test24_inline(Object[] oa, Object o, int index) { oa[index] = o; } - @Test() + @Test public void test24(Object[] oa, MyValue1 vt, int index) { test24_inline(oa, vt, index); } @@ -734,7 +734,7 @@ public void test25_inline(Object[] oa, Object o, int index) { oa[index] = o; } - @Test() + @Test public void test25(Object[] oa, MyValue1 vt, int index) { test25_inline(oa, vt, index); } @@ -756,7 +756,7 @@ public void test26Interface_inline(MyInterface[] ia, MyInterface i, int index) { ia[index] = i; } - @Test() + @Test public void test26Interface(MyInterface[] ia, MyValue1 vt, int index) { test26Interface_inline(ia, vt, index); } @@ -782,7 +782,7 @@ public void test27Interface_inline(MyInterface[] ia, MyInterface i, int index) { ia[index] = i; } - @Test() + @Test public void test27Interface(MyInterface[] ia, MyValue1 vt, int index) { test27Interface_inline(ia, vt, index); } @@ -804,7 +804,7 @@ public void test26Abstract_inline(MyAbstract[] ia, MyAbstract i, int index) { ia[index] = i; } - @Test() + @Test public void test26Abstract(MyAbstract[] ia, MyValue1 vt, int index) { test26Abstract_inline(ia, vt, index); } @@ -830,7 +830,7 @@ public void test27Abstract_inline(MyAbstract[] ia, MyAbstract i, int index) { ia[index] = i; } - @Test() + @Test public void test27Abstract(MyAbstract[] ia, MyValue1 vt, int index) { test27Abstract_inline(ia, vt, index); } @@ -852,7 +852,7 @@ public void test28_inline(Object[] oa, Object o, int index) { oa[index] = o; } - @Test() + @Test public void test28(Object[] oa, Object o, int index) { test28_inline(oa, o, index); } @@ -878,7 +878,7 @@ public void test29_inline(Object[] oa, Object o, int index) { oa[index] = o; } - @Test() + @Test public void test29(Object[] oa, Object o, int index) { test29_inline(oa, o, index); } @@ -900,7 +900,7 @@ public void test30_inline(Object[] oa, Object o, int index) { oa[index] = o; } - @Test() + @Test public void test30(Object[] oa, Object o, int index) { test30_inline(oa, o, index); } @@ -922,7 +922,7 @@ public void test31Interface_inline(MyInterface[] ia, MyInterface i, int index) { ia[index] = i; } - @Test() + @Test public void test31Interface(MyInterface[] ia, MyInterface i, int index) { test31Interface_inline(ia, i, index); } @@ -948,7 +948,7 @@ public void test32Interface_inline(MyInterface[] ia, MyInterface i, int index) { ia[index] = i; } - @Test() + @Test public void test32Interface(MyInterface[] ia, MyInterface i, int index) { test32Interface_inline(ia, i, index); } @@ -970,7 +970,7 @@ public void test31Abstract_inline(MyAbstract[] ia, MyAbstract i, int index) { ia[index] = i; } - @Test() + @Test public void test31Abstract(MyAbstract[] ia, MyAbstract i, int index) { test31Abstract_inline(ia, i, index); } @@ -996,7 +996,7 @@ public void test32Abstract_inline(MyAbstract[] ia, MyAbstract i, int index) { ia[index] = i; } - @Test() + @Test public void test32Abstract(MyAbstract[] ia, MyAbstract i, int index) { test32Abstract_inline(ia, i, index); } @@ -1018,7 +1018,7 @@ public void test33_inline(Object[] oa, Object o, int index) { oa[index] = o; } - @Test() + @Test public void test33(Object[] oa, Object o, int index) { test33_inline(oa, o, index); } @@ -1042,7 +1042,7 @@ public void test34_inline(Object[] oa, Object o, int index) { oa[index] = o; } - @Test() + @Test public void test34(Object[] oa, int index) { test34_inline(oa, null, index); } @@ -1073,7 +1073,7 @@ public void test34_verifier() { return_(); }); - @Test() + @Test public void test35(MyValue1[] va, int index) throws Throwable { setArrayElementNull.invoke(this, va, index); } @@ -1091,7 +1091,7 @@ public void test35_verifier() throws Throwable { } // Test writing an inline type to a null inline type array - @Test() + @Test public void test36(MyValue1[] va, MyValue1 vt, int index) { va[index] = vt; } @@ -1113,7 +1113,7 @@ public void test37_inline(Object[] oa, Object o, int index) { oa[index] = o; } - @Test() + @Test public void test37(MyValue1[] va, Object o, int index) { test37_inline(va, o, index); } @@ -1141,7 +1141,7 @@ public Object[] test38_inline() { return new MyValue1[42]; } - @Test() + @Test public Object[] test38(Object[] oa, Object o, int i1, int i2, int num) { Object[] result = null; switch (num) { @@ -1213,7 +1213,7 @@ public Object test39_inline() { } // Same as above but merging into Object instead of Object[] - @Test() + @Test public Object test39(Object oa, Object o, int i1, int i2, int num) { Object result = null; switch (num) { @@ -1298,7 +1298,7 @@ public void test39_verifier() { } // Test instanceof with inline types and arrays - @Test() + @Test public long test40(Object o, int index) { if (o instanceof MyValue1) { return ((MyValue1)o).hashInterpreted(); @@ -1339,7 +1339,7 @@ public void test41_dontinline(Object o) { Asserts.assertEQ(o, rI); } - @Test() + @Test public void test41() { MyValue1[] vals = new MyValue1[] {testValue1}; test41_dontinline(vals[0].oa[0]); @@ -1355,7 +1355,7 @@ public void test41_verifier() { private static final MyValue1.ref test42VT1 = MyValue1.createWithFieldsInline(rI, rL); private static final MyValue1.ref test42VT2 = MyValue1.createWithFieldsInline(rI + 1, rL + 1); - @Test() + @Test public void test42() { MyValue1[] vals = new MyValue1[] {(MyValue1) test42VT1, (MyValue1) test42VT2}; Asserts.assertEQ(vals[0].hash(), test42VT1.hash()); @@ -1368,7 +1368,7 @@ public void test42_verifier(RunInfo info) { } // Test for bug in Escape Analysis - @Test() + @Test public long test43(boolean deopt, Method m) { MyValue1[] vals = new MyValue1[] {(MyValue1) test42VT1, (MyValue1) test42VT2}; @@ -1400,7 +1400,7 @@ public void test43_verifier(RunInfo info) { return_(); }); - @Test() + @Test public void test44(MyValue1[] va, int index, MyValue2 v) throws Throwable { setArrayElementIncompatible.invoke(this, va, index, v); } @@ -1423,7 +1423,7 @@ public void test45_inline(Object[] oa, Object o, int index) { oa[index] = o; } - @Test() + @Test public void test45(MyValue1[] va, int index, MyValue2 v) throws Throwable { test45_inline(va, v, index); } @@ -1581,7 +1581,7 @@ public long test(Test51Value holder, MyValue1 vt1, Object vt2) { } // Same as test2 but with field holder being an inline type - @Test() + @Test public long test51(Test51Value holder, MyValue1 vt1, Object vt2) { return holder.test(holder, vt1, vt2); } @@ -1598,7 +1598,7 @@ public void test51_verifier() { } // Access non-flattened, uninitialized inline type field with inline type holder - @Test() + @Test public void test52(Test51Value holder) { if ((Object)holder.valueField5 != null) { throw new RuntimeException("Should be null"); @@ -1612,7 +1612,7 @@ public void test52_verifier() { } // Merging inline types of different types - @Test() + @Test public Object test53(Object o, boolean b) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); return b ? vt : o; @@ -1625,7 +1625,7 @@ public void test53_verifier() { Asserts.assertEQ(result.hash(), hash()); } - @Test() + @Test public Object test54(boolean b) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); return b ? vt : testValue2; @@ -1639,7 +1639,7 @@ public void test54_verifier() { Asserts.assertEQ(result2.hash(), testValue2.hash()); } - @Test() + @Test public Object test55(boolean b) { MyValue1 vt1 = MyValue1.createWithFieldsInline(rI, rL); MyValue2 vt2 = MyValue2.createWithFieldsInline(rI, rD); @@ -1655,7 +1655,7 @@ public void test55_verifier() { } // Test synchronization on inline types - @Test() + @Test public void test56(Object vt) { synchronized (vt) { throw new RuntimeException("test56 failed: synchronization on inline type should not succeed"); @@ -1679,7 +1679,7 @@ public void test57_inline(Object vt) { } } - @Test() + @Test public void test57(MyValue1 vt) { test57_inline(vt); } @@ -1701,7 +1701,7 @@ public void test58_inline(Object vt) { } } - @Test() + @Test public void test58() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); test58_inline(vt); @@ -1717,7 +1717,7 @@ public void test58_verifier() { } } - @Test() + @Test public void test59(Object o, boolean b) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); Object sync = b ? vt : o; @@ -1739,7 +1739,7 @@ public void test59_verifier() { } } - @Test() + @Test public void test60(boolean b) { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); Object sync = b ? vt : testValue2; @@ -1765,7 +1765,7 @@ public void test60_verifier() { } // Test catching the IllegalMonitorStateException in compiled code - @Test() + @Test public void test61(Object vt) { boolean thrown = false; try { @@ -1785,7 +1785,7 @@ public void test61_verifier() { test61(testValue1); } - @Test() + @Test public void test62(Object o) { try { synchronized (o) { } @@ -1802,7 +1802,7 @@ public void test62_verifier() { } // Test synchronization without any instructions in the synchronized block - @Test() + @Test public void test63(Object o) { synchronized (o) { } } @@ -1824,7 +1824,7 @@ public MyInterface test64Interface_helper(MyValue1 vt) { return vt; } - @Test() + @Test public MyInterface test64Interface(MyValue1 vt) { return test64Interface_helper(vt); } @@ -1840,7 +1840,7 @@ public MyAbstract test64Abstract_helper(MyValue1 vt) { return vt; } - @Test() + @Test public MyAbstract test64Abstract(MyValue1 vt) { return test64Abstract_helper(vt); } @@ -1851,7 +1851,7 @@ public void test64Abstract_verifier() { } // Array store tests - @Test() + @Test public void test65(Object[] array, MyValue1 vt) { array[0] = vt; } @@ -1863,7 +1863,7 @@ public void test65_verifier() { Asserts.assertEQ(((MyValue1)array[0]).hash(), testValue1.hash()); } - @Test() + @Test public void test66(Object[] array, MyValue1 vt) { array[0] = vt; } @@ -1875,7 +1875,7 @@ public void test66_verifier() { Asserts.assertEQ(array[0].hash(), testValue1.hash()); } - @Test() + @Test public void test67(Object[] array, Object vt) { array[0] = vt; } @@ -1887,7 +1887,7 @@ public void test67_verifier() { Asserts.assertEQ(array[0].hash(), testValue1.hash()); } - @Test() + @Test public void test68(Object[] array, Integer o) { array[0] = o; } @@ -2574,7 +2574,7 @@ public MyValue1 test97_inline2(MyAbstract o) { return (MyValue1)o; } - @Test() + @Test public MyValue1 test97() { MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL); vt = (MyValue1)test97_dontinline1(vt); @@ -2607,7 +2607,7 @@ public MyAbstract readStaticValueField4AsAbstract() { return (MyAbstract)staticValueField4; } - @Test() + @Test public long test98(MyValue1 vt1, MyAbstract vt2) { abstractField1 = vt1; abstractField2 = (MyValue1)vt2; @@ -2653,7 +2653,7 @@ public long hash() { } // Test merging inline types and abstract classes - @Test() + @Test public MyAbstract test99(int state) { MyAbstract res = null; if (state == 0) { @@ -2691,7 +2691,7 @@ public void test99_verifier() { } // Test merging inline types and abstract classes in loops - @Test() + @Test public MyAbstract test100(int iters) { MyAbstract res = new MyObject2(rI); for (int i = 0; i < iters; ++i) { @@ -3424,7 +3424,7 @@ public void test121_verifier() { } // Verify that empty inline type field loads check for null holder - @Test() + @Test public MyValueEmpty test122(TestLWorld t) { return t.fEmpty3; } @@ -3442,7 +3442,7 @@ public void test122_verifier() { } // Verify that empty inline type field stores check for null holder - @Test() + @Test public void test123(TestLWorld t) { t.fEmpty3 = MyValueEmpty.default; } @@ -3617,7 +3617,7 @@ public Object test130_inlinee() { return MyValue1.createWithFieldsInline(rI, rL); } - @Test() + @Test public void test130() { Object obj = test130_inlinee(); synchronized (obj) { @@ -3641,7 +3641,7 @@ public Object test131_inlinee() { return testValue1; } - @Test() + @Test public void test131() { Object obj = test131_inlinee(); synchronized (obj) { @@ -3660,7 +3660,7 @@ public void test131_verifier() { } // Test locking on object that is known to be an inline type only after CCP - @Test() + @Test public void test132() { MyValue2 vt = MyValue2.createWithFieldsInline(rI, rD); Object obj = Integer.valueOf(42); @@ -3687,7 +3687,7 @@ public void test132_verifier() { } // Test conditional locking on inline type and non-escaping object - @Test() + @Test public void test133(boolean b) { Object obj = b ? Integer.valueOf(42) : MyValue2.createWithFieldsInline(rI, rD); synchronized (obj) { @@ -3709,7 +3709,7 @@ public void test133_verifier() { } // Variant with non-scalarized inline type - @Test() + @Test public static void test134(boolean b) { Object obj = null; if (b) { @@ -3809,14 +3809,15 @@ static primitive class Test139Wrapper { Test139Value value = Test139Value.default; } - @Test(failOn = ALLOC + LOAD + STORE + TRAP) + @Test + @IR(failOn = {ALLOC, LOAD, STORE, TRAP}) public MyValueEmpty test139() { Test139Wrapper w = new Test139Wrapper(); return w.value.empty; } - @DontCompile - public void test139_verifier(boolean warmup) { + @Run(test = "test139") + public void test139_verifier() { MyValueEmpty empty = test139(); Asserts.assertEquals(empty, MyValueEmpty.default); } @@ -3830,14 +3831,14 @@ public int get() { } @Test - @Warmup(0) public int test140() { Test140Value vt = Test140Value.default; return vt.get(); } - @DontCompile - public void test140_verifier(boolean warmup) { + @Run(test = "test140") + @Warmup(0) + public void test140_verifier() { int result = test140(); Asserts.assertEquals(result, 0); } @@ -3851,14 +3852,14 @@ public int get() { } @Test - @Warmup(0) public int test141() { Test141Value vt = Test141Value.default; return vt.get(); } - @DontCompile - public void test141_verifier(boolean warmup) { + @Run(test = "test141") + @Warmup(0) + public void test141_verifier() { int result = test141(); Asserts.assertEquals(result, 0); } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java index 8c645c55227..2349a0587ad 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java @@ -23,15 +23,14 @@ package compiler.valhalla.inlinetypes; -import java.lang.reflect.Method; +import compiler.lib.ir_framework.*; +import jdk.test.lib.Asserts; import sun.hotspot.WhiteBox; -import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; -import static compiler.valhalla.inlinetypes.InlineTypes.rI; -import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; +import java.lang.reflect.Method; + import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; +import static compiler.valhalla.inlinetypes.InlineTypes.*; /* * @test diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java index 2b63160cc1a..3263c9936a8 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMethodHandles.java @@ -23,16 +23,17 @@ package compiler.valhalla.inlinetypes; -import java.lang.invoke.*; -import java.lang.reflect.Method; +import compiler.lib.ir_framework.*; +import jdk.test.lib.Asserts; import sun.hotspot.WhiteBox; -import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; -import static compiler.valhalla.inlinetypes.InlineTypes.rI; -import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Method; + import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; +import static compiler.valhalla.inlinetypes.InlineTypes.*; /* * @test diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java index 28b43911ad3..2b00bcbdec2 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableArrays.java @@ -24,7 +24,7 @@ package compiler.valhalla.inlinetypes; import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; +import compiler.lib.ir_framework.*; import static compiler.valhalla.inlinetypes.InlineTypes.rI; import static compiler.valhalla.inlinetypes.InlineTypes.rL; import static compiler.valhalla.inlinetypes.InlineTypes.rD; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java index 36977f34edf..3c124f28943 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java @@ -23,15 +23,18 @@ package compiler.valhalla.inlinetypes; -import java.lang.invoke.*; +import compiler.lib.ir_framework.*; +import jdk.test.lib.Asserts; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.lang.reflect.Method; -import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.ALLOC; +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.STORE; import static compiler.valhalla.inlinetypes.InlineTypes.rI; import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; -import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; /* * @test @@ -966,14 +969,14 @@ public void test39_verifier() { } // Test NPE when casting constant null to inline type - @Test() + @Test public MyValue1 test40() throws Throwable { Object NULL = null; return (MyValue1)NULL; } - @DontCompile - public void test40_verifier(boolean warmup) throws Throwable { + @Run(test = "test40") + public void test40_verifier() throws Throwable { try { test40(); throw new RuntimeException("NullPointerException expected"); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java index a696dffa80d..70264011080 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestOnStackReplacement.java @@ -23,14 +23,12 @@ package compiler.valhalla.inlinetypes; +import compiler.lib.ir_framework.*; import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; + +import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; import static compiler.valhalla.inlinetypes.InlineTypes.rI; import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; -import static compiler.valhalla.inlinetypes.InlineTypes.IRNode.*; - -import java.lang.reflect.Method; /* * @test diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java index 27b2e58ebfb..cc741cdef9d 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java @@ -23,11 +23,13 @@ package compiler.valhalla.inlinetypes; +import compiler.lib.ir_framework.Run; +import compiler.lib.ir_framework.RunInfo; +import compiler.lib.ir_framework.Scenario; +import compiler.lib.ir_framework.Test; import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; + import static compiler.valhalla.inlinetypes.InlineTypes.rI; -import static compiler.valhalla.inlinetypes.InlineTypes.rL; -import static compiler.valhalla.inlinetypes.InlineTypes.rD; /* * @test From c6932b140693d71cc225000dd6e88fae4b6ef7a7 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 4 Jun 2021 11:55:58 +0200 Subject: [PATCH 126/131] Fix converted tests --- .../valhalla/inlinetypes/InlineTypeTest.java | 860 ------------------ .../valhalla/inlinetypes/TestLWorld.java | 2 +- .../valhalla/inlinetypes/TestNewAcmp.java | 4 +- .../TestUnloadedInlineTypeField.java | 2 +- .../valhalla/inlinetypes/TestWithfieldC1.java | 2 +- 5 files changed, 6 insertions(+), 864 deletions(-) delete mode 100644 test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypeTest.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypeTest.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypeTest.java deleted file mode 100644 index d4516a4fd34..00000000000 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/InlineTypeTest.java +++ /dev/null @@ -1,860 +0,0 @@ -/* - * Copyright (c) 2017, 2020, 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.valhalla.inlinetypes; - -import compiler.whitebox.CompilerWhiteBoxTest; -import jdk.test.lib.Asserts; -import jdk.test.lib.management.InputArguments; -import jdk.test.lib.Platform; -import jdk.test.lib.process.ProcessTools; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.Utils; -import sun.hotspot.WhiteBox; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Repeatable; -import java.lang.invoke.*; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Hashtable; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Stream; -import java.util.TreeMap; -import java.util.function.BooleanSupplier; - -// Mark method as test -@Retention(RetentionPolicy.RUNTIME) -@Repeatable(Tests.class) -@interface Test { - // Regular expression used to match forbidden IR nodes - // in the C2 IR emitted for this test. - String failOn() default ""; - // Regular expressions used to match and count IR nodes. - String[] match() default { }; - int[] matchCount() default { }; - int compLevel() default InlineTypeTest.COMP_LEVEL_ANY; - int valid() default 0; -} - -@Retention(RetentionPolicy.RUNTIME) -@interface Tests { - Test[] value(); -} - -// Force method inlining during compilation -@Retention(RetentionPolicy.RUNTIME) -@interface ForceInline { } - -// Prevent method inlining during compilation -@Retention(RetentionPolicy.RUNTIME) -@interface DontInline { } - -// Prevent method compilation -@Retention(RetentionPolicy.RUNTIME) -@interface DontCompile { } - -// Force method compilation -@Retention(RetentionPolicy.RUNTIME) -@interface ForceCompile { - int compLevel() default InlineTypeTest.COMP_LEVEL_ANY; -} - -// Number of warmup iterations -@Retention(RetentionPolicy.RUNTIME) -@interface Warmup { - int value(); -} - -// Do not enqueue the test method for compilation immediately after warmup loops have finished. Instead -// let the test method be compiled with on-stack-replacement. -@Retention(RetentionPolicy.RUNTIME) -@interface OSRCompileOnly {} - -// Skip this test temporarily for C1 testing -@Retention(RetentionPolicy.RUNTIME) -@interface TempSkipForC1 { - String reason() default ""; -} - -public abstract class InlineTypeTest { - protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); - - protected static final int COMP_LEVEL_ANY = -1; - protected static final int COMP_LEVEL_SIMPLE = 1; // C1 - protected static final int COMP_LEVEL_LIMITED_PROFILE = 2; // C1, invocation & backedge counters - protected static final int COMP_LEVEL_FULL_PROFILE = 3; // C1, invocation & backedge counters + mdo - protected static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; // C2 or JVMCI - - protected static final boolean TieredCompilation = (Boolean)WHITE_BOX.getVMFlag("TieredCompilation"); - protected static final long TieredStopAtLevel = (Long)WHITE_BOX.getVMFlag("TieredStopAtLevel"); - static final boolean TEST_C1 = TieredCompilation && TieredStopAtLevel < COMP_LEVEL_FULL_OPTIMIZATION; - - // Random test values - public static final int rI = Utils.getRandomInstance().nextInt() % 1000; - public static final long rL = Utils.getRandomInstance().nextLong() % 1000; - public static final double rD = Utils.getRandomInstance().nextDouble() % 1000; - - // User defined settings - protected static final boolean XCOMP = Platform.isComp(); - private static final boolean PRINT_GRAPH = true; - private static final boolean VERBOSE = Boolean.parseBoolean(System.getProperty("Verbose", "false")); - private static final boolean PRINT_TIMES = Boolean.parseBoolean(System.getProperty("PrintTimes", "false")); - private static final boolean COMPILE_COMMANDS = Boolean.parseBoolean(System.getProperty("CompileCommands", "true")) && !XCOMP; - private static boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true")) && !XCOMP && !TEST_C1 && COMPILE_COMMANDS; - private static final String SCENARIOS = System.getProperty("Scenarios", ""); - private static final String TESTLIST = System.getProperty("Testlist", ""); - private static final String EXCLUDELIST = System.getProperty("Exclude", ""); - private static final int WARMUP = Integer.parseInt(System.getProperty("Warmup", "251")); - private static final boolean DUMP_REPLAY = Boolean.parseBoolean(System.getProperty("DumpReplay", "false")); - private static final boolean FLIP_C1_C2 = Boolean.parseBoolean(System.getProperty("FlipC1C2", "false")); - private static final boolean GC_AFTER = Boolean.parseBoolean(System.getProperty("GCAfter", "false")); - private static final int OSR_TEST_TIMEOUT = Integer.parseInt(System.getProperty("OSRTestTimeOut", "5000")); - protected static final boolean STRESS_CC = Boolean.parseBoolean(System.getProperty("StressCC", "false")); - private static final boolean SHUFFLE_TESTS = Boolean.parseBoolean(System.getProperty("ShuffleTests", "true")); - private static final boolean PREFER_CL_FLAGS = Boolean.parseBoolean(System.getProperty("PreferCommandLineFlags", "false")); - - // Pre-defined settings - private static final String[] defaultFlags = { - "-XX:-BackgroundCompilation"}; - private static final String[] compileCommandFlags = { - "-XX:CompileCommand=quiet", - "-XX:CompileCommand=compileonly,java.lang.invoke.*::*", - "-XX:CompileCommand=compileonly,java.lang.Long::sum", - "-XX:CompileCommand=compileonly,java.lang.Object::", - "-XX:CompileCommand=inline,compiler.valhalla.inlinetypes.MyValue*::", - "-XX:CompileCommand=compileonly,compiler.valhalla.inlinetypes.*::*"}; - private static final String[] printFlags = { - "-XX:+PrintCompilation", "-XX:+PrintIdeal", "-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintOptoAssembly"}; - - protected static final int InlineTypePassFieldsAsArgsOn = 0x1; - protected static final int InlineTypePassFieldsAsArgsOff = 0x2; - protected static final int InlineTypeArrayFlattenOn = 0x4; - protected static final int InlineTypeArrayFlattenOff = 0x8; - protected static final int InlineTypeReturnedAsFieldsOn = 0x10; - protected static final int InlineTypeReturnedAsFieldsOff = 0x20; - protected static final int AlwaysIncrementalInlineOn = 0x40; - protected static final int AlwaysIncrementalInlineOff = 0x80; - protected static final int G1GCOn = 0x100; - protected static final int G1GCOff = 0x200; - protected static final int ZGCOn = 0x400; - protected static final int ZGCOff = 0x800; - protected static final int ArrayLoadStoreProfileOn = 0x1000; - protected static final int ArrayLoadStoreProfileOff = 0x2000; - protected static final int TypeProfileOn = 0x4000; - protected static final int TypeProfileOff = 0x8000; - protected static final int ACmpProfileOn = 0x10000; - protected static final int ACmpProfileOff = 0x20000; - protected static final boolean InlineTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("InlineTypePassFieldsAsArgs"); - protected static final boolean InlineTypeArrayFlatten = (WHITE_BOX.getIntxVMFlag("FlatArrayElementMaxSize") == -1); - protected static final boolean InlineTypeReturnedAsFields = (Boolean)WHITE_BOX.getVMFlag("InlineTypeReturnedAsFields"); - protected static final boolean AlwaysIncrementalInline = (Boolean)WHITE_BOX.getVMFlag("AlwaysIncrementalInline"); - protected static final boolean G1GC = (Boolean)WHITE_BOX.getVMFlag("UseG1GC"); - protected static final boolean ZGC = (Boolean)WHITE_BOX.getVMFlag("UseZGC"); - protected static final boolean VerifyOops = (Boolean)WHITE_BOX.getVMFlag("VerifyOops"); - protected static final boolean UseArrayLoadStoreProfile = (Boolean)WHITE_BOX.getVMFlag("UseArrayLoadStoreProfile"); - protected static final long TypeProfileLevel = (Long)WHITE_BOX.getVMFlag("TypeProfileLevel"); - protected static final boolean UseACmpProfile = (Boolean)WHITE_BOX.getVMFlag("UseACmpProfile"); - protected static final long PerMethodTrapLimit = (Long)WHITE_BOX.getVMFlag("PerMethodTrapLimit"); - protected static final boolean ProfileInterpreter = (Boolean)WHITE_BOX.getVMFlag("ProfileInterpreter"); - - protected static final Hashtable tests = new Hashtable(); - protected static final boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); - protected static final boolean PRINT_IDEAL = WHITE_BOX.getBooleanVMFlag("PrintIdeal"); - - // Regular expressions used to match nodes in the PrintIdeal output - protected static final String START = "(\\d+ (.*"; - protected static final String MID = ".*)+ ===.*"; - protected static final String END = ")|"; - // Generic allocation - protected static final String ALLOC_G = "(.*call,static wrapper for: _new_instance_Java" + END; - protected static final String ALLOCA_G = "(.*call,static wrapper for: _new_array_Java" + END; - // Inline type allocation - protected static final String ALLOC = "(.*precise klass compiler/valhalla/inlinetypes/MyValue.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_instance_Java" + END; - protected static final String ALLOCA = "(.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*\\R(.*(movl|xorl|nop|spill).*\\R)*.*_new_array_Java" + END; - protected static final String LOAD = START + "Load(B|S|I|L|F|D|P|N)" + MID + "@compiler/valhalla/inlinetypes/MyValue.*" + END; - protected static final String LOADK = START + "LoadK" + MID + END; - protected static final String STORE = START + "Store(B|C|S|I|L|F|D|P|N)" + MID + "@compiler/valhalla/inlinetypes/MyValue.*" + END; - protected static final String LOOP = START + "Loop" + MID + "" + END; - protected static final String COUNTEDLOOP = START + "CountedLoop\\b" + MID + "" + END; - protected static final String COUNTEDLOOP_MAIN = START + "CountedLoop\\b" + MID + "main" + END; - protected static final String TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*(unstable_if|predicate)" + END; - protected static final String LINKTOSTATIC = START + "CallStaticJava" + MID + "linkToStatic" + END; - protected static final String NPE = START + "CallStaticJava" + MID + "null_check" + END; - protected static final String CALL = START + "CallStaticJava" + MID + END; - protected static final String STORE_INLINE_FIELDS = START + "CallStaticJava" + MID + "store_inline_type_fields" + END; - protected static final String SCOBJ = "(.*# ScObj.*" + END; - protected static final String LOAD_UNKNOWN_INLINE = "(.*call_leaf,runtime load_unknown_inline.*" + END; - protected static final String STORE_UNKNOWN_INLINE = "(.*call_leaf,runtime store_unknown_inline.*" + END; - protected static final String INLINE_ARRAY_NULL_GUARD = "(.*call,static wrapper for: uncommon_trap.*reason='null_check' action='none'.*" + END; - protected static final String INTRINSIC_SLOW_PATH = "(.*call,static wrapper for: uncommon_trap.*reason='intrinsic_or_type_checked_inlining'.*" + END; - protected static final String CLONE_INTRINSIC_SLOW_PATH = "(.*call,static.*java.lang.Object::clone.*" + END; - protected static final String CLASS_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*class_check" + END; - protected static final String NULL_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*null_check" + END; - protected static final String NULL_ASSERT_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*null_assert" + END; - protected static final String RANGE_CHECK_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*range_check" + END; - protected static final String UNHANDLED_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*unhandled" + END; - protected static final String PREDICATE_TRAP = START + "CallStaticJava" + MID + "uncommon_trap.*predicate" + END; - protected static final String MEMBAR = START + "MemBar" + MID + END; - protected static final String CHECKCAST_ARRAY = "(cmp.*precise klass \\[(L|Q)compiler/valhalla/inlinetypes/MyValue.*" + END; - protected static final String CHECKCAST_ARRAYCOPY = "(.*call_leaf_nofp,runtime checkcast_arraycopy.*" + END; - protected static final String JLONG_ARRAYCOPY = "(.*call_leaf_nofp,runtime jlong_disjoint_arraycopy.*" + END; - protected static final String FIELD_ACCESS = "(.*Field: *" + END; - protected static final String SUBSTITUTABILITY_TEST = START + "CallStaticJava" + MID + "java.lang.invoke.ValueBootstrapMethods::isSubstitutable" + END; - - public static String[] concat(String prefix[], String... extra) { - ArrayList list = new ArrayList(); - if (prefix != null) { - for (String s : prefix) { - list.add(s); - } - } - if (extra != null) { - for (String s : extra) { - list.add(s); - } - } - - return list.toArray(new String[list.size()]); - } - - /** - * Override getNumScenarios and getVMParameters if you want to run with more than - * the 6 built-in scenarios - */ - public int getNumScenarios() { - return 6; - } - - /** - * VM parameters for the 5 built-in test scenarios. If your test needs to append - * extra parameters for (some of) these scenarios, override getExtraVMParameters(). - */ - public String[] getVMParameters(int scenario) { - switch (scenario) { - case 0: return new String[] { - "-XX:-UseACmpProfile", - "-XX:+AlwaysIncrementalInline", - "-XX:FlatArrayElementMaxOops=5", - "-XX:FlatArrayElementMaxSize=-1", - "-XX:-UseArrayLoadStoreProfile", - "-XX:InlineFieldMaxFlatSize=-1", - "-XX:+InlineTypePassFieldsAsArgs", - "-XX:+InlineTypeReturnedAsFields"}; - case 1: return new String[] { - "-XX:-UseACmpProfile", - "-XX:-UseCompressedOops", - "-XX:FlatArrayElementMaxOops=5", - "-XX:FlatArrayElementMaxSize=-1", - "-XX:-UseArrayLoadStoreProfile", - "-XX:InlineFieldMaxFlatSize=-1", - "-XX:-InlineTypePassFieldsAsArgs", - "-XX:-InlineTypeReturnedAsFields"}; - case 2: return new String[] { - "-XX:-UseACmpProfile", - "-XX:-UseCompressedOops", - "-XX:FlatArrayElementMaxOops=0", - "-XX:FlatArrayElementMaxSize=0", - "-XX:-UseArrayLoadStoreProfile", - "-XX:InlineFieldMaxFlatSize=-1", - "-XX:+InlineTypePassFieldsAsArgs", - "-XX:+InlineTypeReturnedAsFields", - "-XX:+StressInlineTypeReturnedAsFields"}; - case 3: return new String[] { - "-DVerifyIR=false", - "-XX:+AlwaysIncrementalInline", - "-XX:FlatArrayElementMaxOops=0", - "-XX:FlatArrayElementMaxSize=0", - "-XX:InlineFieldMaxFlatSize=0", - "-XX:+InlineTypePassFieldsAsArgs", - "-XX:+InlineTypeReturnedAsFields"}; - case 4: return new String[] { - "-DVerifyIR=false", - "-XX:FlatArrayElementMaxOops=-1", - "-XX:FlatArrayElementMaxSize=-1", - "-XX:InlineFieldMaxFlatSize=0", - "-XX:+InlineTypePassFieldsAsArgs", - "-XX:-InlineTypeReturnedAsFields", - "-XX:-ReduceInitialCardMarks"}; - case 5: return new String[] { - "-XX:-UseACmpProfile", - "-XX:+AlwaysIncrementalInline", - "-XX:FlatArrayElementMaxOops=5", - "-XX:FlatArrayElementMaxSize=-1", - "-XX:-UseArrayLoadStoreProfile", - "-XX:InlineFieldMaxFlatSize=-1", - "-XX:-InlineTypePassFieldsAsArgs", - "-XX:-InlineTypeReturnedAsFields"}; - } - return null; - } - - /** - * Override this method and return a non-null reason if the given scenario should be - * ignored (due to an existing bug, etc). - */ - String isScenarioIgnored(int scenario) { - return null; - } - - /** - * Override this method to provide extra parameters for selected scenarios - */ - public String[] getExtraVMParameters(int scenario) { - return null; - } - - public static void main(String[] args) throws Throwable { - if (args.length != 1) { - throw new RuntimeException("Usage: @run main/othervm/timeout=120 -Xbootclasspath/a:." + - " -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions" + - " -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI" + - " compiler.valhalla.inlinetypes.InlineTypeTest "); - } - String testMainClassName = args[0]; - Class testMainClass = Class.forName(testMainClassName); - InlineTypeTest test = (InlineTypeTest)testMainClass.newInstance(); - List scenarios = null; - if (!SCENARIOS.isEmpty()) { - scenarios = Arrays.asList(SCENARIOS.split(",")); - } - for (int i=0; i,,... - // Each case can be just the method name, or can be .. The latter form is useful - // when you are running several tests at the same time. - // - // jtreg -DExclude=test12 TestArrays.java - // jtreg -DExclude=test34 TestLWorld.java - // -- or -- - // jtreg -DExclude=TestArrays.test12,TestLWorld.test34 TestArrays.java TestLWorld.java - // - private List buildExcludeList() { - List exclude = null; - String classPrefix = getClass().getSimpleName() + "."; - if (!EXCLUDELIST.isEmpty()) { - exclude = new ArrayList(Arrays.asList(EXCLUDELIST.split(","))); - for (int i = exclude.size() - 1; i >= 0; i--) { - String ex = exclude.get(i); - if (ex.indexOf(".") > 0) { - if (ex.startsWith(classPrefix)) { - ex = ex.substring(classPrefix.length()); - exclude.set(i, ex); - } else { - exclude.remove(i); - } - } - } - } - return exclude; - } - - protected InlineTypeTest() { - List list = null; - if (!TESTLIST.isEmpty()) { - list = Arrays.asList(TESTLIST.split(",")); - } - List exclude = buildExcludeList(); - - // Gather all test methods and put them in Hashtable - for (Method m : getClass().getDeclaredMethods()) { - Test[] annos = m.getAnnotationsByType(Test.class); - if (annos.length != 0 && - ((list == null || list.contains(m.getName())) && (exclude == null || !exclude.contains(m.getName())))) { - tests.put(getClass().getSimpleName() + "::" + m.getName(), m); - } else if (annos.length == 0 && m.getName().startsWith("test")) { - try { - getClass().getMethod(m.getName() + "_verifier", boolean.class); - throw new RuntimeException(m.getName() + " has a verifier method but no @Test annotation"); - } catch (NoSuchMethodException e) { - // Expected - } - } - } - } - - protected void run(String[] args, Class... classes) throws Throwable { - if (args.length == 0) { - // Spawn a new VM instance - execute_vm(); - } else { - // Execute tests in the VM spawned by the above code. - Asserts.assertTrue(args.length == 1 && args[0].equals("run"), "must be"); - run(classes); - } - } - - private void execute_vm() throws Throwable { - Asserts.assertFalse(tests.isEmpty(), "no tests to execute"); - String[] vmInputArgs = InputArguments.getVmInputArgs(); - for (String arg : vmInputArgs) { - if (arg.startsWith("-XX:CompileThreshold")) { - // Disable IR verification if non-default CompileThreshold is set - VERIFY_IR = false; - } - } - // Each VM is launched with flags in this order, so the later ones can override the earlier one: - // VERIFY_IR flags specified below - // vmInputArgs, which consists of: - // @run options - // getVMParameters() - // getExtraVMParameters() - // defaultFlags - // compileCommandFlags - String cmds[] = null; - if (VERIFY_IR) { - // Add print flags for IR verification - cmds = concat(cmds, printFlags); - // Always trap for exception throwing to not confuse IR verification - cmds = concat(cmds, "-XX:-OmitStackTraceInFastThrow"); - } - cmds = concat(cmds, vmInputArgs); - cmds = concat(cmds, defaultFlags); - if (COMPILE_COMMANDS) { - cmds = concat(cmds, compileCommandFlags); - } - - // Run tests in own process and verify output - cmds = concat(cmds, getClass().getName(), "run"); - OutputAnalyzer oa = ProcessTools.executeTestJvm(cmds); - // If ideal graph printing is enabled/supported, verify output - String output = oa.getOutput(); - oa.shouldHaveExitValue(0); - if (VERIFY_IR) { - if (output.contains("PrintIdeal enabled")) { - parseOutput(output); - } else { - System.out.println(output); - System.out.println("WARNING: IR verification failed! Running with -Xint, -Xcomp or release build?"); - } - } - } - - static final class TestAnnotation { - private final int flag; - private final BooleanSupplier predicate; - - private static final TestAnnotation testAnnotations[] = { - new TestAnnotation(InlineTypePassFieldsAsArgsOn, () -> InlineTypePassFieldsAsArgs), - new TestAnnotation(InlineTypePassFieldsAsArgsOff, () -> !InlineTypePassFieldsAsArgs), - new TestAnnotation(InlineTypeArrayFlattenOn, () -> InlineTypeArrayFlatten), - new TestAnnotation(InlineTypeArrayFlattenOff, () -> !InlineTypeArrayFlatten), - new TestAnnotation(InlineTypeReturnedAsFieldsOn, () -> InlineTypeReturnedAsFields), - new TestAnnotation(InlineTypeReturnedAsFieldsOff, () -> !InlineTypeReturnedAsFields), - new TestAnnotation(AlwaysIncrementalInlineOn, () -> AlwaysIncrementalInline), - new TestAnnotation(AlwaysIncrementalInlineOff, () -> !AlwaysIncrementalInline), - new TestAnnotation(G1GCOn, () -> G1GC), - new TestAnnotation(G1GCOff, () -> !G1GC), - new TestAnnotation(ZGCOn, () -> ZGC), - new TestAnnotation(ZGCOff, () -> !ZGC), - new TestAnnotation(ArrayLoadStoreProfileOn, () -> UseArrayLoadStoreProfile), - new TestAnnotation(ArrayLoadStoreProfileOff, () -> !UseArrayLoadStoreProfile), - new TestAnnotation(TypeProfileOn, () -> TypeProfileLevel == 222), - new TestAnnotation(TypeProfileOff, () -> TypeProfileLevel == 0), - new TestAnnotation(ACmpProfileOn, () -> UseACmpProfile), - new TestAnnotation(ACmpProfileOff, () -> !UseACmpProfile), - }; - - private TestAnnotation(int flag, BooleanSupplier predicate) { - this.flag = flag; - this.predicate = predicate; - } - - private boolean match(Test a) { - return (a.valid() & flag) != 0 && predicate.getAsBoolean(); - } - - static boolean find(Test a) { - Stream s = Arrays.stream(testAnnotations).filter(t -> t.match(a)); - long c = s.count(); - if (c > 1) { - throw new RuntimeException("At most one Test annotation should match"); - } - return c > 0; - } - } - - private void parseOutput(String output) throws Exception { - Pattern comp_re = Pattern.compile("\\n\\s+\\d+\\s+\\d+\\s+(%| )(s| )(!| )b(n| )\\s+\\d?\\s+\\S+\\.(?[^.]+::\\S+)\\s+(?@ \\d+\\s+)?[(]\\d+ bytes[)]"); - Matcher m = comp_re.matcher(output); - Map compilations = new LinkedHashMap<>(); - int prev = 0; - String methodName = null; - while (m.find()) { - if (prev == 0) { - // Print header - System.out.print(output.substring(0, m.start()+1)); - } else if (methodName != null) { - compilations.put(methodName, output.substring(prev, m.start()+1)); - } - if (m.group("osr") != null) { - methodName = null; - } else { - methodName = m.group("name"); - } - prev = m.end(); - } - if (prev == 0) { - // Print header - System.out.print(output); - } else if (methodName != null) { - compilations.put(methodName, output.substring(prev)); - } - // Iterate over compilation output - for (String testName : compilations.keySet()) { - Method test = tests.get(testName); - if (test == null) { - // Skip helper methods - continue; - } - String graph = compilations.get(testName); - System.out.println("\nGraph for " + testName + "\n" + graph); - // Parse graph using regular expressions to determine if it contains forbidden nodes - Test[] annos = test.getAnnotationsByType(Test.class); - Test anno = Arrays.stream(annos).filter(TestAnnotation::find).findFirst().orElse(null); - if (anno == null) { - Object[] res = Arrays.stream(annos).filter(a -> a.valid() == 0).toArray(); - if (res.length != 1) { - throw new RuntimeException("Only one Test annotation should match"); - } - anno = (Test)res[0]; - } - String regexFail = anno.failOn(); - if (!regexFail.isEmpty()) { - Pattern pattern = Pattern.compile(regexFail.substring(0, regexFail.length()-1)); - Matcher matcher = pattern.matcher(graph); - boolean found = matcher.find(); - Asserts.assertFalse(found, "Graph for '" + testName + "' contains forbidden node:\n" + (found ? matcher.group() : "")); - } - String[] regexMatch = anno.match(); - int[] matchCount = anno.matchCount(); - for (int i = 0; i < regexMatch.length; ++i) { - Pattern pattern = Pattern.compile(regexMatch[i].substring(0, regexMatch[i].length()-1)); - Matcher matcher = pattern.matcher(graph); - int count = 0; - String nodes = ""; - while (matcher.find()) { - count++; - nodes += matcher.group() + "\n"; - } - if (matchCount[i] < 0) { - Asserts.assertLTE(Math.abs(matchCount[i]), count, "Graph for '" + testName + "' contains different number of match nodes (expected >= " + Math.abs(matchCount[i]) + " but got " + count + "):\n" + nodes); - } else { - Asserts.assertEQ(matchCount[i], count, "Graph for '" + testName + "' contains different number of match nodes (expected " + matchCount[i] + " but got " + count + "):\n" + nodes); - } - } - tests.remove(testName); - System.out.println(testName + " passed"); - } - // Check if all tests were compiled - if (tests.size() != 0) { - for (String name : tests.keySet()) { - System.out.println("Test '" + name + "' not compiled!"); - } - throw new RuntimeException("Not all tests were compiled"); - } - } - - private void setup(Class clazz) { - if (XCOMP) { - // Don't control compilation if -Xcomp is enabled - return; - } - if (DUMP_REPLAY) { - // Generate replay compilation files - String directive = "[{ match: \"*.*\", DumpReplay: true }]"; - if (WHITE_BOX.addCompilerDirective(directive) != 1) { - throw new RuntimeException("Failed to add compiler directive"); - } - } - - Method[] methods = clazz.getDeclaredMethods(); - for (Method m : methods) { - if (m.isAnnotationPresent(Test.class)) { - // Don't inline tests - WHITE_BOX.testSetDontInlineMethod(m, true); - } - if (m.isAnnotationPresent(DontCompile.class)) { - WHITE_BOX.makeMethodNotCompilable(m, COMP_LEVEL_ANY, true); - WHITE_BOX.makeMethodNotCompilable(m, COMP_LEVEL_ANY, false); - WHITE_BOX.testSetDontInlineMethod(m, true); - } - if (m.isAnnotationPresent(ForceInline.class)) { - Asserts.assertFalse(m.isAnnotationPresent(DontInline.class), "Method " + m.getName() + " has contradicting DontInline annotation"); - WHITE_BOX.testSetForceInlineMethod(m, true); - } - if (m.isAnnotationPresent(DontInline.class)) { - Asserts.assertFalse(m.isAnnotationPresent(ForceInline.class), "Method " + m.getName() + " has contradicting ForceInline annotation"); - WHITE_BOX.testSetDontInlineMethod(m, true); - } - if (STRESS_CC) { - // Exclude some methods from compilation with C2 to stress test the calling convention - if (Utils.getRandomInstance().nextBoolean()) { - System.out.println("Excluding from C2 compilation: " + m); - WHITE_BOX.makeMethodNotCompilable(m, COMP_LEVEL_FULL_OPTIMIZATION, false); - } - } - } - // Only force compilation now because above annotations affect inlining - for (Method m : methods) { - if (m.isAnnotationPresent(ForceCompile.class)) { - Asserts.assertFalse(m.isAnnotationPresent(DontCompile.class), "Method " + m.getName() + " has contradicting DontCompile annotation"); - int compLevel = getCompLevel(m.getAnnotation(ForceCompile.class)); - enqueueMethodForCompilation(m, compLevel); - } - } - // Compile class initializers - int compLevel = getCompLevel(null); - WHITE_BOX.enqueueInitializerForCompilation(clazz, compLevel); - } - - private void run(Class... classes) throws Exception { - if (USE_COMPILER && PRINT_IDEAL && !XCOMP && !STRESS_CC) { - System.out.println("PrintIdeal enabled"); - } - System.out.format("rI = %d, rL = %d\n", rI, rL); - - setup(getClass()); - for (Class clazz : classes) { - setup(clazz); - } - - TreeMap durations = (PRINT_TIMES || VERBOSE) ? new TreeMap() : null; - List testList = new ArrayList(tests.values()); - if (SHUFFLE_TESTS) { - // Execute tests in random order (execution sequence affects profiling) - Collections.shuffle(testList, Utils.getRandomInstance()); - } - for (Method test : testList) { - if (VERBOSE) { - System.out.println("Starting " + test.getName()); - } - TempSkipForC1 c1skip = test.getAnnotation(TempSkipForC1.class); - if (TEST_C1 && c1skip != null) { - System.out.println("Skipped " + test.getName() + " for C1 testing: " + c1skip.reason()); - continue; - } - long startTime = System.nanoTime(); - Method verifier = getClass().getMethod(test.getName() + "_verifier", boolean.class); - // Warmup using verifier method - Warmup anno = test.getAnnotation(Warmup.class); - int warmup = anno == null ? WARMUP : anno.value(); - for (int i = 0; i < warmup; ++i) { - verifier.invoke(this, true); - } - boolean osrOnly = (test.getAnnotation(OSRCompileOnly.class) != null); - int compLevel = getCompLevel(test.getAnnotation(Test.class)); - - // C1 generates a lot of code when VerifyOops is enabled and may run out of space (for a small - // number of test cases). - boolean maybeCodeBufferOverflow = (TEST_C1 && VerifyOops); - - if (osrOnly) { - long started = System.currentTimeMillis(); - boolean stateCleared = false; - for (;;) { - long elapsed = System.currentTimeMillis() - started; - int level = WHITE_BOX.getMethodCompilationLevel(test); - if (maybeCodeBufferOverflow && elapsed > 5000 && (!WHITE_BOX.isMethodCompiled(test, false) || level != compLevel)) { - System.out.println("Temporarily disabling VerifyOops"); - try { - WHITE_BOX.setBooleanVMFlag("VerifyOops", false); - if (!stateCleared) { - WHITE_BOX.clearMethodState(test); - stateCleared = true; - } - verifier.invoke(this, false); - } finally { - WHITE_BOX.setBooleanVMFlag("VerifyOops", true); - System.out.println("Re-enabled VerifyOops"); - } - } else { - verifier.invoke(this, false); - } - - boolean b = WHITE_BOX.isMethodCompiled(test, false); - if (VERBOSE) { - System.out.println("Is " + test.getName() + " compiled? " + b); - } - if (b || XCOMP || STRESS_CC || !USE_COMPILER) { - // Don't control compilation if -Xcomp is enabled, or if compiler is disabled - break; - } - Asserts.assertTrue(OSR_TEST_TIMEOUT < 0 || elapsed < OSR_TEST_TIMEOUT, test + " not compiled after " + OSR_TEST_TIMEOUT + " ms"); - } - } else { - // Trigger compilation - enqueueMethodForCompilation(test, compLevel); - if (maybeCodeBufferOverflow && !WHITE_BOX.isMethodCompiled(test, false)) { - // Let's disable VerifyOops temporarily and retry. - WHITE_BOX.setBooleanVMFlag("VerifyOops", false); - WHITE_BOX.clearMethodState(test); - enqueueMethodForCompilation(test, compLevel); - WHITE_BOX.setBooleanVMFlag("VerifyOops", true); - } - if (!STRESS_CC && USE_COMPILER) { - Asserts.assertTrue(WHITE_BOX.isMethodCompiled(test, false), test + " not compiled"); - int level = WHITE_BOX.getMethodCompilationLevel(test); - Asserts.assertEQ(level, compLevel, "Unexpected compilation level for " + test); - } - // Check result - verifier.invoke(this, false); - } - if (PRINT_TIMES || VERBOSE) { - long endTime = System.nanoTime(); - long duration = (endTime - startTime); - durations.put(duration, test.getName()); - if (VERBOSE) { - System.out.println("Done " + test.getName() + ": " + duration + " ns = " + (duration / 1000000) + " ms"); - } - } - if (GC_AFTER) { - System.out.println("doing GC"); - System.gc(); - } - } - - // Print execution times - if (PRINT_TIMES) { - System.out.println("\n\nTest execution times:"); - for (Map.Entry entry : durations.entrySet()) { - System.out.format("%-10s%15d ns\n", entry.getValue() + ":", entry.getKey()); - } - } - } - - // Get the appropriate compilation level for a method, according to the - // given annotation, as well as the current test scenario and VM options. - // - private int getCompLevel(Object annotation) { - int compLevel; - if (annotation == null) { - compLevel = COMP_LEVEL_ANY; - } else if (annotation instanceof Test) { - compLevel = ((Test)annotation).compLevel(); - } else { - compLevel = ((ForceCompile)annotation).compLevel(); - } - - return restrictCompLevel(compLevel); - } - - // Get the appropriate level as permitted by the test scenario and VM options. - private static int restrictCompLevel(int compLevel) { - if (compLevel == COMP_LEVEL_ANY) { - compLevel = COMP_LEVEL_FULL_OPTIMIZATION; - } - if (FLIP_C1_C2) { - // Effectively treat all (compLevel = C1) as (compLevel = C2), and - // (compLevel = C2) as (compLevel = C1). - if (compLevel == COMP_LEVEL_SIMPLE) { - compLevel = COMP_LEVEL_FULL_OPTIMIZATION; - } else if (compLevel == COMP_LEVEL_FULL_OPTIMIZATION) { - compLevel = COMP_LEVEL_SIMPLE; - } - } - if (!TEST_C1 && compLevel < COMP_LEVEL_FULL_OPTIMIZATION) { - compLevel = COMP_LEVEL_FULL_OPTIMIZATION; - } - if (TieredCompilation && compLevel > (int)TieredStopAtLevel) { - compLevel = (int)TieredStopAtLevel; - } - return compLevel; - } - - public static void enqueueMethodForCompilation(Method m, int level) { - level = restrictCompLevel(level); - if (VERBOSE) { - System.out.println("enqueueMethodForCompilation " + m + ", level = " + level); - } - WHITE_BOX.enqueueMethodForCompilation(m, level); - } - - enum TriState { - Maybe, - Yes, - No - } - - static private TriState compiledByC2(Method m) { - if (!USE_COMPILER || XCOMP || TEST_C1 || - (STRESS_CC && !WHITE_BOX.isMethodCompilable(m, COMP_LEVEL_FULL_OPTIMIZATION, false))) { - return TriState.Maybe; - } - if (WHITE_BOX.isMethodCompiled(m, false) && - WHITE_BOX.getMethodCompilationLevel(m, false) >= COMP_LEVEL_FULL_OPTIMIZATION) { - return TriState.Yes; - } - return TriState.No; - } - - static boolean isCompiledByC2(Method m) { - return compiledByC2(m) == TriState.Yes; - } - - static void assertDeoptimizedByC2(Method m) { - if (compiledByC2(m) == TriState.Yes && PerMethodTrapLimit != 0 && ProfileInterpreter) { - throw new RuntimeException("Expected to have deoptimized"); - } - } - - static void assertCompiledByC2(Method m) { - if (compiledByC2(m) == TriState.No) { - throw new RuntimeException("Expected to be compiled"); - } - } -} diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java index 3fdfb211963..4d1deef5078 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java @@ -43,7 +43,7 @@ * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper - * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestLWorld + * @run driver/timeout=450 compiler.valhalla.inlinetypes.TestLWorld */ @ForceCompileClassInitializer diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNewAcmp.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNewAcmp.java index d77e17b00bf..2575dc65511 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNewAcmp.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNewAcmp.java @@ -33,6 +33,8 @@ package compiler.valhalla.inlinetypes; +import compiler.lib.ir_framework.CompLevel; +import compiler.lib.ir_framework.TestFramework; import jdk.test.lib.Asserts; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; @@ -1804,7 +1806,7 @@ public void run(int nullMode) throws Exception { // Do some warmup runs runTest(m, args, 1000, nullMode, equalities); // Make sure method is compiled - InlineTypeTest.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); + TestFramework.compile(m, CompLevel.ANY); Asserts.assertTrue(WHITE_BOX.isMethodCompiled(m, false), m + " not compiled"); // Run again to verify correctness of compiled code runTest(m, args, 1, nullMode, equalities); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java index cc741cdef9d..f58151b0eaa 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestUnloadedInlineTypeField.java @@ -39,7 +39,7 @@ * @requires os.simpleArch == "x64" * @compile hack/GetUnresolvedInlineFieldWrongSignature.java * @compile TestUnloadedInlineTypeField.java - * @run driver/timeout=120 compiler.valhalla.inlinetypes.TestUnloadedInlineTypeField + * @run driver/timeout=300 compiler.valhalla.inlinetypes.TestUnloadedInlineTypeField */ public class TestUnloadedInlineTypeField { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java index eb8a437828f..17b927ee1ce 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java @@ -24,7 +24,7 @@ package compiler.valhalla.inlinetypes; import jdk.test.lib.Asserts; -import jdk.test.lib.hotspot.ir_framework.*; +import compiler.lib.ir_framework.*; /* * @test From 3943845a2fdc7abc2a5e0cbce35e95740f38d17c Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 3 Jun 2021 17:34:43 +0200 Subject: [PATCH 127/131] Fix failing internal tests on Windows and add missing flag description in README --- test/hotspot/jtreg/compiler/lib/ir_framework/README.md | 1 + .../jtreg/compiler/lib/ir_framework/TestFramework.java | 6 +++++- .../jtreg/compiler/lib/ir_framework/test/AbstractTest.java | 7 +++++-- .../compiler/lib/ir_framework/TestCompLevels.java | 7 ++++--- .../compiler/lib/ir_framework/TestControls.java | 6 +++--- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/README.md b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md index 474519f8aeb..14f8fa03ce6 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/README.md +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md @@ -99,6 +99,7 @@ The framework provides various stress and debug flags. They should mainly be use - `-DShuffleTests=false`: Disables the random execution order of all tests (such a shuffling is always done by default). - `-DDumpReplay=true`: Add the `DumpReplay` directive to the test VM. - `-DGCAfter=true`: Perform `System.gc()` after each test (slows the execution down). +- `-TestCompilationTimeout=20`: Change the default waiting time (default: 10s) for a compilation of a normal `@Test` annotated method. - `-DWaitForCompilationTimeout=20`: Change the default waiting time (default: 10s) for a compilation of a `@Test` annotated method with compilation level [WAIT\_FOR\_COMPILATION](./CompLevel.java). - `-DIgnoreCompilerControls=false`: Ignore all compiler controls applied in the framework. This includes any compiler control annotations (`@DontCompile`, `@DontInline`, `@ForceCompile`, `@ForceInline`, `@ForceCompileStaticInitializer`), the exclusion of `@Run` and `@Check` methods from compilation, and the directive to not inline `@Test` annotated methods. diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java index 898d68d5c78..1afc09856a5 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java @@ -125,6 +125,8 @@ public class TestFramework { public static final boolean TESTLIST = !System.getProperty("Test", "").isEmpty(); public static final boolean EXCLUDELIST = !System.getProperty("Exclude", "").isEmpty(); private static final boolean REPORT_STDOUT = Boolean.getBoolean("ReportStdout"); + // Only used for internal testing and should not be used for normal user testing. + private static final boolean SKIP_WHITEBOX_INSTALL = Boolean.getBoolean("SkipWhiteBoxInstall"); private static final String RERUN_HINT = """ ############################################################# @@ -301,7 +303,9 @@ public TestFramework addScenarios(Scenario... scenarios) { * set test class. */ public void start() { - installWhiteBox(); + if (!SKIP_WHITEBOX_INSTALL) { + installWhiteBox(); + } disableIRVerificationIfNotFeasible(); if (scenarios == null) { diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/test/AbstractTest.java b/test/hotspot/jtreg/compiler/lib/ir_framework/test/AbstractTest.java index ce28b543ed3..f4db830f2b0 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/test/AbstractTest.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/test/AbstractTest.java @@ -129,6 +129,7 @@ protected void compileMethod(DeclaredTest test) { final boolean maybeCodeBufferOverflow = (TestVM.TEST_C1 && VERIFY_OOPS); final long started = System.currentTimeMillis(); long elapsed = 0; + int lastCompilationLevel = -10; enqueueMethodForCompilation(test); do { @@ -149,13 +150,15 @@ protected void compileMethod(DeclaredTest test) { WHITE_BOX.setBooleanVMFlag("VerifyOops", true); } - if (WHITE_BOX.getMethodCompilationLevel(testMethod, false) == test.getCompLevel().getValue()) { + lastCompilationLevel = WHITE_BOX.getMethodCompilationLevel(testMethod, false); + if (lastCompilationLevel == test.getCompLevel().getValue()) { break; } elapsed = System.currentTimeMillis() - started; } while (elapsed < TEST_COMPILATION_TIMEOUT); TestRun.check(elapsed < TEST_COMPILATION_TIMEOUT, - "Could not compile " + testMethod + " after " + TEST_COMPILATION_TIMEOUT/1000 + "s"); + "Could not compile " + testMethod + " at level " + test.getCompLevel() + " after " + + TEST_COMPILATION_TIMEOUT/1000 + "s. Last compilation level: " + lastCompilationLevel); checkCompilationLevel(test); } diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java index 2ad976ff90e..2352e108953 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java @@ -31,12 +31,12 @@ * @test * @requires vm.flagless * @summary Test if compilation levels are used correctly in the framework. - * This test runs directly the test VM which normally does not happen. + * This test partly runs directly the test VM which normally does and should not happen in user tests. * @library /test/lib / * @build sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI - * compiler.lib.ir_framework.TestCompLevels + * @run main/othervm -Xbootclasspath/a:. -DSkipWhiteBoxInstall=true -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI compiler.lib.ir_framework.TestCompLevels */ public class TestCompLevels { @@ -46,6 +46,7 @@ public static void main(String[] args) throws Exception { Method runTestsOnSameVM = TestVM.class.getDeclaredMethod("runTestsOnSameVM", Class.class); runTestsOnSameVM.setAccessible(true); runTestsOnSameVM.invoke(null, new Object[]{null}); + for (int i = 0; i < testExecuted.length; i++) { int value = testExecuted[i]; if (value != TestVM.WARMUP_ITERATIONS + 1) { diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java index 5543d24f68d..a1522d3c984 100644 --- a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java +++ b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java @@ -35,12 +35,12 @@ * @test * @requires vm.debug == true & vm.compMode != "Xint" & vm.compiler2.enabled & vm.flagless * @summary Test if compilation control annotaions are handled correctly in the framework. - * This test runs directly the test VM which normally does not happen. + * This test partly runs directly the test VM which normally does and should not happen in user tests. * @library /test/lib / * @build sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI - * compiler.lib.ir_framework.TestControls + * @run main/othervm -Xbootclasspath/a:. -DSkipWhiteBoxInstall=true -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI compiler.lib.ir_framework.TestControls */ public class TestControls { From 8deedc67dbba1d6a1e3319f7af45e6bc9cc64ed6 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 4 Jun 2021 10:25:51 +0200 Subject: [PATCH 128/131] Move tests and examples #1 --- .../compiler/lib/{ir_framework => tests}/README.md | 0 .../compiler/lib/{ir_framework => tests}/TestAccessModifiers.java | 0 .../compiler/lib/{ir_framework => tests}/TestBadFormat.java | 0 .../compiler/lib/{ir_framework => tests}/TestBasics.java | 0 .../compiler/lib/{ir_framework => tests}/TestCompLevels.java | 0 .../compiler/lib/{ir_framework => tests}/TestControls.java | 0 .../compiler/lib/{ir_framework => tests}/TestDFlags.java | 0 .../lib/{ir_framework => tests}/TestDIgnoreCompilerControls.java | 0 .../compiler/lib/{ir_framework => tests}/TestDScenarios.java | 0 .../compiler/lib/{ir_framework => tests}/TestDTestAndExclude.java | 0 .../compiler/lib/{ir_framework => tests}/TestIRMatching.java | 0 .../compiler/lib/{ir_framework => tests}/TestRunTests.java | 0 .../compiler/lib/{ir_framework => tests}/TestSanity.java | 0 .../compiler/lib/{ir_framework => tests}/TestScenarios.java | 0 .../lib/{ir_framework => tests}/TestWithHelperClasses.java | 0 .../{compiler/lib => }/ir_framework/examples/BaseTestExample.java | 0 .../lib => }/ir_framework/examples/CheckedTestExample.java | 0 .../lib => }/ir_framework/examples/CustomRunTestExample.java | 0 .../{compiler/lib => }/ir_framework/examples/IRExample.java | 0 19 files changed, 0 insertions(+), 0 deletions(-) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/README.md (100%) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/TestAccessModifiers.java (100%) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/TestBadFormat.java (100%) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/TestBasics.java (100%) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/TestCompLevels.java (100%) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/TestControls.java (100%) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/TestDFlags.java (100%) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/TestDIgnoreCompilerControls.java (100%) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/TestDScenarios.java (100%) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/TestDTestAndExclude.java (100%) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/TestIRMatching.java (100%) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/TestRunTests.java (100%) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/TestSanity.java (100%) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/TestScenarios.java (100%) rename test/hotspot/jtreg/testlibrary_tests/compiler/lib/{ir_framework => tests}/TestWithHelperClasses.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => }/ir_framework/examples/BaseTestExample.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => }/ir_framework/examples/CheckedTestExample.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => }/ir_framework/examples/CustomRunTestExample.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => }/ir_framework/examples/IRExample.java (100%) diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/README.md b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/README.md similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/README.md rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/README.md diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestAccessModifiers.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestAccessModifiers.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestAccessModifiers.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestAccessModifiers.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestBadFormat.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBadFormat.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestBadFormat.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBasics.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestBasics.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestBasics.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestBasics.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestCompLevels.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestCompLevels.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestCompLevels.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestControls.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestControls.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestControls.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDFlags.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDFlags.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDFlags.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDFlags.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDIgnoreCompilerControls.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDIgnoreCompilerControls.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDIgnoreCompilerControls.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDIgnoreCompilerControls.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDScenarios.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDScenarios.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDScenarios.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDScenarios.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDTestAndExclude.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDTestAndExclude.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestDTestAndExclude.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDTestAndExclude.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestIRMatching.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestIRMatching.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestRunTests.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestRunTests.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestRunTests.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestRunTests.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestSanity.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestSanity.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestSanity.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestSanity.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestScenarios.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestScenarios.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestScenarios.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestWithHelperClasses.java b/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestWithHelperClasses.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/TestWithHelperClasses.java rename to test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestWithHelperClasses.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/BaseTestExample.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/BaseTestExample.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/BaseTestExample.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/BaseTestExample.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CheckedTestExample.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/CheckedTestExample.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CheckedTestExample.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/CheckedTestExample.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CustomRunTestExample.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/CustomRunTestExample.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/CustomRunTestExample.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/CustomRunTestExample.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/IRExample.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/IRExample.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/ir_framework/examples/IRExample.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/IRExample.java From e9f9c17a926d5172c45a8aba8d3489e70c36317d Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 4 Jun 2021 10:32:17 +0200 Subject: [PATCH 129/131] Move tests and examples #2 --- .../{compiler/lib => ir_framework}/tests/README.md | 0 .../{compiler/lib => ir_framework}/tests/TestAccessModifiers.java | 0 .../{compiler/lib => ir_framework}/tests/TestBadFormat.java | 0 .../{compiler/lib => ir_framework}/tests/TestBasics.java | 0 .../{compiler/lib => ir_framework}/tests/TestCompLevels.java | 0 .../{compiler/lib => ir_framework}/tests/TestControls.java | 0 .../{compiler/lib => ir_framework}/tests/TestDFlags.java | 0 .../lib => ir_framework}/tests/TestDIgnoreCompilerControls.java | 0 .../{compiler/lib => ir_framework}/tests/TestDScenarios.java | 0 .../{compiler/lib => ir_framework}/tests/TestDTestAndExclude.java | 0 .../{compiler/lib => ir_framework}/tests/TestIRMatching.java | 0 .../{compiler/lib => ir_framework}/tests/TestRunTests.java | 0 .../{compiler/lib => ir_framework}/tests/TestSanity.java | 0 .../{compiler/lib => ir_framework}/tests/TestScenarios.java | 0 .../lib => ir_framework}/tests/TestWithHelperClasses.java | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/README.md (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/TestAccessModifiers.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/TestBadFormat.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/TestBasics.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/TestCompLevels.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/TestControls.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/TestDFlags.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/TestDIgnoreCompilerControls.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/TestDScenarios.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/TestDTestAndExclude.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/TestIRMatching.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/TestRunTests.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/TestSanity.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/TestScenarios.java (100%) rename test/hotspot/jtreg/testlibrary_tests/{compiler/lib => ir_framework}/tests/TestWithHelperClasses.java (100%) diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/README.md b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/README.md similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/README.md rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/README.md diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestAccessModifiers.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestAccessModifiers.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestAccessModifiers.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestAccessModifiers.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestBadFormat.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestBadFormat.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestBasics.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBasics.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestBasics.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBasics.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestCompLevels.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestCompLevels.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestCompLevels.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestCompLevels.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestControls.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestControls.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestControls.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestControls.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDFlags.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDFlags.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDFlags.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDFlags.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDIgnoreCompilerControls.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDIgnoreCompilerControls.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDIgnoreCompilerControls.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDIgnoreCompilerControls.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDScenarios.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDScenarios.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDScenarios.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDScenarios.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDTestAndExclude.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDTestAndExclude.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestDTestAndExclude.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDTestAndExclude.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestIRMatching.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestIRMatching.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestRunTests.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestRunTests.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestRunTests.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestRunTests.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestSanity.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestSanity.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestSanity.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestSanity.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestScenarios.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestScenarios.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestScenarios.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestScenarios.java diff --git a/test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestWithHelperClasses.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestWithHelperClasses.java similarity index 100% rename from test/hotspot/jtreg/testlibrary_tests/compiler/lib/tests/TestWithHelperClasses.java rename to test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestWithHelperClasses.java From 1c43e46f6526f17d80c79d9190e68653710558f0 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 4 Jun 2021 11:39:40 +0200 Subject: [PATCH 130/131] Update test and example package names, README files and fix some tests to let them pass in higher tiers --- .../jtreg/compiler/lib/ir_framework/README.md | 14 +++++----- .../examples/BaseTestExample.java | 7 ++--- .../examples/CheckedTestExample.java | 6 ++--- .../examples/CustomRunTestExample.java | 6 ++--- .../ir_framework/examples/IRExample.java | 4 +-- .../ir_framework/tests/README.md | 4 +-- .../tests/TestAccessModifiers.java | 6 +++-- .../ir_framework/tests/TestBadFormat.java | 8 +++--- .../ir_framework/tests/TestBasics.java | 5 ++-- .../ir_framework/tests/TestCompLevels.java | 5 ++-- .../ir_framework/tests/TestControls.java | 6 +++-- .../ir_framework/tests/TestDFlags.java | 26 +++++++++--------- .../tests/TestDIgnoreCompilerControls.java | 7 ++--- .../ir_framework/tests/TestDScenarios.java | 19 +++++++------ .../tests/TestDTestAndExclude.java | 12 ++++++--- .../ir_framework/tests/TestIRMatching.java | 27 ++++++++++--------- .../ir_framework/tests/TestRunTests.java | 7 ++--- .../ir_framework/tests/TestSanity.java | 8 ++++-- .../ir_framework/tests/TestScenarios.java | 13 ++++----- .../tests/TestWithHelperClasses.java | 15 ++++++----- 20 files changed, 115 insertions(+), 90 deletions(-) diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/README.md b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md index 14f8fa03ce6..8a405b3f246 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/README.md +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md @@ -31,24 +31,24 @@ The framework is intended to be used in JTreg tests. The JTreg header of the tes There are various ways how to set up and run a test within the `main()` method of a JTreg test. These are described and can be found in the [TestFramework](./TestFramework.java) class. ## 2. Features - The framework offers various annotations and flags to control how your test code should be invoked and being checked. This section gives an overview over all these features. +The framework offers various annotations and flags to control how your test code should be invoked and being checked. This section gives an overview over all these features. ### 2.1 Different Tests There are three kinds of tests depending on how much control is needed over the test invocation. #### Base Tests The simplest form of testing provides a single `@Test` annotated method which the framework will invoke as part of the testing. The test method has no or well-defined arguments that the framework can automatically provide. -More information on base tests with a precise definition can be found in the Javadocs of [Test](./Test.java). Concrete examples on how to specify a base test can be found in [BaseTestsExample](../../../testlibrary_tests/compiler/lib/ir_framework/examples/BaseTestExample.java). +More information on base tests with a precise definition can be found in the Javadocs of [Test](./Test.java). Concrete examples on how to specify a base test can be found in [BaseTestsExample](../../../testlibrary_tests/ir_framework/examples/BaseTestExample.java). #### Checked Tests The base tests do not provide any way of verification by user code. A checked test enables this by allowing the user to define an additional `@Check` annotated method which is invoked directly after the `@Test` annotated method. This allows the user to perform various checks about the test method including return value verification. -More information on checked tests with a precise definition can be found in the Javadocs of [Check](./Check.java). Concrete examples on how to specify a checked test can be found in [CheckedTestsExample](../../../testlibrary_tests/compiler/lib/ir_framework/examples/CheckedTestExample.java). +More information on checked tests with a precise definition can be found in the Javadocs of [Check](./Check.java). Concrete examples on how to specify a checked test can be found in [CheckedTestsExample](../../../testlibrary_tests/ir_framework/examples/CheckedTestExample.java). #### Custom Run Tests Neither the base nor the checked tests provide any control over how a `@Test` annotated method is invoked in terms of customized argument values and/or conditions for the invocation itself. A custom run test gives full control over the invocation of the `@Test` annotated method to the user. The framework calls a dedicated `@Run` annotated method from which the user can invoke the `@Test` method according to his/her needs. -More information on checked tests with a precise definition can be found in the Javadocs of [Run](./Run.java). Concrete examples on how to specify a custom run test can be found in [CustomRunTestsExample](../../../testlibrary_tests/compiler/lib/ir_framework/examples/CustomRunTestExample.java). +More information on checked tests with a precise definition can be found in the Javadocs of [Run](./Run.java). Concrete examples on how to specify a custom run test can be found in [CustomRunTestsExample](../../../testlibrary_tests/ir_framework/examples/CustomRunTestExample.java). ### 2.2 IR Verification The main feature of this framework is to perform a simple but yet powerful regex-based C2 IR matching on the output of _-XX:+PrintIdeal_ and _-XX:+PrintOptoAssembly_. For simplicity, we will refer to the "IR" or "IR matching" when actually meaning the combined output of _-XX:+PrintIdeal_ and _-XX:+PrintOptoAssembly_ for a C2 compilation. @@ -66,7 +66,7 @@ In general, the framework will only perform IR verification if the used VM flags An `@IR` annotation allows additional preconditions/restrictions on the currently present VM flags to enable or disable rules when certain flags are present or have a specific value (see `applyIfXX` properties of an `@IR` annotation). -More information about IR matching can be found in the Javadocs of [IR](./IR.java). Concrete examples on how to specify IR constraint/rules can be found in [IRExample](../../../testlibrary_tests/compiler/lib/ir_framework/examples/IRExample.java) and [TestIRMatching](../../../testlibrary_tests/compiler/lib/ir_framework/TestIRMatching.java) (an internal framework test). +More information about IR matching can be found in the Javadocs of [IR](./IR.java). Concrete examples on how to specify IR constraint/rules can be found in [IRExample](../../../testlibrary_tests/ir_framework/examples/IRExample.java) and [TestIRMatching](../../../testlibrary_tests/ir_framework/tests/TestIRMatching.java) (an internal framework test). ### 2.3 Test VM Flags and Scenarios The recommended way to use the framework is by defining a single `@run driver` statement in the JTreg header which, however, does not allow the specification of additional test VM flags. Instead, the user has the possibility to provide VM flags by calling `TestFramework.runWithFlags()` or by creating a `TestFramework` builder object on which `addFlags()` can be called. @@ -119,7 +119,7 @@ Some of the steps above can be different due to the kind of the test or due to u More information about the internals and the workflow of the framework can be found in the Javadocs of [TestFramework](./TestFramework.java). ## 4. Internal Framework Tests -There are various tests to verify the correctness of the test framework. These tests can be found in [ir_framework](../../../testlibrary_tests/compiler/lib/ir_framework) and can directly be run with JTreg. The tests are part of the normal JTreg tests of HotSpot and should be run upon changing the framework code as a minimal form of testing. +There are various tests to verify the correctness of the test framework. These tests can be found in [ir_framework](../../../testlibrary_tests/ir_framework) and can directly be run with JTreg. The tests are part of the normal JTreg tests of HotSpot and should be run upon changing the framework code as a minimal form of testing. Additional testing was performed by converting all compiler Inline Types tests that used the currently present IR test framework in Valhalla (see [JDK-8263024](https://bugs.openjdk.java.net/browse/JDK-8263024)). It is strongly advised to make sure a change to the framework still lets these converted tests in Valhalla pass as part of an additional testing step. @@ -132,4 +132,4 @@ A user only needs to import classes from the package `compiler.lib.ir_framework` - `compiler.lib.ir_framework.shared`: These classes can be called from either the driver, flag, or test VM. ## 6. Summary - The initial design and feature set was kept simple and straight forward and serves well for small to medium sized tests. There are a lot of possibilities to further enhance the framework and make it more powerful. This can be tackled in additional RFEs. A few ideas can be found as subtasks of the [initial RFE](https://bugs.openjdk.java.net/browse/JDK-8254129) for this framework. +The initial design and feature set was kept simple and straight forward and serves well for small to medium sized tests. There are a lot of possibilities to further enhance the framework and make it more powerful. This can be tackled in additional RFEs. A few ideas can be found as subtasks of the [initial RFE](https://bugs.openjdk.java.net/browse/JDK-8254129) for this framework. diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/BaseTestExample.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/BaseTestExample.java index 9f8cc1eb135..5307cf5ed6b 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/BaseTestExample.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/BaseTestExample.java @@ -21,15 +21,16 @@ * questions. */ -package compiler.lib.ir_framework.examples; +package ir_framework.examples; import compiler.lib.ir_framework.*; -import compiler.lib.ir_framework.test.TestVM; +import compiler.lib.ir_framework.test.TestVM; // Only used for Javadocs + /* * @test * @summary Example test to use the new test framework. * @library /test/lib / - * @run driver compiler.lib.ir_framework.examples.BaseTestExample + * @run driver ir_framework.examples.BaseTestExample */ /** diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/CheckedTestExample.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/CheckedTestExample.java index c01f0671daf..206b7d9d185 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/CheckedTestExample.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/CheckedTestExample.java @@ -21,16 +21,16 @@ * questions. */ -package compiler.lib.ir_framework.examples; +package ir_framework.examples; import compiler.lib.ir_framework.*; -import compiler.lib.ir_framework.test.TestVM; +import compiler.lib.ir_framework.test.TestVM; // Only used for Javadocs /* * @test * @summary Example test to use the new test framework. * @library /test/lib / - * @run driver compiler.lib.ir_framework.examples.CheckedTestExample + * @run driver ir_framework.examples.CheckedTestExample */ /** diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/CustomRunTestExample.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/CustomRunTestExample.java index 90e15abc439..3565f3def3d 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/CustomRunTestExample.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/CustomRunTestExample.java @@ -21,16 +21,16 @@ * questions. */ -package compiler.lib.ir_framework.examples; +package ir_framework.examples; import compiler.lib.ir_framework.*; -import compiler.lib.ir_framework.test.TestVM; +import compiler.lib.ir_framework.test.TestVM; // Only used for Javadocs /* * @test * @summary Example test to use the new test framework. * @library /test/lib / - * @run driver compiler.lib.ir_framework.examples.CustomRunTestExample + * @run driver ir_framework.examples.CustomRunTestExample */ /** diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/IRExample.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/IRExample.java index 44b3fb6bf50..8d8e5b31bc1 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/IRExample.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/IRExample.java @@ -21,7 +21,7 @@ * questions. */ -package compiler.lib.ir_framework.examples; +package ir_framework.examples; import compiler.lib.ir_framework.*; import compiler.lib.ir_framework.driver.IRViolationException; @@ -30,7 +30,7 @@ * @test * @summary Example test to use the new test framework. * @library /test/lib / - * @run driver compiler.lib.ir_framework.examples.IRExample + * @run driver ir_framework.examples.IRExample */ /** diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/README.md b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/README.md index 0d05c28cc3d..9a1a2557bc1 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/README.md +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/README.md @@ -1,7 +1,5 @@ # Framework internal tests -This folder contains tests which test the functionality of the framework. These should be run with JTreg and without additional VM and Javaopts flags whenever the framework is modified. - -These tests are not part of the normal tier testing as they only should be run when the framework is changed in any way. +This folder contains tests which test the functionality of the framework. These are run with JTreg and are part of tier testing. All tests are run without additional VM and Javaopts flags. These tests must pass whenever the framework is updated. Additional testing should be performed with the converted Valhalla tests to make sure a changeset is correct (these are part of the Valhalla CI). diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestAccessModifiers.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestAccessModifiers.java index f31e13653b1..47bc9741b60 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestAccessModifiers.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestAccessModifiers.java @@ -21,14 +21,16 @@ * questions. */ -package compiler.lib.ir_framework; +package ir_framework.tests; + +import compiler.lib.ir_framework.*; /* * @test * @requires vm.flagless * @summary Test different access modifiers an make sure, the framework can access all methods. * @library /test/lib / - * @run driver compiler.lib.ir_framework.TestAccessModifiers + * @run driver ir_framework.tests.TestAccessModifiers */ public class TestAccessModifiers { diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java index c47c5542cb6..4eb0cba6f14 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java @@ -21,8 +21,10 @@ * questions. */ -package compiler.lib.ir_framework; +package ir_framework.tests; +import compiler.lib.ir_framework.*; +import compiler.lib.ir_framework.Compiler; import compiler.lib.ir_framework.shared.TestFormatException; import jdk.test.lib.Asserts; @@ -37,10 +39,10 @@ /* * @test - * @requires vm.compiler2.enabled & vm.flagless + * @requires vm.debug == true & vm.compiler2.enabled & vm.flagless * @summary Test test format violations. * @library /test/lib / - * @run driver compiler.lib.ir_framework.TestBadFormat + * @run driver ir_framework.tests.TestBadFormat */ public class TestBadFormat { diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBasics.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBasics.java index 5f71367d6e6..82b6f880f2d 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBasics.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBasics.java @@ -21,8 +21,9 @@ * questions. */ -package compiler.lib.ir_framework; +package ir_framework.tests; +import compiler.lib.ir_framework.*; import compiler.lib.ir_framework.test.TestVM; import java.lang.reflect.Method; @@ -37,7 +38,7 @@ * @build sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI - * compiler.lib.ir_framework.TestBasics + * -Xbatch ir_framework.tests.TestBasics */ public class TestBasics { diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestCompLevels.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestCompLevels.java index 2352e108953..4f373ca4027 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestCompLevels.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestCompLevels.java @@ -21,8 +21,9 @@ * questions. */ -package compiler.lib.ir_framework; +package ir_framework.tests; +import compiler.lib.ir_framework.*; import compiler.lib.ir_framework.test.TestVM; import java.lang.reflect.Method; @@ -36,7 +37,7 @@ * @build sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -DSkipWhiteBoxInstall=true -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI compiler.lib.ir_framework.TestCompLevels + * -Xbatch -XX:+WhiteBoxAPI ir_framework.tests.TestCompLevels */ public class TestCompLevels { diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestControls.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestControls.java index a1522d3c984..8dad488740a 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestControls.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestControls.java @@ -21,8 +21,10 @@ * questions. */ -package compiler.lib.ir_framework; +package ir_framework.tests; +import compiler.lib.ir_framework.*; +import compiler.lib.ir_framework.Compiler; import compiler.lib.ir_framework.test.TestVM; import jdk.test.lib.Asserts; import sun.hotspot.WhiteBox; @@ -40,7 +42,7 @@ * @build sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -DSkipWhiteBoxInstall=true -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI compiler.lib.ir_framework.TestControls + * -Xbatch -XX:+WhiteBoxAPI ir_framework.tests.TestControls */ public class TestControls { diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDFlags.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDFlags.java index 3ec0da5c372..752ba5c0e44 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDFlags.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDFlags.java @@ -21,24 +21,26 @@ * questions. */ -package compiler.lib.ir_framework; +package ir_framework.tests; +import compiler.lib.ir_framework.Test; +import compiler.lib.ir_framework.TestFramework; /* * @test * @requires vm.debug == true & vm.compMode != "Xint" & vm.compiler2.enabled & vm.flagless * @summary Sanity test remaining framework property flags. * @library /test/lib / - * @run main/othervm -DFlipC1C2=true compiler.lib.ir_framework.TestDFlags - * @run main/othervm -DExcludeRandom=true compiler.lib.ir_framework.TestDFlags - * @run main/othervm -DVerifyVM=true compiler.lib.ir_framework.TestDFlags - * @run main/othervm -DDumpReplay=true compiler.lib.ir_framework.TestDFlags - * @run main/othervm -DVerbose=true compiler.lib.ir_framework.TestDFlags - * @run main/othervm -DShuffleTests=false compiler.lib.ir_framework.TestDFlags - * @run main/othervm -DReproduce=true compiler.lib.ir_framework.TestDFlags - * @run main/othervm -DReportStdout=true compiler.lib.ir_framework.TestDFlags - * @run main/othervm -DGCAfter=true compiler.lib.ir_framework.TestDFlags - * @run main/othervm -DPrintTimes=true compiler.lib.ir_framework.TestDFlags - * @run main/othervm -DVerifyIR=false compiler.lib.ir_framework.TestDFlags + * @run main/othervm -DFlipC1C2=true ir_framework.tests.TestDFlags + * @run main/othervm -DExcludeRandom=true ir_framework.tests.TestDFlags + * @run main/othervm -DVerifyVM=true ir_framework.tests.TestDFlags + * @run main/othervm -DDumpReplay=true ir_framework.tests.TestDFlags + * @run main/othervm -DVerbose=true ir_framework.tests.TestDFlags + * @run main/othervm -DShuffleTests=false ir_framework.tests.TestDFlags + * @run main/othervm -DReproduce=true ir_framework.tests.TestDFlags + * @run main/othervm -DReportStdout=true ir_framework.tests.TestDFlags + * @run main/othervm -DGCAfter=true ir_framework.tests.TestDFlags + * @run main/othervm -DPrintTimes=true ir_framework.tests.TestDFlags + * @run main/othervm -DVerifyIR=false ir_framework.tests.TestDFlags */ public class TestDFlags { diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDIgnoreCompilerControls.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDIgnoreCompilerControls.java index e33e5552525..47a6ae6e310 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDIgnoreCompilerControls.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDIgnoreCompilerControls.java @@ -21,8 +21,9 @@ * questions. */ -package compiler.lib.ir_framework; +package ir_framework.tests; +import compiler.lib.ir_framework.*; import jdk.test.lib.Asserts; import jdk.test.lib.Utils; import jdk.test.lib.process.OutputAnalyzer; @@ -34,7 +35,7 @@ * @requires vm.debug == true & vm.flagless * @summary Test -DIgnoreCompilerControls property flag. * @library /test/lib / - * @run driver compiler.lib.ir_framework.TestDIgnoreCompilerControls + * @run driver ir_framework.tests.TestDIgnoreCompilerControls */ public class TestDIgnoreCompilerControls { @@ -56,7 +57,7 @@ private static OutputAnalyzer run(String flagValue) throws Exception { ProcessBuilder process = ProcessTools.createJavaProcessBuilder( "-Dtest.class.path=" + Utils.TEST_CLASS_PATH, "-Dtest.jdk=" + Utils.TEST_JDK, "-Dtest.vm.opts=-DIgnoreCompilerControls=" + flagValue, - "compiler.lib.ir_framework.TestDIgnoreCompilerControls", flagValue); + "ir_framework.tests.TestDIgnoreCompilerControls", flagValue); oa = ProcessTools.executeProcess(process); return oa; } diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDScenarios.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDScenarios.java index f0369851395..10a49f9a3c7 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDScenarios.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDScenarios.java @@ -21,11 +21,14 @@ * questions. */ -package compiler.lib.ir_framework; +package ir_framework.tests; +import compiler.lib.ir_framework.Scenario; +import compiler.lib.ir_framework.Test; +import compiler.lib.ir_framework.TestFramework; import compiler.lib.ir_framework.driver.TestVMException; -import jdk.test.lib.Utils; import jdk.test.lib.Asserts; +import jdk.test.lib.Utils; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; @@ -34,11 +37,11 @@ * @requires vm.debug == true & vm.flagless * @summary Test -DScenarios property flag. Run with othervm which should not be done when writing tests using the framework. * @library /test/lib / - * @run main/othervm -DScenarios=1,5,10 compiler.lib.ir_framework.TestDScenarios test - * @run main/othervm -DScenarios=1,4 compiler.lib.ir_framework.TestDScenarios test - * @run main/othervm -DScenarios=3,4,9 compiler.lib.ir_framework.TestDScenarios test - * @run driver compiler.lib.ir_framework.TestDScenarios test2 - * @run driver compiler.lib.ir_framework.TestDScenarios + * @run main/othervm -DScenarios=1,5,10 ir_framework.tests.TestDScenarios test + * @run main/othervm -DScenarios=1,4 ir_framework.tests.TestDScenarios test + * @run main/othervm -DScenarios=3,4,9 ir_framework.tests.TestDScenarios test + * @run driver ir_framework.tests.TestDScenarios test2 + * @run driver ir_framework.tests.TestDScenarios */ public class TestDScenarios { @@ -72,7 +75,7 @@ public static void main(String[] args) throws Exception { OutputAnalyzer oa; ProcessBuilder process = ProcessTools.createJavaProcessBuilder( "-Dtest.jdk=" + Utils.TEST_JDK, "-DScenarios=a,1,b,10", - "compiler.lib.ir_framework.TestDScenarios", " test3"); + "ir_framework.tests.TestDScenarios", " test3"); oa = ProcessTools.executeProcess(process); oa.shouldNotHaveExitValue(0); System.out.println(oa.getOutput()); diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDTestAndExclude.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDTestAndExclude.java index c0d2bb062bc..b74012fd54a 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDTestAndExclude.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestDTestAndExclude.java @@ -21,12 +21,16 @@ * questions. */ -package compiler.lib.ir_framework; +package ir_framework.tests; +import compiler.lib.ir_framework.Check; +import compiler.lib.ir_framework.Run; +import compiler.lib.ir_framework.Test; +import compiler.lib.ir_framework.TestFramework; import compiler.lib.ir_framework.driver.TestVMException; import compiler.lib.ir_framework.shared.NoTestsRunException; -import jdk.test.lib.Utils; import jdk.test.lib.Asserts; +import jdk.test.lib.Utils; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; @@ -35,7 +39,7 @@ * @requires vm.flagless * @summary Test -DTest and -DExclude property flag. * @library /test/lib / - * @run driver compiler.lib.ir_framework.TestDTestAndExclude + * @run driver ir_framework.tests.TestDTestAndExclude */ public class TestDTestAndExclude { @@ -96,7 +100,7 @@ protected static void run(String dTest, String dExclude, String arg) throws Exce ProcessBuilder process = ProcessTools.createJavaProcessBuilder( "-Dtest.class.path=" + Utils.TEST_CLASS_PATH, "-Dtest.jdk=" + Utils.TEST_JDK, "-Dtest.vm.opts=-DTest=" + dTest + " -DExclude=" + dExclude, - "compiler.lib.ir_framework.TestDTestAndExclude", arg); + "ir_framework.tests.TestDTestAndExclude", arg); oa = ProcessTools.executeProcess(process); oa.shouldHaveExitValue(0); } 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 fb066bbd84c..344ff1213a9 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java @@ -21,8 +21,9 @@ * questions. */ -package compiler.lib.ir_framework; +package ir_framework.tests; +import compiler.lib.ir_framework.*; import compiler.lib.ir_framework.driver.IRViolationException; import jdk.test.lib.Asserts; @@ -40,7 +41,7 @@ * @summary Test IR matcher with different default IR node regexes. Use -DPrintIREncoding. * Normally, the framework should be called with driver. * @library /test/lib / - * @run main/othervm -DPrintIREncoding=true compiler.lib.ir_framework.TestIRMatching + * @run main/othervm -DPrintIREncoding=true ir_framework.tests.TestIRMatching */ public class TestIRMatching { @@ -185,7 +186,7 @@ public static void main(String[] args) { runCheck(BadFailOnConstraint.create(Membar.class, "membar()", 1, "MemBar")); runCheck(BadFailOnConstraint.create(CheckCastArray.class, "array()", 1, "cmp", "precise klass"), BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 1,"cmp", "precise klass", "MyClass"), - BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 2,"cmp", "precise klass", "ir_framework/MyClass"), + BadFailOnConstraint.create(CheckCastArray.class, "array()", 2, 2,"cmp", "precise klass", "ir_framework/tests/MyClass"), GoodFailOnConstraint.create(CheckCastArray.class, "array()", 3), BadFailOnConstraint.create(CheckCastArray.class, "arrayCopy(java.lang.Object[],java.lang.Class)", 1, "checkcast_arraycopy") ); @@ -413,7 +414,7 @@ public void fail3() { } @Test - @IR(failOn = {IRNode.STORE_OF_CLASS, "compiler/lib/ir_framework/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "ir_framework/tests/MultipleFailOnBad", IRNode.CALL, IRNode.ALLOC}) public void fail4() { iFld = 42; } @@ -437,7 +438,7 @@ public void fail7() { } @Test - @IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "compiler/lib/ir_framework/MyClassSub"}) + @IR(failOn = {IRNode.STORE_OF_CLASS, "UnknownClass", IRNode.ALLOC_OF, "ir_framework/tests/MyClassSub"}) public void fail8() { myClass = new MyClassSub(); } @@ -635,10 +636,10 @@ public void good4() { @Test @IR(counts = {IRNode.STORE, "2", IRNode.STORE_I, "1", IRNode.STORE_L, "1", IRNode.STORE_OF_CLASS, "GoodCount", "1", IRNode.STORE_L_OF_CLASS, "GoodCount", "1", - IRNode.STORE_OF_CLASS, "compiler/lib/ir_framework/MyClass", "1", - IRNode.STORE_I_OF_CLASS, "compiler/lib/ir_framework/MyClass", "1", - IRNode.STORE_OF_CLASS, "compiler/lib/ir_framework/GoodCount", "1", - IRNode.STORE_L_OF_CLASS, "compiler/lib/ir_framework/GoodCount", "1", + IRNode.STORE_OF_CLASS, "ir_framework/tests/MyClass", "1", + IRNode.STORE_I_OF_CLASS, "ir_framework/tests/MyClass", "1", + IRNode.STORE_OF_CLASS, "ir_framework/tests/GoodCount", "1", + IRNode.STORE_L_OF_CLASS, "ir_framework/tests/GoodCount", "1", IRNode.STORE_OF_FIELD, "x", "2"}) public void good5() { x = 3; // long @@ -803,8 +804,8 @@ class AllocArray { @IR(failOn = {IRNode.ALLOC_ARRAY}) @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClass"}) @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "MyClasss"}) // Does not fail - @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/lib/ir_framework/MySubClass"}) // Does not fail - @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "compiler/lib/ir_framework/MyClass"}) + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "ir_framework/tests/MySubClass"}) // Does not fail + @IR(failOn = {IRNode.ALLOC_ARRAY_OF, "ir_framework/tests/MyClass"}) public void allocArray() { myClassArray = new MyClass[2]; } @@ -820,7 +821,7 @@ class Loads { @IR(failOn = {IRNode.LOOP, IRNode.LOOP}, counts = {IRNode.LOOP, "0", IRNode.LOAD, "1"}) // Does not fail @IR(failOn = {IRNode.LOOP, IRNode.LOOP}, counts = {IRNode.LOOP, "0", IRNode.STORE, "1"}) @IR(failOn = {IRNode.LOOP, IRNode.STORE}, counts = {IRNode.LOOP, "0", IRNode.LOAD, "1"}) - @IR(failOn = {IRNode.LOAD_OF_CLASS, "compiler/lib/ir_framework/Loads"}) + @IR(failOn = {IRNode.LOAD_OF_CLASS, "ir_framework/tests/Loads"}) @IR(failOn = {IRNode.LOAD_OF_CLASS, "Loads"}) @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld"}) @IR(failOn = {IRNode.LOAD_OF_FIELD, "iFld2", IRNode.LOAD_OF_CLASS, "Load"}) // Does not fail @@ -1105,7 +1106,7 @@ class CheckCastArray { @Test @IR(failOn = IRNode.CHECKCAST_ARRAY) // fails @IR(failOn = {IRNode.CHECKCAST_ARRAY_OF, "MyClass", // fails - IRNode.CHECKCAST_ARRAY_OF, "ir_framework/MyClass"}) // fails + IRNode.CHECKCAST_ARRAY_OF, "ir_framework/tests/MyClass"}) // fails @IR(failOn = {IRNode.CHECKCAST_ARRAY_OF, "MyClasss", IRNode.CHECKCAST_ARRAY_OF, "Object"}) public boolean array() { return oArr instanceof MyClass[]; diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestRunTests.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestRunTests.java index a9522fcdeab..7f7cb1830dc 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestRunTests.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestRunTests.java @@ -21,8 +21,9 @@ * questions. */ -package compiler.lib.ir_framework; +package ir_framework.tests; +import compiler.lib.ir_framework.*; import compiler.lib.ir_framework.driver.IRViolationException; import compiler.lib.ir_framework.shared.TestRunException; import jdk.test.lib.Asserts; @@ -31,10 +32,10 @@ /* * @test - * @requires vm.compMode != "Xint" & vm.compiler2.enabled & vm.flagless + * @requires vm.debug == true & vm.compMode != "Xint" & vm.compiler2.enabled & vm.flagless * @summary Test different custom run tests. * @library /test/lib / - * @run driver compiler.lib.ir_framework.TestRunTests + * @run driver ir_framework.tests.TestRunTests */ public class TestRunTests { diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestSanity.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestSanity.java index 582f80c994b..77f8a157363 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestSanity.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestSanity.java @@ -21,14 +21,18 @@ * questions. */ -package compiler.lib.ir_framework; +package ir_framework.tests; + +import compiler.lib.ir_framework.Scenario; +import compiler.lib.ir_framework.Test; +import compiler.lib.ir_framework.TestFramework; /* * @test * @requires vm.flagless * @summary Sanity test the different ways to start the test framework. * @library /test/lib / - * @run driver compiler.lib.ir_framework.TestSanity + * @run driver ir_framework.tests.TestSanity */ public class TestSanity { diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestScenarios.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestScenarios.java index bc8217cb7d2..64edcbc82e2 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestScenarios.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestScenarios.java @@ -21,17 +21,18 @@ * questions. */ -package compiler.lib.ir_framework; +package ir_framework.tests; +import compiler.lib.ir_framework.*; import compiler.lib.ir_framework.shared.TestRunException; import jdk.test.lib.Asserts; /* * @test - * @requires vm.compMode != "Xint" & vm.compiler2.enabled & vm.flagless + * @requires vm.debug == true & vm.compMode != "Xint" & vm.compiler2.enabled & vm.flagless * @summary Test scenarios with the framework. * @library /test/lib / - * @run driver compiler.lib.ir_framework.TestScenarios + * @run driver ir_framework.tests.TestScenarios */ public class TestScenarios { @@ -64,9 +65,9 @@ public static void main(String[] args) { new TestFramework(MyExceptionTest.class).addScenarios(s1, s2, s3).start(); Asserts.fail("Should not reach"); } catch (TestRunException e) { - Asserts.assertTrue(s1.getTestVMOutput().contains("Caused by: compiler.lib.ir_framework.MyScenarioException")); - Asserts.assertTrue(s2.getTestVMOutput().contains("Caused by: compiler.lib.ir_framework.MyScenarioException")); - Asserts.assertTrue(s3.getTestVMOutput().contains("Caused by: compiler.lib.ir_framework.MyScenarioException")); + Asserts.assertTrue(s1.getTestVMOutput().contains("Caused by: ir_framework.tests.MyScenarioException")); + Asserts.assertTrue(s2.getTestVMOutput().contains("Caused by: ir_framework.tests.MyScenarioException")); + Asserts.assertTrue(s3.getTestVMOutput().contains("Caused by: ir_framework.tests.MyScenarioException")); } catch (Exception e) { Asserts.fail("Should not catch other exceptions"); } diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestWithHelperClasses.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestWithHelperClasses.java index 9f04e95c042..f2359bf5900 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestWithHelperClasses.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestWithHelperClasses.java @@ -21,8 +21,9 @@ * questions. */ -package compiler.lib.ir_framework; +package ir_framework.tests; +import compiler.lib.ir_framework.*; import compiler.lib.ir_framework.driver.TestVMException; import compiler.lib.ir_framework.shared.TestFormatException; import jdk.test.lib.Asserts; @@ -32,7 +33,7 @@ * @requires vm.flagless * @summary Test the framework with helper classes. * @library /test/lib / - * @run driver compiler.lib.ir_framework.TestWithHelperClasses + * @run driver ir_framework.tests.TestWithHelperClasses */ public class TestWithHelperClasses { @@ -43,10 +44,10 @@ public static void main(String[] args) { new TestFramework().addHelperClasses(Helper1.class).start(); shouldNotReach(); } catch (TestVMException e) { - Asserts.assertFalse(e.getExceptionInfo().contains("public static void compiler.lib.ir_framework.Helper1.foo() should have been C2 compiled")); - Asserts.assertFalse(TestFramework.getLastTestVMOutput().contains("public static void compiler.lib.ir_framework.Helper1.foo() should have been C2 compiled")); - Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("public static void compiler.lib.ir_framework.Helper2.foo() should have been C2 compiled")); - Asserts.assertTrue(e.getExceptionInfo().contains("public static void compiler.lib.ir_framework.Helper2.foo() should have been C2 compiled")); + Asserts.assertFalse(e.getExceptionInfo().contains("public static void ir_framework.tests.Helper1.foo() should have been C2 compiled")); + Asserts.assertFalse(TestFramework.getLastTestVMOutput().contains("public static void ir_framework.tests.Helper1.foo() should have been C2 compiled")); + Asserts.assertTrue(TestFramework.getLastTestVMOutput().contains("public static void ir_framework.tests.Helper2.foo() should have been C2 compiled")); + Asserts.assertTrue(e.getExceptionInfo().contains("public static void ir_framework.tests.Helper2.foo() should have been C2 compiled")); Asserts.assertFalse(TestFramework.getLastTestVMOutput().contains("Should not be executed")); Asserts.assertFalse(e.getExceptionInfo().contains("Should not be executed")); } @@ -69,7 +70,7 @@ public static void main(String[] args) { new TestFramework(TestAsHelper.class).addHelperClasses(TestAsHelper.class).start(); shouldNotReach(); } catch (TestFormatException e) { - Asserts.assertTrue(e.getMessage().contains("Cannot specify test class compiler.lib.ir_framework." + + Asserts.assertTrue(e.getMessage().contains("Cannot specify test class ir_framework.tests." + "TestAsHelper as helper class, too")); } From 5c52651441b367ff9b9515e85989037754265cbd Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 4 Jun 2021 11:59:24 +0200 Subject: [PATCH 131/131] Update whitelist --- .../jtreg/compiler/lib/ir_framework/TestFramework.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java index 1afc09856a5..2b40ba73a52 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java @@ -110,6 +110,10 @@ public class TestFramework { "Verify", "TLAB", "UseNewCode", + "Xmn", + "Xms", + "Xmx", + "Xss", // The following substrings are only part of one VM flag (=exact match) "CreateCoredumpOnCrash", "IgnoreUnrecognizedVMOptions", @@ -117,7 +121,11 @@ public class TestFramework { "UnlockExperimentalVMOptions", "BackgroundCompilation", "Xbatch", - "TieredCompilation" + "TieredCompilation", + "Xmixed", + "server", + "Xlog", + "LogCompilation" ) );