diff options
Diffstat (limited to 'compiler/jni/quick/calling_convention.h')
| -rw-r--r-- | compiler/jni/quick/calling_convention.h | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/compiler/jni/quick/calling_convention.h b/compiler/jni/quick/calling_convention.h index f2b7fd9a4a..fe3d1cd551 100644 --- a/compiler/jni/quick/calling_convention.h +++ b/compiler/jni/quick/calling_convention.h @@ -60,23 +60,35 @@ class CallingConvention { itr_args_ = 0; itr_refs_ = 0; itr_longs_and_doubles_ = 0; + itr_float_and_doubles_ = 0; } virtual ~CallingConvention() {} protected: CallingConvention(bool is_static, bool is_synchronized, const char* shorty) - : displacement_(0), is_static_(is_static), is_synchronized_(is_synchronized), + : displacement_(0), kSirtPointerSize(sizeof(StackReference<mirror::Object>)), is_static_(is_static), is_synchronized_(is_synchronized), shorty_(shorty) { num_args_ = (is_static ? 0 : 1) + strlen(shorty) - 1; num_ref_args_ = is_static ? 0 : 1; // The implicit this pointer. + num_float_or_double_args_ = 0; num_long_or_double_args_ = 0; for (size_t i = 1; i < strlen(shorty); i++) { char ch = shorty_[i]; - if (ch == 'L') { + switch (ch) { + case 'L': num_ref_args_++; - } else if ((ch == 'D') || (ch == 'J')) { + break; + case 'J': num_long_or_double_args_++; + break; + case 'D': + num_long_or_double_args_++; + num_float_or_double_args_++; + break; + case 'F': + num_float_or_double_args_++; + break; } } } @@ -97,6 +109,16 @@ class CallingConvention { char ch = shorty_[param]; return (ch == 'J' || ch == 'D'); } + bool IsParamAFloatOrDouble(unsigned int param) const { + DCHECK_LT(param, NumArgs()); + if (IsStatic()) { + param++; // 0th argument must skip return value at start of the shorty + } else if (param == 0) { + return false; // this argument + } + char ch = shorty_[param]; + return (ch == 'F' || ch == 'D'); + } bool IsParamAReference(unsigned int param) const { DCHECK_LT(param, NumArgs()); if (IsStatic()) { @@ -112,6 +134,9 @@ class CallingConvention { size_t NumLongOrDoubleArgs() const { return num_long_or_double_args_; } + size_t NumFloatOrDoubleArgs() const { + return num_float_or_double_args_; + } size_t NumReferenceArgs() const { return num_ref_args_; } @@ -141,8 +166,11 @@ class CallingConvention { unsigned int itr_args_; // Number of longs and doubles seen along argument list unsigned int itr_longs_and_doubles_; + // Number of float and doubles seen along argument list + unsigned int itr_float_and_doubles_; // Space for frames below this on the stack FrameOffset displacement_; + size_t kSirtPointerSize; private: const bool is_static_; @@ -150,6 +178,7 @@ class CallingConvention { std::string shorty_; size_t num_args_; size_t num_ref_args_; + size_t num_float_or_double_args_; size_t num_long_or_double_args_; }; @@ -174,6 +203,7 @@ class ManagedRuntimeCallingConvention : public CallingConvention { bool HasNext(); void Next(); bool IsCurrentParamAReference(); + bool IsCurrentParamAFloatOrDouble(); bool IsCurrentArgExplicit(); // ie a non-implict argument such as this bool IsCurrentArgPossiblyNull(); size_t CurrentParamSize(); @@ -185,7 +215,7 @@ class ManagedRuntimeCallingConvention : public CallingConvention { virtual ~ManagedRuntimeCallingConvention() {} // Registers to spill to caller's out registers on entry. - virtual const std::vector<ManagedRegister>& EntrySpills() = 0; + virtual const ManagedRegisterEntrySpills& EntrySpills() = 0; protected: ManagedRuntimeCallingConvention(bool is_static, bool is_synchronized, const char* shorty) @@ -241,6 +271,7 @@ class JniCallingConvention : public CallingConvention { bool HasNext(); virtual void Next(); bool IsCurrentParamAReference(); + bool IsCurrentParamAFloatOrDouble(); size_t CurrentParamSize(); virtual bool IsCurrentParamInRegister() = 0; virtual bool IsCurrentParamOnStack() = 0; @@ -255,13 +286,21 @@ class JniCallingConvention : public CallingConvention { return FrameOffset(displacement_.Int32Value() + kPointerSize); // above Method* } + + FrameOffset SirtLinkOffset() const { + return FrameOffset(SirtOffset().Int32Value() + + StackIndirectReferenceTable::LinkOffset()); + } + FrameOffset SirtNumRefsOffset() const { return FrameOffset(SirtOffset().Int32Value() + StackIndirectReferenceTable::NumberOfReferencesOffset()); } - FrameOffset SirtLinkOffset() const { - return FrameOffset(SirtOffset().Int32Value() + - StackIndirectReferenceTable::LinkOffset()); + + FrameOffset SirtReferencesOffset() const { + // The StackIndirectReferenceTable::number_of_references_ type is uint32_t + return FrameOffset(SirtNumRefsOffset().Int32Value() + + sizeof(uint32_t)); } virtual ~JniCallingConvention() {} |