From 70b634882b523ec9795475dccc347b423cefaef6 Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Fri, 27 Jun 2014 17:19:04 -0700 Subject: 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 --- compiler/driver/compiler_driver.cc | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'compiler/driver/compiler_driver.cc') 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(), 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(), it.GetMethodInvokeType(class_def)); if (method == NULL) { - CHECK(soa.Self()->IsExceptionPending()); - soa.Self()->ClearException(); + CheckAndClearResolveException(soa.Self()); } it.Next(); } -- cgit v1.2.3-59-g8ed1b