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_IMPL_H_ |
| 6 #define V8_COMPILER_LINKAGE_IMPL_H_ |
| 7 |
| 8 namespace v8 { |
| 9 namespace internal { |
| 10 namespace compiler { |
| 11 |
| 12 class LinkageHelper { |
| 13 public: |
| 14 static LinkageLocation TaggedStackSlot(int index) { |
| 15 ASSERT(index < 0); |
| 16 return LinkageLocation(kMachineTagged, index); |
| 17 } |
| 18 |
| 19 static LinkageLocation TaggedRegisterLocation(Register reg) { |
| 20 return LinkageLocation(kMachineTagged, Register::ToAllocationIndex(reg)); |
| 21 } |
| 22 |
| 23 static inline LinkageLocation WordRegisterLocation(Register reg) { |
| 24 return LinkageLocation(MachineOperatorBuilder::pointer_rep(), |
| 25 Register::ToAllocationIndex(reg)); |
| 26 } |
| 27 |
| 28 static LinkageLocation UnconstrainedRegister(MachineRepresentation rep) { |
| 29 return LinkageLocation(rep, LinkageLocation::ANY_REGISTER); |
| 30 } |
| 31 |
| 32 static const RegList kNoCalleeSaved = 0; |
| 33 |
| 34 // TODO(turbofan): cache call descriptors for JSFunction calls. |
| 35 template <typename LinkageTraits> |
| 36 static CallDescriptor* GetJSCallDescriptor(Zone* zone, int parameter_count) { |
| 37 const int jsfunction_count = 1; |
| 38 const int context_count = 1; |
| 39 int input_count = jsfunction_count + parameter_count + context_count; |
| 40 |
| 41 const int return_count = 1; |
| 42 LinkageLocation* locations = |
| 43 zone->NewArray<LinkageLocation>(return_count + input_count); |
| 44 |
| 45 int index = 0; |
| 46 locations[index++] = |
| 47 TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); |
| 48 locations[index++] = |
| 49 TaggedRegisterLocation(LinkageTraits::JSCallFunctionReg()); |
| 50 |
| 51 for (int i = 0; i < parameter_count; i++) { |
| 52 // All parameters to JS calls go on the stack. |
| 53 int spill_slot_index = i - parameter_count; |
| 54 locations[index++] = TaggedStackSlot(spill_slot_index); |
| 55 } |
| 56 locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg()); |
| 57 |
| 58 // TODO(titzer): refactor TurboFan graph to consider context a value input. |
| 59 return new (zone) |
| 60 CallDescriptor(CallDescriptor::kCallJSFunction, // kind |
| 61 return_count, // return_count |
| 62 parameter_count, // parameter_count |
| 63 input_count - context_count, // input_count |
| 64 locations, // locations |
| 65 Operator::kNoProperties, // properties |
| 66 kNoCalleeSaved, // callee-saved registers |
| 67 CallDescriptor::kCanDeoptimize); // deoptimization |
| 68 } |
| 69 |
| 70 |
| 71 // TODO(turbofan): cache call descriptors for runtime calls. |
| 72 template <typename LinkageTraits> |
| 73 static CallDescriptor* GetRuntimeCallDescriptor( |
| 74 Zone* zone, Runtime::FunctionId function_id, int parameter_count, |
| 75 Operator::Property properties, |
| 76 CallDescriptor::DeoptimizationSupport can_deoptimize) { |
| 77 const int code_count = 1; |
| 78 const int function_count = 1; |
| 79 const int num_args_count = 1; |
| 80 const int context_count = 1; |
| 81 const int input_count = code_count + parameter_count + function_count + |
| 82 num_args_count + context_count; |
| 83 |
| 84 const Runtime::Function* function = Runtime::FunctionForId(function_id); |
| 85 const int return_count = function->result_size; |
| 86 LinkageLocation* locations = |
| 87 zone->NewArray<LinkageLocation>(return_count + input_count); |
| 88 |
| 89 int index = 0; |
| 90 if (return_count > 0) { |
| 91 locations[index++] = |
| 92 TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); |
| 93 } |
| 94 if (return_count > 1) { |
| 95 locations[index++] = |
| 96 TaggedRegisterLocation(LinkageTraits::ReturnValue2Reg()); |
| 97 } |
| 98 |
| 99 ASSERT_LE(return_count, 2); |
| 100 |
| 101 locations[index++] = UnconstrainedRegister(kMachineTagged); // CEntryStub |
| 102 |
| 103 for (int i = 0; i < parameter_count; i++) { |
| 104 // All parameters to runtime calls go on the stack. |
| 105 int spill_slot_index = i - parameter_count; |
| 106 locations[index++] = TaggedStackSlot(spill_slot_index); |
| 107 } |
| 108 locations[index++] = |
| 109 TaggedRegisterLocation(LinkageTraits::RuntimeCallFunctionReg()); |
| 110 locations[index++] = |
| 111 WordRegisterLocation(LinkageTraits::RuntimeCallArgCountReg()); |
| 112 locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg()); |
| 113 |
| 114 // TODO(titzer): refactor TurboFan graph to consider context a value input. |
| 115 return new (zone) CallDescriptor(CallDescriptor::kCallCodeObject, // kind |
| 116 return_count, // return_count |
| 117 parameter_count, // parameter_count |
| 118 input_count, // input_count |
| 119 locations, // locations |
| 120 properties, // properties |
| 121 kNoCalleeSaved, // callee-saved registers |
| 122 can_deoptimize, // deoptimization |
| 123 function->name); |
| 124 } |
| 125 |
| 126 |
| 127 // TODO(turbofan): cache call descriptors for code stub calls. |
| 128 template <typename LinkageTraits> |
| 129 static CallDescriptor* GetStubCallDescriptor( |
| 130 Zone* zone, CodeStubInterfaceDescriptor* descriptor, |
| 131 int stack_parameter_count) { |
| 132 int register_parameter_count = descriptor->GetEnvironmentParameterCount(); |
| 133 int parameter_count = register_parameter_count + stack_parameter_count; |
| 134 const int code_count = 1; |
| 135 const int context_count = 1; |
| 136 int input_count = code_count + parameter_count + context_count; |
| 137 |
| 138 const int return_count = 1; |
| 139 LinkageLocation* locations = |
| 140 zone->NewArray<LinkageLocation>(return_count + input_count); |
| 141 |
| 142 int index = 0; |
| 143 locations[index++] = |
| 144 TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); |
| 145 locations[index++] = UnconstrainedRegister(kMachineTagged); // code |
| 146 for (int i = 0; i < parameter_count; i++) { |
| 147 if (i < register_parameter_count) { |
| 148 // The first parameters to code stub calls go in registers. |
| 149 Register reg = descriptor->GetEnvironmentParameterRegister(i); |
| 150 locations[index++] = TaggedRegisterLocation(reg); |
| 151 } else { |
| 152 // The rest of the parameters go on the stack. |
| 153 int stack_slot = i - register_parameter_count - stack_parameter_count; |
| 154 locations[index++] = TaggedStackSlot(stack_slot); |
| 155 } |
| 156 } |
| 157 locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg()); |
| 158 |
| 159 // TODO(titzer): refactor TurboFan graph to consider context a value input. |
| 160 return new (zone) |
| 161 CallDescriptor(CallDescriptor::kCallCodeObject, // kind |
| 162 return_count, // return_count |
| 163 parameter_count, // parameter_count |
| 164 input_count, // input_count |
| 165 locations, // locations |
| 166 Operator::kNoProperties, // properties |
| 167 kNoCalleeSaved, // callee-saved registers |
| 168 CallDescriptor::kCannotDeoptimize, // deoptimization |
| 169 CodeStub::MajorName(descriptor->MajorKey(), false)); |
| 170 // TODO(jarin) should deoptimize! |
| 171 } |
| 172 |
| 173 |
| 174 template <typename LinkageTraits> |
| 175 static CallDescriptor* GetSimplifiedCDescriptor( |
| 176 Zone* zone, int num_params, MachineRepresentation return_type, |
| 177 const MachineRepresentation* param_types) { |
| 178 LinkageLocation* locations = |
| 179 zone->NewArray<LinkageLocation>(num_params + 2); |
| 180 int index = 0; |
| 181 locations[index++] = |
| 182 TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); |
| 183 locations[index++] = LinkageHelper::UnconstrainedRegister( |
| 184 MachineOperatorBuilder::pointer_rep()); |
| 185 // TODO(dcarney): test with lots of parameters. |
| 186 int i = 0; |
| 187 for (; i < LinkageTraits::CRegisterParametersLength() && i < num_params; |
| 188 i++) { |
| 189 locations[index++] = LinkageLocation( |
| 190 param_types[i], |
| 191 Register::ToAllocationIndex(LinkageTraits::CRegisterParameter(i))); |
| 192 } |
| 193 for (; i < num_params; i++) { |
| 194 locations[index++] = LinkageLocation(param_types[i], -1 - i); |
| 195 } |
| 196 return new (zone) CallDescriptor( |
| 197 CallDescriptor::kCallAddress, 1, num_params, num_params + 1, locations, |
| 198 Operator::kNoProperties, LinkageTraits::CCalleeSaveRegisters(), |
| 199 CallDescriptor::kCannotDeoptimize); // TODO(jarin) should deoptimize! |
| 200 } |
| 201 }; |
| 202 } |
| 203 } |
| 204 } // namespace v8::internal::compiler |
| 205 |
| 206 #endif // V8_COMPILER_LINKAGE_IMPL_H_ |
OLD | NEW |