Make compiler initialization of classes parallel.
Fix hang where super class initialization could fail to notify threads
trying to initialize sub-class.
Unify logging to log file being compiled in all occurances.
Remove empty PostCompile method.
Remove experimental ForAllDexFile & Class code.
Change-Id: I471e9414f94d468d53b401e086f0fb65e36cc27c
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 1c87747..fdcbf20 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -2507,6 +2507,7 @@
clinit = klass->FindDeclaredDirectMethod("<clinit>", "()V");
if (clinit != NULL && !can_run_clinit) {
+ DCHECK_EQ(klass->GetStatus(), Class::kStatusVerified) << PrettyClass(klass);
// if the class has a <clinit> but we can't run it during compilation,
// don't bother going to kStatusInitializing. We return false so that
// sub-classes don't believe this class is initialized.
@@ -2532,6 +2533,7 @@
if (!ValidateSuperClassDescriptors(klass)) {
klass->SetStatus(Class::kStatusError);
+ lock.NotifyAll();
return false;
}
@@ -2552,6 +2554,9 @@
} else {
CHECK(klass->IsErroneous());
}
+ // Signal to any waiting threads that saw this class as initializing.
+ ObjectLock lock(klass);
+ lock.NotifyAll();
return false;
}
@@ -2616,6 +2621,10 @@
if (klass->GetStatus() == Class::kStatusInitializing) {
continue;
}
+ if (klass->GetStatus() == Class::kStatusVerified && Runtime::Current()->IsCompiler()) {
+ // Compile time initialization failed.
+ return false;
+ }
if (klass->IsErroneous()) {
// The caller wants an exception, but it was thrown in a
// different thread. Synthesize one here.