blob: 4e2eab7605e174a2c76e139c33eda404261b8cf5 [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
7#include "src/managed_register.h"
8#include "src/object.h"
9#include "src/thread.h"
10
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
29 // Iterator interface
30
31 // Place iterator at start of arguments. The displacement is applied to
32 // frame offset methods to account for frames which may be on the stack
33 // below the one being iterated over.
34 void ResetIterator(FrameOffset displacement) {
35 displacement_ = displacement;
36 itr_position_ = 0;
37 itr_longs_and_doubles_ = 0;
38 }
39
40 protected:
41 explicit CallingConvention(Method* method) : displacement_(0),
42 method_(method) {}
43 const Method* GetMethod() const { return method_; }
44
45 // position along argument list
46 unsigned int itr_position_;
47 // number of longs and doubles seen along argument list
48 unsigned int itr_longs_and_doubles_;
49 // Space for frames below this on the stack
50 FrameOffset displacement_;
51
52 private:
53 const Method* method_;
54};
55
56// Abstraction for managed code's calling conventions
57class ManagedRuntimeCallingConvention : public CallingConvention {
58 public:
59 explicit ManagedRuntimeCallingConvention(Method* method) :
60 CallingConvention(method) {}
61
62 size_t FrameSize();
63
64 // Iterator interface
65 bool HasNext();
66 void Next();
67 bool IsCurrentParamAReference();
68 bool IsCurrentParamInRegister();
69 bool IsCurrentParamOnStack();
70 bool IsCurrentParamPossiblyNull();
Ian Rogersdf20fe02011-07-20 20:34:16 -070071 size_t CurrentParamSize();
Ian Rogersb033c752011-07-20 12:22:35 -070072 ManagedRegister CurrentParamRegister();
73 FrameOffset CurrentParamStackOffset();
74
75 DISALLOW_COPY_AND_ASSIGN(ManagedRuntimeCallingConvention);
76};
77
78// Abstraction for JNI calling conventions
79// | incoming stack args | <-- Prior SP
80// | { Spilled registers |
81// | & return address } |
Ian Rogersdf20fe02011-07-20 20:34:16 -070082// | { Return value spill } | (live on return slow paths)
Ian Rogersb033c752011-07-20 12:22:35 -070083// | { Stack Handle Block |
84// | ... |
Ian Rogersdf20fe02011-07-20 20:34:16 -070085// | num. refs./link } | (here to prior SP is frame size)
Ian Rogersb033c752011-07-20 12:22:35 -070086// | Method* | <-- Anchor SP written to thread
87// | { Outgoing stack args |
88// | ... } | <-- SP at point of call
89// | Native frame |
90class JniCallingConvention : public CallingConvention {
91 public:
92 explicit JniCallingConvention(Method* native_method) :
93 CallingConvention(native_method) {}
94
95 // Size of frame excluding space for outgoing args (its assumed Method* is
96 // always at the bottom of a frame, but this doesn't work for outgoing
97 // native args). Includes alignment.
98 size_t FrameSize();
99 // Size of outgoing arguments, including alignment
100 size_t OutArgSize();
101 // Number of handles in stack handle block
102 size_t HandleCount();
Ian Rogersdf20fe02011-07-20 20:34:16 -0700103 // Location where the return value of a call can be squirreled if another
104 // call is made following the native call
105 FrameOffset ReturnValueSaveLocation();
Ian Rogersb033c752011-07-20 12:22:35 -0700106
107 // Iterator interface
108 bool HasNext();
109 void Next();
110 bool IsCurrentParamAReference();
111 bool IsCurrentParamInRegister();
112 bool IsCurrentParamOnStack();
Ian Rogersdf20fe02011-07-20 20:34:16 -0700113 size_t CurrentParamSize();
Ian Rogersb033c752011-07-20 12:22:35 -0700114 ManagedRegister CurrentParamRegister();
115 FrameOffset CurrentParamStackOffset();
116
117 // Iterator interface extension for JNI
118 FrameOffset CurrentParamHandleOffset();
119
120 // Position of stack handle block and interior fields
121 FrameOffset ShbOffset() {
122 return FrameOffset(displacement_.Int32Value() +
123 kPointerSize); // above Method*
124 }
125 FrameOffset ShbNumRefsOffset() {
126 return FrameOffset(ShbOffset().Int32Value() +
127 StackHandleBlock::NumberOfReferencesOffset());
128 }
129 FrameOffset ShbLinkOffset() {
130 return FrameOffset(ShbOffset().Int32Value() +
131 StackHandleBlock::LinkOffset());
132 }
133
134 private:
135 // Named iterator positions
136 enum IteratorPos {
137 kJniEnv = 0,
138 kObjectOrClass = 1
139 };
140
141 // Number of stack slots for outgoing arguments, above which handles are
142 // located
143 size_t NumberOfOutgoingStackArgs();
144
145 DISALLOW_COPY_AND_ASSIGN(JniCallingConvention);
146};
147
148} // namespace art
149
150#endif // ART_SRC_CALLING_CONVENTION_H_