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