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-inl.h"
23#include "art_method-inl.h"
24#include "class_linker-inl.h"
25#include "class_loader.h"
26#include "common_throws.h"
27#include "dex_cache.h"
28#include "dex_file.h"
29#include "gc/heap-inl.h"
30#include "iftable.h"
31#include "object_array-inl.h"
32#include "read_barrier-inl.h"
33#include "reference-inl.h"
34#include "runtime.h"
35#include "string.h"
36
37namespace art {
38namespace mirror {
39
40template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
41inline uint32_t Class::GetObjectSize() {
42  if (kIsDebugBuild) {
43    // Use a local variable as (D)CHECK can't handle the space between
44    // the two template params.
45    bool is_variable_size = IsVariableSize<kVerifyFlags, kReadBarrierOption>();
46    CHECK(!is_variable_size) << " class=" << PrettyTypeOf(this);
47  }
48  return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, object_size_));
49}
50
51inline Class* Class::GetSuperClass() {
52  // Can only get super class for loaded classes (hack for when runtime is
53  // initializing)
54  DCHECK(IsLoaded() || IsErroneous() || !Runtime::Current()->IsStarted()) << IsLoaded();
55  return GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_));
56}
57
58inline ClassLoader* Class::GetClassLoader() {
59  return GetFieldObject<ClassLoader>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_));
60}
61
62template<VerifyObjectFlags kVerifyFlags>
63inline DexCache* Class::GetDexCache() {
64  return GetFieldObject<DexCache, kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_));
65}
66
67inline ObjectArray<ArtMethod>* Class::GetDirectMethods() {
68  DCHECK(IsLoaded() || IsErroneous());
69  return GetFieldObject<ObjectArray<ArtMethod>>(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_));
70}
71
72inline void Class::SetDirectMethods(ObjectArray<ArtMethod>* new_direct_methods)
73    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
74  DCHECK(NULL == GetFieldObject<ObjectArray<ArtMethod>>(
75      OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_)));
76  DCHECK_NE(0, new_direct_methods->GetLength());
77  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), new_direct_methods);
78}
79
80inline ArtMethod* Class::GetDirectMethod(int32_t i) {
81  return GetDirectMethods()->Get(i);
82}
83
84inline void Class::SetDirectMethod(uint32_t i, ArtMethod* f)  // TODO: uint16_t
85    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
86  ObjectArray<ArtMethod>* direct_methods =
87      GetFieldObject<ObjectArray<ArtMethod>>(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_));
88  direct_methods->Set<false>(i, f);
89}
90
91// Returns the number of static, private, and constructor methods.
92inline uint32_t Class::NumDirectMethods() {
93  return (GetDirectMethods() != NULL) ? GetDirectMethods()->GetLength() : 0;
94}
95
96template<VerifyObjectFlags kVerifyFlags>
97inline ObjectArray<ArtMethod>* Class::GetVirtualMethods() {
98  DCHECK(IsLoaded() || IsErroneous());
99  return GetFieldObject<ObjectArray<ArtMethod>>(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_));
100}
101
102inline void Class::SetVirtualMethods(ObjectArray<ArtMethod>* new_virtual_methods) {
103  // TODO: we reassign virtual methods to grow the table for miranda
104  // methods.. they should really just be assigned once.
105  DCHECK_NE(0, new_virtual_methods->GetLength());
106  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_), new_virtual_methods);
107}
108
109inline uint32_t Class::NumVirtualMethods() {
110  return (GetVirtualMethods() != NULL) ? GetVirtualMethods()->GetLength() : 0;
111}
112
113template<VerifyObjectFlags kVerifyFlags>
114inline ArtMethod* Class::GetVirtualMethod(uint32_t i) {
115  DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>());
116  return GetVirtualMethods()->GetWithoutChecks(i);
117}
118
119inline ArtMethod* Class::GetVirtualMethodDuringLinking(uint32_t i) {
120  DCHECK(IsLoaded() || IsErroneous());
121  return GetVirtualMethods()->GetWithoutChecks(i);
122}
123
124inline void Class::SetVirtualMethod(uint32_t i, ArtMethod* f)  // TODO: uint16_t
125    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
126  ObjectArray<ArtMethod>* virtual_methods =
127      GetFieldObject<ObjectArray<ArtMethod>>(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_));
128  virtual_methods->SetWithoutChecks<false>(i, f);
129}
130
131inline ObjectArray<ArtMethod>* Class::GetVTable() {
132  DCHECK(IsResolved() || IsErroneous());
133  return GetFieldObject<ObjectArray<ArtMethod>>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_));
134}
135
136inline ObjectArray<ArtMethod>* Class::GetVTableDuringLinking() {
137  DCHECK(IsLoaded() || IsErroneous());
138  return GetFieldObject<ObjectArray<ArtMethod>>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_));
139}
140
141inline void Class::SetVTable(ObjectArray<ArtMethod>* new_vtable) {
142  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), new_vtable);
143}
144
145inline ArtMethod* Class::GetEmbeddedImTableEntry(uint32_t i) {
146  uint32_t offset = EmbeddedImTableOffset().Uint32Value() + i * sizeof(ImTableEntry);
147  return GetFieldObject<mirror::ArtMethod>(MemberOffset(offset));
148}
149
150inline void Class::SetEmbeddedImTableEntry(uint32_t i, ArtMethod* method) {
151  uint32_t offset = EmbeddedImTableOffset().Uint32Value() + i * sizeof(ImTableEntry);
152  SetFieldObject<false>(MemberOffset(offset), method);
153}
154
155inline bool Class::HasVTable() {
156  return (GetVTable() != nullptr) || ShouldHaveEmbeddedImtAndVTable();
157}
158
159inline int32_t Class::GetVTableLength() {
160  if (ShouldHaveEmbeddedImtAndVTable()) {
161    return GetEmbeddedVTableLength();
162  }
163  return (GetVTable() != nullptr) ? GetVTable()->GetLength() : 0;
164}
165
166inline ArtMethod* Class::GetVTableEntry(uint32_t i) {
167  if (ShouldHaveEmbeddedImtAndVTable()) {
168    return GetEmbeddedVTableEntry(i);
169  }
170  return (GetVTable() != nullptr) ? GetVTable()->Get(i) : nullptr;
171}
172
173inline int32_t Class::GetEmbeddedVTableLength() {
174  return GetField32(EmbeddedVTableLengthOffset());
175}
176
177inline void Class::SetEmbeddedVTableLength(int32_t len) {
178  SetField32<false>(EmbeddedVTableLengthOffset(), len);
179}
180
181inline ArtMethod* Class::GetEmbeddedVTableEntry(uint32_t i) {
182  uint32_t offset = EmbeddedVTableOffset().Uint32Value() + i * sizeof(VTableEntry);
183  return GetFieldObject<mirror::ArtMethod>(MemberOffset(offset));
184}
185
186inline void Class::SetEmbeddedVTableEntry(uint32_t i, ArtMethod* method) {
187  uint32_t offset = EmbeddedVTableOffset().Uint32Value() + i * sizeof(VTableEntry);
188  SetFieldObject<false>(MemberOffset(offset), method);
189  CHECK(method == GetVTableDuringLinking()->Get(i));
190}
191
192inline bool Class::Implements(Class* klass) {
193  DCHECK(klass != NULL);
194  DCHECK(klass->IsInterface()) << PrettyClass(this);
195  // All interfaces implemented directly and by our superclass, and
196  // recursively all super-interfaces of those interfaces, are listed
197  // in iftable_, so we can just do a linear scan through that.
198  int32_t iftable_count = GetIfTableCount();
199  IfTable* iftable = GetIfTable();
200  for (int32_t i = 0; i < iftable_count; i++) {
201    if (iftable->GetInterface(i) == klass) {
202      return true;
203    }
204  }
205  return false;
206}
207
208// Determine whether "this" is assignable from "src", where both of these
209// are array classes.
210//
211// Consider an array class, e.g. Y[][], where Y is a subclass of X.
212//   Y[][]            = Y[][] --> true (identity)
213//   X[][]            = Y[][] --> true (element superclass)
214//   Y                = Y[][] --> false
215//   Y[]              = Y[][] --> false
216//   Object           = Y[][] --> true (everything is an object)
217//   Object[]         = Y[][] --> true
218//   Object[][]       = Y[][] --> true
219//   Object[][][]     = Y[][] --> false (too many []s)
220//   Serializable     = Y[][] --> true (all arrays are Serializable)
221//   Serializable[]   = Y[][] --> true
222//   Serializable[][] = Y[][] --> false (unless Y is Serializable)
223//
224// Don't forget about primitive types.
225//   Object[]         = int[] --> false
226//
227inline bool Class::IsArrayAssignableFromArray(Class* src) {
228  DCHECK(IsArrayClass())  << PrettyClass(this);
229  DCHECK(src->IsArrayClass()) << PrettyClass(src);
230  return GetComponentType()->IsAssignableFrom(src->GetComponentType());
231}
232
233inline bool Class::IsAssignableFromArray(Class* src) {
234  DCHECK(!IsInterface()) << PrettyClass(this);  // handled first in IsAssignableFrom
235  DCHECK(src->IsArrayClass()) << PrettyClass(src);
236  if (!IsArrayClass()) {
237    // If "this" is not also an array, it must be Object.
238    // src's super should be java_lang_Object, since it is an array.
239    Class* java_lang_Object = src->GetSuperClass();
240    DCHECK(java_lang_Object != NULL) << PrettyClass(src);
241    DCHECK(java_lang_Object->GetSuperClass() == NULL) << PrettyClass(src);
242    return this == java_lang_Object;
243  }
244  return IsArrayAssignableFromArray(src);
245}
246
247template <bool throw_on_failure, bool use_referrers_cache>
248inline bool Class::ResolvedFieldAccessTest(Class* access_to, ArtField* field,
249                                           uint32_t field_idx, DexCache* dex_cache) {
250  DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
251  if (UNLIKELY(!this->CanAccess(access_to))) {
252    // The referrer class can't access the field's declaring class but may still be able
253    // to access the field if the FieldId specifies an accessible subclass of the declaring
254    // class rather than the declaring class itself.
255    DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
256    uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_;
257    // The referenced class has already been resolved with the field, get it from the dex cache.
258    Class* dex_access_to = referrer_dex_cache->GetResolvedType(class_idx);
259    DCHECK(dex_access_to != nullptr);
260    if (UNLIKELY(!this->CanAccess(dex_access_to))) {
261      if (throw_on_failure) {
262        ThrowIllegalAccessErrorClass(this, dex_access_to);
263      }
264      return false;
265    }
266    DCHECK_EQ(this->CanAccessMember(access_to, field->GetAccessFlags()),
267              this->CanAccessMember(dex_access_to, field->GetAccessFlags()));
268  }
269  if (LIKELY(this->CanAccessMember(access_to, field->GetAccessFlags()))) {
270    return true;
271  }
272  if (throw_on_failure) {
273    ThrowIllegalAccessErrorField(this, field);
274  }
275  return false;
276}
277
278template <bool throw_on_failure, bool use_referrers_cache, InvokeType throw_invoke_type>
279inline bool Class::ResolvedMethodAccessTest(Class* access_to, ArtMethod* method,
280                                            uint32_t method_idx, DexCache* dex_cache) {
281  COMPILE_ASSERT(throw_on_failure || throw_invoke_type == kStatic, non_default_throw_invoke_type);
282  DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
283  if (UNLIKELY(!this->CanAccess(access_to))) {
284    // The referrer class can't access the method's declaring class but may still be able
285    // to access the method if the MethodId specifies an accessible subclass of the declaring
286    // class rather than the declaring class itself.
287    DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
288    uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_;
289    // The referenced class has already been resolved with the method, get it from the dex cache.
290    Class* dex_access_to = referrer_dex_cache->GetResolvedType(class_idx);
291    DCHECK(dex_access_to != nullptr);
292    if (UNLIKELY(!this->CanAccess(dex_access_to))) {
293      if (throw_on_failure) {
294        ThrowIllegalAccessErrorClassForMethodDispatch(this, dex_access_to,
295                                                      method, throw_invoke_type);
296      }
297      return false;
298    }
299    DCHECK_EQ(this->CanAccessMember(access_to, method->GetAccessFlags()),
300              this->CanAccessMember(dex_access_to, method->GetAccessFlags()));
301  }
302  if (LIKELY(this->CanAccessMember(access_to, method->GetAccessFlags()))) {
303    return true;
304  }
305  if (throw_on_failure) {
306    ThrowIllegalAccessErrorMethod(this, method);
307  }
308  return false;
309}
310
311inline bool Class::CanAccessResolvedField(Class* access_to, ArtField* field,
312                                          DexCache* dex_cache, uint32_t field_idx) {
313  return ResolvedFieldAccessTest<false, false>(access_to, field, field_idx, dex_cache);
314}
315
316inline bool Class::CheckResolvedFieldAccess(Class* access_to, ArtField* field,
317                                            uint32_t field_idx) {
318  return ResolvedFieldAccessTest<true, true>(access_to, field, field_idx, nullptr);
319}
320
321inline bool Class::CanAccessResolvedMethod(Class* access_to, ArtMethod* method,
322                                           DexCache* dex_cache, uint32_t method_idx) {
323  return ResolvedMethodAccessTest<false, false, kStatic>(access_to, method, method_idx, dex_cache);
324}
325
326template <InvokeType throw_invoke_type>
327inline bool Class::CheckResolvedMethodAccess(Class* access_to, ArtMethod* method,
328                                             uint32_t method_idx) {
329  return ResolvedMethodAccessTest<true, true, throw_invoke_type>(access_to, method, method_idx,
330                                                                 nullptr);
331}
332
333inline bool Class::IsSubClass(Class* klass) {
334  DCHECK(!IsInterface()) << PrettyClass(this);
335  DCHECK(!IsArrayClass()) << PrettyClass(this);
336  Class* current = this;
337  do {
338    if (current == klass) {
339      return true;
340    }
341    current = current->GetSuperClass();
342  } while (current != NULL);
343  return false;
344}
345
346inline ArtMethod* Class::FindVirtualMethodForInterface(ArtMethod* method) {
347  Class* declaring_class = method->GetDeclaringClass();
348  DCHECK(declaring_class != NULL) << PrettyClass(this);
349  DCHECK(declaring_class->IsInterface()) << PrettyMethod(method);
350  // TODO cache to improve lookup speed
351  int32_t iftable_count = GetIfTableCount();
352  IfTable* iftable = GetIfTable();
353  for (int32_t i = 0; i < iftable_count; i++) {
354    if (iftable->GetInterface(i) == declaring_class) {
355      return iftable->GetMethodArray(i)->Get(method->GetMethodIndex());
356    }
357  }
358  return NULL;
359}
360
361inline ArtMethod* Class::FindVirtualMethodForVirtual(ArtMethod* method) {
362  DCHECK(!method->GetDeclaringClass()->IsInterface() || method->IsMiranda());
363  // The argument method may from a super class.
364  // Use the index to a potentially overridden one for this instance's class.
365  return GetVTableEntry(method->GetMethodIndex());
366}
367
368inline ArtMethod* Class::FindVirtualMethodForSuper(ArtMethod* method) {
369  DCHECK(!method->GetDeclaringClass()->IsInterface());
370  return GetSuperClass()->GetVTableEntry(method->GetMethodIndex());
371}
372
373inline ArtMethod* Class::FindVirtualMethodForVirtualOrInterface(ArtMethod* method) {
374  if (method->IsDirect()) {
375    return method;
376  }
377  if (method->GetDeclaringClass()->IsInterface() && !method->IsMiranda()) {
378    return FindVirtualMethodForInterface(method);
379  }
380  return FindVirtualMethodForVirtual(method);
381}
382
383inline IfTable* Class::GetIfTable() {
384  return GetFieldObject<IfTable>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_));
385}
386
387inline int32_t Class::GetIfTableCount() {
388  IfTable* iftable = GetIfTable();
389  if (iftable == NULL) {
390    return 0;
391  }
392  return iftable->Count();
393}
394
395inline void Class::SetIfTable(IfTable* new_iftable) {
396  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), new_iftable);
397}
398
399inline ObjectArray<ArtField>* Class::GetIFields() {
400  DCHECK(IsLoaded() || IsErroneous());
401  return GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
402}
403
404inline MemberOffset Class::GetFirstReferenceInstanceFieldOffset() {
405  Class* super_class = GetSuperClass();
406  return (super_class != nullptr)
407      ? MemberOffset(RoundUp(super_class->GetObjectSize(),
408                             sizeof(mirror::HeapReference<mirror::Object>)))
409      : ClassOffset();
410}
411
412inline MemberOffset Class::GetFirstReferenceStaticFieldOffset() {
413  DCHECK(IsResolved());
414  uint32_t base = sizeof(mirror::Class);  // Static fields come after the class.
415  if (ShouldHaveEmbeddedImtAndVTable()) {
416    // Static fields come after the embedded tables.
417    base = mirror::Class::ComputeClassSize(true, GetEmbeddedVTableLength(),
418                                           0, 0, 0);
419  }
420  return MemberOffset(base);
421}
422
423inline MemberOffset Class::GetFirstReferenceStaticFieldOffsetDuringLinking() {
424  DCHECK(IsLoaded());
425  uint32_t base = sizeof(mirror::Class);  // Static fields come after the class.
426  if (ShouldHaveEmbeddedImtAndVTable()) {
427    // Static fields come after the embedded tables.
428    base = mirror::Class::ComputeClassSize(true, GetVTableDuringLinking()->GetLength(),
429                                           0, 0, 0);
430  }
431  return MemberOffset(base);
432}
433
434inline void Class::SetIFields(ObjectArray<ArtField>* new_ifields)
435    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
436  DCHECK(NULL == GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_)));
437  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
438}
439
440inline ObjectArray<ArtField>* Class::GetSFields() {
441  DCHECK(IsLoaded() || IsErroneous());
442  return GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
443}
444
445inline void Class::SetSFields(ObjectArray<ArtField>* new_sfields)
446    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
447  DCHECK((IsRetired() && new_sfields == nullptr) ||
448         (NULL == GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_))));
449  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
450}
451
452inline uint32_t Class::NumStaticFields() {
453  return (GetSFields() != NULL) ? GetSFields()->GetLength() : 0;
454}
455
456
457inline ArtField* Class::GetStaticField(uint32_t i)  // TODO: uint16_t
458    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
459  return GetSFields()->GetWithoutChecks(i);
460}
461
462inline void Class::SetStaticField(uint32_t i, ArtField* f)  // TODO: uint16_t
463    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
464  ObjectArray<ArtField>* sfields= GetFieldObject<ObjectArray<ArtField>>(
465      OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
466  sfields->Set<false>(i, f);
467}
468
469inline uint32_t Class::NumInstanceFields() {
470  return (GetIFields() != NULL) ? GetIFields()->GetLength() : 0;
471}
472
473inline ArtField* Class::GetInstanceField(uint32_t i) {  // TODO: uint16_t
474  DCHECK_NE(NumInstanceFields(), 0U);
475  return GetIFields()->GetWithoutChecks(i);
476}
477
478inline void Class::SetInstanceField(uint32_t i, ArtField* f)  // TODO: uint16_t
479    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
480  ObjectArray<ArtField>* ifields= GetFieldObject<ObjectArray<ArtField>>(
481      OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
482  ifields->Set<false>(i, f);
483}
484
485template<VerifyObjectFlags kVerifyFlags>
486inline uint32_t Class::GetReferenceInstanceOffsets() {
487  DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>());
488  return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_));
489}
490
491inline void Class::SetClinitThreadId(pid_t new_clinit_thread_id) {
492  if (Runtime::Current()->IsActiveTransaction()) {
493    SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id);
494  } else {
495    SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id);
496  }
497}
498
499inline void Class::SetVerifyErrorClass(Class* klass) {
500  CHECK(klass != NULL) << PrettyClass(this);
501  if (Runtime::Current()->IsActiveTransaction()) {
502    SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass);
503  } else {
504    SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass);
505  }
506}
507
508template<VerifyObjectFlags kVerifyFlags>
509inline uint32_t Class::GetAccessFlags() {
510  // Check class is loaded/retired or this is java.lang.String that has a
511  // circularity issue during loading the names of its members
512  DCHECK(IsIdxLoaded<kVerifyFlags>() || IsRetired<kVerifyFlags>() ||
513         IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() ||
514         this == String::GetJavaLangString() ||
515         this == ArtField::GetJavaLangReflectArtField() ||
516         this == ArtMethod::GetJavaLangReflectArtMethod());
517  return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_));
518}
519
520inline String* Class::GetName() {
521  return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(Class, name_));
522}
523inline void Class::SetName(String* name) {
524  if (Runtime::Current()->IsActiveTransaction()) {
525    SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name);
526  } else {
527    SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name);
528  }
529}
530
531template<VerifyObjectFlags kVerifyFlags>
532inline Primitive::Type Class::GetPrimitiveType() {
533  DCHECK_EQ(sizeof(Primitive::Type), sizeof(int32_t));
534  return static_cast<Primitive::Type>(
535      GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_)));
536}
537
538inline void Class::CheckObjectAlloc() {
539  DCHECK(!IsArrayClass())
540      << PrettyClass(this)
541      << "A array shouldn't be allocated through this "
542      << "as it requires a pre-fence visitor that sets the class size.";
543  DCHECK(!IsClassClass())
544      << PrettyClass(this)
545      << "A class object shouldn't be allocated through this "
546      << "as it requires a pre-fence visitor that sets the class size.";
547  DCHECK(IsInstantiable()) << PrettyClass(this);
548  // TODO: decide whether we want this check. It currently fails during bootstrap.
549  // DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass(this);
550  DCHECK_GE(this->object_size_, sizeof(Object));
551}
552
553template<bool kIsInstrumented, bool kCheckAddFinalizer>
554inline Object* Class::Alloc(Thread* self, gc::AllocatorType allocator_type) {
555  CheckObjectAlloc();
556  gc::Heap* heap = Runtime::Current()->GetHeap();
557  const bool add_finalizer = kCheckAddFinalizer && IsFinalizable();
558  if (!kCheckAddFinalizer) {
559    DCHECK(!IsFinalizable());
560  }
561  mirror::Object* obj =
562      heap->AllocObjectWithAllocator<kIsInstrumented, false>(self, this, this->object_size_,
563                                                             allocator_type, VoidFunctor());
564  if (add_finalizer && LIKELY(obj != nullptr)) {
565    heap->AddFinalizerReference(self, &obj);
566  }
567  return obj;
568}
569
570inline Object* Class::AllocObject(Thread* self) {
571  return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentAllocator());
572}
573
574inline Object* Class::AllocNonMovableObject(Thread* self) {
575  return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentNonMovingAllocator());
576}
577
578inline uint32_t Class::ComputeClassSize(bool has_embedded_tables,
579                                        uint32_t num_vtable_entries,
580                                        uint32_t num_32bit_static_fields,
581                                        uint32_t num_64bit_static_fields,
582                                        uint32_t num_ref_static_fields) {
583  // Space used by java.lang.Class and its instance fields.
584  uint32_t size = sizeof(Class);
585  // Space used by embedded tables.
586  if (has_embedded_tables) {
587    uint32_t embedded_imt_size = kImtSize * sizeof(ImTableEntry);
588    uint32_t embedded_vtable_size = num_vtable_entries * sizeof(VTableEntry);
589    size += embedded_imt_size +
590            sizeof(int32_t) /* vtable len */ +
591            embedded_vtable_size;
592  }
593  // Space used by reference statics.
594  size +=  num_ref_static_fields * sizeof(HeapReference<Object>);
595  // Possible pad for alignment.
596  if (((size & 7) != 0) && (num_64bit_static_fields > 0)) {
597    size += sizeof(uint32_t);
598    if (num_32bit_static_fields != 0) {
599      // Shuffle one 32 bit static field forward.
600      num_32bit_static_fields--;
601    }
602  }
603  // Space used for primitive static fields.
604  size += (num_32bit_static_fields * sizeof(uint32_t)) +
605      (num_64bit_static_fields * sizeof(uint64_t));
606  return size;
607}
608
609template <bool kVisitClass, typename Visitor>
610inline void Class::VisitReferences(mirror::Class* klass, const Visitor& visitor) {
611  // Visit the static fields first so that we don't overwrite the SFields / IFields instance
612  // fields.
613  VisitInstanceFieldsReferences<kVisitClass>(klass, visitor);
614  if (!IsTemp()) {
615    // Temp classes don't ever populate imt/vtable or static fields and they are not even
616    // allocated with the right size for those.
617    VisitStaticFieldsReferences<kVisitClass>(this, visitor);
618    if (ShouldHaveEmbeddedImtAndVTable()) {
619      VisitEmbeddedImtAndVTable(visitor);
620    }
621  }
622}
623
624template<typename Visitor>
625inline void Class::VisitEmbeddedImtAndVTable(const Visitor& visitor) {
626  uint32_t pos = sizeof(mirror::Class);
627
628  size_t count = kImtSize;
629  for (size_t i = 0; i < count; ++i) {
630    MemberOffset offset = MemberOffset(pos);
631    visitor(this, offset, true);
632    pos += sizeof(ImTableEntry);
633  }
634
635  // Skip vtable length.
636  pos += sizeof(int32_t);
637
638  count = GetEmbeddedVTableLength();
639  for (size_t i = 0; i < count; ++i) {
640    MemberOffset offset = MemberOffset(pos);
641    visitor(this, offset, true);
642    pos += sizeof(VTableEntry);
643  }
644}
645
646template<ReadBarrierOption kReadBarrierOption>
647inline bool Class::IsArtFieldClass() const {
648  return this == ArtField::GetJavaLangReflectArtField<kReadBarrierOption>();
649}
650
651template<ReadBarrierOption kReadBarrierOption>
652inline bool Class::IsArtMethodClass() const {
653  return this == ArtMethod::GetJavaLangReflectArtMethod<kReadBarrierOption>();
654}
655
656template<ReadBarrierOption kReadBarrierOption>
657inline bool Class::IsReferenceClass() const {
658  return this == Reference::GetJavaLangRefReference<kReadBarrierOption>();
659}
660
661template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
662inline bool Class::IsClassClass() {
663  Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
664      template GetClass<kVerifyFlags, kReadBarrierOption>();
665  return this == java_lang_Class;
666}
667
668inline const DexFile& Class::GetDexFile() {
669  return *GetDexCache()->GetDexFile();
670}
671
672inline bool Class::DescriptorEquals(const char* match) {
673  if (IsArrayClass()) {
674    return match[0] == '[' && GetComponentType()->DescriptorEquals(match + 1);
675  } else if (IsPrimitive()) {
676    return strcmp(Primitive::Descriptor(GetPrimitiveType()), match) == 0;
677  } else if (IsProxyClass()) {
678    return Runtime::Current()->GetClassLinker()->GetDescriptorForProxy(this) == match;
679  } else {
680    const DexFile& dex_file = GetDexFile();
681    const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
682    return strcmp(dex_file.GetTypeDescriptor(type_id), match) == 0;
683  }
684}
685
686inline void Class::AssertInitializedOrInitializingInThread(Thread* self) {
687  if (kIsDebugBuild && !IsInitialized()) {
688    CHECK(IsInitializing()) << PrettyClass(this) << " is not initializing: " << GetStatus();
689    CHECK_EQ(GetClinitThreadId(), self->GetTid()) << PrettyClass(this)
690                                                  << " is initializing in a different thread";
691  }
692}
693
694inline ObjectArray<Class>* Class::GetInterfaces() {
695  CHECK(IsProxyClass());
696  // First static field.
697  DCHECK(GetSFields()->Get(0)->IsArtField());
698  DCHECK_STREQ(GetSFields()->Get(0)->GetName(), "interfaces");
699  MemberOffset field_offset = GetSFields()->Get(0)->GetOffset();
700  return GetFieldObject<ObjectArray<Class>>(field_offset);
701}
702
703inline ObjectArray<ObjectArray<Class>>* Class::GetThrows() {
704  CHECK(IsProxyClass());
705  // Second static field.
706  DCHECK(GetSFields()->Get(1)->IsArtField());
707  DCHECK_STREQ(GetSFields()->Get(1)->GetName(), "throws");
708  MemberOffset field_offset = GetSFields()->Get(1)->GetOffset();
709  return GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset);
710}
711
712inline MemberOffset Class::GetDisableIntrinsicFlagOffset() {
713  CHECK(IsReferenceClass());
714  // First static field
715  DCHECK(GetSFields()->Get(0)->IsArtField());
716  DCHECK_STREQ(GetSFields()->Get(0)->GetName(), "disableIntrinsic");
717  return GetSFields()->Get(0)->GetOffset();
718}
719
720inline MemberOffset Class::GetSlowPathFlagOffset() {
721  CHECK(IsReferenceClass());
722  // Second static field
723  DCHECK(GetSFields()->Get(1)->IsArtField());
724  DCHECK_STREQ(GetSFields()->Get(1)->GetName(), "slowPathEnabled");
725  return GetSFields()->Get(1)->GetOffset();
726}
727
728inline bool Class::GetSlowPathEnabled() {
729  return GetField32(GetSlowPathFlagOffset());
730}
731
732inline void Class::SetSlowPath(bool enabled) {
733  SetField32<false>(GetSlowPathFlagOffset(), enabled);
734}
735
736inline void Class::InitializeClassVisitor::operator()(
737    mirror::Object* obj, size_t usable_size) const {
738  DCHECK_LE(class_size_, usable_size);
739  // Avoid AsClass as object is not yet in live bitmap or allocation stack.
740  mirror::Class* klass = down_cast<mirror::Class*>(obj);
741  // DCHECK(klass->IsClass());
742  klass->SetClassSize(class_size_);
743  klass->SetPrimitiveType(Primitive::kPrimNot);  // Default to not being primitive.
744  klass->SetDexClassDefIndex(DexFile::kDexNoIndex16);  // Default to no valid class def index.
745  klass->SetDexTypeIndex(DexFile::kDexNoIndex16);  // Default to no valid type index.
746}
747
748inline void Class::SetAccessFlags(uint32_t new_access_flags) {
749  // Called inside a transaction when setting pre-verified flag during boot image compilation.
750  if (Runtime::Current()->IsActiveTransaction()) {
751    SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), new_access_flags);
752  } else {
753    SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), new_access_flags);
754  }
755}
756
757inline uint32_t Class::NumDirectInterfaces() {
758  if (IsPrimitive()) {
759    return 0;
760  } else if (IsArrayClass()) {
761    return 2;
762  } else if (IsProxyClass()) {
763    mirror::ObjectArray<mirror::Class>* interfaces = GetInterfaces();
764    return interfaces != nullptr ? interfaces->GetLength() : 0;
765  } else {
766    const DexFile::TypeList* interfaces = GetInterfaceTypeList();
767    if (interfaces == nullptr) {
768      return 0;
769    } else {
770      return interfaces->Size();
771    }
772  }
773}
774
775inline void Class::SetDexCacheStrings(ObjectArray<String>* new_dex_cache_strings) {
776  SetFieldObject<false>(DexCacheStringsOffset(), new_dex_cache_strings);
777}
778
779inline ObjectArray<String>* Class::GetDexCacheStrings() {
780  return GetFieldObject<ObjectArray<String>>(DexCacheStringsOffset());
781}
782
783}  // namespace mirror
784}  // namespace art
785
786#endif  // ART_RUNTIME_MIRROR_CLASS_INL_H_
787