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