Home | History | Annotate | Download | only in mirror
      1 /*
      2  * Copyright (C) 2011 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 #ifndef ART_RUNTIME_MIRROR_ART_FIELD_INL_H_
     18 #define ART_RUNTIME_MIRROR_ART_FIELD_INL_H_
     19 
     20 #include "art_field.h"
     21 
     22 #include "base/logging.h"
     23 #include "dex_cache.h"
     24 #include "gc/accounting/card_table-inl.h"
     25 #include "jvalue.h"
     26 #include "object-inl.h"
     27 #include "primitive.h"
     28 #include "scoped_thread_state_change.h"
     29 #include "well_known_classes.h"
     30 
     31 namespace art {
     32 namespace mirror {
     33 
     34 inline uint32_t ArtField::ClassSize() {
     35   uint32_t vtable_entries = Object::kVTableLength + 6;
     36   return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0);
     37 }
     38 
     39 inline Class* ArtField::GetDeclaringClass() {
     40   Class* result = GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(ArtField, declaring_class_));
     41   DCHECK(result != NULL);
     42   DCHECK(result->IsLoaded() || result->IsErroneous());
     43   return result;
     44 }
     45 
     46 inline void ArtField::SetDeclaringClass(Class *new_declaring_class) {
     47   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(ArtField, declaring_class_), new_declaring_class);
     48 }
     49 
     50 inline uint32_t ArtField::GetAccessFlags() {
     51   DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
     52   return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, access_flags_));
     53 }
     54 
     55 inline MemberOffset ArtField::GetOffset() {
     56   DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous());
     57   return MemberOffset(GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, offset_)));
     58 }
     59 
     60 inline MemberOffset ArtField::GetOffsetDuringLinking() {
     61   DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
     62   return MemberOffset(GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, offset_)));
     63 }
     64 
     65 inline uint32_t ArtField::Get32(Object* object) {
     66   DCHECK(object != nullptr) << PrettyField(this);
     67   DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
     68   if (UNLIKELY(IsVolatile())) {
     69     return object->GetField32Volatile(GetOffset());
     70   }
     71   return object->GetField32(GetOffset());
     72 }
     73 
     74 template<bool kTransactionActive>
     75 inline void ArtField::Set32(Object* object, uint32_t new_value) {
     76   DCHECK(object != nullptr) << PrettyField(this);
     77   DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
     78   if (UNLIKELY(IsVolatile())) {
     79     object->SetField32Volatile<kTransactionActive>(GetOffset(), new_value);
     80   } else {
     81     object->SetField32<kTransactionActive>(GetOffset(), new_value);
     82   }
     83 }
     84 
     85 inline uint64_t ArtField::Get64(Object* object) {
     86   DCHECK(object != NULL) << PrettyField(this);
     87   DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
     88   if (UNLIKELY(IsVolatile())) {
     89     return object->GetField64Volatile(GetOffset());
     90   }
     91   return object->GetField64(GetOffset());
     92 }
     93 
     94 template<bool kTransactionActive>
     95 inline void ArtField::Set64(Object* object, uint64_t new_value) {
     96   DCHECK(object != NULL) << PrettyField(this);
     97   DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
     98   if (UNLIKELY(IsVolatile())) {
     99     object->SetField64Volatile<kTransactionActive>(GetOffset(), new_value);
    100   } else {
    101     object->SetField64<kTransactionActive>(GetOffset(), new_value);
    102   }
    103 }
    104 
    105 inline Object* ArtField::GetObj(Object* object) {
    106   DCHECK(object != NULL) << PrettyField(this);
    107   DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
    108   if (UNLIKELY(IsVolatile())) {
    109     return object->GetFieldObjectVolatile<Object>(GetOffset());
    110   }
    111   return object->GetFieldObject<Object>(GetOffset());
    112 }
    113 
    114 template<bool kTransactionActive>
    115 inline void ArtField::SetObj(Object* object, Object* new_value) {
    116   DCHECK(object != NULL) << PrettyField(this);
    117   DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
    118   if (UNLIKELY(IsVolatile())) {
    119     object->SetFieldObjectVolatile<kTransactionActive>(GetOffset(), new_value);
    120   } else {
    121     object->SetFieldObject<kTransactionActive>(GetOffset(), new_value);
    122   }
    123 }
    124 
    125 inline bool ArtField::GetBoolean(Object* object) {
    126   DCHECK_EQ(Primitive::kPrimBoolean, GetTypeAsPrimitiveType()) << PrettyField(this);
    127   return Get32(object);
    128 }
    129 
    130 template<bool kTransactionActive>
    131 inline void ArtField::SetBoolean(Object* object, bool z) {
    132   DCHECK_EQ(Primitive::kPrimBoolean, GetTypeAsPrimitiveType()) << PrettyField(this);
    133   Set32<kTransactionActive>(object, z);
    134 }
    135 
    136 inline int8_t ArtField::GetByte(Object* object) {
    137   DCHECK_EQ(Primitive::kPrimByte, GetTypeAsPrimitiveType()) << PrettyField(this);
    138   return Get32(object);
    139 }
    140 
    141 template<bool kTransactionActive>
    142 inline void ArtField::SetByte(Object* object, int8_t b) {
    143   DCHECK_EQ(Primitive::kPrimByte, GetTypeAsPrimitiveType()) << PrettyField(this);
    144   Set32<kTransactionActive>(object, b);
    145 }
    146 
    147 inline uint16_t ArtField::GetChar(Object* object) {
    148   DCHECK_EQ(Primitive::kPrimChar, GetTypeAsPrimitiveType()) << PrettyField(this);
    149   return Get32(object);
    150 }
    151 
    152 template<bool kTransactionActive>
    153 inline void ArtField::SetChar(Object* object, uint16_t c) {
    154   DCHECK_EQ(Primitive::kPrimChar, GetTypeAsPrimitiveType()) << PrettyField(this);
    155   Set32<kTransactionActive>(object, c);
    156 }
    157 
    158 inline int16_t ArtField::GetShort(Object* object) {
    159   DCHECK_EQ(Primitive::kPrimShort, GetTypeAsPrimitiveType()) << PrettyField(this);
    160   return Get32(object);
    161 }
    162 
    163 template<bool kTransactionActive>
    164 inline void ArtField::SetShort(Object* object, int16_t s) {
    165   DCHECK_EQ(Primitive::kPrimShort, GetTypeAsPrimitiveType()) << PrettyField(this);
    166   Set32<kTransactionActive>(object, s);
    167 }
    168 
    169 inline int32_t ArtField::GetInt(Object* object) {
    170   if (kIsDebugBuild) {
    171     Primitive::Type type = GetTypeAsPrimitiveType();
    172     CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
    173   }
    174   return Get32(object);
    175 }
    176 
    177 template<bool kTransactionActive>
    178 inline void ArtField::SetInt(Object* object, int32_t i) {
    179   if (kIsDebugBuild) {
    180     Primitive::Type type = GetTypeAsPrimitiveType();
    181     CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
    182   }
    183   Set32<kTransactionActive>(object, i);
    184 }
    185 
    186 inline int64_t ArtField::GetLong(Object* object) {
    187   if (kIsDebugBuild) {
    188     Primitive::Type type = GetTypeAsPrimitiveType();
    189     CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
    190   }
    191   return Get64(object);
    192 }
    193 
    194 template<bool kTransactionActive>
    195 inline void ArtField::SetLong(Object* object, int64_t j) {
    196   if (kIsDebugBuild) {
    197     Primitive::Type type = GetTypeAsPrimitiveType();
    198     CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
    199   }
    200   Set64<kTransactionActive>(object, j);
    201 }
    202 
    203 inline float ArtField::GetFloat(Object* object) {
    204   DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this);
    205   JValue bits;
    206   bits.SetI(Get32(object));
    207   return bits.GetF();
    208 }
    209 
    210 template<bool kTransactionActive>
    211 inline void ArtField::SetFloat(Object* object, float f) {
    212   DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this);
    213   JValue bits;
    214   bits.SetF(f);
    215   Set32<kTransactionActive>(object, bits.GetI());
    216 }
    217 
    218 inline double ArtField::GetDouble(Object* object) {
    219   DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this);
    220   JValue bits;
    221   bits.SetJ(Get64(object));
    222   return bits.GetD();
    223 }
    224 
    225 template<bool kTransactionActive>
    226 inline void ArtField::SetDouble(Object* object, double d) {
    227   DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this);
    228   JValue bits;
    229   bits.SetD(d);
    230   Set64<kTransactionActive>(object, bits.GetJ());
    231 }
    232 
    233 inline Object* ArtField::GetObject(Object* object) {
    234   DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this);
    235   return GetObj(object);
    236 }
    237 
    238 template<bool kTransactionActive>
    239 inline void ArtField::SetObject(Object* object, Object* l) {
    240   DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this);
    241   SetObj<kTransactionActive>(object, l);
    242 }
    243 
    244 inline const char* ArtField::GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    245   uint32_t field_index = GetDexFieldIndex();
    246   if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
    247     DCHECK(IsStatic());
    248     DCHECK_LT(field_index, 2U);
    249     return field_index == 0 ? "interfaces" : "throws";
    250   }
    251   const DexFile* dex_file = GetDexFile();
    252   return dex_file->GetFieldName(dex_file->GetFieldId(field_index));
    253 }
    254 
    255 inline const char* ArtField::GetTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    256   uint32_t field_index = GetDexFieldIndex();
    257   if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
    258     DCHECK(IsStatic());
    259     DCHECK_LT(field_index, 2U);
    260     // 0 == Class[] interfaces; 1 == Class[][] throws;
    261     return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;";
    262   }
    263   const DexFile* dex_file = GetDexFile();
    264   const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
    265   return dex_file->GetFieldTypeDescriptor(field_id);
    266 }
    267 
    268 inline Primitive::Type ArtField::GetTypeAsPrimitiveType()
    269     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    270   return Primitive::GetType(GetTypeDescriptor()[0]);
    271 }
    272 
    273 inline bool ArtField::IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    274   return GetTypeAsPrimitiveType() != Primitive::kPrimNot;
    275 }
    276 
    277 inline size_t ArtField::FieldSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    278   return Primitive::FieldSize(GetTypeAsPrimitiveType());
    279 }
    280 
    281 inline mirror::DexCache* ArtField::GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    282   return GetDeclaringClass()->GetDexCache();
    283 }
    284 
    285 inline const DexFile* ArtField::GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    286   return GetDexCache()->GetDexFile();
    287 }
    288 
    289 inline ArtField* ArtField::FromReflectedField(const ScopedObjectAccessAlreadyRunnable& soa,
    290                                               jobject jlr_field) {
    291   mirror::ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_reflect_Field_artField);
    292   mirror::ArtField* field = f->GetObject(soa.Decode<mirror::Object*>(jlr_field))->AsArtField();
    293   DCHECK(field != nullptr);
    294   return field;
    295 }
    296 
    297 }  // namespace mirror
    298 }  // namespace art
    299 
    300 #endif  // ART_RUNTIME_MIRROR_ART_FIELD_INL_H_
    301