blob: d14857b4c32bccc3ed3f9f515d21a34e7e7824d2 [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());
Shih-wei Liao5381cf92011-07-27 00:28:04 -070027 if (IsCurrentUserArg() &&
28 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 Liao5381cf92011-07-27 00:28:04 -070032 itr_args_++;
33 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -070034}
35
Shih-wei Liao5381cf92011-07-27 00:28:04 -070036bool ManagedRuntimeCallingConvention::IsCurrentUserArg() {
37 if (GetMethod()->IsStatic()) {
38 return true;
39 }
40 // For a virtual method, "this" should never be NULL.
41 return (itr_args_ != 0);
Ian Rogersb033c752011-07-20 12:22:35 -070042}
43
Ian Rogersdf20fe02011-07-20 20:34:16 -070044size_t ManagedRuntimeCallingConvention::CurrentParamSize() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070045 return GetMethod()->ParamSize(itr_args_);
Ian Rogersb033c752011-07-20 12:22:35 -070046}
47
48bool ManagedRuntimeCallingConvention::IsCurrentParamAReference() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070049 return GetMethod()->IsParamAReference(itr_args_);
Ian Rogersb033c752011-07-20 12:22:35 -070050}
51
Ian Rogersdf20fe02011-07-20 20:34:16 -070052// JNI calling convention
Ian Rogersb033c752011-07-20 12:22:35 -070053
Ian Rogersb033c752011-07-20 12:22:35 -070054size_t JniCallingConvention::OutArgSize() {
55 return RoundUp(NumberOfOutgoingStackArgs() * kPointerSize, 16);
56}
57
58size_t JniCallingConvention::HandleCount() {
59 const Method* method = GetMethod();
60 return method->NumReferenceArgs() + (method->IsStatic() ? 1 : 0);
61}
62
Ian Rogersdf20fe02011-07-20 20:34:16 -070063FrameOffset JniCallingConvention::ReturnValueSaveLocation() {
64 size_t start_of_shb = ShbLinkOffset().Int32Value() + kPointerSize;
65 size_t handle_size = kPointerSize * HandleCount(); // size excluding header
66 return FrameOffset(start_of_shb + handle_size);
67}
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 Liao5381cf92011-07-27 00:28:04 -070087 itr_args_++;
88 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -070089}
90
91bool JniCallingConvention::IsCurrentParamAReference() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070092 switch (itr_args_) {
Ian Rogersb033c752011-07-20 12:22:35 -070093 case kJniEnv:
94 return false; // JNIEnv*
95 case kObjectOrClass:
96 return true; // jobject or jclass
97 default: {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070098 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(GetMethod());
Ian Rogersb033c752011-07-20 12:22:35 -070099 return GetMethod()->IsParamAReference(arg_pos);
100 }
101 }
102}
103
104// Return position of handle holding reference at the current iterator position
105FrameOffset JniCallingConvention::CurrentParamHandleOffset() {
106 CHECK(IsCurrentParamAReference());
107 CHECK_GT(ShbLinkOffset(), ShbNumRefsOffset());
108 // Address of 1st handle
109 int result = ShbLinkOffset().Int32Value() + kPointerSize;
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700110 if (itr_args_ != kObjectOrClass) {
111 const Method *method = GetMethod();
112 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(method);
Ian Rogersb033c752011-07-20 12:22:35 -0700113 int previous_refs = GetMethod()->NumReferenceArgsBefore(arg_pos);
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700114 if (method->IsStatic()) {
Ian Rogersb033c752011-07-20 12:22:35 -0700115 previous_refs++; // account for jclass
116 }
117 result += previous_refs * kPointerSize;
118 }
119 CHECK_GT(result, ShbLinkOffset().Int32Value());
120 return FrameOffset(result);
121}
122
Ian Rogersdf20fe02011-07-20 20:34:16 -0700123size_t JniCallingConvention::CurrentParamSize() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700124 if (itr_args_ <= kObjectOrClass) {
Ian Rogersb033c752011-07-20 12:22:35 -0700125 return kPointerSize; // JNIEnv or jobject/jclass
126 } else {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700127 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(GetMethod());
Ian Rogersdf20fe02011-07-20 20:34:16 -0700128 return GetMethod()->ParamSize(arg_pos);
Ian Rogersb033c752011-07-20 12:22:35 -0700129 }
130}
131
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700132size_t JniCallingConvention::NumberOfExtraArgumentsForJni(
133 const Method* method) {
134 // The first argument is the JNIEnv*.
135 // Static methods have an extra argument which is the jclass.
136 return (method->IsStatic() ? 2 : 1);
137}
138
Ian Rogersb033c752011-07-20 12:22:35 -0700139} // namespace art