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::Property properties, RegList callee_saved_registers, | 60 size_t js_param_count, Operator::Property properties, |
58 Flags flags, const char* debug_name = "") | 61 RegList callee_saved_registers, Flags flags, |
62 const char* debug_name = "") | |
59 : kind_(kind), | 63 : kind_(kind), |
60 return_count_(return_count), | 64 target_type_(target_type), |
61 parameter_count_(parameter_count), | 65 target_loc_(target_loc), |
62 input_count_(input_count), | 66 machine_sig_(machine_sig), |
63 locations_(locations), | 67 location_sig_(location_sig), |
68 js_param_count_(js_param_count), | |
Benedikt Meurer
2014/09/02 19:00:33
Nit: Rename to js_parameter_count_ for consistency
| |
64 properties_(properties), | 69 properties_(properties), |
65 callee_saved_registers_(callee_saved_registers), | 70 callee_saved_registers_(callee_saved_registers), |
66 flags_(flags), | 71 flags_(flags), |
67 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 | |
68 // Returns the kind of this call. | 77 // Returns the kind of this call. |
69 Kind kind() const { return kind_; } | 78 Kind kind() const { return kind_; } |
70 | 79 |
71 // Returns {true} if this descriptor is a call to a JSFunction. | 80 // Returns {true} if this descriptor is a call to a JSFunction. |
72 bool IsJSFunctionCall() const { return kind_ == kCallJSFunction; } | 81 bool IsJSFunctionCall() const { return kind_ == kCallJSFunction; } |
73 | 82 |
74 // The number of return values from this call, usually 0 or 1. | 83 // The number of return values from this call. |
75 int ReturnCount() const { return return_count_; } | 84 size_t ReturnCount() const { return machine_sig_->return_count(); } |
76 | 85 |
77 // The number of JavaScript parameters to this call, including receiver, | 86 // The number of JavaScript parameters to this call, including the receiver |
78 // but not the context. | 87 // object. |
79 int ParameterCount() const { return parameter_count_; } | 88 size_t JSParameterCount() const { return js_param_count_; } |
80 | 89 |
81 int InputCount() const { return input_count_; } | 90 // The total number of inputs to this call, which includes the target, |
91 // receiver, context, etc. | |
92 size_t InputCount() const { return 1 + machine_sig_->parameter_count(); } | |
82 | 93 |
83 int FrameStateCount() const { return NeedsFrameState() ? 1 : 0; } | 94 size_t FrameStateCount() const { return NeedsFrameState() ? 1 : 0; } |
84 | 95 |
85 Flags flags() const { return flags_; } | 96 Flags flags() const { return flags_; } |
86 | 97 |
87 bool NeedsFrameState() const { return flags() & kNeedsFrameState; } | 98 bool NeedsFrameState() const { return flags() & kNeedsFrameState; } |
88 | 99 |
89 LinkageLocation GetReturnLocation(int index) { | 100 LinkageLocation GetReturnLocation(size_t index) const { |
90 DCHECK(index < return_count_); | 101 return location_sig_->GetReturn(index); |
91 return locations_[0 + index]; // return locations start at 0. | |
92 } | 102 } |
93 | 103 |
94 LinkageLocation GetInputLocation(int index) { | 104 LinkageLocation GetInputLocation(size_t index) const { |
95 DCHECK(index < input_count_ + 1); // input_count + 1 is the context. | 105 if (index == 0) return target_loc_; |
96 return locations_[return_count_ + index]; // inputs start after returns. | 106 return location_sig_->GetParam(index - 1); |
107 } | |
108 | |
109 MachineSignature* GetMachineSignature() const { return machine_sig_; } | |
Benedikt Meurer
2014/09/02 19:00:33
Nit: const MachineSignature*
| |
110 | |
111 MachineType GetReturnType(size_t index) const { | |
112 return machine_sig_->GetReturn(index); | |
113 } | |
114 | |
115 MachineType GetInputType(size_t index) const { | |
116 if (index == 0) return target_type_; | |
117 return machine_sig_->GetParam(index - 1); | |
97 } | 118 } |
98 | 119 |
99 // Operator properties describe how this call can be optimized, if at all. | 120 // Operator properties describe how this call can be optimized, if at all. |
100 Operator::Property properties() const { return properties_; } | 121 Operator::Property properties() const { return properties_; } |
101 | 122 |
102 // Get the callee-saved registers, if any, across this call. | 123 // Get the callee-saved registers, if any, across this call. |
103 RegList CalleeSavedRegisters() { return callee_saved_registers_; } | 124 RegList CalleeSavedRegisters() const { return callee_saved_registers_; } |
104 | 125 |
105 const char* debug_name() const { return debug_name_; } | 126 const char* debug_name() const { return debug_name_; } |
106 | 127 |
107 private: | 128 private: |
108 friend class Linkage; | 129 friend class Linkage; |
109 | 130 |
110 Kind kind_; | 131 Kind kind_; |
111 int8_t return_count_; | 132 MachineType target_type_; |
112 int16_t parameter_count_; | 133 LinkageLocation target_loc_; |
113 int16_t input_count_; | 134 MachineSignature* machine_sig_; |
114 LinkageLocation* locations_; | 135 LocationSignature* location_sig_; |
136 size_t js_param_count_; | |
Benedikt Meurer
2014/09/02 19:00:34
Nit: js_parameter_count_
| |
115 Operator::Property properties_; | 137 Operator::Property properties_; |
116 RegList callee_saved_registers_; | 138 RegList callee_saved_registers_; |
117 Flags flags_; | 139 Flags flags_; |
118 const char* debug_name_; | 140 const char* debug_name_; |
119 }; | 141 }; |
120 | 142 |
121 DEFINE_OPERATORS_FOR_FLAGS(CallDescriptor::Flags) | 143 DEFINE_OPERATORS_FOR_FLAGS(CallDescriptor::Flags) |
122 | 144 |
123 OStream& operator<<(OStream& os, const CallDescriptor& d); | 145 OStream& operator<<(OStream& os, const CallDescriptor& d); |
124 OStream& operator<<(OStream& os, const CallDescriptor::Kind& k); | 146 OStream& operator<<(OStream& os, const CallDescriptor::Kind& k); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
161 CodeStubInterfaceDescriptor* descriptor, int stack_parameter_count = 0, | 183 CodeStubInterfaceDescriptor* descriptor, int stack_parameter_count = 0, |
162 CallDescriptor::Flags flags = CallDescriptor::kNoFlags); | 184 CallDescriptor::Flags flags = CallDescriptor::kNoFlags); |
163 static CallDescriptor* GetStubCallDescriptor( | 185 static CallDescriptor* GetStubCallDescriptor( |
164 CodeStubInterfaceDescriptor* descriptor, int stack_parameter_count, | 186 CodeStubInterfaceDescriptor* descriptor, int stack_parameter_count, |
165 CallDescriptor::Flags flags, Zone* zone); | 187 CallDescriptor::Flags flags, Zone* zone); |
166 | 188 |
167 // Creates a call descriptor for simplified C calls that is appropriate | 189 // Creates a call descriptor for simplified C calls that is appropriate |
168 // for the host platform. This simplified calling convention only supports | 190 // for the host platform. This simplified calling convention only supports |
169 // integers and pointers of one word size each, i.e. no floating point, | 191 // integers and pointers of one word size each, i.e. no floating point, |
170 // structs, pointers to members, etc. | 192 // structs, pointers to members, etc. |
171 static CallDescriptor* GetSimplifiedCDescriptor( | 193 static CallDescriptor* GetSimplifiedCDescriptor(Zone* zone, |
172 Zone* zone, int num_params, MachineType return_type, | 194 MachineSignature* sig); |
173 const MachineType* param_types); | |
174 | 195 |
175 // Get the location of an (incoming) parameter to this function. | 196 // Get the location of an (incoming) parameter to this function. |
176 LinkageLocation GetParameterLocation(int index) { | 197 LinkageLocation GetParameterLocation(int index) { |
177 return incoming_->GetInputLocation(index + 1); | 198 return incoming_->GetInputLocation(index + 1); // + 1 to skip target. |
199 } | |
200 | |
201 // Get the machine type of an (incoming) parameter to this function. | |
202 MachineType GetParameterType(int index) { | |
Benedikt Meurer
2014/09/02 19:00:34
Nit: method should be const
| |
203 return incoming_->GetInputType(index + 1); // + 1 to skip target. | |
178 } | 204 } |
179 | 205 |
180 // Get the location where this function should place its return value. | 206 // Get the location where this function should place its return value. |
181 LinkageLocation GetReturnLocation() { | 207 LinkageLocation GetReturnLocation() { |
182 return incoming_->GetReturnLocation(0); | 208 return incoming_->GetReturnLocation(0); |
183 } | 209 } |
184 | 210 |
211 // Get the machine type of this function's return value. | |
212 MachineType GetReturnType() { return incoming_->GetReturnType(0); } | |
Benedikt Meurer
2014/09/02 19:00:33
Nit: method should be const
| |
213 | |
185 // Get the frame offset for a given spill slot. The location depends on the | 214 // Get the frame offset for a given spill slot. The location depends on the |
186 // calling convention and the specific frame layout, and may thus be | 215 // calling convention and the specific frame layout, and may thus be |
187 // architecture-specific. Negative spill slots indicate arguments on the | 216 // architecture-specific. Negative spill slots indicate arguments on the |
188 // caller's frame. The {extra} parameter indicates an additional offset from | 217 // caller's frame. The {extra} parameter indicates an additional offset from |
189 // the frame offset, e.g. to index into part of a double slot. | 218 // the frame offset, e.g. to index into part of a double slot. |
190 FrameOffset GetFrameOffset(int spill_slot, Frame* frame, int extra = 0); | 219 FrameOffset GetFrameOffset(int spill_slot, Frame* frame, int extra = 0); |
191 | 220 |
192 CompilationInfo* info() const { return info_; } | 221 CompilationInfo* info() const { return info_; } |
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 |