blob: bfd0e34d5ae22413837a6f797f75fa2abdd40710 [file] [log] [blame]
Ian Rogersb033c752011-07-20 12:22:35 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2// Author: irogers@google.com (Ian Rogers)
3
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07004#include "calling_convention.h"
5#include "logging.h"
6#include "utils.h"
Ian Rogersb033c752011-07-20 12:22:35 -07007
8namespace art {
9
Carl Shapiroe2d373e2011-07-25 15:20:06 -070010// Offset of Method within the frame
11FrameOffset CallingConvention::MethodStackOffset() {
12 return displacement_;
13}
14
Ian Rogersdf20fe02011-07-20 20:34:16 -070015// Managed runtime calling convention
16
Ian Rogersb033c752011-07-20 12:22:35 -070017size_t ManagedRuntimeCallingConvention::FrameSize() {
18 LOG(FATAL) << "Unimplemented";
19 return 0;
20}
21
22bool ManagedRuntimeCallingConvention::HasNext() {
23 return itr_position_ < GetMethod()->NumArgs();
24}
25
26void ManagedRuntimeCallingConvention::Next() {
27 CHECK(HasNext());
28 if (((itr_position_ != 0) || GetMethod()->IsStatic()) &&
29 GetMethod()->IsParamALongOrDouble(itr_position_)) {
30 itr_longs_and_doubles_++;
31 }
32 itr_position_++;
33}
34
35bool ManagedRuntimeCallingConvention::IsCurrentParamPossiblyNull() {
36 // for a virtual method, this should never be NULL
37 return GetMethod()->IsStatic() || (itr_position_ != 0);
38}
39
Ian Rogersdf20fe02011-07-20 20:34:16 -070040size_t ManagedRuntimeCallingConvention::CurrentParamSize() {
41 return GetMethod()->ParamSize(itr_position_);
Ian Rogersb033c752011-07-20 12:22:35 -070042}
43
44bool ManagedRuntimeCallingConvention::IsCurrentParamAReference() {
45 return GetMethod()->IsParamAReference(itr_position_);
46}
47
Ian Rogersdf20fe02011-07-20 20:34:16 -070048// JNI calling convention
Ian Rogersb033c752011-07-20 12:22:35 -070049
50size_t JniCallingConvention::FrameSize() {
51 // Return address and Method*
52 size_t frame_data_size = 2 * kPointerSize;
53 // Handles plus 2 words for SHB header
54 size_t handle_area_size = (HandleCount() + 2) * kPointerSize;
Ian Rogersdf20fe02011-07-20 20:34:16 -070055 return RoundUp(frame_data_size + handle_area_size + SizeOfReturnValue(), 16);
Ian Rogersb033c752011-07-20 12:22:35 -070056}
57
58size_t JniCallingConvention::OutArgSize() {
59 return RoundUp(NumberOfOutgoingStackArgs() * kPointerSize, 16);
60}
61
62size_t JniCallingConvention::HandleCount() {
63 const Method* method = GetMethod();
64 return method->NumReferenceArgs() + (method->IsStatic() ? 1 : 0);
65}
66
Ian Rogersdf20fe02011-07-20 20:34:16 -070067FrameOffset JniCallingConvention::ReturnValueSaveLocation() {
68 size_t start_of_shb = ShbLinkOffset().Int32Value() + kPointerSize;
69 size_t handle_size = kPointerSize * HandleCount(); // size excluding header
70 return FrameOffset(start_of_shb + handle_size);
71}
72
Ian Rogersb033c752011-07-20 12:22:35 -070073bool JniCallingConvention::HasNext() {
74 if (itr_position_ <= kObjectOrClass) {
75 return true;
76 } else {
77 unsigned int arg_pos = itr_position_ - (GetMethod()->IsStatic() ? 2 : 1);
78 return arg_pos < GetMethod()->NumArgs();
79 }
80}
81
82void JniCallingConvention::Next() {
83 CHECK(HasNext());
84 if (itr_position_ > kObjectOrClass) {
85 int arg_pos = itr_position_ - (GetMethod()->IsStatic() ? 2 : 1);
86 if (GetMethod()->IsParamALongOrDouble(arg_pos)) {
87 itr_longs_and_doubles_++;
88 }
89 }
90 itr_position_++;
91}
92
93bool JniCallingConvention::IsCurrentParamAReference() {
94 switch (itr_position_) {
95 case kJniEnv:
96 return false; // JNIEnv*
97 case kObjectOrClass:
98 return true; // jobject or jclass
99 default: {
100 int arg_pos = itr_position_ - (GetMethod()->IsStatic() ? 2 : 1);
101 return GetMethod()->IsParamAReference(arg_pos);
102 }
103 }
104}
105
106// Return position of handle holding reference at the current iterator position
107FrameOffset JniCallingConvention::CurrentParamHandleOffset() {
108 CHECK(IsCurrentParamAReference());
109 CHECK_GT(ShbLinkOffset(), ShbNumRefsOffset());
110 // Address of 1st handle
111 int result = ShbLinkOffset().Int32Value() + kPointerSize;
112 if (itr_position_ != kObjectOrClass) {
113 bool is_static = GetMethod()->IsStatic();
114 int arg_pos = itr_position_ - (is_static ? 2 : 1);
115 int previous_refs = GetMethod()->NumReferenceArgsBefore(arg_pos);
116 if (is_static) {
117 previous_refs++; // account for jclass
118 }
119 result += previous_refs * kPointerSize;
120 }
121 CHECK_GT(result, ShbLinkOffset().Int32Value());
122 return FrameOffset(result);
123}
124
Ian Rogersdf20fe02011-07-20 20:34:16 -0700125size_t JniCallingConvention::CurrentParamSize() {
Ian Rogersb033c752011-07-20 12:22:35 -0700126 if (itr_position_ <= kObjectOrClass) {
127 return kPointerSize; // JNIEnv or jobject/jclass
128 } else {
129 int arg_pos = itr_position_ - (GetMethod()->IsStatic() ? 2 : 1);
Ian Rogersdf20fe02011-07-20 20:34:16 -0700130 return GetMethod()->ParamSize(arg_pos);
Ian Rogersb033c752011-07-20 12:22:35 -0700131 }
132}
133
134} // namespace art