1 /* 2 * Copyright (c) 2018, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 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 21 * questions. 22 */ 23 24 25 package org.graalvm.compiler.replacements.jdk9; 26 27 import jdk.vm.ci.aarch64.AArch64; 28 import jdk.vm.ci.amd64.AMD64; 29 import jdk.vm.ci.code.TargetDescription; 30 import org.graalvm.compiler.api.test.Graal; 31 import org.graalvm.compiler.core.phases.HighTier; 32 import org.graalvm.compiler.options.OptionValues; 33 import org.graalvm.compiler.replacements.test.MethodSubstitutionTest; 34 import org.graalvm.compiler.runtime.RuntimeProvider; 35 import org.graalvm.compiler.test.AddExports; 36 import org.junit.Test; 37 38 import java.lang.reflect.Field; 39 40 @AddExports("java.base/jdk.internal.misc") 41 public class UnsafeReplacementsTest extends MethodSubstitutionTest { 42 43 static class Container { 44 public volatile boolean booleanField; 45 public volatile byte byteField = 17; 46 public volatile char charField = 1025; 47 public volatile short shortField = 2232; 48 public volatile int intField = 0xcafebabe; 49 public volatile long longField = 0xdedababafafaL; 50 public volatile float floatField = 0.125f; 51 public volatile double doubleField = 0.125; 52 public volatile Object objectField = dummyValue; 53 } 54 55 static jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); 56 static Container dummyValue = new Container(); 57 static Container newDummyValue = new Container(); 58 static long booleanOffset; 59 static long byteOffset; 60 static long charOffset; 61 static long shortOffset; 62 static long intOffset; 63 static long longOffset; 64 static long floatOffset; 65 static long doubleOffset; 66 static long objectOffset; 67 68 static { 69 try { 70 booleanOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("booleanField")); 71 byteOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("byteField")); 72 charOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("charField")); 73 shortOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("shortField")); 74 intOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("intField")); 75 longOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("longField")); 76 floatOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("floatField")); 77 doubleOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("doubleField")); 78 objectOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("objectField")); 79 } catch (NoSuchFieldException e) { 80 throw new RuntimeException(e); 81 } 82 } 83 84 public static boolean unsafeCompareAndSetBoolean() { 85 Container container = new Container(); 86 return unsafe.compareAndSetBoolean(container, booleanOffset, false, true); 87 } 88 89 public static boolean unsafeCompareAndSetByte() { 90 Container container = new Container(); 91 return unsafe.compareAndSetByte(container, byteOffset, (byte) 17, (byte) 121); 92 } 93 94 public static boolean unsafeCompareAndSetChar() { 95 Container container = new Container(); 96 return unsafe.compareAndSetChar(container, charOffset, (char) 1025, (char) 1777); 97 } 98 99 public static boolean unsafeCompareAndSetShort() { 100 Container container = new Container(); 101 return unsafe.compareAndSetShort(container, shortOffset, (short) 2232, (short) 12111); 102 } 103 104 public static boolean unsafeCompareAndSetInt() { 105 Container container = new Container(); 106 return unsafe.compareAndSetInt(container, intOffset, 0xcafebabe, 0xbabefafa); 107 } 108 109 public static boolean unsafeCompareAndSetLong() { 110 Container container = new Container(); 111 return unsafe.compareAndSetLong(container, longOffset, 0xdedababafafaL, 0xfafacecafafadedaL); 112 } 113 114 public static boolean unsafeCompareAndSetFloat() { 115 Container container = new Container(); 116 return unsafe.compareAndSetFloat(container, floatOffset, 0.125f, 0.25f); 117 } 118 119 public static boolean unsafeCompareAndSetDouble() { 120 Container container = new Container(); 121 return unsafe.compareAndSetDouble(container, doubleOffset, 0.125, 0.25); 122 } 123 124 public static boolean unsafeCompareAndSetReference() { 125 Container container = new Container(); 126 return unsafe.compareAndSetReference(container, objectOffset, dummyValue, newDummyValue); 127 } 128 129 public static boolean unsafeCompareAndExchangeBoolean() { 130 Container container = new Container(); 131 return unsafe.compareAndExchangeBoolean(container, booleanOffset, false, true); 132 } 133 134 public static byte unsafeCompareAndExchangeByte() { 135 Container container = new Container(); 136 return unsafe.compareAndExchangeByte(container, byteOffset, (byte) 17, (byte) 31); 137 } 138 139 public static char unsafeCompareAndExchangeChar() { 140 Container container = new Container(); 141 return unsafe.compareAndExchangeChar(container, charOffset, (char) 1025, (char) 4502); 142 } 143 144 public static short unsafeCompareAndExchangeShort() { 145 Container container = new Container(); 146 return unsafe.compareAndExchangeShort(container, shortOffset, (short) 2232, (short) 8121); 147 } 148 149 public static int unsafeCompareAndExchangeInt() { 150 Container container = new Container(); 151 return unsafe.compareAndExchangeInt(container, intOffset, 0xcafebabe, 0xbabefafa); 152 } 153 154 public static long unsafeCompareAndExchangeLong() { 155 Container container = new Container(); 156 return unsafe.compareAndExchangeLong(container, longOffset, 0xdedababafafaL, 0xfafacecafafadedaL); 157 } 158 159 public static float unsafeCompareAndExchangeFloat() { 160 Container container = new Container(); 161 return unsafe.compareAndExchangeFloat(container, floatOffset, 0.125f, 0.25f); 162 } 163 164 public static double unsafeCompareAndExchangeDouble() { 165 Container container = new Container(); 166 return unsafe.compareAndExchangeDouble(container, doubleOffset, 0.125, 0.25); 167 } 168 169 public static Object unsafeCompareAndExchangeReference() { 170 Container container = new Container(); 171 return unsafe.compareAndExchangeReference(container, objectOffset, dummyValue, newDummyValue); 172 } 173 174 @Test 175 public void testCompareAndSet() { 176 TargetDescription target = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getTarget(); 177 if (target.arch instanceof AMD64) { 178 testGraph("unsafeCompareAndSetBoolean"); 179 testGraph("unsafeCompareAndSetByte"); 180 testGraph("unsafeCompareAndSetChar"); 181 testGraph("unsafeCompareAndSetShort"); 182 testGraph("unsafeCompareAndSetInt"); 183 testGraph("unsafeCompareAndSetLong"); 184 testGraph("unsafeCompareAndSetFloat"); 185 testGraph("unsafeCompareAndSetDouble"); 186 testGraph("unsafeCompareAndSetReference"); 187 testGraph("unsafeCompareAndExchangeBoolean"); 188 testGraph("unsafeCompareAndExchangeByte"); 189 testGraph("unsafeCompareAndExchangeChar"); 190 testGraph("unsafeCompareAndExchangeShort"); 191 testGraph("unsafeCompareAndExchangeInt"); 192 testGraph("unsafeCompareAndExchangeLong"); 193 testGraph("unsafeCompareAndExchangeFloat"); 194 testGraph("unsafeCompareAndExchangeDouble"); 195 testGraph("unsafeCompareAndExchangeReference"); 196 } 197 test("unsafeCompareAndSetBoolean"); 198 test("unsafeCompareAndSetByte"); 199 test("unsafeCompareAndSetChar"); 200 test("unsafeCompareAndSetShort"); 201 test("unsafeCompareAndSetInt"); 202 test("unsafeCompareAndSetLong"); 203 test("unsafeCompareAndSetFloat"); 204 test("unsafeCompareAndSetDouble"); 205 test("unsafeCompareAndSetReference"); 206 test("unsafeCompareAndExchangeBoolean"); 207 test("unsafeCompareAndExchangeByte"); 208 test("unsafeCompareAndExchangeChar"); 209 test("unsafeCompareAndExchangeShort"); 210 test("unsafeCompareAndExchangeInt"); 211 test("unsafeCompareAndExchangeLong"); 212 test("unsafeCompareAndExchangeFloat"); 213 test("unsafeCompareAndExchangeDouble"); 214 test("unsafeCompareAndExchangeReference"); 215 } 216 217 public static int unsafeGetAndAddByte() { 218 Container container = new Container(); 219 return unsafe.getAndAddByte(container, byteOffset, (byte) 2); 220 } 221 222 public static int unsafeGetAndAddChar() { 223 Container container = new Container(); 224 return unsafe.getAndAddChar(container, charOffset, (char) 250); 225 } 226 227 public static int unsafeGetAndAddShort() { 228 Container container = new Container(); 229 return unsafe.getAndAddShort(container, shortOffset, (short) 1250); 230 } 231 232 public static int unsafeGetAndAddInt() { 233 Container container = new Container(); 234 return unsafe.getAndAddInt(container, intOffset, 104501); 235 } 236 237 public static long unsafeGetAndAddLong() { 238 Container container = new Container(); 239 return unsafe.getAndAddLong(container, longOffset, 0x123456abcdL); 240 } 241 242 @Test 243 public void testGetAndAdd() { 244 TargetDescription target = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getTarget(); 245 if (target.arch instanceof AMD64) { 246 testGraph("unsafeGetAndAddByte"); 247 testGraph("unsafeGetAndAddChar"); 248 testGraph("unsafeGetAndAddShort"); 249 } 250 if (target.arch instanceof AMD64 || target.arch instanceof AArch64) { 251 testGraph("unsafeGetAndAddInt"); 252 testGraph("unsafeGetAndAddLong"); 253 } 254 test("unsafeGetAndAddByte"); 255 test("unsafeGetAndAddChar"); 256 test("unsafeGetAndAddShort"); 257 test("unsafeGetAndAddInt"); 258 test("unsafeGetAndAddLong"); 259 } 260 261 public static boolean unsafeGetAndSetBoolean() { 262 Container container = new Container(); 263 return unsafe.getAndSetBoolean(container, booleanOffset, true); 264 } 265 266 public static byte unsafeGetAndSetByte() { 267 Container container = new Container(); 268 return unsafe.getAndSetByte(container, byteOffset, (byte) 129); 269 } 270 271 public static char unsafeGetAndSetChar() { 272 Container container = new Container(); 273 return unsafe.getAndSetChar(container, charOffset, (char) 21111); 274 } 275 276 public static short unsafeGetAndSetShort() { 277 Container container = new Container(); 278 return unsafe.getAndSetShort(container, shortOffset, (short) 21111); 279 } 280 281 public static int unsafeGetAndSetInt() { 282 Container container = new Container(); 283 return unsafe.getAndSetInt(container, intOffset, 0x1234af); 284 } 285 286 public static long unsafeGetAndSetLong() { 287 Container container = new Container(); 288 return unsafe.getAndSetLong(container, longOffset, 0x12345678abL); 289 } 290 291 public static Object unsafeGetAndSetReference() { 292 Container container = new Container(); 293 container.objectField = null; 294 Container other = new Container(); 295 return unsafe.getAndSetReference(container, objectOffset, other); 296 } 297 298 @Test 299 public void testGetAndSet() { 300 TargetDescription target = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getTarget(); 301 if (target.arch instanceof AMD64) { 302 testGraph("unsafeGetAndSetBoolean"); 303 testGraph("unsafeGetAndSetByte"); 304 testGraph("unsafeGetAndSetChar"); 305 testGraph("unsafeGetAndSetShort"); 306 } 307 if (target.arch instanceof AMD64 || target.arch instanceof AArch64) { 308 testGraph("unsafeGetAndSetInt"); 309 testGraph("unsafeGetAndSetLong"); 310 testGraph("unsafeGetAndSetReference"); 311 } 312 test("unsafeGetAndSetBoolean"); 313 test("unsafeGetAndSetByte"); 314 test("unsafeGetAndSetChar"); 315 test("unsafeGetAndSetShort"); 316 test("unsafeGetAndSetInt"); 317 test("unsafeGetAndSetLong"); 318 test("unsafeGetAndSetReference"); 319 } 320 321 public static void fieldInstance() { 322 JdkInternalMiscUnsafeAccessTestBoolean.testFieldInstance(); 323 } 324 325 @Test 326 public void testFieldInstance() { 327 test(new OptionValues(getInitialOptions(), HighTier.Options.Inline, false), "fieldInstance"); 328 } 329 330 public static void array() { 331 JdkInternalMiscUnsafeAccessTestBoolean.testArray(); 332 } 333 334 @Test 335 public void testArray() { 336 test(new OptionValues(getInitialOptions(), HighTier.Options.Inline, false), "array"); 337 } 338 339 public static void fieldStatic() { 340 JdkInternalMiscUnsafeAccessTestBoolean.testFieldStatic(); 341 } 342 343 @Test 344 public void testFieldStatic() { 345 test(new OptionValues(getInitialOptions(), HighTier.Options.Inline, false), "fieldStatic"); 346 } 347 348 public static void assertEquals(Object seen, Object expected, String message) { 349 if (seen != expected) { 350 throw new AssertionError(message + " - seen: " + seen + ", expected: " + expected); 351 } 352 } 353 354 public static class JdkInternalMiscUnsafeAccessTestBoolean { 355 static final int ITERATIONS = 100000; 356 357 static final int WEAK_ATTEMPTS = 10; 358 359 static final long V_OFFSET; 360 361 static final Object STATIC_V_BASE; 362 363 static final long STATIC_V_OFFSET; 364 365 static final int ARRAY_OFFSET; 366 367 static final int ARRAY_SHIFT; 368 369 static { 370 try { 371 Field staticVField = UnsafeReplacementsTest.JdkInternalMiscUnsafeAccessTestBoolean.class.getDeclaredField("staticV"); 372 STATIC_V_BASE = unsafe.staticFieldBase(staticVField); 373 STATIC_V_OFFSET = unsafe.staticFieldOffset(staticVField); 374 } catch (Exception e) { 375 throw new RuntimeException(e); 376 } 377 378 try { 379 Field vField = UnsafeReplacementsTest.JdkInternalMiscUnsafeAccessTestBoolean.class.getDeclaredField("v"); 380 V_OFFSET = unsafe.objectFieldOffset(vField); 381 } catch (Exception e) { 382 throw new RuntimeException(e); 383 } 384 385 ARRAY_OFFSET = unsafe.arrayBaseOffset(boolean[].class); 386 int ascale = unsafe.arrayIndexScale(boolean[].class); 387 ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale); 388 } 389 390 static boolean staticV; 391 392 boolean v; 393 394 @BytecodeParserForceInline 395 public static void testFieldInstance() { 396 JdkInternalMiscUnsafeAccessTestBoolean t = new JdkInternalMiscUnsafeAccessTestBoolean(); 397 for (int c = 0; c < ITERATIONS; c++) { 398 testAccess(t, V_OFFSET); 399 } 400 } 401 402 public static void testFieldStatic() { 403 for (int c = 0; c < ITERATIONS; c++) { 404 testAccess(STATIC_V_BASE, STATIC_V_OFFSET); 405 } 406 } 407 408 public static void testArray() { 409 boolean[] array = new boolean[10]; 410 for (int c = 0; c < ITERATIONS; c++) { 411 for (int i = 0; i < array.length; i++) { 412 testAccess(array, (((long) i) << ARRAY_SHIFT) + ARRAY_OFFSET); 413 } 414 } 415 } 416 417 // Checkstyle: stop 418 @BytecodeParserForceInline 419 public static void testAccess(Object base, long offset) { 420 // Advanced compare 421 { 422 boolean r = unsafe.compareAndExchangeBoolean(base, offset, false, true); 423 assertEquals(r, false, "success compareAndExchange boolean"); 424 boolean x = unsafe.getBoolean(base, offset); 425 assertEquals(x, true, "success compareAndExchange boolean value"); 426 } 427 428 { 429 boolean r = unsafe.compareAndExchangeBoolean(base, offset, false, false); 430 assertEquals(r, true, "failing compareAndExchange boolean"); 431 boolean x = unsafe.getBoolean(base, offset); 432 assertEquals(x, true, "failing compareAndExchange boolean value"); 433 } 434 435 { 436 boolean r = unsafe.compareAndExchangeBooleanAcquire(base, offset, true, false); 437 assertEquals(r, true, "success compareAndExchangeAcquire boolean"); 438 boolean x = unsafe.getBoolean(base, offset); 439 assertEquals(x, false, "success compareAndExchangeAcquire boolean value"); 440 } 441 442 { 443 boolean r = unsafe.compareAndExchangeBooleanAcquire(base, offset, true, false); 444 assertEquals(r, false, "failing compareAndExchangeAcquire boolean"); 445 boolean x = unsafe.getBoolean(base, offset); 446 assertEquals(x, false, "failing compareAndExchangeAcquire boolean value"); 447 } 448 449 { 450 boolean r = unsafe.compareAndExchangeBooleanRelease(base, offset, false, true); 451 assertEquals(r, false, "success compareAndExchangeRelease boolean"); 452 boolean x = unsafe.getBoolean(base, offset); 453 assertEquals(x, true, "success compareAndExchangeRelease boolean value"); 454 } 455 456 { 457 boolean r = unsafe.compareAndExchangeBooleanRelease(base, offset, false, false); 458 assertEquals(r, true, "failing compareAndExchangeRelease boolean"); 459 boolean x = unsafe.getBoolean(base, offset); 460 assertEquals(x, true, "failing compareAndExchangeRelease boolean value"); 461 } 462 463 { 464 boolean success = false; 465 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 466 success = unsafe.weakCompareAndSetBooleanPlain(base, offset, true, false); 467 } 468 assertEquals(success, true, "weakCompareAndSetPlain boolean"); 469 boolean x = unsafe.getBoolean(base, offset); 470 assertEquals(x, false, "weakCompareAndSetPlain boolean value"); 471 } 472 473 { 474 boolean success = false; 475 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 476 success = unsafe.weakCompareAndSetBooleanAcquire(base, offset, false, true); 477 } 478 assertEquals(success, true, "weakCompareAndSetAcquire boolean"); 479 boolean x = unsafe.getBoolean(base, offset); 480 assertEquals(x, true, "weakCompareAndSetAcquire boolean"); 481 } 482 483 { 484 boolean success = false; 485 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 486 success = unsafe.weakCompareAndSetBooleanRelease(base, offset, true, false); 487 } 488 assertEquals(success, true, "weakCompareAndSetRelease boolean"); 489 boolean x = unsafe.getBoolean(base, offset); 490 assertEquals(x, false, "weakCompareAndSetRelease boolean"); 491 } 492 493 { 494 boolean success = false; 495 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 496 success = unsafe.weakCompareAndSetBoolean(base, offset, false, true); 497 } 498 assertEquals(success, true, "weakCompareAndSet boolean"); 499 boolean x = unsafe.getBoolean(base, offset); 500 assertEquals(x, true, "weakCompareAndSet boolean"); 501 } 502 503 unsafe.putBoolean(base, offset, false); 504 505 // Compare set and get 506 { 507 boolean o = unsafe.getAndSetBoolean(base, offset, true); 508 assertEquals(o, false, "getAndSet boolean"); 509 boolean x = unsafe.getBoolean(base, offset); 510 assertEquals(x, true, "getAndSet boolean value"); 511 } 512 513 } 514 // Checkstyle: resume 515 } 516 517 public static boolean unsafeGetPutBoolean() { 518 Container container = new Container(); 519 unsafe.putBoolean(container, booleanOffset, true); 520 return unsafe.getBoolean(container, booleanOffset); 521 } 522 523 public static byte unsafeGetPutByte() { 524 Container container = new Container(); 525 unsafe.putByte(container, byteOffset, (byte) 0x12); 526 return unsafe.getByte(container, byteOffset); 527 } 528 529 public static short unsafeGetPutShort() { 530 Container container = new Container(); 531 unsafe.putShort(container, shortOffset, (short) 0x1234); 532 return unsafe.getShort(container, shortOffset); 533 } 534 535 public static char unsafeGetPutChar() { 536 Container container = new Container(); 537 unsafe.putChar(container, charOffset, 'x'); 538 return unsafe.getChar(container, charOffset); 539 } 540 541 public static int unsafeGetPutInt() { 542 Container container = new Container(); 543 unsafe.putInt(container, intOffset, 0x01234567); 544 return unsafe.getInt(container, intOffset); 545 } 546 547 public static long unsafeGetPutLong() { 548 Container container = new Container(); 549 unsafe.putLong(container, longOffset, 0x01234567890ABCDEFL); 550 return unsafe.getLong(container, longOffset); 551 } 552 553 public static float unsafeGetPutFloat() { 554 Container container = new Container(); 555 unsafe.putFloat(container, floatOffset, 1.234F); 556 return unsafe.getFloat(container, floatOffset); 557 } 558 559 public static double unsafeGetPutDouble() { 560 Container container = new Container(); 561 unsafe.putDouble(container, doubleOffset, 1.23456789); 562 return unsafe.getDouble(container, doubleOffset); 563 } 564 565 public static Object unsafeGetPutReference() { 566 Container container = new Container(); 567 unsafe.putReference(container, objectOffset, "Hello there"); 568 return unsafe.getReference(container, objectOffset); 569 } 570 571 public static boolean unsafeGetPutBooleanOpaque() { 572 Container container = new Container(); 573 unsafe.putBooleanOpaque(container, booleanOffset, true); 574 return unsafe.getBooleanOpaque(container, booleanOffset); 575 } 576 577 public static byte unsafeGetPutByteOpaque() { 578 Container container = new Container(); 579 unsafe.putByteOpaque(container, byteOffset, (byte) 0x12); 580 return unsafe.getByteOpaque(container, byteOffset); 581 } 582 583 public static short unsafeGetPutShortOpaque() { 584 Container container = new Container(); 585 unsafe.putShortOpaque(container, shortOffset, (short) 0x1234); 586 return unsafe.getShortOpaque(container, shortOffset); 587 } 588 589 public static char unsafeGetPutCharOpaque() { 590 Container container = new Container(); 591 unsafe.putCharOpaque(container, charOffset, 'x'); 592 return unsafe.getCharOpaque(container, charOffset); 593 } 594 595 public static int unsafeGetPutIntOpaque() { 596 Container container = new Container(); 597 unsafe.putIntOpaque(container, intOffset, 0x01234567); 598 return unsafe.getIntOpaque(container, intOffset); 599 } 600 601 public static long unsafeGetPutLongOpaque() { 602 Container container = new Container(); 603 unsafe.putLongOpaque(container, longOffset, 0x01234567890ABCDEFL); 604 return unsafe.getLongOpaque(container, longOffset); 605 } 606 607 public static float unsafeGetPutFloatOpaque() { 608 Container container = new Container(); 609 unsafe.putFloatOpaque(container, floatOffset, 1.234F); 610 return unsafe.getFloatOpaque(container, floatOffset); 611 } 612 613 public static double unsafeGetPutDoubleOpaque() { 614 Container container = new Container(); 615 unsafe.putDoubleOpaque(container, doubleOffset, 1.23456789); 616 return unsafe.getDoubleOpaque(container, doubleOffset); 617 } 618 619 public static Object unsafeGetPutReferenceOpaque() { 620 Container container = new Container(); 621 unsafe.putReferenceOpaque(container, objectOffset, "Hello there"); 622 return unsafe.getReferenceOpaque(container, objectOffset); 623 } 624 625 public static boolean unsafeGetPutBooleanRA() { 626 Container container = new Container(); 627 unsafe.putBooleanRelease(container, booleanOffset, true); 628 return unsafe.getBooleanAcquire(container, booleanOffset); 629 } 630 631 public static byte unsafeGetPutByteRA() { 632 Container container = new Container(); 633 unsafe.putByteRelease(container, byteOffset, (byte) 0x12); 634 return unsafe.getByteAcquire(container, byteOffset); 635 } 636 637 public static short unsafeGetPutShortRA() { 638 Container container = new Container(); 639 unsafe.putShortRelease(container, shortOffset, (short) 0x1234); 640 return unsafe.getShortAcquire(container, shortOffset); 641 } 642 643 public static char unsafeGetPutCharRA() { 644 Container container = new Container(); 645 unsafe.putCharRelease(container, charOffset, 'x'); 646 return unsafe.getCharAcquire(container, charOffset); 647 } 648 649 public static int unsafeGetPutIntRA() { 650 Container container = new Container(); 651 unsafe.putIntRelease(container, intOffset, 0x01234567); 652 return unsafe.getIntAcquire(container, intOffset); 653 } 654 655 public static long unsafeGetPutLongRA() { 656 Container container = new Container(); 657 unsafe.putLongRelease(container, longOffset, 0x01234567890ABCDEFL); 658 return unsafe.getLongAcquire(container, longOffset); 659 } 660 661 public static float unsafeGetPutFloatRA() { 662 Container container = new Container(); 663 unsafe.putFloatRelease(container, floatOffset, 1.234F); 664 return unsafe.getFloatAcquire(container, floatOffset); 665 } 666 667 public static double unsafeGetPutDoubleRA() { 668 Container container = new Container(); 669 unsafe.putDoubleRelease(container, doubleOffset, 1.23456789); 670 return unsafe.getDoubleAcquire(container, doubleOffset); 671 } 672 673 public static Object unsafeGetPutReferenceRA() { 674 Container container = new Container(); 675 unsafe.putReferenceRelease(container, objectOffset, "Hello there"); 676 return unsafe.getReferenceAcquire(container, objectOffset); 677 } 678 679 public static boolean unsafeGetPutBooleanVolatile() { 680 Container container = new Container(); 681 unsafe.putBooleanVolatile(container, booleanOffset, true); 682 return unsafe.getBooleanVolatile(container, booleanOffset); 683 } 684 685 public static byte unsafeGetPutByteVolatile() { 686 Container container = new Container(); 687 unsafe.putByteVolatile(container, byteOffset, (byte) 0x12); 688 return unsafe.getByteVolatile(container, byteOffset); 689 } 690 691 public static short unsafeGetPutShortVolatile() { 692 Container container = new Container(); 693 unsafe.putShortVolatile(container, shortOffset, (short) 0x1234); 694 return unsafe.getShortVolatile(container, shortOffset); 695 } 696 697 public static char unsafeGetPutCharVolatile() { 698 Container container = new Container(); 699 unsafe.putCharVolatile(container, charOffset, 'x'); 700 return unsafe.getCharVolatile(container, charOffset); 701 } 702 703 public static int unsafeGetPutIntVolatile() { 704 Container container = new Container(); 705 unsafe.putIntVolatile(container, intOffset, 0x01234567); 706 return unsafe.getIntVolatile(container, intOffset); 707 } 708 709 public static long unsafeGetPutLongVolatile() { 710 Container container = new Container(); 711 unsafe.putLongVolatile(container, longOffset, 0x01234567890ABCDEFL); 712 return unsafe.getLongVolatile(container, longOffset); 713 } 714 715 public static float unsafeGetPutFloatVolatile() { 716 Container container = new Container(); 717 unsafe.putFloatVolatile(container, floatOffset, 1.234F); 718 return unsafe.getFloatVolatile(container, floatOffset); 719 } 720 721 public static double unsafeGetPutDoubleVolatile() { 722 Container container = new Container(); 723 unsafe.putDoubleVolatile(container, doubleOffset, 1.23456789); 724 return unsafe.getDoubleVolatile(container, doubleOffset); 725 } 726 727 public static Object unsafeGetPutReferenceVolatile() { 728 Container container = new Container(); 729 unsafe.putReferenceVolatile(container, objectOffset, "Hello there"); 730 return unsafe.getReferenceVolatile(container, objectOffset); 731 } 732 733 @Test 734 public void testUnsafeGetPutPlain() { 735 testGraph("unsafeGetPutBoolean"); 736 testGraph("unsafeGetPutByte"); 737 testGraph("unsafeGetPutShort"); 738 testGraph("unsafeGetPutChar"); 739 testGraph("unsafeGetPutInt"); 740 testGraph("unsafeGetPutLong"); 741 testGraph("unsafeGetPutFloat"); 742 testGraph("unsafeGetPutDouble"); 743 testGraph("unsafeGetPutObject"); 744 745 test("unsafeGetPutBoolean"); 746 test("unsafeGetPutByte"); 747 test("unsafeGetPutShort"); 748 test("unsafeGetPutChar"); 749 test("unsafeGetPutInt"); 750 test("unsafeGetPutLong"); 751 test("unsafeGetPutFloat"); 752 test("unsafeGetPutDouble"); 753 test("unsafeGetPutObject"); 754 } 755 756 @Test 757 public void testUnsafeGetPutOpaque() { 758 testGraph("unsafeGetPutBooleanOpaque"); 759 testGraph("unsafeGetPutByteOpaque"); 760 testGraph("unsafeGetPutShortOpaque"); 761 testGraph("unsafeGetPutCharOpaque"); 762 testGraph("unsafeGetPutIntOpaque"); 763 testGraph("unsafeGetPutLongOpaque"); 764 testGraph("unsafeGetPutFloatOpaque"); 765 testGraph("unsafeGetPutDoubleOpaque"); 766 testGraph("unsafeGetPutObjectOpaque"); 767 768 test("unsafeGetPutBooleanOpaque"); 769 test("unsafeGetPutByteOpaque"); 770 test("unsafeGetPutShortOpaque"); 771 test("unsafeGetPutCharOpaque"); 772 test("unsafeGetPutIntOpaque"); 773 test("unsafeGetPutLongOpaque"); 774 test("unsafeGetPutFloatOpaque"); 775 test("unsafeGetPutDoubleOpaque"); 776 test("unsafeGetPutObjectOpaque"); 777 } 778 779 @Test 780 public void testUnsafeGetPutReleaseAcquire() { 781 testGraph("unsafeGetPutBooleanRA"); 782 testGraph("unsafeGetPutByteRA"); 783 testGraph("unsafeGetPutShortRA"); 784 testGraph("unsafeGetPutCharRA"); 785 testGraph("unsafeGetPutIntRA"); 786 testGraph("unsafeGetPutLongRA"); 787 testGraph("unsafeGetPutFloatRA"); 788 testGraph("unsafeGetPutDoubleRA"); 789 testGraph("unsafeGetPutReferenceRA"); 790 791 test("unsafeGetPutBooleanRA"); 792 test("unsafeGetPutByteRA"); 793 test("unsafeGetPutShortRA"); 794 test("unsafeGetPutCharRA"); 795 test("unsafeGetPutIntRA"); 796 test("unsafeGetPutLongRA"); 797 test("unsafeGetPutFloatRA"); 798 test("unsafeGetPutDoubleRA"); 799 test("unsafeGetPutReferenceRA"); 800 } 801 802 @Test 803 public void testUnsafeGetPutVolatile() { 804 testGraph("unsafeGetPutBooleanVolatile"); 805 testGraph("unsafeGetPutByteVolatile"); 806 testGraph("unsafeGetPutShortVolatile"); 807 testGraph("unsafeGetPutCharVolatile"); 808 testGraph("unsafeGetPutIntVolatile"); 809 testGraph("unsafeGetPutLongVolatile"); 810 testGraph("unsafeGetPutFloatVolatile"); 811 testGraph("unsafeGetPutDoubleVolatile"); 812 testGraph("unsafeGetPutReferenceVolatile"); 813 814 test("unsafeGetPutBooleanVolatile"); 815 test("unsafeGetPutByteVolatile"); 816 test("unsafeGetPutShortVolatile"); 817 test("unsafeGetPutCharVolatile"); 818 test("unsafeGetPutIntVolatile"); 819 test("unsafeGetPutLongVolatile"); 820 test("unsafeGetPutFloatVolatile"); 821 test("unsafeGetPutDoubleVolatile"); 822 test("unsafeGetPutReferenceVolatile"); 823 } 824 }