Make the code more defensive against null DexCache values

Change-Id: Iaa3f17dced518a5d2a53479b3ae3cebacb1e3b6a
diff --git a/src/class_linker.cc b/src/class_linker.cc
index ecf33ac..8d92d01 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -3248,6 +3248,7 @@
 
 String* ClassLinker::ResolveString(const DexFile& dex_file,
     uint32_t string_idx, DexCache* dex_cache) {
+  CHECK(dex_cache != NULL);
   String* resolved = dex_cache->GetResolvedString(string_idx);
   if (resolved != NULL) {
     return resolved;
@@ -3264,6 +3265,7 @@
                                 uint16_t type_idx,
                                 DexCache* dex_cache,
                                 const ClassLoader* class_loader) {
+  CHECK(dex_cache != NULL);
   Class* resolved = dex_cache->GetResolvedType(type_idx);
   if (resolved == NULL) {
     const char* descriptor = dex_file.StringByTypeIdx(type_idx);
@@ -3291,6 +3293,7 @@
                                    DexCache* dex_cache,
                                    const ClassLoader* class_loader,
                                    bool is_direct) {
+  CHECK(dex_cache != NULL);
   Method* resolved = dex_cache->GetResolvedMethod(method_idx);
   if (resolved != NULL) {
     return resolved;
@@ -3340,6 +3343,7 @@
                                  DexCache* dex_cache,
                                  const ClassLoader* class_loader,
                                  bool is_static) {
+  CHECK(dex_cache != NULL);
   Field* resolved = dex_cache->GetResolvedField(field_idx);
   if (resolved != NULL) {
     return resolved;
@@ -3378,6 +3382,7 @@
                                     uint32_t field_idx,
                                     DexCache* dex_cache,
                                     const ClassLoader* class_loader) {
+  CHECK(dex_cache != NULL);
   Field* resolved = dex_cache->GetResolvedField(field_idx);
   if (resolved != NULL) {
     return resolved;
diff --git a/src/compiler.cc b/src/compiler.cc
index 4c10305..1797530 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -655,12 +655,45 @@
   return true;
 }
 
-struct Context {
-  ClassLinker* class_linker;
-  const ClassLoader* class_loader;
-  Compiler* compiler;
-  DexCache* dex_cache;
-  const DexFile* dex_file;
+class Context {
+ public:
+  Context(ClassLinker* class_linker,
+          const ClassLoader* class_loader,
+          Compiler* compiler,
+          DexCache* dex_cache,
+          const DexFile* dex_file)
+    : class_linker_(class_linker),
+      class_loader_(class_loader),
+      compiler_(compiler),
+      dex_cache_(dex_cache),
+      dex_file_(dex_file) {}
+
+  ClassLinker* GetClassLinker() {
+    CHECK(class_linker_ != NULL);
+    return class_linker_;
+  }
+  const ClassLoader* GetClassLoader() {
+    return class_loader_;
+  }
+  Compiler* GetCompiler() {
+    CHECK(compiler_ != NULL);
+    return compiler_;
+  }
+  DexCache* GetDexCache() {
+    CHECK(dex_cache_ != NULL);
+    return dex_cache_;
+  }
+  const DexFile* GetDexFile() {
+    CHECK(dex_file_ != NULL);
+    return dex_file_;
+  }
+
+ private:
+  ClassLinker* class_linker_;
+  const ClassLoader* class_loader_;
+  Compiler* compiler_;
+  DexCache* dex_cache_;
+  const DexFile* dex_file_;
 };
 
 typedef void Callback(Context* context, size_t index);
@@ -733,7 +766,7 @@
 }
 
 static void ResolveClassFieldsAndMethods(Context* context, size_t class_def_index) {
-  const DexFile& dex_file = *context->dex_file;
+  const DexFile& dex_file = *context->GetDexFile();
 
   // Method and Field are the worst. We can't resolve without either
   // context from the code use (to disambiguate virtual vs direct
@@ -743,7 +776,7 @@
   // definitions, since many of them many never be referenced by
   // generated code.
   const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
-  if (SkipClass(context->class_loader, dex_file, class_def)) {
+  if (SkipClass(context->GetClassLoader(), dex_file, class_def)) {
     return;
   }
 
@@ -756,12 +789,12 @@
     return;
   }
   Thread* self = Thread::Current();
-  ClassLinker* class_linker = context->class_linker;
+  ClassLinker* class_linker = context->GetClassLinker();
   DexCache* dex_cache = class_linker->FindDexCache(dex_file);
   ClassDataItemIterator it(dex_file, class_data);
   while (it.HasNextStaticField()) {
     Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
-                                              context->class_loader, true);
+                                              context->GetClassLoader(), true);
     if (field == NULL) {
       CHECK(self->IsExceptionPending());
       self->ClearException();
@@ -770,7 +803,7 @@
   }
   while (it.HasNextInstanceField()) {
     Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
-                                              context->class_loader, false);
+                                              context->GetClassLoader(), false);
     if (field == NULL) {
       CHECK(self->IsExceptionPending());
       self->ClearException();
@@ -779,7 +812,7 @@
   }
   while (it.HasNextDirectMethod()) {
     Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache,
-                                                 context->class_loader, true);
+                                                 context->GetClassLoader(), true);
     if (method == NULL) {
       CHECK(self->IsExceptionPending());
       self->ClearException();
@@ -788,7 +821,7 @@
   }
   while (it.HasNextVirtualMethod()) {
     Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache,
-                                                 context->class_loader, false);
+                                                 context->GetClassLoader(), false);
     if (method == NULL) {
       CHECK(self->IsExceptionPending());
       self->ClearException();
@@ -801,9 +834,10 @@
 static void ResolveType(Context* context, size_t type_idx) {
   // Class derived values are more complicated, they require the linker and loader.
   Thread* self = Thread::Current();
-  ClassLinker* class_linker = context->class_linker;
-  const DexFile& dex_file = *context->dex_file;
-  Class* klass = class_linker->ResolveType(dex_file, type_idx, context->dex_cache, context->class_loader);
+  Class* klass = context->GetClassLinker()->ResolveType(*context->GetDexFile(),
+                                                        type_idx,
+                                                        context->GetDexCache(),
+                                                        context->GetClassLoader());
   if (klass == NULL) {
     CHECK(self->IsExceptionPending());
     Thread::Current()->ClearException();
@@ -824,12 +858,7 @@
     timings.AddSplit("Resolve " + dex_file.GetLocation() + " Strings");
   }
 
-  Context context;
-  context.class_linker = class_linker;
-  context.class_loader = class_loader;
-  context.dex_cache = dex_cache;
-  context.dex_file = &dex_file;
-
+  Context context(class_linker, class_loader, this, dex_cache, &dex_file);
   ForAll(&context, 0, dex_cache->NumResolvedTypes(), ResolveType, thread_count_);
   timings.AddSplit("Resolve " + dex_file.GetLocation() + " Types");
 
@@ -847,9 +876,9 @@
 }
 
 static void VerifyClass(Context* context, size_t class_def_index) {
-  const DexFile::ClassDef& class_def = context->dex_file->GetClassDef(class_def_index);
-  const char* descriptor = context->dex_file->GetClassDescriptor(class_def);
-  Class* klass = context->class_linker->FindClass(descriptor, context->class_loader);
+  const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index);
+  const char* descriptor = context->GetDexFile()->GetClassDescriptor(class_def);
+  Class* klass = context->GetClassLinker()->FindClass(descriptor, context->GetClassLoader());
   if (klass == NULL) {
     Thread* self = Thread::Current();
     CHECK(self->IsExceptionPending());
@@ -861,17 +890,17 @@
      * 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);
+    if (!verifier::DexVerifier::VerifyClass(context->GetDexFile(), context->GetDexCache(),
+        context->GetClassLoader(), class_def_index, error_msg)) {
+      const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index);
       LOG(ERROR) << "Verification failed on class "
-                 << PrettyDescriptor(context->dex_file->GetClassDescriptor(class_def))
+                 << PrettyDescriptor(context->GetDexFile()->GetClassDescriptor(class_def))
                  << " because: " << error_msg;
     }
     return;
   }
   CHECK(klass->IsResolved()) << PrettyClass(klass);
-  context->class_linker->VerifyClass(klass);
+  context->GetClassLinker()->VerifyClass(klass);
 
   if (klass->IsErroneous()) {
     // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
@@ -888,11 +917,8 @@
 void Compiler::VerifyDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
   dex_file.ChangePermissions(PROT_READ | PROT_WRITE);
 
-  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;
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  Context context(class_linker, class_loader, this, class_linker->FindDexCache(dex_file), &dex_file);
   ForAll(&context, 0, dex_file.NumClassDefs(), VerifyClass, thread_count_);
 
   dex_file.ChangePermissions(PROT_READ);
@@ -952,8 +978,8 @@
 }
 
 void Compiler::CompileClass(Context* context, size_t class_def_index) {
-  const ClassLoader* class_loader = context->class_loader;
-  const DexFile& dex_file = *context->dex_file;
+  const ClassLoader* class_loader = context->GetClassLoader();
+  const DexFile& dex_file = *context->GetDexFile();
   const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
 
 #if defined(ART_USE_LLVM_COMPILER)
@@ -987,14 +1013,14 @@
   }
   // Compile direct methods
   while (it.HasNextDirectMethod()) {
-    context->compiler->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
-                                     it.GetMemberIndex(), class_loader, dex_file);
+    context->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
+                                          it.GetMemberIndex(), class_loader, dex_file);
     it.Next();
   }
   // Compile virtual methods
   while (it.HasNextVirtualMethod()) {
-    context->compiler->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
-                                     it.GetMemberIndex(), class_loader, dex_file);
+    context->GetCompiler()->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
+                                          it.GetMemberIndex(), class_loader, dex_file);
     it.Next();
   }
   DCHECK(!it.HasNext());
@@ -1005,10 +1031,7 @@
 }
 
 void Compiler::CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
-  Context context;
-  context.class_loader = class_loader;
-  context.compiler = this;
-  context.dex_file = &dex_file;
+  Context context(NULL, class_loader, this, NULL, &dex_file);
   ForAll(&context, 0, dex_file.NumClassDefs(), Compiler::CompileClass, thread_count_);
 }