summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2017-08-14 18:52:32 +0000
committer Nicolas Geoffray <ngeoffray@google.com> 2017-08-14 18:52:32 +0000
commit7ef52f75dd6e981e1e8c7567f593c197e8a94dcc (patch)
tree9685b783f628e290c6307d6ead024aac749a11ab /runtime/class_linker.cc
parent0888cf1821d6622fd623db31000be19b9365f81c (diff)
Revert "ART: Use proxy ArtMethod's data_ to store the interface method."
Broke a few tests with: +dalvikvm64 F 08-14 18:36:32 136697 136697 art_method-inl.h:392] Check failed: interface_method->GetDeclaringClass()->IsAssignableFrom(GetDeclaringClass()) This reverts commit 0888cf1821d6622fd623db31000be19b9365f81c. Change-Id: Idc93b6686392f9dfeca3bc11bd22104948fd9fd3
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc54
1 files changed, 48 insertions, 6 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 0efc004b48..845bd6d5ff 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3552,6 +3552,7 @@ void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file,
DexCacheData data;
data.weak_root = dex_cache_jweak;
data.dex_file = dex_cache->GetDexFile();
+ data.resolved_methods = dex_cache->GetResolvedMethods();
data.class_table = ClassTableForClassLoader(class_loader);
DCHECK(data.class_table != nullptr);
// Make sure to hold the dex cache live in the class table. This case happens for the boot class
@@ -4667,9 +4668,6 @@ void ClassLinker::CreateProxyConstructor(Handle<mirror::Class> klass, ArtMethod*
kAccPublic |
kAccCompileDontBother);
out->SetDeclaringClass(klass.Get());
-
- // Set the original constructor method.
- out->SetDataPtrSize(proxy_constructor, image_pointer_size_);
}
void ClassLinker::CheckProxyConstructor(ArtMethod* constructor) const {
@@ -4710,9 +4708,6 @@ void ClassLinker::CreateProxyMethod(Handle<mirror::Class> klass, ArtMethod* prot
// method they copy might (if it's a default method).
out->SetCodeItemOffset(0);
- // Set the original interface method.
- out->SetDataPtrSize(prototype, image_pointer_size_);
-
// At runtime the method looks like a reference and argument saving method, clone the code
// related parameters from this method.
out->SetEntryPointFromQuickCompiledCode(GetQuickProxyInvokeHandler());
@@ -9036,6 +9031,53 @@ mirror::IfTable* ClassLinker::AllocIfTable(Thread* self, size_t ifcount) {
ifcount * mirror::IfTable::kMax));
}
+ArtMethod* ClassLinker::FindMethodForProxy(ArtMethod* proxy_method) {
+ DCHECK(proxy_method->IsProxyMethod());
+ {
+ uint32_t method_index = proxy_method->GetDexMethodIndex();
+ PointerSize pointer_size = image_pointer_size_;
+ Thread* const self = Thread::Current();
+ ReaderMutexLock mu(self, *Locks::dex_lock_);
+ // Locate the dex cache of the original interface/Object
+ for (const DexCacheData& data : dex_caches_) {
+ if (!self->IsJWeakCleared(data.weak_root) &&
+ proxy_method->HasSameDexCacheResolvedMethods(data.resolved_methods, pointer_size)) {
+ ObjPtr<mirror::DexCache> dex_cache =
+ ObjPtr<mirror::DexCache>::DownCast(self->DecodeJObject(data.weak_root));
+ if (dex_cache != nullptr) {
+ // Lookup up the method. Instead of going through LookupResolvedMethod()
+ // and thus LookupResolvedType(), use the ClassTable from the DexCacheData.
+ ArtMethod* resolved_method = dex_cache->GetResolvedMethod(method_index, pointer_size);
+ if (resolved_method == nullptr) {
+ const DexFile::MethodId& method_id = data.dex_file->GetMethodId(method_index);
+ ObjPtr<mirror::Class> klass = dex_cache->GetResolvedType(method_id.class_idx_);
+ if (klass == nullptr) {
+ const char* descriptor = data.dex_file->StringByTypeIdx(method_id.class_idx_);
+ klass = data.class_table->Lookup(descriptor, ComputeModifiedUtf8Hash(descriptor));
+ DCHECK(klass != nullptr);
+ dex_cache->SetResolvedType(method_id.class_idx_, klass);
+ }
+ if (klass->IsInterface()) {
+ resolved_method = klass->FindInterfaceMethod(dex_cache, method_index, pointer_size);
+ } else {
+ DCHECK(
+ klass == WellKnownClasses::ToClass(WellKnownClasses::java_lang_reflect_Proxy) ||
+ klass == WellKnownClasses::ToClass(WellKnownClasses::java_lang_Object));
+ resolved_method = klass->FindClassMethod(dex_cache, method_index, pointer_size);
+ }
+ CHECK(resolved_method != nullptr);
+ dex_cache->SetResolvedMethod(method_index, resolved_method, pointer_size);
+ }
+ return resolved_method;
+ }
+ }
+ }
+ }
+ // Note: Do not use proxy_method->PrettyMethod() as it can call back here.
+ LOG(FATAL) << "Didn't find dex cache for " << proxy_method->GetDeclaringClass()->PrettyClass();
+ UNREACHABLE();
+}
+
// Instantiate ResolveMethod.
template ArtMethod* ClassLinker::ResolveMethod<ClassLinker::ResolveMode::kCheckICCEAndIAE>(
const DexFile& dex_file,