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