Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(435)

Side by Side Diff: src/compiler/linkage-impl.h

Issue 530783002: Convert Linkage to use MachineSignature. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_COMPILER_LINKAGE_IMPL_H_ 5 #ifndef V8_COMPILER_LINKAGE_IMPL_H_
6 #define V8_COMPILER_LINKAGE_IMPL_H_ 6 #define V8_COMPILER_LINKAGE_IMPL_H_
7 7
8 namespace v8 { 8 namespace v8 {
9 namespace internal { 9 namespace internal {
10 namespace compiler { 10 namespace compiler {
11 11
12 template <typename LinkageTraits>
12 class LinkageHelper { 13 class LinkageHelper {
13 public: 14 public:
14 static LinkageLocation TaggedStackSlot(int index) {
15 DCHECK(index < 0);
16 return LinkageLocation(kMachAnyTagged, index);
17 }
18
19 static LinkageLocation TaggedRegisterLocation(Register reg) {
20 return LinkageLocation(kMachAnyTagged, Register::ToAllocationIndex(reg));
21 }
22
23 static inline LinkageLocation WordRegisterLocation(Register reg) {
24 return LinkageLocation(kMachPtr, Register::ToAllocationIndex(reg));
25 }
26
27 static LinkageLocation UnconstrainedRegister(MachineType rep) {
28 return LinkageLocation(rep, LinkageLocation::ANY_REGISTER);
29 }
30
31 static const RegList kNoCalleeSaved = 0; 15 static const RegList kNoCalleeSaved = 0;
32 16
17 static void AddReturnLocations(LocationSignature::Builder* locations) {
18 DCHECK_GE(locations->return_count_, 0);
19 DCHECK_LE(locations->return_count_, 2);
20 if (locations->return_count_ > 0) {
21 locations->AddReturn(regloc(LinkageTraits::ReturnValueReg()));
22 }
23 if (locations->return_count_ > 1) {
24 locations->AddReturn(regloc(LinkageTraits::ReturnValue2Reg()));
25 }
26 }
27
33 // TODO(turbofan): cache call descriptors for JSFunction calls. 28 // TODO(turbofan): cache call descriptors for JSFunction calls.
34 template <typename LinkageTraits> 29 static CallDescriptor* GetJSCallDescriptor(Zone* zone, int js_param_count) {
35 static CallDescriptor* GetJSCallDescriptor(Zone* zone, int parameter_count) { 30 const int return_count = 1;
36 const int jsfunction_count = 1;
37 const int context_count = 1; 31 const int context_count = 1;
38 int input_count = jsfunction_count + parameter_count + context_count; 32 const int param_count = js_param_count + context_count;
39 33
40 const int return_count = 1; 34 LocationSignature::Builder locations(zone, return_count, param_count);
41 LinkageLocation* locations = 35 MachineSignature::Builder types(zone, return_count, param_count);
42 zone->NewArray<LinkageLocation>(return_count + input_count); 36
43 37 // Add returns.
44 int index = 0; 38 AddReturnLocations(&locations);
45 locations[index++] = 39 for (int i = 0; i < return_count; i++) {
46 TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); 40 types.AddReturn(kMachAnyTagged);
47 locations[index++] = 41 }
48 TaggedRegisterLocation(LinkageTraits::JSCallFunctionReg()); 42
49 43 // All parameters to JS calls go on the stack.
50 for (int i = 0; i < parameter_count; i++) { 44 for (int i = 0; i < js_param_count; i++) {
51 // All parameters to JS calls go on the stack. 45 int spill_slot_index = i - js_param_count;
52 int spill_slot_index = i - parameter_count; 46 locations.AddParam(stackloc(spill_slot_index));
53 locations[index++] = TaggedStackSlot(spill_slot_index); 47 types.AddParam(kMachAnyTagged);
54 } 48 }
55 locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg()); 49 // Add context.
56 50 locations.AddParam(regloc(LinkageTraits::ContextReg()));
57 // TODO(titzer): refactor TurboFan graph to consider context a value input. 51 types.AddParam(kMachAnyTagged);
58 return new (zone) 52
59 CallDescriptor(CallDescriptor::kCallJSFunction, // kind 53 // The target for JS function calls is the JSFunction object.
60 return_count, // return_count 54 MachineType target_type = kMachAnyTagged;
61 parameter_count, // parameter_count 55 LinkageLocation target_loc = regloc(LinkageTraits::JSCallFunctionReg());
62 input_count - context_count, // input_count 56 return new (zone) CallDescriptor(CallDescriptor::kCallJSFunction, // kind
63 locations, // locations 57 target_type, // target MachineType
64 Operator::kNoProperties, // properties 58 target_loc, // target location
65 kNoCalleeSaved, // callee-saved registers 59 types.Build(), // machine_sig
66 CallDescriptor::kNeedsFrameState); // flags 60 locations.Build(), // location_sig
61 js_param_count, // js_param_count
62 Operator::kNoProperties, // properties
63 kNoCalleeSaved, // callee-saved
64 CallDescriptor::kNeedsFrameState, // flags
65 "js-call");
67 } 66 }
68 67
69 68
70 // TODO(turbofan): cache call descriptors for runtime calls. 69 // TODO(turbofan): cache call descriptors for runtime calls.
71 template <typename LinkageTraits>
72 static CallDescriptor* GetRuntimeCallDescriptor( 70 static CallDescriptor* GetRuntimeCallDescriptor(
73 Zone* zone, Runtime::FunctionId function_id, int parameter_count, 71 Zone* zone, Runtime::FunctionId function_id, int js_param_count,
74 Operator::Property properties, CallDescriptor::Flags flags) { 72 Operator::Property properties, CallDescriptor::Flags flags) {
75 const int code_count = 1;
76 const int function_count = 1; 73 const int function_count = 1;
77 const int num_args_count = 1; 74 const int num_args_count = 1;
78 const int context_count = 1; 75 const int context_count = 1;
79 const int input_count = code_count + parameter_count + function_count + 76 const int param_count =
80 num_args_count + context_count; 77 js_param_count + function_count + num_args_count + context_count;
81 78
82 const Runtime::Function* function = Runtime::FunctionForId(function_id); 79 const Runtime::Function* function = Runtime::FunctionForId(function_id);
83 const int return_count = function->result_size; 80 const int return_count = function->result_size;
84 LinkageLocation* locations = 81
85 zone->NewArray<LinkageLocation>(return_count + input_count); 82 LocationSignature::Builder locations(zone, return_count, param_count);
86 83 MachineSignature::Builder types(zone, return_count, param_count);
87 int index = 0; 84
88 if (return_count > 0) { 85 // Add returns.
89 locations[index++] = 86 AddReturnLocations(&locations);
90 TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); 87 for (int i = 0; i < return_count; i++) {
91 } 88 types.AddReturn(kMachAnyTagged);
92 if (return_count > 1) { 89 }
93 locations[index++] = 90
94 TaggedRegisterLocation(LinkageTraits::ReturnValue2Reg()); 91 // All parameters to the runtime call go on the stack.
95 } 92 for (int i = 0; i < js_param_count; i++) {
96 93 locations.AddParam(stackloc(i - js_param_count));
97 DCHECK_LE(return_count, 2); 94 types.AddParam(kMachAnyTagged);
98 95 }
99 locations[index++] = UnconstrainedRegister(kMachAnyTagged); // CEntryStub 96 // Add runtime function itself.
100 97 locations.AddParam(regloc(LinkageTraits::RuntimeCallFunctionReg()));
101 for (int i = 0; i < parameter_count; i++) { 98 types.AddParam(kMachAnyTagged);
102 // All parameters to runtime calls go on the stack. 99
103 int spill_slot_index = i - parameter_count; 100 // Add runtime call argument count.
104 locations[index++] = TaggedStackSlot(spill_slot_index); 101 locations.AddParam(regloc(LinkageTraits::RuntimeCallArgCountReg()));
105 } 102 types.AddParam(kMachPtr);
106 locations[index++] = 103
107 TaggedRegisterLocation(LinkageTraits::RuntimeCallFunctionReg()); 104 // Add context.
108 locations[index++] = 105 locations.AddParam(regloc(LinkageTraits::ContextReg()));
109 WordRegisterLocation(LinkageTraits::RuntimeCallArgCountReg()); 106 types.AddParam(kMachAnyTagged);
110 locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg()); 107
111 108 // The target for runtime calls is a code object.
112 // TODO(titzer): refactor TurboFan graph to consider context a value input. 109 MachineType target_type = kMachAnyTagged;
110 LinkageLocation target_loc = LinkageLocation::AnyRegister();
113 return new (zone) CallDescriptor(CallDescriptor::kCallCodeObject, // kind 111 return new (zone) CallDescriptor(CallDescriptor::kCallCodeObject, // kind
114 return_count, // return_count 112 target_type, // target MachineType
115 parameter_count, // parameter_count 113 target_loc, // target location
116 input_count, // input_count 114 types.Build(), // machine_sig
117 locations, // locations 115 locations.Build(), // location_sig
118 properties, // properties 116 js_param_count, // js_param_count
119 kNoCalleeSaved, // callee-saved registers 117 properties, // properties
120 flags, // flags 118 kNoCalleeSaved, // callee-saved
121 function->name); 119 flags, // flags
120 function->name); // debug name
122 } 121 }
123 122
124 123
125 // TODO(turbofan): cache call descriptors for code stub calls. 124 // TODO(turbofan): cache call descriptors for code stub calls.
126 template <typename LinkageTraits>
127 static CallDescriptor* GetStubCallDescriptor( 125 static CallDescriptor* GetStubCallDescriptor(
128 Zone* zone, CodeStubInterfaceDescriptor* descriptor, 126 Zone* zone, CodeStubInterfaceDescriptor* descriptor,
129 int stack_parameter_count, CallDescriptor::Flags flags) { 127 int stack_parameter_count, CallDescriptor::Flags flags) {
130 int register_parameter_count = descriptor->GetEnvironmentParameterCount(); 128 int register_parameter_count = descriptor->GetEnvironmentParameterCount();
131 int parameter_count = register_parameter_count + stack_parameter_count; 129 int js_param_count = register_parameter_count + stack_parameter_count;
132 const int code_count = 1;
133 const int context_count = 1; 130 const int context_count = 1;
134 int input_count = code_count + parameter_count + context_count; 131 int param_count = js_param_count + context_count;
135 132 int return_count = 1;
136 const int return_count = 1; 133 LocationSignature::Builder locations(zone, return_count, param_count);
137 LinkageLocation* locations = 134 MachineSignature::Builder types(zone, return_count, param_count);
138 zone->NewArray<LinkageLocation>(return_count + input_count); 135
139 136 // Add return location.
140 int index = 0; 137 AddReturnLocations(&locations);
141 locations[index++] = 138 for (int i = 0; i < return_count; i++) {
142 TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); 139 types.AddReturn(kMachAnyTagged);
143 locations[index++] = UnconstrainedRegister(kMachAnyTagged); // code 140 }
144 for (int i = 0; i < parameter_count; i++) { 141
142 // Add parameters in registers and on the stack.
143 for (int i = 0; i < js_param_count; i++) {
145 if (i < register_parameter_count) { 144 if (i < register_parameter_count) {
146 // The first parameters to code stub calls go in registers. 145 // The first parameters go in registers.
147 Register reg = descriptor->GetEnvironmentParameterRegister(i); 146 Register reg = descriptor->GetEnvironmentParameterRegister(i);
148 locations[index++] = TaggedRegisterLocation(reg); 147 locations.AddParam(regloc(reg));
149 } else { 148 } else {
150 // The rest of the parameters go on the stack. 149 // The rest of the parameters go on the stack.
151 int stack_slot = i - register_parameter_count - stack_parameter_count; 150 int stack_slot = i - register_parameter_count - stack_parameter_count;
152 locations[index++] = TaggedStackSlot(stack_slot); 151 locations.AddParam(stackloc(stack_slot));
153 } 152 }
154 } 153 types.AddParam(kMachAnyTagged);
155 locations[index++] = TaggedRegisterLocation(LinkageTraits::ContextReg()); 154 }
156 155 // Add context.
157 // TODO(titzer): refactor TurboFan graph to consider context a value input. 156 locations.AddParam(regloc(LinkageTraits::ContextReg()));
157 types.AddParam(kMachAnyTagged);
158
159 // The target for stub calls is a code object.
160 MachineType target_type = kMachAnyTagged;
161 LinkageLocation target_loc = LinkageLocation::AnyRegister();
158 return new (zone) 162 return new (zone)
159 CallDescriptor(CallDescriptor::kCallCodeObject, // kind 163 CallDescriptor(CallDescriptor::kCallCodeObject, // kind
160 return_count, // return_count 164 target_type, // target MachineType
161 parameter_count, // parameter_count 165 target_loc, // target location
162 input_count, // input_count 166 types.Build(), // machine_sig
163 locations, // locations 167 locations.Build(), // location_sig
168 js_param_count, // js_param_count
164 Operator::kNoProperties, // properties 169 Operator::kNoProperties, // properties
165 kNoCalleeSaved, // callee-saved registers 170 kNoCalleeSaved, // callee-saved registers
166 flags, // flags 171 flags, // flags
167 CodeStub::MajorName(descriptor->MajorKey(), false)); 172 CodeStub::MajorName(descriptor->MajorKey(), false));
168 } 173 }
169 174
170 175 static CallDescriptor* GetSimplifiedCDescriptor(Zone* zone,
171 template <typename LinkageTraits> 176 MachineSignature* msig) {
172 static CallDescriptor* GetSimplifiedCDescriptor( 177 const int return_count = msig->ReturnCount();
173 Zone* zone, int num_params, MachineType return_type, 178 const int param_count = msig->ParamCount();
174 const MachineType* param_types) { 179
175 LinkageLocation* locations = 180 LocationSignature::Builder locations(zone, return_count, param_count);
176 zone->NewArray<LinkageLocation>(num_params + 2); 181
177 int index = 0; 182 // Add return location(s).
178 locations[index++] = 183 AddReturnLocations(&locations);
179 TaggedRegisterLocation(LinkageTraits::ReturnValueReg()); 184
180 locations[index++] = LinkageHelper::UnconstrainedRegister(kMachPtr); 185 // Add register and/or stack parameter(s).
181 // TODO(dcarney): test with lots of parameters. 186 for (int i = 0; i < param_count; i++) {
182 int i = 0; 187 if (i < LinkageTraits::CRegisterParametersLength()) {
183 for (; i < LinkageTraits::CRegisterParametersLength() && i < num_params; 188 locations.AddParam(regloc(LinkageTraits::CRegisterParameter(i)));
184 i++) { 189 } else {
185 locations[index++] = LinkageLocation( 190 locations.AddParam(stackloc(-1 - i));
186 param_types[i], 191 }
187 Register::ToAllocationIndex(LinkageTraits::CRegisterParameter(i))); 192 }
188 } 193
189 for (; i < num_params; i++) { 194 // The target for C calls is always an address (i.e. machine pointer).
190 locations[index++] = LinkageLocation(param_types[i], -1 - i); 195 MachineType target_type = kMachPtr;
191 } 196 LinkageLocation target_loc = LinkageLocation::AnyRegister();
192 return new (zone) CallDescriptor( 197 return new (zone) CallDescriptor(CallDescriptor::kCallAddress, // kind
193 CallDescriptor::kCallAddress, 1, num_params, num_params + 1, locations, 198 target_type, // target MachineType
194 Operator::kNoProperties, LinkageTraits::CCalleeSaveRegisters(), 199 target_loc, // target location
195 CallDescriptor::kNoFlags); // TODO(jarin) should deoptimize! 200 msig, // machine_sig
201 locations.Build(), // location_sig
202 0, // js_param_count
203 Operator::kNoProperties, // properties
204 LinkageTraits::CCalleeSaveRegisters(),
205 CallDescriptor::kNoFlags, "c-call");
206 }
207
208 static LinkageLocation regloc(Register reg) {
209 return LinkageLocation(Register::ToAllocationIndex(reg));
210 }
211
212 static LinkageLocation stackloc(int i) {
213 DCHECK_LT(i, 0);
214 return LinkageLocation(i);
196 } 215 }
197 }; 216 };
198 217
199 } // namespace compiler 218 } // namespace compiler
200 } // namespace internal 219 } // namespace internal
201 } // namespace v8 220 } // namespace v8
202 221
203 #endif // V8_COMPILER_LINKAGE_IMPL_H_ 222 #endif // V8_COMPILER_LINKAGE_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698