blob: ae6ac251ddf804157c4b19e9eccd4d29412fe94c [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
4#include "src/calling_convention.h"
5#include "src/logging.h"
6#include "src/utils.h"
7
8namespace art {
9
Ian Rogersdf20fe02011-07-20 20:34:16 -070010// Managed runtime calling convention
11
Ian Rogersb033c752011-07-20 12:22:35 -070012size_t ManagedRuntimeCallingConvention::FrameSize() {
13 LOG(FATAL) << "Unimplemented";
14 return 0;
15}
16
17bool ManagedRuntimeCallingConvention::HasNext() {
18 return itr_position_ < GetMethod()->NumArgs();
19}
20
21void ManagedRuntimeCallingConvention::Next() {
22 CHECK(HasNext());
23 if (((itr_position_ != 0) || GetMethod()->IsStatic()) &&
24 GetMethod()->IsParamALongOrDouble(itr_position_)) {
25 itr_longs_and_doubles_++;
26 }
27 itr_position_++;
28}
29
30bool ManagedRuntimeCallingConvention::IsCurrentParamPossiblyNull() {
31 // for a virtual method, this should never be NULL
32 return GetMethod()->IsStatic() || (itr_position_ != 0);
33}
34
Ian Rogersdf20fe02011-07-20 20:34:16 -070035size_t ManagedRuntimeCallingConvention::CurrentParamSize() {
36 return GetMethod()->ParamSize(itr_position_);
Ian Rogersb033c752011-07-20 12:22:35 -070037}
38
39bool ManagedRuntimeCallingConvention::IsCurrentParamAReference() {
40 return GetMethod()->IsParamAReference(itr_position_);
41}
42
Ian Rogersdf20fe02011-07-20 20:34:16 -070043// JNI calling convention
Ian Rogersb033c752011-07-20 12:22:35 -070044
45size_t JniCallingConvention::FrameSize() {
46 // Return address and Method*
47 size_t frame_data_size = 2 * kPointerSize;
48 // Handles plus 2 words for SHB header
49 size_t handle_area_size = (HandleCount() + 2) * kPointerSize;
Ian Rogersdf20fe02011-07-20 20:34:16 -070050 return RoundUp(frame_data_size + handle_area_size + SizeOfReturnValue(), 16);
Ian Rogersb033c752011-07-20 12:22:35 -070051}
52
53size_t JniCallingConvention::OutArgSize() {
54 return RoundUp(NumberOfOutgoingStackArgs() * kPointerSize, 16);
55}
56
57size_t JniCallingConvention::HandleCount() {
58 const Method* method = GetMethod();
59 return method->NumReferenceArgs() + (method->IsStatic() ? 1 : 0);
60}
61
Ian Rogersdf20fe02011-07-20 20:34:16 -070062FrameOffset JniCallingConvention::ReturnValueSaveLocation() {
63 size_t start_of_shb = ShbLinkOffset().Int32Value() + kPointerSize;
64 size_t handle_size = kPointerSize * HandleCount(); // size excluding header
65 return FrameOffset(start_of_shb + handle_size);
66}
67
Ian Rogersb033c752011-07-20 12:22:35 -070068bool JniCallingConvention::HasNext() {
69 if (itr_position_ <= kObjectOrClass) {
70 return true;
71 } else {
72 unsigned int arg_pos = itr_position_ - (GetMethod()->IsStatic() ? 2 : 1);
73 return arg_pos < GetMethod()->NumArgs();
74 }
75}
76
77void JniCallingConvention::Next() {
78 CHECK(HasNext());
79 if (itr_position_ > kObjectOrClass) {
80 int arg_pos = itr_position_ - (GetMethod()->IsStatic() ? 2 : 1);
81 if (GetMethod()->IsParamALongOrDouble(arg_pos)) {
82 itr_longs_and_doubles_++;
83 }
84 }
85 itr_position_++;
86}
87
88bool JniCallingConvention::IsCurrentParamAReference() {
89 switch (itr_position_) {
90 case kJniEnv:
91 return false; // JNIEnv*
92 case kObjectOrClass:
93 return true; // jobject or jclass
94 default: {
95 int arg_pos = itr_position_ - (GetMethod()->IsStatic() ? 2 : 1);
96 return GetMethod()->IsParamAReference(arg_pos);
97 }
98 }
99}
100
101// Return position of handle holding reference at the current iterator position
102FrameOffset JniCallingConvention::CurrentParamHandleOffset() {
103 CHECK(IsCurrentParamAReference());
104 CHECK_GT(ShbLinkOffset(), ShbNumRefsOffset());
105 // Address of 1st handle
106 int result = ShbLinkOffset().Int32Value() + kPointerSize;
107 if (itr_position_ != kObjectOrClass) {
108 bool is_static = GetMethod()->IsStatic();
109 int arg_pos = itr_position_ - (is_static ? 2 : 1);
110 int previous_refs = GetMethod()->NumReferenceArgsBefore(arg_pos);
111 if (is_static) {
112 previous_refs++; // account for jclass
113 }
114 result += previous_refs * kPointerSize;
115 }
116 CHECK_GT(result, ShbLinkOffset().Int32Value());
117 return FrameOffset(result);
118}
119
Ian Rogersdf20fe02011-07-20 20:34:16 -0700120size_t JniCallingConvention::CurrentParamSize() {
Ian Rogersb033c752011-07-20 12:22:35 -0700121 if (itr_position_ <= kObjectOrClass) {
122 return kPointerSize; // JNIEnv or jobject/jclass
123 } else {
124 int arg_pos = itr_position_ - (GetMethod()->IsStatic() ? 2 : 1);
Ian Rogersdf20fe02011-07-20 20:34:16 -0700125 return GetMethod()->ParamSize(arg_pos);
Ian Rogersb033c752011-07-20 12:22:35 -0700126 }
127}
128
129} // namespace art