Remove MethodHelper from the interpreter.

Use ShadowFrame to get the executing method to avoid a handle for the current
method.
Various associated bits of header file clean-up and removal of an unnecessary
use of MethodHelper in CompilerDriver.

Change-Id: I3b6f4413701e8fc6b0c58b0041a0dd15472bedaa
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index b17f303..b04a18b 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -327,37 +327,31 @@
 // Clang 3.4 fails to build the goto interpreter implementation.
 static constexpr InterpreterImplKind kInterpreterImplKind = kSwitchImpl;
 template<bool do_access_check, bool transaction_active>
-JValue ExecuteGotoImpl(Thread*, MethodHelper&, const DexFile::CodeItem*, ShadowFrame&, JValue) {
+JValue ExecuteGotoImpl(Thread*, const DexFile::CodeItem*, ShadowFrame&, JValue) {
   LOG(FATAL) << "UNREACHABLE";
   UNREACHABLE();
 }
 // Explicit definitions of ExecuteGotoImpl.
 template<> SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-JValue ExecuteGotoImpl<true, false>(Thread* self, MethodHelper& mh,
-                                    const DexFile::CodeItem* code_item,
+JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
                                     ShadowFrame& shadow_frame, JValue result_register);
 template<> SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-JValue ExecuteGotoImpl<false, false>(Thread* self, MethodHelper& mh,
-                                     const DexFile::CodeItem* code_item,
+JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
                                      ShadowFrame& shadow_frame, JValue result_register);
 template<> SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-JValue ExecuteGotoImpl<true, true>(Thread* self, MethodHelper& mh,
-                                    const DexFile::CodeItem* code_item,
+JValue ExecuteGotoImpl<true, true>(Thread* self,  const DexFile::CodeItem* code_item,
+                                   ShadowFrame& shadow_frame, JValue result_register);
+template<> SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
                                     ShadowFrame& shadow_frame, JValue result_register);
-template<> SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-JValue ExecuteGotoImpl<false, true>(Thread* self, MethodHelper& mh,
-                                     const DexFile::CodeItem* code_item,
-                                     ShadowFrame& shadow_frame, JValue result_register);
 #endif
 
-static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
-                      ShadowFrame& shadow_frame, JValue result_register)
+static JValue Execute(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame,
+                      JValue result_register)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-static inline JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
+static inline JValue Execute(Thread* self, const DexFile::CodeItem* code_item,
                              ShadowFrame& shadow_frame, JValue result_register) {
-  DCHECK(shadow_frame.GetMethod() == mh.GetMethod() ||
-         shadow_frame.GetMethod()->GetDeclaringClass()->IsProxyClass());
   DCHECK(!shadow_frame.GetMethod()->IsAbstract());
   DCHECK(!shadow_frame.GetMethod()->IsNative());
   shadow_frame.GetMethod()->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self);
@@ -367,32 +361,32 @@
     // Enter the "without access check" interpreter.
     if (kInterpreterImplKind == kSwitchImpl) {
       if (transaction_active) {
-        return ExecuteSwitchImpl<false, true>(self, mh, code_item, shadow_frame, result_register);
+        return ExecuteSwitchImpl<false, true>(self, code_item, shadow_frame, result_register);
       } else {
-        return ExecuteSwitchImpl<false, false>(self, mh, code_item, shadow_frame, result_register);
+        return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register);
       }
     } else {
       DCHECK_EQ(kInterpreterImplKind, kComputedGotoImplKind);
       if (transaction_active) {
-        return ExecuteGotoImpl<false, true>(self, mh, code_item, shadow_frame, result_register);
+        return ExecuteGotoImpl<false, true>(self, code_item, shadow_frame, result_register);
       } else {
-        return ExecuteGotoImpl<false, false>(self, mh, code_item, shadow_frame, result_register);
+        return ExecuteGotoImpl<false, false>(self, code_item, shadow_frame, result_register);
       }
     }
   } else {
     // Enter the "with access check" interpreter.
     if (kInterpreterImplKind == kSwitchImpl) {
       if (transaction_active) {
-        return ExecuteSwitchImpl<true, true>(self, mh, code_item, shadow_frame, result_register);
+        return ExecuteSwitchImpl<true, true>(self, code_item, shadow_frame, result_register);
       } else {
-        return ExecuteSwitchImpl<true, false>(self, mh, code_item, shadow_frame, result_register);
+        return ExecuteSwitchImpl<true, false>(self, code_item, shadow_frame, result_register);
       }
     } else {
       DCHECK_EQ(kInterpreterImplKind, kComputedGotoImplKind);
       if (transaction_active) {
-        return ExecuteGotoImpl<true, true>(self, mh, code_item, shadow_frame, result_register);
+        return ExecuteGotoImpl<true, true>(self, code_item, shadow_frame, result_register);
       } else {
-        return ExecuteGotoImpl<true, false>(self, mh, code_item, shadow_frame, result_register);
+        return ExecuteGotoImpl<true, false>(self, code_item, shadow_frame, result_register);
       }
     }
   }
