summaryrefslogtreecommitdiffstats
path: root/src/calling_convention.h
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2011-08-14 16:03:46 -0700
committerIan Rogers <irogers@google.com>2011-08-15 18:12:54 -0700
commit0d666d8769714dcbc2acc4dd5b06f0deffa6e0a1 (patch)
tree18952f6a1ec70d26c4bcea809d093c027115776e /src/calling_convention.h
parent4e777d4e005375a5a41c4ec3c55783c09565df0d (diff)
downloadart-0d666d8769714dcbc2acc4dd5b06f0deffa6e0a1.zip
art-0d666d8769714dcbc2acc4dd5b06f0deffa6e0a1.tar.gz
art-0d666d8769714dcbc2acc4dd5b06f0deffa6e0a1.tar.bz2
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
Diffstat (limited to 'src/calling_convention.h')
-rw-r--r--src/calling_convention.h23
1 files changed, 20 insertions, 3 deletions
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 @@ class ManagedRuntimeCallingConvention : public CallingConvention {
// 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 ManagedRuntimeCallingConvention : public CallingConvention {
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 @@ class JniCallingConvention : public CallingConvention {
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 @@ class JniCallingConvention : public CallingConvention {
// Position of stack handle block and interior fields
FrameOffset ShbOffset() {
return FrameOffset(displacement_.Int32Value() +
+ SpillAreaSize() +
kPointerSize); // above Method*
}
FrameOffset ShbNumRefsOffset() {
@@ -153,6 +164,12 @@ class JniCallingConvention : public CallingConvention {
// 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);
};