diff options
author | Ian Rogers <irogers@google.com> | 2011-08-14 16:03:46 -0700 |
---|---|---|
committer | Ian Rogers <irogers@google.com> | 2011-08-15 18:12:54 -0700 |
commit | 0d666d8769714dcbc2acc4dd5b06f0deffa6e0a1 (patch) | |
tree | 18952f6a1ec70d26c4bcea809d093c027115776e /src/calling_convention.h | |
parent | 4e777d4e005375a5a41c4ec3c55783c09565df0d (diff) | |
download | art-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.h | 23 |
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); }; |