blob: 0cd653beda1885f269afae025d8d5b6aed4ede3f [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());
Ian Rogers7a99c112011-09-07 12:48:27 -070027 if (IsCurrentArgExplicit() && // don't query parameter type of implicit args
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
Ian Rogers7a99c112011-09-07 12:48:27 -070039bool ManagedRuntimeCallingConvention::IsCurrentArgExplicit() {
40 // Static methods have no implicit arguments, others implicitly pass this
41 return GetMethod()->IsStatic() || (itr_args_ != 0);
42}
43
44bool ManagedRuntimeCallingConvention::IsCurrentArgPossiblyNull() {
45 return IsCurrentArgExplicit(); // any user parameter may be null
Ian Rogersb033c752011-07-20 12:22:35 -070046}
47
Ian Rogersdf20fe02011-07-20 20:34:16 -070048size_t ManagedRuntimeCallingConvention::CurrentParamSize() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070049 return GetMethod()->ParamSize(itr_args_);
Ian Rogersb033c752011-07-20 12:22:35 -070050}
51
52bool ManagedRuntimeCallingConvention::IsCurrentParamAReference() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070053 return GetMethod()->IsParamAReference(itr_args_);
Ian Rogersb033c752011-07-20 12:22:35 -070054}
55
Ian Rogersdf20fe02011-07-20 20:34:16 -070056// JNI calling convention
Ian Rogersb033c752011-07-20 12:22:35 -070057
Ian Rogers408f79a2011-08-23 18:22:33 -070058size_t JniCallingConvention::ReferenceCount() {
Ian Rogersb033c752011-07-20 12:22:35 -070059 const Method* method = GetMethod();
60 return method->NumReferenceArgs() + (method->IsStatic() ? 1 : 0);
61}
62
Ian Rogersdf20fe02011-07-20 20:34:16 -070063FrameOffset JniCallingConvention::ReturnValueSaveLocation() {
Ian Rogers408f79a2011-08-23 18:22:33 -070064 size_t start_of_sirt = SirtLinkOffset().Int32Value() + kPointerSize;
65 size_t references_size = kPointerSize * ReferenceCount(); // size excluding header
66 return FrameOffset(start_of_sirt + references_size);
Ian Rogersdf20fe02011-07-20 20:34:16 -070067}
68
Ian Rogersb033c752011-07-20 12:22:35 -070069bool JniCallingConvention::HasNext() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070070 if (itr_args_ <= kObjectOrClass) {
Ian Rogersb033c752011-07-20 12:22:35 -070071 return true;
72 } else {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070073 unsigned int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(GetMethod());
Ian Rogersb033c752011-07-20 12:22:35 -070074 return arg_pos < GetMethod()->NumArgs();
75 }
76}
77
78void JniCallingConvention::Next() {
79 CHECK(HasNext());
Shih-wei Liao5381cf92011-07-27 00:28:04 -070080 if (itr_args_ > kObjectOrClass) {
81 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(GetMethod());
Ian Rogersb033c752011-07-20 12:22:35 -070082 if (GetMethod()->IsParamALongOrDouble(arg_pos)) {
83 itr_longs_and_doubles_++;
Shih-wei Liao5381cf92011-07-27 00:28:04 -070084 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -070085 }
86 }
Shih-wei Liao668512a2011-09-01 14:18:34 -070087 if (IsCurrentParamAReference()) {
88 itr_refs_++;
89 }
Shih-wei Liao5381cf92011-07-27 00:28:04 -070090 itr_args_++;
91 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -070092}
93
94bool JniCallingConvention::IsCurrentParamAReference() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070095 switch (itr_args_) {
Ian Rogersb033c752011-07-20 12:22:35 -070096 case kJniEnv:
97 return false; // JNIEnv*
98 case kObjectOrClass:
99 return true; // jobject or jclass
100 default: {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700101 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(GetMethod());
Ian Rogersb033c752011-07-20 12:22:35 -0700102 return GetMethod()->IsParamAReference(arg_pos);
103 }
104 }
105}
106
Ian Rogers408f79a2011-08-23 18:22:33 -0700107// Return position of SIRT entry holding reference at the current iterator
108// position
109FrameOffset JniCallingConvention::CurrentParamSirtEntryOffset() {
Ian Rogersb033c752011-07-20 12:22:35 -0700110 CHECK(IsCurrentParamAReference());
Ian Rogers408f79a2011-08-23 18:22:33 -0700111 CHECK_GT(SirtLinkOffset(), SirtNumRefsOffset());
112 // Address of 1st SIRT entry
113 int result = SirtLinkOffset().Int32Value() + kPointerSize;
Shih-wei Liao668512a2011-09-01 14:18:34 -0700114 result += itr_refs_ * kPointerSize;
Ian Rogers408f79a2011-08-23 18:22:33 -0700115 CHECK_GT(result, SirtLinkOffset().Int32Value());
Ian Rogersb033c752011-07-20 12:22:35 -0700116 return FrameOffset(result);
117}
118
Ian Rogersdf20fe02011-07-20 20:34:16 -0700119size_t JniCallingConvention::CurrentParamSize() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700120 if (itr_args_ <= kObjectOrClass) {
Ian Rogersb033c752011-07-20 12:22:35 -0700121 return kPointerSize; // JNIEnv or jobject/jclass
122 } else {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700123 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(GetMethod());
Ian Rogersdf20fe02011-07-20 20:34:16 -0700124 return GetMethod()->ParamSize(arg_pos);
Ian Rogersb033c752011-07-20 12:22:35 -0700125 }
126}
127
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700128size_t JniCallingConvention::NumberOfExtraArgumentsForJni(
129 const Method* method) {
130 // The first argument is the JNIEnv*.
131 // Static methods have an extra argument which is the jclass.
132 return (method->IsStatic() ? 2 : 1);
133}
134
Ian Rogersb033c752011-07-20 12:22:35 -0700135} // namespace art