1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Field; 18*795d594fSAndroid Build Coastguard Worker import sun.misc.Unsafe; 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker public class Main { check(int actual, int expected, String msg)21*795d594fSAndroid Build Coastguard Worker private static void check(int actual, int expected, String msg) { 22*795d594fSAndroid Build Coastguard Worker if (actual != expected) { 23*795d594fSAndroid Build Coastguard Worker System.out.println(msg + " : " + actual + " != " + expected); 24*795d594fSAndroid Build Coastguard Worker System.exit(1); 25*795d594fSAndroid Build Coastguard Worker } 26*795d594fSAndroid Build Coastguard Worker } 27*795d594fSAndroid Build Coastguard Worker check(long actual, long expected, String msg)28*795d594fSAndroid Build Coastguard Worker private static void check(long actual, long expected, String msg) { 29*795d594fSAndroid Build Coastguard Worker if (actual != expected) { 30*795d594fSAndroid Build Coastguard Worker System.out.println(msg + " : " + actual + " != " + expected); 31*795d594fSAndroid Build Coastguard Worker System.exit(1); 32*795d594fSAndroid Build Coastguard Worker } 33*795d594fSAndroid Build Coastguard Worker } 34*795d594fSAndroid Build Coastguard Worker check(float actual, float expected, String msg)35*795d594fSAndroid Build Coastguard Worker private static void check(float actual, float expected, String msg) { 36*795d594fSAndroid Build Coastguard Worker if (actual != expected) { 37*795d594fSAndroid Build Coastguard Worker System.out.println(msg + " : " + actual + " != " + expected); 38*795d594fSAndroid Build Coastguard Worker System.exit(1); 39*795d594fSAndroid Build Coastguard Worker } 40*795d594fSAndroid Build Coastguard Worker } 41*795d594fSAndroid Build Coastguard Worker check(double actual, double expected, String msg)42*795d594fSAndroid Build Coastguard Worker private static void check(double actual, double expected, String msg) { 43*795d594fSAndroid Build Coastguard Worker if (actual != expected) { 44*795d594fSAndroid Build Coastguard Worker System.out.println(msg + " : " + actual + " != " + expected); 45*795d594fSAndroid Build Coastguard Worker System.exit(1); 46*795d594fSAndroid Build Coastguard Worker } 47*795d594fSAndroid Build Coastguard Worker } 48*795d594fSAndroid Build Coastguard Worker check(Object actual, Object expected, String msg)49*795d594fSAndroid Build Coastguard Worker private static void check(Object actual, Object expected, String msg) { 50*795d594fSAndroid Build Coastguard Worker if (actual != expected) { 51*795d594fSAndroid Build Coastguard Worker System.out.println(msg + " : " + actual + " != " + expected); 52*795d594fSAndroid Build Coastguard Worker System.exit(1); 53*795d594fSAndroid Build Coastguard Worker } 54*795d594fSAndroid Build Coastguard Worker } 55*795d594fSAndroid Build Coastguard Worker getUnsafe()56*795d594fSAndroid Build Coastguard Worker private static Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException { 57*795d594fSAndroid Build Coastguard Worker Class<?> unsafeClass = Unsafe.class; 58*795d594fSAndroid Build Coastguard Worker Field f = unsafeClass.getDeclaredField("theUnsafe"); 59*795d594fSAndroid Build Coastguard Worker f.setAccessible(true); 60*795d594fSAndroid Build Coastguard Worker return (Unsafe) f.get(null); 61*795d594fSAndroid Build Coastguard Worker } 62*795d594fSAndroid Build Coastguard Worker main(String[] args)63*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { 64*795d594fSAndroid Build Coastguard Worker System.loadLibrary(args[0]); 65*795d594fSAndroid Build Coastguard Worker Unsafe unsafe = getUnsafe(); 66*795d594fSAndroid Build Coastguard Worker 67*795d594fSAndroid Build Coastguard Worker testArrayBaseOffset(unsafe); 68*795d594fSAndroid Build Coastguard Worker testArrayIndexScale(unsafe); 69*795d594fSAndroid Build Coastguard Worker testGetAndPutAndCAS(unsafe); 70*795d594fSAndroid Build Coastguard Worker testGetAndPutVolatile(unsafe); 71*795d594fSAndroid Build Coastguard Worker testCopyMemoryPrimitiveArrays(unsafe); 72*795d594fSAndroid Build Coastguard Worker } 73*795d594fSAndroid Build Coastguard Worker testArrayBaseOffset(Unsafe unsafe)74*795d594fSAndroid Build Coastguard Worker private static void testArrayBaseOffset(Unsafe unsafe) { 75*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayBaseOffset(boolean[].class), vmArrayBaseOffset(boolean[].class), 76*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayBaseOffset(boolean[])"); 77*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayBaseOffset(byte[].class), vmArrayBaseOffset(byte[].class), 78*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayBaseOffset(byte[])"); 79*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayBaseOffset(char[].class), vmArrayBaseOffset(char[].class), 80*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayBaseOffset(char[])"); 81*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayBaseOffset(double[].class), vmArrayBaseOffset(double[].class), 82*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayBaseOffset(double[])"); 83*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayBaseOffset(float[].class), vmArrayBaseOffset(float[].class), 84*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayBaseOffset(float[])"); 85*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayBaseOffset(int[].class), vmArrayBaseOffset(int[].class), 86*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayBaseOffset(int[])"); 87*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayBaseOffset(long[].class), vmArrayBaseOffset(long[].class), 88*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayBaseOffset(long[])"); 89*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayBaseOffset(Object[].class), vmArrayBaseOffset(Object[].class), 90*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayBaseOffset(Object[])"); 91*795d594fSAndroid Build Coastguard Worker } 92*795d594fSAndroid Build Coastguard Worker testArrayIndexScale(Unsafe unsafe)93*795d594fSAndroid Build Coastguard Worker private static void testArrayIndexScale(Unsafe unsafe) { 94*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayIndexScale(boolean[].class), vmArrayIndexScale(boolean[].class), 95*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayIndexScale(boolean[])"); 96*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayIndexScale(byte[].class), vmArrayIndexScale(byte[].class), 97*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayIndexScale(byte[])"); 98*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayIndexScale(char[].class), vmArrayIndexScale(char[].class), 99*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayIndexScale(char[])"); 100*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayIndexScale(double[].class), vmArrayIndexScale(double[].class), 101*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayIndexScale(double[])"); 102*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayIndexScale(float[].class), vmArrayIndexScale(float[].class), 103*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayIndexScale(float[])"); 104*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayIndexScale(int[].class), vmArrayIndexScale(int[].class), 105*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayIndexScale(int[])"); 106*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayIndexScale(long[].class), vmArrayIndexScale(long[].class), 107*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayIndexScale(long[])"); 108*795d594fSAndroid Build Coastguard Worker check(unsafe.arrayIndexScale(Object[].class), vmArrayIndexScale(Object[].class), 109*795d594fSAndroid Build Coastguard Worker "Unsafe.arrayIndexScale(Object[])"); 110*795d594fSAndroid Build Coastguard Worker } 111*795d594fSAndroid Build Coastguard Worker testGetAndPutAndCAS(Unsafe unsafe)112*795d594fSAndroid Build Coastguard Worker private static void testGetAndPutAndCAS(Unsafe unsafe) throws NoSuchFieldException { 113*795d594fSAndroid Build Coastguard Worker TestClass t = new TestClass(); 114*795d594fSAndroid Build Coastguard Worker 115*795d594fSAndroid Build Coastguard Worker int intValue = 12345678; 116*795d594fSAndroid Build Coastguard Worker Field intField = TestClass.class.getDeclaredField("intVar"); 117*795d594fSAndroid Build Coastguard Worker long intOffset = unsafe.objectFieldOffset(intField); 118*795d594fSAndroid Build Coastguard Worker check(unsafe.getInt(t, intOffset), 0, "Unsafe.getInt(Object, long) - initial"); 119*795d594fSAndroid Build Coastguard Worker unsafe.putInt(t, intOffset, intValue); 120*795d594fSAndroid Build Coastguard Worker check(t.intVar, intValue, "Unsafe.putInt(Object, long, int)"); 121*795d594fSAndroid Build Coastguard Worker check(unsafe.getInt(t, intOffset), intValue, "Unsafe.getInt(Object, long)"); 122*795d594fSAndroid Build Coastguard Worker 123*795d594fSAndroid Build Coastguard Worker long longValue = 1234567887654321L; 124*795d594fSAndroid Build Coastguard Worker Field longField = TestClass.class.getDeclaredField("longVar"); 125*795d594fSAndroid Build Coastguard Worker long longOffset = unsafe.objectFieldOffset(longField); 126*795d594fSAndroid Build Coastguard Worker check(unsafe.getLong(t, longOffset), 0, "Unsafe.getLong(Object, long) - initial"); 127*795d594fSAndroid Build Coastguard Worker unsafe.putLong(t, longOffset, longValue); 128*795d594fSAndroid Build Coastguard Worker check(t.longVar, longValue, "Unsafe.putLong(Object, long, long)"); 129*795d594fSAndroid Build Coastguard Worker check(unsafe.getLong(t, longOffset), longValue, "Unsafe.getLong(Object, long)"); 130*795d594fSAndroid Build Coastguard Worker 131*795d594fSAndroid Build Coastguard Worker Object objectValue = new Object(); 132*795d594fSAndroid Build Coastguard Worker Field objectField = TestClass.class.getDeclaredField("objectVar"); 133*795d594fSAndroid Build Coastguard Worker long objectOffset = unsafe.objectFieldOffset(objectField); 134*795d594fSAndroid Build Coastguard Worker check(unsafe.getObject(t, objectOffset), null, "Unsafe.getObject(Object, long) - initial"); 135*795d594fSAndroid Build Coastguard Worker unsafe.putObject(t, objectOffset, objectValue); 136*795d594fSAndroid Build Coastguard Worker check(t.objectVar, objectValue, "Unsafe.putObject(Object, long, Object)"); 137*795d594fSAndroid Build Coastguard Worker check(unsafe.getObject(t, objectOffset), objectValue, "Unsafe.getObject(Object, long)"); 138*795d594fSAndroid Build Coastguard Worker 139*795d594fSAndroid Build Coastguard Worker byte byteValue = 123; 140*795d594fSAndroid Build Coastguard Worker Field byteField = TestClass.class.getDeclaredField("byteVar"); 141*795d594fSAndroid Build Coastguard Worker long byteOffset = unsafe.objectFieldOffset(byteField); 142*795d594fSAndroid Build Coastguard Worker check(unsafe.getByte(t, byteOffset), 0, "Unsafe.getByte(Object, long) - initial"); 143*795d594fSAndroid Build Coastguard Worker unsafe.putByte(t, byteOffset, byteValue); 144*795d594fSAndroid Build Coastguard Worker check(t.byteVar, byteValue, "Unsafe.putByte(Object, long, byte)"); 145*795d594fSAndroid Build Coastguard Worker check(unsafe.getByte(t, byteOffset), byteValue, "Unsafe.getByte(Object, long)"); 146*795d594fSAndroid Build Coastguard Worker 147*795d594fSAndroid Build Coastguard Worker if (unsafe.compareAndSwapInt(t, intOffset, 0, 1)) { 148*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpectedly succeeding compareAndSwapInt(t, intOffset, 0, 1)"); 149*795d594fSAndroid Build Coastguard Worker } 150*795d594fSAndroid Build Coastguard Worker if (!unsafe.compareAndSwapInt(t, intOffset, intValue, 0)) { 151*795d594fSAndroid Build Coastguard Worker System.out.println( 152*795d594fSAndroid Build Coastguard Worker "Unexpectedly not succeeding compareAndSwapInt(t, intOffset, intValue, 0)"); 153*795d594fSAndroid Build Coastguard Worker } 154*795d594fSAndroid Build Coastguard Worker if (!unsafe.compareAndSwapInt(t, intOffset, 0, 1)) { 155*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpectedly not succeeding compareAndSwapInt(t, intOffset, 0, 1)"); 156*795d594fSAndroid Build Coastguard Worker } 157*795d594fSAndroid Build Coastguard Worker // Exercise sun.misc.Unsafe.compareAndSwapInt using the same 158*795d594fSAndroid Build Coastguard Worker // integer (1) for the `expectedValue` and `newValue` arguments. 159*795d594fSAndroid Build Coastguard Worker if (!unsafe.compareAndSwapInt(t, intOffset, 1, 1)) { 160*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpectedly not succeeding compareAndSwapInt(t, intOffset, 1, 1)"); 161*795d594fSAndroid Build Coastguard Worker } 162*795d594fSAndroid Build Coastguard Worker 163*795d594fSAndroid Build Coastguard Worker if (unsafe.compareAndSwapLong(t, longOffset, 0, 1)) { 164*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpectedly succeeding compareAndSwapLong(t, longOffset, 0, 1)"); 165*795d594fSAndroid Build Coastguard Worker } 166*795d594fSAndroid Build Coastguard Worker if (!unsafe.compareAndSwapLong(t, longOffset, longValue, 0)) { 167*795d594fSAndroid Build Coastguard Worker System.out.println( 168*795d594fSAndroid Build Coastguard Worker "Unexpectedly not succeeding compareAndSwapLong(t, longOffset, longValue, 0)"); 169*795d594fSAndroid Build Coastguard Worker } 170*795d594fSAndroid Build Coastguard Worker if (!unsafe.compareAndSwapLong(t, longOffset, 0, 1)) { 171*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpectedly not succeeding compareAndSwapLong(t, longOffset, 0, 1)"); 172*795d594fSAndroid Build Coastguard Worker } 173*795d594fSAndroid Build Coastguard Worker // Exercise sun.misc.Unsafe.compareAndSwapLong using the same 174*795d594fSAndroid Build Coastguard Worker // integer (1) for the `expectedValue` and `newValue` arguments. 175*795d594fSAndroid Build Coastguard Worker if (!unsafe.compareAndSwapLong(t, longOffset, 1, 1)) { 176*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpectedly not succeeding compareAndSwapLong(t, longOffset, 1, 1)"); 177*795d594fSAndroid Build Coastguard Worker } 178*795d594fSAndroid Build Coastguard Worker 179*795d594fSAndroid Build Coastguard Worker // We do not use `null` as argument to sun.misc.Unsafe.compareAndSwapObject 180*795d594fSAndroid Build Coastguard Worker // in those tests, as this value is not affected by heap poisoning 181*795d594fSAndroid Build Coastguard Worker // (which uses address negation to poison and unpoison heap object 182*795d594fSAndroid Build Coastguard Worker // references). This way, when heap poisoning is enabled, we can 183*795d594fSAndroid Build Coastguard Worker // better exercise its implementation within that method. 184*795d594fSAndroid Build Coastguard Worker if (unsafe.compareAndSwapObject(t, objectOffset, new Object(), new Object())) { 185*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpectedly succeeding " + 186*795d594fSAndroid Build Coastguard Worker "compareAndSwapObject(t, objectOffset, new Object(), new Object())"); 187*795d594fSAndroid Build Coastguard Worker } 188*795d594fSAndroid Build Coastguard Worker Object objectValue2 = new Object(); 189*795d594fSAndroid Build Coastguard Worker if (!unsafe.compareAndSwapObject(t, objectOffset, objectValue, objectValue2)) { 190*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpectedly not succeeding " + 191*795d594fSAndroid Build Coastguard Worker "compareAndSwapObject(t, objectOffset, objectValue, objectValue2)"); 192*795d594fSAndroid Build Coastguard Worker } 193*795d594fSAndroid Build Coastguard Worker Object objectValue3 = new Object(); 194*795d594fSAndroid Build Coastguard Worker if (!unsafe.compareAndSwapObject(t, objectOffset, objectValue2, objectValue3)) { 195*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpectedly not succeeding " + 196*795d594fSAndroid Build Coastguard Worker "compareAndSwapObject(t, objectOffset, objectValue2, objectValue3)"); 197*795d594fSAndroid Build Coastguard Worker } 198*795d594fSAndroid Build Coastguard Worker // Exercise sun.misc.Unsafe.compareAndSwapObject using the same 199*795d594fSAndroid Build Coastguard Worker // object (`objectValue3`) for the `expectedValue` and `newValue` arguments. 200*795d594fSAndroid Build Coastguard Worker if (!unsafe.compareAndSwapObject(t, objectOffset, objectValue3, objectValue3)) { 201*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpectedly not succeeding " + 202*795d594fSAndroid Build Coastguard Worker "compareAndSwapObject(t, objectOffset, objectValue3, objectValue3)"); 203*795d594fSAndroid Build Coastguard Worker } 204*795d594fSAndroid Build Coastguard Worker // Exercise sun.misc.Unsafe.compareAndSwapObject using the same 205*795d594fSAndroid Build Coastguard Worker // object (`t`) for the `obj` and `newValue` arguments. 206*795d594fSAndroid Build Coastguard Worker if (!unsafe.compareAndSwapObject(t, objectOffset, objectValue3, t)) { 207*795d594fSAndroid Build Coastguard Worker System.out.println( 208*795d594fSAndroid Build Coastguard Worker "Unexpectedly not succeeding compareAndSwapObject(t, objectOffset, objectValue3, t)"); 209*795d594fSAndroid Build Coastguard Worker } 210*795d594fSAndroid Build Coastguard Worker // Exercise sun.misc.Unsafe.compareAndSwapObject using the same 211*795d594fSAndroid Build Coastguard Worker // object (`t`) for the `obj`, `expectedValue` and `newValue` arguments. 212*795d594fSAndroid Build Coastguard Worker if (!unsafe.compareAndSwapObject(t, objectOffset, t, t)) { 213*795d594fSAndroid Build Coastguard Worker System.out.println("Unexpectedly not succeeding compareAndSwapObject(t, objectOffset, t, t)"); 214*795d594fSAndroid Build Coastguard Worker } 215*795d594fSAndroid Build Coastguard Worker // Exercise sun.misc.Unsafe.compareAndSwapObject using the same 216*795d594fSAndroid Build Coastguard Worker // object (`t`) for the `obj` and `expectedValue` arguments. 217*795d594fSAndroid Build Coastguard Worker if (!unsafe.compareAndSwapObject(t, objectOffset, t, new Object())) { 218*795d594fSAndroid Build Coastguard Worker System.out.println( 219*795d594fSAndroid Build Coastguard Worker "Unexpectedly not succeeding compareAndSwapObject(t, objectOffset, t, new Object())"); 220*795d594fSAndroid Build Coastguard Worker } 221*795d594fSAndroid Build Coastguard Worker } 222*795d594fSAndroid Build Coastguard Worker testGetAndPutVolatile(Unsafe unsafe)223*795d594fSAndroid Build Coastguard Worker private static void testGetAndPutVolatile(Unsafe unsafe) throws NoSuchFieldException { 224*795d594fSAndroid Build Coastguard Worker TestVolatileClass tv = new TestVolatileClass(); 225*795d594fSAndroid Build Coastguard Worker 226*795d594fSAndroid Build Coastguard Worker int intValue = 12345678; 227*795d594fSAndroid Build Coastguard Worker Field volatileIntField = TestVolatileClass.class.getDeclaredField("volatileIntVar"); 228*795d594fSAndroid Build Coastguard Worker long volatileIntOffset = unsafe.objectFieldOffset(volatileIntField); 229*795d594fSAndroid Build Coastguard Worker check(unsafe.getIntVolatile(tv, volatileIntOffset), 230*795d594fSAndroid Build Coastguard Worker 0, 231*795d594fSAndroid Build Coastguard Worker "Unsafe.getIntVolatile(Object, long) - initial"); 232*795d594fSAndroid Build Coastguard Worker unsafe.putIntVolatile(tv, volatileIntOffset, intValue); 233*795d594fSAndroid Build Coastguard Worker check(tv.volatileIntVar, intValue, "Unsafe.putIntVolatile(Object, long, int)"); 234*795d594fSAndroid Build Coastguard Worker check(unsafe.getIntVolatile(tv, volatileIntOffset), 235*795d594fSAndroid Build Coastguard Worker intValue, 236*795d594fSAndroid Build Coastguard Worker "Unsafe.getIntVolatile(Object, long)"); 237*795d594fSAndroid Build Coastguard Worker 238*795d594fSAndroid Build Coastguard Worker long longValue = 1234567887654321L; 239*795d594fSAndroid Build Coastguard Worker Field volatileLongField = TestVolatileClass.class.getDeclaredField("volatileLongVar"); 240*795d594fSAndroid Build Coastguard Worker long volatileLongOffset = unsafe.objectFieldOffset(volatileLongField); 241*795d594fSAndroid Build Coastguard Worker check(unsafe.getLongVolatile(tv, volatileLongOffset), 242*795d594fSAndroid Build Coastguard Worker 0, 243*795d594fSAndroid Build Coastguard Worker "Unsafe.getLongVolatile(Object, long) - initial"); 244*795d594fSAndroid Build Coastguard Worker unsafe.putLongVolatile(tv, volatileLongOffset, longValue); 245*795d594fSAndroid Build Coastguard Worker check(tv.volatileLongVar, longValue, "Unsafe.putLongVolatile(Object, long, long)"); 246*795d594fSAndroid Build Coastguard Worker check(unsafe.getLongVolatile(tv, volatileLongOffset), 247*795d594fSAndroid Build Coastguard Worker longValue, 248*795d594fSAndroid Build Coastguard Worker "Unsafe.getLongVolatile(Object, long)"); 249*795d594fSAndroid Build Coastguard Worker 250*795d594fSAndroid Build Coastguard Worker Object objectValue = new Object(); 251*795d594fSAndroid Build Coastguard Worker Field volatileObjectField = TestVolatileClass.class.getDeclaredField("volatileObjectVar"); 252*795d594fSAndroid Build Coastguard Worker long volatileObjectOffset = unsafe.objectFieldOffset(volatileObjectField); 253*795d594fSAndroid Build Coastguard Worker check(unsafe.getObjectVolatile(tv, volatileObjectOffset), 254*795d594fSAndroid Build Coastguard Worker null, 255*795d594fSAndroid Build Coastguard Worker "Unsafe.getObjectVolatile(Object, long) - initial"); 256*795d594fSAndroid Build Coastguard Worker unsafe.putObjectVolatile(tv, volatileObjectOffset, objectValue); 257*795d594fSAndroid Build Coastguard Worker check(tv.volatileObjectVar, objectValue, "Unsafe.putObjectVolatile(Object, long, Object)"); 258*795d594fSAndroid Build Coastguard Worker check(unsafe.getObjectVolatile(tv, volatileObjectOffset), 259*795d594fSAndroid Build Coastguard Worker objectValue, 260*795d594fSAndroid Build Coastguard Worker "Unsafe.getObjectVolatile(Object, long)"); 261*795d594fSAndroid Build Coastguard Worker } 262*795d594fSAndroid Build Coastguard Worker testGetAndPutAbsoluteAddress(Unsafe unsafe)263*795d594fSAndroid Build Coastguard Worker private static void testGetAndPutAbsoluteAddress(Unsafe unsafe) throws NoSuchFieldException { 264*795d594fSAndroid Build Coastguard Worker long address = 0; 265*795d594fSAndroid Build Coastguard Worker try { 266*795d594fSAndroid Build Coastguard Worker address = unsafe.allocateMemory(8); 267*795d594fSAndroid Build Coastguard Worker 268*795d594fSAndroid Build Coastguard Worker unsafe.putByte(address, (byte) 17); 269*795d594fSAndroid Build Coastguard Worker check(unsafe.getByte(address), (byte) 17, "Unsafe.getByte(long)"); 270*795d594fSAndroid Build Coastguard Worker 271*795d594fSAndroid Build Coastguard Worker unsafe.putInt(address, 0xDEADBEEF); 272*795d594fSAndroid Build Coastguard Worker check(unsafe.getInt(address), 0xDEADBEEF, "Unsafe.getInt(long)"); 273*795d594fSAndroid Build Coastguard Worker 274*795d594fSAndroid Build Coastguard Worker unsafe.putLong(address, 0xFEEDFACEDECAFBADL); 275*795d594fSAndroid Build Coastguard Worker check(unsafe.getInt(address), 0xFEEDFACEDECAFBADL, "Unsafe.getLong(long)"); 276*795d594fSAndroid Build Coastguard Worker } finally { 277*795d594fSAndroid Build Coastguard Worker if (address != 0) { 278*795d594fSAndroid Build Coastguard Worker unsafe.freeMemory(address); 279*795d594fSAndroid Build Coastguard Worker } 280*795d594fSAndroid Build Coastguard Worker } 281*795d594fSAndroid Build Coastguard Worker } 282*795d594fSAndroid Build Coastguard Worker 283*795d594fSAndroid Build Coastguard Worker // Regression test for "copyMemory" operations hitting a DCHECK() for float/double arrays. testCopyMemoryPrimitiveArrays(Unsafe unsafe)284*795d594fSAndroid Build Coastguard Worker private static void testCopyMemoryPrimitiveArrays(Unsafe unsafe) { 285*795d594fSAndroid Build Coastguard Worker int size = 4 * 1024; 286*795d594fSAndroid Build Coastguard Worker long memory = unsafeTestMalloc(size); 287*795d594fSAndroid Build Coastguard Worker 288*795d594fSAndroid Build Coastguard Worker int floatSize = 4; 289*795d594fSAndroid Build Coastguard Worker float[] inputFloats = new float[size / floatSize]; 290*795d594fSAndroid Build Coastguard Worker for (int i = 0; i != inputFloats.length; ++i) { 291*795d594fSAndroid Build Coastguard Worker inputFloats[i] = ((float)i) + 0.5f; 292*795d594fSAndroid Build Coastguard Worker } 293*795d594fSAndroid Build Coastguard Worker float[] outputFloats = new float[size / floatSize]; 294*795d594fSAndroid Build Coastguard Worker unsafe.copyMemoryFromPrimitiveArray(inputFloats, 0, memory, size); 295*795d594fSAndroid Build Coastguard Worker unsafe.copyMemoryToPrimitiveArray(memory, outputFloats, 0, size); 296*795d594fSAndroid Build Coastguard Worker for (int i = 0; i != inputFloats.length; ++i) { 297*795d594fSAndroid Build Coastguard Worker check(inputFloats[i], outputFloats[i], "unsafe.copyMemory/float"); 298*795d594fSAndroid Build Coastguard Worker } 299*795d594fSAndroid Build Coastguard Worker 300*795d594fSAndroid Build Coastguard Worker int doubleSize = 8; 301*795d594fSAndroid Build Coastguard Worker double[] inputDoubles = new double[size / doubleSize]; 302*795d594fSAndroid Build Coastguard Worker for (int i = 0; i != inputDoubles.length; ++i) { 303*795d594fSAndroid Build Coastguard Worker inputDoubles[i] = ((double)i) + 0.5; 304*795d594fSAndroid Build Coastguard Worker } 305*795d594fSAndroid Build Coastguard Worker double[] outputDoubles = new double[size / doubleSize]; 306*795d594fSAndroid Build Coastguard Worker unsafe.copyMemoryFromPrimitiveArray(inputDoubles, 0, memory, size); 307*795d594fSAndroid Build Coastguard Worker unsafe.copyMemoryToPrimitiveArray(memory, outputDoubles, 0, size); 308*795d594fSAndroid Build Coastguard Worker for (int i = 0; i != inputDoubles.length; ++i) { 309*795d594fSAndroid Build Coastguard Worker check(inputDoubles[i], outputDoubles[i], "unsafe.copyMemory/double"); 310*795d594fSAndroid Build Coastguard Worker } 311*795d594fSAndroid Build Coastguard Worker 312*795d594fSAndroid Build Coastguard Worker unsafeTestFree(memory); 313*795d594fSAndroid Build Coastguard Worker } 314*795d594fSAndroid Build Coastguard Worker 315*795d594fSAndroid Build Coastguard Worker private static class TestClass { 316*795d594fSAndroid Build Coastguard Worker public int intVar = 0; 317*795d594fSAndroid Build Coastguard Worker public long longVar = 0; 318*795d594fSAndroid Build Coastguard Worker public Object objectVar = null; 319*795d594fSAndroid Build Coastguard Worker public byte byteVar = 0; 320*795d594fSAndroid Build Coastguard Worker } 321*795d594fSAndroid Build Coastguard Worker 322*795d594fSAndroid Build Coastguard Worker private static class TestVolatileClass { 323*795d594fSAndroid Build Coastguard Worker public volatile int volatileIntVar = 0; 324*795d594fSAndroid Build Coastguard Worker public volatile long volatileLongVar = 0; 325*795d594fSAndroid Build Coastguard Worker public volatile Object volatileObjectVar = null; 326*795d594fSAndroid Build Coastguard Worker } 327*795d594fSAndroid Build Coastguard Worker vmArrayBaseOffset(Class<?> clazz)328*795d594fSAndroid Build Coastguard Worker private static native int vmArrayBaseOffset(Class<?> clazz); vmArrayIndexScale(Class<?> clazz)329*795d594fSAndroid Build Coastguard Worker private static native int vmArrayIndexScale(Class<?> clazz); unsafeTestMalloc(long size)330*795d594fSAndroid Build Coastguard Worker private static native long unsafeTestMalloc(long size); unsafeTestFree(long memory)331*795d594fSAndroid Build Coastguard Worker private static native void unsafeTestFree(long memory); 332*795d594fSAndroid Build Coastguard Worker } 333