diff options
author | Vladimir Marko <vmarko@google.com> | 2020-05-05 14:29:30 +0100 |
---|---|---|
committer | Vladimir Marko <vmarko@google.com> | 2020-05-06 08:10:01 +0000 |
commit | 6621013ee43ae5c8ec3ab5e35530fe2c732da85b (patch) | |
tree | ccb518cd35e44e2d2376b803175d4a3f6ec14993 /dex2oat/driver/compiler_driver.cc | |
parent | 9e4b42ad325ee8583b3c98550010516a3a127527 (diff) | |
download | art-6621013ee43ae5c8ec3ab5e35530fe2c732da85b.tar.gz |
Allow unresolved exception classes in boot image.
And incorporate dex2oat_image_test changes from
https://android-review.googlesource.com/1302586
to test that this works.
Test: m test-art-host-gtest
Bug: 153648261
Change-Id: I810de9c84973156c06a2c871bf2e0921c80a3fa4
Diffstat (limited to 'dex2oat/driver/compiler_driver.cc')
-rw-r--r-- | dex2oat/driver/compiler_driver.cc | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc index e21f492ed4..b97c1f02dd 100644 --- a/dex2oat/driver/compiler_driver.cc +++ b/dex2oat/driver/compiler_driver.cc @@ -976,8 +976,7 @@ class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor { return true; } - void FindExceptionTypesToResolve( - std::set<std::pair<dex::TypeIndex, const DexFile*>>* exceptions_to_resolve) + void FindExceptionTypesToResolve(std::set<TypeReference>* exceptions_to_resolve) REQUIRES_SHARED(Locks::mutator_lock_) { const auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); for (ObjPtr<mirror::Class> klass : classes_) { @@ -990,7 +989,7 @@ class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor { private: void FindExceptionTypesToResolveForMethod( ArtMethod* method, - std::set<std::pair<dex::TypeIndex, const DexFile*>>* exceptions_to_resolve) + std::set<TypeReference>* exceptions_to_resolve) REQUIRES_SHARED(Locks::mutator_lock_) { if (method->GetCodeItem() == nullptr) { return; // native or abstract method @@ -1013,8 +1012,8 @@ class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor { dex::TypeIndex(DecodeUnsignedLeb128(&encoded_catch_handler_list)); // Add to set of types to resolve if not already in the dex cache resolved types if (!method->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx)) { - exceptions_to_resolve->emplace(encoded_catch_handler_handlers_type_idx, - method->GetDexFile()); + exceptions_to_resolve->emplace(method->GetDexFile(), + encoded_catch_handler_handlers_type_idx); } // ignore address associated with catch handler DecodeUnsignedLeb128(&encoded_catch_handler_list); @@ -1107,10 +1106,12 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings, // Resolve exception classes referenced by the loaded classes. The catch logic assumes // exceptions are resolved by the verifier when there is a catch block in an interested method. // Do this here so that exception classes appear to have been specified image classes. - std::set<std::pair<dex::TypeIndex, const DexFile*>> unresolved_exception_types; - StackHandleScope<1> hs(self); + std::set<TypeReference> unresolved_exception_types; + StackHandleScope<2u> hs(self); Handle<mirror::Class> java_lang_Throwable( hs.NewHandle(class_linker->FindSystemClass(self, "Ljava/lang/Throwable;"))); + MutableHandle<mirror::DexCache> dex_cache = hs.NewHandle(java_lang_Throwable->GetDexCache()); + DCHECK(dex_cache != nullptr); do { unresolved_exception_types.clear(); { @@ -1121,24 +1122,25 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings, class_linker->VisitClasses(&visitor); visitor.FindExceptionTypesToResolve(&unresolved_exception_types); } - for (const auto& exception_type : unresolved_exception_types) { - dex::TypeIndex exception_type_idx = exception_type.first; - const DexFile* dex_file = exception_type.second; - StackHandleScope<1> hs2(self); - Handle<mirror::DexCache> dex_cache(hs2.NewHandle(class_linker->RegisterDexFile(*dex_file, - nullptr))); - ObjPtr<mirror::Class> klass = - (dex_cache != nullptr) - ? class_linker->ResolveType(exception_type_idx, - dex_cache, - ScopedNullHandle<mirror::ClassLoader>()) - : nullptr; + for (auto it = unresolved_exception_types.begin(); it != unresolved_exception_types.end(); ) { + dex::TypeIndex exception_type_idx = it->TypeIndex(); + const DexFile* dex_file = it->dex_file; + if (dex_cache->GetDexFile() != dex_file) { + dex_cache.Assign(class_linker->RegisterDexFile(*dex_file, /*class_loader=*/ nullptr)); + DCHECK(dex_cache != nullptr); + } + ObjPtr<mirror::Class> klass = class_linker->ResolveType( + exception_type_idx, dex_cache, ScopedNullHandle<mirror::ClassLoader>()); if (klass == nullptr) { const dex::TypeId& type_id = dex_file->GetTypeId(exception_type_idx); const char* descriptor = dex_file->GetTypeDescriptor(type_id); - LOG(FATAL) << "Failed to resolve class " << descriptor; + VLOG(compiler) << "Failed to resolve exception class " << descriptor; + self->ClearException(); + it = unresolved_exception_types.erase(it); + } else { + DCHECK(java_lang_Throwable->IsAssignableFrom(klass)); + ++it; } - DCHECK(java_lang_Throwable->IsAssignableFrom(klass)); } // Resolving exceptions may load classes that reference more exceptions, iterate until no // more are found |