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 */ 25 26 /* 27 * @test TestStableByte 28 * @summary tests on stable fields and arrays 29 * @library /testlibrary /test/lib 30 * @build TestStableByte 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/TestStableByte 35 * java/lang/invoke/TestStableByte$ByteStable 36 * java/lang/invoke/TestStableByte$StaticByteStable 37 * java/lang/invoke/TestStableByte$VolatileByteStable 38 * java/lang/invoke/TestStableByte$ByteArrayDim1 39 * java/lang/invoke/TestStableByte$ByteArrayDim2 40 * java/lang/invoke/TestStableByte$ByteArrayDim3 41 * java/lang/invoke/TestStableByte$ByteArrayDim4 42 * java/lang/invoke/TestStableByte$ObjectArrayLowerDim0 43 * java/lang/invoke/TestStableByte$ObjectArrayLowerDim1 44 * java/lang/invoke/TestStableByte$NestedStableField 45 * java/lang/invoke/TestStableByte$NestedStableField$A 46 * java/lang/invoke/TestStableByte$NestedStableField1 47 * java/lang/invoke/TestStableByte$NestedStableField1$A 48 * java/lang/invoke/TestStableByte$NestedStableField2 49 * java/lang/invoke/TestStableByte$NestedStableField2$A 50 * java/lang/invoke/TestStableByte$NestedStableField3 51 * java/lang/invoke/TestStableByte$NestedStableField3$A 52 * java/lang/invoke/TestStableByte$DefaultValue 53 * java/lang/invoke/TestStableByte$DefaultStaticValue 54 * java/lang/invoke/TestStableByte$ObjectArrayLowerDim2 55 * 56 * @run main/othervm -Xbootclasspath/a:. 57 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp 58 * -XX:-TieredCompilation 59 * -XX:+FoldStableValues 60 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 61 * java.lang.invoke.TestStableByte 62 * @run main/othervm -Xbootclasspath/a:. 63 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp 64 * -XX:-TieredCompilation 65 * -XX:-FoldStableValues 66 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 67 * java.lang.invoke.TestStableByte 68 * 69 * @run main/othervm -Xbootclasspath/a:. 70 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp 71 * -XX:+TieredCompilation -XX:TieredStopAtLevel=1 72 * -XX:+FoldStableValues 73 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 74 * java.lang.invoke.TestStableByte 75 * @run main/othervm -Xbootclasspath/a:. 76 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp 77 * -XX:+TieredCompilation -XX:TieredStopAtLevel=1 78 * -XX:-FoldStableValues 79 * -XX:CompileOnly=::get,::get1,::get2,::get3,::get4 80 * java.lang.invoke.TestStableByte 81 * 82 */ 83 package java.lang.invoke; 84 85 import jdk.internal.vm.annotation.Stable; 86 87 import java.lang.reflect.InvocationTargetException; 88 89 public class TestStableByte { 90 static final boolean isStableEnabled = StableConfiguration.isStableEnabled; 91 static final boolean isServerWithStable = StableConfiguration.isServerWithStable; 92 93 public static void main(String[] args) throws Exception { 94 run(DefaultValue.class); 95 run(ByteStable.class); 96 run(DefaultStaticValue.class); 97 run(StaticByteStable.class); 98 run(VolatileByteStable.class); 99 100 // @Stable arrays: Dim 1-4 101 run(ByteArrayDim1.class); 102 run(ByteArrayDim2.class); 103 run(ByteArrayDim3.class); 104 run(ByteArrayDim4.class); 105 106 // @Stable Object field: dynamic arrays 107 run(ObjectArrayLowerDim0.class); 108 run(ObjectArrayLowerDim1.class); 109 run(ObjectArrayLowerDim2.class); 110 111 // Nested @Stable fields 112 run(NestedStableField.class); 113 run(NestedStableField1.class); 114 run(NestedStableField2.class); 115 run(NestedStableField3.class); 116 117 if (failed) { 118 throw new Error("TEST FAILED"); 119 } 120 } 121 122 /* ==================================================== */ 123 124 static class DefaultValue { 125 public @Stable byte v; 126 127 public static final DefaultValue c = new DefaultValue(); 128 public static byte get() { return c.v; } 129 public static void test() throws Exception { 130 byte val1 = get(); 131 c.v = 1; byte val2 = get(); 132 assertEquals(val1, 0); 133 assertEquals(val2, 1); 134 } 135 } 136 137 /* ==================================================== */ 138 139 static class ByteStable { 140 public @Stable byte v; 141 142 public static final ByteStable c = new ByteStable(); 143 public static byte get() { return c.v; } 144 public static void test() throws Exception { 145 c.v = 5; byte val1 = get(); 146 c.v = 127; byte val2 = get(); 147 assertEquals(val1, 5); 148 assertEquals(val2, (isStableEnabled ? 5 : 127)); 149 } 150 } 151 152 /* ==================================================== */ 153 154 static class DefaultStaticValue { 155 public static @Stable byte v; 156 157 public static final DefaultStaticValue c = new DefaultStaticValue(); 158 public static byte get() { return c.v; } 159 public static void test() throws Exception { 160 byte val1 = get(); 161 c.v = 1; byte val2 = get(); 162 assertEquals(val1, 0); 163 assertEquals(val2, 1); 164 } 165 } 166 167 /* ==================================================== */ 168 169 static class StaticByteStable { 170 public static @Stable byte v; 171 172 public static final StaticByteStable c = new StaticByteStable(); 173 public static byte get() { return c.v; } 174 public static void test() throws Exception { 175 c.v = 5; byte val1 = get(); 176 c.v = 127; byte val2 = get(); 177 assertEquals(val1, 5); 178 assertEquals(val2, (isStableEnabled ? 5 : 127)); 179 } 180 } 181 182 /* ==================================================== */ 183 184 static class VolatileByteStable { 185 public @Stable volatile byte v; 186 187 public static final VolatileByteStable c = new VolatileByteStable(); 188 public static byte get() { return c.v; } 189 public static void test() throws Exception { 190 c.v = 5; byte val1 = get(); 191 c.v = 127; byte val2 = get(); 192 assertEquals(val1, 5); 193 assertEquals(val2, (isStableEnabled ? 5 : 127)); 194 } 195 } 196 197 /* ==================================================== */ 198 // @Stable array == field && all components are stable 199 200 static class ByteArrayDim1 { 201 public @Stable byte[] v; 202 203 public static final ByteArrayDim1 c = new ByteArrayDim1(); 204 public static byte get() { return c.v[0]; } 205 public static byte get1() { return c.v[10]; } 206 public static byte[] get2() { return c.v; } 207 public static void test() throws Exception { 208 { 209 c.v = new byte[1]; c.v[0] = 1; byte val1 = get(); 210 c.v[0] = 2; byte val2 = get(); 211 assertEquals(val1, 1); 212 assertEquals(val2, (isServerWithStable ? 1 : 2)); 213 214 c.v = new byte[1]; c.v[0] = 3; byte val3 = get(); 215 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 1 : 2) 216 : 3)); 217 } 218 219 { 220 c.v = new byte[20]; c.v[10] = 1; byte val1 = get1(); 221 c.v[10] = 2; byte val2 = get1(); 222 assertEquals(val1, 1); 223 assertEquals(val2, (isServerWithStable ? 1 : 2)); 224 225 c.v = new byte[20]; c.v[10] = 3; byte val3 = get1(); 226 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 1 : 2) 227 : 3)); 228 } 229 230 { 231 c.v = new byte[1]; byte[] val1 = get2(); 232 c.v = new byte[1]; byte[] val2 = get2(); 233 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 234 } 235 } 236 } 237 238 /* ==================================================== */ 239 240 static class ByteArrayDim2 { 241 public @Stable byte[][] v; 242 243 public static final ByteArrayDim2 c = new ByteArrayDim2(); 244 public static byte get() { return c.v[0][0]; } 245 public static byte[] get1() { return c.v[0]; } 246 public static byte[][] get2() { return c.v; } 247 public static void test() throws Exception { 248 { 249 c.v = new byte[1][1]; c.v[0][0] = 1; byte val1 = get(); 250 c.v[0][0] = 2; byte val2 = get(); 251 assertEquals(val1, 1); 252 assertEquals(val2, (isServerWithStable ? 1 : 2)); 253 254 c.v = new byte[1][1]; c.v[0][0] = 3; byte val3 = get(); 255 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 1 : 2) 256 : 3)); 257 258 c.v[0] = new byte[1]; c.v[0][0] = 4; byte val4 = get(); 259 assertEquals(val4, (isStableEnabled ? (isServerWithStable ? 1 : 2) 260 : 4)); 261 } 262 263 { 264 c.v = new byte[1][1]; byte[] val1 = get1(); 265 c.v[0] = new byte[1]; byte[] val2 = get1(); 266 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 267 } 268 269 { 270 c.v = new byte[1][1]; byte[][] val1 = get2(); 271 c.v = new byte[1][1]; byte[][] val2 = get2(); 272 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 273 } 274 } 275 } 276 277 /* ==================================================== */ 278 279 static class ByteArrayDim3 { 280 public @Stable byte[][][] v; 281 282 public static final ByteArrayDim3 c = new ByteArrayDim3(); 283 public static byte get() { return c.v[0][0][0]; } 284 public static byte[] get1() { return c.v[0][0]; } 285 public static byte[][] get2() { return c.v[0]; } 286 public static byte[][][] get3() { return c.v; } 287 public static void test() throws Exception { 288 { 289 c.v = new byte[1][1][1]; c.v[0][0][0] = 1; byte val1 = get(); 290 c.v[0][0][0] = 2; byte val2 = get(); 291 assertEquals(val1, 1); 292 assertEquals(val2, (isServerWithStable ? 1 : 2)); 293 294 c.v = new byte[1][1][1]; c.v[0][0][0] = 3; byte val3 = get(); 295 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 1 : 2) 296 : 3)); 297 298 c.v[0] = new byte[1][1]; c.v[0][0][0] = 4; byte val4 = get(); 299 assertEquals(val4, (isStableEnabled ? (isServerWithStable ? 1 : 2) 300 : 4)); 301 302 c.v[0][0] = new byte[1]; c.v[0][0][0] = 5; byte val5 = get(); 303 assertEquals(val5, (isStableEnabled ? (isServerWithStable ? 1 : 2) 304 : 5)); 305 } 306 307 { 308 c.v = new byte[1][1][1]; byte[] val1 = get1(); 309 c.v[0][0] = new byte[1]; byte[] val2 = get1(); 310 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 311 } 312 313 { 314 c.v = new byte[1][1][1]; byte[][] val1 = get2(); 315 c.v[0] = new byte[1][1]; byte[][] val2 = get2(); 316 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 317 } 318 319 { 320 c.v = new byte[1][1][1]; byte[][][] val1 = get3(); 321 c.v = new byte[1][1][1]; byte[][][] val2 = get3(); 322 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 323 } 324 } 325 } 326 327 /* ==================================================== */ 328 329 static class ByteArrayDim4 { 330 public @Stable byte[][][][] v; 331 332 public static final ByteArrayDim4 c = new ByteArrayDim4(); 333 public static byte get() { return c.v[0][0][0][0]; } 334 public static byte[] get1() { return c.v[0][0][0]; } 335 public static byte[][] get2() { return c.v[0][0]; } 336 public static byte[][][] get3() { return c.v[0]; } 337 public static byte[][][][] get4() { return c.v; } 338 public static void test() throws Exception { 339 { 340 c.v = new byte[1][1][1][1]; c.v[0][0][0][0] = 1; byte val1 = get(); 341 c.v[0][0][0][0] = 2; byte val2 = get(); 342 assertEquals(val1, 1); 343 assertEquals(val2, (isServerWithStable ? 1 : 2)); 344 345 c.v = new byte[1][1][1][1]; c.v[0][0][0][0] = 3; byte val3 = get(); 346 assertEquals(val3, (isStableEnabled ? (isServerWithStable ? 1 : 2) 347 : 3)); 348 349 c.v[0] = new byte[1][1][1]; c.v[0][0][0][0] = 4; byte val4 = get(); 350 assertEquals(val4, (isStableEnabled ? (isServerWithStable ? 1 : 2) 351 : 4)); 352 353 c.v[0][0] = new byte[1][1]; c.v[0][0][0][0] = 5; byte val5 = get(); 354 assertEquals(val5, (isStableEnabled ? (isServerWithStable ? 1 : 2) 355 : 5)); 356 357 c.v[0][0][0] = new byte[1]; c.v[0][0][0][0] = 6; byte val6 = get(); 358 assertEquals(val6, (isStableEnabled ? (isServerWithStable ? 1 : 2) 359 : 6)); 360 } 361 362 { 363 c.v = new byte[1][1][1][1]; byte[] val1 = get1(); 364 c.v[0][0][0] = new byte[1]; byte[] val2 = get1(); 365 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 366 } 367 368 { 369 c.v = new byte[1][1][1][1]; byte[][] val1 = get2(); 370 c.v[0][0] = new byte[1][1]; byte[][] val2 = get2(); 371 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 372 } 373 374 { 375 c.v = new byte[1][1][1][1]; byte[][][] val1 = get3(); 376 c.v[0] = new byte[1][1][1]; byte[][][] val2 = get3(); 377 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 378 } 379 380 { 381 c.v = new byte[1][1][1][1]; byte[][][][] val1 = get4(); 382 c.v = new byte[1][1][1][1]; byte[][][][] val2 = get4(); 383 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 384 } 385 386 } 387 } 388 389 /* ==================================================== */ 390 // Dynamic Dim is higher than static 391 392 static class ObjectArrayLowerDim0 { 393 public @Stable Object v; 394 395 public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0(); 396 public static byte get() { return ((byte[])c.v)[0]; } 397 public static byte[] get1() { return (byte[])c.v; } 398 399 public static void test() throws Exception { 400 { 401 c.v = new byte[1]; ((byte[])c.v)[0] = 1; byte val1 = get(); 402 ((byte[])c.v)[0] = 2; byte val2 = get(); 403 404 assertEquals(val1, 1); 405 assertEquals(val2, 2); 406 } 407 408 { 409 c.v = new byte[1]; byte[] val1 = get1(); 410 c.v = new byte[1]; byte[] val2 = get1(); 411 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 412 } 413 } 414 } 415 416 /* ==================================================== */ 417 418 static class ObjectArrayLowerDim1 { 419 public @Stable Object[] v; 420 421 public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1(); 422 public static byte get() { return ((byte[][])c.v)[0][0]; } 423 public static byte[] get1() { return (byte[])(c.v[0]); } 424 public static Object[] get2() { return c.v; } 425 426 public static void test() throws Exception { 427 { 428 c.v = new byte[1][1]; ((byte[][])c.v)[0][0] = 1; byte val1 = get(); 429 ((byte[][])c.v)[0][0] = 2; byte val2 = get(); 430 431 assertEquals(val1, 1); 432 assertEquals(val2, 2); 433 } 434 435 { 436 c.v = new byte[1][1]; c.v[0] = new byte[0]; byte[] val1 = get1(); 437 c.v[0] = new byte[0]; byte[] val2 = get1(); 438 439 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 440 } 441 442 { 443 c.v = new byte[0][0]; Object[] val1 = get2(); 444 c.v = new byte[0][0]; Object[] val2 = get2(); 445 446 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 447 } 448 } 449 } 450 451 /* ==================================================== */ 452 453 static class ObjectArrayLowerDim2 { 454 public @Stable Object[][] v; 455 456 public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2(); 457 public static byte get() { return ((byte[][][])c.v)[0][0][0]; } 458 public static byte[] get1() { return (byte[])(c.v[0][0]); } 459 public static byte[][] get2() { return (byte[][])(c.v[0]); } 460 public static Object[][] get3() { return c.v; } 461 462 public static void test() throws Exception { 463 { 464 c.v = new byte[1][1][1]; ((byte[][][])c.v)[0][0][0] = 1; byte val1 = get(); 465 ((byte[][][])c.v)[0][0][0] = 2; byte val2 = get(); 466 467 assertEquals(val1, 1); 468 assertEquals(val2, 2); 469 } 470 471 { 472 c.v = new byte[1][1][1]; c.v[0][0] = new byte[0]; byte[] val1 = get1(); 473 c.v[0][0] = new byte[0]; byte[] val2 = get1(); 474 475 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 476 } 477 478 { 479 c.v = new byte[1][1][1]; c.v[0] = new byte[0][0]; byte[][] val1 = get2(); 480 c.v[0] = new byte[0][0]; byte[][] val2 = get2(); 481 482 assertTrue((isServerWithStable ? (val1 == val2) : (val1 != val2))); 483 } 484 485 { 486 c.v = new byte[0][0][0]; Object[][] val1 = get3(); 487 c.v = new byte[0][0][0]; Object[][] val2 = get3(); 488 489 assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2))); 490 } 491 } 492 } 493 494 /* ==================================================== */ 495 496 static class NestedStableField { 497 static class A { 498 public @Stable byte a; 499 500 } 501 public @Stable A v; 502 503 public static final NestedStableField c = new NestedStableField(); 504 public static A get() { return c.v; } 505 public static byte get1() { return get().a; } 506 507 public static void test() throws Exception { 508 { 509 c.v = new A(); c.v.a = 1; A val1 = get(); 510 c.v.a = 2; A val2 = get(); 511 512 assertEquals(val1.a, 2); 513 assertEquals(val2.a, 2); 514 } 515 516 { 517 c.v = new A(); c.v.a = 1; byte val1 = get1(); 518 c.v.a = 2; byte val2 = get1(); 519 c.v = new A(); c.v.a = 3; byte val3 = get1(); 520 521 assertEquals(val1, 1); 522 assertEquals(val2, (isStableEnabled ? 1 : 2)); 523 assertEquals(val3, (isStableEnabled ? 1 : 3)); 524 } 525 } 526 } 527 528 /* ==================================================== */ 529 530 static class NestedStableField1 { 531 static class A { 532 public @Stable byte a; 533 public @Stable A next; 534 } 535 public @Stable A v; 536 537 public static final NestedStableField1 c = new NestedStableField1(); 538 public static A get() { return c.v.next.next.next.next.next.next.next; } 539 public static byte get1() { return get().a; } 540 541 public static void test() throws Exception { 542 { 543 c.v = new A(); c.v.next = new A(); c.v.next.next = c.v; 544 c.v.a = 1; c.v.next.a = 1; A val1 = get(); 545 c.v.a = 2; c.v.next.a = 2; A val2 = get(); 546 547 assertEquals(val1.a, 2); 548 assertEquals(val2.a, 2); 549 } 550 551 { 552 c.v = new A(); c.v.next = c.v; 553 c.v.a = 1; byte val1 = get1(); 554 c.v.a = 2; byte val2 = get1(); 555 c.v = new A(); c.v.next = c.v; 556 c.v.a = 3; byte val3 = get1(); 557 558 assertEquals(val1, 1); 559 assertEquals(val2, (isStableEnabled ? 1 : 2)); 560 assertEquals(val3, (isStableEnabled ? 1 : 3)); 561 } 562 } 563 } 564 /* ==================================================== */ 565 566 static class NestedStableField2 { 567 static class A { 568 public @Stable byte a; 569 public @Stable A left; 570 public A right; 571 } 572 573 public @Stable A v; 574 575 public static final NestedStableField2 c = new NestedStableField2(); 576 public static byte get() { return c.v.left.left.left.a; } 577 public static byte get1() { return c.v.left.left.right.left.a; } 578 579 public static void test() throws Exception { 580 { 581 c.v = new A(); c.v.left = c.v.right = c.v; 582 c.v.a = 1; byte val1 = get(); byte val2 = get1(); 583 c.v.a = 2; byte val3 = get(); byte val4 = get1(); 584 585 assertEquals(val1, 1); 586 assertEquals(val3, (isStableEnabled ? 1 : 2)); 587 588 assertEquals(val2, 1); 589 assertEquals(val4, 2); 590 } 591 } 592 } 593 594 /* ==================================================== */ 595 596 static class NestedStableField3 { 597 static class A { 598 public @Stable byte a; 599 public @Stable A[] left; 600 public A[] right; 601 } 602 603 public @Stable A[] v; 604 605 public static final NestedStableField3 c = new NestedStableField3(); 606 public static byte get() { return c.v[0].left[1].left[0].left[1].a; } 607 public static byte get1() { return c.v[1].left[0].left[1].right[0].left[1].a; } 608 609 public static void test() throws Exception { 610 { 611 A elem = new A(); 612 c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v; 613 elem.a = 1; byte val1 = get(); byte val2 = get1(); 614 elem.a = 2; byte val3 = get(); byte val4 = get1(); 615 616 assertEquals(val1, 1); 617 assertEquals(val3, (isServerWithStable ? 1 : 2)); 618 619 assertEquals(val2, 1); 620 assertEquals(val4, 2); 621 } 622 } 623 } 624 625 /* ==================================================== */ 626 // Auxiliary methods 627 static void assertEquals(int i, int j) { if (i != j) throw new AssertionError(i + " != " + j); } 628 static void assertTrue(boolean b) { if (!b) throw new AssertionError(); } 629 630 static boolean failed = false; 631 632 public static void run(Class<?> test) { 633 Throwable ex = null; 634 System.out.print(test.getName()+": "); 635 try { 636 test.getMethod("test").invoke(null); 637 } catch (InvocationTargetException e) { 638 ex = e.getCause(); 639 } catch (Throwable e) { 640 ex = e; 641 } finally { 642 if (ex == null) { 643 System.out.println("PASSED"); 644 } else { 645 failed = true; 646 System.out.println("FAILED"); 647 ex.printStackTrace(System.out); 648 } 649 } 650 } 651 }