Some more interpreter cleanup.

- Pass method helper and code item to entry point so they don't
  have to be regenerated.
- Removed interpreter only check from invoke, changing entry
  points instead.

Change-Id: Ib0ea83dcffcdb295d3a48d92ad8a93ac59f9932e
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index 0997438..124c0ee 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -50,12 +50,13 @@
 static const int64_t kMaxLong = std::numeric_limits<int64_t>::max();
 static const int64_t kMinLong = std::numeric_limits<int64_t>::min();
 
-static void UnstartedRuntimeInvoke(Thread* self, AbstractMethod* target_method,
-                                   ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
+static void UnstartedRuntimeInvoke(Thread* self, MethodHelper& mh,
+                                   const DexFile::CodeItem* code_item, ShadowFrame* shadow_frame,
+                                   JValue* result, size_t arg_offset)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   // In a runtime that's not started we intercept certain methods to avoid complicated dependency
   // problems in core libraries.
-  std::string name(PrettyMethod(target_method));
+  std::string name(PrettyMethod(shadow_frame->GetMethod()));
   if (name == "java.lang.Class java.lang.Class.forName(java.lang.String)") {
     std::string descriptor(DotToDescriptor(shadow_frame->GetVRegReference(arg_offset)->AsString()->ToModifiedUtf8().c_str()));
     ClassLoader* class_loader = NULL; // shadow_frame.GetMethod()->GetDeclaringClass()->GetClassLoader();
@@ -132,7 +133,7 @@
     }
   } else {
     // Not special, continue with regular interpreter execution.
-    EnterInterpreterFromInterpreter(self, shadow_frame, result);
+    EnterInterpreterFromInterpreter(self, mh, code_item, shadow_frame, result);
   }
 }
 
@@ -387,47 +388,40 @@
 static void DoInvoke(Thread* self, ShadowFrame& shadow_frame,
                      const Instruction* inst, JValue* result)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c();
-  Object* receiver;
-  if (type == kStatic) {
-    receiver = NULL;
-  } else {
-    receiver = shadow_frame.GetVRegReference(vregC);
-  }
   uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
-  AbstractMethod* target_method = FindMethodFromCode(method_idx, receiver,
-                                                     shadow_frame.GetMethod(),
-                                                     self, true, type);
-  if (UNLIKELY(target_method == NULL)) {
+  uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c();
+  Object* receiver = (type == kStatic) ? NULL : shadow_frame.GetVRegReference(vregC);
+  AbstractMethod* method = FindMethodFromCode(method_idx, receiver, shadow_frame.GetMethod(), self,
+                                              true, type);
+  if (UNLIKELY(method == NULL)) {
     CHECK(self->IsExceptionPending());
     result->SetJ(0);
     return;
   }
-  MethodHelper target_mh(target_method);
 
-  const DexFile::CodeItem* code_item = target_mh.GetCodeItem();
+  MethodHelper mh(method);
+  const DexFile::CodeItem* code_item = mh.GetCodeItem();
   uint16_t num_regs;
   uint16_t num_ins;
-  if (code_item != NULL) {
+  if (LIKELY(code_item != NULL)) {
     num_regs = code_item->registers_size_;
     num_ins = code_item->ins_size_;
-  } else if (target_method->IsAbstract()) {
+  } else if (method->IsAbstract()) {
     ThrowLocation throw_location = self->GetCurrentLocationForThrow();
     self->ThrowNewExceptionF(throw_location, "Ljava/lang/AbstractMethodError;",
-                             "abstract method \"%s\"", PrettyMethod(target_method).c_str());
+                             "abstract method \"%s\"", PrettyMethod(method).c_str());
     return;
   } else {
-    DCHECK(target_method->IsNative() || target_method->IsProxyMethod());
-    num_regs = num_ins = AbstractMethod::NumArgRegisters(target_mh.GetShorty());
-    if (!target_method->IsStatic()) {
+    DCHECK(method->IsNative() || method->IsProxyMethod());
+    num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty());
+    if (!method->IsStatic()) {
       num_regs++;
       num_ins++;
     }
   }
 
   void* memory = alloca(ShadowFrame::ComputeSize(num_regs));
-  ShadowFrame* new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame,
-                                                    target_method, 0, memory));
+  ShadowFrame* new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame, method, 0, memory));
   size_t cur_reg = num_regs - num_ins;
   if (receiver != NULL) {
     new_shadow_frame->SetVRegReference(cur_reg, receiver);
@@ -435,13 +429,13 @@
   }
 
   size_t arg_offset = (receiver == NULL) ? 0 : 1;
-  const char* shorty = target_mh.GetShorty();
+  const char* shorty = mh.GetShorty();
   uint32_t arg[5];
   if (!is_range) {
     inst->GetArgs(arg);
   }
   for (size_t shorty_pos = 0; cur_reg < num_regs; ++shorty_pos, cur_reg++, arg_offset++) {
-    DCHECK_LT(shorty_pos + 1, target_mh.GetShortyLength());
+    DCHECK_LT(shorty_pos + 1, mh.GetShortyLength());
     size_t arg_pos = is_range ? vregC + arg_offset : arg[arg_offset];
     switch (shorty[shorty_pos + 1]) {
       case 'L': {
@@ -464,9 +458,9 @@
   }
 
   if (LIKELY(Runtime::Current()->IsStarted())) {
-    (target_method->GetEntryPointFromInterpreter())(self, new_shadow_frame, result);
+    (method->GetEntryPointFromInterpreter())(self, mh, code_item, new_shadow_frame, result);
   } else {
-    UnstartedRuntimeInvoke(self, target_method, new_shadow_frame, result, num_regs - num_ins);
+    UnstartedRuntimeInvoke(self, mh, code_item, new_shadow_frame, result, num_regs - num_ins);
   }
 }
 
@@ -2701,7 +2695,7 @@
 void EnterInterpreterFromInvoke(Thread* self, AbstractMethod* method, Object* receiver,
                                 uint32_t* args, JValue* result) {
   DCHECK_EQ(self, Thread::Current());
-  if (__builtin_frame_address(0) < self->GetStackEnd()) {
+  if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) {
     ThrowStackOverflowError(self);
     return;
   }
@@ -2805,7 +2799,7 @@
                                 ShadowFrame& shadow_frame)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   DCHECK_EQ(self, Thread::Current());
-  if (__builtin_frame_address(0) < self->GetStackEnd()) {
+  if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) {
     ThrowStackOverflowError(self);
     return JValue();
   }
@@ -2813,9 +2807,11 @@
   return Execute(self, mh, code_item, shadow_frame, JValue());
 }
 
-void EnterInterpreterFromInterpreter(Thread* self, ShadowFrame* shadow_frame, JValue* result)
+void EnterInterpreterFromInterpreter(Thread* self, MethodHelper& mh,
+                                     const DexFile::CodeItem* code_item, ShadowFrame* shadow_frame,
+                                     JValue* result)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  if (__builtin_frame_address(0) < self->GetStackEnd()) {
+  if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) {
     ThrowStackOverflowError(self);
     return;
   }
@@ -2832,8 +2828,6 @@
 
   self->PushShadowFrame(shadow_frame);
 
-  MethodHelper mh(method);
-  const DexFile::CodeItem* code_item = mh.GetCodeItem();
   if (LIKELY(!method->IsNative())) {
     result->SetJ(Execute(self, mh, code_item, *shadow_frame, JValue()).GetJ());
   } else {