diff options
| author | 2014-06-27 17:19:04 -0700 | |
|---|---|---|
| committer | 2014-07-07 09:31:58 -0700 | |
| commit | 70b634882b523ec9795475dccc347b423cefaef6 (patch) | |
| tree | 1a3e4392271096dd904100db187fa0677ec95911 /compiler/driver/compiler_driver.cc | |
| parent | fbf156c9394e777385ae2661e673a4c783dfd836 (diff) | |
Only allow whitelisted exceptions during dex2oat resolving.
Previously we would clear any exceptions even though we only want
to clear NoClassDefFound and IncompatibleClassChangeError exceptions.
This meant that out of memory exceptions would incorrectly get
cleared resulting in excessively long dex2oat times when you ran out
of memory.
Bug: 15936401
Change-Id: Iba3911f2c689b8c8d7d41e8c36546f027c08e9d7
Diffstat (limited to 'compiler/driver/compiler_driver.cc')
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 96625c5dac..770ae89ca2 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -1461,6 +1461,18 @@ static bool SkipClass(jobject class_loader, const DexFile& dex_file, mirror::Cla return false; } +static void CheckAndClearResolveException(Thread* self) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + CHECK(self->IsExceptionPending()); + mirror::Throwable* exception = self->GetException(nullptr); + std::string descriptor = exception->GetClass()->GetDescriptor(); + if (descriptor != "Ljava/lang/IncompatibleClassChangeError;" && + descriptor != "Ljava/lang/NoClassDefFoundError;") { + LOG(FATAL) << "Unexpected exeption " << exception->Dump(); + } + self->ClearException(); +} + static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manager, size_t class_def_index) LOCKS_EXCLUDED(Locks::mutator_lock_) { @@ -1496,8 +1508,7 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag if (klass == NULL) { // Class couldn't be resolved, for example, super-class is in a different dex file. Don't // attempt to resolve methods and fields when there is no declaring class. - CHECK(soa.Self()->IsExceptionPending()); - soa.Self()->ClearException(); + CheckAndClearResolveException(soa.Self()); resolve_fields_and_methods = false; } else { resolve_fields_and_methods = manager->GetCompiler()->IsImage(); @@ -1516,8 +1527,7 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, class_loader, true); if (field == NULL) { - CHECK(soa.Self()->IsExceptionPending()); - soa.Self()->ClearException(); + CheckAndClearResolveException(soa.Self()); } } it.Next(); @@ -1532,8 +1542,7 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, class_loader, false); if (field == NULL) { - CHECK(soa.Self()->IsExceptionPending()); - soa.Self()->ClearException(); + CheckAndClearResolveException(soa.Self()); } } it.Next(); @@ -1545,8 +1554,7 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag NullHandle<mirror::ArtMethod>(), it.GetMethodInvokeType(class_def)); if (method == NULL) { - CHECK(soa.Self()->IsExceptionPending()); - soa.Self()->ClearException(); + CheckAndClearResolveException(soa.Self()); } it.Next(); } @@ -1556,8 +1564,7 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag NullHandle<mirror::ArtMethod>(), it.GetMethodInvokeType(class_def)); if (method == NULL) { - CHECK(soa.Self()->IsExceptionPending()); - soa.Self()->ClearException(); + CheckAndClearResolveException(soa.Self()); } it.Next(); } |