Fix CHA: Treat default conflict method like abstract.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: testrunner.py --host --picimage --no-image -t 181
Bug: 217494697
Change-Id: I9d7745e4fb9348d8588191db3085405cc7532265
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 851ed12..ac6988a 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -542,6 +542,7 @@
DCHECK(!IsNative());
// Non-abstract method's single implementation is just itself.
DCHECK(IsAbstract());
+ DCHECK(method == nullptr || method->IsInvokable());
SetDataPtrSize(method, pointer_size);
}
diff --git a/runtime/cha.cc b/runtime/cha.cc
index d01dec6..bb96518 100644
--- a/runtime/cha.cc
+++ b/runtime/cha.cc
@@ -467,11 +467,13 @@
return;
}
- if (implementation_method->IsAbstract()) {
- // An instantiable class doesn't supply an implementation for
- // interface_method. Invoking the interface method on the class will throw
- // AbstractMethodError. This is an uncommon case, so we simply treat
- // interface_method as not having single-implementation.
+ if (!implementation_method->IsInvokable()) {
+ DCHECK(implementation_method->IsAbstract() || implementation_method->IsDefaultConflicting());
+ // An instantiable class doesn't supply an implementation for interface_method,
+ // or has conflicting default method implementations. Invoking the interface method
+ // on the class will throw AbstractMethodError or IncompatibleClassChangeError.
+ // (Note: The RI throws AME instead of ICCE for default conflict.) This is an uncommon
+ // case, so we simply treat interface_method as not having single-implementation.
invalidated_single_impl_methods.insert(interface_method);
return;
}
@@ -493,9 +495,8 @@
// Keep interface_method's single-implementation status.
return;
}
- DCHECK(!single_impl->IsAbstract());
- if ((single_impl->GetDeclaringClass() == implementation_method->GetDeclaringClass()) &&
- !implementation_method->IsDefaultConflicting()) {
+ DCHECK(single_impl->IsInvokable());
+ if ((single_impl->GetDeclaringClass() == implementation_method->GetDeclaringClass())) {
// Same implementation. Since implementation_method may be a copy of a default
// method, we need to check the declaring class for equality.
return;
diff --git a/test/knownfailures.json b/test/knownfailures.json
index c92e36a..f68f6f0 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -1474,11 +1474,5 @@
"tests": ["667-jit-jni-stub"],
"variant": "jit-on-first-use | redefine-stress",
"description": ["jit-on-first-use disables jit GC but this test requires jit GC"]
- },
- {
- "tests": ["181-default-methods"],
- "variant": "no-image",
- "bug": "b/217494697",
- "description": ["Disabled due to CHA bug. b/217494697"]
}
]