blob: 5256ee1fabc0ae45240ff9e2caff0dd368497a91 [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"
Ian Rogers2c8f6532011-09-02 17:16:34 -07004
5#include "calling_convention_arm.h"
6#include "calling_convention_x86.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07007#include "logging.h"
8#include "utils.h"
Ian Rogersb033c752011-07-20 12:22:35 -07009
10namespace art {
11
Carl Shapiroe2d373e2011-07-25 15:20:06 -070012// Offset of Method within the frame
13FrameOffset CallingConvention::MethodStackOffset() {
14 return displacement_;
15}
16
Ian Rogersdf20fe02011-07-20 20:34:16 -070017// Managed runtime calling convention
18
Ian Rogers2c8f6532011-09-02 17:16:34 -070019ManagedRuntimeCallingConvention* ManagedRuntimeCallingConvention::Create(
Brian Carlstrom3320cf42011-10-04 14:58:28 -070020 const Method* native_method, InstructionSet instruction_set) {
Ian Rogers2c8f6532011-09-02 17:16:34 -070021 if (instruction_set == kX86) {
22 return new x86::X86ManagedRuntimeCallingConvention(native_method);
23 } else {
24 CHECK(instruction_set == kArm || instruction_set == kThumb2);
25 return new arm::ArmManagedRuntimeCallingConvention(native_method);
26 }
27}
28
Ian Rogersb033c752011-07-20 12:22:35 -070029size_t ManagedRuntimeCallingConvention::FrameSize() {
Ian Rogers2c8f6532011-09-02 17:16:34 -070030 return GetMethod()->GetFrameSizeInBytes();
Ian Rogersb033c752011-07-20 12:22:35 -070031}
32
33bool ManagedRuntimeCallingConvention::HasNext() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070034 return itr_args_ < GetMethod()->NumArgs();
Ian Rogersb033c752011-07-20 12:22:35 -070035}
36
37void ManagedRuntimeCallingConvention::Next() {
38 CHECK(HasNext());
Ian Rogers7a99c112011-09-07 12:48:27 -070039 if (IsCurrentArgExplicit() && // don't query parameter type of implicit args
Shih-wei Liao5381cf92011-07-27 00:28:04 -070040 GetMethod()->IsParamALongOrDouble(itr_args_)) {
Ian Rogersb033c752011-07-20 12:22:35 -070041 itr_longs_and_doubles_++;
Shih-wei Liao5381cf92011-07-27 00:28:04 -070042 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -070043 }
Shih-wei Liao668512a2011-09-01 14:18:34 -070044 if (IsCurrentParamAReference()) {
45 itr_refs_++;
46 }
Shih-wei Liao5381cf92011-07-27 00:28:04 -070047 itr_args_++;
48 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -070049}
50
Ian Rogers7a99c112011-09-07 12:48:27 -070051bool ManagedRuntimeCallingConvention::IsCurrentArgExplicit() {
52 // Static methods have no implicit arguments, others implicitly pass this
53 return GetMethod()->IsStatic() || (itr_args_ != 0);
54}
55
56bool ManagedRuntimeCallingConvention::IsCurrentArgPossiblyNull() {
57 return IsCurrentArgExplicit(); // any user parameter may be null
Ian Rogersb033c752011-07-20 12:22:35 -070058}
59
Ian Rogersdf20fe02011-07-20 20:34:16 -070060size_t ManagedRuntimeCallingConvention::CurrentParamSize() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070061 return GetMethod()->ParamSize(itr_args_);
Ian Rogersb033c752011-07-20 12:22:35 -070062}
63
64bool ManagedRuntimeCallingConvention::IsCurrentParamAReference() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070065 return GetMethod()->IsParamAReference(itr_args_);
Ian Rogersb033c752011-07-20 12:22:35 -070066}
67
Ian Rogersdf20fe02011-07-20 20:34:16 -070068// JNI calling convention
Ian Rogersb033c752011-07-20 12:22:35 -070069
Brian Carlstrom3320cf42011-10-04 14:58:28 -070070JniCallingConvention* JniCallingConvention::Create(const Method* native_method,
Ian Rogers2c8f6532011-09-02 17:16:34 -070071 InstructionSet instruction_set) {
72 if (instruction_set == kX86) {
73 return new x86::X86JniCallingConvention(native_method);
74 } else {
75 CHECK(instruction_set == kArm || instruction_set == kThumb2);
76 return new arm::ArmJniCallingConvention(native_method);
77 }
78}
79
Ian Rogersdc51b792011-09-22 20:41:37 -070080size_t JniCallingConvention::ReferenceCount() const {
Ian Rogersb033c752011-07-20 12:22:35 -070081 const Method* method = GetMethod();
82 return method->NumReferenceArgs() + (method->IsStatic() ? 1 : 0);
83}
84
Ian Rogers5a7a74a2011-09-26 16:32:29 -070085FrameOffset JniCallingConvention::SavedLocalReferenceCookieOffset() const {
Ian Rogers408f79a2011-08-23 18:22:33 -070086 size_t start_of_sirt = SirtLinkOffset().Int32Value() + kPointerSize;
87 size_t references_size = kPointerSize * ReferenceCount(); // size excluding header
88 return FrameOffset(start_of_sirt + references_size);
Ian Rogersdf20fe02011-07-20 20:34:16 -070089}
90
Ian Rogersdc51b792011-09-22 20:41:37 -070091FrameOffset JniCallingConvention::ReturnValueSaveLocation() const {
92 // Segment state is 4 bytes long
Ian Rogers5a7a74a2011-09-26 16:32:29 -070093 return FrameOffset(SavedLocalReferenceCookieOffset().Int32Value() + 4);
Ian Rogersdc51b792011-09-22 20:41:37 -070094}
95
Ian Rogersb033c752011-07-20 12:22:35 -070096bool JniCallingConvention::HasNext() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070097 if (itr_args_ <= kObjectOrClass) {
Ian Rogersb033c752011-07-20 12:22:35 -070098 return true;
99 } else {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700100 unsigned int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(GetMethod());
Ian Rogersb033c752011-07-20 12:22:35 -0700101 return arg_pos < GetMethod()->NumArgs();
102 }
103}
104
105void JniCallingConvention::Next() {
106 CHECK(HasNext());
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700107 if (itr_args_ > kObjectOrClass) {
108 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(GetMethod());
Ian Rogersb033c752011-07-20 12:22:35 -0700109 if (GetMethod()->IsParamALongOrDouble(arg_pos)) {
110 itr_longs_and_doubles_++;
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700111 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -0700112 }
113 }
Shih-wei Liao668512a2011-09-01 14:18:34 -0700114 if (IsCurrentParamAReference()) {
115 itr_refs_++;
116 }
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700117 itr_args_++;
118 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -0700119}
120
121bool JniCallingConvention::IsCurrentParamAReference() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700122 switch (itr_args_) {
Ian Rogersb033c752011-07-20 12:22:35 -0700123 case kJniEnv:
124 return false; // JNIEnv*
125 case kObjectOrClass:
126 return true; // jobject or jclass
127 default: {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700128 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(GetMethod());
Ian Rogersb033c752011-07-20 12:22:35 -0700129 return GetMethod()->IsParamAReference(arg_pos);
130 }
131 }
132}
133
Ian Rogers408f79a2011-08-23 18:22:33 -0700134// Return position of SIRT entry holding reference at the current iterator
135// position
136FrameOffset JniCallingConvention::CurrentParamSirtEntryOffset() {
Ian Rogersb033c752011-07-20 12:22:35 -0700137 CHECK(IsCurrentParamAReference());
Ian Rogers408f79a2011-08-23 18:22:33 -0700138 CHECK_GT(SirtLinkOffset(), SirtNumRefsOffset());
139 // Address of 1st SIRT entry
140 int result = SirtLinkOffset().Int32Value() + kPointerSize;
Shih-wei Liao668512a2011-09-01 14:18:34 -0700141 result += itr_refs_ * kPointerSize;
Ian Rogers408f79a2011-08-23 18:22:33 -0700142 CHECK_GT(result, SirtLinkOffset().Int32Value());
Ian Rogersb033c752011-07-20 12:22:35 -0700143 return FrameOffset(result);
144}
145
Ian Rogersdf20fe02011-07-20 20:34:16 -0700146size_t JniCallingConvention::CurrentParamSize() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700147 if (itr_args_ <= kObjectOrClass) {
Ian Rogersb033c752011-07-20 12:22:35 -0700148 return kPointerSize; // JNIEnv or jobject/jclass
149 } else {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700150 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(GetMethod());
Ian Rogersdf20fe02011-07-20 20:34:16 -0700151 return GetMethod()->ParamSize(arg_pos);
Ian Rogersb033c752011-07-20 12:22:35 -0700152 }
153}
154
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700155size_t JniCallingConvention::NumberOfExtraArgumentsForJni(const Method* method) {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700156 // The first argument is the JNIEnv*.
157 // Static methods have an extra argument which is the jclass.
Ian Rogers2c8f6532011-09-02 17:16:34 -0700158 return method->IsStatic() ? 2 : 1;
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700159}
160
Ian Rogersb033c752011-07-20 12:22:35 -0700161} // namespace art