sun_misc_Unsafe.cc revision d2fe10a3a34af171bf1631219cd2d6ff6b7778b5
1/*
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
17#include "gc/accounting/card_table-inl.h"
18#include "jni_internal.h"
19#include "mirror/array.h"
20#include "mirror/object.h"
21#include "mirror/object-inl.h"
22#include "scoped_fast_native_object_access.h"
23
24namespace art {
25
26static jboolean Unsafe_compareAndSwapInt(JNIEnv* env, jobject, jobject javaObj, jlong offset,
27                                         jint expectedValue, jint newValue) {
28  ScopedFastNativeObjectAccess soa(env);
29  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
30  // JNI must use non transactional mode.
31  bool success = obj->CasField32<false>(MemberOffset(offset), expectedValue, newValue);
32  return success ? JNI_TRUE : JNI_FALSE;
33}
34
35static jboolean Unsafe_compareAndSwapLong(JNIEnv* env, jobject, jobject javaObj, jlong offset,
36                                          jlong expectedValue, jlong newValue) {
37  ScopedFastNativeObjectAccess soa(env);
38  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
39  // JNI must use non transactional mode.
40  bool success = obj->CasField64<false>(MemberOffset(offset), expectedValue, newValue);
41  return success ? JNI_TRUE : JNI_FALSE;
42}
43
44static jboolean Unsafe_compareAndSwapObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
45                                            jobject javaExpectedValue, jobject javaNewValue) {
46  ScopedFastNativeObjectAccess soa(env);
47  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
48  mirror::Object* expectedValue = soa.Decode<mirror::Object*>(javaExpectedValue);
49  mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
50  // JNI must use non transactional mode.
51  bool success = obj->CasFieldObject<false>(MemberOffset(offset), expectedValue, newValue);
52  return success ? JNI_TRUE : JNI_FALSE;
53}
54
55static jint Unsafe_getInt(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
56  ScopedFastNativeObjectAccess soa(env);
57  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
58  return obj->GetField32(MemberOffset(offset), false);
59}
60
61static jint Unsafe_getIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
62  ScopedFastNativeObjectAccess soa(env);
63  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
64  return obj->GetField32(MemberOffset(offset), true);
65}
66
67static void Unsafe_putInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint newValue) {
68  ScopedFastNativeObjectAccess soa(env);
69  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
70  // JNI must use non transactional mode.
71  obj->SetField32<false>(MemberOffset(offset), newValue, false);
72}
73
74static void Unsafe_putIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
75                                  jint newValue) {
76  ScopedFastNativeObjectAccess soa(env);
77  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
78  // JNI must use non transactional mode.
79  obj->SetField32<false>(MemberOffset(offset), newValue, true);
80}
81
82static void Unsafe_putOrderedInt(JNIEnv* env, jobject, jobject javaObj, jlong offset,
83                                 jint newValue) {
84  ScopedFastNativeObjectAccess soa(env);
85  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
86  QuasiAtomic::MembarStoreStore();
87  // JNI must use non transactional mode.
88  obj->SetField32<false>(MemberOffset(offset), newValue, false);
89}
90
91static jlong Unsafe_getLong(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
92  ScopedFastNativeObjectAccess soa(env);
93  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
94  return obj->GetField64(MemberOffset(offset), false);
95}
96
97static jlong Unsafe_getLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
98  ScopedFastNativeObjectAccess soa(env);
99  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
100  return obj->GetField64(MemberOffset(offset), true);
101}
102
103static void Unsafe_putLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong newValue) {
104  ScopedFastNativeObjectAccess soa(env);
105  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
106  // JNI must use non transactional mode.
107  obj->SetField64<false>(MemberOffset(offset), newValue, false);
108}
109
110static void Unsafe_putLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
111                                   jlong newValue) {
112  ScopedFastNativeObjectAccess soa(env);
113  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
114  // JNI must use non transactional mode.
115  obj->SetField64<false>(MemberOffset(offset), newValue, true);
116}
117
118static void Unsafe_putOrderedLong(JNIEnv* env, jobject, jobject javaObj, jlong offset,
119                                  jlong newValue) {
120  ScopedFastNativeObjectAccess soa(env);
121  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
122  QuasiAtomic::MembarStoreStore();
123  // JNI must use non transactional mode.
124  obj->SetField64<false>(MemberOffset(offset), newValue, false);
125}
126
127static jobject Unsafe_getObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
128  ScopedFastNativeObjectAccess soa(env);
129  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
130  mirror::Object* value = obj->GetFieldObject<mirror::Object>(MemberOffset(offset), true);
131  return soa.AddLocalReference<jobject>(value);
132}
133
134static jobject Unsafe_getObject(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
135  ScopedFastNativeObjectAccess soa(env);
136  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
137  mirror::Object* value = obj->GetFieldObject<mirror::Object>(MemberOffset(offset), false);
138  return soa.AddLocalReference<jobject>(value);
139}
140
141static void Unsafe_putObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
142                             jobject javaNewValue) {
143  ScopedFastNativeObjectAccess soa(env);
144  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
145  mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
146  // JNI must use non transactional mode.
147  obj->SetFieldObject<false>(MemberOffset(offset), newValue, false);
148}
149
150static void Unsafe_putObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
151                                     jobject javaNewValue) {
152  ScopedFastNativeObjectAccess soa(env);
153  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
154  mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
155  // JNI must use non transactional mode.
156  obj->SetFieldObject<false>(MemberOffset(offset), newValue, true);
157}
158
159static void Unsafe_putOrderedObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
160                                    jobject javaNewValue) {
161  ScopedFastNativeObjectAccess soa(env);
162  mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
163  mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
164  QuasiAtomic::MembarStoreStore();
165  // JNI must use non transactional mode.
166  obj->SetFieldObject<false>(MemberOffset(offset), newValue, false);
167}
168
169static jint Unsafe_getArrayBaseOffsetForComponentType(JNIEnv* env, jclass, jobject component_class) {
170  ScopedFastNativeObjectAccess soa(env);
171  mirror::Class* component = soa.Decode<mirror::Class*>(component_class);
172  Primitive::Type primitive_type = component->GetPrimitiveType();
173  return mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value();
174}
175
176static jint Unsafe_getArrayIndexScaleForComponentType(JNIEnv* env, jclass, jobject component_class) {
177  ScopedFastNativeObjectAccess soa(env);
178  mirror::Class* component = soa.Decode<mirror::Class*>(component_class);
179  Primitive::Type primitive_type = component->GetPrimitiveType();
180  return Primitive::ComponentSize(primitive_type);
181}
182
183static JNINativeMethod gMethods[] = {
184  NATIVE_METHOD(Unsafe, compareAndSwapInt, "!(Ljava/lang/Object;JII)Z"),
185  NATIVE_METHOD(Unsafe, compareAndSwapLong, "!(Ljava/lang/Object;JJJ)Z"),
186  NATIVE_METHOD(Unsafe, compareAndSwapObject, "!(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z"),
187  NATIVE_METHOD(Unsafe, getIntVolatile, "!(Ljava/lang/Object;J)I"),
188  NATIVE_METHOD(Unsafe, putIntVolatile, "!(Ljava/lang/Object;JI)V"),
189  NATIVE_METHOD(Unsafe, getLongVolatile, "!(Ljava/lang/Object;J)J"),
190  NATIVE_METHOD(Unsafe, putLongVolatile, "!(Ljava/lang/Object;JJ)V"),
191  NATIVE_METHOD(Unsafe, getObjectVolatile, "!(Ljava/lang/Object;J)Ljava/lang/Object;"),
192  NATIVE_METHOD(Unsafe, putObjectVolatile, "!(Ljava/lang/Object;JLjava/lang/Object;)V"),
193  NATIVE_METHOD(Unsafe, getInt, "!(Ljava/lang/Object;J)I"),
194  NATIVE_METHOD(Unsafe, putInt, "!(Ljava/lang/Object;JI)V"),
195  NATIVE_METHOD(Unsafe, putOrderedInt, "!(Ljava/lang/Object;JI)V"),
196  NATIVE_METHOD(Unsafe, getLong, "!(Ljava/lang/Object;J)J"),
197  NATIVE_METHOD(Unsafe, putLong, "!(Ljava/lang/Object;JJ)V"),
198  NATIVE_METHOD(Unsafe, putOrderedLong, "!(Ljava/lang/Object;JJ)V"),
199  NATIVE_METHOD(Unsafe, getObject, "!(Ljava/lang/Object;J)Ljava/lang/Object;"),
200  NATIVE_METHOD(Unsafe, putObject, "!(Ljava/lang/Object;JLjava/lang/Object;)V"),
201  NATIVE_METHOD(Unsafe, putOrderedObject, "!(Ljava/lang/Object;JLjava/lang/Object;)V"),
202  NATIVE_METHOD(Unsafe, getArrayBaseOffsetForComponentType, "!(Ljava/lang/Class;)I"),
203  NATIVE_METHOD(Unsafe, getArrayIndexScaleForComponentType, "!(Ljava/lang/Class;)I"),
204};
205
206void register_sun_misc_Unsafe(JNIEnv* env) {
207  REGISTER_NATIVE_METHODS("sun/misc/Unsafe");
208}
209
210}  // namespace art
211