Interpreter-only mode should cause dex-to-dex compilation.

Also, fix quick iget/iput that had similar issues to:
https://android-review.googlesource.com/91423
Also, remove fall-back resolution code from quick invokes/igets/iputs as we
allow class loading for the exception throw and regular verification already
allows class loading.
Bug: 14133618

Change-Id: I51199e6e2392da0354f64b157e79af494c183778
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index eb0522a..611ce0b 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1230,6 +1230,10 @@
 
 void Runtime::AddCurrentRuntimeFeaturesAsDex2OatArguments(std::vector<std::string>* argv)
     const {
+  if (GetInstrumentation()->InterpretOnly()) {
+    argv->push_back("--compiler-filter=interpret-only");
+  }
+
   argv->push_back("--runtime-arg");
   std::string checkstr = "-implicit-checks";
 
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 462711e..1ee0b1a 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -359,6 +359,10 @@
   bool InitZygote();
   void DidForkFromZygote();
 
+  const instrumentation::Instrumentation* GetInstrumentation() const {
+    return &instrumentation_;
+  }
+
   instrumentation::Instrumentation* GetInstrumentation() {
     return &instrumentation_;
   }
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index dbde7c7..535c76d 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -361,7 +361,7 @@
   SirtRef<mirror::DexCache> dex_cache(self, mh.GetDexCache());
   SirtRef<mirror::ClassLoader> class_loader(self, mh.GetClassLoader());
   MethodVerifier verifier(&mh.GetDexFile(), &dex_cache, &class_loader, &mh.GetClassDef(),
-                          mh.GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), false,
+                          mh.GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
                           true);
   return verifier.FindAccessedFieldAtDexPc(dex_pc);
 }
@@ -375,11 +375,11 @@
   // got what we wanted.
   bool success = Verify();
   if (!success) {
-    return NULL;
+    return nullptr;
   }
   RegisterLine* register_line = reg_table_.GetLine(dex_pc);
   if (register_line == NULL) {
-    return NULL;
+    return nullptr;
   }
   const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc);
   return GetQuickFieldAccess(inst, register_line);
@@ -3118,37 +3118,14 @@
   DCHECK(inst->Opcode() == Instruction::INVOKE_VIRTUAL_QUICK ||
          inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
   const RegType& actual_arg_type = reg_line->GetInvocationThis(inst, is_range);
-  if (actual_arg_type.IsConflict()) {  // GetInvocationThis failed.
-    return nullptr;
-  } else if (actual_arg_type.IsZero()) {  // Invoke on "null" instance: we can't go further.
+  if (!actual_arg_type.HasClass()) {
+    VLOG(verifier) << "Failed to get mirror::Class* from '" << actual_arg_type << "'";
     return nullptr;
   }
-  mirror::Class* this_class = NULL;
-  if (!actual_arg_type.IsUnresolvedTypes()) {
-    this_class = actual_arg_type.GetClass();
-  } else {
-    const std::string& descriptor(actual_arg_type.GetDescriptor());
-    // Try to resolve type.
-    const RegType& resolved_arg_type = reg_types_.FromDescriptor(class_loader_->get(),
-                                                                 descriptor.c_str(), false);
-    if (!resolved_arg_type.HasClass()) {
-      return nullptr;  // Resolution failed.
-    }
-    this_class = resolved_arg_type.GetClass();
-    if (this_class == NULL) {
-      Thread* self = Thread::Current();
-      self->ClearException();
-      // Look for a system class
-      this_class = reg_types_.FromDescriptor(nullptr, descriptor.c_str(), false).GetClass();
-    }
-  }
-  if (this_class == NULL) {
-    return NULL;
-  }
-  mirror::ObjectArray<mirror::ArtMethod>* vtable = this_class->GetVTable();
-  CHECK(vtable != NULL);
+  mirror::ObjectArray<mirror::ArtMethod>* vtable = actual_arg_type.GetClass()->GetVTable();
+  CHECK(vtable != nullptr);
   uint16_t vtable_index = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
-  CHECK(vtable_index < vtable->GetLength());
+  CHECK_LT(static_cast<int32_t>(vtable_index), vtable->GetLength());
   mirror::ArtMethod* res_method = vtable->Get(vtable_index);
   CHECK(!Thread::Current()->IsExceptionPending());
   return res_method;
@@ -3636,12 +3613,12 @@
   if (klass->GetSuperClass() != NULL) {
     return FindInstanceFieldWithOffset(klass->GetSuperClass(), field_offset);
   } else {
-    return NULL;
+    VLOG(verifier) << "Failed to find instance field at offset '" << field_offset
+        << "' from '" << PrettyDescriptor(klass) << "'";
+    return nullptr;
   }
 }
 
-// Returns the access field of a quick field access (iget/iput-quick) or NULL
-// if it cannot be found.
 mirror::ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst,
                                                       RegisterLine* reg_line) {
   DCHECK(inst->Opcode() == Instruction::IGET_QUICK ||
@@ -3651,29 +3628,12 @@
          inst->Opcode() == Instruction::IPUT_WIDE_QUICK ||
          inst->Opcode() == Instruction::IPUT_OBJECT_QUICK);
   const RegType& object_type = reg_line->GetRegisterType(inst->VRegB_22c());
-  mirror::Class* object_class = NULL;
-  if (!object_type.IsUnresolvedTypes()) {
-    object_class = object_type.GetClass();
-  } else {
-    // We need to resolve the class from its descriptor.
-    const std::string& descriptor(object_type.GetDescriptor());
-    Thread* self = Thread::Current();
-    object_class = reg_types_.FromDescriptor(class_loader_->get(), descriptor.c_str(),
-                                             false).GetClass();
-    if (object_class == NULL) {
-      self->ClearException();
-      // Look for a system class
-      object_class = reg_types_.FromDescriptor(nullptr, descriptor.c_str(),
-                                               false).GetClass();
-    }
-  }
-  if (object_class == NULL) {
-    // Failed to get the Class* from reg type.
-    LOG(WARNING) << "Failed to get Class* from " << object_type;
-    return NULL;
+  if (!object_type.HasClass()) {
+    VLOG(verifier) << "Failed to get mirror::Class* from '" << object_type << "'";
+    return nullptr;
   }
   uint32_t field_offset = static_cast<uint32_t>(inst->VRegC_22c());
-  return FindInstanceFieldWithOffset(object_class, field_offset);
+  return FindInstanceFieldWithOffset(object_type.GetClass(), field_offset);
 }
 
 void MethodVerifier::VerifyIGetQuick(const Instruction* inst, const RegType& insn_type,