Chromium Code Reviews| Index: src/compiler/linkage-impl.h |
| diff --git a/src/compiler/linkage-impl.h b/src/compiler/linkage-impl.h |
| index 88cf125540fae3101b5388e26f904966ced4f3fd..4b1c77914722a58b5e3f223da3fce2c8f9ec6dcc 100644 |
| --- a/src/compiler/linkage-impl.h |
| +++ b/src/compiler/linkage-impl.h |
| @@ -9,190 +9,211 @@ namespace v8 { |
| namespace internal { |
| namespace compiler { |
| +template <typename LinkageTraits> |
| class LinkageHelper { |
| public: |
| - static LinkageLocation TaggedStackSlot(int index) { |
| - DCHECK(index < 0); |
| - return LinkageLocation(kMachAnyTagged, index); |
| - } |
| - |
| - static LinkageLocation TaggedRegisterLocation(Register reg) { |
| - return LinkageLocation(kMachAnyTagged, Register::ToAllocationIndex(reg)); |
| - } |
| - |
| - static inline LinkageLocation WordRegisterLocation(Register reg) { |
| - return LinkageLocation(kMachPtr, Register::ToAllocationIndex(reg)); |
| - } |
| + static const RegList kNoCalleeSaved = 0; |
| - static LinkageLocation UnconstrainedRegister(MachineType rep) { |
| - return LinkageLocation(rep, LinkageLocation::ANY_REGISTER); |
| + static void AddReturnLocations(LocationSignature::Builder* locations) { |
| + DCHECK(locations->return_count_ <= 2); |
| + if (locations->return_count_ > 0) { |
| + locations->AddReturn(regloc(LinkageTraits::ReturnValueReg())); |
| + } |
| + if (locations->return_count_ > 1) { |
| + locations->AddReturn(regloc(LinkageTraits::ReturnValue2Reg())); |
| + } |
| } |
| - 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); |
| + static CallDescriptor* GetJSCallDescriptor(Zone* zone, |
| + int js_parameter_count) { |
|
Benedikt Meurer
2014/09/02 19:00:33
size_t
|
| + const size_t return_count = 1; |
| + const size_t context_count = 1; |
| + const size_t parameter_count = js_parameter_count + context_count; |
| + |
| + LocationSignature::Builder locations(zone, return_count, parameter_count); |
| + MachineSignature::Builder types(zone, return_count, parameter_count); |
| + |
| + // Add returns. |
| + AddReturnLocations(&locations); |
| + for (size_t i = 0; i < return_count; i++) { |
| + types.AddReturn(kMachAnyTagged); |
| } |
| - 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::kNeedsFrameState); // flags |
| + // All parameters to JS calls go on the stack. |
| + for (int i = 0; i < js_parameter_count; i++) { |
|
Benedikt Meurer
2014/09/02 19:00:33
size_t
|
| + int spill_slot_index = i - js_parameter_count; |
| + locations.AddParam(stackloc(spill_slot_index)); |
| + types.AddParam(kMachAnyTagged); |
| + } |
| + // Add context. |
| + locations.AddParam(regloc(LinkageTraits::ContextReg())); |
| + types.AddParam(kMachAnyTagged); |
| + |
| + // The target for JS function calls is the JSFunction object. |
| + MachineType target_type = kMachAnyTagged; |
| + LinkageLocation target_loc = regloc(LinkageTraits::JSCallFunctionReg()); |
| + return new (zone) CallDescriptor(CallDescriptor::kCallJSFunction, // kind |
| + target_type, // target MachineType |
| + target_loc, // target location |
| + types.Build(), // machine_sig |
| + locations.Build(), // location_sig |
| + js_parameter_count, // js_parameter_count |
| + Operator::kNoProperties, // properties |
| + kNoCalleeSaved, // callee-saved |
| + CallDescriptor::kNeedsFrameState, // flags |
| + "js-call"); |
| } |
| // TODO(turbofan): cache call descriptors for runtime calls. |
| - template <typename LinkageTraits> |
| static CallDescriptor* GetRuntimeCallDescriptor( |
| - Zone* zone, Runtime::FunctionId function_id, int parameter_count, |
| + Zone* zone, Runtime::FunctionId function_id, int js_parameter_count, |
|
Benedikt Meurer
2014/09/02 19:00:33
size_t
|
| Operator::Property properties, CallDescriptor::Flags flags) { |
| - 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 size_t function_count = 1; |
| + const size_t num_args_count = 1; |
| + const size_t context_count = 1; |
| + const size_t parameter_count = |
| + js_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()); |
| - } |
| + const size_t return_count = function->result_size; |
| - DCHECK_LE(return_count, 2); |
| + LocationSignature::Builder locations(zone, return_count, parameter_count); |
| + MachineSignature::Builder types(zone, return_count, parameter_count); |
| - locations[index++] = UnconstrainedRegister(kMachAnyTagged); // CEntryStub |
| + // Add returns. |
| + AddReturnLocations(&locations); |
| + for (size_t i = 0; i < return_count; i++) { |
| + types.AddReturn(kMachAnyTagged); |
| + } |
| - 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); |
| + // All parameters to the runtime call go on the stack. |
| + for (int i = 0; i < js_parameter_count; i++) { |
| + locations.AddParam(stackloc(i - js_parameter_count)); |
| + types.AddParam(kMachAnyTagged); |
| } |
| - locations[index++] = |
| - TaggedRegisterLocation(LinkageTraits::RuntimeCallFunctionReg()); |
| - locations[index++] = |
| - WordRegisterLocation(LinkageTraits::RuntimeCallArgCountReg()); |
| - locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg()); |
| + // Add runtime function itself. |
| + locations.AddParam(regloc(LinkageTraits::RuntimeCallFunctionReg())); |
| + types.AddParam(kMachAnyTagged); |
| + |
| + // Add runtime call argument count. |
| + locations.AddParam(regloc(LinkageTraits::RuntimeCallArgCountReg())); |
| + types.AddParam(kMachPtr); |
| - // TODO(titzer): refactor TurboFan graph to consider context a value input. |
| + // Add context. |
| + locations.AddParam(regloc(LinkageTraits::ContextReg())); |
| + types.AddParam(kMachAnyTagged); |
| + |
| + // The target for runtime calls is a code object. |
| + MachineType target_type = kMachAnyTagged; |
| + LinkageLocation target_loc = LinkageLocation::AnyRegister(); |
| 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 |
| - flags, // flags |
| - function->name); |
| + target_type, // target MachineType |
| + target_loc, // target location |
| + types.Build(), // machine_sig |
| + locations.Build(), // location_sig |
| + js_parameter_count, // js_parameter_count |
| + properties, // properties |
| + kNoCalleeSaved, // callee-saved |
| + flags, // flags |
| + function->name); // debug name |
| } |
| // TODO(turbofan): cache call descriptors for code stub calls. |
| - template <typename LinkageTraits> |
| static CallDescriptor* GetStubCallDescriptor( |
| Zone* zone, CodeStubInterfaceDescriptor* descriptor, |
| int stack_parameter_count, CallDescriptor::Flags flags) { |
| - 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(kMachAnyTagged); // code |
| - for (int i = 0; i < parameter_count; i++) { |
| + size_t register_parameter_count = |
| + descriptor->GetEnvironmentParameterCount(); |
| + size_t js_parameter_count = |
| + register_parameter_count + stack_parameter_count; |
| + const size_t context_count = 1; |
| + size_t parameter_count = js_parameter_count + context_count; |
| + size_t return_count = 1; |
| + LocationSignature::Builder locations(zone, return_count, parameter_count); |
| + MachineSignature::Builder types(zone, return_count, parameter_count); |
| + |
| + // Add return location. |
| + AddReturnLocations(&locations); |
| + for (size_t i = 0; i < return_count; i++) { |
| + types.AddReturn(kMachAnyTagged); |
| + } |
| + |
| + // Add parameters in registers and on the stack. |
| + for (size_t i = 0; i < js_parameter_count; i++) { |
| if (i < register_parameter_count) { |
| - // The first parameters to code stub calls go in registers. |
| + // The first parameters go in registers. |
| Register reg = descriptor->GetEnvironmentParameterRegister(i); |
| - locations[index++] = TaggedRegisterLocation(reg); |
| + locations.AddParam(regloc(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.AddParam(stackloc(stack_slot)); |
| } |
| + types.AddParam(kMachAnyTagged); |
| } |
| - locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg()); |
| + // Add context. |
| + locations.AddParam(regloc(LinkageTraits::ContextReg())); |
| + types.AddParam(kMachAnyTagged); |
| - // TODO(titzer): refactor TurboFan graph to consider context a value input. |
| + // The target for stub calls is a code object. |
| + MachineType target_type = kMachAnyTagged; |
| + LinkageLocation target_loc = LinkageLocation::AnyRegister(); |
| return new (zone) |
| CallDescriptor(CallDescriptor::kCallCodeObject, // kind |
| - return_count, // return_count |
| - parameter_count, // parameter_count |
| - input_count, // input_count |
| - locations, // locations |
| + target_type, // target MachineType |
| + target_loc, // target location |
| + types.Build(), // machine_sig |
| + locations.Build(), // location_sig |
| + js_parameter_count, // js_parameter_count |
| Operator::kNoProperties, // properties |
| kNoCalleeSaved, // callee-saved registers |
| flags, // flags |
| CodeStub::MajorName(descriptor->MajorKey(), false)); |
| } |
| + static CallDescriptor* GetSimplifiedCDescriptor(Zone* zone, |
| + MachineSignature* msig) { |
| + const size_t return_count = msig->return_count(); |
| + const size_t parameter_count = msig->parameter_count(); |
| - template <typename LinkageTraits> |
| - static CallDescriptor* GetSimplifiedCDescriptor( |
| - Zone* zone, int num_params, MachineType return_type, |
| - const MachineType* param_types) { |
| - LinkageLocation* locations = |
| - zone->NewArray<LinkageLocation>(num_params + 2); |
| - int index = 0; |
| - locations[index++] = |
| - TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); |
| - locations[index++] = LinkageHelper::UnconstrainedRegister(kMachPtr); |
| - // 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); |
| + LocationSignature::Builder locations(zone, return_count, parameter_count); |
| + |
| + // Add return location(s). |
| + AddReturnLocations(&locations); |
| + |
| + // Add register and/or stack parameter(s). |
| + for (size_t i = 0; i < parameter_count; i++) { |
| + if (static_cast<int>(i) < LinkageTraits::CRegisterParametersLength()) { |
| + locations.AddParam(regloc(LinkageTraits::CRegisterParameter(i))); |
| + } else { |
| + locations.AddParam(stackloc(-1 - i)); |
| + } |
| } |
| - return new (zone) CallDescriptor( |
| - CallDescriptor::kCallAddress, 1, num_params, num_params + 1, locations, |
| - Operator::kNoProperties, LinkageTraits::CCalleeSaveRegisters(), |
| - CallDescriptor::kNoFlags); // TODO(jarin) should deoptimize! |
| + |
| + // The target for C calls is always an address (i.e. machine pointer). |
| + MachineType target_type = kMachPtr; |
| + LinkageLocation target_loc = LinkageLocation::AnyRegister(); |
| + return new (zone) CallDescriptor(CallDescriptor::kCallAddress, // kind |
| + target_type, // target MachineType |
| + target_loc, // target location |
| + msig, // machine_sig |
| + locations.Build(), // location_sig |
| + 0, // js_parameter_count |
| + Operator::kNoProperties, // properties |
| + LinkageTraits::CCalleeSaveRegisters(), |
| + CallDescriptor::kNoFlags, "c-call"); |
| + } |
| + |
| + static LinkageLocation regloc(Register reg) { |
| + return LinkageLocation(Register::ToAllocationIndex(reg)); |
| + } |
| + |
| + static LinkageLocation stackloc(int i) { |
| + DCHECK_LT(i, 0); |
| + return LinkageLocation(i); |
| } |
| }; |