Pass the dex method index directly to interface trampoline.

This avoids computing the dex pc and re-finding the method
index again. I have kept the code for kDebugBuild.

Change-Id: Icd60e0deade755e32b54021c0875b1af592b8c3e
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index 3c145d7..6e53ba4 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -890,10 +890,7 @@
      * dex method index.
      */
 ENTRY art_quick_imt_conflict_trampoline
-    ldr    r0, [sp, #0]            @ load caller Method*
-    ldr    r0, [r0, #MIRROR_ART_METHOD_DEX_CACHE_METHODS_OFFSET]  @ load dex_cache_resolved_methods
-    add    r0, #MIRROR_OBJECT_ARRAY_DATA_OFFSET  @ get starting address of data
-    ldr    r0, [r0, r12, lsl 2]    @ load the target method
+    mov    r0, r12
     b art_quick_invoke_interface_trampoline
 END art_quick_imt_conflict_trampoline
 
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 991d29f..7eb6c16 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -1426,10 +1426,7 @@
      * dex method index.
      */
 ENTRY art_quick_imt_conflict_trampoline
-    ldr    w0, [sp, #0]                                // load caller Method*
-    ldr    w0, [x0, #MIRROR_ART_METHOD_DEX_CACHE_METHODS_OFFSET]  // load dex_cache_resolved_methods
-    add    x0, x0, #MIRROR_OBJECT_ARRAY_DATA_OFFSET    // get starting address of data
-    ldr    w0, [x0, xIP1, lsl 2]                       // load the target method
+    mov    x0, xIP1
     b art_quick_invoke_interface_trampoline
 END art_quick_imt_conflict_trampoline
 
diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S
index 92b180e..89d1449 100644
--- a/runtime/arch/mips/quick_entrypoints_mips.S
+++ b/runtime/arch/mips/quick_entrypoints_mips.S
@@ -1091,13 +1091,9 @@
      * dex method index.
      */
 ENTRY art_quick_imt_conflict_trampoline
-    lw      $a0, 0($sp)            # load caller Method*
-    lw      $a0, MIRROR_ART_METHOD_DEX_CACHE_METHODS_OFFSET($a0)  # load dex_cache_resolved_methods
-    sll     $t0, 2                 # convert target method offset to bytes
-    add     $a0, $t0               # get address of target method
-    lw      $a0, MIRROR_OBJECT_ARRAY_DATA_OFFSET($a0)  # load the target method
     la      $t9, art_quick_invoke_interface_trampoline
     jalr    $zero, $t9
+    move    $a0, $t0
 END art_quick_imt_conflict_trampoline
 
     .extern artQuickResolutionTrampoline
diff --git a/runtime/arch/mips64/quick_entrypoints_mips64.S b/runtime/arch/mips64/quick_entrypoints_mips64.S
index b7320a6..031f85f 100644
--- a/runtime/arch/mips64/quick_entrypoints_mips64.S
+++ b/runtime/arch/mips64/quick_entrypoints_mips64.S
@@ -1365,14 +1365,10 @@
      * dex method index.
      */
 ENTRY art_quick_imt_conflict_trampoline
-    lwu     $a0, 0($sp)            # load caller Method*
-    lwu     $a0, MIRROR_ART_METHOD_DEX_CACHE_METHODS_OFFSET($a0)  # load dex_cache_resolved_methods
-    dsll    $t0, 2                 # convert target method offset to bytes
-    daddu   $a0, $t0               # get address of target method
     dla     $t9, art_quick_invoke_interface_trampoline
     .cpreturn
     jalr    $zero, $t9
-    lwu     $a0, MIRROR_OBJECT_ARRAY_DATA_OFFSET($a0)  # load the target method
+    move    $a0, $t0
 END art_quick_imt_conflict_trampoline
 
     .extern artQuickResolutionTrampoline
diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S
index d62c1bc..8207360 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -1385,16 +1385,11 @@
 END_FUNCTION art_quick_proxy_invoke_handler
 
     /*
-     * Called to resolve an imt conflict. xmm0 is a hidden argument that holds the target method's
+     * Called to resolve an imt conflict. xmm7 is a hidden argument that holds the target method's
      * dex method index.
      */
 DEFINE_FUNCTION art_quick_imt_conflict_trampoline
-    PUSH ecx
-    movl 8(%esp), %eax            // load caller Method*
-    movl MIRROR_ART_METHOD_DEX_CACHE_METHODS_OFFSET(%eax), %eax  // load dex_cache_resolved_methods
-    movd %xmm7, %ecx              // get target method index stored in xmm0
-    movl MIRROR_OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4), %eax  // load the target method
-    POP ecx
+    movd %xmm7, %eax              // get target method index stored in xmm7
     jmp SYMBOL(art_quick_invoke_interface_trampoline)
 END_FUNCTION art_quick_imt_conflict_trampoline
 
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index ddeb5b8..7bb18a4 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -1338,9 +1338,7 @@
     int3
     int3
 #else
-    movl 8(%rsp), %edi            // load caller Method*
-    movl MIRROR_ART_METHOD_DEX_CACHE_METHODS_OFFSET(%rdi), %edi  // load dex_cache_resolved_methods
-    movl MIRROR_OBJECT_ARRAY_DATA_OFFSET(%rdi, %rax, 4), %edi  // load the target method
+    movq %rax, %rdi
     jmp art_quick_invoke_interface_trampoline
 #endif  // __APPLE__
 END_FUNCTION art_quick_imt_conflict_trampoline
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 838427f..f5bc080 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -2059,13 +2059,14 @@
 }
 
 // Determine target of interface dispatch. This object is known non-null.
-extern "C" TwoWordReturn artInvokeInterfaceTrampoline(mirror::ArtMethod* interface_method,
+extern "C" TwoWordReturn artInvokeInterfaceTrampoline(uint32_t dex_method_idx,
                                                       mirror::Object* this_object,
                                                       Thread* self,
                                                       StackReference<mirror::ArtMethod>* sp)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   ScopedQuickEntrypointChecks sqec(self);
   mirror::ArtMethod* caller_method = QuickArgumentVisitor::GetCallingMethod(sp);
+  mirror::ArtMethod* interface_method = caller_method->GetDexCacheResolvedMethod(dex_method_idx);
   mirror::ArtMethod* method;
   if (LIKELY(interface_method->GetDexMethodIndex() != DexFile::kDexNoIndex)) {
     method = this_object->GetClass()->FindVirtualMethodForInterface(interface_method);
@@ -2076,21 +2077,21 @@
     }
   } else {
     DCHECK(interface_method == Runtime::Current()->GetResolutionMethod());
-
-    uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp);
-    const DexFile::CodeItem* code = caller_method->GetCodeItem();
-    CHECK_LT(dex_pc, code->insns_size_in_code_units_);
-    const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
-    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(nullptr);
-    uint32_t dex_method_idx;
-    if (instr_code == Instruction::INVOKE_INTERFACE) {
-      dex_method_idx = instr->VRegB_35c();
-    } else {
-      DCHECK_EQ(instr_code, Instruction::INVOKE_INTERFACE_RANGE);
-      dex_method_idx = instr->VRegB_3rc();
+    if (kIsDebugBuild) {
+      uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp);
+      const DexFile::CodeItem* code = caller_method->GetCodeItem();
+      CHECK_LT(dex_pc, code->insns_size_in_code_units_);
+      const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
+      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(nullptr);
+      if (instr_code == Instruction::INVOKE_INTERFACE) {
+        CHECK_EQ(dex_method_idx, instr->VRegB_35c());
+      } else {
+        CHECK_EQ(instr_code, Instruction::INVOKE_INTERFACE_RANGE);
+        CHECK_EQ(dex_method_idx, instr->VRegB_3rc());
+      }
     }
 
     const DexFile* dex_file = caller_method->GetDeclaringClass()->GetDexCache()