Index: src/compiler/linkage-impl.h |
diff --git a/src/compiler/linkage-impl.h b/src/compiler/linkage-impl.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7159bde59b0d64efdaf4d91b11c83376a81c4838 |
--- /dev/null |
+++ b/src/compiler/linkage-impl.h |
@@ -0,0 +1,206 @@ |
+// Copyright 2014 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef V8_COMPILER_LINKAGE_IMPL_H_ |
+#define V8_COMPILER_LINKAGE_IMPL_H_ |
+ |
+namespace v8 { |
+namespace internal { |
+namespace compiler { |
+ |
+class LinkageHelper { |
+ public: |
+ static LinkageLocation TaggedStackSlot(int index) { |
+ ASSERT(index < 0); |
+ return LinkageLocation(kMachineTagged, index); |
+ } |
+ |
+ static LinkageLocation TaggedRegisterLocation(Register reg) { |
+ return LinkageLocation(kMachineTagged, Register::ToAllocationIndex(reg)); |
+ } |
+ |
+ static inline LinkageLocation WordRegisterLocation(Register reg) { |
+ return LinkageLocation(MachineOperatorBuilder::pointer_rep(), |
+ Register::ToAllocationIndex(reg)); |
+ } |
+ |
+ static LinkageLocation UnconstrainedRegister(MachineRepresentation rep) { |
+ return LinkageLocation(rep, LinkageLocation::ANY_REGISTER); |
+ } |
+ |
+ static const RegList kNoCalleeSaved = 0; |
+ |
+ // TODO(turbofan): cache call descriptors for JSFunction calls. |
+ template <typename LinkageTraits> |
+ static CallDescriptor* GetJSCallDescriptor(Zone* zone, int parameter_count) { |
+ const int jsfunction_count = 1; |
+ const int context_count = 1; |
+ int input_count = jsfunction_count + parameter_count + context_count; |
+ |
+ const int return_count = 1; |
+ LinkageLocation* locations = |
+ zone->NewArray<LinkageLocation>(return_count + input_count); |
+ |
+ int index = 0; |
+ locations[index++] = |
+ TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); |
+ locations[index++] = |
+ TaggedRegisterLocation(LinkageTraits::JSCallFunctionReg()); |
+ |
+ for (int i = 0; i < parameter_count; i++) { |
+ // All parameters to JS calls go on the stack. |
+ int spill_slot_index = i - parameter_count; |
+ locations[index++] = TaggedStackSlot(spill_slot_index); |
+ } |
+ locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg()); |
+ |
+ // TODO(titzer): refactor TurboFan graph to consider context a value input. |
+ return new (zone) |
+ CallDescriptor(CallDescriptor::kCallJSFunction, // kind |
+ return_count, // return_count |
+ parameter_count, // parameter_count |
+ input_count - context_count, // input_count |
+ locations, // locations |
+ Operator::kNoProperties, // properties |
+ kNoCalleeSaved, // callee-saved registers |
+ CallDescriptor::kCanDeoptimize); // deoptimization |
+ } |
+ |
+ |
+ // TODO(turbofan): cache call descriptors for runtime calls. |
+ template <typename LinkageTraits> |
+ static CallDescriptor* GetRuntimeCallDescriptor( |
+ Zone* zone, Runtime::FunctionId function_id, int parameter_count, |
+ Operator::Property properties, |
+ CallDescriptor::DeoptimizationSupport can_deoptimize) { |
+ const int code_count = 1; |
+ const int function_count = 1; |
+ const int num_args_count = 1; |
+ const int context_count = 1; |
+ const int input_count = code_count + parameter_count + function_count + |
+ num_args_count + context_count; |
+ |
+ const Runtime::Function* function = Runtime::FunctionForId(function_id); |
+ const int return_count = function->result_size; |
+ LinkageLocation* locations = |
+ zone->NewArray<LinkageLocation>(return_count + input_count); |
+ |
+ int index = 0; |
+ if (return_count > 0) { |
+ locations[index++] = |
+ TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); |
+ } |
+ if (return_count > 1) { |
+ locations[index++] = |
+ TaggedRegisterLocation(LinkageTraits::ReturnValue2Reg()); |
+ } |
+ |
+ ASSERT_LE(return_count, 2); |
+ |
+ locations[index++] = UnconstrainedRegister(kMachineTagged); // CEntryStub |
+ |
+ for (int i = 0; i < parameter_count; i++) { |
+ // All parameters to runtime calls go on the stack. |
+ int spill_slot_index = i - parameter_count; |
+ locations[index++] = TaggedStackSlot(spill_slot_index); |
+ } |
+ locations[index++] = |
+ TaggedRegisterLocation(LinkageTraits::RuntimeCallFunctionReg()); |
+ locations[index++] = |
+ WordRegisterLocation(LinkageTraits::RuntimeCallArgCountReg()); |
+ locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg()); |
+ |
+ // TODO(titzer): refactor TurboFan graph to consider context a value input. |
+ return new (zone) CallDescriptor(CallDescriptor::kCallCodeObject, // kind |
+ return_count, // return_count |
+ parameter_count, // parameter_count |
+ input_count, // input_count |
+ locations, // locations |
+ properties, // properties |
+ kNoCalleeSaved, // callee-saved registers |
+ can_deoptimize, // deoptimization |
+ function->name); |
+ } |
+ |
+ |
+ // TODO(turbofan): cache call descriptors for code stub calls. |
+ template <typename LinkageTraits> |
+ static CallDescriptor* GetStubCallDescriptor( |
+ Zone* zone, CodeStubInterfaceDescriptor* descriptor, |
+ int stack_parameter_count) { |
+ int register_parameter_count = descriptor->GetEnvironmentParameterCount(); |
+ int parameter_count = register_parameter_count + stack_parameter_count; |
+ const int code_count = 1; |
+ const int context_count = 1; |
+ int input_count = code_count + parameter_count + context_count; |
+ |
+ const int return_count = 1; |
+ LinkageLocation* locations = |
+ zone->NewArray<LinkageLocation>(return_count + input_count); |
+ |
+ int index = 0; |
+ locations[index++] = |
+ TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); |
+ locations[index++] = UnconstrainedRegister(kMachineTagged); // code |
+ for (int i = 0; i < parameter_count; i++) { |
+ if (i < register_parameter_count) { |
+ // The first parameters to code stub calls go in registers. |
+ Register reg = descriptor->GetEnvironmentParameterRegister(i); |
+ locations[index++] = TaggedRegisterLocation(reg); |
+ } else { |
+ // The rest of the parameters go on the stack. |
+ int stack_slot = i - register_parameter_count - stack_parameter_count; |
+ locations[index++] = TaggedStackSlot(stack_slot); |
+ } |
+ } |
+ locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg()); |
+ |
+ // TODO(titzer): refactor TurboFan graph to consider context a value input. |
+ return new (zone) |
+ CallDescriptor(CallDescriptor::kCallCodeObject, // kind |
+ return_count, // return_count |
+ parameter_count, // parameter_count |
+ input_count, // input_count |
+ locations, // locations |
+ Operator::kNoProperties, // properties |
+ kNoCalleeSaved, // callee-saved registers |
+ CallDescriptor::kCannotDeoptimize, // deoptimization |
+ CodeStub::MajorName(descriptor->MajorKey(), false)); |
+ // TODO(jarin) should deoptimize! |
+ } |
+ |
+ |
+ template <typename LinkageTraits> |
+ static CallDescriptor* GetSimplifiedCDescriptor( |
+ Zone* zone, int num_params, MachineRepresentation return_type, |
+ const MachineRepresentation* param_types) { |
+ LinkageLocation* locations = |
+ zone->NewArray<LinkageLocation>(num_params + 2); |
+ int index = 0; |
+ locations[index++] = |
+ TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); |
+ locations[index++] = LinkageHelper::UnconstrainedRegister( |
+ MachineOperatorBuilder::pointer_rep()); |
+ // TODO(dcarney): test with lots of parameters. |
+ int i = 0; |
+ for (; i < LinkageTraits::CRegisterParametersLength() && i < num_params; |
+ i++) { |
+ locations[index++] = LinkageLocation( |
+ param_types[i], |
+ Register::ToAllocationIndex(LinkageTraits::CRegisterParameter(i))); |
+ } |
+ for (; i < num_params; i++) { |
+ locations[index++] = LinkageLocation(param_types[i], -1 - i); |
+ } |
+ return new (zone) CallDescriptor( |
+ CallDescriptor::kCallAddress, 1, num_params, num_params + 1, locations, |
+ Operator::kNoProperties, LinkageTraits::CCalleeSaveRegisters(), |
+ CallDescriptor::kCannotDeoptimize); // TODO(jarin) should deoptimize! |
+ } |
+}; |
+} |
+} |
+} // namespace v8::internal::compiler |
+ |
+#endif // V8_COMPILER_LINKAGE_IMPL_H_ |