| Index: src/compiler/linkage-impl.h | 
| diff --git a/src/compiler/linkage-impl.h b/src/compiler/linkage-impl.h | 
| index 88cf125540fae3101b5388e26f904966ced4f3fd..3c3e0cb8ad19afd200c05a9b44c7dba566b325b2 100644 | 
| --- a/src/compiler/linkage-impl.h | 
| +++ b/src/compiler/linkage-impl.h | 
| @@ -9,190 +9,209 @@ 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_GE(locations->return_count_, 0); | 
| +    DCHECK_LE(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; | 
| +  static CallDescriptor* GetJSCallDescriptor(Zone* zone, int js_param_count) { | 
| +    const int return_count = 1; | 
| const int context_count = 1; | 
| -    int input_count = jsfunction_count + parameter_count + context_count; | 
| +    const int param_count = js_param_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); | 
| +    LocationSignature::Builder locations(zone, return_count, param_count); | 
| +    MachineSignature::Builder types(zone, return_count, param_count); | 
| + | 
| +    // Add returns. | 
| +    AddReturnLocations(&locations); | 
| +    for (int 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_param_count; i++) { | 
| +      int spill_slot_index = i - js_param_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_param_count,     // js_param_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_param_count, | 
| 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 int param_count = | 
| +        js_param_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()); | 
| +    LocationSignature::Builder locations(zone, return_count, param_count); | 
| +    MachineSignature::Builder types(zone, return_count, param_count); | 
| + | 
| +    // Add returns. | 
| +    AddReturnLocations(&locations); | 
| +    for (int i = 0; i < return_count; i++) { | 
| +      types.AddReturn(kMachAnyTagged); | 
| } | 
|  | 
| -    DCHECK_LE(return_count, 2); | 
| +    // All parameters to the runtime call go on the stack. | 
| +    for (int i = 0; i < js_param_count; i++) { | 
| +      locations.AddParam(stackloc(i - js_param_count)); | 
| +      types.AddParam(kMachAnyTagged); | 
| +    } | 
| +    // Add runtime function itself. | 
| +    locations.AddParam(regloc(LinkageTraits::RuntimeCallFunctionReg())); | 
| +    types.AddParam(kMachAnyTagged); | 
|  | 
| -    locations[index++] = UnconstrainedRegister(kMachAnyTagged);  // CEntryStub | 
| +    // Add runtime call argument count. | 
| +    locations.AddParam(regloc(LinkageTraits::RuntimeCallArgCountReg())); | 
| +    types.AddParam(kMachPtr); | 
|  | 
| -    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()); | 
| +    // Add context. | 
| +    locations.AddParam(regloc(LinkageTraits::ContextReg())); | 
| +    types.AddParam(kMachAnyTagged); | 
|  | 
| -    // TODO(titzer): refactor TurboFan graph to consider context a value input. | 
| +    // 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_param_count,     // js_param_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; | 
| +    int js_param_count = register_parameter_count + stack_parameter_count; | 
| const int context_count = 1; | 
| -    int input_count = code_count + parameter_count + context_count; | 
| +    int param_count = js_param_count + context_count; | 
| +    int return_count = 1; | 
| +    LocationSignature::Builder locations(zone, return_count, param_count); | 
| +    MachineSignature::Builder types(zone, return_count, param_count); | 
| + | 
| +    // Add return location. | 
| +    AddReturnLocations(&locations); | 
| +    for (int i = 0; i < return_count; i++) { | 
| +      types.AddReturn(kMachAnyTagged); | 
| +    } | 
|  | 
| -    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++) { | 
| +    // Add parameters in registers and on the stack. | 
| +    for (int i = 0; i < js_param_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_param_count,                   // js_param_count | 
| Operator::kNoProperties,          // properties | 
| kNoCalleeSaved,  // callee-saved registers | 
| flags,           // flags | 
| CodeStub::MajorName(descriptor->MajorKey(), false)); | 
| } | 
|  | 
| +  static CallDescriptor* GetSimplifiedCDescriptor(Zone* zone, | 
| +                                                  MachineSignature* msig) { | 
| +    const int return_count = msig->ReturnCount(); | 
| +    const int param_count = msig->ParamCount(); | 
|  | 
| -  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, param_count); | 
| + | 
| +    // Add return location(s). | 
| +    AddReturnLocations(&locations); | 
| + | 
| +    // Add register and/or stack parameter(s). | 
| +    for (int i = 0; i < param_count; i++) { | 
| +      if (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_param_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); | 
| } | 
| }; | 
|  | 
|  |