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