Verifier can handle an unresolved method or class.

Added a new dex verifier entry point that takes in a ClassDef index and
context instead of a Class pointer. This allows basic structural
verification to still be run on classes that FindClass fails to find. If
the basic structural classes fail, then the compilation for the class is
skipped. Before, an unresolvable malformed class would cause the
compiler to segfault.

Change-Id: Ia02c77560bf274281c4e22250983dc96511501eb
diff --git a/src/compiler.cc b/src/compiler.cc
index e54dd89..4c10305 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -25,6 +25,7 @@
 #include "class_linker.h"
 #include "class_loader.h"
 #include "dex_cache.h"
+#include "dex_verifier.h"
 #include "jni_internal.h"
 #include "oat_compilation_unit.h"
 #include "oat_file.h"
@@ -63,14 +64,6 @@
   ByteArray* CreateJniDlsymLookupStub();
 }
 
-namespace verifier {
-  class DexVerifier {
-   public:
-    static const std::vector<uint8_t>* GetGcMap(Compiler::MethodReference ref);
-    static bool IsClassRejected(Compiler::ClassReference ref);
-  };
-}
-
 static double Percentage(size_t x, size_t y) {
   return 100.0 * ((double)x) / ((double)(x + y));
 }
@@ -861,6 +854,20 @@
     Thread* self = Thread::Current();
     CHECK(self->IsExceptionPending());
     self->ClearException();
+
+    /*
+     * At compile time, we can still structurally verify the class even if FindClass fails.
+     * This is to ensure the class is structurally sound for compilation. An unsound class
+     * will be rejected by the verifier and later skipped during compilation in the compiler.
+     */
+    std::string error_msg;
+    if (!verifier::DexVerifier::VerifyClass(context->dex_file, context->dex_cache,
+        context->class_loader, class_def_index, error_msg)) {
+      const DexFile::ClassDef& class_def = context->dex_file->GetClassDef(class_def_index);
+      LOG(ERROR) << "Verification failed on class "
+                 << PrettyDescriptor(context->dex_file->GetClassDescriptor(class_def))
+                 << " because: " << error_msg;
+    }
     return;
   }
   CHECK(klass->IsResolved()) << PrettyClass(klass);
@@ -884,6 +891,7 @@
   Context context;
   context.class_linker = Runtime::Current()->GetClassLinker();
   context.class_loader = class_loader;
+  context.dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
   context.dex_file = &dex_file;
   ForAll(&context, 0, dex_file.NumClassDefs(), VerifyClass, thread_count_);