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