1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package libcore.jdk.internal.misc; 17 18 import static org.junit.Assert.assertEquals; 19 20 import java.lang.reflect.Field; 21 22 import jdk.internal.misc.Unsafe; 23 24 import libcore.test.annotation.NonCts; 25 import libcore.test.reasons.NonCtsReasons; 26 27 import org.junit.Test; 28 import org.junit.runner.RunWith; 29 import org.junit.runners.JUnit4; 30 31 @NonCts(bug = 287231726, reason = NonCtsReasons.INTERNAL_APIS) 32 @RunWith(JUnit4.class) 33 public class UnsafeTest { 34 35 @SuppressWarnings("unused") 36 private static class TestFixture { 37 public static boolean staticBooleanVar = false; 38 public static byte staticByteVar = 40; 39 public static int staticIntVar = 2056; 40 public static long staticLongVar = 1234567890; 41 public static float staticFloatVar = 2.618f; 42 public static double staticDoubleVar = 3.1415; 43 44 public boolean booleanVar = true; 45 public byte byteVar = 42; 46 public int intVar = 2046; 47 public long longVar = 123456789; 48 public float floatVar = 1.618f; 49 public double doubleVar = 3.141; 50 public Object objectVar = new Object(); 51 } 52 53 54 @Test testCompareAndExchangeLong()55 public void testCompareAndExchangeLong() throws Exception { 56 Unsafe unsafe = getUnsafe(); 57 TestFixture tf = new TestFixture(); 58 long offset = unsafe.objectFieldOffset(TestFixture.class, "longVar"); 59 assertEquals(123456789, unsafe.compareAndExchangeLong(tf, offset, 0, -1)); 60 assertEquals(123456789, tf.longVar); 61 assertEquals(123456789, unsafe.compareAndExchangeLong(tf, offset, 123456789, -1)); 62 assertEquals(-1, tf.longVar); 63 assertEquals(-1, unsafe.compareAndExchangeLong(tf, offset, 0, 1)); 64 assertEquals(-1, tf.longVar); 65 assertEquals(-1, unsafe.compareAndExchangeLong(tf, offset, -1, 1)); 66 assertEquals(1, tf.longVar); 67 } 68 69 @Test testStaticOffset()70 public void testStaticOffset() throws Exception { 71 Unsafe unsafe = getUnsafe(); 72 Class c = Class.forName("libcore.jdk.internal.misc.UnsafeTest$TestFixture"); 73 Field f = c.getDeclaredField("staticIntVar"); 74 Object obj = unsafe.staticFieldBase(f); 75 long offset = unsafe.staticFieldOffset(f); 76 77 assertEquals(2056, unsafe.getInt(obj, offset)); 78 assertEquals(2056, unsafe.getAndSetInt(obj, offset, 0)); 79 assertEquals(0, TestFixture.staticIntVar); 80 81 assertEquals(0, unsafe.getAndSetInt(obj, offset, 1)); 82 assertEquals(1, TestFixture.staticIntVar); 83 84 assertEquals(1, unsafe.getAndSetInt(obj, offset, 2056)); 85 assertEquals(2056, TestFixture.staticIntVar); 86 } 87 getUnsafe()88 private static Unsafe getUnsafe() throws Exception { 89 Class<?> unsafeClass = Class.forName("jdk.internal.misc.Unsafe"); 90 Field f = unsafeClass.getDeclaredField("theUnsafe"); 91 f.setAccessible(true); 92 return (Unsafe) f.get(null); 93 } 94 95 } 96