diff options
-rw-r--r-- | runtime/class_linker.cc | 19 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 1 | ||||
-rw-r--r-- | runtime/mirror/class-inl.h | 11 | ||||
-rw-r--r-- | runtime/mirror/class.h | 2 |
4 files changed, 18 insertions, 15 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index d5efb685c8..c265c0e5dc 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -5973,17 +5973,6 @@ ClassTable* ClassLinker::ClassTableForClassLoader(ObjPtr<mirror::ClassLoader> cl return class_loader == nullptr ? boot_class_table_.get() : class_loader->GetClassTable(); } -static ImTable* FindSuperImt(ObjPtr<mirror::Class> klass, PointerSize pointer_size) - REQUIRES_SHARED(Locks::mutator_lock_) { - while (klass->HasSuperClass()) { - klass = klass->GetSuperClass(); - if (klass->ShouldHaveImt()) { - return klass->GetImt(pointer_size); - } - } - return nullptr; -} - bool ClassLinker::LinkClass(Thread* self, const char* descriptor, Handle<mirror::Class> klass, @@ -6019,7 +6008,7 @@ bool ClassLinker::LinkClass(Thread* self, // will possibly create a table that is incorrect for either of the classes. // Same IMT with new_conflict does not happen very often. if (!new_conflict) { - ImTable* super_imt = FindSuperImt(klass.Get(), image_pointer_size_); + ImTable* super_imt = klass->FindSuperImt(image_pointer_size_); if (super_imt != nullptr) { bool imt_equals = true; for (size_t i = 0; i < ImTable::kSize && imt_equals; ++i) { @@ -6393,9 +6382,8 @@ void ClassLinker::FillIMTAndConflictTables(ObjPtr<mirror::Class> klass) { // Compare the IMT with the super class including the conflict methods. If they are equivalent, // we can just use the same pointer. ImTable* imt = nullptr; - ObjPtr<mirror::Class> super_class = klass->GetSuperClass(); - if (super_class != nullptr && super_class->ShouldHaveImt()) { - ImTable* super_imt = super_class->GetImt(image_pointer_size_); + ImTable* super_imt = klass->FindSuperImt(image_pointer_size_); + if (super_imt != nullptr) { bool same = true; for (size_t i = 0; same && i < ImTable::kSize; ++i) { ArtMethod* method = imt_data[i]; @@ -6424,6 +6412,7 @@ void ClassLinker::FillIMTAndConflictTables(ObjPtr<mirror::Class> klass) { if (imt == nullptr) { imt = klass->GetImt(image_pointer_size_); DCHECK(imt != nullptr); + DCHECK_NE(imt, super_imt); imt->Populate(imt_data, image_pointer_size_); } else { klass->SetImt(imt, image_pointer_size_); diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index f0c5953f87..f08b0056e9 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -2293,6 +2293,7 @@ extern "C" TwoWordReturn artInvokeInterfaceTrampoline(ArtMethod* interface_metho interface_method, method); if (new_conflict_method != conflict_method) { + DCHECK_NE(imt, cls->FindSuperImt(kRuntimePointerSize)); // Update the IMT if we create a new conflict method. No fence needed here, as the // data is consistent. imt->Set(imt_index, diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h index b6b1415b09..e2fd82f83a 100644 --- a/runtime/mirror/class-inl.h +++ b/runtime/mirror/class-inl.h @@ -1195,6 +1195,17 @@ inline void Class::SetHasDefaultMethods() { SetAccessFlagsDuringLinking(flags | kAccHasDefaultMethod); } +inline ImTable* Class::FindSuperImt(PointerSize pointer_size) { + ObjPtr<mirror::Class> klass = this; + while (klass->HasSuperClass()) { + klass = klass->GetSuperClass(); + if (klass->ShouldHaveImt()) { + return klass->GetImt(pointer_size); + } + } + return nullptr; +} + } // namespace mirror } // namespace art diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index bd37534b6b..fa2352dfdc 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -866,6 +866,8 @@ class MANAGED Class final : public Object { void SetImt(ImTable* imt, PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_); + ImTable* FindSuperImt(PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_); + ArtMethod* GetEmbeddedVTableEntry(uint32_t i, PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_); |