diff options
author | 2017-07-06 14:55:02 +0100 | |
---|---|---|
committer | 2017-07-20 16:33:00 +0100 | |
commit | 07bfbace6f835e6c748fd68ec7624992478b16c1 (patch) | |
tree | 5d094a00fbc90455bd9b53e042cf8b4fe8433462 /runtime/class_linker-inl.h | |
parent | ba118827465d12177f3996e50133960087b1c916 (diff) |
Hash-based DexCache methods array.
Total boot*.art size for aosp_angler-userdebug:
- arm64:
- before: 11603968
- after: 10129408 (-1.4MiB, -12.7%)
- arm:
- before: 8626176
- after: 7888896 (-0.7MiB, -8.5%)
Test: m test-art-host-gtest
Test: testrunner.py --host
Test: Nexus 6P boots.
Test: testrunner.py --target
Test: Build aosp_mips64-eng
Bug: 30627598
Change-Id: I7f858605de5f074cbd7f0d9c4c072fbd44aee28f
Diffstat (limited to 'runtime/class_linker-inl.h')
-rw-r--r-- | runtime/class_linker-inl.h | 58 |
1 files changed, 27 insertions, 31 deletions
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index d29db15f0a..9a736973bc 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -156,6 +156,29 @@ inline bool ClassLinker::CheckInvokeClassMismatch(ObjPtr<mirror::DexCache> dex_c }); } +inline ArtMethod* ClassLinker::LookupResolvedMethod(uint32_t method_idx, + ObjPtr<mirror::DexCache> dex_cache, + ObjPtr<mirror::ClassLoader> class_loader) { + PointerSize pointer_size = image_pointer_size_; + ArtMethod* resolved = dex_cache->GetResolvedMethod(method_idx, pointer_size); + if (resolved == nullptr) { + const DexFile& dex_file = *dex_cache->GetDexFile(); + const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx); + ObjPtr<mirror::Class> klass = LookupResolvedType(method_id.class_idx_, dex_cache, class_loader); + if (klass != nullptr) { + if (klass->IsInterface()) { + resolved = klass->FindInterfaceMethod(dex_cache, method_idx, pointer_size); + } else { + resolved = klass->FindClassMethod(dex_cache, method_idx, pointer_size); + } + if (resolved != nullptr) { + dex_cache->SetResolvedMethod(method_idx, resolved, pointer_size); + } + } + } + return resolved; +} + template <InvokeType type, ClassLinker::ResolveMode kResolveMode> inline ArtMethod* ClassLinker::GetResolvedMethod(uint32_t method_idx, ArtMethod* referrer) { DCHECK(referrer != nullptr); @@ -164,9 +187,10 @@ inline ArtMethod* ClassLinker::GetResolvedMethod(uint32_t method_idx, ArtMethod* // However, we delay the GetInterfaceMethodIfProxy() until needed. DCHECK(!referrer->IsProxyMethod() || referrer->IsConstructor()); ArtMethod* resolved_method = referrer->GetDexCacheResolvedMethod(method_idx, image_pointer_size_); - if (resolved_method == nullptr || resolved_method->IsRuntimeMethod()) { + if (resolved_method == nullptr) { return nullptr; } + DCHECK(!resolved_method->IsRuntimeMethod()); if (kResolveMode == ResolveMode::kCheckICCEAndIAE) { referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_); // Check if the invoke type matches the class type. @@ -203,7 +227,8 @@ inline ArtMethod* ClassLinker::ResolveMethod(Thread* self, DCHECK(!referrer->IsProxyMethod() || referrer->IsConstructor()); Thread::PoisonObjectPointersIfDebug(); ArtMethod* resolved_method = referrer->GetDexCacheResolvedMethod(method_idx, image_pointer_size_); - if (UNLIKELY(resolved_method == nullptr || resolved_method->IsRuntimeMethod())) { + DCHECK(resolved_method == nullptr || !resolved_method->IsRuntimeMethod()); + if (UNLIKELY(resolved_method == nullptr)) { referrer = referrer->GetInterfaceMethodIfProxy(image_pointer_size_); ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass(); StackHandleScope<2> hs(self); @@ -287,35 +312,6 @@ inline mirror::Class* ClassLinker::GetClassRoot(ClassRoot class_root) { return klass.Ptr(); } -template<ReadBarrierOption kReadBarrierOption> -ArtMethod* ClassLinker::FindMethodForProxy(ObjPtr<mirror::Class> proxy_class, - ArtMethod* proxy_method) { - DCHECK(proxy_class->IsProxyClass()); - DCHECK(proxy_method->IsProxyMethod()); - { - 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, - image_pointer_size_)) { - ObjPtr<mirror::DexCache> dex_cache = - ObjPtr<mirror::DexCache>::DownCast(self->DecodeJObject(data.weak_root)); - if (dex_cache != nullptr) { - ArtMethod* resolved_method = dex_cache->GetResolvedMethod( - proxy_method->GetDexMethodIndex(), image_pointer_size_); - CHECK(resolved_method != nullptr); - return resolved_method; - } - } - } - } - LOG(FATAL) << "Didn't find dex cache for " << proxy_class->PrettyClass() << " " - << proxy_method->PrettyMethod(); - UNREACHABLE(); -} - } // namespace art #endif // ART_RUNTIME_CLASS_LINKER_INL_H_ |