blob: bf27b6cc8f30b5f7b49dd44d8f3bff900d3b0b6f [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(
Ian Rogers169c9a72011-11-13 20:13:17 -080020 bool is_static, bool is_synchronized, const char* shorty, InstructionSet instruction_set) {
Ian Rogers2c8f6532011-09-02 17:16:34 -070021 if (instruction_set == kX86) {
Ian Rogers169c9a72011-11-13 20:13:17 -080022 return new x86::X86ManagedRuntimeCallingConvention(is_static, is_synchronized, shorty);
Ian Rogers2c8f6532011-09-02 17:16:34 -070023 } else {
24 CHECK(instruction_set == kArm || instruction_set == kThumb2);
Ian Rogers169c9a72011-11-13 20:13:17 -080025 return new arm::ArmManagedRuntimeCallingConvention(is_static, is_synchronized, shorty);
Ian Rogers2c8f6532011-09-02 17:16:34 -070026 }
27}
28
Ian Rogersb033c752011-07-20 12:22:35 -070029bool ManagedRuntimeCallingConvention::HasNext() {
Ian Rogers169c9a72011-11-13 20:13:17 -080030 return itr_args_ < NumArgs();
Ian Rogersb033c752011-07-20 12:22:35 -070031}
32
33void ManagedRuntimeCallingConvention::Next() {
34 CHECK(HasNext());
Ian Rogers7a99c112011-09-07 12:48:27 -070035 if (IsCurrentArgExplicit() && // don't query parameter type of implicit args
Ian Rogers169c9a72011-11-13 20:13:17 -080036 IsParamALongOrDouble(itr_args_)) {
Ian Rogersb033c752011-07-20 12:22:35 -070037 itr_longs_and_doubles_++;
Shih-wei Liao5381cf92011-07-27 00:28:04 -070038 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -070039 }
Shih-wei Liao668512a2011-09-01 14:18:34 -070040 if (IsCurrentParamAReference()) {
41 itr_refs_++;
42 }
Shih-wei Liao5381cf92011-07-27 00:28:04 -070043 itr_args_++;
44 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -070045}
46
Ian Rogers7a99c112011-09-07 12:48:27 -070047bool ManagedRuntimeCallingConvention::IsCurrentArgExplicit() {
48 // Static methods have no implicit arguments, others implicitly pass this
Ian Rogers169c9a72011-11-13 20:13:17 -080049 return IsStatic() || (itr_args_ != 0);
Ian Rogers7a99c112011-09-07 12:48:27 -070050}
51
52bool ManagedRuntimeCallingConvention::IsCurrentArgPossiblyNull() {
53 return IsCurrentArgExplicit(); // any user parameter may be null
Ian Rogersb033c752011-07-20 12:22:35 -070054}
55
Ian Rogersdf20fe02011-07-20 20:34:16 -070056size_t ManagedRuntimeCallingConvention::CurrentParamSize() {
Ian Rogers169c9a72011-11-13 20:13:17 -080057 return ParamSize(itr_args_);
Ian Rogersb033c752011-07-20 12:22:35 -070058}
59
60bool ManagedRuntimeCallingConvention::IsCurrentParamAReference() {
Ian Rogers169c9a72011-11-13 20:13:17 -080061 return IsParamAReference(itr_args_);
Ian Rogersb033c752011-07-20 12:22:35 -070062}
63
Ian Rogersdf20fe02011-07-20 20:34:16 -070064// JNI calling convention
Ian Rogersb033c752011-07-20 12:22:35 -070065
Ian Rogers169c9a72011-11-13 20:13:17 -080066JniCallingConvention* JniCallingConvention::Create(bool is_static, bool is_synchronized,
67 const char* shorty,
68 InstructionSet instruction_set) {
Ian Rogers2c8f6532011-09-02 17:16:34 -070069 if (instruction_set == kX86) {
Ian Rogers169c9a72011-11-13 20:13:17 -080070 return new x86::X86JniCallingConvention(is_static, is_synchronized, shorty);
Ian Rogers2c8f6532011-09-02 17:16:34 -070071 } else {
72 CHECK(instruction_set == kArm || instruction_set == kThumb2);
Ian Rogers169c9a72011-11-13 20:13:17 -080073 return new arm::ArmJniCallingConvention(is_static, is_synchronized, shorty);
Ian Rogers2c8f6532011-09-02 17:16:34 -070074 }
75}
76
Ian Rogersdc51b792011-09-22 20:41:37 -070077size_t JniCallingConvention::ReferenceCount() const {
Ian Rogers169c9a72011-11-13 20:13:17 -080078 return NumReferenceArgs() + (IsStatic() ? 1 : 0);
Ian Rogersb033c752011-07-20 12:22:35 -070079}
80
Ian Rogers5a7a74a2011-09-26 16:32:29 -070081FrameOffset JniCallingConvention::SavedLocalReferenceCookieOffset() const {
Ian Rogers408f79a2011-08-23 18:22:33 -070082 size_t start_of_sirt = SirtLinkOffset().Int32Value() + kPointerSize;
83 size_t references_size = kPointerSize * ReferenceCount(); // size excluding header
84 return FrameOffset(start_of_sirt + references_size);
Ian Rogersdf20fe02011-07-20 20:34:16 -070085}
86
Ian Rogersdc51b792011-09-22 20:41:37 -070087FrameOffset JniCallingConvention::ReturnValueSaveLocation() const {
88 // Segment state is 4 bytes long
Ian Rogers5a7a74a2011-09-26 16:32:29 -070089 return FrameOffset(SavedLocalReferenceCookieOffset().Int32Value() + 4);
Ian Rogersdc51b792011-09-22 20:41:37 -070090}
91
Ian Rogersb033c752011-07-20 12:22:35 -070092bool JniCallingConvention::HasNext() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -070093 if (itr_args_ <= kObjectOrClass) {
Ian Rogersb033c752011-07-20 12:22:35 -070094 return true;
95 } else {
Ian Rogers169c9a72011-11-13 20:13:17 -080096 unsigned int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni();
97 return arg_pos < NumArgs();
Ian Rogersb033c752011-07-20 12:22:35 -070098 }
99}
100
101void JniCallingConvention::Next() {
102 CHECK(HasNext());
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700103 if (itr_args_ > kObjectOrClass) {
Ian Rogers169c9a72011-11-13 20:13:17 -0800104 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni();
105 if (IsParamALongOrDouble(arg_pos)) {
Ian Rogersb033c752011-07-20 12:22:35 -0700106 itr_longs_and_doubles_++;
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700107 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -0700108 }
109 }
Shih-wei Liao668512a2011-09-01 14:18:34 -0700110 if (IsCurrentParamAReference()) {
111 itr_refs_++;
112 }
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700113 itr_args_++;
114 itr_slots_++;
Ian Rogersb033c752011-07-20 12:22:35 -0700115}
116
117bool JniCallingConvention::IsCurrentParamAReference() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700118 switch (itr_args_) {
Ian Rogersb033c752011-07-20 12:22:35 -0700119 case kJniEnv:
120 return false; // JNIEnv*
121 case kObjectOrClass:
122 return true; // jobject or jclass
123 default: {
Ian Rogers169c9a72011-11-13 20:13:17 -0800124 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni();
125 return IsParamAReference(arg_pos);
Ian Rogersb033c752011-07-20 12:22:35 -0700126 }
127 }
128}
129
Ian Rogers408f79a2011-08-23 18:22:33 -0700130// Return position of SIRT entry holding reference at the current iterator
131// position
132FrameOffset JniCallingConvention::CurrentParamSirtEntryOffset() {
Ian Rogersb033c752011-07-20 12:22:35 -0700133 CHECK(IsCurrentParamAReference());
Ian Rogers408f79a2011-08-23 18:22:33 -0700134 CHECK_GT(SirtLinkOffset(), SirtNumRefsOffset());
135 // Address of 1st SIRT entry
136 int result = SirtLinkOffset().Int32Value() + kPointerSize;
Shih-wei Liao668512a2011-09-01 14:18:34 -0700137 result += itr_refs_ * kPointerSize;
Ian Rogers408f79a2011-08-23 18:22:33 -0700138 CHECK_GT(result, SirtLinkOffset().Int32Value());
Ian Rogersb033c752011-07-20 12:22:35 -0700139 return FrameOffset(result);
140}
141
Ian Rogersdf20fe02011-07-20 20:34:16 -0700142size_t JniCallingConvention::CurrentParamSize() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700143 if (itr_args_ <= kObjectOrClass) {
Ian Rogersb033c752011-07-20 12:22:35 -0700144 return kPointerSize; // JNIEnv or jobject/jclass
145 } else {
Ian Rogers169c9a72011-11-13 20:13:17 -0800146 int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni();
147 return ParamSize(arg_pos);
Ian Rogersb033c752011-07-20 12:22:35 -0700148 }
149}
150
Ian Rogers169c9a72011-11-13 20:13:17 -0800151size_t JniCallingConvention::NumberOfExtraArgumentsForJni() {
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700152 // The first argument is the JNIEnv*.
153 // Static methods have an extra argument which is the jclass.
Ian Rogers169c9a72011-11-13 20:13:17 -0800154 return IsStatic() ? 2 : 1;
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700155}
156
Ian Rogersb033c752011-07-20 12:22:35 -0700157} // namespace art