diff options
author | 2024-05-02 15:40:47 +0100 | |
---|---|---|
committer | 2024-05-03 15:40:42 +0000 | |
commit | a4ac01044c50f4da02c40b8da5520d2eb65b41d9 (patch) | |
tree | cd19c2cf8a0422876df3d70327687229748bd77a /runtime/class_linker-inl.h | |
parent | 721bbf2bfd6ffe689067df5657059925e038bb0d (diff) |
Workaround for b/336842546
Resolve the type if it hasn't been resolved before. Also, change to
use Handles instead of ObjPtr since ResolveType can potentially
suspend.
Bug: 336842546
Bug: 73760543
Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Change-Id: I8ad77e63d6d9cc76fee8aac88742d4a4b678abf5
Diffstat (limited to 'runtime/class_linker-inl.h')
-rw-r--r-- | runtime/class_linker-inl.h | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index 6951e35791..1f5272c7ce 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -271,16 +271,31 @@ 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) { - DCHECK(dex_cache->GetClassLoader() == class_loader); + Handle<mirror::DexCache> dex_cache, + Handle<mirror::ClassLoader> class_loader) { + DCHECK(dex_cache->GetClassLoader() == class_loader.Get()); ArtMethod* resolved = dex_cache->GetResolvedMethod(method_idx); if (resolved == nullptr) { const DexFile& dex_file = *dex_cache->GetDexFile(); const dex::MethodId& method_id = dex_file.GetMethodId(method_idx); - ObjPtr<mirror::Class> klass = LookupResolvedType(method_id.class_idx_, dex_cache, class_loader); + ObjPtr<mirror::Class> klass = + LookupResolvedType(method_id.class_idx_, dex_cache.Get(), class_loader.Get()); + + if (UNLIKELY(klass == nullptr)) { + // We normaly should not end up here. However the verifier currently doesn't guarantee + // the invariant of having the klass in the class table. b/73760543 b/336842546 + klass = ResolveType(method_id.class_idx_, dex_cache, class_loader); + if (UNLIKELY(klass == nullptr)) { + // This can only happen if the current thread is not allowed to load + // classes. + DCHECK(!Thread::Current()->CanLoadClasses()); + DCHECK(Thread::Current()->IsExceptionPending()); + return nullptr; + } + } + if (klass != nullptr) { - resolved = FindResolvedMethod(klass, dex_cache, class_loader, method_idx); + resolved = FindResolvedMethod(klass, dex_cache.Get(), class_loader.Get(), method_idx); } } return resolved; |