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