Move FindDexMethodIndexInOtherDexFile into ArtMethod.

Move FindDexMethodIndexInOtherDexFile out of MethodHelper into ArtMethod in
preparation for the removal of MethodHelper.
Tidy ClassLinker::ResolveMethod so that all exception paths flow through the
exception pending assertion.
Tidy artQuickResolutionTrampoline to be more explicit about variable names and
only update the dex cache if necessary.

Change-Id: I3e48eb4f6c1291533067c1b53efe90c53bfcaea8
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index e3eb707..a176a87 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -22,7 +22,7 @@
 #include "entrypoints/runtime_asm_entrypoints.h"
 #include "gc/accounting/card_table-inl.h"
 #include "interpreter/interpreter.h"
-#include "method_helper.h"
+#include "method_reference.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
 #include "mirror/dex_cache-inl.h"
@@ -642,7 +642,7 @@
 
   // Convert proxy method into expected interface method.
   mirror::ArtMethod* interface_method = proxy_method->FindOverriddenMethod();
-  DCHECK(interface_method != NULL) << PrettyMethod(proxy_method);
+  DCHECK(interface_method != nullptr) << PrettyMethod(proxy_method);
   DCHECK(!interface_method->IsProxyMethod()) << PrettyMethod(interface_method);
   jobject interface_method_jobj = soa.AddLocalReference<jobject>(interface_method);
 
@@ -711,12 +711,12 @@
   ClassLinker* linker = Runtime::Current()->GetClassLinker();
   mirror::ArtMethod* caller = QuickArgumentVisitor::GetCallingMethod(sp);
   InvokeType invoke_type;
-  const DexFile* dex_file;
-  uint32_t dex_method_idx;
-  if (called->IsRuntimeMethod()) {
+  MethodReference called_method(nullptr, 0);
+  const bool called_method_known_on_entry = !called->IsRuntimeMethod();
+  if (!called_method_known_on_entry) {
     uint32_t dex_pc = caller->ToDexPc(QuickArgumentVisitor::GetCallingPc(sp));
     const DexFile::CodeItem* code;
-    dex_file = caller->GetDexFile();
+    called_method.dex_file = caller->GetDexFile();
     code = caller->GetCodeItem();
     CHECK_LT(dex_pc, code->insns_size_in_code_units_);
     const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
@@ -764,33 +764,33 @@
         is_range = true;
         break;
       default:
-        LOG(FATAL) << "Unexpected call into trampoline: " << instr->DumpString(NULL);
-        // Avoid used uninitialized warnings.
-        invoke_type = kDirect;
-        is_range = false;
+        LOG(FATAL) << "Unexpected call into trampoline: " << instr->DumpString(nullptr);
+        UNREACHABLE();
     }
-    dex_method_idx = (is_range) ? instr->VRegB_3rc() : instr->VRegB_35c();
+    called_method.dex_method_index = (is_range) ? instr->VRegB_3rc() : instr->VRegB_35c();
   } else {
     invoke_type = kStatic;
-    dex_file = called->GetDexFile();
-    dex_method_idx = called->GetDexMethodIndex();
+    called_method.dex_file = called->GetDexFile();
+    called_method.dex_method_index = called->GetDexMethodIndex();
   }
   uint32_t shorty_len;
   const char* shorty =
-      dex_file->GetMethodShorty(dex_file->GetMethodId(dex_method_idx), &shorty_len);
+      called_method.dex_file->GetMethodShorty(
+          called_method.dex_file->GetMethodId(called_method.dex_method_index), &shorty_len);
   RememberForGcArgumentVisitor visitor(sp, invoke_type == kStatic, shorty, shorty_len, &soa);
   visitor.VisitArguments();
   self->EndAssertNoThreadSuspension(old_cause);
-  bool virtual_or_interface = invoke_type == kVirtual || invoke_type == kInterface;
+  const bool virtual_or_interface = invoke_type == kVirtual || invoke_type == kInterface;
   // Resolve method filling in dex cache.
