Mercurial > hg > truffle
comparison test/compiler/whitebox/CompilerWhiteBoxTest.java @ 10143:c4af77d20454 hs25-b30
Merge
author | amurillo |
---|---|
date | Fri, 26 Apr 2013 00:29:11 -0700 |
parents | 4b2eebe03f93 |
children | d1c9384eecb4 |
comparison
equal
deleted
inserted
replaced
10124:d080f5168deb | 10143:c4af77d20454 |
---|---|
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 } |