summaryrefslogtreecommitdiff
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
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
-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;
}