Upstream version 9.38.198.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 namespace v8 {
9 namespace internal {
10 namespace compiler {
11
12 class LinkageHelper {
13  public:
14   static LinkageLocation TaggedStackSlot(int index) {
15     DCHECK(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(MachineType 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     DCHECK_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       CallDescriptor::DeoptimizationSupport can_deoptimize) {
133     int register_parameter_count = descriptor->GetEnvironmentParameterCount();
134     int parameter_count = register_parameter_count + stack_parameter_count;
135     const int code_count = 1;
136     const int context_count = 1;
137     int input_count = code_count + parameter_count + context_count;
138
139     const int return_count = 1;
140     LinkageLocation* locations =
141         zone->NewArray<LinkageLocation>(return_count + input_count);
142
143     int index = 0;
144     locations[index++] =
145         TaggedRegisterLocation(LinkageTraits::ReturnValueReg());
146     locations[index++] = UnconstrainedRegister(kMachineTagged);  // code
147     for (int i = 0; i < parameter_count; i++) {
148       if (i < register_parameter_count) {
149         // The first parameters to code stub calls go in registers.
150         Register reg = descriptor->GetEnvironmentParameterRegister(i);
151         locations[index++] = TaggedRegisterLocation(reg);
152       } else {
153         // The rest of the parameters go on the stack.
154         int stack_slot = i - register_parameter_count - stack_parameter_count;
155         locations[index++] = TaggedStackSlot(stack_slot);
156       }
157     }
158     locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg());
159
160     // TODO(titzer): refactor TurboFan graph to consider context a value input.
161     return new (zone)
162         CallDescriptor(CallDescriptor::kCallCodeObject,  // kind
163                        return_count,                     // return_count
164                        parameter_count,                  // parameter_count
165                        input_count,                      // input_count
166                        locations,                        // locations
167                        Operator::kNoProperties,          // properties
168                        kNoCalleeSaved,  // callee-saved registers
169                        can_deoptimize,  // deoptimization
170                        CodeStub::MajorName(descriptor->MajorKey(), false));
171   }
172
173
174   template <typename LinkageTraits>
175   static CallDescriptor* GetSimplifiedCDescriptor(
176       Zone* zone, int num_params, MachineType return_type,
177       const MachineType* 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_