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_CLASS_INL_H_
     18 #define ART_RUNTIME_MIRROR_CLASS_INL_H_
     19 
     20 #include "class.h"
     21 
     22 #include "art_field-inl.h"
     23 #include "art_method-inl.h"
     24 #include "class_linker-inl.h"
     25 #include "class_loader.h"
     26 #include "common_throws.h"
     27 #include "dex_cache.h"
     28 #include "dex_file.h"
     29 #include "gc/heap-inl.h"
     30 #include "iftable.h"
     31 #include "object_array-inl.h"
     32 #include "read_barrier-inl.h"
     33 #include "reference-inl.h"
     34 #include "runtime.h"
     35 #include "string.h"
     36 
     37 namespace art {
     38 namespace mirror {
     39 
     40 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
     41 inline uint32_t Class::GetObjectSize() {
     42   if (kIsDebugBuild) {
     43     // Use a local variable as (D)CHECK can't handle the space between
     44     // the two template params.
     45     bool is_variable_size = IsVariableSize<kVerifyFlags, kReadBarrierOption>();
     46     CHECK(!is_variable_size) << " class=" << PrettyTypeOf(this);
     47   }
     48   return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, object_size_));
     49 }
     50 
     51 inline Class* Class::GetSuperClass() {
     52   // Can only get super class for loaded classes (hack for when runtime is
     53   // initializing)
     54   DCHECK(IsLoaded() || IsErroneous() || !Runtime::Current()->IsStarted()) << IsLoaded();
     55   return GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_));
     56 }
     57 
     58 inline ClassLoader* Class::GetClassLoader() {
     59   return GetFieldObject<ClassLoader>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_));
     60 }
     61 
     62 template<VerifyObjectFlags kVerifyFlags>
     63 inline DexCache* Class::GetDexCache() {
     64   return GetFieldObject<DexCache, kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_));
     65 }
     66 
     67 inline ObjectArray<ArtMethod>* Class::GetDirectMethods() {
     68   DCHECK(IsLoaded() || IsErroneous());
     69   return GetFieldObject<ObjectArray<ArtMethod>>(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_));
     70 }
     71 
     72 inline void Class::SetDirectMethods(ObjectArray<ArtMethod>* new_direct_methods)
     73     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     74   DCHECK(NULL == GetFieldObject<ObjectArray<ArtMethod>>(
     75       OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_)));
     76   DCHECK_NE(0, new_direct_methods->GetLength());
     77   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), new_direct_methods);
     78 }
     79 
     80 inline ArtMethod* Class::GetDirectMethod(int32_t i) {
     81   return GetDirectMethods()->Get(i);
     82 }
     83 
     84 inline void Class::SetDirectMethod(uint32_t i, ArtMethod* f)  // TODO: uint16_t
     85     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     86   ObjectArray<ArtMethod>* direct_methods =
     87       GetFieldObject<ObjectArray<ArtMethod>>(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_));
     88   direct_methods->Set<false>(i, f);
     89 }
     90 
     91 // Returns the number of static, private, and constructor methods.
     92 inline uint32_t Class::NumDirectMethods() {
     93   return (GetDirectMethods() != NULL) ? GetDirectMethods()->GetLength() : 0;
     94 }
     95 
     96 template<VerifyObjectFlags kVerifyFlags>
     97 inline ObjectArray<ArtMethod>* Class::GetVirtualMethods() {
     98   DCHECK(IsLoaded() || IsErroneous());
     99   return GetFieldObject<ObjectArray<ArtMethod>>(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_));
    100 }
    101 
    102 inline void Class::SetVirtualMethods(ObjectArray<ArtMethod>* new_virtual_methods) {
    103   // TODO: we reassign virtual methods to grow the table for miranda
    104   // methods.. they should really just be assigned once.
    105   DCHECK_NE(0, new_virtual_methods->GetLength());
    106   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_), new_virtual_methods);
    107 }
    108 
    109 inline uint32_t Class::NumVirtualMethods() {
    110   return (GetVirtualMethods() != NULL) ? GetVirtualMethods()->GetLength() : 0;
    111 }
    112 
    113 template<VerifyObjectFlags kVerifyFlags>
    114 inline ArtMethod* Class::GetVirtualMethod(uint32_t i) {
    115   DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>());
    116   return GetVirtualMethods()->Get(i);
    117 }
    118 
    119 inline ArtMethod* Class::GetVirtualMethodDuringLinking(uint32_t i) {
    120   DCHECK(IsLoaded() || IsErroneous());
    121   return GetVirtualMethods()->Get(i);
    122 }
    123 
    124 inline void Class::SetVirtualMethod(uint32_t i, ArtMethod* f)  // TODO: uint16_t
    125     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    126   ObjectArray<ArtMethod>* virtual_methods =
    127       GetFieldObject<ObjectArray<ArtMethod>>(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_));
    128   virtual_methods->Set<false>(i, f);
    129 }
    130 
    131 inline ObjectArray<ArtMethod>* Class::GetVTable() {
    132   DCHECK(IsResolved() || IsErroneous());
    133   return GetFieldObject<ObjectArray<ArtMethod>>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_));
    134 }
    135 
    136 inline ObjectArray<ArtMethod>* Class::GetVTableDuringLinking() {
    137   DCHECK(IsLoaded() || IsErroneous());
    138   return GetFieldObject<ObjectArray<ArtMethod>>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_));
    139 }
    140 
    141 inline void Class::SetVTable(ObjectArray<ArtMethod>* new_vtable) {
    142   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), new_vtable);
    143 }
    144 
    145 inline ObjectArray<ArtMethod>* Class::GetImTable() {
    146   return GetFieldObject<ObjectArray<ArtMethod>>(OFFSET_OF_OBJECT_MEMBER(Class, imtable_));
    147 }
    148 
    149 inline void Class::SetImTable(ObjectArray<ArtMethod>* new_imtable) {
    150   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, imtable_), new_imtable);
    151 }
    152 
    153 inline ArtMethod* Class::GetEmbeddedImTableEntry(uint32_t i) {
    154   uint32_t offset = EmbeddedImTableOffset().Uint32Value() + i * sizeof(ImTableEntry);
    155   return GetFieldObject<mirror::ArtMethod>(MemberOffset(offset));
    156 }
    157 
    158 inline void Class::SetEmbeddedImTableEntry(uint32_t i, ArtMethod* method) {
    159   uint32_t offset = EmbeddedImTableOffset().Uint32Value() + i * sizeof(ImTableEntry);
    160   SetFieldObject<false>(MemberOffset(offset), method);
    161   CHECK(method == GetImTable()->Get(i));
    162 }
    163 
    164 inline bool Class::HasVTable() {
    165   return (GetVTable() != nullptr) || ShouldHaveEmbeddedImtAndVTable();
    166 }
    167 
    168 inline int32_t Class::GetVTableLength() {
    169   if (ShouldHaveEmbeddedImtAndVTable()) {
    170     return GetEmbeddedVTableLength();
    171   }
    172   return (GetVTable() != nullptr) ? GetVTable()->GetLength() : 0;
    173 }
    174 
    175 inline ArtMethod* Class::GetVTableEntry(uint32_t i) {
    176   if (ShouldHaveEmbeddedImtAndVTable()) {
    177     return GetEmbeddedVTableEntry(i);
    178   }
    179   return (GetVTable() != nullptr) ? GetVTable()->Get(i) : nullptr;
    180 }
    181 
    182 inline int32_t Class::GetEmbeddedVTableLength() {
    183   return GetField32(EmbeddedVTableLengthOffset());
    184 }
    185 
    186 inline void Class::SetEmbeddedVTableLength(int32_t len) {
    187   SetField32<false>(EmbeddedVTableLengthOffset(), len);
    188 }
    189 
    190 inline ArtMethod* Class::GetEmbeddedVTableEntry(uint32_t i) {
    191   uint32_t offset = EmbeddedVTableOffset().Uint32Value() + i * sizeof(VTableEntry);
    192   return GetFieldObject<mirror::ArtMethod>(MemberOffset(offset));
    193 }
    194 
    195 inline void Class::SetEmbeddedVTableEntry(uint32_t i, ArtMethod* method) {
    196   uint32_t offset = EmbeddedVTableOffset().Uint32Value() + i * sizeof(VTableEntry);
    197   SetFieldObject<false>(MemberOffset(offset), method);
    198   CHECK(method == GetVTableDuringLinking()->Get(i));
    199 }
    200 
    201 inline bool Class::Implements(Class* klass) {
    202   DCHECK(klass != NULL);
    203   DCHECK(klass->IsInterface()) << PrettyClass(this);
    204   // All interfaces implemented directly and by our superclass, and
    205   // recursively all super-interfaces of those interfaces, are listed
    206   // in iftable_, so we can just do a linear scan through that.
    207   int32_t iftable_count = GetIfTableCount();
    208   IfTable* iftable = GetIfTable();
    209   for (int32_t i = 0; i < iftable_count; i++) {
    210     if (iftable->GetInterface(i) == klass) {
    211       return true;
    212     }
    213   }
    214   return false;
    215 }
    216 
    217 // Determine whether "this" is assignable from "src", where both of these
    218 // are array classes.
    219 //
    220 // Consider an array class, e.g. Y[][], where Y is a subclass of X.
    221 //   Y[][]            = Y[][] --> true (identity)
    222 //   X[][]            = Y[][] --> true (element superclass)
    223 //   Y                = Y[][] --> false
    224 //   Y[]              = Y[][] --> false
    225 //   Object           = Y[][] --> true (everything is an object)
    226 //   Object[]         = Y[][] --> true
    227 //   Object[][]       = Y[][] --> true
    228 //   Object[][][]     = Y[][] --> false (too many []s)
    229 //   Serializable     = Y[][] --> true (all arrays are Serializable)
    230 //   Serializable[]   = Y[][] --> true
    231 //   Serializable[][] = Y[][] --> false (unless Y is Serializable)
    232 //
    233 // Don't forget about primitive types.
    234 //   Object[]         = int[] --> false
    235 //
    236 inline bool Class::IsArrayAssignableFromArray(Class* src) {
    237   DCHECK(IsArrayClass())  << PrettyClass(this);
    238   DCHECK(src->IsArrayClass()) << PrettyClass(src);
    239   return GetComponentType()->IsAssignableFrom(src->GetComponentType());
    240 }
    241 
    242 inline bool Class::IsAssignableFromArray(Class* src) {
    243   DCHECK(!IsInterface()) << PrettyClass(this);  // handled first in IsAssignableFrom
    244   DCHECK(src->IsArrayClass()) << PrettyClass(src);
    245   if (!IsArrayClass()) {
    246     // If "this" is not also an array, it must be Object.
    247     // src's super should be java_lang_Object, since it is an array.
    248     Class* java_lang_Object = src->GetSuperClass();
    249     DCHECK(java_lang_Object != NULL) << PrettyClass(src);
    250     DCHECK(java_lang_Object->GetSuperClass() == NULL) << PrettyClass(src);
    251     return this == java_lang_Object;
    252   }
    253   return IsArrayAssignableFromArray(src);
    254 }
    255 
    256 template <bool throw_on_failure, bool use_referrers_cache>
    257 inline bool Class::ResolvedFieldAccessTest(Class* access_to, ArtField* field,
    258                                            uint32_t field_idx, DexCache* dex_cache) {
    259   DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
    260   if (UNLIKELY(!this->CanAccess(access_to))) {
    261     // The referrer class can't access the field's declaring class but may still be able
    262     // to access the field if the FieldId specifies an accessible subclass of the declaring
    263     // class rather than the declaring class itself.
    264     DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
    265     uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_;
    266     // The referenced class has already been resolved with the field, get it from the dex cache.
    267     Class* dex_access_to = referrer_dex_cache->GetResolvedType(class_idx);
    268     DCHECK(dex_access_to != nullptr);
    269     if (UNLIKELY(!this->CanAccess(dex_access_to))) {
    270       if (throw_on_failure) {
    271         ThrowIllegalAccessErrorClass(this, dex_access_to);
    272       }
    273       return false;
    274     }
    275     DCHECK_EQ(this->CanAccessMember(access_to, field->GetAccessFlags()),
    276               this->CanAccessMember(dex_access_to, field->GetAccessFlags()));
    277   }
    278   if (LIKELY(this->CanAccessMember(access_to, field->GetAccessFlags()))) {
    279     return true;
    280   }
    281   if (throw_on_failure) {
    282     ThrowIllegalAccessErrorField(this, field);
    283   }
    284   return false;
    285 }
    286 
    287 template <bool throw_on_failure, bool use_referrers_cache, InvokeType throw_invoke_type>
    288 inline bool Class::ResolvedMethodAccessTest(Class* access_to, ArtMethod* method,
    289                                             uint32_t method_idx, DexCache* dex_cache) {
    290   COMPILE_ASSERT(throw_on_failure || throw_invoke_type == kStatic, non_default_throw_invoke_type);
    291   DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
    292   if (UNLIKELY(!this->CanAccess(access_to))) {
    293     // The referrer class can't access the method's declaring class but may still be able
    294     // to access the method if the MethodId specifies an accessible subclass of the declaring
    295     // class rather than the declaring class itself.
    296     DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
    297     uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_;
    298     // The referenced class has already been resolved with the method, get it from the dex cache.
    299     Class* dex_access_to = referrer_dex_cache->GetResolvedType(class_idx);
    300     DCHECK(dex_access_to != nullptr);
    301     if (UNLIKELY(!this->CanAccess(dex_access_to))) {
    302       if (throw_on_failure) {
    303         ThrowIllegalAccessErrorClassForMethodDispatch(this, dex_access_to,
    304                                                       method, throw_invoke_type);
    305       }
    306       return false;
    307     }
    308     DCHECK_EQ(this->CanAccessMember(access_to, method->GetAccessFlags()),
    309               this->CanAccessMember(dex_access_to, method->GetAccessFlags()));
    310   }
    311   if (LIKELY(this->CanAccessMember(access_to, method->GetAccessFlags()))) {
    312     return true;
    313   }
    314   if (throw_on_failure) {
    315     ThrowIllegalAccessErrorMethod(this, method);
    316   }
    317   return false;
    318 }
    319 
    320 inline bool Class::CanAccessResolvedField(Class* access_to, ArtField* field,
    321                                           DexCache* dex_cache, uint32_t field_idx) {
    322   return ResolvedFieldAccessTest<false, false>(access_to, field, field_idx, dex_cache);
    323 }
    324 
    325 inline bool Class::CheckResolvedFieldAccess(Class* access_to, ArtField* field,
    326                                             uint32_t field_idx) {
    327   return ResolvedFieldAccessTest<true, true>(access_to, field, field_idx, nullptr);
    328 }
    329 
    330 inline bool Class::CanAccessResolvedMethod(Class* access_to, ArtMethod* method,
    331                                            DexCache* dex_cache, uint32_t method_idx) {
    332   return ResolvedMethodAccessTest<false, false, kStatic>(access_to, method, method_idx, dex_cache);
    333 }
    334 
    335 template <InvokeType throw_invoke_type>
    336 inline bool Class::CheckResolvedMethodAccess(Class* access_to, ArtMethod* method,
    337                                              uint32_t method_idx) {
    338   return ResolvedMethodAccessTest<true, true, throw_invoke_type>(access_to, method, method_idx,
    339                                                                  nullptr);
    340 }
    341 
    342 inline bool Class::IsSubClass(Class* klass) {
    343   DCHECK(!IsInterface()) << PrettyClass(this);
    344   DCHECK(!IsArrayClass()) << PrettyClass(this);
    345   Class* current = this;
    346   do {
    347     if (current == klass) {
    348       return true;
    349     }
    350     current = current->GetSuperClass();
    351   } while (current != NULL);
    352   return false;
    353 }
    354 
    355 inline ArtMethod* Class::FindVirtualMethodForInterface(ArtMethod* method) {
    356   Class* declaring_class = method->GetDeclaringClass();
    357   DCHECK(declaring_class != NULL) << PrettyClass(this);
    358   DCHECK(declaring_class->IsInterface()) << PrettyMethod(method);
    359   // TODO cache to improve lookup speed
    360   int32_t iftable_count = GetIfTableCount();
    361   IfTable* iftable = GetIfTable();
    362   for (int32_t i = 0; i < iftable_count; i++) {
    363     if (iftable->GetInterface(i) == declaring_class) {
    364       return iftable->GetMethodArray(i)->Get(method->GetMethodIndex());
    365     }
    366   }
    367   return NULL;
    368 }
    369 
    370 inline ArtMethod* Class::FindVirtualMethodForVirtual(ArtMethod* method) {
    371   DCHECK(!method->GetDeclaringClass()->IsInterface() || method->IsMiranda());
    372   // The argument method may from a super class.
    373   // Use the index to a potentially overridden one for this instance's class.
    374   return GetVTableEntry(method->GetMethodIndex());
    375 }
    376 
    377 inline ArtMethod* Class::FindVirtualMethodForSuper(ArtMethod* method) {
    378   DCHECK(!method->GetDeclaringClass()->IsInterface());
    379   return GetSuperClass()->GetVTableEntry(method->GetMethodIndex());
    380 }
    381 
    382 inline ArtMethod* Class::FindVirtualMethodForVirtualOrInterface(ArtMethod* method) {
    383   if (method->IsDirect()) {
    384     return method;
    385   }
    386   if (method->GetDeclaringClass()->IsInterface() && !method->IsMiranda()) {
    387     return FindVirtualMethodForInterface(method);
    388   }
    389   return FindVirtualMethodForVirtual(method);
    390 }
    391 
    392 inline IfTable* Class::GetIfTable() {
    393   return GetFieldObject<IfTable>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_));
    394 }
    395 
    396 inline int32_t Class::GetIfTableCount() {
    397   IfTable* iftable = GetIfTable();
    398   if (iftable == NULL) {
    399     return 0;
    400   }
    401   return iftable->Count();
    402 }
    403 
    404 inline void Class::SetIfTable(IfTable* new_iftable) {
    405   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), new_iftable);
    406 }
    407 
    408 inline ObjectArray<ArtField>* Class::GetIFields() {
    409   DCHECK(IsLoaded() || IsErroneous());
    410   return GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
    411 }
    412 
    413 inline void Class::SetIFields(ObjectArray<ArtField>* new_ifields)
    414     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    415   DCHECK(NULL == GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_)));
    416   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
    417 }
    418 
    419 inline ObjectArray<ArtField>* Class::GetSFields() {
    420   DCHECK(IsLoaded() || IsErroneous());
    421   return GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
    422 }
    423 
    424 inline void Class::SetSFields(ObjectArray<ArtField>* new_sfields)
    425     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    426   DCHECK((IsRetired() && new_sfields == nullptr) ||
    427          (NULL == GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_))));
    428   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
    429 }
    430 
    431 inline uint32_t Class::NumStaticFields() {
    432   return (GetSFields() != NULL) ? GetSFields()->GetLength() : 0;
    433 }
    434 
    435 
    436 inline ArtField* Class::GetStaticField(uint32_t i)  // TODO: uint16_t
    437     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    438   return GetSFields()->GetWithoutChecks(i);
    439 }
    440 
    441 inline void Class::SetStaticField(uint32_t i, ArtField* f)  // TODO: uint16_t
    442     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    443   ObjectArray<ArtField>* sfields= GetFieldObject<ObjectArray<ArtField>>(
    444       OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
    445   sfields->Set<false>(i, f);
    446 }
    447 
    448 inline uint32_t Class::NumInstanceFields() {
    449   return (GetIFields() != NULL) ? GetIFields()->GetLength() : 0;
    450 }
    451 
    452 inline ArtField* Class::GetInstanceField(uint32_t i) {  // TODO: uint16_t
    453   DCHECK_NE(NumInstanceFields(), 0U);
    454   return GetIFields()->GetWithoutChecks(i);
    455 }
    456 
    457 inline void Class::SetInstanceField(uint32_t i, ArtField* f)  // TODO: uint16_t
    458     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    459   ObjectArray<ArtField>* ifields= GetFieldObject<ObjectArray<ArtField>>(
    460       OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
    461   ifields->Set<false>(i, f);
    462 }
    463 
    464 template<VerifyObjectFlags kVerifyFlags>
    465 inline uint32_t Class::GetReferenceInstanceOffsets() {
    466   DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>());
    467   return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_));
    468 }
    469 
    470 inline void Class::SetClinitThreadId(pid_t new_clinit_thread_id) {
    471   if (Runtime::Current()->IsActiveTransaction()) {
    472     SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id);
    473   } else {
    474     SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id);
    475   }
    476 }
    477 
    478 inline void Class::SetVerifyErrorClass(Class* klass) {
    479   CHECK(klass != NULL) << PrettyClass(this);
    480   if (Runtime::Current()->IsActiveTransaction()) {
    481     SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass);
    482   } else {
    483     SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass);
    484   }
    485 }
    486 
    487 template<VerifyObjectFlags kVerifyFlags>
    488 inline uint32_t Class::GetAccessFlags() {
    489   // Check class is loaded/retired or this is java.lang.String that has a
    490   // circularity issue during loading the names of its members
    491   DCHECK(IsIdxLoaded<kVerifyFlags>() || IsRetired<kVerifyFlags>() ||
    492          IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() ||
    493          this == String::GetJavaLangString() ||
    494          this == ArtField::GetJavaLangReflectArtField() ||
    495          this == ArtMethod::GetJavaLangReflectArtMethod());
    496   return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_));
    497 }
    498 
    499 inline String* Class::GetName() {
    500   return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(Class, name_));
    501 }
    502 inline void Class::SetName(String* name) {
    503   if (Runtime::Current()->IsActiveTransaction()) {
    504     SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name);
    505   } else {
    506     SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name);
    507   }
    508 }
    509 
    510 template<VerifyObjectFlags kVerifyFlags>
    511 inline Primitive::Type Class::GetPrimitiveType() {
    512   DCHECK_EQ(sizeof(Primitive::Type), sizeof(int32_t));
    513   return static_cast<Primitive::Type>(
    514       GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_)));
    515 }
    516 
    517 inline void Class::CheckObjectAlloc() {
    518   DCHECK(!IsArrayClass())
    519       << PrettyClass(this)
    520       << "A array shouldn't be allocated through this "
    521       << "as it requires a pre-fence visitor that sets the class size.";
    522   DCHECK(!IsClassClass())
    523       << PrettyClass(this)
    524       << "A class object shouldn't be allocated through this "
    525       << "as it requires a pre-fence visitor that sets the class size.";
    526   DCHECK(IsInstantiable()) << PrettyClass(this);
    527   // TODO: decide whether we want this check. It currently fails during bootstrap.
    528   // DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass(this);
    529   DCHECK_GE(this->object_size_, sizeof(Object));
    530 }
    531 
    532 template<bool kIsInstrumented, bool kCheckAddFinalizer>
    533 inline Object* Class::Alloc(Thread* self, gc::AllocatorType allocator_type) {
    534   CheckObjectAlloc();
    535   gc::Heap* heap = Runtime::Current()->GetHeap();
    536   const bool add_finalizer = kCheckAddFinalizer && IsFinalizable();
    537   if (!kCheckAddFinalizer) {
    538     DCHECK(!IsFinalizable());
    539   }
    540   mirror::Object* obj =
    541       heap->AllocObjectWithAllocator<kIsInstrumented, false>(self, this, this->object_size_,
    542                                                              allocator_type, VoidFunctor());
    543   if (add_finalizer && LIKELY(obj != nullptr)) {
    544     heap->AddFinalizerReference(self, &obj);
    545   }
    546   return obj;
    547 }
    548 
    549 inline Object* Class::AllocObject(Thread* self) {
    550   return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentAllocator());
    551 }
    552 
    553 inline Object* Class::AllocNonMovableObject(Thread* self) {
    554   return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentNonMovingAllocator());
    555 }
    556 
    557 inline uint32_t Class::ComputeClassSize(bool has_embedded_tables,
    558                                         uint32_t num_vtable_entries,
    559                                         uint32_t num_32bit_static_fields,
    560                                         uint32_t num_64bit_static_fields,
    561                                         uint32_t num_ref_static_fields) {
    562   // Space used by java.lang.Class and its instance fields.
    563   uint32_t size = sizeof(Class);
    564   // Space used by embedded tables.
    565   if (has_embedded_tables) {
    566     uint32_t embedded_imt_size = kImtSize * sizeof(ImTableEntry);
    567     uint32_t embedded_vtable_size = num_vtable_entries * sizeof(VTableEntry);
    568     size += embedded_imt_size +
    569             sizeof(int32_t) /* vtable len */ +
    570             embedded_vtable_size;
    571   }
    572   // Space used by reference statics.
    573   size +=  num_ref_static_fields * sizeof(HeapReference<Object>);
    574   // Possible pad for alignment.
    575   if (((size & 7) != 0) && (num_64bit_static_fields > 0)) {
    576     size += sizeof(uint32_t);
    577     if (num_32bit_static_fields != 0) {
    578       // Shuffle one 32 bit static field forward.
    579       num_32bit_static_fields--;
    580     }
    581   }
    582   // Space used for primitive static fields.
    583   size += (num_32bit_static_fields * sizeof(uint32_t)) +
    584       (num_64bit_static_fields * sizeof(uint64_t));
    585   return size;
    586 }
    587 
    588 template <bool kVisitClass, typename Visitor>
    589 inline void Class::VisitReferences(mirror::Class* klass, const Visitor& visitor) {
    590   // Visit the static fields first so that we don't overwrite the SFields / IFields instance
    591   // fields.
    592   VisitInstanceFieldsReferences<kVisitClass>(klass, visitor);
    593   if (!IsTemp()) {
    594     // Temp classes don't ever populate imt/vtable or static fields and they are not even
    595     // allocated with the right size for those.
    596     VisitStaticFieldsReferences<kVisitClass>(this, visitor);
    597     if (ShouldHaveEmbeddedImtAndVTable()) {
    598       VisitEmbeddedImtAndVTable(visitor);
    599     }
    600   }
    601 }
    602 
    603 template<typename Visitor>
    604 inline void Class::VisitEmbeddedImtAndVTable(const Visitor& visitor) {
    605   uint32_t pos = sizeof(mirror::Class);
    606 
    607   size_t count = kImtSize;
    608   for (size_t i = 0; i < count; ++i) {
    609     MemberOffset offset = MemberOffset(pos);
    610     visitor(this, offset, true);
    611     pos += sizeof(ImTableEntry);
    612   }
    613 
    614   // Skip vtable length.
    615   pos += sizeof(int32_t);
    616 
    617   count = GetEmbeddedVTableLength();
    618   for (size_t i = 0; i < count; ++i) {
    619     MemberOffset offset = MemberOffset(pos);
    620     visitor(this, offset, true);
    621     pos += sizeof(VTableEntry);
    622   }
    623 }
    624 
    625 template<ReadBarrierOption kReadBarrierOption>
    626 inline bool Class::IsArtFieldClass() const {
    627   return this == ArtField::GetJavaLangReflectArtField<kReadBarrierOption>();
    628 }
    629 
    630 template<ReadBarrierOption kReadBarrierOption>
    631 inline bool Class::IsArtMethodClass() const {
    632   return this == ArtMethod::GetJavaLangReflectArtMethod<kReadBarrierOption>();
    633 }
    634 
    635 template<ReadBarrierOption kReadBarrierOption>
    636 inline bool Class::IsReferenceClass() const {
    637   return this == Reference::GetJavaLangRefReference<kReadBarrierOption>();
    638 }
    639 
    640 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
    641 inline bool Class::IsClassClass() {
    642   Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
    643       template GetClass<kVerifyFlags, kReadBarrierOption>();
    644   return this == java_lang_Class;
    645 }
    646 
    647 inline const DexFile& Class::GetDexFile() {
    648   return *GetDexCache()->GetDexFile();
    649 }
    650 
    651 inline bool Class::DescriptorEquals(const char* match) {
    652   if (IsArrayClass()) {
    653     return match[0] == '[' && GetComponentType()->DescriptorEquals(match + 1);
    654   } else if (IsPrimitive()) {
    655     return strcmp(Primitive::Descriptor(GetPrimitiveType()), match) == 0;
    656   } else if (IsProxyClass()) {
    657     return Runtime::Current()->GetClassLinker()->GetDescriptorForProxy(this) == match;
    658   } else {
    659     const DexFile& dex_file = GetDexFile();
    660     const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
    661     return strcmp(dex_file.GetTypeDescriptor(type_id), match) == 0;
    662   }
    663 }
    664 
    665 inline void Class::AssertInitializedOrInitializingInThread(Thread* self) {
    666   if (kIsDebugBuild && !IsInitialized()) {
    667     CHECK(IsInitializing()) << PrettyClass(this) << " is not initializing: " << GetStatus();
    668     CHECK_EQ(GetClinitThreadId(), self->GetTid()) << PrettyClass(this)
    669                                                   << " is initializing in a different thread";
    670   }
    671 }
    672 
    673 inline ObjectArray<Class>* Class::GetInterfaces() {
    674   CHECK(IsProxyClass());
    675   // First static field.
    676   DCHECK(GetSFields()->Get(0)->IsArtField());
    677   DCHECK_STREQ(GetSFields()->Get(0)->GetName(), "interfaces");
    678   MemberOffset field_offset = GetSFields()->Get(0)->GetOffset();
    679   return GetFieldObject<ObjectArray<Class>>(field_offset);
    680 }
    681 
    682 inline ObjectArray<ObjectArray<Class>>* Class::GetThrows() {
    683   CHECK(IsProxyClass());
    684   // Second static field.
    685   DCHECK(GetSFields()->Get(1)->IsArtField());
    686   DCHECK_STREQ(GetSFields()->Get(1)->GetName(), "throws");
    687   MemberOffset field_offset = GetSFields()->Get(1)->GetOffset();
    688   return GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset);
    689 }
    690 
    691 inline MemberOffset Class::GetDisableIntrinsicFlagOffset() {
    692   CHECK(IsReferenceClass());
    693   // First static field
    694   DCHECK(GetSFields()->Get(0)->IsArtField());
    695   DCHECK_STREQ(GetSFields()->Get(0)->GetName(), "disableIntrinsic");
    696   return GetSFields()->Get(0)->GetOffset();
    697 }
    698 
    699 inline MemberOffset Class::GetSlowPathFlagOffset() {
    700   CHECK(IsReferenceClass());
    701   // Second static field
    702   DCHECK(GetSFields()->Get(1)->IsArtField());
    703   DCHECK_STREQ(GetSFields()->Get(1)->GetName(), "slowPathEnabled");
    704   return GetSFields()->Get(1)->GetOffset();
    705 }
    706 
    707 inline bool Class::GetSlowPathEnabled() {
    708   return GetField32(GetSlowPathFlagOffset());
    709 }
    710 
    711 inline void Class::SetSlowPath(bool enabled) {
    712   SetField32<false>(GetSlowPathFlagOffset(), enabled);
    713 }
    714 
    715 inline void Class::InitializeClassVisitor::operator()(
    716     mirror::Object* obj, size_t usable_size) const {
    717   DCHECK_LE(class_size_, usable_size);
    718   // Avoid AsClass as object is not yet in live bitmap or allocation stack.
    719   mirror::Class* klass = down_cast<mirror::Class*>(obj);
    720   // DCHECK(klass->IsClass());
    721   klass->SetClassSize(class_size_);
    722   klass->SetPrimitiveType(Primitive::kPrimNot);  // Default to not being primitive.
    723   klass->SetDexClassDefIndex(DexFile::kDexNoIndex16);  // Default to no valid class def index.
    724   klass->SetDexTypeIndex(DexFile::kDexNoIndex16);  // Default to no valid type index.
    725 }
    726 
    727 inline void Class::SetAccessFlags(uint32_t new_access_flags) {
    728   // Called inside a transaction when setting pre-verified flag during boot image compilation.
    729   if (Runtime::Current()->IsActiveTransaction()) {
    730     SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), new_access_flags);
    731   } else {
    732     SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), new_access_flags);
    733   }
    734 }
    735 
    736 }  // namespace mirror
    737 }  // namespace art
    738 
    739 #endif  // ART_RUNTIME_MIRROR_CLASS_INL_H_
    740