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);