summaryrefslogtreecommitdiff
path: root/compiler/jni/quick/calling_convention.h
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/jni/quick/calling_convention.h')
-rw-r--r--compiler/jni/quick/calling_convention.h53
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() {}