@@ -473,9 +467,7 @@
     }
   }
   if (LIKELY(!method->IsNative())) {
-    StackHandleScope<1> hs(self);
-    MethodHelper mh(hs.NewHandle(method));
-    JValue r = Execute(self, mh, code_item, *shadow_frame, JValue());
+    JValue r = Execute(self, code_item, *shadow_frame, JValue());
     if (result != NULL) {
       *result = r;
     }
@@ -500,10 +492,8 @@
   value.SetJ(ret_val->GetJ());  // Set value to last known result in case the shadow frame chain is empty.
   while (shadow_frame != NULL) {
     self->SetTopOfShadowStack(shadow_frame);
-    StackHandleScope<1> hs(self);
-    MethodHelper mh(hs.NewHandle(shadow_frame->GetMethod()));
-    const DexFile::CodeItem* code_item = mh.GetMethod()->GetCodeItem();
-    value = Execute(self, mh, code_item, *shadow_frame, value);
+    const DexFile::CodeItem* code_item = shadow_frame->GetMethod()->GetCodeItem();
+    value = Execute(self, code_item, *shadow_frame, value);
     ShadowFrame* old_frame = shadow_frame;
     shadow_frame = shadow_frame->GetLink();
     delete old_frame;
@@ -511,8 +501,7 @@
   ret_val->SetJ(value.GetJ());
 }
 
-JValue EnterInterpreterFromEntryPoint(Thread* self, MethodHelper* mh,
-                                      const DexFile::CodeItem* code_item,
+JValue EnterInterpreterFromEntryPoint(Thread* self, const DexFile::CodeItem* code_item,
                                       ShadowFrame* shadow_frame) {
   DCHECK_EQ(self, Thread::Current());
   bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks();
@@ -521,11 +510,10 @@
     return JValue();
   }
 
-  return Execute(self, *mh, code_item, *shadow_frame, JValue());
+  return Execute(self, code_item, *shadow_frame, JValue());
 }
 
-extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper* mh,
-                                                  const DexFile::CodeItem* code_item,
+extern "C" void artInterpreterToInterpreterBridge(Thread* self, const DexFile::CodeItem* code_item,
                                                   ShadowFrame* shadow_frame, JValue* result) {
   bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks();
   if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) {
@@ -534,10 +522,10 @@
   }
 
   self->PushShadowFrame(shadow_frame);
-  DCHECK_EQ(shadow_frame->GetMethod(), mh->Get());
   // Ensure static methods are initialized.
-  if (mh->Get()->IsStatic()) {
-    mirror::Class* declaring_class = mh->Get()->GetDeclaringClass();
+  const bool is_static = shadow_frame->GetMethod()->IsStatic();
+  if (is_static) {
+    mirror::Class* declaring_class = shadow_frame->GetMethod()->GetDeclaringClass();
     if (UNLIKELY(!declaring_class->IsInitialized())) {
       StackHandleScope<1> hs(self);
       HandleWrapper<Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class));
@@ -551,15 +539,15 @@
     }
   }
 
