blob: 83f7a0071210062dfcffb7f2b982a086d4bde2d3 [file] [log] [blame]
Ian Rogersb033c752011-07-20 12:22:35 -07001// Copyright 2011 Google Inc. All Rights Reserved.
Ian Rogersb033c752011-07-20 12:22:35 -07002
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07003#include "calling_convention.h"
4#include "logging.h"
5#include "utils.h"
Ian Rogersb033c752011-07-20 12:22:35 -07006
7namespace art {
8
Carl Shapiroe2d373e2011-07-25 15:20:06 -07009// Offset of Method within the frame
10FrameOffset CallingConvention::MethodStackOffset() {
11 return displacement_;
12}
13
Ian Rogersdf20fe02011-07-20 20:34:16 -070014// Managed runtime calling convention
15
Ian Rogersb033c752011-07-20 12:22:35 -070016size_t ManagedRuntimeCallingConvention::FrameSize() {
Elliott Hughes53b61312011-08-12 18:28:20 -070017 UNIMPLEMENTED(FATAL);
Ian Rogersb033c752011-07-20 12:22:35 -070018 return 0;
19}
20
21bool ManagedRuntimeCallingConvention::HasNext() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070022 return itr_args_ < GetMethod()->NumArgs();
Ian Rogersb033c752011-07-20 12:22:35 -070023}
24
25void ManagedRuntimeCallingConvention::Next() {
26 CHECK(HasNext());
Brian Carlstroma663ea52011-08-19 23:33:41 -070027 if (IsCurrentUserArg() &&
Shih-wei Liao5381cf92011-07-27 00:28:04 -070028 GetMethod()->IsParamALongOrDouble(itr_args_)) {
Ian Rogersb033c752011-07-20 12:22:35 -070029 itr_longs_and_doubles_++;
Shih-wei Liao5381cf92011-07-27 00:28:04 -070030 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -070031 }
Shih-wei Liao668512a2011-09-01 14:18:34 -070032 if (IsCurrentParamAReference()) {
33 itr_refs_++;
34 }
Shih-wei Liao5381cf92011-07-27 00:28:04 -070035 itr_args_++;
36 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -070037}
38
Shih-wei Liao5381cf92011-07-27 00:28:04 -070039bool ManagedRuntimeCallingConvention::IsCurrentUserArg() {
40 if (GetMethod()->IsStatic()) {
41 return true;
42 }
43 // For a virtual method, "this" should never be NULL.
44 return (itr_args_ != 0);
Ian Rogersb033c752011-07-20 12:22:35 -070045}
46
Ian Rogersdf20fe02011-07-20 20:34:16 -070047size_t ManagedRuntimeCallingConvention::CurrentParamSize() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070048 return GetMethod()->ParamSize(itr_args_);
Ian Rogersb033c752011-07-20 12:22:35 -070049}
50
51bool ManagedRuntimeCallingConvention::IsCurrentParamAReference() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070052 return GetMethod()->IsParamAReference(itr_args_);
Ian Rogersb033c752011-07-20 12:22:35 -070053}
54
Ian Rogersdf20fe02011-07-20 20:34:16 -070055// JNI calling convention
Ian Rogersb033c752011-07-20 12:22:35 -070056
Ian Rogersb033c752011-07-20 12:22:35 -070057size_t JniCallingConvention::OutArgSize() {
Ian Rogers408f79a2011-08-23 18:22:33 -070058 return RoundUp(NumberOfOutgoingStackArgs() * kPointerSize, kStackAlignment);
Ian Rogersb033c752011-07-20 12:22:35 -070059}
60
Ian Rogers408f79a2011-08-23 18:22:33 -070061size_t JniCallingConvention::ReferenceCount() {
Ian Rogersb033c752011-07-20 12:22:35 -070062 const Method* method = GetMethod();
63 return method->NumReferenceArgs() + (method->IsStatic() ? 1 : 0);
64}
65
Ian Rogersdf20fe02011-07-20 20:34:16 -070066FrameOffset JniCallingConvention::ReturnValueSaveLocation() {
Ian Rogers408f79a2011-08-23 18:22:33 -070067 size_t start_of_sirt = SirtLinkOffset().Int32Value() + kPointerSize;
68 size_t references_size = kPointerSize * ReferenceCount(); // size excluding header
69 return FrameOffset(start_of_sirt + references_size);
Ian Rogersdf20fe02011-07-20 20:34:16 -070070}
71
Ian Rogersb033c752011-07-20 12:22:35 -070072bool JniCallingConvention::HasNext() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070073 if (itr_args_ <= kObjectOrClass) {
Ian Rogersb033c752011-07-20 12:22:35 -070074 return true;
75 } else {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070076 unsigned int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(GetMethod());
Ian Rogersb033c752011-07-20 12:22:35 -070077 return arg_pos < GetMethod()->NumArgs();
78 }
79}
80
81void JniCallingConvention::Next() {
82 CHECK(HasNext());
Shih-wei Liao5381cf92011-07-27 00:28:04 -070083 if (itr_args_ > kObjectOrClass) {
84 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(GetMethod());
Ian Rogersb033c752011-07-20 12:22:35 -070085 if (GetMethod()->IsParamALongOrDouble(arg_pos)) {
86 itr_longs_and_doubles_++;
Shih-wei Liao5381cf92011-07-27 00:28:04 -070087 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -070088 }
89 }
Shih-wei Liao668512a2011-09-01 14:18:34 -070090 if (IsCurrentParamAReference()) {
91 itr_refs_++;
92 }
Shih-wei Liao5381cf92011-07-27 00:28:04 -070093 itr_args_++;
94 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -070095}
96
97bool JniCallingConvention::IsCurrentParamAReference() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070098 switch (itr_args_) {
Ian Rogersb033c752011-07-20 12:22:35 -070099 case kJniEnv:
100 return false; // JNIEnv*
101 case kObjectOrClass:
102 return true; // jobject or jclass
103 default: {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700104 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(GetMethod());
Ian Rogersb033c752011-07-20 12:22:35 -0700105 return GetMethod()->IsParamAReference(arg_pos);
106 }
107 }
108}
109
Ian Rogers408f79a2011-08-23 18:22:33 -0700110// Return position of SIRT entry holding reference at the current iterator
111// position
112FrameOffset JniCallingConvention::CurrentParamSirtEntryOffset() {
Ian Rogersb033c752011-07-20 12:22:35 -0700113 CHECK(IsCurrentParamAReference());
Ian Rogers408f79a2011-08-23 18:22:33 -0700114 CHECK_GT(SirtLinkOffset(), SirtNumRefsOffset());
115 // Address of 1st SIRT entry
116 int result = SirtLinkOffset().Int32Value() + kPointerSize;
Shih-wei Liao668512a2011-09-01 14:18:34 -0700117 result += itr_refs_ * kPointerSize;
Ian Rogers408f79a2011-08-23 18:22:33 -0700118 CHECK_GT(result, SirtLinkOffset().Int32Value());
Ian Rogersb033c752011-07-20 12:22:35 -0700119 return FrameOffset(result);
120}
121
Ian Rogersdf20fe02011-07-20 20:34:16 -0700122size_t JniCallingConvention::CurrentParamSize() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700123 if (itr_args_ <= kObjectOrClass) {
Ian Rogersb033c752011-07-20 12:22:35 -0700124 return kPointerSize; // JNIEnv or jobject/jclass
125 } else {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700126 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(GetMethod());
Ian Rogersdf20fe02011-07-20 20:34:16 -0700127 return GetMethod()->ParamSize(arg_pos);
Ian Rogersb033c752011-07-20 12:22:35 -0700128 }
129}
130
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700131size_t JniCallingConvention::NumberOfExtraArgumentsForJni(
132 const Method* method) {
133 // The first argument is the JNIEnv*.
134 // Static methods have an extra argument which is the jclass.
135 return (method->IsStatic() ? 2 : 1);
136}
137
Ian Rogersb033c752011-07-20 12:22:35 -0700138} // namespace art