Don't allow class status to go backward except for error.

Allow greater parallelism of initialization.
Bug 10393546.

Change-Id: Ic194ed490bb0a986250c09fcf335eb1be9714657
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 29025f2..19e134f 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -51,14 +51,20 @@
 }
 
 void Class::SetStatus(Status new_status) {
-  CHECK(new_status > GetStatus() || new_status == kStatusError || !Runtime::Current()->IsStarted())
-      << PrettyClass(this) << " " << GetStatus() << " -> " << new_status;
-  CHECK(sizeof(Status) == sizeof(uint32_t)) << PrettyClass(this);
+  if (UNLIKELY(new_status <= GetStatus() && new_status != kStatusError)) {
+    bool class_linker_initialized = Runtime::Current()->GetClassLinker() != nullptr;
+    if (class_linker_initialized) {
+      LOG(FATAL) << "Unexpected change back of class status for " << PrettyClass(this) << " "
+          << GetStatus() << " -> " << new_status;
+    }
+  }
   if (new_status > kStatusResolved) {
-    CHECK_EQ(GetThinLockId(), Thread::Current()->GetThinLockId()) << PrettyClass(this);
+    CHECK_EQ(GetThinLockId(), Thread::Current()->GetThinLockId())
+        << "Attempt to change status of class while not holding its lock " << PrettyClass(this);
   }
   if (new_status == kStatusError) {
-    CHECK_NE(GetStatus(), kStatusError) << PrettyClass(this);
+    CHECK_NE(GetStatus(), kStatusError)
+        << "Attempt to set as erroneous an already erroneous class " << PrettyClass(this);
 
     // Stash current exception.
     Thread* self = Thread::Current();
@@ -96,6 +102,7 @@
 
     self->SetException(gc_safe_throw_location, old_exception.get());
   }
+  CHECK(sizeof(Status) == sizeof(uint32_t)) << PrettyClass(this);
   return SetField32(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status, false);
 }