blob: b56c244d5c5a8578873d4b14c2b79836a943771d [file] [log] [blame]
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.replacements.jdk9;
import jdk.vm.ci.aarch64.AArch64;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.code.TargetDescription;
import org.graalvm.compiler.api.test.Graal;
import org.graalvm.compiler.core.phases.HighTier;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.replacements.test.MethodSubstitutionTest;
import org.graalvm.compiler.runtime.RuntimeProvider;
import org.graalvm.compiler.test.AddExports;
import org.junit.Test;
import java.lang.reflect.Field;
@AddExports("java.base/jdk.internal.misc")
public class UnsafeReplacementsTest extends MethodSubstitutionTest {
static class Container {
public volatile boolean booleanField;
public volatile byte byteField = 17;
public volatile char charField = 1025;
public volatile short shortField = 2232;
public volatile int intField = 0xcafebabe;
public volatile long longField = 0xdedababafafaL;
public volatile float floatField = 0.125f;
public volatile double doubleField = 0.125;
public volatile Object objectField = dummyValue;
}
static jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
static Container dummyValue = new Container();
static Container newDummyValue = new Container();
static long booleanOffset;
static long byteOffset;
static long charOffset;
static long shortOffset;
static long intOffset;
static long longOffset;
static long floatOffset;
static long doubleOffset;
static long objectOffset;
static {
try {
booleanOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("booleanField"));
byteOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("byteField"));
charOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("charField"));
shortOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("shortField"));
intOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("intField"));
longOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("longField"));
floatOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("floatField"));
doubleOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("doubleField"));
objectOffset = unsafe.objectFieldOffset(Container.class.getDeclaredField("objectField"));
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
public static boolean unsafeCompareAndSetBoolean() {
Container container = new Container();
return unsafe.compareAndSetBoolean(container, booleanOffset, false, true);
}
public static boolean unsafeCompareAndSetByte() {
Container container = new Container();
return unsafe.compareAndSetByte(container, byteOffset, (byte) 17, (byte) 121);
}
public static boolean unsafeCompareAndSetChar() {
Container container = new Container();
return unsafe.compareAndSetChar(container, charOffset, (char) 1025, (char) 1777);
}
public static boolean unsafeCompareAndSetShort() {
Container container = new Container();
return unsafe.compareAndSetShort(container, shortOffset, (short) 2232, (short) 12111);
}
public static boolean unsafeCompareAndSetInt() {
Container container = new Container();
return unsafe.compareAndSetInt(container, intOffset, 0xcafebabe, 0xbabefafa);
}
public static boolean unsafeCompareAndSetLong() {
Container container = new Container();
return unsafe.compareAndSetLong(container, longOffset, 0xdedababafafaL, 0xfafacecafafadedaL);
}
public static boolean unsafeCompareAndSetFloat() {
Container container = new Container();
return unsafe.compareAndSetFloat(container, floatOffset, 0.125f, 0.25f);
}
public static boolean unsafeCompareAndSetDouble() {
Container container = new Container();
return unsafe.compareAndSetDouble(container, doubleOffset, 0.125, 0.25);
}
public static boolean unsafeCompareAndSetObject() {
Container container = new Container();
return unsafe.compareAndSetObject(container, objectOffset, dummyValue, newDummyValue);
}
public static boolean unsafeCompareAndExchangeBoolean() {
Container container = new Container();
return unsafe.compareAndExchangeBoolean(container, booleanOffset, false, true);
}
public static byte unsafeCompareAndExchangeByte() {
Container container = new Container();
return unsafe.compareAndExchangeByte(container, byteOffset, (byte) 17, (byte) 31);
}
public static char unsafeCompareAndExchangeChar() {
Container container = new Container();
return unsafe.compareAndExchangeChar(container, charOffset, (char) 1025, (char) 4502);
}
public static short unsafeCompareAndExchangeShort() {
Container container = new Container();
return unsafe.compareAndExchangeShort(container, shortOffset, (short) 2232, (short) 8121);
}
public static int unsafeCompareAndExchangeInt() {
Container container = new Container();
return unsafe.compareAndExchangeInt(container, intOffset, 0xcafebabe, 0xbabefafa);
}
public static long unsafeCompareAndExchangeLong() {
Container container = new Container();
return unsafe.compareAndExchangeLong(container, longOffset, 0xdedababafafaL, 0xfafacecafafadedaL);
}
public static float unsafeCompareAndExchangeFloat() {
Container container = new Container();
return unsafe.compareAndExchangeFloat(container, floatOffset, 0.125f, 0.25f);
}
public static double unsafeCompareAndExchangeDouble() {
Container container = new Container();
return unsafe.compareAndExchangeDouble(container, doubleOffset, 0.125, 0.25);
}
public static Object unsafeCompareAndExchangeObject() {
Container container = new Container();
return unsafe.compareAndExchangeObject(container, objectOffset, dummyValue, newDummyValue);
}
@Test
public void testCompareAndSet() {
TargetDescription target = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getTarget();
if (target.arch instanceof AMD64) {
testGraph("unsafeCompareAndSetBoolean");
testGraph("unsafeCompareAndSetByte");
testGraph("unsafeCompareAndSetChar");
testGraph("unsafeCompareAndSetShort");
testGraph("unsafeCompareAndSetInt");
testGraph("unsafeCompareAndSetLong");
testGraph("unsafeCompareAndSetFloat");
testGraph("unsafeCompareAndSetDouble");
testGraph("unsafeCompareAndSetObject");
testGraph("unsafeCompareAndExchangeBoolean");
testGraph("unsafeCompareAndExchangeByte");
testGraph("unsafeCompareAndExchangeChar");
testGraph("unsafeCompareAndExchangeShort");
testGraph("unsafeCompareAndExchangeInt");
testGraph("unsafeCompareAndExchangeLong");
testGraph("unsafeCompareAndExchangeFloat");
testGraph("unsafeCompareAndExchangeDouble");
testGraph("unsafeCompareAndExchangeObject");
}
test("unsafeCompareAndSetBoolean");
test("unsafeCompareAndSetByte");
test("unsafeCompareAndSetChar");
test("unsafeCompareAndSetShort");
test("unsafeCompareAndSetInt");
test("unsafeCompareAndSetLong");
test("unsafeCompareAndSetFloat");
test("unsafeCompareAndSetDouble");
test("unsafeCompareAndSetObject");
test("unsafeCompareAndExchangeBoolean");
test("unsafeCompareAndExchangeByte");
test("unsafeCompareAndExchangeChar");
test("unsafeCompareAndExchangeShort");
test("unsafeCompareAndExchangeInt");
test("unsafeCompareAndExchangeLong");
test("unsafeCompareAndExchangeFloat");
test("unsafeCompareAndExchangeDouble");
test("unsafeCompareAndExchangeObject");
}
public static int unsafeGetAndAddByte() {
Container container = new Container();
return unsafe.getAndAddByte(container, byteOffset, (byte) 2);
}
public static int unsafeGetAndAddChar() {
Container container = new Container();
return unsafe.getAndAddChar(container, charOffset, (char) 250);
}
public static int unsafeGetAndAddShort() {
Container container = new Container();
return unsafe.getAndAddShort(container, shortOffset, (short) 1250);
}
public static int unsafeGetAndAddInt() {
Container container = new Container();
return unsafe.getAndAddInt(container, intOffset, 104501);
}
public static long unsafeGetAndAddLong() {
Container container = new Container();
return unsafe.getAndAddLong(container, longOffset, 0x123456abcdL);
}
@Test
public void testGetAndAdd() {
TargetDescription target = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getTarget();
if (target.arch instanceof AMD64) {
testGraph("unsafeGetAndAddByte");
testGraph("unsafeGetAndAddChar");
testGraph("unsafeGetAndAddShort");
}
if (target.arch instanceof AMD64 || target.arch instanceof AArch64) {
testGraph("unsafeGetAndAddInt");
testGraph("unsafeGetAndAddLong");
}
test("unsafeGetAndAddByte");
test("unsafeGetAndAddChar");
test("unsafeGetAndAddShort");
test("unsafeGetAndAddInt");
test("unsafeGetAndAddLong");
}
public static boolean unsafeGetAndSetBoolean() {
Container container = new Container();
return unsafe.getAndSetBoolean(container, booleanOffset, true);
}
public static byte unsafeGetAndSetByte() {
Container container = new Container();
return unsafe.getAndSetByte(container, byteOffset, (byte) 129);
}
public static char unsafeGetAndSetChar() {
Container container = new Container();
return unsafe.getAndSetChar(container, charOffset, (char) 21111);
}
public static short unsafeGetAndSetShort() {
Container container = new Container();
return unsafe.getAndSetShort(container, shortOffset, (short) 21111);
}
public static int unsafeGetAndSetInt() {
Container container = new Container();
return unsafe.getAndSetInt(container, intOffset, 0x1234af);
}
public static long unsafeGetAndSetLong() {
Container container = new Container();
return unsafe.getAndSetLong(container, longOffset, 0x12345678abL);
}
public static Object unsafeGetAndSetObject() {
Container container = new Container();
container.objectField = null;
Container other = new Container();
return unsafe.getAndSetObject(container, objectOffset, other);
}
@Test
public void testGetAndSet() {
TargetDescription target = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getTarget();
if (target.arch instanceof AMD64) {
testGraph("unsafeGetAndSetBoolean");
testGraph("unsafeGetAndSetByte");
testGraph("unsafeGetAndSetChar");
testGraph("unsafeGetAndSetShort");
}
if (target.arch instanceof AMD64 || target.arch instanceof AArch64) {
testGraph("unsafeGetAndSetInt");
testGraph("unsafeGetAndSetLong");
testGraph("unsafeGetAndSetObject");
}
test("unsafeGetAndSetBoolean");
test("unsafeGetAndSetByte");
test("unsafeGetAndSetChar");
test("unsafeGetAndSetShort");
test("unsafeGetAndSetInt");
test("unsafeGetAndSetLong");
test("unsafeGetAndSetObject");
}
public static void fieldInstance() {
JdkInternalMiscUnsafeAccessTestBoolean.testFieldInstance();
}
@Test
public void testFieldInstance() {
test(new OptionValues(getInitialOptions(), HighTier.Options.Inline, false), "fieldInstance");
}
public static void array() {
JdkInternalMiscUnsafeAccessTestBoolean.testArray();
}
@Test
public void testArray() {
test(new OptionValues(getInitialOptions(), HighTier.Options.Inline, false), "array");
}
public static void fieldStatic() {
JdkInternalMiscUnsafeAccessTestBoolean.testFieldStatic();
}
@Test
public void testFieldStatic() {
test(new OptionValues(getInitialOptions(), HighTier.Options.Inline, false), "fieldStatic");
}
public static void assertEquals(Object seen, Object expected, String message) {
if (seen != expected) {
throw new AssertionError(message + " - seen: " + seen + ", expected: " + expected);
}
}
public static class JdkInternalMiscUnsafeAccessTestBoolean {
static final int ITERATIONS = 100000;
static final int WEAK_ATTEMPTS = 10;
static final long V_OFFSET;
static final Object STATIC_V_BASE;
static final long STATIC_V_OFFSET;
static final int ARRAY_OFFSET;
static final int ARRAY_SHIFT;
static {
try {
Field staticVField = UnsafeReplacementsTest.JdkInternalMiscUnsafeAccessTestBoolean.class.getDeclaredField("staticV");
STATIC_V_BASE = unsafe.staticFieldBase(staticVField);
STATIC_V_OFFSET = unsafe.staticFieldOffset(staticVField);
} catch (Exception e) {
throw new RuntimeException(e);
}
try {
Field vField = UnsafeReplacementsTest.JdkInternalMiscUnsafeAccessTestBoolean.class.getDeclaredField("v");
V_OFFSET = unsafe.objectFieldOffset(vField);
} catch (Exception e) {
throw new RuntimeException(e);
}
ARRAY_OFFSET = unsafe.arrayBaseOffset(boolean[].class);
int ascale = unsafe.arrayIndexScale(boolean[].class);
ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale);
}
static boolean staticV;
boolean v;
@BytecodeParserForceInline
public static void testFieldInstance() {
JdkInternalMiscUnsafeAccessTestBoolean t = new JdkInternalMiscUnsafeAccessTestBoolean();
for (int c = 0; c < ITERATIONS; c++) {
testAccess(t, V_OFFSET);
}
}
public static void testFieldStatic() {
for (int c = 0; c < ITERATIONS; c++) {
testAccess(STATIC_V_BASE, STATIC_V_OFFSET);
}
}
public static void testArray() {
boolean[] array = new boolean[10];
for (int c = 0; c < ITERATIONS; c++) {
for (int i = 0; i < array.length; i++) {
testAccess(array, (((long) i) << ARRAY_SHIFT) + ARRAY_OFFSET);
}
}
}
// Checkstyle: stop
@BytecodeParserForceInline
public static void testAccess(Object base, long offset) {
// Advanced compare
{
boolean r = unsafe.compareAndExchangeBoolean(base, offset, false, true);
assertEquals(r, false, "success compareAndExchange boolean");
boolean x = unsafe.getBoolean(base, offset);
assertEquals(x, true, "success compareAndExchange boolean value");
}
{
boolean r = unsafe.compareAndExchangeBoolean(base, offset, false, false);
assertEquals(r, true, "failing compareAndExchange boolean");
boolean x = unsafe.getBoolean(base, offset);
assertEquals(x, true, "failing compareAndExchange boolean value");
}
{
boolean r = unsafe.compareAndExchangeBooleanAcquire(base, offset, true, false);
assertEquals(r, true, "success compareAndExchangeAcquire boolean");
boolean x = unsafe.getBoolean(base, offset);
assertEquals(x, false, "success compareAndExchangeAcquire boolean value");
}
{
boolean r = unsafe.compareAndExchangeBooleanAcquire(base, offset, true, false);
assertEquals(r, false, "failing compareAndExchangeAcquire boolean");
boolean x = unsafe.getBoolean(base, offset);
assertEquals(x, false, "failing compareAndExchangeAcquire boolean value");
}
{
boolean r = unsafe.compareAndExchangeBooleanRelease(base, offset, false, true);
assertEquals(r, false, "success compareAndExchangeRelease boolean");
boolean x = unsafe.getBoolean(base, offset);
assertEquals(x, true, "success compareAndExchangeRelease boolean value");
}
{
boolean r = unsafe.compareAndExchangeBooleanRelease(base, offset, false, false);
assertEquals(r, true, "failing compareAndExchangeRelease boolean");
boolean x = unsafe.getBoolean(base, offset);
assertEquals(x, true, "failing compareAndExchangeRelease boolean value");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = unsafe.weakCompareAndSetBooleanPlain(base, offset, true, false);
}
assertEquals(success, true, "weakCompareAndSetPlain boolean");
boolean x = unsafe.getBoolean(base, offset);
assertEquals(x, false, "weakCompareAndSetPlain boolean value");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = unsafe.weakCompareAndSetBooleanAcquire(base, offset, false, true);
}
assertEquals(success, true, "weakCompareAndSetAcquire boolean");
boolean x = unsafe.getBoolean(base, offset);
assertEquals(x, true, "weakCompareAndSetAcquire boolean");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = unsafe.weakCompareAndSetBooleanRelease(base, offset, true, false);
}
assertEquals(success, true, "weakCompareAndSetRelease boolean");
boolean x = unsafe.getBoolean(base, offset);
assertEquals(x, false, "weakCompareAndSetRelease boolean");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = unsafe.weakCompareAndSetBoolean(base, offset, false, true);
}
assertEquals(success, true, "weakCompareAndSet boolean");
boolean x = unsafe.getBoolean(base, offset);
assertEquals(x, true, "weakCompareAndSet boolean");
}
unsafe.putBoolean(base, offset, false);
// Compare set and get
{
boolean o = unsafe.getAndSetBoolean(base, offset, true);
assertEquals(o, false, "getAndSet boolean");
boolean x = unsafe.getBoolean(base, offset);
assertEquals(x, true, "getAndSet boolean value");
}
}
// Checkstyle: resume
}
public static boolean unsafeGetPutBoolean() {
Container container = new Container();
unsafe.putBoolean(container, booleanOffset, true);
return unsafe.getBoolean(container, booleanOffset);
}
public static byte unsafeGetPutByte() {
Container container = new Container();
unsafe.putByte(container, byteOffset, (byte) 0x12);
return unsafe.getByte(container, byteOffset);
}
public static short unsafeGetPutShort() {
Container container = new Container();
unsafe.putShort(container, shortOffset, (short) 0x1234);
return unsafe.getShort(container, shortOffset);
}
public static char unsafeGetPutChar() {
Container container = new Container();
unsafe.putChar(container, charOffset, 'x');
return unsafe.getChar(container, charOffset);
}
public static int unsafeGetPutInt() {
Container container = new Container();
unsafe.putInt(container, intOffset, 0x01234567);
return unsafe.getInt(container, intOffset);
}
public static long unsafeGetPutLong() {
Container container = new Container();
unsafe.putLong(container, longOffset, 0x01234567890ABCDEFL);
return unsafe.getLong(container, longOffset);
}
public static float unsafeGetPutFloat() {
Container container = new Container();
unsafe.putFloat(container, floatOffset, 1.234F);
return unsafe.getFloat(container, floatOffset);
}
public static double unsafeGetPutDouble() {
Container container = new Container();
unsafe.putDouble(container, doubleOffset, 1.23456789);
return unsafe.getDouble(container, doubleOffset);
}
public static Object unsafeGetPutObject() {
Container container = new Container();
unsafe.putObject(container, objectOffset, "Hello there");
return unsafe.getObject(container, objectOffset);
}
public static boolean unsafeGetPutBooleanOpaque() {
Container container = new Container();
unsafe.putBooleanOpaque(container, booleanOffset, true);
return unsafe.getBooleanOpaque(container, booleanOffset);
}
public static byte unsafeGetPutByteOpaque() {
Container container = new Container();
unsafe.putByteOpaque(container, byteOffset, (byte) 0x12);
return unsafe.getByteOpaque(container, byteOffset);
}
public static short unsafeGetPutShortOpaque() {
Container container = new Container();
unsafe.putShortOpaque(container, shortOffset, (short) 0x1234);
return unsafe.getShortOpaque(container, shortOffset);
}
public static char unsafeGetPutCharOpaque() {
Container container = new Container();
unsafe.putCharOpaque(container, charOffset, 'x');
return unsafe.getCharOpaque(container, charOffset);
}
public static int unsafeGetPutIntOpaque() {
Container container = new Container();
unsafe.putIntOpaque(container, intOffset, 0x01234567);
return unsafe.getIntOpaque(container, intOffset);
}
public static long unsafeGetPutLongOpaque() {
Container container = new Container();
unsafe.putLongOpaque(container, longOffset, 0x01234567890ABCDEFL);
return unsafe.getLongOpaque(container, longOffset);
}
public static float unsafeGetPutFloatOpaque() {
Container container = new Container();
unsafe.putFloatOpaque(container, floatOffset, 1.234F);
return unsafe.getFloatOpaque(container, floatOffset);
}
public static double unsafeGetPutDoubleOpaque() {
Container container = new Container();
unsafe.putDoubleOpaque(container, doubleOffset, 1.23456789);
return unsafe.getDoubleOpaque(container, doubleOffset);
}
public static Object unsafeGetPutObjectOpaque() {
Container container = new Container();
unsafe.putObjectOpaque(container, objectOffset, "Hello there");
return unsafe.getObjectOpaque(container, objectOffset);
}
public static boolean unsafeGetPutBooleanRA() {
Container container = new Container();
unsafe.putBooleanRelease(container, booleanOffset, true);
return unsafe.getBooleanAcquire(container, booleanOffset);
}
public static byte unsafeGetPutByteRA() {
Container container = new Container();
unsafe.putByteRelease(container, byteOffset, (byte) 0x12);
return unsafe.getByteAcquire(container, byteOffset);
}
public static short unsafeGetPutShortRA() {
Container container = new Container();
unsafe.putShortRelease(container, shortOffset, (short) 0x1234);
return unsafe.getShortAcquire(container, shortOffset);
}
public static char unsafeGetPutCharRA() {
Container container = new Container();
unsafe.putCharRelease(container, charOffset, 'x');
return unsafe.getCharAcquire(container, charOffset);
}
public static int unsafeGetPutIntRA() {
Container container = new Container();
unsafe.putIntRelease(container, intOffset, 0x01234567);
return unsafe.getIntAcquire(container, intOffset);
}
public static long unsafeGetPutLongRA() {
Container container = new Container();
unsafe.putLongRelease(container, longOffset, 0x01234567890ABCDEFL);
return unsafe.getLongAcquire(container, longOffset);
}
public static float unsafeGetPutFloatRA() {
Container container = new Container();
unsafe.putFloatRelease(container, floatOffset, 1.234F);
return unsafe.getFloatAcquire(container, floatOffset);
}
public static double unsafeGetPutDoubleRA() {
Container container = new Container();
unsafe.putDoubleRelease(container, doubleOffset, 1.23456789);
return unsafe.getDoubleAcquire(container, doubleOffset);
}
public static Object unsafeGetPutObjectRA() {
Container container = new Container();
unsafe.putObjectRelease(container, objectOffset, "Hello there");
return unsafe.getObjectAcquire(container, objectOffset);
}
public static boolean unsafeGetPutBooleanVolatile() {
Container container = new Container();
unsafe.putBooleanVolatile(container, booleanOffset, true);
return unsafe.getBooleanVolatile(container, booleanOffset);
}
public static byte unsafeGetPutByteVolatile() {
Container container = new Container();
unsafe.putByteVolatile(container, byteOffset, (byte) 0x12);
return unsafe.getByteVolatile(container, byteOffset);
}
public static short unsafeGetPutShortVolatile() {
Container container = new Container();
unsafe.putShortVolatile(container, shortOffset, (short) 0x1234);
return unsafe.getShortVolatile(container, shortOffset);
}
public static char unsafeGetPutCharVolatile() {
Container container = new Container();
unsafe.putCharVolatile(container, charOffset, 'x');
return unsafe.getCharVolatile(container, charOffset);
}
public static int unsafeGetPutIntVolatile() {
Container container = new Container();
unsafe.putIntVolatile(container, intOffset, 0x01234567);
return unsafe.getIntVolatile(container, intOffset);
}
public static long unsafeGetPutLongVolatile() {
Container container = new Container();
unsafe.putLongVolatile(container, longOffset, 0x01234567890ABCDEFL);
return unsafe.getLongVolatile(container, longOffset);
}
public static float unsafeGetPutFloatVolatile() {
Container container = new Container();
unsafe.putFloatVolatile(container, floatOffset, 1.234F);
return unsafe.getFloatVolatile(container, floatOffset);
}
public static double unsafeGetPutDoubleVolatile() {
Container container = new Container();
unsafe.putDoubleVolatile(container, doubleOffset, 1.23456789);
return unsafe.getDoubleVolatile(container, doubleOffset);
}
public static Object unsafeGetPutObjectVolatile() {
Container container = new Container();
unsafe.putObjectVolatile(container, objectOffset, "Hello there");
return unsafe.getObjectVolatile(container, objectOffset);
}
@Test
public void testUnsafeGetPutPlain() {
testGraph("unsafeGetPutBoolean");
testGraph("unsafeGetPutByte");
testGraph("unsafeGetPutShort");
testGraph("unsafeGetPutChar");
testGraph("unsafeGetPutInt");
testGraph("unsafeGetPutLong");
testGraph("unsafeGetPutFloat");
testGraph("unsafeGetPutDouble");
testGraph("unsafeGetPutObject");
test("unsafeGetPutBoolean");
test("unsafeGetPutByte");
test("unsafeGetPutShort");
test("unsafeGetPutChar");
test("unsafeGetPutInt");
test("unsafeGetPutLong");
test("unsafeGetPutFloat");
test("unsafeGetPutDouble");
test("unsafeGetPutObject");
}
@Test
public void testUnsafeGetPutOpaque() {
testGraph("unsafeGetPutBooleanOpaque");
testGraph("unsafeGetPutByteOpaque");
testGraph("unsafeGetPutShortOpaque");
testGraph("unsafeGetPutCharOpaque");
testGraph("unsafeGetPutIntOpaque");
testGraph("unsafeGetPutLongOpaque");
testGraph("unsafeGetPutFloatOpaque");
testGraph("unsafeGetPutDoubleOpaque");
testGraph("unsafeGetPutObjectOpaque");
test("unsafeGetPutBooleanOpaque");
test("unsafeGetPutByteOpaque");
test("unsafeGetPutShortOpaque");
test("unsafeGetPutCharOpaque");
test("unsafeGetPutIntOpaque");
test("unsafeGetPutLongOpaque");
test("unsafeGetPutFloatOpaque");
test("unsafeGetPutDoubleOpaque");
test("unsafeGetPutObjectOpaque");
}
@Test
public void testUnsafeGetPutReleaseAcquire() {
testGraph("unsafeGetPutBooleanRA");
testGraph("unsafeGetPutByteRA");
testGraph("unsafeGetPutShortRA");
testGraph("unsafeGetPutCharRA");
testGraph("unsafeGetPutIntRA");
testGraph("unsafeGetPutLongRA");
testGraph("unsafeGetPutFloatRA");
testGraph("unsafeGetPutDoubleRA");
testGraph("unsafeGetPutObjectRA");
test("unsafeGetPutBooleanRA");
test("unsafeGetPutByteRA");
test("unsafeGetPutShortRA");
test("unsafeGetPutCharRA");
test("unsafeGetPutIntRA");
test("unsafeGetPutLongRA");
test("unsafeGetPutFloatRA");
test("unsafeGetPutDoubleRA");
test("unsafeGetPutObjectRA");
}
@Test
public void testUnsafeGetPutVolatile() {
testGraph("unsafeGetPutBooleanVolatile");
testGraph("unsafeGetPutByteVolatile");
testGraph("unsafeGetPutShortVolatile");
testGraph("unsafeGetPutCharVolatile");
testGraph("unsafeGetPutIntVolatile");
testGraph("unsafeGetPutLongVolatile");
testGraph("unsafeGetPutFloatVolatile");
testGraph("unsafeGetPutDoubleVolatile");
testGraph("unsafeGetPutObjectVolatile");
test("unsafeGetPutBooleanVolatile");
test("unsafeGetPutByteVolatile");
test("unsafeGetPutShortVolatile");
test("unsafeGetPutCharVolatile");
test("unsafeGetPutIntVolatile");
test("unsafeGetPutLongVolatile");
test("unsafeGetPutFloatVolatile");
test("unsafeGetPutDoubleVolatile");
test("unsafeGetPutObjectVolatile");
}
}