-  if (UNLIKELY(called->IsRuntimeMethod())) {
+  if (!called_method_known_on_entry) {
     StackHandleScope<1> hs(self);
     mirror::Object* dummy = nullptr;
     HandleWrapper<mirror::Object> h_receiver(
         hs.NewHandleWrapper(virtual_or_interface ? &receiver : &dummy));
-    called = linker->ResolveMethod(self, dex_method_idx, &caller, invoke_type);
+    DCHECK_EQ(caller->GetDexFile(), called_method.dex_file);
+    called = linker->ResolveMethod(self, called_method.dex_method_index, &caller, invoke_type);
   }
-  const void* code = NULL;
+  const void* code = nullptr;
   if (LIKELY(!self->IsExceptionPending())) {
     // Incompatible class change should have been handled in resolve method.
     CHECK(!called->CheckIncompatibleClassChange(invoke_type))
@@ -811,20 +811,23 @@
                                << invoke_type << " " << orig_called->GetVtableIndex();
 
       // We came here because of sharpening. Ensure the dex cache is up-to-date on the method index
-      // of the sharpened method.
-      if (called->HasSameDexCacheResolvedMethods(caller)) {
-        caller->SetDexCacheResolvedMethod(called->GetDexMethodIndex(), called);
-      } else {
+      // of the sharpened method avoiding dirtying the dex cache if possible.
+      uint32_t update_dex_cache_method_index = called_method.dex_method_index;
+      if (!called->HasSameDexCacheResolvedMethods(caller)) {
         // Calling from one dex file to another, need to compute the method index appropriate to
         // the caller's dex file. Since we get here only if the original called was a runtime
         // method, we've got the correct dex_file and a dex_method_idx from above.
-        DCHECK_EQ(caller->GetDexFile(), dex_file);
-        StackHandleScope<1> hs(self);
-        MethodHelper mh(hs.NewHandle(called));
-        uint32_t method_index = mh.FindDexMethodIndexInOtherDexFile(*dex_file, dex_method_idx);
-        if (method_index != DexFile::kDexNoIndex) {
-          caller->SetDexCacheResolvedMethod(method_index, called);
-        }
+        DCHECK(!called_method_known_on_entry);
+        DCHECK_EQ(caller->GetDexFile(), called_method.dex_file);
+        const DexFile* caller_dex_file = called_method.dex_file;
+        uint32_t caller_method_name_and_sig_index = called_method.dex_method_index;
+        update_dex_cache_method_index =
+            called->FindDexMethodIndexInOtherDexFile(*caller_dex_file,
+                                                     caller_method_name_and_sig_index);
+      }
+      if ((update_dex_cache_method_index != DexFile::kDexNoIndex) &&
+          (caller->GetDexCacheResolvedMethod(update_dex_cache_method_index) != called)) {
+        caller->SetDexCacheResolvedMethod(update_dex_cache_method_index, called);
       }
     }
     // Ensure that the called method's class is initialized.
@@ -846,7 +849,7 @@
       DCHECK(called_class->IsErroneous());
     }
   }
-  CHECK_EQ(code == NULL, self->IsExceptionPending());
+  CHECK_EQ(code == nullptr, self->IsExceptionPending());
   // Fixup any locally saved objects may have moved during a GC.
   visitor.FixupReferences();
   // Place called method in callee-save frame to be placed as first argument to quick method.
@@ -1263,6 +1266,7 @@
           break;
         default:
           LOG(FATAL) << "Unexpected type: " << cur_type_ << " in " << shorty;
+          UNREACHABLE();
       }
     }
 
@@ -1786,7 +1790,7 @@
       visitor.FixupReferences();
     }
 
-    if (UNLIKELY(method == NULL)) {
+    if (UNLIKELY(method == nullptr)) {
       CHECK(self->IsExceptionPending());
       return GetTwoWordFailureValue();  // Failure.
     }
@@ -1795,7 +1799,7 @@
   const void* code = method->GetEntryPointFromQuickCompiledCode();
 
   // When we return, the caller will branch to this address, so it had better not be 0!
-  DCHECK(code != nullptr) << "Code was NULL in method: " << PrettyMethod(method)
+  DCHECK(code != nullptr) << "Code was null in method: " << PrettyMethod(method)
                           << " location: "
                           << method->GetDexFile()->GetLocation();
 
@@ -1881,7 +1885,7 @@
   mirror::ArtMethod* method;
   if (LIKELY(interface_method->GetDexMethodIndex() != DexFile::kDexNoIndex)) {
     method = this_object->GetClass()->FindVirtualMethodForInterface(interface_method);
-    if (UNLIKELY(method == NULL)) {
+    if (UNLIKELY(method == nullptr)) {
       ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(interface_method, this_object,
                                                                  caller_method);
       return GetTwoWordFailureValue();  // Failure.
@@ -1901,7 +1905,7 @@
     Instruction::Code instr_code = instr->Opcode();
     CHECK(instr_code == Instruction::INVOKE_INTERFACE ||
           instr_code == Instruction::INVOKE_INTERFACE_RANGE)
-        << "Unexpected call into interface trampoline: " << instr->DumpString(NULL);
+        << "Unexpected call into interface trampoline: " << instr->DumpString(nullptr);
     uint32_t dex_method_idx;
     if (instr_code == Instruction::INVOKE_INTERFACE) {
       dex_method_idx = instr->VRegB_35c();
@@ -1933,7 +1937,7 @@
   const void* code = method->GetEntryPointFromQuickCompiledCode();
 
   // When we return, the caller will branch to this address, so it had better not be 0!
-  DCHECK(code != nullptr) << "Code was NULL in method: " << PrettyMethod(method)
+  DCHECK(code != nullptr) << "Code was null in method: " << PrettyMethod(method)
                           << " location: " << method->GetDexFile()->GetLocation();
 
   return GetTwoWordSuccessValue(reinterpret_cast<uintptr_t>(code),