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