1 /* 2 * Copyright (c) 2013, Oracle and/or its affiliates. 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 import sun.hotspot.WhiteBox; 25 import sun.management.ManagementFactoryHelper; 26 import com.sun.management.HotSpotDiagnosticMXBean; 27 28 import java.lang.reflect.Method; 29 30 /* 31 * @author igor.ignatyev@oracle.com 32 */ 33 public abstract class CompilerWhiteBoxTest { 34 protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 35 protected static final Method METHOD = getMethod("method"); 36 protected static final int COMPILE_THRESHOLD 37 = Integer.parseInt(getVMOption("CompileThreshold", "10000")); 38 protected static final boolean BACKGROUND_COMPILATION 39 = Boolean.valueOf(getVMOption("BackgroundCompilation", "true")); 40 protected static final boolean TIERED_COMPILATION 41 = Boolean.valueOf(getVMOption("TieredCompilation", "false")); 42 43 protected static Method getMethod(String name) { 44 try { 45 return CompilerWhiteBoxTest.class.getDeclaredMethod(name); 46 } catch (NoSuchMethodException | SecurityException e) { 47 throw new RuntimeException( 48 "exception on getting method " + name, e); 49 } 50 } 51 52 protected static String getVMOption(String name) { 53 String result; 54 HotSpotDiagnosticMXBean diagnostic 55 = ManagementFactoryHelper.getDiagnosticMXBean(); 56 result = diagnostic.getVMOption(name).getValue(); 57 return result; 58 } 59 60 protected static String getVMOption(String name, String defaultValue) { 61 String result = getVMOption(name); 62 return result == null ? defaultValue : result; 63 } 64 65 protected final void runTest() throws RuntimeException { 66 if (ManagementFactoryHelper.getCompilationMXBean() == null) { 67 System.err.println( 68 "Warning: test is not applicable in interpreted mode"); 69 return; 70 } 71 System.out.println("at test's start:"); 72 printInfo(METHOD); 73 try { 74 test(); 75 } catch (Exception e) { 76 System.out.printf("on exception '%s':", e.getMessage()); 77 printInfo(METHOD); 78 e.printStackTrace(); 79 throw new RuntimeException(e); 80 } 81 System.out.println("at test's end:"); 82 printInfo(METHOD); 83 } 84 85 protected static void checkNotCompiled(Method method) { 86 if (WHITE_BOX.isMethodQueuedForCompilation(METHOD)) { 87 throw new RuntimeException(METHOD + " must not be in queue"); 88 } 89 if (WHITE_BOX.isMethodCompiled(method)) { 90 throw new RuntimeException(method + " must be not compiled"); 91 } 92 if (WHITE_BOX.getMethodCompilationLevel(method) != 0) { 93 throw new RuntimeException(method + " comp_level must be == 0"); 94 } 95 } 96 97 protected static void checkCompiled(Method method) 98 throws InterruptedException { 99 final long start = System.currentTimeMillis(); 100 waitBackgroundCompilation(method); 101 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { 102 System.err.printf("Warning: %s is still in queue after %dms%n", 103 method, System.currentTimeMillis() - start); 104 return; 105 } 106 if (!WHITE_BOX.isMethodCompiled(method)) { 107 throw new RuntimeException(method + " must be compiled"); 108 } 109 if (WHITE_BOX.getMethodCompilationLevel(method) == 0) { 110 throw new RuntimeException(method + " comp_level must be != 0"); 111 } 112 } 113 114 protected static void waitBackgroundCompilation(Method method) 115 throws InterruptedException { 116 if (!BACKGROUND_COMPILATION) { 117 return; 118 } 119 final Object obj = new Object(); 120 synchronized (obj) { 121 for (int i = 0; i < 10; ++i) { 122 if (!WHITE_BOX.isMethodQueuedForCompilation(method)) { 123 break; 124 } 125 obj.wait(1000); 126 } 127 } 128 } 129 130 protected static void printInfo(Method method) { 131 System.out.printf("%n%s:%n", method); 132 System.out.printf("\tcompilable:\t%b%n", 133 WHITE_BOX.isMethodCompilable(method)); 134 System.out.printf("\tcompiled:\t%b%n", 135 WHITE_BOX.isMethodCompiled(method)); 136 System.out.printf("\tcomp_level:\t%d%n", 137 WHITE_BOX.getMethodCompilationLevel(method)); 138 System.out.printf("\tin_queue:\t%b%n", 139 WHITE_BOX.isMethodQueuedForCompilation(method)); 140 System.out.printf("compile_queues_size:\t%d%n%n", 141 WHITE_BOX.getCompileQueuesSize()); 142 } 143 144 protected abstract void test() throws Exception; 145 146 protected final int compile() { 147 return compile(Math.max(COMPILE_THRESHOLD, 150000)); 148 } 149 150 protected final int compile(int count) { 151 int result = 0; 152 for (int i = 0; i < count; ++i) { 153 result += method(); 154 } 155 System.out.println("method was invoked " + count + " times"); 156 return result; 157 } 158 159 protected int method() { 160 return 42; 161 } 162 }