2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include "native/InternalNativePriv.h"
25 * private static native long objectFieldOffset0(Field field);
27 static void Dalvik_sun_misc_Unsafe_objectFieldOffset0(const u4* args,
30 Object* fieldObject = (Object*) args[0];
31 InstField* field = (InstField*) dvmGetFieldFromReflectObj(fieldObject);
32 s8 result = ((s8) field->byteOffset);
38 * private static native int arrayBaseOffset0(Class clazz);
40 static void Dalvik_sun_misc_Unsafe_arrayBaseOffset0(const u4* args,
43 // The base offset is not type-dependent in this vm.
44 UNUSED_PARAMETER(args);
45 RETURN_INT(offsetof(ArrayObject, contents));
49 * private static native int arrayIndexScale0(Class clazz);
51 static void Dalvik_sun_misc_Unsafe_arrayIndexScale0(const u4* args,
54 ClassObject* clazz = (ClassObject*) args[0];
57 if ((clazz == gDvm.classArrayBoolean) ||
58 (clazz == gDvm.classArrayByte)) {
60 } else if ((clazz == gDvm.classArrayChar) ||
61 (clazz == gDvm.classArrayShort)) {
63 } else if ((clazz == gDvm.classArrayLong) ||
64 (clazz == gDvm.classArrayDouble)) {
74 * public native boolean compareAndSwapInt(Object obj, long offset,
75 * int expectedValue, int newValue);
77 static void Dalvik_sun_misc_Unsafe_compareAndSwapInt(const u4* args,
80 // We ignore the this pointer in args[0].
81 Object* obj = (Object*) args[1];
82 s8 offset = GET_ARG_LONG(args, 2);
83 s4 expectedValue = args[4];
84 s4 newValue = args[5];
85 volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);
87 // Note: android_atomic_release_cas() returns 0 on success, not failure.
88 int result = android_atomic_release_cas(expectedValue, newValue, address);
90 RETURN_BOOLEAN(result == 0);
94 * public native boolean compareAndSwapLong(Object obj, long offset,
95 * long expectedValue, long newValue);
97 static void Dalvik_sun_misc_Unsafe_compareAndSwapLong(const u4* args,
100 // We ignore the this pointer in args[0].
101 Object* obj = (Object*) args[1];
102 s8 offset = GET_ARG_LONG(args, 2);
103 s8 expectedValue = GET_ARG_LONG(args, 4);
104 s8 newValue = GET_ARG_LONG(args, 6);
105 volatile int64_t* address = (volatile int64_t*) (((u1*) obj) + offset);
107 // Note: android_atomic_cmpxchg() returns 0 on success, not failure.
109 dvmQuasiAtomicCas64(expectedValue, newValue, address);
111 RETURN_BOOLEAN(result == 0);
115 * public native boolean compareAndSwapObject(Object obj, long offset,
116 * Object expectedValue, Object newValue);
118 static void Dalvik_sun_misc_Unsafe_compareAndSwapObject(const u4* args,
121 // We ignore the this pointer in args[0].
122 Object* obj = (Object*) args[1];
123 s8 offset = GET_ARG_LONG(args, 2);
124 Object* expectedValue = (Object*) args[4];
125 Object* newValue = (Object*) args[5];
126 int32_t* address = (int32_t*) (((u1*) obj) + offset);
128 // Note: android_atomic_cmpxchg() returns 0 on success, not failure.
129 int result = android_atomic_release_cas((int32_t) expectedValue,
130 (int32_t) newValue, address);
131 dvmWriteBarrierField(obj, address);
132 RETURN_BOOLEAN(result == 0);
136 * public native int getIntVolatile(Object obj, long offset);
138 static void Dalvik_sun_misc_Unsafe_getIntVolatile(const u4* args,
141 // We ignore the this pointer in args[0].
142 Object* obj = (Object*) args[1];
143 s8 offset = GET_ARG_LONG(args, 2);
144 volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);
146 int32_t value = android_atomic_acquire_load(address);
151 * public native void putIntVolatile(Object obj, long offset, int newValue);
153 static void Dalvik_sun_misc_Unsafe_putIntVolatile(const u4* args,
156 // We ignore the this pointer in args[0].
157 Object* obj = (Object*) args[1];
158 s8 offset = GET_ARG_LONG(args, 2);
159 s4 value = (s4) args[4];
160 volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);
162 android_atomic_release_store(value, address);
167 * public native long getLongVolatile(Object obj, long offset);
169 static void Dalvik_sun_misc_Unsafe_getLongVolatile(const u4* args,
172 // We ignore the this pointer in args[0].
173 Object* obj = (Object*) args[1];
174 s8 offset = GET_ARG_LONG(args, 2);
175 volatile int64_t* address = (volatile int64_t*) (((u1*) obj) + offset);
177 RETURN_LONG(dvmQuasiAtomicRead64(address));
181 * public native void putLongVolatile(Object obj, long offset, long newValue);
183 static void Dalvik_sun_misc_Unsafe_putLongVolatile(const u4* args,
186 // We ignore the this pointer in args[0].
187 Object* obj = (Object*) args[1];
188 s8 offset = GET_ARG_LONG(args, 2);
189 s8 value = GET_ARG_LONG(args, 4);
190 volatile int64_t* address = (volatile int64_t*) (((u1*) obj) + offset);
192 dvmQuasiAtomicSwap64(value, address);
197 * public native Object getObjectVolatile(Object obj, long offset);
199 static void Dalvik_sun_misc_Unsafe_getObjectVolatile(const u4* args,
202 // We ignore the this pointer in args[0].
203 Object* obj = (Object*) args[1];
204 s8 offset = GET_ARG_LONG(args, 2);
205 volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);
207 RETURN_PTR((Object*) android_atomic_acquire_load(address));
211 * public native void putObjectVolatile(Object obj, long offset,
214 static void Dalvik_sun_misc_Unsafe_putObjectVolatile(const u4* args,
217 // We ignore the this pointer in args[0].
218 Object* obj = (Object*) args[1];
219 s8 offset = GET_ARG_LONG(args, 2);
220 Object* value = (Object*) args[4];
221 volatile int32_t* address = (volatile int32_t*) (((u1*) obj) + offset);
223 android_atomic_release_store((int32_t)value, address);
224 dvmWriteBarrierField(obj, (void *)address);
229 * public native int getInt(Object obj, long offset);
231 static void Dalvik_sun_misc_Unsafe_getInt(const u4* args, JValue* pResult)
233 // We ignore the this pointer in args[0].
234 Object* obj = (Object*) args[1];
235 s8 offset = GET_ARG_LONG(args, 2);
236 s4* address = (s4*) (((u1*) obj) + offset);
238 RETURN_INT(*address);
242 * public native void putInt(Object obj, long offset, int newValue);
244 static void Dalvik_sun_misc_Unsafe_putInt(const u4* args, JValue* pResult)
246 // We ignore the this pointer in args[0].
247 Object* obj = (Object*) args[1];
248 s8 offset = GET_ARG_LONG(args, 2);
249 s4 value = (s4) args[4];
250 s4* address = (s4*) (((u1*) obj) + offset);
257 * public native void putOrderedInt(Object obj, long offset, int newValue);
259 static void Dalvik_sun_misc_Unsafe_putOrderedInt(const u4* args,
262 // We ignore the this pointer in args[0].
263 Object* obj = (Object*) args[1];
264 s8 offset = GET_ARG_LONG(args, 2);
265 s4 value = (s4) args[4];
266 s4* address = (s4*) (((u1*) obj) + offset);
268 ANDROID_MEMBAR_STORE();
274 * public native long getLong(Object obj, long offset);
276 static void Dalvik_sun_misc_Unsafe_getLong(const u4* args, JValue* pResult)
278 // We ignore the this pointer in args[0].
279 Object* obj = (Object*) args[1];
280 s8 offset = GET_ARG_LONG(args, 2);
281 s8* address = (s8*) (((u1*) obj) + offset);
283 RETURN_LONG(*address);
287 * public native void putLong(Object obj, long offset, long newValue);
289 static void Dalvik_sun_misc_Unsafe_putLong(const u4* args, JValue* pResult)
291 // We ignore the this pointer in args[0].
292 Object* obj = (Object*) args[1];
293 s8 offset = GET_ARG_LONG(args, 2);
294 s8 value = GET_ARG_LONG(args, 4);
295 s8* address = (s8*) (((u1*) obj) + offset);
302 * public native void putOrderedLong(Object obj, long offset, long newValue);
304 static void Dalvik_sun_misc_Unsafe_putOrderedLong(const u4* args,
307 // We ignore the this pointer in args[0].
308 Object* obj = (Object*) args[1];
309 s8 offset = GET_ARG_LONG(args, 2);
310 s8 value = GET_ARG_LONG(args, 4);
311 s8* address = (s8*) (((u1*) obj) + offset);
313 ANDROID_MEMBAR_STORE();
319 * public native Object getObject(Object obj, long offset);
321 static void Dalvik_sun_misc_Unsafe_getObject(const u4* args, JValue* pResult)
323 // We ignore the this pointer in args[0].
324 Object* obj = (Object*) args[1];
325 s8 offset = GET_ARG_LONG(args, 2);
326 Object** address = (Object**) (((u1*) obj) + offset);
328 RETURN_PTR(*address);
332 * public native void putObject(Object obj, long offset, Object newValue);
334 static void Dalvik_sun_misc_Unsafe_putObject(const u4* args, JValue* pResult)
336 // We ignore the this pointer in args[0].
337 Object* obj = (Object*) args[1];
338 s8 offset = GET_ARG_LONG(args, 2);
339 Object* value = (Object*) args[4];
340 Object** address = (Object**) (((u1*) obj) + offset);
343 dvmWriteBarrierField(obj, address);
348 * public native void putOrderedObject(Object obj, long offset,
351 static void Dalvik_sun_misc_Unsafe_putOrderedObject(const u4* args,
354 // We ignore the this pointer in args[0].
355 Object* obj = (Object*) args[1];
356 s8 offset = GET_ARG_LONG(args, 2);
357 Object* value = (Object*) args[4];
358 Object** address = (Object**) (((u1*) obj) + offset);
360 ANDROID_MEMBAR_STORE();
362 dvmWriteBarrierField(obj, address);
366 const DalvikNativeMethod dvm_sun_misc_Unsafe[] = {
367 { "objectFieldOffset0", "(Ljava/lang/reflect/Field;)J",
368 Dalvik_sun_misc_Unsafe_objectFieldOffset0 },
369 { "arrayBaseOffset0", "(Ljava/lang/Class;)I",
370 Dalvik_sun_misc_Unsafe_arrayBaseOffset0 },
371 { "arrayIndexScale0", "(Ljava/lang/Class;)I",
372 Dalvik_sun_misc_Unsafe_arrayIndexScale0 },
373 { "compareAndSwapInt", "(Ljava/lang/Object;JII)Z",
374 Dalvik_sun_misc_Unsafe_compareAndSwapInt },
375 { "compareAndSwapLong", "(Ljava/lang/Object;JJJ)Z",
376 Dalvik_sun_misc_Unsafe_compareAndSwapLong },
377 { "compareAndSwapObject",
378 "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
379 Dalvik_sun_misc_Unsafe_compareAndSwapObject },
380 { "getIntVolatile", "(Ljava/lang/Object;J)I",
381 Dalvik_sun_misc_Unsafe_getIntVolatile },
382 { "putIntVolatile", "(Ljava/lang/Object;JI)V",
383 Dalvik_sun_misc_Unsafe_putIntVolatile },
384 { "getLongVolatile", "(Ljava/lang/Object;J)J",
385 Dalvik_sun_misc_Unsafe_getLongVolatile },
386 { "putLongVolatile", "(Ljava/lang/Object;JJ)V",
387 Dalvik_sun_misc_Unsafe_putLongVolatile },
388 { "getObjectVolatile", "(Ljava/lang/Object;J)Ljava/lang/Object;",
389 Dalvik_sun_misc_Unsafe_getObjectVolatile },
390 { "putObjectVolatile", "(Ljava/lang/Object;JLjava/lang/Object;)V",
391 Dalvik_sun_misc_Unsafe_putObjectVolatile },
392 { "getInt", "(Ljava/lang/Object;J)I",
393 Dalvik_sun_misc_Unsafe_getInt },
394 { "putInt", "(Ljava/lang/Object;JI)V",
395 Dalvik_sun_misc_Unsafe_putInt },
396 { "putOrderedInt", "(Ljava/lang/Object;JI)V",
397 Dalvik_sun_misc_Unsafe_putOrderedInt },
398 { "getLong", "(Ljava/lang/Object;J)J",
399 Dalvik_sun_misc_Unsafe_getLong },
400 { "putLong", "(Ljava/lang/Object;JJ)V",
401 Dalvik_sun_misc_Unsafe_putLong },
402 { "putOrderedLong", "(Ljava/lang/Object;JJ)V",
403 Dalvik_sun_misc_Unsafe_putOrderedLong },
404 { "getObject", "(Ljava/lang/Object;J)Ljava/lang/Object;",
405 Dalvik_sun_misc_Unsafe_getObject },
406 { "putObject", "(Ljava/lang/Object;JLjava/lang/Object;)V",
407 Dalvik_sun_misc_Unsafe_putObject },
408 { "putOrderedObject", "(Ljava/lang/Object;JLjava/lang/Object;)V",
409 Dalvik_sun_misc_Unsafe_putOrderedObject },
410 { NULL, NULL, NULL },