OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_COMPILER_LINKAGE_H_ | 5 #ifndef V8_COMPILER_LINKAGE_H_ |
6 #define V8_COMPILER_LINKAGE_H_ | 6 #define V8_COMPILER_LINKAGE_H_ |
7 | 7 |
8 #include "src/base/flags.h" | 8 #include "src/base/flags.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/compiler/frame.h" | 10 #include "src/compiler/frame.h" |
11 #include "src/compiler/machine-type.h" | 11 #include "src/compiler/machine-type.h" |
12 #include "src/compiler/node.h" | 12 #include "src/compiler/node.h" |
13 #include "src/compiler/operator.h" | 13 #include "src/compiler/operator.h" |
14 #include "src/zone.h" | 14 #include "src/zone.h" |
15 | 15 |
16 namespace v8 { | 16 namespace v8 { |
17 namespace internal { | 17 namespace internal { |
18 namespace compiler { | 18 namespace compiler { |
19 | 19 |
20 // Describes the location for a parameter or a return value to a call. | 20 // Describes the location for a parameter or a return value to a call. |
21 // TODO(titzer): replace with Radium locations when they are ready. | |
22 class LinkageLocation { | 21 class LinkageLocation { |
23 public: | 22 public: |
24 LinkageLocation(MachineType rep, int location) | 23 explicit LinkageLocation(int location) : location_(location) {} |
25 : rep_(rep), location_(location) {} | |
26 | |
27 inline MachineType representation() const { return rep_; } | |
28 | 24 |
29 static const int16_t ANY_REGISTER = 32767; | 25 static const int16_t ANY_REGISTER = 32767; |
30 | 26 |
| 27 static LinkageLocation AnyRegister() { return LinkageLocation(ANY_REGISTER); } |
| 28 |
31 private: | 29 private: |
32 friend class CallDescriptor; | 30 friend class CallDescriptor; |
33 friend class OperandGenerator; | 31 friend class OperandGenerator; |
34 MachineType rep_; | |
35 int16_t location_; // >= 0 implies register, otherwise stack slot. | 32 int16_t location_; // >= 0 implies register, otherwise stack slot. |
36 }; | 33 }; |
37 | 34 |
| 35 typedef Signature<LinkageLocation> LocationSignature; |
38 | 36 |
| 37 // Describes a call to various parts of the compiler. Every call has the notion |
| 38 // of a "target", which is the first input to the call. |
39 class CallDescriptor FINAL : public ZoneObject { | 39 class CallDescriptor FINAL : public ZoneObject { |
40 public: | 40 public: |
41 // Describes whether the first parameter is a code object, a JSFunction, | 41 // Describes the kind of this call, which determines the target. |
42 // or an address--all of which require different machine sequences to call. | 42 enum Kind { |
43 enum Kind { kCallCodeObject, kCallJSFunction, kCallAddress }; | 43 kCallCodeObject, // target is a Code object |
| 44 kCallJSFunction, // target is a JSFunction object |
| 45 kCallAddress // target is a machine pointer |
| 46 }; |
44 | 47 |
45 enum Flag { | 48 enum Flag { |
46 // TODO(jarin) kLazyDeoptimization and kNeedsFrameState should be unified. | 49 // TODO(jarin) kLazyDeoptimization and kNeedsFrameState should be unified. |
47 kNoFlags = 0u, | 50 kNoFlags = 0u, |
48 kNeedsFrameState = 1u << 0, | 51 kNeedsFrameState = 1u << 0, |
49 kPatchableCallSite = 1u << 1, | 52 kPatchableCallSite = 1u << 1, |
50 kNeedsNopAfterCall = 1u << 2, | 53 kNeedsNopAfterCall = 1u << 2, |
51 kPatchableCallSiteWithNop = kPatchableCallSite | kNeedsNopAfterCall | 54 kPatchableCallSiteWithNop = kPatchableCallSite | kNeedsNopAfterCall |
52 }; | 55 }; |
53 typedef base::Flags<Flag> Flags; | 56 typedef base::Flags<Flag> Flags; |
54 | 57 |
55 CallDescriptor(Kind kind, int8_t return_count, int16_t parameter_count, | 58 CallDescriptor(Kind kind, MachineType target_type, LinkageLocation target_loc, |
56 int16_t input_count, LinkageLocation* locations, | 59 MachineSignature* machine_sig, LocationSignature* location_sig, |
57 Operator::Properties properties, | 60 size_t js_param_count, Operator::Properties properties, |
58 RegList callee_saved_registers, Flags flags, | 61 RegList callee_saved_registers, Flags flags, |
59 const char* debug_name = "") | 62 const char* debug_name = "") |
60 : kind_(kind), | 63 : kind_(kind), |
61 return_count_(return_count), | 64 target_type_(target_type), |
62 parameter_count_(parameter_count), | 65 target_loc_(target_loc), |
63 input_count_(input_count), | 66 machine_sig_(machine_sig), |
64 locations_(locations), | 67 location_sig_(location_sig), |
| 68 js_param_count_(js_param_count), |
65 properties_(properties), | 69 properties_(properties), |
66 callee_saved_registers_(callee_saved_registers), | 70 callee_saved_registers_(callee_saved_registers), |
67 flags_(flags), | 71 flags_(flags), |
68 debug_name_(debug_name) {} | 72 debug_name_(debug_name) { |
| 73 DCHECK(machine_sig->return_count() == location_sig->return_count()); |
| 74 DCHECK(machine_sig->parameter_count() == location_sig->parameter_count()); |
| 75 } |
| 76 |
69 // Returns the kind of this call. | 77 // Returns the kind of this call. |
70 Kind kind() const { return kind_; } | 78 Kind kind() const { return kind_; } |
71 | 79 |
72 // Returns {true} if this descriptor is a call to a JSFunction. | 80 // Returns {true} if this descriptor is a call to a JSFunction. |
73 bool IsJSFunctionCall() const { return kind_ == kCallJSFunction; } | 81 bool IsJSFunctionCall() const { return kind_ == kCallJSFunction; } |
74 | 82 |
75 // The number of return values from this call, usually 0 or 1. | 83 // The number of return values from this call. |
76 int ReturnCount() const { return return_count_; } | 84 size_t ReturnCount() const { return machine_sig_->return_count(); } |
77 | 85 |
78 // The number of JavaScript parameters to this call, including receiver, | 86 // The number of JavaScript parameters to this call, including the receiver |
79 // but not the context. | 87 // object. |
80 int ParameterCount() const { return parameter_count_; } | 88 size_t JSParameterCount() const { return js_param_count_; } |
81 | 89 |
82 int InputCount() const { return input_count_; } | 90 // The total number of inputs to this call, which includes the target, |
| 91 // receiver, context, etc. |
| 92 // TODO(titzer): this should input the framestate input too. |
| 93 size_t InputCount() const { return 1 + machine_sig_->parameter_count(); } |
83 | 94 |
84 int FrameStateCount() const { return NeedsFrameState() ? 1 : 0; } | 95 size_t FrameStateCount() const { return NeedsFrameState() ? 1 : 0; } |
85 | 96 |
86 Flags flags() const { return flags_; } | 97 Flags flags() const { return flags_; } |
87 | 98 |
88 bool NeedsFrameState() const { return flags() & kNeedsFrameState; } | 99 bool NeedsFrameState() const { return flags() & kNeedsFrameState; } |
89 | 100 |
90 LinkageLocation GetReturnLocation(int index) { | 101 LinkageLocation GetReturnLocation(size_t index) const { |
91 DCHECK(index < return_count_); | 102 return location_sig_->GetReturn(index); |
92 return locations_[0 + index]; // return locations start at 0. | |
93 } | 103 } |
94 | 104 |
95 LinkageLocation GetInputLocation(int index) { | 105 LinkageLocation GetInputLocation(size_t index) const { |
96 DCHECK(index < input_count_ + 1); // input_count + 1 is the context. | 106 if (index == 0) return target_loc_; |
97 return locations_[return_count_ + index]; // inputs start after returns. | 107 return location_sig_->GetParam(index - 1); |
| 108 } |
| 109 |
| 110 const MachineSignature* GetMachineSignature() const { return machine_sig_; } |
| 111 |
| 112 MachineType GetReturnType(size_t index) const { |
| 113 return machine_sig_->GetReturn(index); |
| 114 } |
| 115 |
| 116 MachineType GetInputType(size_t index) const { |
| 117 if (index == 0) return target_type_; |
| 118 return machine_sig_->GetParam(index - 1); |
98 } | 119 } |
99 | 120 |
100 // Operator properties describe how this call can be optimized, if at all. | 121 // Operator properties describe how this call can be optimized, if at all. |
101 Operator::Properties properties() const { return properties_; } | 122 Operator::Properties properties() const { return properties_; } |
102 | 123 |
103 // Get the callee-saved registers, if any, across this call. | 124 // Get the callee-saved registers, if any, across this call. |
104 RegList CalleeSavedRegisters() { return callee_saved_registers_; } | 125 RegList CalleeSavedRegisters() const { return callee_saved_registers_; } |
105 | 126 |
106 const char* debug_name() const { return debug_name_; } | 127 const char* debug_name() const { return debug_name_; } |
107 | 128 |
108 private: | 129 private: |
109 friend class Linkage; | 130 friend class Linkage; |
110 | 131 |
111 Kind kind_; | 132 Kind kind_; |
112 int8_t return_count_; | 133 MachineType target_type_; |
113 int16_t parameter_count_; | 134 LinkageLocation target_loc_; |
114 int16_t input_count_; | 135 MachineSignature* machine_sig_; |
115 LinkageLocation* locations_; | 136 LocationSignature* location_sig_; |
| 137 size_t js_param_count_; |
116 Operator::Properties properties_; | 138 Operator::Properties properties_; |
117 RegList callee_saved_registers_; | 139 RegList callee_saved_registers_; |
118 Flags flags_; | 140 Flags flags_; |
119 const char* debug_name_; | 141 const char* debug_name_; |
120 }; | 142 }; |
121 | 143 |
122 DEFINE_OPERATORS_FOR_FLAGS(CallDescriptor::Flags) | 144 DEFINE_OPERATORS_FOR_FLAGS(CallDescriptor::Flags) |
123 | 145 |
124 OStream& operator<<(OStream& os, const CallDescriptor& d); | 146 OStream& operator<<(OStream& os, const CallDescriptor& d); |
125 OStream& operator<<(OStream& os, const CallDescriptor::Kind& k); | 147 OStream& operator<<(OStream& os, const CallDescriptor::Kind& k); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 CodeStubInterfaceDescriptor* descriptor, int stack_parameter_count = 0, | 181 CodeStubInterfaceDescriptor* descriptor, int stack_parameter_count = 0, |
160 CallDescriptor::Flags flags = CallDescriptor::kNoFlags); | 182 CallDescriptor::Flags flags = CallDescriptor::kNoFlags); |
161 static CallDescriptor* GetStubCallDescriptor( | 183 static CallDescriptor* GetStubCallDescriptor( |
162 CodeStubInterfaceDescriptor* descriptor, int stack_parameter_count, | 184 CodeStubInterfaceDescriptor* descriptor, int stack_parameter_count, |
163 CallDescriptor::Flags flags, Zone* zone); | 185 CallDescriptor::Flags flags, Zone* zone); |
164 | 186 |
165 // Creates a call descriptor for simplified C calls that is appropriate | 187 // Creates a call descriptor for simplified C calls that is appropriate |
166 // for the host platform. This simplified calling convention only supports | 188 // for the host platform. This simplified calling convention only supports |
167 // integers and pointers of one word size each, i.e. no floating point, | 189 // integers and pointers of one word size each, i.e. no floating point, |
168 // structs, pointers to members, etc. | 190 // structs, pointers to members, etc. |
169 static CallDescriptor* GetSimplifiedCDescriptor( | 191 static CallDescriptor* GetSimplifiedCDescriptor(Zone* zone, |
170 Zone* zone, int num_params, MachineType return_type, | 192 MachineSignature* sig); |
171 const MachineType* param_types); | |
172 | 193 |
173 // Get the location of an (incoming) parameter to this function. | 194 // Get the location of an (incoming) parameter to this function. |
174 LinkageLocation GetParameterLocation(int index) { | 195 LinkageLocation GetParameterLocation(int index) { |
175 return incoming_->GetInputLocation(index + 1); | 196 return incoming_->GetInputLocation(index + 1); // + 1 to skip target. |
| 197 } |
| 198 |
| 199 // Get the machine type of an (incoming) parameter to this function. |
| 200 MachineType GetParameterType(int index) { |
| 201 return incoming_->GetInputType(index + 1); // + 1 to skip target. |
176 } | 202 } |
177 | 203 |
178 // Get the location where this function should place its return value. | 204 // Get the location where this function should place its return value. |
179 LinkageLocation GetReturnLocation() { | 205 LinkageLocation GetReturnLocation() { |
180 return incoming_->GetReturnLocation(0); | 206 return incoming_->GetReturnLocation(0); |
181 } | 207 } |
182 | 208 |
| 209 // Get the machine type of this function's return value. |
| 210 MachineType GetReturnType() { return incoming_->GetReturnType(0); } |
| 211 |
183 // Get the frame offset for a given spill slot. The location depends on the | 212 // Get the frame offset for a given spill slot. The location depends on the |
184 // calling convention and the specific frame layout, and may thus be | 213 // calling convention and the specific frame layout, and may thus be |
185 // architecture-specific. Negative spill slots indicate arguments on the | 214 // architecture-specific. Negative spill slots indicate arguments on the |
186 // caller's frame. The {extra} parameter indicates an additional offset from | 215 // caller's frame. The {extra} parameter indicates an additional offset from |
187 // the frame offset, e.g. to index into part of a double slot. | 216 // the frame offset, e.g. to index into part of a double slot. |
188 FrameOffset GetFrameOffset(int spill_slot, Frame* frame, int extra = 0); | 217 FrameOffset GetFrameOffset(int spill_slot, Frame* frame, int extra = 0); |
189 | 218 |
190 CompilationInfo* info() const { return info_; } | 219 CompilationInfo* info() const { return info_; } |
191 | 220 |
192 static bool NeedsFrameState(Runtime::FunctionId function); | 221 static bool NeedsFrameState(Runtime::FunctionId function); |
193 | 222 |
194 private: | 223 private: |
195 CompilationInfo* info_; | 224 CompilationInfo* info_; |
196 CallDescriptor* incoming_; | 225 CallDescriptor* incoming_; |
197 }; | 226 }; |
198 | 227 |
199 } // namespace compiler | 228 } // namespace compiler |
200 } // namespace internal | 229 } // namespace internal |
201 } // namespace v8 | 230 } // namespace v8 |
202 | 231 |
203 #endif // V8_COMPILER_LINKAGE_H_ | 232 #endif // V8_COMPILER_LINKAGE_H_ |
OLD | NEW |