1 /* 2 * Copyright (c) 2016 SAP SE. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8150646 27 * @summary Add support for blocking compiles through whitebox API 28 * @library /testlibrary /test/lib / 29 * @ignore This test is too shaky to run it automatically (see 8151796) 30 * @build sun.hotspot.WhiteBox 31 * compiler.testlibrary.CompilerUtils 32 * @run main ClassFileInstaller sun.hotspot.WhiteBox 33 * sun.hotspot.WhiteBox$WhiteBoxPermission 34 * 35 * @run main/othervm 36 * -Xbootclasspath/a:. 37 * -Xmixed 38 * -XX:+UnlockDiagnosticVMOptions 39 * -XX:+WhiteBoxAPI 40 * -XX:+PrintCompilation 41 * -XX:CompileCommand=option,BlockingCompilation::foo,PrintInlining 42 * BlockingCompilation 43 */ 44 45 import java.lang.reflect.Method; 46 import java.util.Random; 47 48 import sun.hotspot.WhiteBox; 49 import compiler.testlibrary.CompilerUtils; 50 51 public class BlockingCompilation { 52 private static final WhiteBox WB = WhiteBox.getWhiteBox(); 53 private static final Random RANDOM = new Random(); 54 55 public static int foo() { 56 return RANDOM.nextInt(); 57 } 58 59 public static void main(String[] args) throws Exception { 60 long sum = 0; 61 int level = 0; 62 boolean enqued = false; 63 Method m = BlockingCompilation.class.getMethod("foo"); 64 int[] levels = CompilerUtils.getAvailableCompilationLevels(); 65 66 // If there are no compilers available these tests don't make any sense. 67 if (levels.length == 0) return; 68 int max_level = levels[levels.length - 1]; 69 70 // Normal, non-blocking compilation 71 for (int i = 0; i < 500_000; i++) { 72 sum += foo(); 73 if (!enqued && WB.isMethodQueuedForCompilation(m)) { 74 System.out.println("==> " + m + " enqued for compilation in iteration " + i); 75 enqued = true; 76 } 77 if (WB.isMethodCompiled(m)) { 78 if (WB.getMethodCompilationLevel(m) != level) { 79 level = WB.getMethodCompilationLevel(m); 80 System.out.println("==> " + m + " compiled at level " + level + " in iteration " + i); 81 enqued = false; 82 if (level == max_level) break; 83 } 84 } 85 } 86 87 // This is necessarry because WB.deoptimizeMethod doesn't clear the methods 88 // MDO and therefore level 3 compilations will be downgraded to level 2. 89 WB.clearMethodState(m); 90 91 // Blocking compilations on all levels, using the default versions of 92 // WB.enqueueMethodForCompilation() and manually setting compiler directives. 93 String directive = "[{ match: \"BlockingCompilation.foo\", BackgroundCompilation: false }]"; 94 WB.addCompilerDirective(directive); 95 96 for (int l : levels) { 97 WB.deoptimizeMethod(m); 98 WB.enqueueMethodForCompilation(m, l); 99 100 if (!WB.isMethodCompiled(m) || WB.getMethodCompilationLevel(m) != l) { 101 String msg = m + " should be compiled at level " + l + 102 "(but is actually compiled at level " + 103 WB.getMethodCompilationLevel(m) + ")"; 104 System.out.println("==> " + msg); 105 throw new Exception(msg); 106 } 107 } 108 109 WB.removeCompilerDirective(1); 110 111 WB.deoptimizeMethod(m); 112 WB.clearMethodState(m); 113 level = 0; 114 enqued = false; 115 int iteration = 0; 116 117 // Normal, non-blocking compilation 118 for (int i = 0; i < 500_000; i++) { 119 sum += foo(); 120 if (!enqued && WB.isMethodQueuedForCompilation(m)) { 121 System.out.println("==> " + m + " enqued for compilation in iteration " + i); 122 iteration = i; 123 enqued = true; 124 } 125 if (WB.isMethodCompiled(m)) { 126 if (WB.getMethodCompilationLevel(m) != level) { 127 level = WB.getMethodCompilationLevel(m); 128 System.out.println("==> " + m + " compiled at level " + level + " in iteration " + i); 129 if (level == 4 && iteration == i) { 130 throw new Exception("This seems to be a blocking compilation although it shouldn't."); 131 } 132 enqued = false; 133 if (level == max_level) break; 134 } 135 } 136 } 137 } 138 }