summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2022-02-02 17:20:12 +0000
committer Treehugger Robot <treehugger-gerrit@google.com> 2022-02-02 21:16:49 +0000
commit0f71b191492cc63b9c8835e85f6016228889da2f (patch)
treebe397ff83fcff9121fe2f9f6ac8df237808c342d /runtime/class_linker.cc
parentc226211ebcf8e0185d4e46376bff6468d0c6967f (diff)
Do not reuse superclass IfTable with non-marker interfaces...
... even if there are no new interfaces and no new virtual methods. While we could theoretically reuse the IfTable in this case, we currently fail to correctly update the IMT. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Test: atest MultiuserHostsideIntegrationTests:com.android.test.multiuser.host.OpenAppTest#testChrome -- --abi x86_64 Bug: 215510819 Bug: 181943478 Change-Id: I149cfb22c83c766c5a8da31e1494a446ae5e58c9
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc17
1 files changed, 7 insertions, 10 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 9538f8a1d4..f4a13e9fcf 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -6576,8 +6576,8 @@ static ObjPtr<mirror::IfTable> SetupInterfaceLookupTable(
// If there are no new interfaces, we can recycle parent's interface table if the class
// inherits no interfaces from the superclass (this is always the case for interfaces as
- // their superclass `java.lang.Object` does not implement any interface), or there are no
- // new virtuals, or all interfaces inherited from the superclass are just marker interfaces.
+ // their superclass `java.lang.Object` does not implement any interface), or all interfaces
+ // inherited from the superclass are just marker interfaces.
auto is_marker_iface = [=](size_t index) REQUIRES_SHARED(Locks::mutator_lock_) ALWAYS_INLINE {
return super_iftable->GetMethodArrayCount(index) == 0;
};
@@ -6586,8 +6586,7 @@ static ObjPtr<mirror::IfTable> SetupInterfaceLookupTable(
return true;
}
DCHECK(!klass->IsInterface());
- return klass->NumDeclaredVirtualMethods() == 0u ||
- std::all_of(CountIter(0), CountIter(super_ifcount), is_marker_iface);
+ return std::all_of(CountIter(0), CountIter(super_ifcount), is_marker_iface);
};
if (num_interfaces == 0 && can_reuse_super_iftable()) {
return super_iftable;
@@ -8251,10 +8250,10 @@ bool ClassLinker::LinkMethodsHelper<kPointerSize>::LinkMethods(
const size_t super_vtable_length = klass->GetSuperClass()->GetVTableLength();
Handle<mirror::Class> super_class(hs.NewHandle(klass->GetSuperClass()));
- // If there are no new virtual methods and no new interfaces, we can simply reuse
- // the vtable from superclass. We may need to make a copy if it's embedded.
- if (num_virtual_methods == 0 &&
- static_cast<size_t>(super_class->GetIfTableCount()) == iftable->Count()) {
+ // If there are no new virtual methods and no new interfaces and no non-marker
+ // interfaces in the superclass, we can simply reuse the vtable from superclass.
+ // We may need to make a copy if it's embedded.
+ if (num_virtual_methods == 0 && iftable.Get() == super_class->GetIfTable()) {
if (super_class->ShouldHaveEmbeddedVTable()) {
ObjPtr<mirror::PointerArray> vtable =
class_linker_->AllocPointerArray(self, super_vtable_length);
@@ -8273,8 +8272,6 @@ bool ClassLinker::LinkMethodsHelper<kPointerSize>::LinkMethods(
CHECK(super_vtable != nullptr) << super_class->PrettyClass();
klass->SetVTable(super_vtable);
}
- // The interface table from superclass has also been reused by `SetupInterfaceLookupTable()`.
- DCHECK(iftable.Get() == super_class->GetIfTable()) << klass->PrettyDescriptor();
klass->SetIfTable(iftable.Get());
return true;
}