-  if (LIKELY(!mh->Get()->IsNative())) {
-    result->SetJ(Execute(self, *mh, code_item, *shadow_frame, JValue()).GetJ());
+  if (LIKELY(!shadow_frame->GetMethod()->IsNative())) {
+    result->SetJ(Execute(self, code_item, *shadow_frame, JValue()).GetJ());
   } else {
     // We don't expect to be asked to interpret native code (which is entered via a JNI compiler
     // generated stub) except during testing and image writing.
     CHECK(!Runtime::Current()->IsStarted());
-    Object* receiver = mh->Get()->IsStatic() ? nullptr : shadow_frame->GetVRegReference(0);
-    uint32_t* args = shadow_frame->GetVRegArgs(mh->Get()->IsStatic() ? 0 : 1);
-    UnstartedRuntimeJni(self, mh->Get(), receiver, args, result);
+    Object* receiver = is_static ? nullptr : shadow_frame->GetVRegReference(0);
+    uint32_t* args = shadow_frame->GetVRegArgs(is_static ? 0 : 1);
+    UnstartedRuntimeJni(self, shadow_frame->GetMethod(), receiver, args, result);
   }
 
   self->PopShadowFrame();
diff --git a/runtime/interpreter/interpreter.h b/runtime/interpreter/interpreter.h
index d327a71..7d634b3 100644
--- a/runtime/interpreter/interpreter.h
+++ b/runtime/interpreter/interpreter.h
@@ -27,7 +27,6 @@
 }  // namespace mirror
 
 union JValue;
-class MethodHelper;
 class ShadowFrame;
 class Thread;
 
@@ -42,21 +41,18 @@
                                            JValue* ret_val)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-extern JValue EnterInterpreterFromEntryPoint(Thread* self, MethodHelper* mh,
-                                             const DexFile::CodeItem* code_item,
+extern JValue EnterInterpreterFromEntryPoint(Thread* self, const DexFile::CodeItem* code_item,
                                              ShadowFrame* shadow_frame)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 
 }  // namespace interpreter
 
-extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper* mh,
-                                                  const DexFile::CodeItem* code_item,
+extern "C" void artInterpreterToInterpreterBridge(Thread* self, const DexFile::CodeItem* code_item,
                                                   ShadowFrame* shadow_frame, JValue* result)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-extern "C" void artInterpreterToCompiledCodeBridge(Thread* self, MethodHelper* mh,
-                                                   const DexFile::CodeItem* code_item,
+extern "C" void artInterpreterToCompiledCodeBridge(Thread* self, const DexFile::CodeItem* code_item,
                                                    ShadowFrame* shadow_frame, JValue* result)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index eb80c30..5340bee 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -505,14 +505,14 @@
   return found_dex_pc;
 }
 
-void UnexpectedOpcode(const Instruction* inst, MethodHelper& mh) {
-  LOG(FATAL) << "Unexpected instruction: " << inst->DumpString(mh.GetMethod()->GetDexFile());
-  exit(0);  // Unreachable, keep GCC happy.
+void UnexpectedOpcode(const Instruction* inst, const ShadowFrame& shadow_frame) {
+  LOG(FATAL) << "Unexpected instruction: "
+             << inst->DumpString(shadow_frame.GetMethod()->GetDexFile());
+  UNREACHABLE();
 }
 
-static void UnstartedRuntimeInvoke(Thread* self, MethodHelper* mh,
-                                   const DexFile::CodeItem* code_item, ShadowFrame* shadow_frame,
-                                   JValue* result, size_t arg_offset)
+static void UnstartedRuntimeInvoke(Thread* self, const DexFile::CodeItem* code_item,
+                                   ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 // Assign register 'src_reg' from shadow_frame to register 'dest_reg' into new_shadow_frame.
@@ -540,30 +540,39 @@
   va_end(args);
 }
 
+static mirror::Class* GetClassFromTypeIdx(mirror::ArtMethod* method, uint16_t type_idx)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+  mirror::Class* type = method->GetDexCacheResolvedType(type_idx);
+  if (type == nullptr) {
+    type = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
+    CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
+  }
+  return type;
+}
+
 template<bool is_range, bool do_assignability_check>
-bool DoCall(ArtMethod* method, Thread* self, ShadowFrame& shadow_frame,
+bool DoCall(ArtMethod* called_method, Thread* self, ShadowFrame& shadow_frame,
             const Instruction* inst, uint16_t inst_data, JValue* result) {
   // Compute method information.
-  const DexFile::CodeItem* code_item = method->GetCodeItem();
+  const DexFile::CodeItem* code_item = called_method->GetCodeItem();
   const uint16_t num_ins = (is_range) ? inst->VRegA_3rc(inst_data) : inst->VRegA_35c(inst_data);
   uint16_t num_regs;
   if (LIKELY(code_item != NULL)) {
     num_regs = code_item->registers_size_;
     DCHECK_EQ(num_ins, code_item->ins_size_);
   } else {
-    DCHECK(method->IsNative() || method->IsProxyMethod());
+    DCHECK(called_method->IsNative() || called_method->IsProxyMethod());
     num_regs = num_ins;
   }
 
   // Allocate shadow frame on the stack.
   const char* old_cause = self->StartAssertNoThreadSuspension("DoCall");
   void* memory = alloca(ShadowFrame::ComputeSize(num_regs));
-  ShadowFrame* new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame, method, 0, memory));
+  ShadowFrame* new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame, called_method, 0,
+                                                    memory));
 
   // Initialize new shadow frame.
   const size_t first_dest_reg = num_regs - num_ins;
