Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / v8 / src / compiler / linkage-impl.h
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 #include "src/code-stubs.h"
9
10 namespace v8 {
11 namespace internal {
12 namespace compiler {
13
14 // TODO(titzer): replace uses of int with size_t in LinkageHelper.
15 template <typename LinkageTraits>
16 class LinkageHelper {
17  public:
18   static const RegList kNoCalleeSaved = 0;
19
20   static void AddReturnLocations(LocationSignature::Builder* locations) {
21     DCHECK(locations->return_count_ <= 2);
22     if (locations->return_count_ > 0) {
23       locations->AddReturn(regloc(LinkageTraits::ReturnValueReg()));
24     }
25     if (locations->return_count_ > 1) {
26       locations->AddReturn(regloc(LinkageTraits::ReturnValue2Reg()));
27     }
28   }
29
30   // TODO(turbofan): cache call descriptors for JSFunction calls.
31   static CallDescriptor* GetJSCallDescriptor(Zone* zone, int js_parameter_count,
32                                              CallDescriptor::Flags flags) {
33     const size_t return_count = 1;
34     const size_t context_count = 1;
35     const size_t parameter_count = js_parameter_count + context_count;
36
37     LocationSignature::Builder locations(zone, return_count, parameter_count);
38     MachineSignature::Builder types(zone, return_count, parameter_count);
39
40     // Add returns.
41     AddReturnLocations(&locations);
42     for (size_t i = 0; i < return_count; i++) {
43       types.AddReturn(kMachAnyTagged);
44     }
45
46     // All parameters to JS calls go on the stack.
47     for (int i = 0; i < js_parameter_count; i++) {
48       int spill_slot_index = i - js_parameter_count;
49       locations.AddParam(stackloc(spill_slot_index));
50       types.AddParam(kMachAnyTagged);
51     }
52     // Add context.
53     locations.AddParam(regloc(LinkageTraits::ContextReg()));
54     types.AddParam(kMachAnyTagged);
55
56     // The target for JS function calls is the JSFunction object.
57     MachineType target_type = kMachAnyTagged;
58     LinkageLocation target_loc = regloc(LinkageTraits::JSCallFunctionReg());
59     return new (zone) CallDescriptor(     // --
60         CallDescriptor::kCallJSFunction,  // kind
61         target_type,                      // target MachineType
62         target_loc,                       // target location
63         types.Build(),                    // machine_sig
64         locations.Build(),                // location_sig
65         js_parameter_count,               // js_parameter_count
66         Operator::kNoProperties,          // properties
67         kNoCalleeSaved,                   // callee-saved
68         flags,                            // flags
69         "js-call");
70   }
71
72
73   // TODO(turbofan): cache call descriptors for runtime calls.
74   static CallDescriptor* GetRuntimeCallDescriptor(
75       Zone* zone, Runtime::FunctionId function_id, int js_parameter_count,
76       Operator::Properties properties) {
77     const size_t function_count = 1;
78     const size_t num_args_count = 1;
79     const size_t context_count = 1;
80     const size_t parameter_count = function_count +
81                                    static_cast<size_t>(js_parameter_count) +
82                                    num_args_count + context_count;
83
84     const Runtime::Function* function = Runtime::FunctionForId(function_id);
85     const size_t return_count = static_cast<size_t>(function->result_size);
86
87     LocationSignature::Builder locations(zone, return_count, parameter_count);
88     MachineSignature::Builder types(zone, return_count, parameter_count);
89
90     // Add returns.
91     AddReturnLocations(&locations);
92     for (size_t i = 0; i < return_count; i++) {
93       types.AddReturn(kMachAnyTagged);
94     }
95
96     // All parameters to the runtime call go on the stack.
97     for (int i = 0; i < js_parameter_count; i++) {
98       locations.AddParam(stackloc(i - js_parameter_count));
99       types.AddParam(kMachAnyTagged);
100     }
101     // Add runtime function itself.
102     locations.AddParam(regloc(LinkageTraits::RuntimeCallFunctionReg()));
103     types.AddParam(kMachAnyTagged);
104
105     // Add runtime call argument count.
106     locations.AddParam(regloc(LinkageTraits::RuntimeCallArgCountReg()));
107     types.AddParam(kMachPtr);
108
109     // Add context.
110     locations.AddParam(regloc(LinkageTraits::ContextReg()));
111     types.AddParam(kMachAnyTagged);
112
113     CallDescriptor::Flags flags = Linkage::NeedsFrameState(function_id)
114                                       ? CallDescriptor::kNeedsFrameState
115                                       : CallDescriptor::kNoFlags;
116
117     // The target for runtime calls is a code object.
118     MachineType target_type = kMachAnyTagged;
119     LinkageLocation target_loc = LinkageLocation::AnyRegister();
120     return new (zone) CallDescriptor(     // --
121         CallDescriptor::kCallCodeObject,  // kind
122         target_type,                      // target MachineType
123         target_loc,                       // target location
124         types.Build(),                    // machine_sig
125         locations.Build(),                // location_sig
126         js_parameter_count,               // js_parameter_count
127         properties,                       // properties
128         kNoCalleeSaved,                   // callee-saved
129         flags,                            // flags
130         function->name);                  // debug name
131   }
132
133
134   // TODO(turbofan): cache call descriptors for code stub calls.
135   static CallDescriptor* GetStubCallDescriptor(
136       Zone* zone, const CallInterfaceDescriptor& descriptor,
137       int stack_parameter_count, CallDescriptor::Flags flags) {
138     const int register_parameter_count =
139         descriptor.GetEnvironmentParameterCount();
140     const int js_parameter_count =
141         register_parameter_count + stack_parameter_count;
142     const int context_count = 1;
143     const size_t return_count = 1;
144     const size_t parameter_count =
145         static_cast<size_t>(js_parameter_count + context_count);
146
147     LocationSignature::Builder locations(zone, return_count, parameter_count);
148     MachineSignature::Builder types(zone, return_count, parameter_count);
149
150     // Add return location.
151     AddReturnLocations(&locations);
152     types.AddReturn(kMachAnyTagged);
153
154     // Add parameters in registers and on the stack.
155     for (int i = 0; i < js_parameter_count; i++) {
156       if (i < register_parameter_count) {
157         // The first parameters go in registers.
158         Register reg = descriptor.GetEnvironmentParameterRegister(i);
159         locations.AddParam(regloc(reg));
160       } else {
161         // The rest of the parameters go on the stack.
162         int stack_slot = i - register_parameter_count - stack_parameter_count;
163         locations.AddParam(stackloc(stack_slot));
164       }
165       types.AddParam(kMachAnyTagged);
166     }
167     // Add context.
168     locations.AddParam(regloc(LinkageTraits::ContextReg()));
169     types.AddParam(kMachAnyTagged);
170
171     // The target for stub calls is a code object.
172     MachineType target_type = kMachAnyTagged;
173     LinkageLocation target_loc = LinkageLocation::AnyRegister();
174     return new (zone) CallDescriptor(     // --
175         CallDescriptor::kCallCodeObject,  // kind
176         target_type,                      // target MachineType
177         target_loc,                       // target location
178         types.Build(),                    // machine_sig
179         locations.Build(),                // location_sig
180         js_parameter_count,               // js_parameter_count
181         Operator::kNoProperties,          // properties
182         kNoCalleeSaved,                   // callee-saved registers
183         flags,                            // flags
184         descriptor.DebugName(zone->isolate()));
185   }
186
187   static CallDescriptor* GetSimplifiedCDescriptor(Zone* zone,
188                                                   MachineSignature* msig) {
189     LocationSignature::Builder locations(zone, msig->return_count(),
190                                          msig->parameter_count());
191     // Add return location(s).
192     AddReturnLocations(&locations);
193
194     // Add register and/or stack parameter(s).
195     const int parameter_count = static_cast<int>(msig->parameter_count());
196     for (int i = 0; i < parameter_count; i++) {
197       if (i < LinkageTraits::CRegisterParametersLength()) {
198         locations.AddParam(regloc(LinkageTraits::CRegisterParameter(i)));
199       } else {
200         locations.AddParam(stackloc(-1 - i));
201       }
202     }
203
204     // The target for C calls is always an address (i.e. machine pointer).
205     MachineType target_type = kMachPtr;
206     LinkageLocation target_loc = LinkageLocation::AnyRegister();
207     return new (zone) CallDescriptor(  // --
208         CallDescriptor::kCallAddress,  // kind
209         target_type,                   // target MachineType
210         target_loc,                    // target location
211         msig,                          // machine_sig
212         locations.Build(),             // location_sig
213         0,                             // js_parameter_count
214         Operator::kNoProperties,       // properties
215         LinkageTraits::CCalleeSaveRegisters(), CallDescriptor::kNoFlags,
216         "c-call");
217   }
218
219   static LinkageLocation regloc(Register reg) {
220     return LinkageLocation(Register::ToAllocationIndex(reg));
221   }
222
223   static LinkageLocation stackloc(int i) {
224     DCHECK_LT(i, 0);
225     return LinkageLocation(i);
226   }
227 };
228 }  // namespace compiler
229 }  // namespace internal
230 }  // namespace v8
231
232 #endif  // V8_COMPILER_LINKAGE_IMPL_H_