Fix the weird state transitions in verification.

This probably wants to be done differently, without Compiler involving
ClassLinker, and with DexVerifier being told whether it should throw
or not. But this gets us further for now.

Test 077 still crashes, but that's now in code that's actively being
worked on, which I'll leave for now.

Change-Id: I4f265b20663837547933d0c5fa70032d22fc6c12
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 7225764..71abb21 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -533,7 +533,7 @@
     Class* c = GetClassRoot(ClassRoot(i));
     if (!c->IsArrayClass() && !c->IsPrimitive()) {
       EnsureInitialized(GetClassRoot(ClassRoot(i)), true);
-      CHECK(!self->IsExceptionPending());
+      CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException());
     }
   }
 }
@@ -1368,10 +1368,12 @@
     klass->SetStatus(Class::kStatusVerified);
   } else {
     LOG(ERROR) << "Verification failed on class " << PrettyClass(klass);
-    CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException());
-
+    Thread* self = Thread::Current();
+    CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException());
+    self->ThrowNewExceptionF("Ljava/lang/VerifyError;", "Verification of %s failed",
+        PrettyDescriptor(klass->GetDescriptor()).c_str());
     CHECK_EQ(klass->GetStatus(), Class::kStatusVerifying);
-    klass->SetStatus(Class::kStatusResolved);
+    klass->SetStatus(Class::kStatusError);
   }
 }
 
@@ -1465,7 +1467,7 @@
 
 bool ClassLinker::WaitForInitializeClass(Class* klass, Thread* self, ObjectLock& lock) {
   while (true) {
-    CHECK(!self->IsExceptionPending());
+    CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException());
     lock.Wait();
 
     // When we wake up, repeat the test for init-in-progress.  If
diff --git a/src/compiler.cc b/src/compiler.cc
index c6705a6..f4e8874 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -201,6 +201,15 @@
     }
     CHECK(klass->IsResolved()) << PrettyClass(klass);
     class_linker->VerifyClass(klass);
+
+    if (klass->IsErroneous()) {
+      // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
+      CHECK(Thread::Current()->IsExceptionPending());
+      Thread::Current()->ClearException();
+      // We want to try verification again at run-time, so move back into the resolved state.
+      klass->SetStatus(Class::kStatusResolved);
+    }
+
     CHECK(klass->IsVerified() || klass->IsResolved()) << PrettyClass(klass);
     CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException());
   }
diff --git a/src/object.cc b/src/object.cc
index b812b90..342599e 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -795,21 +795,18 @@
 }
 
 void Class::SetStatus(Status new_status) {
-  CHECK(new_status > GetStatus() || new_status == kStatusError ||
-      !Runtime::Current()->IsStarted()) << PrettyClass(this);
+  CHECK(new_status > GetStatus() || new_status == kStatusError || !Runtime::Current()->IsStarted())
+      << PrettyClass(this) << " " << GetStatus() << " -> " << new_status;
   CHECK(sizeof(Status) == sizeof(uint32_t)) << PrettyClass(this);
-  return SetField32(OFFSET_OF_OBJECT_MEMBER(Class, status_),
-                    new_status, false);
+  return SetField32(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status, false);
 }
 
 DexCache* Class::GetDexCache() const {
-  return GetFieldObject<DexCache*>(
-      OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), false);
+  return GetFieldObject<DexCache*>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), false);
 }
 
 void Class::SetDexCache(DexCache* new_dex_cache) {
-  SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_),
-                 new_dex_cache, false);
+  SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache, false);
 }
 
 Object* Class::AllocObject() {