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.h"
     23 #include "art_method.h"
     24 #include "base/array_slice.h"
     25 #include "base/length_prefixed_array.h"
     26 #include "base/utils.h"
     27 #include "class_linker.h"
     28 #include "class_loader.h"
     29 #include "common_throws.h"
     30 #include "dex/dex_file-inl.h"
     31 #include "dex/invoke_type.h"
     32 #include "dex_cache.h"
     33 #include "gc/heap-inl.h"
     34 #include "iftable.h"
     35 #include "subtype_check.h"
     36 #include "object-inl.h"
     37 #include "object_array.h"
     38 #include "read_barrier-inl.h"
     39 #include "reference-inl.h"
     40 #include "runtime.h"
     41 #include "string.h"
     42 
     43 namespace art {
     44 namespace mirror {
     45 
     46 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
     47 inline uint32_t Class::GetObjectSize() {
     48   // Note: Extra parentheses to avoid the comma being interpreted as macro parameter separator.
     49   DCHECK((!IsVariableSize<kVerifyFlags, kReadBarrierOption>())) << "class=" << PrettyTypeOf();
     50   return GetField32(ObjectSizeOffset());
     51 }
     52 
     53 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
     54 inline uint32_t Class::GetObjectSizeAllocFastPath() {
     55   // Note: Extra parentheses to avoid the comma being interpreted as macro parameter separator.
     56   DCHECK((!IsVariableSize<kVerifyFlags, kReadBarrierOption>())) << "class=" << PrettyTypeOf();
     57   return GetField32(ObjectSizeAllocFastPathOffset());
     58 }
     59 
     60 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
     61 inline Class* Class::GetSuperClass() {
     62   // Can only get super class for loaded classes (hack for when runtime is
     63   // initializing)
     64   DCHECK(IsLoaded<kVerifyFlags>() ||
     65          IsErroneous<kVerifyFlags>() ||
     66          !Runtime::Current()->IsStarted()) << IsLoaded();
     67   return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(
     68       OFFSET_OF_OBJECT_MEMBER(Class, super_class_));
     69 }
     70 
     71 inline void Class::SetSuperClass(ObjPtr<Class> new_super_class) {
     72   // Super class is assigned once, except during class linker initialization.
     73   if (kIsDebugBuild) {
     74     ObjPtr<Class> old_super_class =
     75         GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_));
     76     DCHECK(old_super_class == nullptr || old_super_class == new_super_class);
     77   }
     78   DCHECK(new_super_class != nullptr);
     79   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_), new_super_class);
     80 }
     81 
     82 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
     83 inline ClassLoader* Class::GetClassLoader() {
     84   return GetFieldObject<ClassLoader, kVerifyFlags, kReadBarrierOption>(
     85       OFFSET_OF_OBJECT_MEMBER(Class, class_loader_));
     86 }
     87 
     88 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
     89 inline ClassExt* Class::GetExtData() {
     90   return GetFieldObject<ClassExt, kVerifyFlags, kReadBarrierOption>(
     91       OFFSET_OF_OBJECT_MEMBER(Class, ext_data_));
     92 }
     93 
     94 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
     95 inline DexCache* Class::GetDexCache() {
     96   return GetFieldObject<DexCache, kVerifyFlags, kReadBarrierOption>(
     97       OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_));
     98 }
     99 
    100 inline uint32_t Class::GetCopiedMethodsStartOffset() {
    101   // Object::GetFieldShort returns an int16_t value, but
    102   // Class::copied_methods_offset_ is an uint16_t value; cast the
    103   // latter to uint16_t before returning it as an uint32_t value, so
    104   // that uint16_t values between 2^15 and 2^16-1 are correctly
    105   // handled.
    106   return static_cast<uint16_t>(
    107       GetFieldShort(OFFSET_OF_OBJECT_MEMBER(Class, copied_methods_offset_)));
    108 }
    109 
    110 inline uint32_t Class::GetDirectMethodsStartOffset() {
    111   return 0;
    112 }
    113 
    114 inline uint32_t Class::GetVirtualMethodsStartOffset() {
    115   // Object::GetFieldShort returns an int16_t value, but
    116   // Class::virtual_method_offset_ is an uint16_t value; cast the
    117   // latter to uint16_t before returning it as an uint32_t value, so
    118   // that uint16_t values between 2^15 and 2^16-1 are correctly
    119   // handled.
    120   return static_cast<uint16_t>(
    121       GetFieldShort(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_offset_)));
    122 }
    123 
    124 template<VerifyObjectFlags kVerifyFlags>
    125 inline ArraySlice<ArtMethod> Class::GetDirectMethodsSlice(PointerSize pointer_size) {
    126   DCHECK(IsLoaded() || IsErroneous());
    127   return GetDirectMethodsSliceUnchecked(pointer_size);
    128 }
    129 
    130 inline ArraySlice<ArtMethod> Class::GetDirectMethodsSliceUnchecked(PointerSize pointer_size) {
    131   return GetMethodsSliceRangeUnchecked(GetMethodsPtr(),
    132                                        pointer_size,
    133                                        GetDirectMethodsStartOffset(),
    134                                        GetVirtualMethodsStartOffset());
    135 }
    136 
    137 template<VerifyObjectFlags kVerifyFlags>
    138 inline ArraySlice<ArtMethod> Class::GetDeclaredMethodsSlice(PointerSize pointer_size) {
    139   DCHECK(IsLoaded() || IsErroneous());
    140   return GetDeclaredMethodsSliceUnchecked(pointer_size);
    141 }
    142 
    143 inline ArraySlice<ArtMethod> Class::GetDeclaredMethodsSliceUnchecked(PointerSize pointer_size) {
    144   return GetMethodsSliceRangeUnchecked(GetMethodsPtr(),
    145                                        pointer_size,
    146                                        GetDirectMethodsStartOffset(),
    147                                        GetCopiedMethodsStartOffset());
    148 }
    149 template<VerifyObjectFlags kVerifyFlags>
    150 inline ArraySlice<ArtMethod> Class::GetDeclaredVirtualMethodsSlice(PointerSize pointer_size) {
    151   DCHECK(IsLoaded() || IsErroneous());
    152   return GetDeclaredVirtualMethodsSliceUnchecked(pointer_size);
    153 }
    154 
    155 inline ArraySlice<ArtMethod> Class::GetDeclaredVirtualMethodsSliceUnchecked(
    156     PointerSize pointer_size) {
    157   return GetMethodsSliceRangeUnchecked(GetMethodsPtr(),
    158                                        pointer_size,
    159                                        GetVirtualMethodsStartOffset(),
    160                                        GetCopiedMethodsStartOffset());
    161 }
    162 
    163 template<VerifyObjectFlags kVerifyFlags>
    164 inline ArraySlice<ArtMethod> Class::GetVirtualMethodsSlice(PointerSize pointer_size) {
    165   DCHECK(IsLoaded() || IsErroneous());
    166   return GetVirtualMethodsSliceUnchecked(pointer_size);
    167 }
    168 
    169 inline ArraySlice<ArtMethod> Class::GetVirtualMethodsSliceUnchecked(PointerSize pointer_size) {
    170   LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
    171   return GetMethodsSliceRangeUnchecked(methods,
    172                                        pointer_size,
    173                                        GetVirtualMethodsStartOffset(),
    174                                        NumMethods(methods));
    175 }
    176 
    177 template<VerifyObjectFlags kVerifyFlags>
    178 inline ArraySlice<ArtMethod> Class::GetCopiedMethodsSlice(PointerSize pointer_size) {
    179   DCHECK(IsLoaded() || IsErroneous());
    180   return GetCopiedMethodsSliceUnchecked(pointer_size);
    181 }
    182 
    183 inline ArraySlice<ArtMethod> Class::GetCopiedMethodsSliceUnchecked(PointerSize pointer_size) {
    184   LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
    185   return GetMethodsSliceRangeUnchecked(methods,
    186                                        pointer_size,
    187                                        GetCopiedMethodsStartOffset(),
    188                                        NumMethods(methods));
    189 }
    190 
    191 inline LengthPrefixedArray<ArtMethod>* Class::GetMethodsPtr() {
    192   return reinterpret_cast<LengthPrefixedArray<ArtMethod>*>(
    193       static_cast<uintptr_t>(GetField64(OFFSET_OF_OBJECT_MEMBER(Class, methods_))));
    194 }
    195 
    196 template<VerifyObjectFlags kVerifyFlags>
    197 inline ArraySlice<ArtMethod> Class::GetMethodsSlice(PointerSize pointer_size) {
    198   DCHECK(IsLoaded() || IsErroneous());
    199   LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
    200   return GetMethodsSliceRangeUnchecked(methods, pointer_size, 0, NumMethods(methods));
    201 }
    202 
    203 inline ArraySlice<ArtMethod> Class::GetMethodsSliceRangeUnchecked(
    204     LengthPrefixedArray<ArtMethod>* methods,
    205     PointerSize pointer_size,
    206     uint32_t start_offset,
    207     uint32_t end_offset) {
    208   DCHECK_LE(start_offset, end_offset);
    209   DCHECK_LE(end_offset, NumMethods(methods));
    210   uint32_t size = end_offset - start_offset;
    211   if (size == 0u) {
    212     return ArraySlice<ArtMethod>();
    213   }
    214   DCHECK(methods != nullptr);
    215   DCHECK_LE(end_offset, methods->size());
    216   size_t method_size = ArtMethod::Size(pointer_size);
    217   size_t method_alignment = ArtMethod::Alignment(pointer_size);
    218   ArraySlice<ArtMethod> slice(&methods->At(0u, method_size, method_alignment),
    219                               methods->size(),
    220                               method_size);
    221   return slice.SubArray(start_offset, size);
    222 }
    223 
    224 inline uint32_t Class::NumMethods() {
    225   return NumMethods(GetMethodsPtr());
    226 }
    227 
    228 inline uint32_t Class::NumMethods(LengthPrefixedArray<ArtMethod>* methods) {
    229   return (methods == nullptr) ? 0 : methods->size();
    230 }
    231 
    232 inline ArtMethod* Class::GetDirectMethodUnchecked(size_t i, PointerSize pointer_size) {
    233   CheckPointerSize(pointer_size);
    234   return &GetDirectMethodsSliceUnchecked(pointer_size)[i];
    235 }
    236 
    237 inline ArtMethod* Class::GetDirectMethod(size_t i, PointerSize pointer_size) {
    238   CheckPointerSize(pointer_size);
    239   return &GetDirectMethodsSlice(pointer_size)[i];
    240 }
    241 
    242 inline void Class::SetMethodsPtr(LengthPrefixedArray<ArtMethod>* new_methods,
    243                                  uint32_t num_direct,
    244                                  uint32_t num_virtual) {
    245   DCHECK(GetMethodsPtr() == nullptr);
    246   SetMethodsPtrUnchecked(new_methods, num_direct, num_virtual);
    247 }
    248 
    249 
    250 inline void Class::SetMethodsPtrUnchecked(LengthPrefixedArray<ArtMethod>* new_methods,
    251                                           uint32_t num_direct,
    252                                           uint32_t num_virtual) {
    253   DCHECK_LE(num_direct + num_virtual, (new_methods == nullptr) ? 0 : new_methods->size());
    254   SetMethodsPtrInternal(new_methods);
    255   SetFieldShort<false>(OFFSET_OF_OBJECT_MEMBER(Class, copied_methods_offset_),
    256                     dchecked_integral_cast<uint16_t>(num_direct + num_virtual));
    257   SetFieldShort<false>(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_offset_),
    258                        dchecked_integral_cast<uint16_t>(num_direct));
    259 }
    260 
    261 inline void Class::SetMethodsPtrInternal(LengthPrefixedArray<ArtMethod>* new_methods) {
    262   SetField64<false>(OFFSET_OF_OBJECT_MEMBER(Class, methods_),
    263                     static_cast<uint64_t>(reinterpret_cast<uintptr_t>(new_methods)));
    264 }
    265 
    266 template<VerifyObjectFlags kVerifyFlags>
    267 inline ArtMethod* Class::GetVirtualMethod(size_t i, PointerSize pointer_size) {
    268   CheckPointerSize(pointer_size);
    269   DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>())
    270       << Class::PrettyClass() << " status=" << GetStatus();
    271   return GetVirtualMethodUnchecked(i, pointer_size);
    272 }
    273 
    274 inline ArtMethod* Class::GetVirtualMethodDuringLinking(size_t i, PointerSize pointer_size) {
    275   CheckPointerSize(pointer_size);
    276   DCHECK(IsLoaded() || IsErroneous());
    277   return GetVirtualMethodUnchecked(i, pointer_size);
    278 }
    279 
    280 inline ArtMethod* Class::GetVirtualMethodUnchecked(size_t i, PointerSize pointer_size) {
    281   CheckPointerSize(pointer_size);
    282   return &GetVirtualMethodsSliceUnchecked(pointer_size)[i];
    283 }
    284 
    285 template<VerifyObjectFlags kVerifyFlags,
    286          ReadBarrierOption kReadBarrierOption>
    287 inline PointerArray* Class::GetVTable() {
    288   DCHECK(IsLoaded<kVerifyFlags>() || IsErroneous<kVerifyFlags>());
    289   return GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(
    290       OFFSET_OF_OBJECT_MEMBER(Class, vtable_));
    291 }
    292 
    293 inline PointerArray* Class::GetVTableDuringLinking() {
    294   DCHECK(IsLoaded() || IsErroneous());
    295   return GetFieldObject<PointerArray>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_));
    296 }
    297 
    298 inline void Class::SetVTable(PointerArray* new_vtable) {
    299   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), new_vtable);
    300 }
    301 
    302 inline bool Class::HasVTable() {
    303   return GetVTable() != nullptr || ShouldHaveEmbeddedVTable();
    304 }
    305 
    306   template<VerifyObjectFlags kVerifyFlags,
    307            ReadBarrierOption kReadBarrierOption>
    308 inline int32_t Class::GetVTableLength() {
    309   if (ShouldHaveEmbeddedVTable<kVerifyFlags, kReadBarrierOption>()) {
    310     return GetEmbeddedVTableLength();
    311   }
    312   return GetVTable<kVerifyFlags, kReadBarrierOption>() != nullptr ?
    313       GetVTable<kVerifyFlags, kReadBarrierOption>()->GetLength() : 0;
    314 }
    315 
    316   template<VerifyObjectFlags kVerifyFlags,
    317            ReadBarrierOption kReadBarrierOption>
    318 inline ArtMethod* Class::GetVTableEntry(uint32_t i, PointerSize pointer_size) {
    319   if (ShouldHaveEmbeddedVTable<kVerifyFlags, kReadBarrierOption>()) {
    320     return GetEmbeddedVTableEntry(i, pointer_size);
    321   }
    322   auto* vtable = GetVTable<kVerifyFlags, kReadBarrierOption>();
    323   DCHECK(vtable != nullptr);
    324   return vtable->template GetElementPtrSize<ArtMethod*, kVerifyFlags, kReadBarrierOption>(i, pointer_size);
    325 }
    326 
    327 inline int32_t Class::GetEmbeddedVTableLength() {
    328   return GetField32(MemberOffset(EmbeddedVTableLengthOffset()));
    329 }
    330 
    331 inline void Class::SetEmbeddedVTableLength(int32_t len) {
    332   SetField32<false>(MemberOffset(EmbeddedVTableLengthOffset()), len);
    333 }
    334 
    335 inline ImTable* Class::GetImt(PointerSize pointer_size) {
    336   return GetFieldPtrWithSize<ImTable*>(MemberOffset(ImtPtrOffset(pointer_size)), pointer_size);
    337 }
    338 
    339 inline void Class::SetImt(ImTable* imt, PointerSize pointer_size) {
    340   return SetFieldPtrWithSize<false>(MemberOffset(ImtPtrOffset(pointer_size)), imt, pointer_size);
    341 }
    342 
    343 inline MemberOffset Class::EmbeddedVTableEntryOffset(uint32_t i, PointerSize pointer_size) {
    344   return MemberOffset(
    345       EmbeddedVTableOffset(pointer_size).Uint32Value() + i * VTableEntrySize(pointer_size));
    346 }
    347 
    348 inline ArtMethod* Class::GetEmbeddedVTableEntry(uint32_t i, PointerSize pointer_size) {
    349   return GetFieldPtrWithSize<ArtMethod*>(EmbeddedVTableEntryOffset(i, pointer_size), pointer_size);
    350 }
    351 
    352 inline void Class::SetEmbeddedVTableEntryUnchecked(
    353     uint32_t i, ArtMethod* method, PointerSize pointer_size) {
    354   SetFieldPtrWithSize<false>(EmbeddedVTableEntryOffset(i, pointer_size), method, pointer_size);
    355 }
    356 
    357 inline void Class::SetEmbeddedVTableEntry(uint32_t i, ArtMethod* method, PointerSize pointer_size) {
    358   auto* vtable = GetVTableDuringLinking();
    359   CHECK_EQ(method, vtable->GetElementPtrSize<ArtMethod*>(i, pointer_size));
    360   SetEmbeddedVTableEntryUnchecked(i, method, pointer_size);
    361 }
    362 
    363 inline bool Class::Implements(ObjPtr<Class> klass) {
    364   DCHECK(klass != nullptr);
    365   DCHECK(klass->IsInterface()) << PrettyClass();
    366   // All interfaces implemented directly and by our superclass, and
    367   // recursively all super-interfaces of those interfaces, are listed
    368   // in iftable_, so we can just do a linear scan through that.
    369   int32_t iftable_count = GetIfTableCount();
    370   ObjPtr<IfTable> iftable = GetIfTable();
    371   for (int32_t i = 0; i < iftable_count; i++) {
    372     if (iftable->GetInterface(i) == klass) {
    373       return true;
    374     }
    375   }
    376   return false;
    377 }
    378 
    379 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
    380 inline bool Class::IsVariableSize() {
    381   // Classes, arrays, and strings vary in size, and so the object_size_ field cannot
    382   // be used to Get their instance size
    383   return IsClassClass<kVerifyFlags, kReadBarrierOption>() ||
    384          IsArrayClass<kVerifyFlags, kReadBarrierOption>() ||
    385          IsStringClass();
    386 }
    387 
    388 inline void Class::SetObjectSize(uint32_t new_object_size) {
    389   DCHECK(!IsVariableSize());
    390   // Not called within a transaction.
    391   return SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, object_size_), new_object_size);
    392 }
    393 
    394 // Determine whether "this" is assignable from "src", where both of these
    395 // are array classes.
    396 //
    397 // Consider an array class, e.g. Y[][], where Y is a subclass of X.
    398 //   Y[][]            = Y[][] --> true (identity)
    399 //   X[][]            = Y[][] --> true (element superclass)
    400 //   Y                = Y[][] --> false
    401 //   Y[]              = Y[][] --> false
    402 //   Object           = Y[][] --> true (everything is an object)
    403 //   Object[]         = Y[][] --> true
    404 //   Object[][]       = Y[][] --> true
    405 //   Object[][][]     = Y[][] --> false (too many []s)
    406 //   Serializable     = Y[][] --> true (all arrays are Serializable)
    407 //   Serializable[]   = Y[][] --> true
    408 //   Serializable[][] = Y[][] --> false (unless Y is Serializable)
    409 //
    410 // Don't forget about primitive types.
    411 //   Object[]         = int[] --> false
    412 //
    413 inline bool Class::IsArrayAssignableFromArray(ObjPtr<Class> src) {
    414   DCHECK(IsArrayClass())  << PrettyClass();
    415   DCHECK(src->IsArrayClass()) << src->PrettyClass();
    416   return GetComponentType()->IsAssignableFrom(src->GetComponentType());
    417 }
    418 
    419 inline bool Class::IsAssignableFromArray(ObjPtr<Class> src) {
    420   DCHECK(!IsInterface()) << PrettyClass();  // handled first in IsAssignableFrom
    421   DCHECK(src->IsArrayClass()) << src->PrettyClass();
    422   if (!IsArrayClass()) {
    423     // If "this" is not also an array, it must be Object.
    424     // src's super should be java_lang_Object, since it is an array.
    425     ObjPtr<Class> java_lang_Object = src->GetSuperClass();
    426     DCHECK(java_lang_Object != nullptr) << src->PrettyClass();
    427     DCHECK(java_lang_Object->GetSuperClass() == nullptr) << src->PrettyClass();
    428     return this == java_lang_Object;
    429   }
    430   return IsArrayAssignableFromArray(src);
    431 }
    432 
    433 template <bool throw_on_failure>
    434 inline bool Class::ResolvedFieldAccessTest(ObjPtr<Class> access_to,
    435                                            ArtField* field,
    436                                            ObjPtr<DexCache> dex_cache,
    437                                            uint32_t field_idx) {
    438   DCHECK(dex_cache != nullptr);
    439   if (UNLIKELY(!this->CanAccess(access_to))) {
    440     // The referrer class can't access the field's declaring class but may still be able
    441     // to access the field if the FieldId specifies an accessible subclass of the declaring
    442     // class rather than the declaring class itself.
    443     dex::TypeIndex class_idx = dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_;
    444     // The referenced class has already been resolved with the field, but may not be in the dex
    445     // cache. Use LookupResolveType here to search the class table if it is not in the dex cache.
    446     // should be no thread suspension due to the class being resolved.
    447     ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType(
    448         class_idx,
    449         dex_cache,
    450         access_to->GetClassLoader());
    451     DCHECK(dex_access_to != nullptr);
    452     if (UNLIKELY(!this->CanAccess(dex_access_to))) {
    453       if (throw_on_failure) {
    454         ThrowIllegalAccessErrorClass(this, dex_access_to);
    455       }
    456       return false;
    457     }
    458   }
    459   if (LIKELY(this->CanAccessMember(access_to, field->GetAccessFlags()))) {
    460     return true;
    461   }
    462   if (throw_on_failure) {
    463     ThrowIllegalAccessErrorField(this, field);
    464   }
    465   return false;
    466 }
    467 
    468 template <bool throw_on_failure>
    469 inline bool Class::ResolvedMethodAccessTest(ObjPtr<Class> access_to,
    470                                             ArtMethod* method,
    471                                             ObjPtr<DexCache> dex_cache,
    472                                             uint32_t method_idx,
    473                                             InvokeType throw_invoke_type) {
    474   DCHECK(throw_on_failure || throw_invoke_type == kStatic);
    475   DCHECK(dex_cache != nullptr);
    476   if (UNLIKELY(!this->CanAccess(access_to))) {
    477     // The referrer class can't access the method's declaring class but may still be able
    478     // to access the method if the MethodId specifies an accessible subclass of the declaring
    479     // class rather than the declaring class itself.
    480     dex::TypeIndex class_idx = dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_;
    481     // The referenced class has already been resolved with the method, but may not be in the dex
    482     // cache.
    483     ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType(
    484         class_idx,
    485         dex_cache,
    486         access_to->GetClassLoader());
    487     DCHECK(dex_access_to != nullptr);
    488     if (UNLIKELY(!this->CanAccess(dex_access_to))) {
    489       if (throw_on_failure) {
    490         ThrowIllegalAccessErrorClassForMethodDispatch(this,
    491                                                       dex_access_to.Ptr(),
    492                                                       method,
    493                                                       throw_invoke_type);
    494       }
    495       return false;
    496     }
    497   }
    498   if (LIKELY(this->CanAccessMember(access_to, method->GetAccessFlags()))) {
    499     return true;
    500   }
    501   if (throw_on_failure) {
    502     ThrowIllegalAccessErrorMethod(this, method);
    503   }
    504   return false;
    505 }
    506 
    507 inline bool Class::CanAccessResolvedField(ObjPtr<Class> access_to,
    508                                           ArtField* field,
    509                                           ObjPtr<DexCache> dex_cache,
    510                                           uint32_t field_idx) {
    511   return ResolvedFieldAccessTest<false>(access_to, field, dex_cache, field_idx);
    512 }
    513 
    514 inline bool Class::CheckResolvedFieldAccess(ObjPtr<Class> access_to,
    515                                             ArtField* field,
    516                                             ObjPtr<DexCache> dex_cache,
    517                                             uint32_t field_idx) {
    518   return ResolvedFieldAccessTest<true>(access_to, field, dex_cache, field_idx);
    519 }
    520 
    521 inline bool Class::CanAccessResolvedMethod(ObjPtr<Class> access_to,
    522                                            ArtMethod* method,
    523                                            ObjPtr<DexCache> dex_cache,
    524                                            uint32_t method_idx) {
    525   return ResolvedMethodAccessTest<false>(access_to, method, dex_cache, method_idx, kStatic);
    526 }
    527 
    528 inline bool Class::CheckResolvedMethodAccess(ObjPtr<Class> access_to,
    529                                              ArtMethod* method,
    530                                              ObjPtr<DexCache> dex_cache,
    531                                              uint32_t method_idx,
    532                                              InvokeType throw_invoke_type) {
    533   return ResolvedMethodAccessTest<true>(
    534       access_to, method, dex_cache, method_idx, throw_invoke_type);
    535 }
    536 
    537 inline bool Class::IsSubClass(ObjPtr<Class> klass) {
    538   // Since the SubtypeCheck::IsSubtypeOf needs to lookup the Depth,
    539   // it is always O(Depth) in terms of speed to do the check.
    540   //
    541   // So always do the "slow" linear scan in normal release builds.
    542   //
    543   // Future note: If we could have the depth in O(1) we could use the 'fast'
    544   // method instead as it avoids a loop and a read barrier.
    545   bool result = false;
    546   DCHECK(!IsInterface()) << PrettyClass();
    547   DCHECK(!IsArrayClass()) << PrettyClass();
    548   ObjPtr<Class> current = this;
    549   do {
    550     if (current == klass) {
    551       result = true;
    552       break;
    553     }
    554     current = current->GetSuperClass();
    555   } while (current != nullptr);
    556 
    557   if (kIsDebugBuild && kBitstringSubtypeCheckEnabled) {
    558     ObjPtr<mirror::Class> dis(this);
    559 
    560     SubtypeCheckInfo::Result sc_result = SubtypeCheck<ObjPtr<Class>>::IsSubtypeOf(dis, klass);
    561     if (sc_result != SubtypeCheckInfo::kUnknownSubtypeOf) {
    562       // Note: The "kUnknownSubTypeOf" can be avoided if and only if:
    563       //   SubtypeCheck::EnsureInitialized(source)
    564       //       happens-before source.IsSubClass(target)
    565       //   SubtypeCheck::EnsureAssigned(target).GetState() == Assigned
    566       //       happens-before source.IsSubClass(target)
    567       //
    568       // When code generated by optimizing compiler executes this operation, both
    569       // happens-before are guaranteed, so there is no fallback code there.
    570       SubtypeCheckInfo::Result expected_result =
    571           result ? SubtypeCheckInfo::kSubtypeOf : SubtypeCheckInfo::kNotSubtypeOf;
    572       DCHECK_EQ(expected_result, sc_result)
    573           << "source: " << PrettyClass() << "target: " << klass->PrettyClass();
    574     }
    575   }
    576 
    577   return result;
    578 }
    579 
    580 inline ArtMethod* Class::FindVirtualMethodForInterface(ArtMethod* method,
    581                                                        PointerSize pointer_size) {
    582   ObjPtr<Class> declaring_class = method->GetDeclaringClass();
    583   DCHECK(declaring_class != nullptr) << PrettyClass();
    584   if (UNLIKELY(!declaring_class->IsInterface())) {
    585     DCHECK(declaring_class->IsObjectClass()) << method->PrettyMethod();
    586     DCHECK(method->IsPublic() && !method->IsStatic());
    587     return FindVirtualMethodForVirtual(method, pointer_size);
    588   }
    589   DCHECK(!method->IsCopied());
    590   // TODO cache to improve lookup speed
    591   const int32_t iftable_count = GetIfTableCount();
    592   ObjPtr<IfTable> iftable = GetIfTable();
    593   for (int32_t i = 0; i < iftable_count; i++) {
    594     if (iftable->GetInterface(i) == declaring_class) {
    595       return iftable->GetMethodArray(i)->GetElementPtrSize<ArtMethod*>(
    596           method->GetMethodIndex(), pointer_size);
    597     }
    598   }
    599   return nullptr;
    600 }
    601 
    602 inline ArtMethod* Class::FindVirtualMethodForVirtual(ArtMethod* method, PointerSize pointer_size) {
    603   // Only miranda or default methods may come from interfaces and be used as a virtual.
    604   DCHECK(!method->GetDeclaringClass()->IsInterface() || method->IsDefault() || method->IsMiranda());
    605   // The argument method may from a super class.
    606   // Use the index to a potentially overridden one for this instance's class.
    607   return GetVTableEntry(method->GetMethodIndex(), pointer_size);
    608 }
    609 
    610 inline ArtMethod* Class::FindVirtualMethodForSuper(ArtMethod* method, PointerSize pointer_size) {
    611   DCHECK(!method->GetDeclaringClass()->IsInterface());
    612   return GetSuperClass()->GetVTableEntry(method->GetMethodIndex(), pointer_size);
    613 }
    614 
    615 inline ArtMethod* Class::FindVirtualMethodForVirtualOrInterface(ArtMethod* method,
    616                                                                 PointerSize pointer_size) {
    617   if (method->IsDirect()) {
    618     return method;
    619   }
    620   if (method->GetDeclaringClass()->IsInterface() && !method->IsCopied()) {
    621     return FindVirtualMethodForInterface(method, pointer_size);
    622   }
    623   return FindVirtualMethodForVirtual(method, pointer_size);
    624 }
    625 
    626 template<VerifyObjectFlags kVerifyFlags,
    627          ReadBarrierOption kReadBarrierOption>
    628 inline IfTable* Class::GetIfTable() {
    629   ObjPtr<IfTable> ret = GetFieldObject<IfTable, kVerifyFlags, kReadBarrierOption>(IfTableOffset());
    630   DCHECK(ret != nullptr) << PrettyClass(this);
    631   return ret.Ptr();
    632 }
    633 
    634 template<VerifyObjectFlags kVerifyFlags,
    635          ReadBarrierOption kReadBarrierOption>
    636 inline int32_t Class::GetIfTableCount() {
    637   return GetIfTable<kVerifyFlags, kReadBarrierOption>()->Count();
    638 }
    639 
    640 inline void Class::SetIfTable(ObjPtr<IfTable> new_iftable) {
    641   DCHECK(new_iftable != nullptr) << PrettyClass(this);
    642   SetFieldObject<false>(IfTableOffset(), new_iftable);
    643 }
    644 
    645 inline LengthPrefixedArray<ArtField>* Class::GetIFieldsPtr() {
    646   DCHECK(IsLoaded() || IsErroneous()) << GetStatus();
    647   return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
    648 }
    649 
    650 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
    651 inline MemberOffset Class::GetFirstReferenceInstanceFieldOffset() {
    652   ObjPtr<Class> super_class = GetSuperClass<kVerifyFlags, kReadBarrierOption>();
    653   return (super_class != nullptr)
    654       ? MemberOffset(RoundUp(super_class->GetObjectSize<kVerifyFlags, kReadBarrierOption>(),
    655                              kHeapReferenceSize))
    656       : ClassOffset();
    657 }
    658 
    659 template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
    660 inline MemberOffset Class::GetFirstReferenceStaticFieldOffset(PointerSize pointer_size) {
    661   DCHECK(IsResolved());
    662   uint32_t base = sizeof(Class);  // Static fields come after the class.
    663   if (ShouldHaveEmbeddedVTable<kVerifyFlags, kReadBarrierOption>()) {
    664     // Static fields come after the embedded tables.
    665     base = Class::ComputeClassSize(
    666         true, GetEmbeddedVTableLength(), 0, 0, 0, 0, 0, pointer_size);
    667   }
    668   return MemberOffset(base);
    669 }
    670 
    671 inline MemberOffset Class::GetFirstReferenceStaticFieldOffsetDuringLinking(
    672     PointerSize pointer_size) {
    673   DCHECK(IsLoaded());
    674   uint32_t base = sizeof(Class);  // Static fields come after the class.
    675   if (ShouldHaveEmbeddedVTable()) {
    676     // Static fields come after the embedded tables.
    677     base = Class::ComputeClassSize(true, GetVTableDuringLinking()->GetLength(),
    678                                            0, 0, 0, 0, 0, pointer_size);
    679   }
    680   return MemberOffset(base);
    681 }
    682 
    683 inline void Class::SetIFieldsPtr(LengthPrefixedArray<ArtField>* new_ifields) {
    684   DCHECK(GetIFieldsPtrUnchecked() == nullptr);
    685   return SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
    686 }
    687 
    688 inline void Class::SetIFieldsPtrUnchecked(LengthPrefixedArray<ArtField>* new_ifields) {
    689   SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
    690 }
    691 
    692 inline LengthPrefixedArray<ArtField>* Class::GetSFieldsPtrUnchecked() {
    693   return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
    694 }
    695 
    696 inline LengthPrefixedArray<ArtField>* Class::GetIFieldsPtrUnchecked() {
    697   return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
    698 }
    699 
    700 inline LengthPrefixedArray<ArtField>* Class::GetSFieldsPtr() {
    701   DCHECK(IsLoaded() || IsErroneous()) << GetStatus();
    702   return GetSFieldsPtrUnchecked();
    703 }
    704 
    705 inline void Class::SetSFieldsPtr(LengthPrefixedArray<ArtField>* new_sfields) {
    706   DCHECK((IsRetired() && new_sfields == nullptr) ||
    707          GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_)) == nullptr);
    708   SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
    709 }
    710 
    711 inline void Class::SetSFieldsPtrUnchecked(LengthPrefixedArray<ArtField>* new_sfields) {
    712   SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
    713 }
    714 
    715 inline ArtField* Class::GetStaticField(uint32_t i) {
    716   return &GetSFieldsPtr()->At(i);
    717 }
    718 
    719 inline ArtField* Class::GetInstanceField(uint32_t i) {
    720   return &GetIFieldsPtr()->At(i);
    721 }
    722 
    723 template<VerifyObjectFlags kVerifyFlags>
    724 inline uint32_t Class::GetReferenceInstanceOffsets() {
    725   DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>());
    726   return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_));
    727 }
    728 
    729 inline void Class::SetClinitThreadId(pid_t new_clinit_thread_id) {
    730   SetField32Transaction(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id);
    731 }
    732 
    733 inline String* Class::GetName() {
    734   return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(Class, name_));
    735 }
    736 
    737 inline void Class::SetName(ObjPtr<String> name) {
    738     SetFieldObjectTransaction(OFFSET_OF_OBJECT_MEMBER(Class, name_), name);
    739 }
    740 
    741 template<VerifyObjectFlags kVerifyFlags>
    742 inline Primitive::Type Class::GetPrimitiveType() {
    743   static_assert(sizeof(Primitive::Type) == sizeof(int32_t),
    744                 "art::Primitive::Type and int32_t have different sizes.");
    745   int32_t v32 = GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_));
    746   Primitive::Type type = static_cast<Primitive::Type>(v32 & kPrimitiveTypeMask);
    747   DCHECK_EQ(static_cast<size_t>(v32 >> kPrimitiveTypeSizeShiftShift),
    748             Primitive::ComponentSizeShift(type));
    749   return type;
    750 }
    751 
    752 template<VerifyObjectFlags kVerifyFlags>
    753 inline size_t Class::GetPrimitiveTypeSizeShift() {
    754   static_assert(sizeof(Primitive::Type) == sizeof(int32_t),
    755                 "art::Primitive::Type and int32_t have different sizes.");
    756   int32_t v32 = GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_));
    757   size_t size_shift = static_cast<Primitive::Type>(v32 >> kPrimitiveTypeSizeShiftShift);
    758   DCHECK_EQ(size_shift,
    759             Primitive::ComponentSizeShift(static_cast<Primitive::Type>(v32 & kPrimitiveTypeMask)));
    760   return size_shift;
    761 }
    762 
    763 inline void Class::CheckObjectAlloc() {
    764   DCHECK(!IsArrayClass())
    765       << PrettyClass()
    766       << "A array shouldn't be allocated through this "
    767       << "as it requires a pre-fence visitor that sets the class size.";
    768   DCHECK(!IsClassClass())
    769       << PrettyClass()
    770       << "A class object shouldn't be allocated through this "
    771       << "as it requires a pre-fence visitor that sets the class size.";
    772   DCHECK(!IsStringClass())
    773       << PrettyClass()
    774       << "A string shouldn't be allocated through this "
    775       << "as it requires a pre-fence visitor that sets the class size.";
    776   DCHECK(IsInstantiable()) << PrettyClass();
    777   // TODO: decide whether we want this check. It currently fails during bootstrap.
    778   // DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass();
    779   DCHECK_GE(this->object_size_, sizeof(Object));
    780 }
    781 
    782 template<bool kIsInstrumented, bool kCheckAddFinalizer>
    783 inline ObjPtr<Object> Class::Alloc(Thread* self, gc::AllocatorType allocator_type) {
    784   CheckObjectAlloc();
    785   gc::Heap* heap = Runtime::Current()->GetHeap();
    786   const bool add_finalizer = kCheckAddFinalizer && IsFinalizable();
    787   if (!kCheckAddFinalizer) {
    788     DCHECK(!IsFinalizable());
    789   }
    790   // Note that the this pointer may be invalidated after the allocation.
    791   ObjPtr<Object> obj =
    792       heap->AllocObjectWithAllocator<kIsInstrumented, false>(self,
    793                                                              this,
    794                                                              this->object_size_,
    795                                                              allocator_type,
    796                                                              VoidFunctor());
    797   if (add_finalizer && LIKELY(obj != nullptr)) {
    798     heap->AddFinalizerReference(self, &obj);
    799     if (UNLIKELY(self->IsExceptionPending())) {
    800       // Failed to allocate finalizer reference, it means that the whole allocation failed.
    801       obj = nullptr;
    802     }
    803   }
    804   return obj.Ptr();
    805 }
    806 
    807 inline ObjPtr<Object> Class::AllocObject(Thread* self) {
    808   return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentAllocator());
    809 }
    810 
    811 inline ObjPtr<Object> Class::AllocNonMovableObject(Thread* self) {
    812   return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentNonMovingAllocator());
    813 }
    814 
    815 inline uint32_t Class::ComputeClassSize(bool has_embedded_vtable,
    816                                         uint32_t num_vtable_entries,
    817                                         uint32_t num_8bit_static_fields,
    818                                         uint32_t num_16bit_static_fields,
    819                                         uint32_t num_32bit_static_fields,
    820                                         uint32_t num_64bit_static_fields,
    821                                         uint32_t num_ref_static_fields,
    822                                         PointerSize pointer_size) {
    823   // Space used by java.lang.Class and its instance fields.
    824   uint32_t size = sizeof(Class);
    825   // Space used by embedded tables.
    826   if (has_embedded_vtable) {
    827     size = RoundUp(size + sizeof(uint32_t), static_cast<size_t>(pointer_size));
    828     size += static_cast<size_t>(pointer_size);  // size of pointer to IMT
    829     size += num_vtable_entries * VTableEntrySize(pointer_size);
    830   }
    831 
    832   // Space used by reference statics.
    833   size += num_ref_static_fields * kHeapReferenceSize;
    834   if (!IsAligned<8>(size) && num_64bit_static_fields > 0) {
    835     uint32_t gap = 8 - (size & 0x7);
    836     size += gap;  // will be padded
    837     // Shuffle 4-byte fields forward.
    838     while (gap >= sizeof(uint32_t) && num_32bit_static_fields != 0) {
    839       --num_32bit_static_fields;
    840       gap -= sizeof(uint32_t);
    841     }
    842     // Shuffle 2-byte fields forward.
    843     while (gap >= sizeof(uint16_t) && num_16bit_static_fields != 0) {
    844       --num_16bit_static_fields;
    845       gap -= sizeof(uint16_t);
    846     }
    847     // Shuffle byte fields forward.
    848     while (gap >= sizeof(uint8_t) && num_8bit_static_fields != 0) {
    849       --num_8bit_static_fields;
    850       gap -= sizeof(uint8_t);
    851     }
    852   }
    853   // Guaranteed to be at least 4 byte aligned. No need for further alignments.
    854   // Space used for primitive static fields.
    855   size += num_8bit_static_fields * sizeof(uint8_t) + num_16bit_static_fields * sizeof(uint16_t) +
    856       num_32bit_static_fields * sizeof(uint32_t) + num_64bit_static_fields * sizeof(uint64_t);
    857   return size;
    858 }
    859 
    860 template<ReadBarrierOption kReadBarrierOption>
    861 inline bool Class::IsReferenceClass() const {
    862   return this == Reference::GetJavaLangRefReference<kReadBarrierOption>();
    863 }
    864 
    865 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
    866 inline bool Class::IsClassClass() {
    867   ObjPtr<Class> java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
    868       template GetClass<kVerifyFlags, kReadBarrierOption>();
    869   return this == java_lang_Class;
    870 }
    871 
    872 inline const DexFile& Class::GetDexFile() {
    873   // From-space version is the same as the to-space version since the dex file never changes.
    874   // Avoiding the read barrier here is important to prevent recursive AssertToSpaceInvariant issues
    875   // from PrettyTypeOf.
    876   return *GetDexCache<kDefaultVerifyFlags, kWithoutReadBarrier>()->GetDexFile();
    877 }
    878 
    879 inline bool Class::DescriptorEquals(const char* match) {
    880   if (IsArrayClass()) {
    881     return match[0] == '[' && GetComponentType()->DescriptorEquals(match + 1);
    882   } else if (IsPrimitive()) {
    883     return strcmp(Primitive::Descriptor(GetPrimitiveType()), match) == 0;
    884   } else if (IsProxyClass()) {
    885     return ProxyDescriptorEquals(match);
    886   } else {
    887     const DexFile& dex_file = GetDexFile();
    888     const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
    889     return strcmp(dex_file.GetTypeDescriptor(type_id), match) == 0;
    890   }
    891 }
    892 
    893 inline void Class::AssertInitializedOrInitializingInThread(Thread* self) {
    894   if (kIsDebugBuild && !IsInitialized()) {
    895     CHECK(IsInitializing()) << PrettyClass() << " is not initializing: " << GetStatus();
    896     CHECK_EQ(GetClinitThreadId(), self->GetTid()) << PrettyClass()
    897                                                   << " is initializing in a different thread";
    898   }
    899 }
    900 
    901 inline ObjectArray<Class>* Class::GetProxyInterfaces() {
    902   CHECK(IsProxyClass());
    903   // First static field.
    904   auto* field = GetStaticField(0);
    905   DCHECK_STREQ(field->GetName(), "interfaces");
    906   MemberOffset field_offset = field->GetOffset();
    907   return GetFieldObject<ObjectArray<Class>>(field_offset);
    908 }
    909 
    910 inline ObjectArray<ObjectArray<Class>>* Class::GetProxyThrows() {
    911   CHECK(IsProxyClass());
    912   // Second static field.
    913   auto* field = GetStaticField(1);
    914   DCHECK_STREQ(field->GetName(), "throws");
    915   MemberOffset field_offset = field->GetOffset();
    916   return GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset);
    917 }
    918 
    919 inline MemberOffset Class::GetDisableIntrinsicFlagOffset() {
    920   CHECK(IsReferenceClass());
    921   // First static field
    922   auto* field = GetStaticField(0);
    923   DCHECK_STREQ(field->GetName(), "disableIntrinsic");
    924   return field->GetOffset();
    925 }
    926 
    927 inline MemberOffset Class::GetSlowPathFlagOffset() {
    928   CHECK(IsReferenceClass());
    929   // Second static field
    930   auto* field = GetStaticField(1);
    931   DCHECK_STREQ(field->GetName(), "slowPathEnabled");
    932   return field->GetOffset();
    933 }
    934 
    935 inline bool Class::GetSlowPathEnabled() {
    936   return GetFieldBoolean(GetSlowPathFlagOffset());
    937 }
    938 
    939 inline void Class::SetSlowPath(bool enabled) {
    940   SetFieldBoolean<false, false>(GetSlowPathFlagOffset(), enabled);
    941 }
    942 
    943 inline void Class::InitializeClassVisitor::operator()(ObjPtr<Object> obj,
    944                                                       size_t usable_size) const {
    945   DCHECK_LE(class_size_, usable_size);
    946   // Avoid AsClass as object is not yet in live bitmap or allocation stack.
    947   ObjPtr<Class> klass = ObjPtr<Class>::DownCast(obj);
    948   klass->SetClassSize(class_size_);
    949   klass->SetPrimitiveType(Primitive::kPrimNot);  // Default to not being primitive.
    950   klass->SetDexClassDefIndex(DexFile::kDexNoIndex16);  // Default to no valid class def index.
    951   klass->SetDexTypeIndex(dex::TypeIndex(DexFile::kDexNoIndex16));  // Default to no valid type
    952                                                                    // index.
    953   // Default to force slow path until initialized.
    954   klass->SetObjectSizeAllocFastPath(std::numeric_limits<uint32_t>::max());
    955 }
    956 
    957 inline void Class::SetAccessFlags(uint32_t new_access_flags) {
    958   // Called inside a transaction when setting pre-verified flag during boot image compilation.
    959   if (Runtime::Current()->IsActiveTransaction()) {
    960     SetField32<true>(AccessFlagsOffset(), new_access_flags);
    961   } else {
    962     SetField32<false>(AccessFlagsOffset(), new_access_flags);
    963   }
    964 }
    965 
    966 inline void Class::SetClassFlags(uint32_t new_flags) {
    967   if (Runtime::Current()->IsActiveTransaction()) {
    968     SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, class_flags_), new_flags);
    969   } else {
    970     SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_flags_), new_flags);
    971   }
    972 }
    973 
    974 inline uint32_t Class::NumDirectInterfaces() {
    975   if (IsPrimitive()) {
    976     return 0;
    977   } else if (IsArrayClass()) {
    978     return 2;
    979   } else if (IsProxyClass()) {
    980     ObjectArray<Class>* interfaces = GetProxyInterfaces();
    981     return interfaces != nullptr ? interfaces->GetLength() : 0;
    982   } else {
    983     const DexFile::TypeList* interfaces = GetInterfaceTypeList();
    984     if (interfaces == nullptr) {
    985       return 0;
    986     } else {
    987       return interfaces->Size();
    988     }
    989   }
    990 }
    991 
    992 inline ArraySlice<ArtMethod> Class::GetDirectMethods(PointerSize pointer_size) {
    993   CheckPointerSize(pointer_size);
    994   return GetDirectMethodsSliceUnchecked(pointer_size);
    995 }
    996 
    997 inline ArraySlice<ArtMethod> Class::GetDeclaredMethods(
    998       PointerSize pointer_size) {
    999   return GetDeclaredMethodsSliceUnchecked(pointer_size);
   1000 }
   1001 
   1002 inline ArraySlice<ArtMethod> Class::GetDeclaredVirtualMethods(
   1003       PointerSize pointer_size) {
   1004   return GetDeclaredVirtualMethodsSliceUnchecked(pointer_size);
   1005 }
   1006 
   1007 inline ArraySlice<ArtMethod> Class::GetVirtualMethods(
   1008     PointerSize pointer_size) {
   1009   CheckPointerSize(pointer_size);
   1010   return GetVirtualMethodsSliceUnchecked(pointer_size);
   1011 }
   1012 
   1013 inline ArraySlice<ArtMethod> Class::GetCopiedMethods(PointerSize pointer_size) {
   1014   CheckPointerSize(pointer_size);
   1015   return GetCopiedMethodsSliceUnchecked(pointer_size);
   1016 }
   1017 
   1018 
   1019 inline ArraySlice<ArtMethod> Class::GetMethods(PointerSize pointer_size) {
   1020   CheckPointerSize(pointer_size);
   1021   LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
   1022   return GetMethodsSliceRangeUnchecked(methods, pointer_size, 0u, NumMethods(methods));
   1023 }
   1024 
   1025 inline IterationRange<StrideIterator<ArtField>> Class::GetIFields() {
   1026   return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtr());
   1027 }
   1028 
   1029 inline IterationRange<StrideIterator<ArtField>> Class::GetSFields() {
   1030   return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtr());
   1031 }
   1032 
   1033 inline IterationRange<StrideIterator<ArtField>> Class::GetIFieldsUnchecked() {
   1034   return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtrUnchecked());
   1035 }
   1036 
   1037 inline IterationRange<StrideIterator<ArtField>> Class::GetSFieldsUnchecked() {
   1038   return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtrUnchecked());
   1039 }
   1040 
   1041 inline MemberOffset Class::EmbeddedVTableOffset(PointerSize pointer_size) {
   1042   CheckPointerSize(pointer_size);
   1043   return MemberOffset(ImtPtrOffset(pointer_size).Uint32Value() + static_cast<size_t>(pointer_size));
   1044 }
   1045 
   1046 inline void Class::CheckPointerSize(PointerSize pointer_size) {
   1047   DCHECK_EQ(pointer_size, Runtime::Current()->GetClassLinker()->GetImagePointerSize());
   1048 }
   1049 
   1050 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
   1051 inline Class* Class::GetComponentType() {
   1052   return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(ComponentTypeOffset());
   1053 }
   1054 
   1055 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
   1056 inline bool Class::IsArrayClass() {
   1057   return GetComponentType<kVerifyFlags, kReadBarrierOption>() != nullptr;
   1058 }
   1059 
   1060 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
   1061 inline bool Class::IsObjectArrayClass() {
   1062   ObjPtr<Class> const component_type = GetComponentType<kVerifyFlags, kReadBarrierOption>();
   1063   return component_type != nullptr && !component_type->IsPrimitive();
   1064 }
   1065 
   1066 inline bool Class::IsAssignableFrom(ObjPtr<Class> src) {
   1067   DCHECK(src != nullptr);
   1068   if (this == src) {
   1069     // Can always assign to things of the same type.
   1070     return true;
   1071   } else if (IsObjectClass()) {
   1072     // Can assign any reference to java.lang.Object.
   1073     return !src->IsPrimitive();
   1074   } else if (IsInterface()) {
   1075     return src->Implements(this);
   1076   } else if (src->IsArrayClass()) {
   1077     return IsAssignableFromArray(src);
   1078   } else {
   1079     return !src->IsInterface() && src->IsSubClass(this);
   1080   }
   1081 }
   1082 
   1083 inline uint32_t Class::NumDirectMethods() {
   1084   return GetVirtualMethodsStartOffset();
   1085 }
   1086 
   1087 inline uint32_t Class::NumDeclaredVirtualMethods() {
   1088   return GetCopiedMethodsStartOffset() - GetVirtualMethodsStartOffset();
   1089 }
   1090 
   1091 inline uint32_t Class::NumVirtualMethods() {
   1092   return NumMethods() - GetVirtualMethodsStartOffset();
   1093 }
   1094 
   1095 inline uint32_t Class::NumInstanceFields() {
   1096   LengthPrefixedArray<ArtField>* arr = GetIFieldsPtrUnchecked();
   1097   return arr != nullptr ? arr->size() : 0u;
   1098 }
   1099 
   1100 inline uint32_t Class::NumStaticFields() {
   1101   LengthPrefixedArray<ArtField>* arr = GetSFieldsPtrUnchecked();
   1102   return arr != nullptr ? arr->size() : 0u;
   1103 }
   1104 
   1105 template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor>
   1106 inline void Class::FixupNativePointers(Class* dest,
   1107                                        PointerSize pointer_size,
   1108                                        const Visitor& visitor) {
   1109   // Update the field arrays.
   1110   LengthPrefixedArray<ArtField>* const sfields = GetSFieldsPtr();
   1111   LengthPrefixedArray<ArtField>* const new_sfields = visitor(sfields);
   1112   if (sfields != new_sfields) {
   1113     dest->SetSFieldsPtrUnchecked(new_sfields);
   1114   }
   1115   LengthPrefixedArray<ArtField>* const ifields = GetIFieldsPtr();
   1116   LengthPrefixedArray<ArtField>* const new_ifields = visitor(ifields);
   1117   if (ifields != new_ifields) {
   1118     dest->SetIFieldsPtrUnchecked(new_ifields);
   1119   }
   1120   // Update method array.
   1121   LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr();
   1122   LengthPrefixedArray<ArtMethod>* new_methods = visitor(methods);
   1123   if (methods != new_methods) {
   1124     dest->SetMethodsPtrInternal(new_methods);
   1125   }
   1126   // Fix up embedded tables.
   1127   if (!IsTemp() && ShouldHaveEmbeddedVTable<kVerifyNone, kReadBarrierOption>()) {
   1128     for (int32_t i = 0, count = GetEmbeddedVTableLength(); i < count; ++i) {
   1129       ArtMethod* method = GetEmbeddedVTableEntry(i, pointer_size);
   1130       void** dest_addr = reinterpret_cast<void**>(reinterpret_cast<uintptr_t>(dest) +
   1131           EmbeddedVTableEntryOffset(i, pointer_size).Uint32Value());
   1132       ArtMethod* new_method = visitor(method, dest_addr);
   1133       if (method != new_method) {
   1134         dest->SetEmbeddedVTableEntryUnchecked(i, new_method, pointer_size);
   1135       }
   1136     }
   1137   }
   1138   if (!IsTemp() && ShouldHaveImt<kVerifyNone, kReadBarrierOption>()) {
   1139     dest->SetImt(visitor(GetImt(pointer_size)), pointer_size);
   1140   }
   1141 }
   1142 
   1143 inline bool Class::CanAccess(ObjPtr<Class> that) {
   1144   return that->IsPublic() || this->IsInSamePackage(that);
   1145 }
   1146 
   1147 
   1148 inline bool Class::CanAccessMember(ObjPtr<Class> access_to, uint32_t member_flags) {
   1149   // Classes can access all of their own members
   1150   if (this == access_to) {
   1151     return true;
   1152   }
   1153   // Public members are trivially accessible
   1154   if (member_flags & kAccPublic) {
   1155     return true;
   1156   }
   1157   // Private members are trivially not accessible
   1158   if (member_flags & kAccPrivate) {
   1159     return false;
   1160   }
   1161   // Check for protected access from a sub-class, which may or may not be in the same package.
   1162   if (member_flags & kAccProtected) {
   1163     if (!this->IsInterface() && this->IsSubClass(access_to)) {
   1164       return true;
   1165     }
   1166   }
   1167   // Allow protected access from other classes in the same package.
   1168   return this->IsInSamePackage(access_to);
   1169 }
   1170 
   1171 inline bool Class::CannotBeAssignedFromOtherTypes() {
   1172   if (!IsArrayClass()) {
   1173     return IsFinal();
   1174   }
   1175   ObjPtr<Class> component = GetComponentType();
   1176   return component->IsPrimitive() || component->CannotBeAssignedFromOtherTypes();
   1177 }
   1178 
   1179 }  // namespace mirror
   1180 }  // namespace art
   1181 
   1182 #endif  // ART_RUNTIME_MIRROR_CLASS_INL_H_
   1183