blob: adcafca435f5b494acf62002ab2fa68e29e13f99 [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
3#ifndef ART_SRC_CALLING_CONVENTION_H_
4#define ART_SRC_CALLING_CONVENTION_H_
5
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07006#include "managed_register.h"
7#include "object.h"
8#include "thread.h"
Ian Rogersb033c752011-07-20 12:22:35 -07009
10namespace art {
11
12// Top-level abstraction for different calling conventions
13class CallingConvention {
14 public:
15 CallingConvention* GetCallingConvention(Method* method);
16
17 bool IsReturnAReference() const { return method_->IsReturnAReference(); }
18
Ian Rogersdf20fe02011-07-20 20:34:16 -070019 size_t SizeOfReturnValue() const { return method_->ReturnSize(); }
20
Ian Rogersb033c752011-07-20 12:22:35 -070021 // Register that holds the incoming method argument
22 ManagedRegister MethodRegister();
23 // Register that holds result of this method
24 ManagedRegister ReturnRegister();
25 // Register reserved for scratch usage during procedure calls
26 ManagedRegister InterproceduralScratchRegister();
27
Carl Shapiroe2d373e2011-07-25 15:20:06 -070028 // Offset of Method within the frame
29 FrameOffset MethodStackOffset();
30
Ian Rogersb033c752011-07-20 12:22:35 -070031 // Iterator interface
32
33 // Place iterator at start of arguments. The displacement is applied to
34 // frame offset methods to account for frames which may be on the stack
35 // below the one being iterated over.
36 void ResetIterator(FrameOffset displacement) {
37 displacement_ = displacement;
Shih-wei Liao5381cf92011-07-27 00:28:04 -070038 itr_slots_ = 0;
39 itr_args_ = 0;
Ian Rogersb033c752011-07-20 12:22:35 -070040 itr_longs_and_doubles_ = 0;
41 }
42
43 protected:
44 explicit CallingConvention(Method* method) : displacement_(0),
45 method_(method) {}
46 const Method* GetMethod() const { return method_; }
47
Shih-wei Liao5381cf92011-07-27 00:28:04 -070048 // The slot number for current calling_convention argument.
49 // Note that each slot is 32-bit. When the current argument is bigger
50 // than 32 bits, return the first slot number for this argument.
51 unsigned int itr_slots_;
52 // The argument number along argument list for current argument
53 unsigned int itr_args_;
54 // Number of longs and doubles seen along argument list
Ian Rogersb033c752011-07-20 12:22:35 -070055 unsigned int itr_longs_and_doubles_;
56 // Space for frames below this on the stack
57 FrameOffset displacement_;
58
59 private:
60 const Method* method_;
61};
62
63// Abstraction for managed code's calling conventions
64class ManagedRuntimeCallingConvention : public CallingConvention {
65 public:
66 explicit ManagedRuntimeCallingConvention(Method* method) :
67 CallingConvention(method) {}
68
69 size_t FrameSize();
70
71 // Iterator interface
72 bool HasNext();
73 void Next();
74 bool IsCurrentParamAReference();
75 bool IsCurrentParamInRegister();
76 bool IsCurrentParamOnStack();
Shih-wei Liao5381cf92011-07-27 00:28:04 -070077 bool IsCurrentUserArg();
Ian Rogersdf20fe02011-07-20 20:34:16 -070078 size_t CurrentParamSize();
Ian Rogersb033c752011-07-20 12:22:35 -070079 ManagedRegister CurrentParamRegister();
80 FrameOffset CurrentParamStackOffset();
81
82 DISALLOW_COPY_AND_ASSIGN(ManagedRuntimeCallingConvention);
83};
84
85// Abstraction for JNI calling conventions
86// | incoming stack args | <-- Prior SP
87// | { Spilled registers |
88// | & return address } |
Ian Rogersdf20fe02011-07-20 20:34:16 -070089// | { Return value spill } | (live on return slow paths)
Ian Rogersb033c752011-07-20 12:22:35 -070090// | { Stack Handle Block |
91// | ... |
Ian Rogersdf20fe02011-07-20 20:34:16 -070092// | num. refs./link } | (here to prior SP is frame size)
Ian Rogersb033c752011-07-20 12:22:35 -070093// | Method* | <-- Anchor SP written to thread
94// | { Outgoing stack args |
95// | ... } | <-- SP at point of call
96// | Native frame |
97class JniCallingConvention : public CallingConvention {
98 public:
99 explicit JniCallingConvention(Method* native_method) :
100 CallingConvention(native_method) {}
101
102 // Size of frame excluding space for outgoing args (its assumed Method* is
103 // always at the bottom of a frame, but this doesn't work for outgoing
104 // native args). Includes alignment.
105 size_t FrameSize();
106 // Size of outgoing arguments, including alignment
107 size_t OutArgSize();
108 // Number of handles in stack handle block
109 size_t HandleCount();
Ian Rogersdf20fe02011-07-20 20:34:16 -0700110 // Location where the return value of a call can be squirreled if another
111 // call is made following the native call
112 FrameOffset ReturnValueSaveLocation();
Ian Rogersb033c752011-07-20 12:22:35 -0700113
Carl Shapiroe2d373e2011-07-25 15:20:06 -0700114 // Returns true if the register will be clobbered by an outgoing
115 // argument value.
116 bool IsOutArgRegister(ManagedRegister reg);
117
Ian Rogersb033c752011-07-20 12:22:35 -0700118 // Iterator interface
119 bool HasNext();
120 void Next();
121 bool IsCurrentParamAReference();
122 bool IsCurrentParamInRegister();
123 bool IsCurrentParamOnStack();
Ian Rogersdf20fe02011-07-20 20:34:16 -0700124 size_t CurrentParamSize();
Ian Rogersb033c752011-07-20 12:22:35 -0700125 ManagedRegister CurrentParamRegister();
126 FrameOffset CurrentParamStackOffset();
127
128 // Iterator interface extension for JNI
129 FrameOffset CurrentParamHandleOffset();
130
131 // Position of stack handle block and interior fields
132 FrameOffset ShbOffset() {
133 return FrameOffset(displacement_.Int32Value() +
134 kPointerSize); // above Method*
135 }
136 FrameOffset ShbNumRefsOffset() {
137 return FrameOffset(ShbOffset().Int32Value() +
138 StackHandleBlock::NumberOfReferencesOffset());
139 }
140 FrameOffset ShbLinkOffset() {
141 return FrameOffset(ShbOffset().Int32Value() +
142 StackHandleBlock::LinkOffset());
143 }
144
145 private:
146 // Named iterator positions
147 enum IteratorPos {
148 kJniEnv = 0,
149 kObjectOrClass = 1
150 };
151
152 // Number of stack slots for outgoing arguments, above which handles are
153 // located
154 size_t NumberOfOutgoingStackArgs();
155
Shih-wei Liao5381cf92011-07-27 00:28:04 -0700156 static size_t NumberOfExtraArgumentsForJni(const Method* method);
Ian Rogersb033c752011-07-20 12:22:35 -0700157 DISALLOW_COPY_AND_ASSIGN(JniCallingConvention);
158};
159
160} // namespace art
161
162#endif // ART_SRC_CALLING_CONVENTION_H_