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