Fix JNI compiler for synchronized methods.

Calls to the monitor enter/exit routines were passing the JNI env with
the iterator in the wrong position. Reset the iterator to make sure it
is in the correct position for the monitor enter/exit call.

Also fix clobbering of arguments in registers when calling monitor enter
for synchronized methods on ARM.

Also some tidying of code/comments.

Change-Id: I5bf1dd7e65d925e768411cb5865919ee5f54edbf
diff --git a/src/calling_convention.h b/src/calling_convention.h
index adcafca..7bfc28e 100644
--- a/src/calling_convention.h
+++ b/src/calling_convention.h
@@ -3,6 +3,7 @@
 #ifndef ART_SRC_CALLING_CONVENTION_H_
 #define ART_SRC_CALLING_CONVENTION_H_
 
+#include <vector>
 #include "managed_register.h"
 #include "object.h"
 #include "thread.h"
@@ -84,12 +85,12 @@
 
 // Abstraction for JNI calling conventions
 // | incoming stack args    | <-- Prior SP
-// | { Spilled registers    |
-// |   & return address }   |
+// | { Return address }     |     (x86)
 // | { Return value spill } |     (live on return slow paths)
 // | { Stack Handle Block   |
 // |   ...                  |
 // |   num. refs./link }    |     (here to prior SP is frame size)
+// | { Spill area }         |     (ARM)
 // | Method*                | <-- Anchor SP written to thread
 // | { Outgoing stack args  |
 // |   ... }                | <-- SP at point of call
@@ -97,7 +98,8 @@
 class JniCallingConvention : public CallingConvention {
  public:
   explicit JniCallingConvention(Method* native_method) :
-                      CallingConvention(native_method) {}
+                      CallingConvention(native_method),
+                      spill_regs_(ComputeRegsToSpillPreCall()) {}
 
   // Size of frame excluding space for outgoing args (its assumed Method* is
   // always at the bottom of a frame, but this doesn't work for outgoing
@@ -107,10 +109,18 @@
   size_t OutArgSize();
   // Number of handles in stack handle block
   size_t HandleCount();
+  // Size of area used to hold spilled registers
+  size_t SpillAreaSize();
   // Location where the return value of a call can be squirreled if another
   // call is made following the native call
   FrameOffset ReturnValueSaveLocation();
 
+  // Registers that must be spilled (due to clobbering) before the call into
+  // the native routine
+  const std::vector<ManagedRegister>& RegsToSpillPreCall() {
+    return *spill_regs_.get();
+  }
+
   // Returns true if the register will be clobbered by an outgoing
   // argument value.
   bool IsOutArgRegister(ManagedRegister reg);
@@ -131,6 +141,7 @@
   // Position of stack handle block and interior fields
   FrameOffset ShbOffset() {
     return FrameOffset(displacement_.Int32Value() +
+                       SpillAreaSize() +
                        kPointerSize);  // above Method*
   }
   FrameOffset ShbNumRefsOffset() {
@@ -153,6 +164,12 @@
   // located
   size_t NumberOfOutgoingStackArgs();
 
+  // Compute registers for RegsToSpillPreCall
+  std::vector<ManagedRegister>* ComputeRegsToSpillPreCall();
+
+  // Extra registers to spill before the call into native
+  const scoped_ptr<std::vector<ManagedRegister> > spill_regs_;
+
   static size_t NumberOfExtraArgumentsForJni(const Method* method);
   DISALLOW_COPY_AND_ASSIGN(JniCallingConvention);
 };