summaryrefslogtreecommitdiff
path: root/dex2oat/driver/compiler_driver.cc
diff options
context:
space:
mode:
authorVladimir Marko <vmarko@google.com>2020-05-05 14:29:30 +0100
committerVladimir Marko <vmarko@google.com>2020-05-06 08:10:01 +0000
commit6621013ee43ae5c8ec3ab5e35530fe2c732da85b (patch)
treeccb518cd35e44e2d2376b803175d4a3f6ec14993 /dex2oat/driver/compiler_driver.cc
parent9e4b42ad325ee8583b3c98550010516a3a127527 (diff)
downloadart-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.cc44
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