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/jni_compiler.cc b/src/jni_compiler.cc
index 07aeec3..dd7d5e5 100644
--- a/src/jni_compiler.cc
+++ b/src/jni_compiler.cc
@@ -28,7 +28,8 @@
// 1. Build the frame
const size_t frame_size(jni_conv.FrameSize());
- jni_asm->BuildFrame(frame_size, mr_conv.MethodRegister());
+ const std::vector<ManagedRegister>& spill_regs = jni_conv.RegsToSpillPreCall();
+ jni_asm->BuildFrame(frame_size, mr_conv.MethodRegister(), spill_regs);
// 2. Save callee save registers that aren't callee save in the native code
// TODO: implement computing the difference of the callee saves
@@ -124,6 +125,7 @@
CopyParameter(jni_asm, &mr_conv, &jni_conv, frame_size, out_arg_size);
}
// Generate JNIEnv* in place and leave a copy in jni_env_register
+ jni_conv.ResetIterator(FrameOffset(out_arg_size));
ManagedRegister jni_env_register =
jni_conv.InterproceduralScratchRegister();
if (jni_conv.IsCurrentParamInRegister()) {
@@ -138,6 +140,7 @@
static Offset monitor_enter(OFFSETOF_MEMBER(JNIEnvExt, MonitorEnterHelper));
jni_asm->Call(jni_env_register, monitor_enter,
jni_conv.InterproceduralScratchRegister());
+ jni_asm->FillFromSpillArea(spill_regs, out_arg_size);
jni_asm->ExceptionPoll(jni_conv.InterproceduralScratchRegister());
}
@@ -224,6 +227,7 @@
CopyParameter(jni_asm, &mr_conv, &jni_conv, frame_size, out_arg_size);
}
// Generate JNIEnv* in place and leave a copy in jni_env_register
+ jni_conv.ResetIterator(FrameOffset(out_arg_size));
ManagedRegister jni_env_register =
jni_conv.InterproceduralScratchRegister();
if (jni_conv.IsCurrentParamInRegister()) {
@@ -238,7 +242,6 @@
static Offset monitor_exit(OFFSETOF_MEMBER(JNIEnvExt, MonitorExitHelper));
jni_asm->Call(jni_env_register, monitor_exit,
jni_conv.InterproceduralScratchRegister());
- jni_asm->ExceptionPoll(jni_conv.InterproceduralScratchRegister());
// Reload return value
jni_asm->Load(jni_conv.ReturnRegister(), return_save_location,
jni_conv.SizeOfReturnValue());
@@ -277,7 +280,7 @@
jni_conv.InterproceduralScratchRegister());
// 17. Remove activation
- jni_asm->RemoveFrame(frame_size);
+ jni_asm->RemoveFrame(frame_size, spill_regs);
// 18. Finalize code generation
jni_asm->EmitSlowPaths();