Revert^4 "ART: Use proxy ArtMethod's data_ to store the interface method."
Fix a DCHECK() failure while visiting references for non-CC
moving GC by avoiding the DCHECK(); reference equality may
give false negatives at that stage as we may compare the new
reference against an old one for the same object.
Test: m test-art-host-gtest
Test: testrunner.py --host
Test: testrunner.py --host --jit
Test: testrunner.py --host --gcstress
Test: ART_DEFAULT_GC_TYPE=SS ART_USE_READ_BARRIER=false \
testrunner.py --host --gcstress -t 048-reflect-v8
This reverts commit 76ccd09c3d98317dfbd179c6f5c231dcfc5d6996.
Change-Id: I13cc339d5b31fceedf39ea9a77f27369ba72279f
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h
index 50e9144..11f8253 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -384,21 +384,22 @@
return GetDeclaringClass<kWithoutReadBarrier>()->IsProxyClass();
}
+inline ArtMethod* ArtMethod::GetInterfaceMethodForProxyUnchecked(PointerSize pointer_size) {
+ DCHECK(IsProxyMethod());
+ // Do not check IsAssignableFrom() here as it relies on raw reference comparison
+ // which may give false negatives while visiting references for a non-CC moving GC.
+ return reinterpret_cast<ArtMethod*>(GetDataPtrSize(pointer_size));
+}
+
inline ArtMethod* ArtMethod::GetInterfaceMethodIfProxy(PointerSize pointer_size) {
if (LIKELY(!IsProxyMethod())) {
return this;
}
- uint32_t method_index = GetDexMethodIndex();
- uint32_t slot_idx = method_index % mirror::DexCache::kDexCacheMethodCacheSize;
- mirror::MethodDexCachePair pair = mirror::DexCache::GetNativePairPtrSize(
- GetDexCacheResolvedMethods(pointer_size), slot_idx, pointer_size);
- ArtMethod* interface_method = pair.GetObjectForIndex(method_index);
- if (LIKELY(interface_method != nullptr)) {
- DCHECK_EQ(interface_method, Runtime::Current()->GetClassLinker()->FindMethodForProxy(this));
- } else {
- interface_method = Runtime::Current()->GetClassLinker()->FindMethodForProxy(this);
- DCHECK(interface_method != nullptr);
- }
+ ArtMethod* interface_method = GetInterfaceMethodForProxyUnchecked(pointer_size);
+ // We can check that the proxy class implements the interface only if the proxy class
+ // is resolved, otherwise the interface table is not yet initialized.
+ DCHECK(!GetDeclaringClass()->IsResolved() ||
+ interface_method->GetDeclaringClass()->IsAssignableFrom(GetDeclaringClass()));
return interface_method;
}
@@ -480,7 +481,7 @@
if (UNLIKELY(klass->IsProxyClass())) {
// For normal methods, dex cache shortcuts will be visited through the declaring class.
// However, for proxies we need to keep the interface method alive, so we visit its roots.
- ArtMethod* interface_method = GetInterfaceMethodIfProxy(pointer_size);
+ ArtMethod* interface_method = GetInterfaceMethodForProxyUnchecked(pointer_size);
DCHECK(interface_method != nullptr);
interface_method->VisitRoots(visitor, pointer_size);
}