comparison test/compiler/whitebox/CompilerWhiteBoxTest.java @ 10113:4b2eebe03f93

8011971: WB API doesn't accept j.l.reflect.Constructor Reviewed-by: kvn, vlivanov
author iignatyev
date Tue, 16 Apr 2013 10:04:01 -0700
parents b84fd7d73702
children d1c9384eecb4
comparison
equal deleted inserted replaced
10112:c89eab0b6b30 10113:4b2eebe03f93
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 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 20 * or visit www.oracle.com if you need additional information or have any
21 * questions. 21 * questions.
22 */ 22 */
23 23
24 import com.sun.management.HotSpotDiagnosticMXBean;
25 import com.sun.management.VMOption;
24 import sun.hotspot.WhiteBox; 26 import sun.hotspot.WhiteBox;
25 import sun.management.ManagementFactoryHelper; 27 import sun.management.ManagementFactoryHelper;
26 import com.sun.management.HotSpotDiagnosticMXBean; 28
27 29 import java.lang.reflect.Constructor;
30 import java.lang.reflect.Executable;
28 import java.lang.reflect.Method; 31 import java.lang.reflect.Method;
29 32 import java.util.Objects;
30 /* 33 import java.util.concurrent.Callable;
34
35 /**
36 * Abstract class for WhiteBox testing of JIT.
37 *
31 * @author igor.ignatyev@oracle.com 38 * @author igor.ignatyev@oracle.com
32 */ 39 */
33 public abstract class CompilerWhiteBoxTest { 40 public abstract class CompilerWhiteBoxTest {
41 /** {@code CompLevel::CompLevel_none} -- Interpreter */
42 protected static int COMP_LEVEL_NONE = 0;
43 /** {@code CompLevel::CompLevel_any}, {@code CompLevel::CompLevel_all} */
44 protected static int COMP_LEVEL_ANY = -1;
45 /** Instance of WhiteBox */
34 protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 46 protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
35 protected static final Method METHOD = getMethod("method"); 47 /** Value of {@code -XX:CompileThreshold} */
36 protected static final int COMPILE_THRESHOLD 48 protected static final int COMPILE_THRESHOLD
37 = Integer.parseInt(getVMOption("CompileThreshold", "10000")); 49 = Integer.parseInt(getVMOption("CompileThreshold", "10000"));
50 /** Value of {@code -XX:BackgroundCompilation} */
38 protected static final boolean BACKGROUND_COMPILATION 51 protected static final boolean BACKGROUND_COMPILATION
39 = Boolean.valueOf(getVMOption("BackgroundCompilation", "true")); 52 = Boolean.valueOf(getVMOption("BackgroundCompilation", "true"));
53 /** Value of {@code -XX:TieredCompilation} */
40 protected static final boolean TIERED_COMPILATION 54 protected static final boolean TIERED_COMPILATION
41 = Boolean.valueOf(getVMOption("TieredCompilation", "false")); 55 = Boolean.valueOf(getVMOption("TieredCompilation", "false"));
42 56 /** Value of {@code -XX:TieredStopAtLevel} */
43 protected static Method getMethod(String name) { 57 protected static final int TIERED_STOP_AT_LEVEL
44 try { 58 = Integer.parseInt(getVMOption("TieredStopAtLevel", "0"));
45 return CompilerWhiteBoxTest.class.getDeclaredMethod(name); 59
46 } catch (NoSuchMethodException | SecurityException e) { 60 /**
47 throw new RuntimeException( 61 * Returns value of VM option.
48 "exception on getting method " + name, e); 62 *
49 } 63 * @param name option's name
50 } 64 * @return value of option or {@code null}, if option doesn't exist
51 65 * @throws NullPointerException if name is null
66 */
52 protected static String getVMOption(String name) { 67 protected static String getVMOption(String name) {
53 String result; 68 Objects.requireNonNull(name);
54 HotSpotDiagnosticMXBean diagnostic 69 HotSpotDiagnosticMXBean diagnostic
55 = ManagementFactoryHelper.getDiagnosticMXBean(); 70 = ManagementFactoryHelper.getDiagnosticMXBean();
56 result = diagnostic.getVMOption(name).getValue(); 71 VMOption tmp;
57 return result; 72 try {
58 } 73 tmp = diagnostic.getVMOption(name);
59 74 } catch (IllegalArgumentException e) {
75 tmp = null;
76 }
77 return (tmp == null ? null : tmp.getValue());
78 }
79
80 /**
81 * Returns value of VM option or default value.
82 *
83 * @param name option's name
84 * @param defaultValue default value
85 * @return value of option or {@code defaultValue}, if option doesn't exist
86 * @throws NullPointerException if name is null
87 * @see #getVMOption(String)
88 */
60 protected static String getVMOption(String name, String defaultValue) { 89 protected static String getVMOption(String name, String defaultValue) {
61 String result = getVMOption(name); 90 String result = getVMOption(name);
62 return result == null ? defaultValue : result; 91 return result == null ? defaultValue : result;
63 } 92 }
64 93
65 protected final void runTest() throws RuntimeException { 94 /** tested method */
95 protected final Executable method;
96 private final Callable<Integer> callable;
97
98 /**
99 * Constructor.
100 *
101 * @param testCase object, that contains tested method and way to invoke it.
102 */
103 protected CompilerWhiteBoxTest(TestCase testCase) {
104 Objects.requireNonNull(testCase);
105 System.out.println("TEST CASE:" + testCase.name());
106 method = testCase.executable;
107 callable = testCase.callable;
108 }
109
110 /**
111 * Template method for testing. Prints tested method's info before
112 * {@linkplain #test()} and after {@linkplain #test()} or on thrown
113 * exception.
114 *
115 * @throws RuntimeException if method {@linkplain #test()} throws any
116 * exception
117 * @see #test()
118 */
119 protected final void runTest() {
66 if (ManagementFactoryHelper.getCompilationMXBean() == null) { 120 if (ManagementFactoryHelper.getCompilationMXBean() == null) {
67 System.err.println( 121 System.err.println(
68 "Warning: test is not applicable in interpreted mode"); 122 "Warning: test is not applicable in interpreted mode");
69 return; 123 return;
70 } 124 }
71 System.out.println("at test's start:"); 125 System.out.println("at test's start:");
72 printInfo(METHOD); 126 printInfo();
73 try { 127 try {
74 test(); 128 test();
75 } catch (Exception e) { 129 } catch (Exception e) {
76 System.out.printf("on exception '%s':", e.getMessage()); 130 System.out.printf("on exception '%s':", e.getMessage());
77 printInfo(METHOD); 131 printInfo();
78 e.printStackTrace(); 132 e.printStackTrace();
133 if (e instanceof RuntimeException) {
134 throw (RuntimeException) e;
135 }
79 throw new RuntimeException(e); 136 throw new RuntimeException(e);
80 } 137 }
81 System.out.println("at test's end:"); 138 System.out.println("at test's end:");
82 printInfo(METHOD); 139 printInfo();
83 } 140 }
84 141
85 protected static void checkNotCompiled(Method method) { 142 /**
143 * Checks, that {@linkplain #method} is not compiled.
144 *
145 * @throws RuntimeException if {@linkplain #method} is in compiler queue or
146 * is compiled, or if {@linkplain #method} has zero
147 * compilation level.
148 */
149 protected final void checkNotCompiled() {
86 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { 150 if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
87 throw new RuntimeException(method + " must not be in queue"); 151 throw new RuntimeException(method + " must not be in queue");
88 } 152 }
89 if (WHITE_BOX.isMethodCompiled(method)) { 153 if (WHITE_BOX.isMethodCompiled(method)) {
90 throw new RuntimeException(method + " must be not compiled"); 154 throw new RuntimeException(method + " must be not compiled");
92 if (WHITE_BOX.getMethodCompilationLevel(method) != 0) { 156 if (WHITE_BOX.getMethodCompilationLevel(method) != 0) {
93 throw new RuntimeException(method + " comp_level must be == 0"); 157 throw new RuntimeException(method + " comp_level must be == 0");
94 } 158 }
95 } 159 }
96 160
97 protected static void checkCompiled(Method method) 161 /**
98 throws InterruptedException { 162 * Checks, that {@linkplain #method} is compiled.
163 *
164 * @throws RuntimeException if {@linkplain #method} isn't in compiler queue
165 * and isn't compiled, or if {@linkplain #method}
166 * has nonzero compilation level
167 */
168 protected final void checkCompiled() {
99 final long start = System.currentTimeMillis(); 169 final long start = System.currentTimeMillis();
100 waitBackgroundCompilation(method); 170 waitBackgroundCompilation();
101 if (WHITE_BOX.isMethodQueuedForCompilation(method)) { 171 if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
102 System.err.printf("Warning: %s is still in queue after %dms%n", 172 System.err.printf("Warning: %s is still in queue after %dms%n",
103 method, System.currentTimeMillis() - start); 173 method, System.currentTimeMillis() - start);
104 return; 174 return;
105 } 175 }
109 if (WHITE_BOX.getMethodCompilationLevel(method) == 0) { 179 if (WHITE_BOX.getMethodCompilationLevel(method) == 0) {
110 throw new RuntimeException(method + " comp_level must be != 0"); 180 throw new RuntimeException(method + " comp_level must be != 0");
111 } 181 }
112 } 182 }
113 183
114 protected static void waitBackgroundCompilation(Method method) 184 /**
115 throws InterruptedException { 185 * Waits for completion of background compilation of {@linkplain #method}.
186 */
187 protected final void waitBackgroundCompilation() {
116 if (!BACKGROUND_COMPILATION) { 188 if (!BACKGROUND_COMPILATION) {
117 return; 189 return;
118 } 190 }
119 final Object obj = new Object(); 191 final Object obj = new Object();
120 synchronized (obj) { 192 for (int i = 0; i < 10
121 for (int i = 0; i < 10; ++i) { 193 && WHITE_BOX.isMethodQueuedForCompilation(method); ++i) {
122 if (!WHITE_BOX.isMethodQueuedForCompilation(method)) { 194 synchronized (obj) {
123 break; 195 try {
196 obj.wait(1000);
197 } catch (InterruptedException e) {
198 Thread.currentThread().interrupt();
124 } 199 }
125 obj.wait(1000); 200 }
126 } 201 }
127 } 202 }
128 } 203
129 204 /**
130 protected static void printInfo(Method method) { 205 * Prints information about {@linkplain #method}.
206 */
207 protected final void printInfo() {
131 System.out.printf("%n%s:%n", method); 208 System.out.printf("%n%s:%n", method);
132 System.out.printf("\tcompilable:\t%b%n", 209 System.out.printf("\tcompilable:\t%b%n",
133 WHITE_BOX.isMethodCompilable(method)); 210 WHITE_BOX.isMethodCompilable(method));
134 System.out.printf("\tcompiled:\t%b%n", 211 System.out.printf("\tcompiled:\t%b%n",
135 WHITE_BOX.isMethodCompiled(method)); 212 WHITE_BOX.isMethodCompiled(method));
139 WHITE_BOX.isMethodQueuedForCompilation(method)); 216 WHITE_BOX.isMethodQueuedForCompilation(method));
140 System.out.printf("compile_queues_size:\t%d%n%n", 217 System.out.printf("compile_queues_size:\t%d%n%n",
141 WHITE_BOX.getCompileQueuesSize()); 218 WHITE_BOX.getCompileQueuesSize());
142 } 219 }
143 220
221 /**
222 * Executes testing.
223 */
144 protected abstract void test() throws Exception; 224 protected abstract void test() throws Exception;
145 225
226 /**
227 * Tries to trigger compilation of {@linkplain #method} by call
228 * {@linkplain #callable} enough times.
229 *
230 * @return accumulated result
231 * @see #compile(int)
232 */
146 protected final int compile() { 233 protected final int compile() {
147 return compile(Math.max(COMPILE_THRESHOLD, 150000)); 234 return compile(Math.max(COMPILE_THRESHOLD, 150000));
148 } 235 }
149 236
237 /**
238 * Tries to trigger compilation of {@linkplain #method} by call
239 * {@linkplain #callable} specified times.
240 *
241 * @param count invocation count
242 * @return accumulated result
243 */
150 protected final int compile(int count) { 244 protected final int compile(int count) {
151 int result = 0; 245 int result = 0;
246 Integer tmp;
152 for (int i = 0; i < count; ++i) { 247 for (int i = 0; i < count; ++i) {
153 result += method(); 248 try {
249 tmp = callable.call();
250 } catch (Exception e) {
251 tmp = null;
252 }
253 result += tmp == null ? 0 : tmp;
154 } 254 }
155 System.out.println("method was invoked " + count + " times"); 255 System.out.println("method was invoked " + count + " times");
156 return result; 256 return result;
157 } 257 }
158
159 protected int method() {
160 return 42;
161 }
162 } 258 }
259
260 /**
261 * Utility structure containing tested method and object to invoke it.
262 */
263 enum TestCase {
264 /** constructor test case */
265 CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE),
266 /** method test case */
267 METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE),
268 /** static method test case */
269 STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE);
270
271 /** tested method */
272 final Executable executable;
273 /** object to invoke {@linkplain #executable} */
274 final Callable<Integer> callable;
275
276 private TestCase(Executable executable, Callable<Integer> callable) {
277 this.executable = executable;
278 this.callable = callable;
279 }
280
281 private static class Helper {
282 private static final Callable<Integer> CONSTRUCTOR_CALLABLE
283 = new Callable<Integer>() {
284 @Override
285 public Integer call() throws Exception {
286 return new Helper(1337).hashCode();
287 }
288 };
289
290 private static final Callable<Integer> METHOD_CALLABLE
291 = new Callable<Integer>() {
292 private final Helper helper = new Helper();
293
294 @Override
295 public Integer call() throws Exception {
296 return helper.method();
297 }
298 };
299
300 private static final Callable<Integer> STATIC_CALLABLE
301 = new Callable<Integer>() {
302 @Override
303 public Integer call() throws Exception {
304 return staticMethod();
305 }
306 };
307
308 private static final Constructor CONSTRUCTOR;
309 private static final Method METHOD;
310 private static final Method STATIC;
311
312 static {
313 try {
314 CONSTRUCTOR = Helper.class.getDeclaredConstructor(int.class);
315 } catch (NoSuchMethodException | SecurityException e) {
316 throw new RuntimeException(
317 "exception on getting method Helper.<init>(int)", e);
318 }
319 try {
320 METHOD = Helper.class.getDeclaredMethod("method");
321 } catch (NoSuchMethodException | SecurityException e) {
322 throw new RuntimeException(
323 "exception on getting method Helper.method()", e);
324 }
325 try {
326 STATIC = Helper.class.getDeclaredMethod("staticMethod");
327 } catch (NoSuchMethodException | SecurityException e) {
328 throw new RuntimeException(
329 "exception on getting method Helper.staticMethod()", e);
330 }
331 }
332
333 private static int staticMethod() {
334 return 1138;
335 }
336
337 private int method() {
338 return 42;
339 }
340
341 private final int x;
342
343 public Helper() {
344 x = 0;
345 }
346
347 private Helper(int x) {
348 this.x = x;
349 }
350
351 @Override
352 public int hashCode() {
353 return x;
354 }
355 }
356 }