• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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