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