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