jdk-24/test/hotspot/jtreg/compiler/lib/ir_framework/CompLevel.java
Christian Hagedorn 3396b69fc9 8254129: IR Test Framework to support regex-based matching on the IR in JTreg compiler tests
Co-authored-by: Christian Hagedorn <chagedorn@openjdk.org>
Co-authored-by: Tobias Hartmann <thartmann@openjdk.org>
Reviewed-by: iignatyev
2021-06-07 14:11:50 +00:00

172 lines
6.1 KiB
Java

/*
* 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.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;
import java.util.HashMap;
import java.util.Map;
/**
* 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.
*
* <p>
* The compilation levels can be specified in the {@link Test}, {@link ForceCompile}, and
* {@link ForceCompileClassInitializer} annotation.
*
* @see Test
* @see ForceCompile
* @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 -DExcludeRandom=true}.
*/
WAIT_FOR_COMPILATION(-4),
/**
* Can only be used at {@link Test#compLevel()}. Skip a compilation of the {@link Test @Test} method completely.
*/
SKIP(-3),
/**
* Use any compilation level depending on the usage:
* <ul>
* <li><p>{@link Test @Test}, {@link ForceCompile @ForceCompile}: Use the highest available compilation level
* which is usually C2.</li>
* <li><p>{@link DontCompile @DontCompile}: Prevents any compilation of the associated helper method.</li>
* </ul>
*/
ANY(-1),
/**
* Compilation level 1: C1 compilation without any profile information.
*/
C1_SIMPLE(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<Integer, CompLevel> TYPES_BY_VALUE = new HashMap<>();
private final int value;
static {
for (CompLevel level : CompLevel.values()) {
TYPES_BY_VALUE.put(level.value, level);
}
}
CompLevel(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;
}
/**
* 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) {
CompLevel level = TYPES_BY_VALUE.get(value);
TestRun.check(level != null, "Invalid compilation level " + value);
return level;
}
/**
* Called by {@link TestFramework} to check if this compilation level is not part of the compiler.
*/
public 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);
};
}
/**
* Called by {@link TestFramework} to flip compilation levels.
*/
public CompLevel flipCompLevel() {
switch (this) {
case C1_SIMPLE, C1_LIMITED_PROFILE, C1_FULL_PROFILE -> {
return CompLevel.C2;
}
case C2 -> {
return CompLevel.C1_SIMPLE;
}
}
return this;
}
/**
* Called by {@link TestFramework}. Return the compilation level when only allowing a compilation with the specified
* compiler.
*/
public CompLevel excludeCompilationRandomly(Executable ex) {
if (Utils.getRandomInstance().nextBoolean()) {
// No exclusion
return this;
}
Compiler compiler = TestVM.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_SIMPLE || this == C1_LIMITED_PROFILE || this == C1_FULL_PROFILE;
}
}