blob: 65dece04e657fbf5b579af6fba6fcbc353e88ff6 [file] [log] [blame]
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -07001/*
2 * Copyright (C) 2008 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
Ian Rogers1d54e732013-05-02 21:10:01 -070017#include "gc/accounting/card_table-inl.h"
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070018#include "jni_internal.h"
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -080019#include "mirror/array.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080020#include "mirror/object.h"
21#include "mirror/object-inl.h"
Ian Rogers1eb512d2013-10-18 15:42:20 -070022#include "scoped_fast_native_object_access.h"
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070023
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070024namespace art {
25
Ian Rogersef7d42f2014-01-06 12:55:46 -080026static jboolean Unsafe_compareAndSwapInt(JNIEnv* env, jobject, jobject javaObj, jlong offset,
27 jint expectedValue, jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070028 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080029 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010030 // JNI must use non transactional mode.
Hans Boehmd8434432014-07-11 09:56:07 -070031 bool success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
32 expectedValue, newValue);
Ian Rogers9adbff52013-01-23 18:19:03 -080033 return success ? JNI_TRUE : JNI_FALSE;
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070034}
35
Ian Rogersef7d42f2014-01-06 12:55:46 -080036static jboolean Unsafe_compareAndSwapLong(JNIEnv* env, jobject, jobject javaObj, jlong offset,
37 jlong expectedValue, jlong newValue) {
38 ScopedFastNativeObjectAccess soa(env);
39 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010040 // JNI must use non transactional mode.
Hans Boehmd8434432014-07-11 09:56:07 -070041 bool success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
42 expectedValue, newValue);
Ian Rogersef7d42f2014-01-06 12:55:46 -080043 return success ? JNI_TRUE : JNI_FALSE;
44}
45
46static jboolean Unsafe_compareAndSwapObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
47 jobject javaExpectedValue, jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070048 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080049 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
50 mirror::Object* expectedValue = soa.Decode<mirror::Object*>(javaExpectedValue);
51 mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010052 // JNI must use non transactional mode.
Hans Boehmd8434432014-07-11 09:56:07 -070053 bool success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset),
54 expectedValue, newValue);
Ian Rogersef7d42f2014-01-06 12:55:46 -080055 return success ? JNI_TRUE : JNI_FALSE;
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070056}
57
Elliott Hughes0512f022012-03-15 22:10:52 -070058static jint Unsafe_getInt(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070059 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080060 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070061 return obj->GetField32(MemberOffset(offset));
Ian Rogers5d76c432011-10-31 21:42:49 -070062}
63
Elliott Hughes0512f022012-03-15 22:10:52 -070064static jint Unsafe_getIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070065 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080066 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070067 return obj->GetField32Volatile(MemberOffset(offset));
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070068}
69
Elliott Hughes0512f022012-03-15 22:10:52 -070070static void Unsafe_putInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070071 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080072 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010073 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070074 obj->SetField32<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -070075}
76
Ian Rogersef7d42f2014-01-06 12:55:46 -080077static void Unsafe_putIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
78 jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070079 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080080 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010081 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070082 obj->SetField32Volatile<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070083}
84
Ian Rogersef7d42f2014-01-06 12:55:46 -080085static void Unsafe_putOrderedInt(JNIEnv* env, jobject, jobject javaObj, jlong offset,
86 jint newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070087 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080088 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Hans Boehm30359612014-05-21 17:46:23 -070089 QuasiAtomic::ThreadFenceRelease();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010090 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070091 obj->SetField32<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070092}
93
Elliott Hughes0512f022012-03-15 22:10:52 -070094static jlong Unsafe_getLong(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -070095 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080096 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070097 return obj->GetField64(MemberOffset(offset));
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -070098}
99
Elliott Hughes0512f022012-03-15 22:10:52 -0700100static jlong Unsafe_getLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700101 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800102 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700103 return obj->GetField64Volatile(MemberOffset(offset));
Ian Rogers5d76c432011-10-31 21:42:49 -0700104}
105
Elliott Hughes0512f022012-03-15 22:10:52 -0700106static void Unsafe_putLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700107 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800108 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100109 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700110 obj->SetField64<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -0700111}
112
Ian Rogersef7d42f2014-01-06 12:55:46 -0800113static void Unsafe_putLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
114 jlong newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700115 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800116 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100117 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700118 obj->SetField64Volatile<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700119}
120
Ian Rogersef7d42f2014-01-06 12:55:46 -0800121static void Unsafe_putOrderedLong(JNIEnv* env, jobject, jobject javaObj, jlong offset,
122 jlong newValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700123 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800124 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Hans Boehm30359612014-05-21 17:46:23 -0700125 QuasiAtomic::ThreadFenceRelease();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100126 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700127 obj->SetField64<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -0700128}
129
Elliott Hughes0512f022012-03-15 22:10:52 -0700130static jobject Unsafe_getObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700131 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800132 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700133 mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700134 return soa.AddLocalReference<jobject>(value);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700135}
136
Elliott Hughes0512f022012-03-15 22:10:52 -0700137static jobject Unsafe_getObject(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700138 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800139 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700140 mirror::Object* value = obj->GetFieldObject<mirror::Object>(MemberOffset(offset));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700141 return soa.AddLocalReference<jobject>(value);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700142}
143
Ian Rogersef7d42f2014-01-06 12:55:46 -0800144static void Unsafe_putObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
145 jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700146 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800147 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
148 mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100149 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700150 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700151}
152
Ian Rogersef7d42f2014-01-06 12:55:46 -0800153static void Unsafe_putObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
154 jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700155 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800156 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
157 mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100158 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700159 obj->SetFieldObjectVolatile<false>(MemberOffset(offset), newValue);
Ian Rogers5d76c432011-10-31 21:42:49 -0700160}
161
Ian Rogersef7d42f2014-01-06 12:55:46 -0800162static void Unsafe_putOrderedObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
163 jobject javaNewValue) {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700164 ScopedFastNativeObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800165 mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
166 mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
Hans Boehm30359612014-05-21 17:46:23 -0700167 QuasiAtomic::ThreadFenceRelease();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100168 // JNI must use non transactional mode.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700169 obj->SetFieldObject<false>(MemberOffset(offset), newValue);
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700170}
171
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -0800172static jint Unsafe_getArrayBaseOffsetForComponentType(JNIEnv* env, jclass, jobject component_class) {
173 ScopedFastNativeObjectAccess soa(env);
174 mirror::Class* component = soa.Decode<mirror::Class*>(component_class);
175 Primitive::Type primitive_type = component->GetPrimitiveType();
176 return mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value();
177}
178
179static jint Unsafe_getArrayIndexScaleForComponentType(JNIEnv* env, jclass, jobject component_class) {
180 ScopedFastNativeObjectAccess soa(env);
181 mirror::Class* component = soa.Decode<mirror::Class*>(component_class);
182 Primitive::Type primitive_type = component->GetPrimitiveType();
183 return Primitive::ComponentSize(primitive_type);
184}
185
Elliott Hughes0512f022012-03-15 22:10:52 -0700186static JNINativeMethod gMethods[] = {
Ian Rogers1eb512d2013-10-18 15:42:20 -0700187 NATIVE_METHOD(Unsafe, compareAndSwapInt, "!(Ljava/lang/Object;JII)Z"),
188 NATIVE_METHOD(Unsafe, compareAndSwapLong, "!(Ljava/lang/Object;JJJ)Z"),
189 NATIVE_METHOD(Unsafe, compareAndSwapObject, "!(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z"),
190 NATIVE_METHOD(Unsafe, getIntVolatile, "!(Ljava/lang/Object;J)I"),
191 NATIVE_METHOD(Unsafe, putIntVolatile, "!(Ljava/lang/Object;JI)V"),
192 NATIVE_METHOD(Unsafe, getLongVolatile, "!(Ljava/lang/Object;J)J"),
193 NATIVE_METHOD(Unsafe, putLongVolatile, "!(Ljava/lang/Object;JJ)V"),
194 NATIVE_METHOD(Unsafe, getObjectVolatile, "!(Ljava/lang/Object;J)Ljava/lang/Object;"),
195 NATIVE_METHOD(Unsafe, putObjectVolatile, "!(Ljava/lang/Object;JLjava/lang/Object;)V"),
196 NATIVE_METHOD(Unsafe, getInt, "!(Ljava/lang/Object;J)I"),
197 NATIVE_METHOD(Unsafe, putInt, "!(Ljava/lang/Object;JI)V"),
198 NATIVE_METHOD(Unsafe, putOrderedInt, "!(Ljava/lang/Object;JI)V"),
199 NATIVE_METHOD(Unsafe, getLong, "!(Ljava/lang/Object;J)J"),
200 NATIVE_METHOD(Unsafe, putLong, "!(Ljava/lang/Object;JJ)V"),
201 NATIVE_METHOD(Unsafe, putOrderedLong, "!(Ljava/lang/Object;JJ)V"),
202 NATIVE_METHOD(Unsafe, getObject, "!(Ljava/lang/Object;J)Ljava/lang/Object;"),
203 NATIVE_METHOD(Unsafe, putObject, "!(Ljava/lang/Object;JLjava/lang/Object;)V"),
204 NATIVE_METHOD(Unsafe, putOrderedObject, "!(Ljava/lang/Object;JLjava/lang/Object;)V"),
Hiroshi Yamauchi4d2efce2014-02-10 16:19:09 -0800205 NATIVE_METHOD(Unsafe, getArrayBaseOffsetForComponentType, "!(Ljava/lang/Class;)I"),
206 NATIVE_METHOD(Unsafe, getArrayIndexScaleForComponentType, "!(Ljava/lang/Class;)I"),
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700207};
208
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700209void register_sun_misc_Unsafe(JNIEnv* env) {
Elliott Hugheseac76672012-05-24 21:56:51 -0700210 REGISTER_NATIVE_METHODS("sun/misc/Unsafe");
Elliott Hughes5ee7a8b2011-09-13 16:40:07 -0700211}
212
213} // namespace art