class-inl.h revision d85614222fa062ec809af9d65f04ab6b7dc1c248
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()->Get(i);
117}
118
119inline ArtMethod* Class::GetVirtualMethodDuringLinking(uint32_t i) {
120  DCHECK(IsLoaded() || IsErroneous());
121  return GetVirtualMethods()->Get(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->Set<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 ObjectArray<ArtMethod>* Class::GetImTable() {
146  return GetFieldObject<ObjectArray<ArtMethod>>(OFFSET_OF_OBJECT_MEMBER(Class, imtable_));
147}
148
149inline void Class::SetImTable(ObjectArray<ArtMethod>* new_imtable) {
150  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, imtable_), new_imtable);
151}
152
153inline ArtMethod* Class::GetEmbeddedImTableEntry(uint32_t i) {
154  uint32_t offset = EmbeddedImTableOffset().Uint32Value() + i * sizeof(ImTableEntry);
155  return GetFieldObject<mirror::ArtMethod>(MemberOffset(offset));
156}
157
158inline void Class::SetEmbeddedImTableEntry(uint32_t i, ArtMethod* method) {
159  uint32_t offset = EmbeddedImTableOffset().Uint32Value() + i * sizeof(ImTableEntry);
160  SetFieldObject<false>(MemberOffset(offset), method);
161  CHECK(method == GetImTable()->Get(i));
162}
163
164inline void Class::SetEmbeddedVTableEntry(uint32_t i, ArtMethod* method) {
165  uint32_t offset = EmbeddedVTableOffset().Uint32Value() + i * sizeof(VTableEntry);
166  SetFieldObject<false>(MemberOffset(offset), method);
167  CHECK(method == GetVTableDuringLinking()->Get(i));
168}
169
170inline bool Class::Implements(Class* klass) {
171  DCHECK(klass != NULL);
172  DCHECK(klass->IsInterface()) << PrettyClass(this);
173  // All interfaces implemented directly and by our superclass, and
174  // recursively all super-interfaces of those interfaces, are listed
175  // in iftable_, so we can just do a linear scan through that.
176  int32_t iftable_count = GetIfTableCount();
177  IfTable* iftable = GetIfTable();
178  for (int32_t i = 0; i < iftable_count; i++) {
179    if (iftable->GetInterface(i) == klass) {
180      return true;
181    }
182  }
183  return false;
184}
185
186// Determine whether "this" is assignable from "src", where both of these
187// are array classes.
188//
189// Consider an array class, e.g. Y[][], where Y is a subclass of X.
190//   Y[][]            = Y[][] --> true (identity)
191//   X[][]            = Y[][] --> true (element superclass)
192//   Y                = Y[][] --> false
193//   Y[]              = Y[][] --> false
194//   Object           = Y[][] --> true (everything is an object)
195//   Object[]         = Y[][] --> true
196//   Object[][]       = Y[][] --> true
197//   Object[][][]     = Y[][] --> false (too many []s)
198//   Serializable     = Y[][] --> true (all arrays are Serializable)
199//   Serializable[]   = Y[][] --> true
200//   Serializable[][] = Y[][] --> false (unless Y is Serializable)
201//
202// Don't forget about primitive types.
203//   Object[]         = int[] --> false
204//
205inline bool Class::IsArrayAssignableFromArray(Class* src) {
206  DCHECK(IsArrayClass())  << PrettyClass(this);
207  DCHECK(src->IsArrayClass()) << PrettyClass(src);
208  return GetComponentType()->IsAssignableFrom(src->GetComponentType());
209}
210
211inline bool Class::IsAssignableFromArray(Class* src) {
212  DCHECK(!IsInterface()) << PrettyClass(this);  // handled first in IsAssignableFrom
213  DCHECK(src->IsArrayClass()) << PrettyClass(src);
214  if (!IsArrayClass()) {
215    // If "this" is not also an array, it must be Object.
216    // src's super should be java_lang_Object, since it is an array.
217    Class* java_lang_Object = src->GetSuperClass();
218    DCHECK(java_lang_Object != NULL) << PrettyClass(src);
219    DCHECK(java_lang_Object->GetSuperClass() == NULL) << PrettyClass(src);
220    return this == java_lang_Object;
221  }
222  return IsArrayAssignableFromArray(src);
223}
224
225template <bool throw_on_failure, bool use_referrers_cache>
226inline bool Class::ResolvedFieldAccessTest(Class* access_to, ArtField* field,
227                                           uint32_t field_idx, DexCache* dex_cache) {
228  DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
229  if (UNLIKELY(!this->CanAccess(access_to))) {
230    // The referrer class can't access the field's declaring class but may still be able
231    // to access the field if the FieldId specifies an accessible subclass of the declaring
232    // class rather than the declaring class itself.
233    DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
234    uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_;
235    // The referenced class has already been resolved with the field, get it from the dex cache.
236    Class* dex_access_to = referrer_dex_cache->GetResolvedType(class_idx);
237    DCHECK(dex_access_to != nullptr);
238    if (UNLIKELY(!this->CanAccess(dex_access_to))) {
239      if (throw_on_failure) {
240        ThrowIllegalAccessErrorClass(this, dex_access_to);
241      }
242      return false;
243    }
244    DCHECK_EQ(this->CanAccessMember(access_to, field->GetAccessFlags()),
245              this->CanAccessMember(dex_access_to, field->GetAccessFlags()));
246  }
247  if (LIKELY(this->CanAccessMember(access_to, field->GetAccessFlags()))) {
248    return true;
249  }
250  if (throw_on_failure) {
251    ThrowIllegalAccessErrorField(this, field);
252  }
253  return false;
254}
255
256template <bool throw_on_failure, bool use_referrers_cache, InvokeType throw_invoke_type>
257inline bool Class::ResolvedMethodAccessTest(Class* access_to, ArtMethod* method,
258                                            uint32_t method_idx, DexCache* dex_cache) {
259  COMPILE_ASSERT(throw_on_failure || throw_invoke_type == kStatic, non_default_throw_invoke_type);
260  DCHECK_EQ(use_referrers_cache, dex_cache == nullptr);
261  if (UNLIKELY(!this->CanAccess(access_to))) {
262    // The referrer class can't access the method's declaring class but may still be able
263    // to access the method if the MethodId specifies an accessible subclass of the declaring
264    // class rather than the declaring class itself.
265    DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache;
266    uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_;
267    // The referenced class has already been resolved with the method, get it from the dex cache.
268    Class* dex_access_to = referrer_dex_cache->GetResolvedType(class_idx);
269    DCHECK(dex_access_to != nullptr);
270    if (UNLIKELY(!this->CanAccess(dex_access_to))) {
271      if (throw_on_failure) {
272        ThrowIllegalAccessErrorClassForMethodDispatch(this, dex_access_to,
273                                                      method, throw_invoke_type);
274      }
275      return false;
276    }
277    DCHECK_EQ(this->CanAccessMember(access_to, method->GetAccessFlags()),
278              this->CanAccessMember(dex_access_to, method->GetAccessFlags()));
279  }
280  if (LIKELY(this->CanAccessMember(access_to, method->GetAccessFlags()))) {
281    return true;
282  }
283  if (throw_on_failure) {
284    ThrowIllegalAccessErrorMethod(this, method);
285  }
286  return false;
287}
288
289inline bool Class::CanAccessResolvedField(Class* access_to, ArtField* field,
290                                          DexCache* dex_cache, uint32_t field_idx) {
291  return ResolvedFieldAccessTest<false, false>(access_to, field, field_idx, dex_cache);
292}
293
294inline bool Class::CheckResolvedFieldAccess(Class* access_to, ArtField* field,
295                                            uint32_t field_idx) {
296  return ResolvedFieldAccessTest<true, true>(access_to, field, field_idx, nullptr);
297}
298
299inline bool Class::CanAccessResolvedMethod(Class* access_to, ArtMethod* method,
300                                           DexCache* dex_cache, uint32_t method_idx) {
301  return ResolvedMethodAccessTest<false, false, kStatic>(access_to, method, method_idx, dex_cache);
302}
303
304template <InvokeType throw_invoke_type>
305inline bool Class::CheckResolvedMethodAccess(Class* access_to, ArtMethod* method,
306                                             uint32_t method_idx) {
307  return ResolvedMethodAccessTest<true, true, throw_invoke_type>(access_to, method, method_idx,
308                                                                 nullptr);
309}
310
311inline bool Class::IsSubClass(Class* klass) {
312  DCHECK(!IsInterface()) << PrettyClass(this);
313  DCHECK(!IsArrayClass()) << PrettyClass(this);
314  Class* current = this;
315  do {
316    if (current == klass) {
317      return true;
318    }
319    current = current->GetSuperClass();
320  } while (current != NULL);
321  return false;
322}
323
324inline ArtMethod* Class::FindVirtualMethodForInterface(ArtMethod* method) {
325  Class* declaring_class = method->GetDeclaringClass();
326  DCHECK(declaring_class != NULL) << PrettyClass(this);
327  DCHECK(declaring_class->IsInterface()) << PrettyMethod(method);
328  // TODO cache to improve lookup speed
329  int32_t iftable_count = GetIfTableCount();
330  IfTable* iftable = GetIfTable();
331  for (int32_t i = 0; i < iftable_count; i++) {
332    if (iftable->GetInterface(i) == declaring_class) {
333      return iftable->GetMethodArray(i)->Get(method->GetMethodIndex());
334    }
335  }
336  return NULL;
337}
338
339inline ArtMethod* Class::FindVirtualMethodForVirtual(ArtMethod* method) {
340  DCHECK(!method->GetDeclaringClass()->IsInterface() || method->IsMiranda());
341  // The argument method may from a super class.
342  // Use the index to a potentially overridden one for this instance's class.
343  return GetVTable()->Get(method->GetMethodIndex());
344}
345
346inline ArtMethod* Class::FindVirtualMethodForSuper(ArtMethod* method) {
347  DCHECK(!method->GetDeclaringClass()->IsInterface());
348  return GetSuperClass()->GetVTable()->Get(method->GetMethodIndex());
349}
350
351inline ArtMethod* Class::FindVirtualMethodForVirtualOrInterface(ArtMethod* method) {
352  if (method->IsDirect()) {
353    return method;
354  }
355  if (method->GetDeclaringClass()->IsInterface() && !method->IsMiranda()) {
356    return FindVirtualMethodForInterface(method);
357  }
358  return FindVirtualMethodForVirtual(method);
359}
360
361inline IfTable* Class::GetIfTable() {
362  return GetFieldObject<IfTable>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_));
363}
364
365inline int32_t Class::GetIfTableCount() {
366  IfTable* iftable = GetIfTable();
367  if (iftable == NULL) {
368    return 0;
369  }
370  return iftable->Count();
371}
372
373inline void Class::SetIfTable(IfTable* new_iftable) {
374  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), new_iftable);
375}
376
377inline ObjectArray<ArtField>* Class::GetIFields() {
378  DCHECK(IsLoaded() || IsErroneous());
379  return GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
380}
381
382inline void Class::SetIFields(ObjectArray<ArtField>* new_ifields)
383    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
384  DCHECK(NULL == GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_)));
385  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
386}
387
388inline ObjectArray<ArtField>* Class::GetSFields() {
389  DCHECK(IsLoaded() || IsErroneous());
390  return GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
391}
392
393inline void Class::SetSFields(ObjectArray<ArtField>* new_sfields)
394    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
395  DCHECK((IsRetired() && new_sfields == nullptr) ||
396         (NULL == GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_))));
397  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
398}
399
400inline uint32_t Class::NumStaticFields() {
401  return (GetSFields() != NULL) ? GetSFields()->GetLength() : 0;
402}
403
404
405inline ArtField* Class::GetStaticField(uint32_t i)  // TODO: uint16_t
406    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
407  return GetSFields()->GetWithoutChecks(i);
408}
409
410inline void Class::SetStaticField(uint32_t i, ArtField* f)  // TODO: uint16_t
411    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
412  ObjectArray<ArtField>* sfields= GetFieldObject<ObjectArray<ArtField>>(
413      OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
414  sfields->Set<false>(i, f);
415}
416
417inline uint32_t Class::NumInstanceFields() {
418  return (GetIFields() != NULL) ? GetIFields()->GetLength() : 0;
419}
420
421inline ArtField* Class::GetInstanceField(uint32_t i) {  // TODO: uint16_t
422  DCHECK_NE(NumInstanceFields(), 0U);
423  return GetIFields()->GetWithoutChecks(i);
424}
425
426inline void Class::SetInstanceField(uint32_t i, ArtField* f)  // TODO: uint16_t
427    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
428  ObjectArray<ArtField>* ifields= GetFieldObject<ObjectArray<ArtField>>(
429      OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
430  ifields->Set<false>(i, f);
431}
432
433template<VerifyObjectFlags kVerifyFlags>
434inline uint32_t Class::GetReferenceInstanceOffsets() {
435  DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>());
436  return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_));
437}
438
439inline void Class::SetClinitThreadId(pid_t new_clinit_thread_id) {
440  if (Runtime::Current()->IsActiveTransaction()) {
441    SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id);
442  } else {
443    SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id);
444  }
445}
446
447inline void Class::SetVerifyErrorClass(Class* klass) {
448  CHECK(klass != NULL) << PrettyClass(this);
449  if (Runtime::Current()->IsActiveTransaction()) {
450    SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass);
451  } else {
452    SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass);
453  }
454}
455
456template<VerifyObjectFlags kVerifyFlags>
457inline uint32_t Class::GetAccessFlags() {
458  // Check class is loaded/retired or this is java.lang.String that has a
459  // circularity issue during loading the names of its members
460  DCHECK(IsIdxLoaded<kVerifyFlags>() || IsRetired<kVerifyFlags>() ||
461         IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() ||
462         this == String::GetJavaLangString() ||
463         this == ArtField::GetJavaLangReflectArtField() ||
464         this == ArtMethod::GetJavaLangReflectArtMethod());
465  return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_));
466}
467
468inline String* Class::GetName() {
469  return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(Class, name_));
470}
471inline void Class::SetName(String* name) {
472  if (Runtime::Current()->IsActiveTransaction()) {
473    SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name);
474  } else {
475    SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name);
476  }
477}
478
479template<VerifyObjectFlags kVerifyFlags>
480inline Primitive::Type Class::GetPrimitiveType() {
481  DCHECK_EQ(sizeof(Primitive::Type), sizeof(int32_t));
482  return static_cast<Primitive::Type>(
483      GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_)));
484}
485
486inline void Class::CheckObjectAlloc() {
487  DCHECK(!IsArrayClass())
488      << PrettyClass(this)
489      << "A array shouldn't be allocated through this "
490      << "as it requires a pre-fence visitor that sets the class size.";
491  DCHECK(!IsClassClass())
492      << PrettyClass(this)
493      << "A class object shouldn't be allocated through this "
494      << "as it requires a pre-fence visitor that sets the class size.";
495  DCHECK(IsInstantiable()) << PrettyClass(this);
496  // TODO: decide whether we want this check. It currently fails during bootstrap.
497  // DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass(this);
498  DCHECK_GE(this->object_size_, sizeof(Object));
499}
500
501template<bool kIsInstrumented, bool kCheckAddFinalizer>
502inline Object* Class::Alloc(Thread* self, gc::AllocatorType allocator_type) {
503  CheckObjectAlloc();
504  gc::Heap* heap = Runtime::Current()->GetHeap();
505  const bool add_finalizer = kCheckAddFinalizer && IsFinalizable();
506  if (!kCheckAddFinalizer) {
507    DCHECK(!IsFinalizable());
508  }
509  mirror::Object* obj =
510      heap->AllocObjectWithAllocator<kIsInstrumented, false>(self, this, this->object_size_,
511                                                             allocator_type, VoidFunctor());
512  if (add_finalizer && LIKELY(obj != nullptr)) {
513    heap->AddFinalizerReference(self, &obj);
514  }
515  return obj;
516}
517
518inline Object* Class::AllocObject(Thread* self) {
519  return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentAllocator());
520}
521
522inline Object* Class::AllocNonMovableObject(Thread* self) {
523  return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentNonMovingAllocator());
524}
525
526inline uint32_t Class::ComputeClassSize(bool has_embedded_tables,
527                                        uint32_t num_vtable_entries,
528                                        uint32_t num_32bit_static_fields,
529                                        uint32_t num_64bit_static_fields,
530                                        uint32_t num_ref_static_fields) {
531  // Space used by java.lang.Class and its instance fields.
532  uint32_t size = sizeof(Class);
533  // Space used by embedded tables.
534  if (has_embedded_tables) {
535    uint32_t embedded_imt_size = kImtSize * sizeof(ImTableEntry);
536    uint32_t embedded_vtable_size = num_vtable_entries * sizeof(VTableEntry);
537    size += embedded_imt_size + embedded_vtable_size;
538  }
539  // Space used by reference statics.
540  size +=  num_ref_static_fields * sizeof(HeapReference<Object>);
541  // Possible pad for alignment.
542  if (((size & 7) != 0) && (num_64bit_static_fields > 0) && (num_32bit_static_fields == 0)) {
543    size += sizeof(uint32_t);
544  }
545  // Space used for primitive static fields.
546  size += (num_32bit_static_fields * sizeof(uint32_t)) +
547      (num_64bit_static_fields * sizeof(uint64_t));
548  return size;
549}
550
551template <bool kVisitClass, typename Visitor>
552inline void Class::VisitReferences(mirror::Class* klass, const Visitor& visitor) {
553  // Visit the static fields first so that we don't overwrite the SFields / IFields instance
554  // fields.
555  VisitInstanceFieldsReferences<kVisitClass>(klass, visitor);
556  if (!IsTemp()) {
557    // Temp classes don't ever populate imt/vtable or static fields and they are not even
558    // allocated with the right size for those.
559    VisitStaticFieldsReferences<kVisitClass>(this, visitor);
560    if (ShouldHaveEmbeddedImtAndVTable()) {
561      VisitEmbeddedImtAndVTable(visitor);
562    }
563  }
564}
565
566template<typename Visitor>
567inline void Class::VisitEmbeddedImtAndVTable(const Visitor& visitor) {
568  uint32_t pos = sizeof(mirror::Class);
569
570  size_t count = kImtSize;
571  for (size_t i = 0; i < count; ++i) {
572    MemberOffset offset = MemberOffset(pos);
573    visitor(this, offset, true);
574    pos += sizeof(ImTableEntry);
575  }
576
577  count = ((GetVTable() != NULL) ? GetVTable()->GetLength() : 0);
578  for (size_t i = 0; i < count; ++i) {
579    MemberOffset offset = MemberOffset(pos);
580    visitor(this, offset, true);
581    pos += sizeof(VTableEntry);
582  }
583}
584
585template<ReadBarrierOption kReadBarrierOption>
586inline bool Class::IsArtFieldClass() const {
587  return this == ArtField::GetJavaLangReflectArtField<kReadBarrierOption>();
588}
589
590template<ReadBarrierOption kReadBarrierOption>
591inline bool Class::IsArtMethodClass() const {
592  return this == ArtMethod::GetJavaLangReflectArtMethod<kReadBarrierOption>();
593}
594
595template<ReadBarrierOption kReadBarrierOption>
596inline bool Class::IsReferenceClass() const {
597  return this == Reference::GetJavaLangRefReference<kReadBarrierOption>();
598}
599
600template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
601inline bool Class::IsClassClass() {
602  Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
603      template GetClass<kVerifyFlags, kReadBarrierOption>();
604  return this == java_lang_Class;
605}
606
607inline const DexFile& Class::GetDexFile() {
608  return *GetDexCache()->GetDexFile();
609}
610
611inline bool Class::DescriptorEquals(const char* match) {
612  if (UNLIKELY(IsArrayClass())) {
613    return match[0] == '[' && GetComponentType()->DescriptorEquals(match + 1);
614  } else if (UNLIKELY(IsPrimitive())) {
615    return strcmp(Primitive::Descriptor(GetPrimitiveType()), match) == 0;
616  } else if (UNLIKELY(IsProxyClass())) {
617    return Runtime::Current()->GetClassLinker()->GetDescriptorForProxy(this) == match;
618  } else {
619    const DexFile& dex_file = GetDexFile();
620    const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
621    return strcmp(dex_file.GetTypeDescriptor(type_id), match) == 0;
622  }
623}
624
625inline void Class::AssertInitializedOrInitializingInThread(Thread* self) {
626  if (kIsDebugBuild && !IsInitialized()) {
627    CHECK(IsInitializing()) << PrettyClass(this) << " is not initializing: " << GetStatus();
628    CHECK_EQ(GetClinitThreadId(), self->GetTid()) << PrettyClass(this)
629                                                  << " is initializing in a different thread";
630  }
631}
632
633inline ObjectArray<Class>* Class::GetInterfaces() {
634  CHECK(IsProxyClass());
635  // First static field.
636  DCHECK(GetSFields()->Get(0)->IsArtField());
637  DCHECK_STREQ(GetSFields()->Get(0)->GetName(), "interfaces");
638  MemberOffset field_offset = GetSFields()->Get(0)->GetOffset();
639  return GetFieldObject<ObjectArray<Class>>(field_offset);
640}
641
642inline ObjectArray<ObjectArray<Class>>* Class::GetThrows() {
643  CHECK(IsProxyClass());
644  // Second static field.
645  DCHECK(GetSFields()->Get(1)->IsArtField());
646  DCHECK_STREQ(GetSFields()->Get(1)->GetName(), "throws");
647  MemberOffset field_offset = GetSFields()->Get(1)->GetOffset();
648  return GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset);
649}
650
651inline MemberOffset Class::GetDisableIntrinsicFlagOffset() {
652  CHECK(IsReferenceClass());
653  // First static field
654  DCHECK(GetSFields()->Get(0)->IsArtField());
655  DCHECK_STREQ(GetSFields()->Get(0)->GetName(), "disableIntrinsic");
656  return GetSFields()->Get(0)->GetOffset();
657}
658
659inline MemberOffset Class::GetSlowPathFlagOffset() {
660  CHECK(IsReferenceClass());
661  // Second static field
662  DCHECK(GetSFields()->Get(1)->IsArtField());
663  DCHECK_STREQ(GetSFields()->Get(1)->GetName(), "slowPathEnabled");
664  return GetSFields()->Get(1)->GetOffset();
665}
666
667inline bool Class::GetSlowPathEnabled() {
668  return GetField32(GetSlowPathFlagOffset());
669}
670
671inline void Class::SetSlowPath(bool enabled) {
672  SetField32<false>(GetSlowPathFlagOffset(), enabled);
673}
674
675inline void Class::InitializeClassVisitor::operator()(
676    mirror::Object* obj, size_t usable_size) const {
677  DCHECK_LE(class_size_, usable_size);
678  // Avoid AsClass as object is not yet in live bitmap or allocation stack.
679  mirror::Class* klass = down_cast<mirror::Class*>(obj);
680  // DCHECK(klass->IsClass());
681  klass->SetClassSize(class_size_);
682  klass->SetPrimitiveType(Primitive::kPrimNot);  // Default to not being primitive.
683  klass->SetDexClassDefIndex(DexFile::kDexNoIndex16);  // Default to no valid class def index.
684  klass->SetDexTypeIndex(DexFile::kDexNoIndex16);  // Default to no valid type index.
685}
686
687}  // namespace mirror
688}  // namespace art
689
690#endif  // ART_RUNTIME_MIRROR_CLASS_INL_H_
691