-  StackHandleScope<1> hs(self);
-  MethodHelper mh(hs.NewHandle(method));
   if (do_assignability_check) {
     // Slow path.
     // We might need to do class loading, which incurs a thread state change to kNative. So
@@ -573,11 +582,12 @@
 
     // We need to do runtime check on reference assignment. We need to load the shorty
     // to get the exact type of each reference argument.
-    const DexFile::TypeList* params = mh.Get()->GetParameterTypeList();
+    const DexFile::TypeList* params = new_shadow_frame->GetMethod()->GetParameterTypeList();
     uint32_t shorty_len = 0;
-    const char* shorty = mh.Get()->GetShorty(&shorty_len);
+    const char* shorty = new_shadow_frame->GetMethod()->GetShorty(&shorty_len);
 
-    // TODO: find a cleaner way to separate non-range and range information without duplicating code.
+    // TODO: find a cleaner way to separate non-range and range information without duplicating
+    //       code.
     uint32_t arg[5];  // only used in invoke-XXX.
     uint32_t vregC;   // only used in invoke-XXX-range.
     if (is_range) {
@@ -589,7 +599,7 @@
     // Handle receiver apart since it's not part of the shorty.
     size_t dest_reg = first_dest_reg;
     size_t arg_offset = 0;
-    if (!mh.Get()->IsStatic()) {
+    if (!new_shadow_frame->GetMethod()->IsStatic()) {
       size_t receiver_reg = is_range ? vregC : arg[0];
       new_shadow_frame->SetVRegReference(dest_reg, shadow_frame.GetVRegReference(receiver_reg));
       ++dest_reg;
@@ -602,7 +612,8 @@
         case 'L': {
           Object* o = shadow_frame.GetVRegReference(src_reg);
           if (do_assignability_check && o != NULL) {
-            Class* arg_type = mh.GetClassFromTypeIdx(params->GetTypeItem(shorty_pos).type_idx_);
+            Class* arg_type = GetClassFromTypeIdx(new_shadow_frame->GetMethod(),
+                                                  params->GetTypeItem(shorty_pos).type_idx_);
             if (arg_type == NULL) {
               CHECK(self->IsExceptionPending());
               return false;
@@ -613,7 +624,7 @@
               self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
                                        "Ljava/lang/VirtualMachineError;",
                                        "Invoking %s with bad arg %d, type '%s' not instance of '%s'",
-                                       mh.Get()->GetName(), shorty_pos,
+                                       new_shadow_frame->GetMethod()->GetName(), shorty_pos,
                                        o->GetClass()->GetDescriptor(&temp1),
                                        arg_type->GetDescriptor(&temp2));
               return false;
@@ -650,7 +661,8 @@
       uint16_t regList = inst->Fetch16(2);
       uint16_t count = num_ins;
       if (count == 5) {
-        AssignRegister(new_shadow_frame, shadow_frame, first_dest_reg + 4U, (inst_data >> 8) & 0x0f);
+        AssignRegister(new_shadow_frame, shadow_frame, first_dest_reg + 4U,
+                       (inst_data >> 8) & 0x0f);
         --count;
        }
       for (size_t arg_index = 0; arg_index < count; ++arg_index, regList >>= 4) {
@@ -662,17 +674,24 @@
 
   // Do the call now.
   if (LIKELY(Runtime::Current()->IsStarted())) {
-    if (kIsDebugBuild && mh.Get()->GetEntryPointFromInterpreter() == nullptr) {
-      LOG(FATAL) << "Attempt to invoke non-executable method: " << PrettyMethod(mh.Get());
+    if (kIsDebugBuild && new_shadow_frame->GetMethod()->GetEntryPointFromInterpreter() == nullptr) {
+      LOG(FATAL) << "Attempt to invoke non-executable method: "
+          << PrettyMethod(new_shadow_frame->GetMethod());
+      UNREACHABLE();
     }
     if (kIsDebugBuild && Runtime::Current()->GetInstrumentation()->IsForcedInterpretOnly() &&
-        !mh.Get()->IsNative() && !mh.Get()->IsProxyMethod() &&
-        mh.Get()->GetEntryPointFromInterpreter() == artInterpreterToCompiledCodeBridge) {
-      LOG(FATAL) << "Attempt to call compiled code when -Xint: " << PrettyMethod(mh.Get());
+        !new_shadow_frame->GetMethod()->IsNative() &&
+        !new_shadow_frame->GetMethod()->IsProxyMethod() &&
+        new_shadow_frame->GetMethod()->GetEntryPointFromInterpreter()
+            == artInterpreterToCompiledCodeBridge) {
+      LOG(FATAL) << "Attempt to call compiled code when -Xint: "
+          << PrettyMethod(new_shadow_frame->GetMethod());
+      UNREACHABLE();
     }
-    (mh.Get()->GetEntryPointFromInterpreter())(self, &mh, code_item, new_shadow_frame, result);
+    (new_shadow_frame->GetMethod()->GetEntryPointFromInterpreter())(self, code_item,
+                                                                    new_shadow_frame, result);
   } else {
-    UnstartedRuntimeInvoke(self, &mh, code_item, new_shadow_frame, result, first_dest_reg);
+    UnstartedRuntimeInvoke(self, code_item, new_shadow_frame, result, first_dest_reg);
   }
   return !self->IsExceptionPending();
 }
@@ -813,8 +832,8 @@
   result->SetL(found);
 }
 
-static void UnstartedRuntimeInvoke(Thread* self, MethodHelper* mh,
-                                   const DexFile::CodeItem* code_item, ShadowFrame* shadow_frame,
+static void UnstartedRuntimeInvoke(Thread* self,  const DexFile::CodeItem* code_item,
+                                   ShadowFrame* shadow_frame,
                                    JValue* result, size_t arg_offset) {
   // In a runtime that's not started we intercept certain methods to avoid complicated dependency
   // problems in core libraries.
@@ -934,7 +953,7 @@
     }
   } else {
     // Not special, continue with regular interpreter execution.
-    artInterpreterToInterpreterBridge(self, mh, code_item, shadow_frame, result);
+    artInterpreterToInterpreterBridge(self, code_item, shadow_frame, result);
   }
 }
 
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index f88d56a..ce7c1c3 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -33,7 +33,6 @@
 #include "entrypoints/entrypoint_utils-inl.h"
 #include "gc/accounting/card_table-inl.h"
 #include "handle_scope-inl.h"
-#include "method_helper-inl.h"
 #include "nth_caller_visitor.h"
 #include "mirror/art_field-inl.h"
 #include "mirror/art_method.h"
@@ -70,13 +69,11 @@
 // External references to both interpreter implementations.
 
 template<bool do_access_check, bool transaction_active>
-extern JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh,
-                                const DexFile::CodeItem* code_item,
+extern JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
                                 ShadowFrame& shadow_frame, JValue result_register);
 
 template<bool do_access_check, bool transaction_active>
-extern JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh,
-                              const DexFile::CodeItem* code_item,
+extern JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item,
                               ShadowFrame& shadow_frame, JValue result_register);
 
 void ThrowNullPointerExceptionFromInterpreter(const ShadowFrame& shadow_frame)
@@ -100,7 +97,7 @@
 // DoInvokeVirtualQuick functions.
 // Returns true on success, otherwise throws an exception and returns false.
 template<bool is_range, bool do_assignability_check>
-bool DoCall(ArtMethod* method, Thread* self, ShadowFrame& shadow_frame,
+bool DoCall(ArtMethod* called_method, Thread* self, ShadowFrame& shadow_frame,
             const Instruction* inst, uint16_t inst_data, JValue* result);
 
 // Handles invoke-XXX/range instructions.
@@ -112,19 +109,20 @@
   const uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c();
   Object* receiver = (type == kStatic) ? nullptr : shadow_frame.GetVRegReference(vregC);
   mirror::ArtMethod* sf_method = shadow_frame.GetMethod();
-  ArtMethod* const method = FindMethodFromCode<type, do_access_check>(
+  ArtMethod* const called_method = FindMethodFromCode<type, do_access_check>(
       method_idx, &receiver, &sf_method, self);
   // The shadow frame should already be pushed, so we don't need to update it.
-  if (UNLIKELY(method == nullptr)) {
+  if (UNLIKELY(called_method == nullptr)) {
     CHECK(self->IsExceptionPending());
     result->SetJ(0);
     return false;
-  } else if (UNLIKELY(method->IsAbstract())) {
-    ThrowAbstractMethodError(method);
+  } else if (UNLIKELY(called_method->IsAbstract())) {
+    ThrowAbstractMethodError(called_method);
     result->SetJ(0);
     return false;
   } else {
-    return DoCall<is_range, do_access_check>(method, self, shadow_frame, inst, inst_data, result);
+    return DoCall<is_range, do_access_check>(called_method, self, shadow_frame, inst, inst_data,
+                                             result);
   }
 }
 
@@ -144,18 +142,18 @@
   }
   const uint32_t vtable_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   CHECK(receiver->GetClass()->ShouldHaveEmbeddedImtAndVTable());
-  ArtMethod* const method = receiver->GetClass()->GetEmbeddedVTableEntry(vtable_idx);
-  if (UNLIKELY(method == nullptr)) {
+  ArtMethod* const called_method = receiver->GetClass()->GetEmbeddedVTableEntry(vtable_idx);
+  if (UNLIKELY(called_method == nullptr)) {
     CHECK(self->IsExceptionPending());
     result->SetJ(0);
     return false;
-  } else if (UNLIKELY(method->IsAbstract())) {
-    ThrowAbstractMethodError(method);
+  } else if (UNLIKELY(called_method->IsAbstract())) {
+    ThrowAbstractMethodError(called_method);
     result->SetJ(0);
     return false;
   } else {
     // No need to check since we've been quickened.
-    return DoCall<is_range, false>(method, self, shadow_frame, inst, inst_data, result);
+    return DoCall<is_range, false>(called_method, self, shadow_frame, inst, inst_data, result);
   }
 }
 
@@ -351,12 +349,12 @@
     uint32_t dex_pc, const instrumentation::Instrumentation* instrumentation)
         SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-void UnexpectedOpcode(const Instruction* inst, MethodHelper& mh)
+void UnexpectedOpcode(const Instruction* inst, const ShadowFrame& shadow_frame)
   __attribute__((cold, noreturn))
   SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 static inline void TraceExecution(const ShadowFrame& shadow_frame, const Instruction* inst,
-                                  const uint32_t dex_pc, MethodHelper& mh)
+                                  const uint32_t dex_pc)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   constexpr bool kTracing = false;
   if (kTracing) {
@@ -364,7 +362,7 @@
     std::ostringstream oss;
     oss << PrettyMethod(shadow_frame.GetMethod())
         << StringPrintf("\n0x%x: ", dex_pc)
-        << inst->DumpString(mh.GetMethod()->GetDexFile()) << "\n";
+        << inst->DumpString(shadow_frame.GetMethod()->GetDexFile()) << "\n";
     for (uint32_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) {
       uint32_t raw_value = shadow_frame.GetVReg(i);
       Object* ref_value = shadow_frame.GetVRegReference(i);
diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc
index 6350c56..c332a7b 100644
--- a/runtime/interpreter/interpreter_goto_table_impl.cc
+++ b/runtime/interpreter/interpreter_goto_table_impl.cc
@@ -26,7 +26,6 @@
 // - "inst_data" : the current instruction's first 16 bits.
 // - "dex_pc": the current pc.
 // - "shadow_frame": the current shadow frame.
-// - "mh": the current MethodHelper.
 // - "currentHandlersTable": the current table of pointer to each instruction handler.
 
 // Advance to the next instruction and updates interpreter state.
@@ -36,7 +35,7 @@
     inst = inst->RelativeAt(disp);                                          \
     dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp);    \
     shadow_frame.SetDexPC(dex_pc);                                          \
-    TraceExecution(shadow_frame, inst, dex_pc, mh);                         \
+    TraceExecution(shadow_frame, inst, dex_pc);                             \
     inst_data = inst->Fetch16(0);                                           \
     goto *currentHandlersTable[inst->Opcode(inst_data)];                    \
   } while (false)
@@ -59,6 +58,7 @@
   do {                                          \
     if (kIsDebugBuild) {                        \
       LOG(FATAL) << "We should not be here !";  \
+      UNREACHABLE();                            \
     }                                           \
   } while (false)
 
@@ -111,8 +111,8 @@
  *
  */
 template<bool do_access_check, bool transaction_active>
-JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
-                       ShadowFrame& shadow_frame, JValue result_register) {
+JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame,
+                       JValue result_register) {
   // Define handler tables:
   // - The main handler table contains execution handlers for each instruction.
   // - The alternative handler table contains prelude handlers which check for thread suspend and
@@ -2279,103 +2279,103 @@
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_3E)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_3F)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_40)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_41)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_42)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_43)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_79)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_7A)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_EF)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_F0)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_F1)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_F2)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_F3)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_F4)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_F5)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_F6)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_F7)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_F8)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_F9)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_FA)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_FB)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_FC)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_FD)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_FE)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   HANDLE_INSTRUCTION_START(UNUSED_FF)
-    UnexpectedOpcode(inst, mh);
+    UnexpectedOpcode(inst, shadow_frame);
   HANDLE_INSTRUCTION_END();
 
   exception_pending_label: {
@@ -2430,21 +2430,17 @@
 
 // Explicit definitions of ExecuteGotoImpl.
 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
-JValue ExecuteGotoImpl<true, false>(Thread* self, MethodHelper& mh,
-                                    const DexFile::CodeItem* code_item,
+JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
                                     ShadowFrame& shadow_frame, JValue result_register);
 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
-JValue ExecuteGotoImpl<false, false>(Thread* self, MethodHelper& mh,
-                                     const DexFile::CodeItem* code_item,
+JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
                                      ShadowFrame& shadow_frame, JValue result_register);
 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-JValue ExecuteGotoImpl<true, true>(Thread* self, MethodHelper& mh,
-                                    const DexFile::CodeItem* code_item,
+JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
+                                   ShadowFrame& shadow_frame, JValue result_register);
+template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
                                     ShadowFrame& shadow_frame, JValue result_register);
