Thu, 10 Jul 2014 12:04:43 -0700
8043546: C1 optimizes @Stable instance fields with default values
Reviewed-by: kvn, jrose
1 /*
2 * Copyright (c) 2014, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 /*
27 * @test TestStableBoolean
28 * @summary tests on stable fields and arrays
29 * @library /testlibrary /testlibrary/whitebox
30 * @build TestStableBoolean StableConfiguration sun.hotspot.WhiteBox
31 * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
32 * @run main ClassFileInstaller
33 * java/lang/invoke/StableConfiguration
34 * java/lang/invoke/TestStableBoolean
35 * java/lang/invoke/TestStableBoolean$BooleanStable
36 * java/lang/invoke/TestStableBoolean$StaticBooleanStable
37 * java/lang/invoke/TestStableBoolean$VolatileBooleanStable
38 * java/lang/invoke/TestStableBoolean$BooleanArrayDim1
39 * java/lang/invoke/TestStableBoolean$BooleanArrayDim2
40 * java/lang/invoke/TestStableBoolean$BooleanArrayDim3
41 * java/lang/invoke/TestStableBoolean$BooleanArrayDim4
42 * java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim0
43 * java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim1
44 * java/lang/invoke/TestStableBoolean$NestedStableField
45 * java/lang/invoke/TestStableBoolean$NestedStableField$A
46 * java/lang/invoke/TestStableBoolean$NestedStableField1
47 * java/lang/invoke/TestStableBoolean$NestedStableField1$A
48 * java/lang/invoke/TestStableBoolean$NestedStableField2
49 * java/lang/invoke/TestStableBoolean$NestedStableField2$A
50 * java/lang/invoke/TestStableBoolean$NestedStableField3
51 * java/lang/invoke/TestStableBoolean$NestedStableField3$A
52 * java/lang/invoke/TestStableBoolean$DefaultValue
53 * java/lang/invoke/TestStableBoolean$DefaultStaticValue
54 * java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim2
55 *
56 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
57 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
58 * -server -XX:-TieredCompilation
59 * -XX:+FoldStableValues
60 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
61 * java.lang.invoke.TestStableBoolean
62 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
63 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
64 * -server -XX:-TieredCompilation
65 * -XX:-FoldStableValues
66 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
67 * java.lang.invoke.TestStableBoolean
68 *
69 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
70 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
71 * -server -XX:+TieredCompilation -XX:TieredStopAtLevel=1
72 * -XX:+FoldStableValues
73 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
74 * java.lang.invoke.TestStableBoolean
75 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
76 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
77 * -server -XX:+TieredCompilation -XX:TieredStopAtLevel=1
78 * -XX:-FoldStableValues
79 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
80 * java.lang.invoke.TestStableBoolean
81 *
82 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
83 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
84 * -client -XX:-TieredCompilation
85 * -XX:+FoldStableValues
86 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
87 * java.lang.invoke.TestStableBoolean
88 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
89 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp
90 * -client -XX:-TieredCompilation
91 * -XX:-FoldStableValues
92 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
93 * java.lang.invoke.TestStableBoolean
94 */
95 package java.lang.invoke;
97 import java.lang.reflect.InvocationTargetException;
99 public class TestStableBoolean {
100 static final boolean isStableEnabled = StableConfiguration.isStableEnabled;
101 static final boolean isServerWithStable = StableConfiguration.isServerWithStable;
103 public static void main(String[] args) throws Exception {
104 run(DefaultValue.class);
105 run(BooleanStable.class);
106 run(DefaultStaticValue.class);
107 run(StaticBooleanStable.class);
108 run(VolatileBooleanStable.class);
110 // @Stable arrays: Dim 1-4
111 run(BooleanArrayDim1.class);
112 run(BooleanArrayDim2.class);
113 run(BooleanArrayDim3.class);
114 run(BooleanArrayDim4.class);
116 // @Stable Object field: dynamic arrays
117 run(ObjectArrayLowerDim0.class);
118 run(ObjectArrayLowerDim1.class);
119 run(ObjectArrayLowerDim2.class);
121 // Nested @Stable fields
122 run(NestedStableField.class);
123 run(NestedStableField1.class);
124 run(NestedStableField2.class);
125 run(NestedStableField3.class);
127 if (failed) {
128 throw new Error("TEST FAILED");
129 }
130 }
132 /* ==================================================== */
134 static class DefaultValue {
135 public @Stable boolean v;
137 public static final DefaultValue c = new DefaultValue();
138 public static boolean get() { return c.v; }
139 public static void test() throws Exception {
140 boolean val1 = get();
141 c.v = true; boolean val2 = get();
142 assertEquals(val1, false);
143 assertEquals(val2, true);
144 }
145 }
147 /* ==================================================== */
149 static class BooleanStable {
150 public @Stable boolean v;
152 public static final BooleanStable c = new BooleanStable();
153 public static boolean get() { return c.v; }
154 public static void test() throws Exception {
155 c.v = true; boolean val1 = get();
156 c.v = false; boolean val2 = get();
157 assertEquals(val1, true);
158 assertEquals(val2, (isStableEnabled ? true : false));
159 }
160 }
162 /* ==================================================== */
164 static class DefaultStaticValue {
165 public static @Stable boolean v;
167 public static final DefaultStaticValue c = new DefaultStaticValue();
168 public static boolean get() { return c.v; }
169 public static void test() throws Exception {
170 boolean val1 = get();
171 c.v = true; boolean val2 = get();
172 assertEquals(val1, false);
173 assertEquals(val2, true);
174 }
175 }
177 /* ==================================================== */
179 static class StaticBooleanStable {
180 public static @Stable boolean v;
182 public static final StaticBooleanStable c = new StaticBooleanStable();
183 public static boolean get() { return c.v; }
184 public static void test() throws Exception {
185 c.v = true; boolean val1 = get();
186 c.v = false; boolean val2 = get();
187 assertEquals(val1, true);
188 assertEquals(val2, (isStableEnabled ? true : false));
189 }
190 }
192 /* ==================================================== */
194 static class VolatileBooleanStable {
195 public @Stable volatile boolean v;
197 public static final VolatileBooleanStable c = new VolatileBooleanStable();
198 public static boolean get() { return c.v; }
199 public static void test() throws Exception {
200 c.v = true; boolean val1 = get();
201 c.v = false; boolean val2 = get();
202 assertEquals(val1, true);
203 assertEquals(val2, (isStableEnabled ? true : false));
204 }
205 }
207 /* ==================================================== */
208 // @Stable array == field && all components are stable
210 static class BooleanArrayDim1 {
211 public @Stable boolean[] v;
213 public static final BooleanArrayDim1 c = new BooleanArrayDim1();
214 public static boolean get() { return c.v[0]; }
215 public static boolean get1() { return c.v[10]; }
216 public static boolean[] get2() { return c.v; }
217 public static void test() throws Exception {
218 {
219 c.v = new boolean[1]; c.v[0] = true; boolean val1 = get();
220 c.v[0] = false; boolean val2 = get();
221 assertEquals(val1, true);
222 assertEquals(val2, (isServerWithStable ? true : false));
223 }
225 {
226 c.v = new boolean[20]; c.v[10] = true; boolean val1 = get1();
227 c.v[10] = false; boolean val2 = get1();
228 assertEquals(val1, true);
229 assertEquals(val2, (isServerWithStable ? true : false));
230 }
232 {
233 c.v = new boolean[1]; boolean[] val1 = get2();
234 c.v = new boolean[1]; boolean[] val2 = get2();
235 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
236 }
237 }
238 }
240 /* ==================================================== */
242 static class BooleanArrayDim2 {
243 public @Stable boolean[][] v;
245 public static final BooleanArrayDim2 c = new BooleanArrayDim2();
246 public static boolean get() { return c.v[0][0]; }
247 public static boolean[] get1() { return c.v[0]; }
248 public static boolean[][] get2() { return c.v; }
249 public static void test() throws Exception {
250 {
251 c.v = new boolean[1][1]; c.v[0][0] = true; boolean val1 = get();
252 c.v[0][0] = false; boolean val2 = get();
253 assertEquals(val1, true);
254 assertEquals(val2, (isServerWithStable ? true : false));
256 c.v = new boolean[1][1]; c.v[0][0] = false; boolean val3 = get();
257 assertEquals(val3, (isServerWithStable ? true : false));
259 c.v[0] = new boolean[1]; c.v[0][0] = false; boolean val4 = get();
260 assertEquals(val4, (isServerWithStable ? true : false));
261 }
263 {
264 c.v = new boolean[1][1]; boolean[] val1 = get1();
265 c.v[0] = new boolean[1]; boolean[] val2 = get1();
266 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
267 }
269 {
270 c.v = new boolean[1][1]; boolean[][] val1 = get2();
271 c.v = new boolean[1][1]; boolean[][] val2 = get2();
272 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
273 }
274 }
275 }
277 /* ==================================================== */
279 static class BooleanArrayDim3 {
280 public @Stable boolean[][][] v;
282 public static final BooleanArrayDim3 c = new BooleanArrayDim3();
283 public static boolean get() { return c.v[0][0][0]; }
284 public static boolean[] get1() { return c.v[0][0]; }
285 public static boolean[][] get2() { return c.v[0]; }
286 public static boolean[][][] get3() { return c.v; }
287 public static void test() throws Exception {
288 {
289 c.v = new boolean[1][1][1]; c.v[0][0][0] = true; boolean val1 = get();
290 c.v[0][0][0] = false; boolean val2 = get();
291 assertEquals(val1, true);
292 assertEquals(val2, (isServerWithStable ? true : false));
294 c.v = new boolean[1][1][1]; c.v[0][0][0] = false; boolean val3 = get();
295 assertEquals(val3, (isServerWithStable ? true : false));
297 c.v[0] = new boolean[1][1]; c.v[0][0][0] = false; boolean val4 = get();
298 assertEquals(val4, (isServerWithStable ? true : false));
300 c.v[0][0] = new boolean[1]; c.v[0][0][0] = false; boolean val5 = get();
301 assertEquals(val5, (isServerWithStable ? true : false));
302 }
304 {
305 c.v = new boolean[1][1][1]; boolean[] val1 = get1();
306 c.v[0][0] = new boolean[1]; boolean[] val2 = get1();
307 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
308 }
310 {
311 c.v = new boolean[1][1][1]; boolean[][] val1 = get2();
312 c.v[0] = new boolean[1][1]; boolean[][] val2 = get2();
313 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
314 }
316 {
317 c.v = new boolean[1][1][1]; boolean[][][] val1 = get3();
318 c.v = new boolean[1][1][1]; boolean[][][] val2 = get3();
319 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
320 }
321 }
322 }
324 /* ==================================================== */
326 static class BooleanArrayDim4 {
327 public @Stable boolean[][][][] v;
329 public static final BooleanArrayDim4 c = new BooleanArrayDim4();
330 public static boolean get() { return c.v[0][0][0][0]; }
331 public static boolean[] get1() { return c.v[0][0][0]; }
332 public static boolean[][] get2() { return c.v[0][0]; }
333 public static boolean[][][] get3() { return c.v[0]; }
334 public static boolean[][][][] get4() { return c.v; }
335 public static void test() throws Exception {
336 {
337 c.v = new boolean[1][1][1][1]; c.v[0][0][0][0] = true; boolean val1 = get();
338 c.v[0][0][0][0] = false; boolean val2 = get();
339 assertEquals(val1, true);
340 assertEquals(val2, (isServerWithStable ? true : false));
342 c.v = new boolean[1][1][1][1]; c.v[0][0][0][0] = false; boolean val3 = get();
343 assertEquals(val3, (isServerWithStable ? true : false));
345 c.v[0] = new boolean[1][1][1]; c.v[0][0][0][0] = false; boolean val4 = get();
346 assertEquals(val4, (isServerWithStable ? true : false));
348 c.v[0][0] = new boolean[1][1]; c.v[0][0][0][0] = false; boolean val5 = get();
349 assertEquals(val5, (isServerWithStable ? true : false));
351 c.v[0][0][0] = new boolean[1]; c.v[0][0][0][0] = false; boolean val6 = get();
352 assertEquals(val6, (isServerWithStable ? true : false));
353 }
355 {
356 c.v = new boolean[1][1][1][1]; boolean[] val1 = get1();
357 c.v[0][0][0] = new boolean[1]; boolean[] val2 = get1();
358 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
359 }
361 {
362 c.v = new boolean[1][1][1][1]; boolean[][] val1 = get2();
363 c.v[0][0] = new boolean[1][1]; boolean[][] val2 = get2();
364 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
365 }
367 {
368 c.v = new boolean[1][1][1][1]; boolean[][][] val1 = get3();
369 c.v[0] = new boolean[1][1][1]; boolean[][][] val2 = get3();
370 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
371 }
373 {
374 c.v = new boolean[1][1][1][1]; boolean[][][][] val1 = get4();
375 c.v = new boolean[1][1][1][1]; boolean[][][][] val2 = get4();
376 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
377 }
379 }
380 }
382 /* ==================================================== */
383 // Dynamic Dim is higher than static
385 static class ObjectArrayLowerDim0 {
386 public @Stable Object v;
388 public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
389 public static boolean get() { return ((boolean[])c.v)[0]; }
390 public static boolean[] get1() { return (boolean[])c.v; }
391 public static boolean[] get2() { return (boolean[])c.v; }
393 public static void test() throws Exception {
394 {
395 c.v = new boolean[1]; ((boolean[])c.v)[0] = true; boolean val1 = get();
396 ((boolean[])c.v)[0] = false; boolean val2 = get();
398 assertEquals(val1, true);
399 assertEquals(val2, false);
400 }
402 {
403 c.v = new boolean[1]; boolean[] val1 = get1();
404 c.v = new boolean[1]; boolean[] val2 = get1();
405 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
406 }
407 }
408 }
410 /* ==================================================== */
412 static class ObjectArrayLowerDim1 {
413 public @Stable Object[] v;
415 public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
416 public static boolean get() { return ((boolean[][])c.v)[0][0]; }
417 public static boolean[] get1() { return (boolean[])(c.v[0]); }
418 public static Object[] get2() { return c.v; }
420 public static void test() throws Exception {
421 {
422 c.v = new boolean[1][1]; ((boolean[][])c.v)[0][0] = true; boolean val1 = get();
423 ((boolean[][])c.v)[0][0] = false; boolean val2 = get();
425 assertEquals(val1, true);
426 assertEquals(val2, false);
427 }
429 {
430 c.v = new boolean[1][1]; c.v[0] = new boolean[0]; boolean[] val1 = get1();
431 c.v[0] = new boolean[0]; boolean[] val2 = get1();
433 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
434 }
436 {
437 c.v = new boolean[0][0]; Object[] val1 = get2();
438 c.v = new boolean[0][0]; Object[] val2 = get2();
440 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
441 }
442 }
443 }
445 /* ==================================================== */
447 static class ObjectArrayLowerDim2 {
448 public @Stable Object[][] v;
450 public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
451 public static boolean get() { return ((boolean[][][])c.v)[0][0][0]; }
452 public static boolean[] get1() { return (boolean[])(c.v[0][0]); }
453 public static boolean[][] get2() { return (boolean[][])(c.v[0]); }
454 public static Object[][] get3() { return c.v; }
456 public static void test() throws Exception {
457 {
458 c.v = new boolean[1][1][1]; ((boolean[][][])c.v)[0][0][0] = true; boolean val1 = get();
459 ((boolean[][][])c.v)[0][0][0] = false; boolean val2 = get();
461 assertEquals(val1, true);
462 assertEquals(val2, false);
463 }
465 {
466 c.v = new boolean[1][1][1]; c.v[0][0] = new boolean[0]; boolean[] val1 = get1();
467 c.v[0][0] = new boolean[0]; boolean[] val2 = get1();
469 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
470 }
472 {
473 c.v = new boolean[1][1][1]; c.v[0] = new boolean[0][0]; boolean[][] val1 = get2();
474 c.v[0] = new boolean[0][0]; boolean[][] val2 = get2();
476 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2)));
477 }
479 {
480 c.v = new boolean[0][0][0]; Object[][] val1 = get3();
481 c.v = new boolean[0][0][0]; Object[][] val2 = get3();
483 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
484 }
485 }
486 }
488 /* ==================================================== */
490 static class NestedStableField {
491 static class A {
492 public @Stable boolean a;
494 }
495 public @Stable A v;
497 public static final NestedStableField c = new NestedStableField();
498 public static A get() { return c.v; }
499 public static boolean get1() { return get().a; }
501 public static void test() throws Exception {
502 {
503 c.v = new A(); c.v.a = true; A val1 = get();
504 c.v.a = false; A val2 = get();
506 assertEquals(val1.a, false);
507 assertEquals(val2.a, false);
508 }
510 {
511 c.v = new A(); c.v.a = true; boolean val1 = get1();
512 c.v.a = false; boolean val2 = get1();
513 c.v = new A(); c.v.a = false; boolean val3 = get1();
515 assertEquals(val1, true);
516 assertEquals(val2, (isStableEnabled ? true : false));
517 assertEquals(val3, (isStableEnabled ? true : false));
518 }
519 }
520 }
522 /* ==================================================== */
524 static class NestedStableField1 {
525 static class A {
526 public @Stable boolean a;
527 public @Stable A next;
528 }
529 public @Stable A v;
531 public static final NestedStableField1 c = new NestedStableField1();
532 public static A get() { return c.v.next.next.next.next.next.next.next; }
533 public static boolean get1() { return get().a; }
535 public static void test() throws Exception {
536 {
537 c.v = new A(); c.v.next = new A(); c.v.next.next = c.v;
538 c.v.a = true; c.v.next.a = true; A val1 = get();
539 c.v.a = false; c.v.next.a = false; A val2 = get();
541 assertEquals(val1.a, false);
542 assertEquals(val2.a, false);
543 }
545 {
546 c.v = new A(); c.v.next = c.v;
547 c.v.a = true; boolean val1 = get1();
548 c.v.a = false; boolean val2 = get1();
549 c.v = new A(); c.v.next = c.v;
550 c.v.a = false; boolean val3 = get1();
552 assertEquals(val1, true);
553 assertEquals(val2, (isStableEnabled ? true : false));
554 assertEquals(val3, (isStableEnabled ? true : false));
555 }
556 }
557 }
558 /* ==================================================== */
560 static class NestedStableField2 {
561 static class A {
562 public @Stable boolean a;
563 public @Stable A left;
564 public A right;
565 }
567 public @Stable A v;
569 public static final NestedStableField2 c = new NestedStableField2();
570 public static boolean get() { return c.v.left.left.left.a; }
571 public static boolean get1() { return c.v.left.left.right.left.a; }
573 public static void test() throws Exception {
574 {
575 c.v = new A(); c.v.left = c.v.right = c.v;
576 c.v.a = true; boolean val1 = get(); boolean val2 = get1();
577 c.v.a = false; boolean val3 = get(); boolean val4 = get1();
579 assertEquals(val1, true);
580 assertEquals(val3, (isStableEnabled ? true : false));
582 assertEquals(val2, true);
583 assertEquals(val4, false);
584 }
585 }
586 }
588 /* ==================================================== */
590 static class NestedStableField3 {
591 static class A {
592 public @Stable boolean a;
593 public @Stable A[] left;
594 public A[] right;
595 }
597 public @Stable A[] v;
599 public static final NestedStableField3 c = new NestedStableField3();
600 public static boolean get() { return c.v[0].left[1].left[0].left[1].a; }
601 public static boolean get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
603 public static void test() throws Exception {
604 {
605 A elem = new A();
606 c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
607 elem.a = true; boolean val1 = get(); boolean val2 = get1();
608 elem.a = false; boolean val3 = get(); boolean val4 = get1();
610 assertEquals(val1, true);
611 assertEquals(val3, (isServerWithStable ? true : false));
613 assertEquals(val2, true);
614 assertEquals(val4, false);
615 }
616 }
617 }
619 /* ==================================================== */
620 // Auxiliary methods
621 static void assertEquals(boolean i, boolean j) { if (i != j) throw new AssertionError(i + " != " + j); }
622 static void assertTrue(boolean b) { if (!b) throw new AssertionError(); }
624 static boolean failed = false;
626 public static void run(Class<?> test) {
627 Throwable ex = null;
628 System.out.print(test.getName()+": ");
629 try {
630 test.getMethod("test").invoke(null);
631 } catch (InvocationTargetException e) {
632 ex = e.getCause();
633 } catch (Throwable e) {
634 ex = e;
635 } finally {
636 if (ex == null) {
637 System.out.println("PASSED");
638 } else {
639 failed = true;
640 System.out.println("FAILED");
641 ex.printStackTrace(System.out);
642 }
643 }
644 }
645 }