Finish the OutOfMemoryError implementation.
This copes with the double-OOME case.
Also check that I don't leave local references in a newly-attached thread's
local reference table, and fix the leaks this discovered.
Also fix the code that implements fillInNativeStackTrace to cope with the
situation where we're not able to allocate (because we're throwing
OutOfMemoryError and there's not enough space left for our arrays).
Also fix the order of checking for a pending exception and popping the
local references in the JNI native method invocation stub. (This fixes
the warnings we'd been seeing from the IndirectReferenceTable in test 064.)
Also improve some -Xcheck:jni output.
This fixes test 061.
Change-Id: Icc04a2c06339bd28d6772190350a86abfc5734b8
diff --git a/src/jni_compiler.cc b/src/jni_compiler.cc
index ffcbc11..127b53d 100644
--- a/src/jni_compiler.cc
+++ b/src/jni_compiler.cc
@@ -368,10 +368,7 @@
jni_conv->ReturnRegister(), return_save_location,
jni_conv->SizeOfReturnValue());
- // 13. Check for pending exception and forward if there
- __ ExceptionPoll(jni_conv->InterproceduralScratchRegister());
-
- // 14. Place result in correct register possibly loading from indirect
+ // 13. Place result in correct register possibly loading from indirect
// reference table
if (jni_conv->IsReturnAReference()) {
__ IncreaseFrameSize(out_arg_size);
@@ -401,7 +398,7 @@
}
__ Move(mr_conv->ReturnRegister(), jni_conv->ReturnRegister());
- // 15. Restore segment state and remove SIRT from thread
+ // 14. Restore segment state and remove SIRT from thread
{
ManagedRegister jni_env = jni_conv->InterproceduralScratchRegister();
__ LoadRawPtrFromThread(jni_env, Thread::JniEnvOffset());
@@ -417,10 +414,15 @@
__ CopyRawPtrToThread(Thread::TopSirtOffset(), jni_conv->SirtLinkOffset(),
jni_conv->InterproceduralScratchRegister());
+ // 15. Check for pending exception and forward if there
+ __ ExceptionPoll(jni_conv->InterproceduralScratchRegister());
+
// 16. Remove activation
if (native_method->IsSynchronized()) {
__ RemoveFrame(frame_size, callee_save_regs);
} else {
+ // no need to restore callee save registers because we didn't
+ // clobber them while locking the monitor.
__ RemoveFrame(frame_size, std::vector<ManagedRegister>());
}