diff options
| author | 2017-08-14 18:52:32 +0000 | |
|---|---|---|
| committer | 2017-08-14 18:52:32 +0000 | |
| commit | 7ef52f75dd6e981e1e8c7567f593c197e8a94dcc (patch) | |
| tree | 9685b783f628e290c6307d6ead024aac749a11ab /runtime/class_linker.cc | |
| parent | 0888cf1821d6622fd623db31000be19b9365f81c (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.cc | 54 |
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, |