| 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 |