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