Merge "Fix the weird state transitions in verification." into dalvik-dev
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() {