summaryrefslogtreecommitdiff
path: root/compiler/driver/compiler_driver.cc
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2014-06-27 17:19:04 -0700
committer Mathieu Chartier <mathieuc@google.com> 2014-07-07 09:31:58 -0700
commit70b634882b523ec9795475dccc347b423cefaef6 (patch)
tree1a3e4392271096dd904100db187fa0677ec95911 /compiler/driver/compiler_driver.cc
parentfbf156c9394e777385ae2661e673a4c783dfd836 (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.cc27
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();
}