Fix JNI compiler frame size adjustments.

Bug: 16321952
Change-Id: I6f84a59c679e335e02a8e70944a5d0bc8d73f90b
diff --git a/compiler/jni/quick/jni_compiler.cc b/compiler/jni/quick/jni_compiler.cc
index dec84f1..c38cfaf 100644
--- a/compiler/jni/quick/jni_compiler.cc
+++ b/compiler/jni/quick/jni_compiler.cc
@@ -183,9 +183,8 @@
 
   // 5. Move frame down to allow space for out going args.
   const size_t main_out_arg_size = main_jni_conv->OutArgSize();
-  const size_t end_out_arg_size = end_jni_conv->OutArgSize();
-  const size_t max_out_arg_size = std::max(main_out_arg_size, end_out_arg_size);
-  __ IncreaseFrameSize(max_out_arg_size);
+  size_t current_out_arg_size = main_out_arg_size;
+  __ IncreaseFrameSize(main_out_arg_size);
 
   // 6. Call into appropriate JniMethodStart passing Thread* so that transition out of Runnable
   //    can occur. The result is the saved JNI local state that is restored by the exit call. We
@@ -244,7 +243,7 @@
   //    NULL (which must be encoded as NULL).
   //    Note: we do this prior to materializing the JNIEnv* and static's jclass to
   //    give as many free registers for the shuffle as possible
-  mr_conv->ResetIterator(FrameOffset(frame_size+main_out_arg_size));
+  mr_conv->ResetIterator(FrameOffset(frame_size + main_out_arg_size));
   uint32_t args_count = 0;
   while (mr_conv->HasNext()) {
     args_count++;
@@ -270,7 +269,7 @@
   }
   if (is_static) {
     // Create argument for Class
-    mr_conv->ResetIterator(FrameOffset(frame_size+main_out_arg_size));
+    mr_conv->ResetIterator(FrameOffset(frame_size + main_out_arg_size));
     main_jni_conv->ResetIterator(FrameOffset(main_out_arg_size));
     main_jni_conv->Next();  // Skip JNIEnv*
     FrameOffset handle_scope_offset = main_jni_conv->CurrentParamHandleScopeEntryOffset();
@@ -333,10 +332,21 @@
       // Ensure doubles are 8-byte aligned for MIPS
       return_save_location = FrameOffset(return_save_location.Uint32Value() + kMipsPointerSize);
     }
-    CHECK_LT(return_save_location.Uint32Value(), frame_size+main_out_arg_size);
+    CHECK_LT(return_save_location.Uint32Value(), frame_size + main_out_arg_size);
     __ Store(return_save_location, main_jni_conv->ReturnRegister(), main_jni_conv->SizeOfReturnValue());
   }
 
+  // Increase frame size for out args if needed by the end_jni_conv.
+  const size_t end_out_arg_size = end_jni_conv->OutArgSize();
+  if (end_out_arg_size > current_out_arg_size) {
+    size_t out_arg_size_diff = end_out_arg_size - current_out_arg_size;
+    current_out_arg_size = end_out_arg_size;
+    __ IncreaseFrameSize(out_arg_size_diff);
+    saved_cookie_offset = FrameOffset(saved_cookie_offset.SizeValue() + out_arg_size_diff);
+    locked_object_handle_scope_offset =
+        FrameOffset(locked_object_handle_scope_offset.SizeValue() + out_arg_size_diff);
+    return_save_location = FrameOffset(return_save_location.SizeValue() + out_arg_size_diff);
+  }
   //     thread.
   end_jni_conv->ResetIterator(FrameOffset(end_out_arg_size));
   ThreadOffset<4> jni_end32(-1);
@@ -403,7 +413,7 @@
   }
 
   // 14. Move frame up now we're done with the out arg space.
-  __ DecreaseFrameSize(max_out_arg_size);
+  __ DecreaseFrameSize(current_out_arg_size);
 
   // 15. Process pending exceptions from JNI call or monitor exit.
   __ ExceptionPoll(main_jni_conv->InterproceduralScratchRegister(), 0);