Clean up `ClassLinker::FindDefaultMethodImplementation()`.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 181943478
Change-Id: I00f430255f39d5cabab9bf291550c199133ddd36
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 5eab75d..ab3cd9b 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -6224,33 +6224,29 @@
// is a subtype of iface.
// - False: There is no method that matches the target comparator in any interface that is a subtype
// of iface.
-static bool ContainsOverridingMethodOf(Thread* self,
- MethodNameAndSignatureComparator& target,
- Handle<mirror::IfTable> iftable,
+static bool ContainsOverridingMethodOf(MethodNameAndSignatureComparator& target,
+ ObjPtr<mirror::IfTable> iftable,
size_t ifstart,
- Handle<mirror::Class> iface,
+ ObjPtr<mirror::Class> iface,
PointerSize image_pointer_size)
REQUIRES_SHARED(Locks::mutator_lock_) {
- DCHECK(self != nullptr);
DCHECK(iface != nullptr);
DCHECK(iftable != nullptr);
DCHECK_GE(ifstart, 0u);
DCHECK_LT(ifstart, iftable->Count());
- DCHECK_EQ(iface.Get(), iftable->GetInterface(ifstart));
+ DCHECK_EQ(iface, iftable->GetInterface(ifstart));
DCHECK(iface->IsInterface());
size_t iftable_count = iftable->Count();
- StackHandleScope<1> hs(self);
- MutableHandle<mirror::Class> current_iface(hs.NewHandle<mirror::Class>(nullptr));
for (size_t k = ifstart + 1; k < iftable_count; k++) {
// Skip ifstart since our current interface obviously cannot override itself.
- current_iface.Assign(iftable->GetInterface(k));
+ ObjPtr<mirror::Class> current_iface = iftable->GetInterface(k);
// Iterate through every method on this interface. The order does not matter.
for (ArtMethod& current_method : current_iface->GetDeclaredVirtualMethods(image_pointer_size)) {
if (UNLIKELY(target.HasSameNameAndSignature(
current_method.GetInterfaceMethodIfProxy(image_pointer_size)))) {
// Check if the i'th interface is a subtype of this one.
- if (iface->IsAssignableFrom(current_iface.Get())) {
+ if (current_iface->Implements(iface)) {
return true;
}
break;
@@ -6265,11 +6261,9 @@
// kAbstractFound and store nullptr into out_default_method. If an error occurs (such as a
// default_method conflict) it will return kDefaultConflict.
ClassLinker::DefaultMethodSearchResult ClassLinker::FindDefaultMethodImplementation(
- Thread* self,
ArtMethod* target_method,
- Handle<mirror::Class> klass,
+ ObjPtr<mirror::Class> klass,
/*out*/ArtMethod** out_default_method) const {
- DCHECK(self != nullptr);
DCHECK(target_method != nullptr);
DCHECK(out_default_method != nullptr);
@@ -6288,19 +6282,15 @@
return DefaultMethodSearchResult::kAbstractFound;
}
- StackHandleScope<3> hs(self);
- MutableHandle<mirror::Class> chosen_iface(hs.NewHandle<mirror::Class>(nullptr));
- MutableHandle<mirror::IfTable> iftable(hs.NewHandle(klass->GetIfTable()));
- MutableHandle<mirror::Class> iface(hs.NewHandle<mirror::Class>(nullptr));
+ ObjPtr<mirror::IfTable> iftable = klass->GetIfTable();
+ ObjPtr<mirror::Class> chosen_iface = nullptr;
MethodNameAndSignatureComparator target_name_comparator(
target_method->GetInterfaceMethodIfProxy(image_pointer_size_));
// Iterates over the klass's iftable in reverse
for (size_t k = iftable_count; k != 0; ) {
--k;
-
DCHECK_LT(k, iftable->Count());
-
- iface.Assign(iftable->GetInterface(k));
+ ObjPtr<mirror::Class> iface = iftable->GetInterface(k);
// Iterate through every declared method on this interface. The order does not matter.
for (auto& method_iter : iface->GetDeclaredVirtualMethods(image_pointer_size_)) {
ArtMethod* current_method = &method_iter;
@@ -6323,9 +6313,8 @@
// We need to check if this possibly conflicting method is either a superclass of the chosen
// default implementation or is overridden by a non-default interface method. In either case
// there is no conflict.
- if (!iface->IsAssignableFrom(chosen_iface.Get()) &&
- !ContainsOverridingMethodOf(self,
- target_name_comparator,
+ if (!chosen_iface->Implements(iface) &&
+ !ContainsOverridingMethodOf(target_name_comparator,
iftable,
k,
iface,
@@ -6341,8 +6330,7 @@
}
} else {
// chosen_iface == null
- if (!ContainsOverridingMethodOf(self,
- target_name_comparator,
+ if (!ContainsOverridingMethodOf(target_name_comparator,
iftable,
k,
iface,
@@ -6352,7 +6340,7 @@
// interface was abstract then we wouldn't select this interface as chosen anyway since
// the abstract method masks it.
*out_default_method = current_method;
- chosen_iface.Assign(iface.Get());
+ chosen_iface = iface;
// We should now finish traversing the graph to find if we have default methods that
// conflict.
} else {
@@ -7505,9 +7493,8 @@
MethodNameAndSignatureComparator& interface_name_comparator,
ArtMethod* vtable_impl) {
ArtMethod* current_method = nullptr;
- switch (class_linker_->FindDefaultMethodImplementation(self_,
- interface_method,
- klass_,
+ switch (class_linker_->FindDefaultMethodImplementation(interface_method,
+ klass_.Get(),
/*out*/¤t_method)) {
case DefaultMethodSearchResult::kDefaultConflict: {
// Default method conflict.
@@ -8146,9 +8133,8 @@
// We didn't directly override this method but we might through default methods...
// Check for default method update.
ArtMethod* default_method = nullptr;
- switch (class_linker_->FindDefaultMethodImplementation(self,
- super_method,
- klass,
+ switch (class_linker_->FindDefaultMethodImplementation(super_method,
+ klass.Get(),
/*out*/&default_method)) {
case DefaultMethodSearchResult::kDefaultConflict: {
// A conflict was found looking for default methods. Note this (assuming it wasn't
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index e2b8794..83c9a37 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -1189,9 +1189,8 @@
// * kDefaultConflict - Conflicting method implementations were found when searching for
// target_method. The value of *out_default_method is null.
DefaultMethodSearchResult FindDefaultMethodImplementation(
- Thread* self,
ArtMethod* target_method,
- Handle<mirror::Class> klass,
+ ObjPtr<mirror::Class> klass,
/*out*/ArtMethod** out_default_method) const
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 6c839ca..7b967ac 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -647,6 +647,9 @@
// to themselves. Classes for primitive types may not assign to each other.
ALWAYS_INLINE bool IsAssignableFrom(ObjPtr<Class> src) REQUIRES_SHARED(Locks::mutator_lock_);
+ // Check if this class implements a given interface.
+ bool Implements(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
+
// Checks if 'klass' is a redefined version of this.
bool IsObsoleteVersionOf(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
@@ -1370,7 +1373,6 @@
InvokeType throw_invoke_type)
REQUIRES_SHARED(Locks::mutator_lock_);
- bool Implements(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
bool IsArrayAssignableFromArray(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
bool IsAssignableFromArray(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);