test/compiler/tiered/LevelTransitionTest.java

Mon, 03 Jun 2019 16:14:54 +0100

author
xliu
date
Mon, 03 Jun 2019 16:14:54 +0100
changeset 9689
89dcef434423
permissions
-rw-r--r--

8059575: JEP-JDK-8043304: Test task: Tiered Compilation level transition tests
Summary: Includes compile_id addition from JDK-8054492
Reviewed-by: andrew

xliu@9689 1 /*
xliu@9689 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
xliu@9689 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
xliu@9689 4 *
xliu@9689 5 * This code is free software; you can redistribute it and/or modify it
xliu@9689 6 * under the terms of the GNU General Public License version 2 only, as
xliu@9689 7 * published by the Free Software Foundation.
xliu@9689 8 *
xliu@9689 9 * This code is distributed in the hope that it will be useful, but WITHOUT
xliu@9689 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
xliu@9689 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
xliu@9689 12 * version 2 for more details (a copy is included in the LICENSE file that
xliu@9689 13 * accompanied this code).
xliu@9689 14 *
xliu@9689 15 * You should have received a copy of the GNU General Public License version
xliu@9689 16 * 2 along with this work; if not, write to the Free Software Foundation,
xliu@9689 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
xliu@9689 18 *
xliu@9689 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
xliu@9689 20 * or visit www.oracle.com if you need additional information or have any
xliu@9689 21 * questions.
xliu@9689 22 */
xliu@9689 23
xliu@9689 24 import java.lang.reflect.Executable;
xliu@9689 25 import java.lang.reflect.Method;
xliu@9689 26 import java.util.Objects;
xliu@9689 27 import java.util.concurrent.Callable;
xliu@9689 28
xliu@9689 29 /**
xliu@9689 30 * @test LevelTransitionTest
xliu@9689 31 * @library /testlibrary /testlibrary/whitebox /compiler/whitebox
xliu@9689 32 * @build TransitionsTestExecutor LevelTransitionTest
xliu@9689 33 * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
xliu@9689 34 * @run main/othervm/timeout=240 -Xmixed -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
xliu@9689 35 * -XX:+WhiteBoxAPI -XX:+TieredCompilation
xliu@9689 36 * -XX:CompileCommand=compileonly,SimpleTestCase$Helper::*
xliu@9689 37 * -XX:CompileCommand=compileonly,ExtendedTestCase$CompileMethodHolder::*
xliu@9689 38 * TransitionsTestExecutor LevelTransitionTest
xliu@9689 39 * @summary Test the correctness of compilation level transitions for different methods
xliu@9689 40 */
xliu@9689 41 public class LevelTransitionTest extends TieredLevelsTest {
xliu@9689 42 /** Shows if method was profiled by being executed on levels 2 or 3 */
xliu@9689 43 protected boolean isMethodProfiled;
xliu@9689 44 private int transitionCount;
xliu@9689 45
xliu@9689 46 public static void main(String[] args) throws Throwable {
xliu@9689 47 assert (!CompilerWhiteBoxTest.skipOnTieredCompilation(false));
xliu@9689 48
xliu@9689 49 CompilerWhiteBoxTest.main(LevelTransitionTest::new, args);
xliu@9689 50 // run extended test cases
xliu@9689 51 for (TestCase testCase : ExtendedTestCase.values()) {
xliu@9689 52 new LevelTransitionTest(testCase).runTest();
xliu@9689 53 }
xliu@9689 54 }
xliu@9689 55
xliu@9689 56 protected LevelTransitionTest(TestCase testCase) {
xliu@9689 57 super(testCase);
xliu@9689 58 isMethodProfiled = testCase.isOsr(); // OSR methods were already profiled by warmup
xliu@9689 59 transitionCount = 0;
xliu@9689 60 }
xliu@9689 61
xliu@9689 62 @Override
xliu@9689 63 protected void test() throws Exception {
xliu@9689 64 checkTransitions();
xliu@9689 65 deoptimize();
xliu@9689 66 printInfo();
xliu@9689 67 if (testCase.isOsr()) {
xliu@9689 68 // deoptimization makes the following transitions be unstable
xliu@9689 69 // methods go to level 3 before 4 because of uncommon_trap and reprofile
xliu@9689 70 return;
xliu@9689 71 }
xliu@9689 72 checkTransitions();
xliu@9689 73 }
xliu@9689 74
xliu@9689 75 /**
xliu@9689 76 * Makes and verifies transitions between compilation levels
xliu@9689 77 */
xliu@9689 78 protected void checkTransitions() {
xliu@9689 79 checkNotCompiled();
xliu@9689 80 boolean finish = false;
xliu@9689 81 while (!finish) {
xliu@9689 82 System.out.printf("Level transition #%d%n", ++transitionCount);
xliu@9689 83 int newLevel;
xliu@9689 84 int current = getCompLevel();
xliu@9689 85 int expected = getNextLevel(current);
xliu@9689 86 if (current == expected) {
xliu@9689 87 // if we are on expected level, just execute it more
xliu@9689 88 // to ensure that the level won't change
xliu@9689 89 System.out.printf("Method %s is already on expected level %d%n", method, expected);
xliu@9689 90 compile();
xliu@9689 91 newLevel = getCompLevel();
xliu@9689 92 finish = true;
xliu@9689 93 } else {
xliu@9689 94 newLevel = changeCompLevel();
xliu@9689 95 finish = false;
xliu@9689 96 }
xliu@9689 97 System.out.printf("Method %s is compiled on level %d. Expected level is %d%n", method, newLevel, expected);
xliu@9689 98 checkLevel(expected, newLevel);
xliu@9689 99 printInfo();
xliu@9689 100 };
xliu@9689 101 }
xliu@9689 102
xliu@9689 103 /**
xliu@9689 104 * Gets next expected level for the test case on each transition.
xliu@9689 105 *
xliu@9689 106 * @param currentLevel a level the test case is compiled on
xliu@9689 107 * @return expected compilation level
xliu@9689 108 */
xliu@9689 109 protected int getNextLevel(int currentLevel) {
xliu@9689 110 int nextLevel = currentLevel;
xliu@9689 111 switch (currentLevel) {
xliu@9689 112 case CompilerWhiteBoxTest.COMP_LEVEL_NONE:
xliu@9689 113 nextLevel = isMethodProfiled ? CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION
xliu@9689 114 : CompilerWhiteBoxTest.COMP_LEVEL_FULL_PROFILE;
xliu@9689 115 break;
xliu@9689 116 case CompilerWhiteBoxTest.COMP_LEVEL_LIMITED_PROFILE:
xliu@9689 117 case CompilerWhiteBoxTest.COMP_LEVEL_FULL_PROFILE:
xliu@9689 118 nextLevel = CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION;
xliu@9689 119 isMethodProfiled = true;
xliu@9689 120 break;
xliu@9689 121 }
xliu@9689 122 nextLevel = isTrivial() ? CompilerWhiteBoxTest.COMP_LEVEL_SIMPLE : nextLevel;
xliu@9689 123 return Math.min(nextLevel, CompilerWhiteBoxTest.TIERED_STOP_AT_LEVEL);
xliu@9689 124 }
xliu@9689 125
xliu@9689 126 /**
xliu@9689 127 * Determines if tested method should be handled as trivial
xliu@9689 128 *
xliu@9689 129 * @return {@code true} for trivial methods, {@code false} otherwise
xliu@9689 130 */
xliu@9689 131 protected boolean isTrivial() {
xliu@9689 132 return testCase == ExtendedTestCase.ACCESSOR_TEST
xliu@9689 133 || testCase == SimpleTestCase.METHOD_TEST
xliu@9689 134 || testCase == SimpleTestCase.STATIC_TEST
xliu@9689 135 || (testCase == ExtendedTestCase.TRIVIAL_CODE_TEST && isMethodProfiled);
xliu@9689 136 }
xliu@9689 137
xliu@9689 138 /**
xliu@9689 139 * Invokes {@linkplain #method} until its compilation level is changed.
xliu@9689 140 * Note that if the level won't change, it will be an endless loop
xliu@9689 141 *
xliu@9689 142 * @return compilation level the {@linkplain #method} was compiled on
xliu@9689 143 */
xliu@9689 144 protected int changeCompLevel() {
xliu@9689 145 int currentLevel = getCompLevel();
xliu@9689 146 int newLevel = currentLevel;
xliu@9689 147 int result = 0;
xliu@9689 148 while (currentLevel == newLevel) {
xliu@9689 149 result = compile(1);
xliu@9689 150 if (WHITE_BOX.isMethodCompiled(method, testCase.isOsr())) {
xliu@9689 151 newLevel = getCompLevel();
xliu@9689 152 }
xliu@9689 153 }
xliu@9689 154 return newLevel;
xliu@9689 155 }
xliu@9689 156
xliu@9689 157 protected static class Helper {
xliu@9689 158 /**
xliu@9689 159 * Gets method from a specified class using its name
xliu@9689 160 *
xliu@9689 161 * @param aClass type method belongs to
xliu@9689 162 * @param name the name of the method
xliu@9689 163 * @return {@link Method} that represents corresponding class method
xliu@9689 164 */
xliu@9689 165 public static Method getMethod(Class<?> aClass, String name) {
xliu@9689 166 Method method;
xliu@9689 167 try {
xliu@9689 168 method = aClass.getDeclaredMethod(name);
xliu@9689 169 } catch (NoSuchMethodException e) {
xliu@9689 170 throw new Error("TESTBUG: Unable to get method " + name, e);
xliu@9689 171 }
xliu@9689 172 return method;
xliu@9689 173 }
xliu@9689 174
xliu@9689 175 /**
xliu@9689 176 * Gets {@link Callable} that invokes given method from the given object
xliu@9689 177 *
xliu@9689 178 * @param object the object the specified method is invoked from
xliu@9689 179 * @param name the name of the method
xliu@9689 180 */
xliu@9689 181 public static Callable<Integer> getCallable(Object object, String name) {
xliu@9689 182 Method method = getMethod(object.getClass(), name);
xliu@9689 183 return () -> {
xliu@9689 184 try {
xliu@9689 185 return Objects.hashCode(method.invoke(object));
xliu@9689 186 } catch (ReflectiveOperationException e) {
xliu@9689 187 throw new Error("TESTBUG: Invocation failure", e);
xliu@9689 188 }
xliu@9689 189 };
xliu@9689 190 }
xliu@9689 191 }
xliu@9689 192 }
xliu@9689 193
xliu@9689 194 enum ExtendedTestCase implements CompilerWhiteBoxTest.TestCase {
xliu@9689 195 ACCESSOR_TEST("accessor"),
xliu@9689 196 NONTRIVIAL_METHOD_TEST("nonTrivialMethod"),
xliu@9689 197 TRIVIAL_CODE_TEST("trivialCode");
xliu@9689 198
xliu@9689 199 private final Executable executable;
xliu@9689 200 private final Callable<Integer> callable;
xliu@9689 201
xliu@9689 202 @Override
xliu@9689 203 public Executable getExecutable() {
xliu@9689 204 return executable;
xliu@9689 205 }
xliu@9689 206
xliu@9689 207 @Override
xliu@9689 208 public Callable<Integer> getCallable() {
xliu@9689 209 return callable;
xliu@9689 210 }
xliu@9689 211
xliu@9689 212 @Override
xliu@9689 213 public boolean isOsr() {
xliu@9689 214 return false;
xliu@9689 215 }
xliu@9689 216
xliu@9689 217 private ExtendedTestCase(String methodName) {
xliu@9689 218 this.executable = LevelTransitionTest.Helper.getMethod(CompileMethodHolder.class, methodName);
xliu@9689 219 this.callable = LevelTransitionTest.Helper.getCallable(new CompileMethodHolder(), methodName);
xliu@9689 220 }
xliu@9689 221
xliu@9689 222 private static class CompileMethodHolder {
xliu@9689 223 private final int iter = 10;
xliu@9689 224 private int field = 42;
xliu@9689 225
xliu@9689 226 /** Non-trivial method for threshold policy: contains loops */
xliu@9689 227 public int nonTrivialMethod() {
xliu@9689 228 int acc = 0;
xliu@9689 229 for (int i = 0; i < iter; i++) {
xliu@9689 230 acc += i;
xliu@9689 231 }
xliu@9689 232 return acc;
xliu@9689 233 }
xliu@9689 234
xliu@9689 235 /** Field accessor method */
xliu@9689 236 public int accessor() {
xliu@9689 237 return field;
xliu@9689 238 }
xliu@9689 239
xliu@9689 240 /** Method considered as trivial by amount of code */
xliu@9689 241 public int trivialCode() {
xliu@9689 242 int var = 0xBAAD_C0DE;
xliu@9689 243 var *= field;
xliu@9689 244 return var;
xliu@9689 245 }
xliu@9689 246 }
xliu@9689 247 }

mercurial