ART: Simplify MethodHandle invocations

Use an operand iterator rather than passing arguments for both
range and varargs operands.

Test: art/test.py --host -j32
Change-Id: Ia42398773bd3732d917e19c25aa431b1e1369320
diff --git a/runtime/method_handles.h b/runtime/method_handles.h
index 930b8db..bc74bf2 100644
--- a/runtime/method_handles.h
+++ b/runtime/method_handles.h
@@ -126,50 +126,40 @@
                         int32_t num_conversions) REQUIRES_SHARED(Locks::mutator_lock_);
 
 // A convenience class that allows for iteration through a list of
-// input argument registers |arg| for non-range invokes or a list of
-// consecutive registers starting with a given based for range
-// invokes.
-//
-// This is used to iterate over input arguments while performing standard
-// argument conversions.
-template <bool is_range>
+// input argument registers. This is used to iterate over input
+// arguments while performing standard argument conversions.
 class ShadowFrameGetter {
  public:
-  ShadowFrameGetter(size_t first_src_reg,
-                    const uint32_t (&arg)[Instruction::kMaxVarArgRegs],
-                    const ShadowFrame& shadow_frame) :
-      first_src_reg_(first_src_reg),
-      arg_(arg),
-      shadow_frame_(shadow_frame),
-      arg_index_(0) {
-  }
+  ShadowFrameGetter(const InstructionOperands* const operands, const ShadowFrame& shadow_frame)
+      : operands_(operands), operand_index_(0), shadow_frame_(shadow_frame) {}
 
   ALWAYS_INLINE uint32_t Get() REQUIRES_SHARED(Locks::mutator_lock_) {
-    const uint32_t next = (is_range ? first_src_reg_ + arg_index_ : arg_[arg_index_]);
-    ++arg_index_;
-
-    return shadow_frame_.GetVReg(next);
+    return shadow_frame_.GetVReg(Next());
   }
 
   ALWAYS_INLINE int64_t GetLong() REQUIRES_SHARED(Locks::mutator_lock_) {
-    const uint32_t next = (is_range ? first_src_reg_ + arg_index_ : arg_[arg_index_]);
-    arg_index_ += 2;
-
-    return shadow_frame_.GetVRegLong(next);
+    return shadow_frame_.GetVRegLong(NextLong());
   }
 
   ALWAYS_INLINE ObjPtr<mirror::Object> GetReference() REQUIRES_SHARED(Locks::mutator_lock_) {
-    const uint32_t next = (is_range ? first_src_reg_ + arg_index_ : arg_[arg_index_]);
-    ++arg_index_;
-
-    return shadow_frame_.GetVRegReference(next);
+    return shadow_frame_.GetVRegReference(Next());
   }
 
  private:
-  const size_t first_src_reg_;
-  const uint32_t (&arg_)[Instruction::kMaxVarArgRegs];
+  uint32_t Next() {
+    const uint32_t next = operands_->GetOperand(operand_index_);
+    operand_index_ += 1;
+    return next;
+  }
+  uint32_t NextLong() {
+    const uint32_t next = operands_->GetOperand(operand_index_);
+    operand_index_ += 2;
+    return next;
+  }
+
+  const InstructionOperands* const operands_;
+  size_t operand_index_;  // the next register operand to read from frame
   const ShadowFrame& shadow_frame_;
-  size_t arg_index_;
 };
 
 // A convenience class that allows values to be written to a given shadow frame,
@@ -201,23 +191,19 @@
   size_t arg_index_;
 };
 
-template <bool is_range>
 bool MethodHandleInvoke(Thread* self,
                         ShadowFrame& shadow_frame,
                         Handle<mirror::MethodHandle> method_handle,
                         Handle<mirror::MethodType> callsite_type,
-                        const uint32_t (&args)[Instruction::kMaxVarArgRegs],
-                        uint32_t first_arg,
+                        const InstructionOperands* const args,
                         JValue* result)
     REQUIRES_SHARED(Locks::mutator_lock_);
 
-template <bool is_range>
 bool MethodHandleInvokeExact(Thread* self,
                              ShadowFrame& shadow_frame,
                              Handle<mirror::MethodHandle> method_handle,
                              Handle<mirror::MethodType> callsite_type,
-                             const uint32_t (&args)[Instruction::kMaxVarArgRegs],
-                             uint32_t first_arg,
+                             const InstructionOperands* const args,
                              JValue* result)
     REQUIRES_SHARED(Locks::mutator_lock_);