blob: 23ca6d6e24d60c3754c93fac6b88ae9c639e3d8d [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#ifndef ART_SRC_CALLING_CONVENTION_H_
5#define ART_SRC_CALLING_CONVENTION_H_
6
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07007#include "managed_register.h"
8#include "object.h"
9#include "thread.h"
Ian Rogersb033c752011-07-20 12:22:35 -070010
11namespace art {
12
13// Top-level abstraction for different calling conventions
14class CallingConvention {
15 public:
16 CallingConvention* GetCallingConvention(Method* method);
17
18 bool IsReturnAReference() const { return method_->IsReturnAReference(); }
19
Ian Rogersdf20fe02011-07-20 20:34:16 -070020 size_t SizeOfReturnValue() const { return method_->ReturnSize(); }
21
Ian Rogersb033c752011-07-20 12:22:35 -070022 // Register that holds the incoming method argument
23 ManagedRegister MethodRegister();
24 // Register that holds result of this method
25 ManagedRegister ReturnRegister();
26 // Register reserved for scratch usage during procedure calls
27 ManagedRegister InterproceduralScratchRegister();
28
Carl Shapiroe2d373e2011-07-25 15:20:06 -070029 // Offset of Method within the frame
30 FrameOffset MethodStackOffset();
31
Ian Rogersb033c752011-07-20 12:22:35 -070032 // Iterator interface
33
34 // Place iterator at start of arguments. The displacement is applied to
35 // frame offset methods to account for frames which may be on the stack
36 // below the one being iterated over.
37 void ResetIterator(FrameOffset displacement) {
38 displacement_ = displacement;
39 itr_position_ = 0;
40 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
48 // position along argument list
49 unsigned int itr_position_;
50 // number of longs and doubles seen along argument list
51 unsigned int itr_longs_and_doubles_;
52 // Space for frames below this on the stack
53 FrameOffset displacement_;
54
55 private:
56 const Method* method_;
57};
58
59// Abstraction for managed code's calling conventions
60class ManagedRuntimeCallingConvention : public CallingConvention {
61 public:
62 explicit ManagedRuntimeCallingConvention(Method* method) :
63 CallingConvention(method) {}
64
65 size_t FrameSize();
66
67 // Iterator interface
68 bool HasNext();
69 void Next();
70 bool IsCurrentParamAReference();
71 bool IsCurrentParamInRegister();
72 bool IsCurrentParamOnStack();
73 bool IsCurrentParamPossiblyNull();
Ian Rogersdf20fe02011-07-20 20:34:16 -070074 size_t CurrentParamSize();
Ian Rogersb033c752011-07-20 12:22:35 -070075 ManagedRegister CurrentParamRegister();
76 FrameOffset CurrentParamStackOffset();
77
78 DISALLOW_COPY_AND_ASSIGN(ManagedRuntimeCallingConvention);
79};
80
81// Abstraction for JNI calling conventions
82// | incoming stack args | <-- Prior SP
83// | { Spilled registers |
84// | & return address } |
Ian Rogersdf20fe02011-07-20 20:34:16 -070085// | { Return value spill } | (live on return slow paths)
Ian Rogersb033c752011-07-20 12:22:35 -070086// | { Stack Handle Block |
87// | ... |
Ian Rogersdf20fe02011-07-20 20:34:16 -070088// | num. refs./link } | (here to prior SP is frame size)
Ian Rogersb033c752011-07-20 12:22:35 -070089// | Method* | <-- Anchor SP written to thread
90// | { Outgoing stack args |
91// | ... } | <-- SP at point of call
92// | Native frame |
93class JniCallingConvention : public CallingConvention {
94 public:
95 explicit JniCallingConvention(Method* native_method) :
96 CallingConvention(native_method) {}
97
98 // Size of frame excluding space for outgoing args (its assumed Method* is
99 // always at the bottom of a frame, but this doesn't work for outgoing
100 // native args). Includes alignment.
101 size_t FrameSize();
102 // Size of outgoing arguments, including alignment
103 size_t OutArgSize();
104 // Number of handles in stack handle block
105 size_t HandleCount();
Ian Rogersdf20fe02011-07-20 20:34:16 -0700106 // Location where the return value of a call can be squirreled if another
107 // call is made following the native call
108 FrameOffset ReturnValueSaveLocation();
Ian Rogersb033c752011-07-20 12:22:35 -0700109
Carl Shapiroe2d373e2011-07-25 15:20:06 -0700110 // Returns true if the register will be clobbered by an outgoing
111 // argument value.
112 bool IsOutArgRegister(ManagedRegister reg);
113
Ian Rogersb033c752011-07-20 12:22:35 -0700114 // Iterator interface
115 bool HasNext();
116 void Next();
117 bool IsCurrentParamAReference();
118 bool IsCurrentParamInRegister();
119 bool IsCurrentParamOnStack();
Ian Rogersdf20fe02011-07-20 20:34:16 -0700120 size_t CurrentParamSize();
Ian Rogersb033c752011-07-20 12:22:35 -0700121 ManagedRegister CurrentParamRegister();
122 FrameOffset CurrentParamStackOffset();
123
124 // Iterator interface extension for JNI
125 FrameOffset CurrentParamHandleOffset();
126
127 // Position of stack handle block and interior fields
128 FrameOffset ShbOffset() {
129 return FrameOffset(displacement_.Int32Value() +
130 kPointerSize); // above Method*
131 }
132 FrameOffset ShbNumRefsOffset() {
133 return FrameOffset(ShbOffset().Int32Value() +
134 StackHandleBlock::NumberOfReferencesOffset());
135 }
136 FrameOffset ShbLinkOffset() {
137 return FrameOffset(ShbOffset().Int32Value() +
138 StackHandleBlock::LinkOffset());
139 }
140
141 private:
142 // Named iterator positions
143 enum IteratorPos {
144 kJniEnv = 0,
145 kObjectOrClass = 1
146 };
147
148 // Number of stack slots for outgoing arguments, above which handles are
149 // located
150 size_t NumberOfOutgoingStackArgs();
151
152 DISALLOW_COPY_AND_ASSIGN(JniCallingConvention);
153};
154
155} // namespace art
156
157#endif // ART_SRC_CALLING_CONVENTION_H_