Added new state and Soft/Hard error return to verifier for bad supers.

Market was failing because a superclass failed with a soft error, and
then its subclass would be rejected with a hard error. New states and
return values were added, and now ClassLinker::VerifyClass allows a
superclass to have either kStatusVerified or
kStatusRetryVerificationAtRuntime as valid states.

Change-Id: I72f23d25fa3bdcfd08f3113b091303535a327c14
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 98d5fe0..b37a468 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1967,7 +1967,7 @@
     return;
   }
 
-  CHECK_EQ(klass->GetStatus(), Class::kStatusResolved) << PrettyClass(klass);
+  CHECK(klass->IsResolved()) << PrettyClass(klass);
   klass->SetStatus(Class::kStatusVerifying);
 
   // Verify super class
@@ -1980,7 +1980,7 @@
     if (!super->IsVerified() && !super->IsErroneous()) {
       Runtime::Current()->GetClassLinker()->VerifyClass(super);
     }
-    if (!super->IsVerified()) {
+    if (!super->IsCompileTimeVerified()) {
       error_msg = "Rejecting class ";
       error_msg += PrettyDescriptor(klass);
       error_msg += " that attempts to sub-class erroneous class ";
@@ -2005,16 +2005,22 @@
   const DexFile& dex_file = FindDexFile(klass->GetDexCache());
   Class::Status oat_file_class_status(Class::kStatusNotReady);
   bool preverified = VerifyClassUsingOatFile(dex_file, klass, oat_file_class_status);
-  bool verified = preverified || verifier::MethodVerifier::VerifyClass(klass, error_msg);
-  if (verified) {
+  verifier::MethodVerifier::FailureKind verifier_failure = verifier::MethodVerifier::kNoFailure;
+  if (!preverified) {
+    verifier_failure = verifier::MethodVerifier::VerifyClass(klass, error_msg);
+  }
+  if (preverified || verifier_failure != verifier::MethodVerifier::kHardFailure) {
     if (!preverified && oat_file_class_status == Class::kStatusError) {
       LOG(FATAL) << "Verification failed hard on class " << PrettyDescriptor(klass)
                  << " at compile time, but succeeded at runtime! The verifier must be broken.";
     }
     DCHECK(!Thread::Current()->IsExceptionPending());
+    CHECK(verifier_failure == verifier::MethodVerifier::kNoFailure ||
+          Runtime::Current()->IsCompiler());
     // Make sure all classes referenced by catch blocks are resolved
     ResolveClassExceptionHandlerTypes(dex_file, klass);
-    klass->SetStatus(Class::kStatusVerified);
+    klass->SetStatus(verifier_failure == verifier::MethodVerifier::kNoFailure ?
+                     Class::kStatusVerified : Class::kStatusRetryVerificationAtRuntime);
     // Sanity check that a verified class has GC maps on all methods
     CheckMethodsHaveGcMaps(klass);
   } else {
@@ -2052,7 +2058,7 @@
   if (oat_file_class_status == Class::kStatusVerified || oat_file_class_status == Class::kStatusInitialized) {
     return true;
   }
-  if (oat_file_class_status == Class::kStatusResolved) {
+  if (oat_file_class_status == Class::kStatusRetryVerificationAtRuntime) {
     // Compile time verification failed with a soft error. Compile time verification can fail
     // because we have incomplete type information. Consider the following:
     // class ... {