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.h"
     24 #include "art_method-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 #include "utils.h"
     37 
     38 namespace art {
     39 namespace mirror {
     40 
     41 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
     42 inline uint32_t Class::GetObjectSize() {
     43   // Note: Extra parentheses to avoid the comma being interpreted as macro parameter separator.
     44   DCHECK((!IsVariableSize<kVerifyFlags, kReadBarrierOption>())) << " class=" << PrettyTypeOf(this);
     45   return GetField32(ObjectSizeOffset());
     46 }
     47 
     48 inline Class* Class::GetSuperClass() {
     49   // Can only get super class for loaded classes (hack for when runtime is
     50   // initializing)
     51   DCHECK(IsLoaded() || IsErroneous() || !Runtime::Current()->IsStarted()) << IsLoaded();
     52   return GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_));
     53 }
     54 
     55 inline ClassLoader* Class::GetClassLoader() {
     56   return GetFieldObject<ClassLoader>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_));
     57 }
     58 
     59 template<VerifyObjectFlags kVerifyFlags>
     60 inline DexCache* Class::GetDexCache() {
     61   return GetFieldObject<DexCache, kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_));
     62 }
     63 
     64 inline ArtMethod* Class::GetDirectMethodsPtr() {
     65   DCHECK(IsLoaded() || IsErroneous());
     66   return GetDirectMethodsPtrUnchecked();
     67 }
     68 
     69 inline ArtMethod* Class::GetDirectMethodsPtrUnchecked() {
     70   return reinterpret_cast<ArtMethod*>(GetField64(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_)));
     71 }
     72 
     73 inline ArtMethod* Class::GetVirtualMethodsPtrUnchecked() {
     74   return reinterpret_cast<ArtMethod*>(GetField64(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_)));
     75 }
     76 
     77 inline void Class::SetDirectMethodsPtr(ArtMethod* new_direct_methods) {
     78   DCHECK(GetDirectMethodsPtrUnchecked() == nullptr);
     79   SetDirectMethodsPtrUnchecked(new_direct_methods);
     80 }
     81 
     82 inline void Class::SetDirectMethodsPtrUnchecked(ArtMethod* new_direct_methods) {
     83   SetField64<false>(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_),
     84                     reinterpret_cast<uint64_t>(new_direct_methods));
     85 }
     86 
     87 inline ArtMethod* Class::GetDirectMethodUnchecked(size_t i, size_t pointer_size) {
     88   CheckPointerSize(pointer_size);
     89   auto* methods = GetDirectMethodsPtrUnchecked();
     90   DCHECK(methods != nullptr);
     91   return reinterpret_cast<ArtMethod*>(reinterpret_cast<uintptr_t>(methods) +
     92       ArtMethod::ObjectSize(pointer_size) * i);
     93 }
     94 
     95 inline ArtMethod* Class::GetDirectMethod(size_t i, size_t pointer_size) {
     96   CheckPointerSize(pointer_size);
     97   auto* methods = GetDirectMethodsPtr();
     98   DCHECK(methods != nullptr);
     99   return reinterpret_cast<ArtMethod*>(reinterpret_cast<uintptr_t>(methods) +
    100       ArtMethod::ObjectSize(pointer_size) * i);
    101 }
    102 
    103 template<VerifyObjectFlags kVerifyFlags>
    104 inline ArtMethod* Class::GetVirtualMethodsPtr() {
    105   DCHECK(IsLoaded<kVerifyFlags>() || IsErroneous<kVerifyFlags>());
    106   return GetVirtualMethodsPtrUnchecked();
    107 }
    108 
    109 inline void Class::SetVirtualMethodsPtr(ArtMethod* new_virtual_methods) {
    110   // TODO: we reassign virtual methods to grow the table for miranda
    111   // methods.. they should really just be assigned once.
    112   SetField64<false>(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_),
    113                     reinterpret_cast<uint64_t>(new_virtual_methods));
    114 }
    115 
    116 template<VerifyObjectFlags kVerifyFlags>
    117 inline ArtMethod* Class::GetVirtualMethod(size_t i, size_t pointer_size) {
    118   CheckPointerSize(pointer_size);
    119   DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>())
    120       << PrettyClass(this) << " status=" << GetStatus();
    121   return GetVirtualMethodUnchecked(i, pointer_size);
    122 }
    123 
    124 inline ArtMethod* Class::GetVirtualMethodDuringLinking(size_t i, size_t pointer_size) {
    125   CheckPointerSize(pointer_size);
    126   DCHECK(IsLoaded() || IsErroneous());
    127   return GetVirtualMethodUnchecked(i, pointer_size);
    128 }
    129 
    130 inline ArtMethod* Class::GetVirtualMethodUnchecked(size_t i, size_t pointer_size) {
    131   CheckPointerSize(pointer_size);
    132   auto* methods = GetVirtualMethodsPtrUnchecked();
    133   DCHECK(methods != nullptr);
    134   return reinterpret_cast<ArtMethod*>(reinterpret_cast<uintptr_t>(methods) +
    135       ArtMethod::ObjectSize(pointer_size) * i);
    136 }
    137 
    138 inline PointerArray* Class::GetVTable() {
    139   DCHECK(IsResolved() || IsErroneous());
    140   return GetFieldObject<PointerArray>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_));
    141 }
    142 
    143 inline PointerArray* Class::GetVTableDuringLinking() {
    144   DCHECK(IsLoaded() || IsErroneous());
    145   return GetFieldObject<PointerArray>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_));
    146 }
    147 
    148 inline void Class::SetVTable(PointerArray* new_vtable) {
    149   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), new_vtable);
    150 }
    151 
    152 inline MemberOffset Class::EmbeddedImTableEntryOffset(uint32_t i, size_t pointer_size) {
    153   DCHECK_LT(i, kImtSize);
    154   return MemberOffset(
    155       EmbeddedImTableOffset(pointer_size).Uint32Value() + i * ImTableEntrySize(pointer_size));
    156 }
    157 
    158 inline ArtMethod* Class::GetEmbeddedImTableEntry(uint32_t i, size_t pointer_size) {
    159   DCHECK(ShouldHaveEmbeddedImtAndVTable());
    160   return GetFieldPtrWithSize<ArtMethod*>(
    161       EmbeddedImTableEntryOffset(i, pointer_size), pointer_size);
    162 }
    163 
    164 inline void Class::SetEmbeddedImTableEntry(uint32_t i, ArtMethod* method, size_t pointer_size) {
    165   DCHECK(ShouldHaveEmbeddedImtAndVTable());
    166   SetFieldPtrWithSize<false>(EmbeddedImTableEntryOffset(i, pointer_size), method, pointer_size);
    167 }
    168 
    169 inline bool Class::HasVTable() {
    170   return GetVTable() != nullptr || ShouldHaveEmbeddedImtAndVTable();
    171 }
    172 
    173 inline int32_t Class::GetVTableLength() {
    174   if (ShouldHaveEmbeddedImtAndVTable()) {
    175     return GetEmbeddedVTableLength();
    176   }
    177   return GetVTable() != nullptr ? GetVTable()->GetLength() : 0;
    178 }
    179 
    180 inline ArtMethod* Class::GetVTableEntry(uint32_t i, size_t pointer_size) {
    181   if (ShouldHaveEmbeddedImtAndVTable()) {
    182     return GetEmbeddedVTableEntry(i, pointer_size);
    183   }
    184   auto* vtable = GetVTable();
    185   DCHECK(vtable != nullptr);
    186   return vtable->GetElementPtrSize<ArtMethod*>(i, pointer_size);
    187 }
    188 
    189 inline int32_t Class::GetEmbeddedVTableLength() {
    190   return GetField32(MemberOffset(EmbeddedVTableLengthOffset()));
    191 }
    192 
    193 inline void Class::SetEmbeddedVTableLength(int32_t len) {
    194   SetField32<false>(MemberOffset(EmbeddedVTableLengthOffset()), len);
    195 }
    196 
    197 inline MemberOffset Class::EmbeddedVTableEntryOffset(uint32_t i, size_t pointer_size) {
    198   return MemberOffset(
    199       EmbeddedVTableOffset(pointer_size).Uint32Value() + i * VTableEntrySize(pointer_size));
    200 }
    201 
    202 inline ArtMethod* Class::GetEmbeddedVTableEntry(uint32_t i, size_t pointer_size) {
    203   return GetFieldPtrWithSize<ArtMethod*>(EmbeddedVTableEntryOffset(i, pointer_size), pointer_size);
    204 }
    205 
    206 inline void Class::SetEmbeddedVTableEntryUnchecked(
    207     uint32_t i, ArtMethod* method, size_t pointer_size) {
    208   SetFieldPtrWithSize<false>(EmbeddedVTableEntryOffset(i, pointer_size), method, pointer_size);
    209 }
    210 
    211 inline void Class::SetEmbeddedVTableEntry(uint32_t i, ArtMethod* method, size_t pointer_size) {
    212   auto* vtable = GetVTableDuringLinking();
    213   CHECK_EQ(method, vtable->GetElementPtrSize<ArtMethod*>(i, pointer_size));
    214   SetEmbeddedVTableEntryUnchecked(i, method, pointer_size);
    215 }
    216 
    217 inline bool Class::Implements(Class* klass) {
    218   DCHECK(klass != nullptr);
    219   DCHECK(klass->IsInterface()) << PrettyClass(this);
    220   // All interfaces implemented directly and by our superclass, and
    221   // recursively all super-interfaces of those interfaces, are listed
    222   // in iftable_, so we can just do a linear scan through that.
    223   int32_t iftable_count = GetIfTableCount();
    224   IfTable* iftable = GetIfTable();
    225   for (int32_t i = 0; i < iftable_count; i++) {
    226     if (iftable->GetInterface(i) == klass) {
    227       return true;
    228     }
    229   }
    230   return false;
    231 }
    232 
    233 // Determine whether "this" is assignable from "src", where both of these
    234 // are array classes.
    235 //
    236 // Consider an array class, e.g. Y[][], where Y is a subclass of X.
    237 //   Y[][]            = Y[][] --> true (identity)
    238 //   X[][]            = Y[][] --> true (element superclass)
    239 //   Y                = Y[][] --> false
    240 //   Y[]              = Y[][] --> false
    241 //   Object           = Y[][] --> true (everything is an object)
    242 //   Object[]         = Y[][] --> true
    243 //   Object[][]       = Y[][] --> true
    244 //   Object[][][]     = Y[][] --> false (too many []s)
    245 //   Serializable     = Y[][] --> true (all arrays are Serializable)
    246 //   Serializable[]   = Y[][] --> true
    247 //   Serializable[][] = Y[][] --> false (unless Y is Serializable)
    248 //
    249 // Don't forget about primitive types.
    250 //   Object[]         = int[] --> false
    251 //
    252 inline bool Class::IsArrayAssignableFromArray(Class* src) {
    253   DCHECK(IsArrayClass())  << PrettyClass(this);
    254   DCHECK(src->IsArrayClass()) << PrettyClass(src);
    255   return GetComponentType()->IsAssignableFrom(src->GetComponentType());
    256 }
    257 
    258 inline bool Class::IsAssignableFromArray(Class* src) {
    259   DCHECK(!IsInterface()) << PrettyClass(this);  // handled first in IsAssignableFrom
    260   DCHECK(src->IsArrayClass()) << PrettyClass(src);
    261   if (!IsArrayClass()) {
    262     // If "this" is not also an array, it must be Object.
    263     // src's super should be java_lang_Object, since it is an array.
    264     Class* java_lang_Object = src->GetSuperClass();
    265     DCHECK(java_lang_Object != nullptr) << PrettyClass(src);
    266     DCHECK(java_lang_Object->GetSuperClass() == nullptr) << PrettyClass(src);
    267     return this == java_lang_Object;
    268   }
    269   return IsArrayAssignableFromArray(src);
    270 }
    271 
    272 template <bool throw_on_failure, bool use_referrers_cache>
    273 inline bool Class::ResolvedFieldAccessTest(Class* access_to, ArtField* field,
    274                                            uint32_t field_idx, DexCache* dex_cache) {
    275   DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
    276   if (UNLIKELY(!this->CanAccess(access_to))) {
    277     // The referrer class can't access the field's declaring class but may still be able
    278     // to access the field if the FieldId specifies an accessible subclass of the declaring
    279     // class rather than the declaring class itself.
    280     DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
    281     uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_;
    282     // The referenced class has already been resolved with the field, get it from the dex cache.
    283     Class* dex_access_to = referrer_dex_cache->GetResolvedType(class_idx);
    284     DCHECK(dex_access_to != nullptr);
    285     if (UNLIKELY(!this->CanAccess(dex_access_to))) {
    286       if (throw_on_failure) {
    287         ThrowIllegalAccessErrorClass(this, dex_access_to);
    288       }
    289       return false;
    290     }
    291     DCHECK_EQ(this->CanAccessMember(access_to, field->GetAccessFlags()),
    292               this->CanAccessMember(dex_access_to, field->GetAccessFlags()));
    293   }
    294   if (LIKELY(this->CanAccessMember(access_to, field->GetAccessFlags()))) {
    295     return true;
    296   }
    297   if (throw_on_failure) {
    298     ThrowIllegalAccessErrorField(this, field);
    299   }
    300   return false;
    301 }
    302 
    303 template <bool throw_on_failure, bool use_referrers_cache, InvokeType throw_invoke_type>
    304 inline bool Class::ResolvedMethodAccessTest(Class* access_to, ArtMethod* method,
    305                                             uint32_t method_idx, DexCache* dex_cache) {
    306   static_assert(throw_on_failure || throw_invoke_type == kStatic, "Non-default throw invoke type");
    307   DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
    308   if (UNLIKELY(!this->CanAccess(access_to))) {
    309     // The referrer class can't access the method's declaring class but may still be able
    310     // to access the method if the MethodId specifies an accessible subclass of the declaring
    311     // class rather than the declaring class itself.
    312     DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
    313     uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_;
    314     // The referenced class has already been resolved with the method, get it from the dex cache.
    315     Class* dex_access_to = referrer_dex_cache->GetResolvedType(class_idx);
    316     DCHECK(dex_access_to != nullptr);
    317     if (UNLIKELY(!this->CanAccess(dex_access_to))) {
    318       if (throw_on_failure) {
    319         ThrowIllegalAccessErrorClassForMethodDispatch(this, dex_access_to,
    320                                                       method, throw_invoke_type);
    321       }
    322       return false;
    323     }
    324     DCHECK_EQ(this->CanAccessMember(access_to, method->GetAccessFlags()),
    325               this->CanAccessMember(dex_access_to, method->GetAccessFlags()));
    326   }
    327   if (LIKELY(this->CanAccessMember(access_to, method->GetAccessFlags()))) {
    328     return true;
    329   }
    330   if (throw_on_failure) {
    331     ThrowIllegalAccessErrorMethod(this, method);
    332   }
    333   return false;
    334 }
    335 
    336 inline bool Class::CanAccessResolvedField(Class* access_to, ArtField* field,
    337                                           DexCache* dex_cache, uint32_t field_idx) {
    338   return ResolvedFieldAccessTest<false, false>(access_to, field, field_idx, dex_cache);
    339 }
    340 
    341 inline bool Class::CheckResolvedFieldAccess(Class* access_to, ArtField* field,
    342                                             uint32_t field_idx) {
    343   return ResolvedFieldAccessTest<true, true>(access_to, field, field_idx, nullptr);
    344 }
    345 
    346 inline bool Class::CanAccessResolvedMethod(Class* access_to, ArtMethod* method,
    347                                            DexCache* dex_cache, uint32_t method_idx) {
    348   return ResolvedMethodAccessTest<false, false, kStatic>(access_to, method, method_idx, dex_cache);
    349 }
    350 
    351 template <InvokeType throw_invoke_type>
    352 inline bool Class::CheckResolvedMethodAccess(Class* access_to, ArtMethod* method,
    353                                              uint32_t method_idx) {
    354   return ResolvedMethodAccessTest<true, true, throw_invoke_type>(access_to, method, method_idx,
    355                                                                  nullptr);
    356 }
    357 
    358 inline bool Class::IsSubClass(Class* klass) {
    359   DCHECK(!IsInterface()) << PrettyClass(this);
    360   DCHECK(!IsArrayClass()) << PrettyClass(this);
    361   Class* current = this;
    362   do {
    363     if (current == klass) {
    364       return true;
    365     }
    366     current = current->GetSuperClass();
    367   } while (current != nullptr);
    368   return false;
    369 }
    370 
    371 inline ArtMethod* Class::FindVirtualMethodForInterface(ArtMethod* method, size_t pointer_size) {
    372   Class* declaring_class = method->GetDeclaringClass();
    373   DCHECK(declaring_class != nullptr) << PrettyClass(this);
    374   DCHECK(declaring_class->IsInterface()) << PrettyMethod(method);
    375   // TODO cache to improve lookup speed
    376   const int32_t iftable_count = GetIfTableCount();
    377   IfTable* iftable = GetIfTable();
    378   for (int32_t i = 0; i < iftable_count; i++) {
    379     if (iftable->GetInterface(i) == declaring_class) {
    380       return iftable->GetMethodArray(i)->GetElementPtrSize<ArtMethod*>(
    381           method->GetMethodIndex(), pointer_size);
    382     }
    383   }
    384   return nullptr;
    385 }
    386 
    387 inline ArtMethod* Class::FindVirtualMethodForVirtual(ArtMethod* method, size_t pointer_size) {
    388   DCHECK(!method->GetDeclaringClass()->IsInterface() || method->IsMiranda());
    389   // The argument method may from a super class.
    390   // Use the index to a potentially overridden one for this instance's class.
    391   return GetVTableEntry(method->GetMethodIndex(), pointer_size);
    392 }
    393 
    394 inline ArtMethod* Class::FindVirtualMethodForSuper(ArtMethod* method, size_t pointer_size) {
    395   DCHECK(!method->GetDeclaringClass()->IsInterface());
    396   return GetSuperClass()->GetVTableEntry(method->GetMethodIndex(), pointer_size);
    397 }
    398 
    399 inline ArtMethod* Class::FindVirtualMethodForVirtualOrInterface(ArtMethod* method,
    400                                                                 size_t pointer_size) {
    401   if (method->IsDirect()) {
    402     return method;
    403   }
    404   if (method->GetDeclaringClass()->IsInterface() && !method->IsMiranda()) {
    405     return FindVirtualMethodForInterface(method, pointer_size);
    406   }
    407   return FindVirtualMethodForVirtual(method, pointer_size);
    408 }
    409 
    410 inline IfTable* Class::GetIfTable() {
    411   return GetFieldObject<IfTable>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_));
    412 }
    413 
    414 inline int32_t Class::GetIfTableCount() {
    415   IfTable* iftable = GetIfTable();
    416   if (iftable == nullptr) {
    417     return 0;
    418   }
    419   return iftable->Count();
    420 }
    421 
    422 inline void Class::SetIfTable(IfTable* new_iftable) {
    423   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), new_iftable);
    424 }
    425 
    426 inline ArtField* Class::GetIFields() {
    427   DCHECK(IsLoaded() || IsErroneous());
    428   return GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
    429 }
    430 
    431 inline MemberOffset Class::GetFirstReferenceInstanceFieldOffset() {
    432   Class* super_class = GetSuperClass();
    433   return (super_class != nullptr)
    434       ? MemberOffset(RoundUp(super_class->GetObjectSize(),
    435                              sizeof(mirror::HeapReference<mirror::Object>)))
    436       : ClassOffset();
    437 }
    438 
    439 inline MemberOffset Class::GetFirstReferenceStaticFieldOffset(size_t pointer_size) {
    440   DCHECK(IsResolved());
    441   uint32_t base = sizeof(mirror::Class);  // Static fields come after the class.
    442   if (ShouldHaveEmbeddedImtAndVTable()) {
    443     // Static fields come after the embedded tables.
    444     base = mirror::Class::ComputeClassSize(
    445         true, GetEmbeddedVTableLength(), 0, 0, 0, 0, 0, pointer_size);
    446   }
    447   return MemberOffset(base);
    448 }
    449 
    450 inline MemberOffset Class::GetFirstReferenceStaticFieldOffsetDuringLinking(size_t pointer_size) {
    451   DCHECK(IsLoaded());
    452   uint32_t base = sizeof(mirror::Class);  // Static fields come after the class.
    453   if (ShouldHaveEmbeddedImtAndVTable()) {
    454     // Static fields come after the embedded tables.
    455     base = mirror::Class::ComputeClassSize(true, GetVTableDuringLinking()->GetLength(),
    456                                            0, 0, 0, 0, 0, pointer_size);
    457   }
    458   return MemberOffset(base);
    459 }
    460 
    461 inline void Class::SetIFields(ArtField* new_ifields) {
    462   DCHECK(GetIFieldsUnchecked() == nullptr);
    463   return SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
    464 }
    465 
    466 inline void Class::SetIFieldsUnchecked(ArtField* new_ifields) {
    467   SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
    468 }
    469 
    470 inline ArtField* Class::GetSFieldsUnchecked() {
    471   return GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
    472 }
    473 
    474 inline ArtField* Class::GetIFieldsUnchecked() {
    475   return GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
    476 }
    477 
    478 inline ArtField* Class::GetSFields() {
    479   DCHECK(IsLoaded() || IsErroneous()) << GetStatus();
    480   return GetSFieldsUnchecked();
    481 }
    482 
    483 inline void Class::SetSFields(ArtField* new_sfields) {
    484   DCHECK((IsRetired() && new_sfields == nullptr) ||
    485          GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_)) == nullptr);
    486   SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
    487 }
    488 
    489 inline void Class::SetSFieldsUnchecked(ArtField* new_sfields) {
    490   SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
    491 }
    492 
    493 inline ArtField* Class::GetStaticField(uint32_t i) {
    494   DCHECK_LT(i, NumStaticFields());
    495   return &GetSFields()[i];
    496 }
    497 
    498 inline ArtField* Class::GetInstanceField(uint32_t i) {
    499   DCHECK_LT(i, NumInstanceFields());
    500   return &GetIFields()[i];
    501 }
    502 
    503 template<VerifyObjectFlags kVerifyFlags>
    504 inline uint32_t Class::GetReferenceInstanceOffsets() {
    505   DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>());
    506   return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_));
    507 }
    508 
    509 inline void Class::SetClinitThreadId(pid_t new_clinit_thread_id) {
    510   if (Runtime::Current()->IsActiveTransaction()) {
    511     SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id);
    512   } else {
    513     SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id);
    514   }
    515 }
    516 
    517 inline void Class::SetVerifyErrorClass(Class* klass) {
    518   CHECK(klass != nullptr) << PrettyClass(this);
    519   if (Runtime::Current()->IsActiveTransaction()) {
    520     SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass);
    521   } else {
    522     SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass);
    523   }
    524 }
    525 
    526 template<VerifyObjectFlags kVerifyFlags>
    527 inline uint32_t Class::GetAccessFlags() {
    528   // Check class is loaded/retired or this is java.lang.String that has a
    529   // circularity issue during loading the names of its members
    530   DCHECK(IsIdxLoaded<kVerifyFlags>() || IsRetired<kVerifyFlags>() ||
    531          IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() ||
    532          this == String::GetJavaLangString())
    533       << "IsIdxLoaded=" << IsIdxLoaded<kVerifyFlags>()
    534       << " IsRetired=" << IsRetired<kVerifyFlags>()
    535       << " IsErroneous=" <<
    536           IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>()
    537       << " IsString=" << (this == String::GetJavaLangString())
    538       << " descriptor=" << PrettyDescriptor(this);
    539   return GetField32<kVerifyFlags>(AccessFlagsOffset());
    540 }
    541 
    542 inline String* Class::GetName() {
    543   return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(Class, name_));
    544 }
    545 inline void Class::SetName(String* name) {
    546   if (Runtime::Current()->IsActiveTransaction()) {
    547     SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name);
    548   } else {
    549     SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name);
    550   }
    551 }
    552 
    553 template<VerifyObjectFlags kVerifyFlags>
    554 inline Primitive::Type Class::GetPrimitiveType() {
    555   DCHECK_EQ(sizeof(Primitive::Type), sizeof(int32_t));
    556   int32_t v32 = GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_));
    557   Primitive::Type type = static_cast<Primitive::Type>(v32 & 0xFFFF);
    558   DCHECK_EQ(static_cast<size_t>(v32 >> 16), Primitive::ComponentSizeShift(type));
    559   return type;
    560 }
    561 
    562 template<VerifyObjectFlags kVerifyFlags>
    563 inline size_t Class::GetPrimitiveTypeSizeShift() {
    564   DCHECK_EQ(sizeof(Primitive::Type), sizeof(int32_t));
    565   int32_t v32 = GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_));
    566   size_t size_shift = static_cast<Primitive::Type>(v32 >> 16);
    567   DCHECK_EQ(size_shift, Primitive::ComponentSizeShift(static_cast<Primitive::Type>(v32 & 0xFFFF)));
    568   return size_shift;
    569 }
    570 
    571 inline void Class::CheckObjectAlloc() {
    572   DCHECK(!IsArrayClass())
    573       << PrettyClass(this)
    574       << "A array shouldn't be allocated through this "
    575       << "as it requires a pre-fence visitor that sets the class size.";
    576   DCHECK(!IsClassClass())
    577       << PrettyClass(this)
    578       << "A class object shouldn't be allocated through this "
    579       << "as it requires a pre-fence visitor that sets the class size.";
    580   DCHECK(!IsStringClass())
    581       << PrettyClass(this)
    582       << "A string shouldn't be allocated through this "
    583       << "as it requires a pre-fence visitor that sets the class size.";
    584   DCHECK(IsInstantiable()) << PrettyClass(this);
    585   // TODO: decide whether we want this check. It currently fails during bootstrap.
    586   // DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass(this);
    587   DCHECK_GE(this->object_size_, sizeof(Object));
    588 }
    589 
    590 template<bool kIsInstrumented, bool kCheckAddFinalizer>
    591 inline Object* Class::Alloc(Thread* self, gc::AllocatorType allocator_type) {
    592   CheckObjectAlloc();
    593   gc::Heap* heap = Runtime::Current()->GetHeap();
    594   const bool add_finalizer = kCheckAddFinalizer && IsFinalizable();
    595   if (!kCheckAddFinalizer) {
    596     DCHECK(!IsFinalizable());
    597   }
    598   mirror::Object* obj =
    599       heap->AllocObjectWithAllocator<kIsInstrumented, false>(self, this, this->object_size_,
    600                                                              allocator_type, VoidFunctor());
    601   if (add_finalizer && LIKELY(obj != nullptr)) {
    602     heap->AddFinalizerReference(self, &obj);
    603     if (UNLIKELY(self->IsExceptionPending())) {
    604       // Failed to allocate finalizer reference, it means that the whole allocation failed.
    605       obj = nullptr;
    606     }
    607   }
    608   return obj;
    609 }
    610 
    611 inline Object* Class::AllocObject(Thread* self) {
    612   return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentAllocator());
    613 }
    614 
    615 inline Object* Class::AllocNonMovableObject(Thread* self) {
    616   return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentNonMovingAllocator());
    617 }
    618 
    619 inline uint32_t Class::ComputeClassSize(bool has_embedded_tables,
    620                                         uint32_t num_vtable_entries,
    621                                         uint32_t num_8bit_static_fields,
    622                                         uint32_t num_16bit_static_fields,
    623                                         uint32_t num_32bit_static_fields,
    624                                         uint32_t num_64bit_static_fields,
    625                                         uint32_t num_ref_static_fields,
    626                                         size_t pointer_size) {
    627   // Space used by java.lang.Class and its instance fields.
    628   uint32_t size = sizeof(Class);
    629   // Space used by embedded tables.
    630   if (has_embedded_tables) {
    631     const uint32_t embedded_imt_size = kImtSize * ImTableEntrySize(pointer_size);
    632     const uint32_t embedded_vtable_size = num_vtable_entries * VTableEntrySize(pointer_size);
    633     size = RoundUp(size + sizeof(uint32_t) /* embedded vtable len */, pointer_size) +
    634         embedded_imt_size + embedded_vtable_size;
    635   }
    636 
    637   // Space used by reference statics.
    638   size += num_ref_static_fields * sizeof(HeapReference<Object>);
    639   if (!IsAligned<8>(size) && num_64bit_static_fields > 0) {
    640     uint32_t gap = 8 - (size & 0x7);
    641     size += gap;  // will be padded
    642     // Shuffle 4-byte fields forward.
    643     while (gap >= sizeof(uint32_t) && num_32bit_static_fields != 0) {
    644       --num_32bit_static_fields;
    645       gap -= sizeof(uint32_t);
    646     }
    647     // Shuffle 2-byte fields forward.
    648     while (gap >= sizeof(uint16_t) && num_16bit_static_fields != 0) {
    649       --num_16bit_static_fields;
    650       gap -= sizeof(uint16_t);
    651     }
    652     // Shuffle byte fields forward.
    653     while (gap >= sizeof(uint8_t) && num_8bit_static_fields != 0) {
    654       --num_8bit_static_fields;
    655       gap -= sizeof(uint8_t);
    656     }
    657   }
    658   // Guaranteed to be at least 4 byte aligned. No need for further alignments.
    659   // Space used for primitive static fields.
    660   size += num_8bit_static_fields * sizeof(uint8_t) + num_16bit_static_fields * sizeof(uint16_t) +
    661       num_32bit_static_fields * sizeof(uint32_t) + num_64bit_static_fields * sizeof(uint64_t);
    662   return size;
    663 }
    664 
    665 template <bool kVisitClass, typename Visitor>
    666 inline void Class::VisitReferences(mirror::Class* klass, const Visitor& visitor) {
    667   VisitInstanceFieldsReferences<kVisitClass>(klass, visitor);
    668   // Right after a class is allocated, but not yet loaded
    669   // (kStatusNotReady, see ClassLinkder::LoadClass()), GC may find it
    670   // and scan it. IsTemp() may call Class::GetAccessFlags() but may
    671   // fail in the DCHECK in Class::GetAccessFlags() because the class
    672   // status is kStatusNotReady. To avoid it, rely on IsResolved()
    673   // only. This is fine because a temp class never goes into the
    674   // kStatusResolved state.
    675   if (IsResolved()) {
    676     // Temp classes don't ever populate imt/vtable or static fields and they are not even
    677     // allocated with the right size for those. Also, unresolved classes don't have fields
    678     // linked yet.
    679     VisitStaticFieldsReferences<kVisitClass>(this, visitor);
    680   }
    681 }
    682 
    683 template<ReadBarrierOption kReadBarrierOption>
    684 inline bool Class::IsReferenceClass() const {
    685   return this == Reference::GetJavaLangRefReference<kReadBarrierOption>();
    686 }
    687 
    688 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
    689 inline bool Class::IsClassClass() {
    690   Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
    691       template GetClass<kVerifyFlags, kReadBarrierOption>();
    692   return this == java_lang_Class;
    693 }
    694 
    695 inline const DexFile& Class::GetDexFile() {
    696   return *GetDexCache()->GetDexFile();
    697 }
    698 
    699 inline bool Class::DescriptorEquals(const char* match) {
    700   if (IsArrayClass()) {
    701     return match[0] == '[' && GetComponentType()->DescriptorEquals(match + 1);
    702   } else if (IsPrimitive()) {
    703     return strcmp(Primitive::Descriptor(GetPrimitiveType()), match) == 0;
    704   } else if (IsProxyClass()) {
    705     return ProxyDescriptorEquals(match);
    706   } else {
    707     const DexFile& dex_file = GetDexFile();
    708     const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
    709     return strcmp(dex_file.GetTypeDescriptor(type_id), match) == 0;
    710   }
    711 }
    712 
    713 inline void Class::AssertInitializedOrInitializingInThread(Thread* self) {
    714   if (kIsDebugBuild && !IsInitialized()) {
    715     CHECK(IsInitializing()) << PrettyClass(this) << " is not initializing: " << GetStatus();
    716     CHECK_EQ(GetClinitThreadId(), self->GetTid()) << PrettyClass(this)
    717                                                   << " is initializing in a different thread";
    718   }
    719 }
    720 
    721 inline ObjectArray<Class>* Class::GetInterfaces() {
    722   CHECK(IsProxyClass());
    723   // First static field.
    724   auto* field = GetStaticField(0);
    725   DCHECK_STREQ(field->GetName(), "interfaces");
    726   MemberOffset field_offset = field->GetOffset();
    727   return GetFieldObject<ObjectArray<Class>>(field_offset);
    728 }
    729 
    730 inline ObjectArray<ObjectArray<Class>>* Class::GetThrows() {
    731   CHECK(IsProxyClass());
    732   // Second static field.
    733   auto* field = GetStaticField(1);
    734   DCHECK_STREQ(field->GetName(), "throws");
    735   MemberOffset field_offset = field->GetOffset();
    736   return GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset);
    737 }
    738 
    739 inline MemberOffset Class::GetDisableIntrinsicFlagOffset() {
    740   CHECK(IsReferenceClass());
    741   // First static field
    742   auto* field = GetStaticField(0);
    743   DCHECK_STREQ(field->GetName(), "disableIntrinsic");
    744   return field->GetOffset();
    745 }
    746 
    747 inline MemberOffset Class::GetSlowPathFlagOffset() {
    748   CHECK(IsReferenceClass());
    749   // Second static field
    750   auto* field = GetStaticField(1);
    751   DCHECK_STREQ(field->GetName(), "slowPathEnabled");
    752   return field->GetOffset();
    753 }
    754 
    755 inline bool Class::GetSlowPathEnabled() {
    756   return GetFieldBoolean(GetSlowPathFlagOffset());
    757 }
    758 
    759 inline void Class::SetSlowPath(bool enabled) {
    760   SetFieldBoolean<false, false>(GetSlowPathFlagOffset(), enabled);
    761 }
    762 
    763 inline void Class::InitializeClassVisitor::operator()(
    764     mirror::Object* obj, size_t usable_size) const {
    765   DCHECK_LE(class_size_, usable_size);
    766   // Avoid AsClass as object is not yet in live bitmap or allocation stack.
    767   mirror::Class* klass = down_cast<mirror::Class*>(obj);
    768   // DCHECK(klass->IsClass());
    769   klass->SetClassSize(class_size_);
    770   klass->SetPrimitiveType(Primitive::kPrimNot);  // Default to not being primitive.
    771   klass->SetDexClassDefIndex(DexFile::kDexNoIndex16);  // Default to no valid class def index.
    772   klass->SetDexTypeIndex(DexFile::kDexNoIndex16);  // Default to no valid type index.
    773 }
    774 
    775 inline void Class::SetAccessFlags(uint32_t new_access_flags) {
    776   // Called inside a transaction when setting pre-verified flag during boot image compilation.
    777   if (Runtime::Current()->IsActiveTransaction()) {
    778     SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), new_access_flags);
    779   } else {
    780     SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), new_access_flags);
    781   }
    782 }
    783 
    784 inline uint32_t Class::NumDirectInterfaces() {
    785   if (IsPrimitive()) {
    786     return 0;
    787   } else if (IsArrayClass()) {
    788     return 2;
    789   } else if (IsProxyClass()) {
    790     mirror::ObjectArray<mirror::Class>* interfaces = GetInterfaces();
    791     return interfaces != nullptr ? interfaces->GetLength() : 0;
    792   } else {
    793     const DexFile::TypeList* interfaces = GetInterfaceTypeList();
    794     if (interfaces == nullptr) {
    795       return 0;
    796     } else {
    797       return interfaces->Size();
    798     }
    799   }
    800 }
    801 
    802 inline void Class::SetDexCacheStrings(ObjectArray<String>* new_dex_cache_strings) {
    803   SetFieldObject<false>(DexCacheStringsOffset(), new_dex_cache_strings);
    804 }
    805 
    806 inline ObjectArray<String>* Class::GetDexCacheStrings() {
    807   return GetFieldObject<ObjectArray<String>>(DexCacheStringsOffset());
    808 }
    809 
    810 template<class Visitor>
    811 void mirror::Class::VisitNativeRoots(Visitor& visitor, size_t pointer_size) {
    812   ArtField* const sfields = GetSFieldsUnchecked();
    813   // Since we visit class roots while we may be writing these fields, check against null.
    814   if (sfields != nullptr) {
    815     for (size_t i = 0, count = NumStaticFields(); i < count; ++i) {
    816       auto* f = &sfields[i];
    817       if (kIsDebugBuild && IsResolved()) {
    818         CHECK_EQ(f->GetDeclaringClass(), this) << GetStatus();
    819       }
    820       f->VisitRoots(visitor);
    821     }
    822   }
    823   ArtField* const ifields = GetIFieldsUnchecked();
    824   if (ifields != nullptr) {
    825     for (size_t i = 0, count = NumInstanceFields(); i < count; ++i) {
    826       auto* f = &ifields[i];
    827       if (kIsDebugBuild && IsResolved()) {
    828         CHECK_EQ(f->GetDeclaringClass(), this) << GetStatus();
    829       }
    830       f->VisitRoots(visitor);
    831     }
    832   }
    833   for (auto& m : GetDirectMethods(pointer_size)) {
    834     m.VisitRoots(visitor);
    835   }
    836   for (auto& m : GetVirtualMethods(pointer_size)) {
    837     m.VisitRoots(visitor);
    838   }
    839 }
    840 
    841 inline StrideIterator<ArtMethod> Class::DirectMethodsBegin(size_t pointer_size)  {
    842   CheckPointerSize(pointer_size);
    843   auto* methods = GetDirectMethodsPtrUnchecked();
    844   auto stride = ArtMethod::ObjectSize(pointer_size);
    845   return StrideIterator<ArtMethod>(reinterpret_cast<uintptr_t>(methods), stride);
    846 }
    847 
    848 inline StrideIterator<ArtMethod> Class::DirectMethodsEnd(size_t pointer_size) {
    849   CheckPointerSize(pointer_size);
    850   auto* methods = GetDirectMethodsPtrUnchecked();
    851   auto stride = ArtMethod::ObjectSize(pointer_size);
    852   auto count = NumDirectMethods();
    853   return StrideIterator<ArtMethod>(reinterpret_cast<uintptr_t>(methods) + stride * count, stride);
    854 }
    855 
    856 inline IterationRange<StrideIterator<ArtMethod>> Class::GetDirectMethods(size_t pointer_size) {
    857   CheckPointerSize(pointer_size);
    858   return MakeIterationRange(DirectMethodsBegin(pointer_size), DirectMethodsEnd(pointer_size));
    859 }
    860 
    861 inline StrideIterator<ArtMethod> Class::VirtualMethodsBegin(size_t pointer_size)  {
    862   CheckPointerSize(pointer_size);
    863   auto* methods = GetVirtualMethodsPtrUnchecked();
    864   auto stride = ArtMethod::ObjectSize(pointer_size);
    865   return StrideIterator<ArtMethod>(reinterpret_cast<uintptr_t>(methods), stride);
    866 }
    867 
    868 inline StrideIterator<ArtMethod> Class::VirtualMethodsEnd(size_t pointer_size) {
    869   CheckPointerSize(pointer_size);
    870   auto* methods = GetVirtualMethodsPtrUnchecked();
    871   auto stride = ArtMethod::ObjectSize(pointer_size);
    872   auto count = NumVirtualMethods();
    873   return StrideIterator<ArtMethod>(reinterpret_cast<uintptr_t>(methods) + stride * count, stride);
    874 }
    875 
    876 inline IterationRange<StrideIterator<ArtMethod>> Class::GetVirtualMethods(size_t pointer_size) {
    877   return MakeIterationRange(VirtualMethodsBegin(pointer_size), VirtualMethodsEnd(pointer_size));
    878 }
    879 
    880 inline MemberOffset Class::EmbeddedImTableOffset(size_t pointer_size) {
    881   CheckPointerSize(pointer_size);
    882   // Round up since we want the embedded imt and vtable to be pointer size aligned in case 64 bits.
    883   // Add 32 bits for embedded vtable length.
    884   return MemberOffset(
    885       RoundUp(EmbeddedVTableLengthOffset().Uint32Value() + sizeof(uint32_t), pointer_size));
    886 }
    887 
    888 inline MemberOffset Class::EmbeddedVTableOffset(size_t pointer_size) {
    889   CheckPointerSize(pointer_size);
    890   return MemberOffset(EmbeddedImTableOffset(pointer_size).Uint32Value() +
    891                       kImtSize * ImTableEntrySize(pointer_size));
    892 }
    893 
    894 inline void Class::CheckPointerSize(size_t pointer_size) {
    895   DCHECK(ValidPointerSize(pointer_size)) << pointer_size;
    896   DCHECK_EQ(pointer_size, Runtime::Current()->GetClassLinker()->GetImagePointerSize());
    897 }
    898 
    899 }  // namespace mirror
    900 }  // namespace art
    901 
    902 #endif  // ART_RUNTIME_MIRROR_CLASS_INL_H_
    903