OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef V8_COMPILER_LINKAGE_H_ |
| 6 #define V8_COMPILER_LINKAGE_H_ |
| 7 |
| 8 #include "src/v8.h" |
| 9 |
| 10 #include "src/code-stubs.h" |
| 11 #include "src/compiler/frame.h" |
| 12 #include "src/compiler/machine-operator.h" |
| 13 #include "src/compiler/node.h" |
| 14 #include "src/compiler/operator.h" |
| 15 #include "src/zone.h" |
| 16 |
| 17 namespace v8 { |
| 18 namespace internal { |
| 19 namespace compiler { |
| 20 |
| 21 // Describes the location for a parameter or a return value to a call. |
| 22 // TODO(titzer): replace with Radium locations when they are ready. |
| 23 class LinkageLocation { |
| 24 public: |
| 25 LinkageLocation(MachineRepresentation rep, int location) |
| 26 : rep_(rep), location_(location) {} |
| 27 |
| 28 inline MachineRepresentation representation() const { return rep_; } |
| 29 |
| 30 static const int16_t ANY_REGISTER = 32767; |
| 31 |
| 32 private: |
| 33 friend class CallDescriptor; |
| 34 friend class OperandGenerator; |
| 35 MachineRepresentation rep_; |
| 36 int16_t location_; // >= 0 implies register, otherwise stack slot. |
| 37 }; |
| 38 |
| 39 |
| 40 class CallDescriptor : public ZoneObject { |
| 41 public: |
| 42 // Describes whether the first parameter is a code object, a JSFunction, |
| 43 // or an address--all of which require different machine sequences to call. |
| 44 enum Kind { kCallCodeObject, kCallJSFunction, kCallAddress }; |
| 45 |
| 46 enum DeoptimizationSupport { kCanDeoptimize, kCannotDeoptimize }; |
| 47 |
| 48 CallDescriptor(Kind kind, int8_t return_count, int16_t parameter_count, |
| 49 int16_t input_count, LinkageLocation* locations, |
| 50 Operator::Property properties, RegList callee_saved_registers, |
| 51 DeoptimizationSupport deoptimization_support, |
| 52 const char* debug_name = "") |
| 53 : kind_(kind), |
| 54 return_count_(return_count), |
| 55 parameter_count_(parameter_count), |
| 56 input_count_(input_count), |
| 57 locations_(locations), |
| 58 properties_(properties), |
| 59 callee_saved_registers_(callee_saved_registers), |
| 60 deoptimization_support_(deoptimization_support), |
| 61 debug_name_(debug_name) {} |
| 62 // Returns the kind of this call. |
| 63 Kind kind() const { return kind_; } |
| 64 |
| 65 // Returns {true} if this descriptor is a call to a JSFunction. |
| 66 bool IsJSFunctionCall() const { return kind_ == kCallJSFunction; } |
| 67 |
| 68 // The number of return values from this call, usually 0 or 1. |
| 69 int ReturnCount() const { return return_count_; } |
| 70 |
| 71 // The number of JavaScript parameters to this call, including receiver, |
| 72 // but not the context. |
| 73 int ParameterCount() const { return parameter_count_; } |
| 74 |
| 75 int InputCount() const { return input_count_; } |
| 76 |
| 77 bool CanLazilyDeoptimize() const { |
| 78 return deoptimization_support_ == kCanDeoptimize; |
| 79 } |
| 80 |
| 81 LinkageLocation GetReturnLocation(int index) { |
| 82 ASSERT(index < return_count_); |
| 83 return locations_[0 + index]; // return locations start at 0. |
| 84 } |
| 85 |
| 86 LinkageLocation GetInputLocation(int index) { |
| 87 ASSERT(index < input_count_ + 1); // input_count + 1 is the context. |
| 88 return locations_[return_count_ + index]; // inputs start after returns. |
| 89 } |
| 90 |
| 91 // Operator properties describe how this call can be optimized, if at all. |
| 92 Operator::Property properties() const { return properties_; } |
| 93 |
| 94 // Get the callee-saved registers, if any, across this call. |
| 95 RegList CalleeSavedRegisters() { return callee_saved_registers_; } |
| 96 |
| 97 const char* debug_name() const { return debug_name_; } |
| 98 |
| 99 private: |
| 100 friend class Linkage; |
| 101 |
| 102 Kind kind_; |
| 103 int8_t return_count_; |
| 104 int16_t parameter_count_; |
| 105 int16_t input_count_; |
| 106 LinkageLocation* locations_; |
| 107 Operator::Property properties_; |
| 108 RegList callee_saved_registers_; |
| 109 DeoptimizationSupport deoptimization_support_; |
| 110 const char* debug_name_; |
| 111 }; |
| 112 |
| 113 OStream& operator<<(OStream& os, const CallDescriptor& d); |
| 114 OStream& operator<<(OStream& os, const CallDescriptor::Kind& k); |
| 115 |
| 116 // Defines the linkage for a compilation, including the calling conventions |
| 117 // for incoming parameters and return value(s) as well as the outgoing calling |
| 118 // convention for any kind of call. Linkage is generally architecture-specific. |
| 119 // |
| 120 // Can be used to translate {arg_index} (i.e. index of the call node input) as |
| 121 // well as {param_index} (i.e. as stored in parameter nodes) into an operator |
| 122 // representing the architecture-specific location. The following call node |
| 123 // layouts are supported (where {n} is the number value inputs): |
| 124 // |
| 125 // #0 #1 #2 #3 [...] #n |
| 126 // Call[CodeStub] code, arg 1, arg 2, arg 3, [...], context |
| 127 // Call[JSFunction] function, rcvr, arg 1, arg 2, [...], context |
| 128 // Call[Runtime] CEntryStub, arg 1, arg 2, arg 3, [...], fun, #arg, context |
| 129 class Linkage : public ZoneObject { |
| 130 public: |
| 131 explicit Linkage(CompilationInfo* info); |
| 132 explicit Linkage(CompilationInfo* info, CallDescriptor* incoming) |
| 133 : info_(info), incoming_(incoming) {} |
| 134 |
| 135 // The call descriptor for this compilation unit describes the locations |
| 136 // of incoming parameters and the outgoing return value(s). |
| 137 CallDescriptor* GetIncomingDescriptor() { return incoming_; } |
| 138 CallDescriptor* GetJSCallDescriptor(int parameter_count); |
| 139 static CallDescriptor* GetJSCallDescriptor(int parameter_count, Zone* zone); |
| 140 CallDescriptor* GetRuntimeCallDescriptor( |
| 141 Runtime::FunctionId function, int parameter_count, |
| 142 Operator::Property properties, |
| 143 CallDescriptor::DeoptimizationSupport can_deoptimize = |
| 144 CallDescriptor::kCannotDeoptimize); |
| 145 static CallDescriptor* GetRuntimeCallDescriptor( |
| 146 Runtime::FunctionId function, int parameter_count, |
| 147 Operator::Property properties, |
| 148 CallDescriptor::DeoptimizationSupport can_deoptimize, Zone* zone); |
| 149 |
| 150 CallDescriptor* GetStubCallDescriptor(CodeStubInterfaceDescriptor* descriptor, |
| 151 int stack_parameter_count = 0); |
| 152 |
| 153 // Creates a call descriptor for simplified C calls that is appropriate |
| 154 // for the host platform. This simplified calling convention only supports |
| 155 // integers and pointers of one word size each, i.e. no floating point, |
| 156 // structs, pointers to members, etc. |
| 157 static CallDescriptor* GetSimplifiedCDescriptor( |
| 158 Zone* zone, int num_params, MachineRepresentation return_type, |
| 159 const MachineRepresentation* param_types); |
| 160 |
| 161 // Get the location of an (incoming) parameter to this function. |
| 162 LinkageLocation GetParameterLocation(int index) { |
| 163 return incoming_->GetInputLocation(index + 1); |
| 164 } |
| 165 |
| 166 // Get the location where this function should place its return value. |
| 167 LinkageLocation GetReturnLocation() { |
| 168 return incoming_->GetReturnLocation(0); |
| 169 } |
| 170 |
| 171 // Get the frame offset for a given spill slot. The location depends on the |
| 172 // calling convention and the specific frame layout, and may thus be |
| 173 // architecture-specific. Negative spill slots indicate arguments on the |
| 174 // caller's frame. The {extra} parameter indicates an additional offset from |
| 175 // the frame offset, e.g. to index into part of a double slot. |
| 176 FrameOffset GetFrameOffset(int spill_slot, Frame* frame, int extra = 0); |
| 177 |
| 178 CompilationInfo* info() const { return info_; } |
| 179 |
| 180 private: |
| 181 CompilationInfo* info_; |
| 182 CallDescriptor* incoming_; |
| 183 }; |
| 184 } |
| 185 } |
| 186 } // namespace v8::internal::compiler |
| 187 |
| 188 #endif // V8_COMPILER_LINKAGE_H_ |
OLD | NEW |