Mon, 03 Jun 2019 16:14:54 +0100
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 | } |