-template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-JValue ExecuteGotoImpl<false, true>(Thread* self, MethodHelper& mh,
-                                     const DexFile::CodeItem* code_item,
-                                     ShadowFrame& shadow_frame, JValue result_register);
 
 }  // namespace interpreter
 }  // namespace art
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index 1b6f53e..f9bbfa1 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -57,7 +57,7 @@
   } while (false)
 
 template<bool do_access_check, bool transaction_active>
-JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
+JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
                          ShadowFrame& shadow_frame, JValue result_register) {
   bool do_assignability_check = do_access_check;
   if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
@@ -82,7 +82,7 @@
   while (true) {
     dex_pc = inst->GetDexPc(insns);
     shadow_frame.SetDexPC(dex_pc);
-    TraceExecution(shadow_frame, inst, dex_pc, mh);
+    TraceExecution(shadow_frame, inst, dex_pc);
     inst_data = inst->Fetch16(0);
     switch (inst->Opcode(inst_data)) {
       case Instruction::NOP:
@@ -2140,27 +2140,23 @@
       case Instruction::UNUSED_EF ... Instruction::UNUSED_FF:
       case Instruction::UNUSED_79:
       case Instruction::UNUSED_7A:
-        UnexpectedOpcode(inst, mh);
+        UnexpectedOpcode(inst, shadow_frame);
     }
   }
 }  // NOLINT(readability/fn_size)
 
 // Explicit definitions of ExecuteSwitchImpl.
 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
-JValue ExecuteSwitchImpl<true, false>(Thread* self, MethodHelper& mh,
-                                      const DexFile::CodeItem* code_item,
+JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
                                       ShadowFrame& shadow_frame, JValue result_register);
 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
-JValue ExecuteSwitchImpl<false, false>(Thread* self, MethodHelper& mh,
-                                       const DexFile::CodeItem* code_item,
+JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
                                        ShadowFrame& shadow_frame, JValue result_register);
 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-JValue ExecuteSwitchImpl<true, true>(Thread* self, MethodHelper& mh,
-                                     const DexFile::CodeItem* code_item,
+JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
                                      ShadowFrame& shadow_frame, JValue result_register);
 template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
-JValue ExecuteSwitchImpl<false, true>(Thread* self, MethodHelper& mh,
-                                      const DexFile::CodeItem* code_item,
+JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
                                       ShadowFrame& shadow_frame, JValue result_register);
 
 }  // namespace interpreter