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