Home | History | Annotate | Download | only in native
      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 
     24 namespace art {
     25 
     26 static 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->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset),
     32                                                                     expectedValue, newValue);
     33   return success ? JNI_TRUE : JNI_FALSE;
     34 }
     35 
     36 static 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);
     40   // JNI must use non transactional mode.
     41   bool success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset),
     42                                                                     expectedValue, newValue);
     43   return success ? JNI_TRUE : JNI_FALSE;
     44 }
     45 
     46 static jboolean Unsafe_compareAndSwapObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
     47                                             jobject javaExpectedValue, jobject javaNewValue) {
     48   ScopedFastNativeObjectAccess soa(env);
     49   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);
     52   // JNI must use non transactional mode.
     53   bool success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset),
     54                                                                         expectedValue, newValue);
     55   return success ? JNI_TRUE : JNI_FALSE;
     56 }
     57 
     58 static jint Unsafe_getInt(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
     59   ScopedFastNativeObjectAccess soa(env);
     60   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
     61   return obj->GetField32(MemberOffset(offset));
     62 }
     63 
     64 static jint Unsafe_getIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
     65   ScopedFastNativeObjectAccess soa(env);
     66   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
     67   return obj->GetField32Volatile(MemberOffset(offset));
     68 }
     69 
     70 static void Unsafe_putInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint newValue) {
     71   ScopedFastNativeObjectAccess soa(env);
     72   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
     73   // JNI must use non transactional mode.
     74   obj->SetField32<false>(MemberOffset(offset), newValue);
     75 }
     76 
     77 static void Unsafe_putIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
     78                                   jint newValue) {
     79   ScopedFastNativeObjectAccess soa(env);
     80   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
     81   // JNI must use non transactional mode.
     82   obj->SetField32Volatile<false>(MemberOffset(offset), newValue);
     83 }
     84 
     85 static void Unsafe_putOrderedInt(JNIEnv* env, jobject, jobject javaObj, jlong offset,
     86                                  jint newValue) {
     87   ScopedFastNativeObjectAccess soa(env);
     88   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
     89   QuasiAtomic::ThreadFenceRelease();
     90   // JNI must use non transactional mode.
     91   obj->SetField32<false>(MemberOffset(offset), newValue);
     92 }
     93 
     94 static jlong Unsafe_getLong(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
     95   ScopedFastNativeObjectAccess soa(env);
     96   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
     97   return obj->GetField64(MemberOffset(offset));
     98 }
     99 
    100 static jlong Unsafe_getLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
    101   ScopedFastNativeObjectAccess soa(env);
    102   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
    103   return obj->GetField64Volatile(MemberOffset(offset));
    104 }
    105 
    106 static void Unsafe_putLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong newValue) {
    107   ScopedFastNativeObjectAccess soa(env);
    108   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
    109   // JNI must use non transactional mode.
    110   obj->SetField64<false>(MemberOffset(offset), newValue);
    111 }
    112 
    113 static void Unsafe_putLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
    114                                    jlong newValue) {
    115   ScopedFastNativeObjectAccess soa(env);
    116   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
    117   // JNI must use non transactional mode.
    118   obj->SetField64Volatile<false>(MemberOffset(offset), newValue);
    119 }
    120 
    121 static void Unsafe_putOrderedLong(JNIEnv* env, jobject, jobject javaObj, jlong offset,
    122                                   jlong newValue) {
    123   ScopedFastNativeObjectAccess soa(env);
    124   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
    125   QuasiAtomic::ThreadFenceRelease();
    126   // JNI must use non transactional mode.
    127   obj->SetField64<false>(MemberOffset(offset), newValue);
    128 }
    129 
    130 static jobject Unsafe_getObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
    131   ScopedFastNativeObjectAccess soa(env);
    132   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
    133   mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset));
    134   return soa.AddLocalReference<jobject>(value);
    135 }
    136 
    137 static jobject Unsafe_getObject(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
    138   ScopedFastNativeObjectAccess soa(env);
    139   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
    140   mirror::Object* value = obj->GetFieldObject<mirror::Object>(MemberOffset(offset));
    141   return soa.AddLocalReference<jobject>(value);
    142 }
    143 
    144 static void Unsafe_putObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
    145                              jobject javaNewValue) {
    146   ScopedFastNativeObjectAccess soa(env);
    147   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
    148   mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
    149   // JNI must use non transactional mode.
    150   obj->SetFieldObject<false>(MemberOffset(offset), newValue);
    151 }
    152 
    153 static void Unsafe_putObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset,
    154                                      jobject javaNewValue) {
    155   ScopedFastNativeObjectAccess soa(env);
    156   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
    157   mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
    158   // JNI must use non transactional mode.
    159   obj->SetFieldObjectVolatile<false>(MemberOffset(offset), newValue);
    160 }
    161 
    162 static void Unsafe_putOrderedObject(JNIEnv* env, jobject, jobject javaObj, jlong offset,
    163                                     jobject javaNewValue) {
    164   ScopedFastNativeObjectAccess soa(env);
    165   mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
    166   mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
    167   QuasiAtomic::ThreadFenceRelease();
    168   // JNI must use non transactional mode.
    169   obj->SetFieldObject<false>(MemberOffset(offset), newValue);
    170 }
    171 
    172 static 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 
    179 static 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 
    186 static JNINativeMethod gMethods[] = {
    187   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"),
    205   NATIVE_METHOD(Unsafe, getArrayBaseOffsetForComponentType, "!(Ljava/lang/Class;)I"),
    206   NATIVE_METHOD(Unsafe, getArrayIndexScaleForComponentType, "!(Ljava/lang/Class;)I"),
    207 };
    208 
    209 void register_sun_misc_Unsafe(JNIEnv* env) {
    210   REGISTER_NATIVE_METHODS("sun/misc/Unsafe");
    211 }
    212 
    213 }  // namespace art
    214