OLD | NEW |
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 #include "src/ast/scopes.h" | 5 #include "src/ast/scopes.h" |
6 #include "src/code-stubs.h" | 6 #include "src/code-stubs.h" |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/compiler/common-operator.h" | 8 #include "src/compiler/common-operator.h" |
9 #include "src/compiler/frame.h" | 9 #include "src/compiler/frame.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
11 #include "src/compiler/node.h" | 11 #include "src/compiler/node.h" |
12 #include "src/compiler/osr.h" | 12 #include "src/compiler/osr.h" |
13 #include "src/compiler/pipeline.h" | 13 #include "src/compiler/pipeline.h" |
14 | 14 |
15 namespace v8 { | 15 namespace v8 { |
16 namespace internal { | 16 namespace internal { |
17 namespace compiler { | 17 namespace compiler { |
18 | 18 |
19 namespace { | 19 namespace { |
20 LinkageLocation regloc(Register reg) { | 20 |
21 return LinkageLocation::ForRegister(reg.code()); | 21 LinkageLocation regloc(Register reg, MachineType type) { |
| 22 return LinkageLocation::ForRegister(reg.code(), type); |
22 } | 23 } |
23 | 24 |
24 | |
25 MachineType reptyp(Representation representation) { | 25 MachineType reptyp(Representation representation) { |
26 switch (representation.kind()) { | 26 switch (representation.kind()) { |
27 case Representation::kInteger8: | 27 case Representation::kInteger8: |
28 return MachineType::Int8(); | 28 return MachineType::Int8(); |
29 case Representation::kUInteger8: | 29 case Representation::kUInteger8: |
30 return MachineType::Uint8(); | 30 return MachineType::Uint8(); |
31 case Representation::kInteger16: | 31 case Representation::kInteger16: |
32 return MachineType::Int16(); | 32 return MachineType::Int16(); |
33 case Representation::kUInteger16: | 33 case Representation::kUInteger16: |
34 return MachineType::Uint16(); | 34 return MachineType::Uint16(); |
35 case Representation::kInteger32: | 35 case Representation::kInteger32: |
36 return MachineType::Int32(); | 36 return MachineType::Int32(); |
37 case Representation::kSmi: | 37 case Representation::kSmi: |
38 case Representation::kTagged: | 38 case Representation::kTagged: |
39 case Representation::kHeapObject: | 39 case Representation::kHeapObject: |
40 return MachineType::AnyTagged(); | 40 return MachineType::AnyTagged(); |
41 case Representation::kDouble: | 41 case Representation::kDouble: |
42 return MachineType::Float64(); | 42 return MachineType::Float64(); |
43 case Representation::kExternal: | 43 case Representation::kExternal: |
44 return MachineType::Pointer(); | 44 return MachineType::Pointer(); |
45 case Representation::kNone: | 45 case Representation::kNone: |
46 case Representation::kNumRepresentations: | 46 case Representation::kNumRepresentations: |
47 break; | 47 break; |
48 } | 48 } |
49 UNREACHABLE(); | 49 UNREACHABLE(); |
50 return MachineType::None(); | 50 return MachineType::None(); |
51 } | 51 } |
| 52 |
52 } // namespace | 53 } // namespace |
53 | 54 |
54 | 55 |
55 std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k) { | 56 std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k) { |
56 switch (k) { | 57 switch (k) { |
57 case CallDescriptor::kCallCodeObject: | 58 case CallDescriptor::kCallCodeObject: |
58 os << "Code"; | 59 os << "Code"; |
59 break; | 60 break; |
60 case CallDescriptor::kCallJSFunction: | 61 case CallDescriptor::kCallJSFunction: |
61 os << "JS"; | 62 os << "JS"; |
62 break; | 63 break; |
63 case CallDescriptor::kCallAddress: | 64 case CallDescriptor::kCallAddress: |
64 os << "Addr"; | 65 os << "Addr"; |
65 break; | 66 break; |
66 } | 67 } |
67 return os; | 68 return os; |
68 } | 69 } |
69 | 70 |
70 | 71 |
71 std::ostream& operator<<(std::ostream& os, const CallDescriptor& d) { | 72 std::ostream& operator<<(std::ostream& os, const CallDescriptor& d) { |
72 // TODO(svenpanne) Output properties etc. and be less cryptic. | 73 // TODO(svenpanne) Output properties etc. and be less cryptic. |
73 return os << d.kind() << ":" << d.debug_name() << ":r" << d.ReturnCount() | 74 return os << d.kind() << ":" << d.debug_name() << ":r" << d.ReturnCount() |
74 << "s" << d.StackParameterCount() << "i" << d.InputCount() << "f" | 75 << "s" << d.StackParameterCount() << "i" << d.InputCount() << "f" |
75 << d.FrameStateCount() << "t" << d.SupportsTailCalls(); | 76 << d.FrameStateCount() << "t" << d.SupportsTailCalls(); |
76 } | 77 } |
77 | 78 |
| 79 MachineSignature* CallDescriptor::GetMachineSignature(Zone* zone) const { |
| 80 size_t param_count = ParameterCount(); |
| 81 size_t return_count = ReturnCount(); |
| 82 MachineType* types = reinterpret_cast<MachineType*>( |
| 83 zone->New(sizeof(MachineType*) * (param_count + return_count))); |
| 84 int current = 0; |
| 85 for (size_t i = 0; i < return_count; ++i) { |
| 86 types[current++] = GetReturnType(i); |
| 87 } |
| 88 for (size_t i = 0; i < param_count; ++i) { |
| 89 types[current++] = GetParameterType(i); |
| 90 } |
| 91 return new (zone) MachineSignature(return_count, param_count, types); |
| 92 } |
78 | 93 |
79 bool CallDescriptor::HasSameReturnLocationsAs( | 94 bool CallDescriptor::HasSameReturnLocationsAs( |
80 const CallDescriptor* other) const { | 95 const CallDescriptor* other) const { |
81 if (ReturnCount() != other->ReturnCount()) return false; | 96 if (ReturnCount() != other->ReturnCount()) return false; |
82 for (size_t i = 0; i < ReturnCount(); ++i) { | 97 for (size_t i = 0; i < ReturnCount(); ++i) { |
83 if (GetReturnLocation(i) != other->GetReturnLocation(i)) return false; | 98 if (GetReturnLocation(i) != other->GetReturnLocation(i)) return false; |
84 } | 99 } |
85 return true; | 100 return true; |
86 } | 101 } |
87 | 102 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 const size_t num_args_count = 1; | 227 const size_t num_args_count = 1; |
213 const size_t context_count = 1; | 228 const size_t context_count = 1; |
214 const size_t parameter_count = function_count + | 229 const size_t parameter_count = function_count + |
215 static_cast<size_t>(js_parameter_count) + | 230 static_cast<size_t>(js_parameter_count) + |
216 num_args_count + context_count; | 231 num_args_count + context_count; |
217 | 232 |
218 const Runtime::Function* function = Runtime::FunctionForId(function_id); | 233 const Runtime::Function* function = Runtime::FunctionForId(function_id); |
219 const size_t return_count = static_cast<size_t>(function->result_size); | 234 const size_t return_count = static_cast<size_t>(function->result_size); |
220 | 235 |
221 LocationSignature::Builder locations(zone, return_count, parameter_count); | 236 LocationSignature::Builder locations(zone, return_count, parameter_count); |
222 MachineSignature::Builder types(zone, return_count, parameter_count); | |
223 | 237 |
224 // Add returns. | 238 // Add returns. |
225 if (locations.return_count_ > 0) { | 239 if (locations.return_count_ > 0) { |
226 locations.AddReturn(regloc(kReturnRegister0)); | 240 locations.AddReturn(regloc(kReturnRegister0, MachineType::AnyTagged())); |
227 } | 241 } |
228 if (locations.return_count_ > 1) { | 242 if (locations.return_count_ > 1) { |
229 locations.AddReturn(regloc(kReturnRegister1)); | 243 locations.AddReturn(regloc(kReturnRegister1, MachineType::AnyTagged())); |
230 } | 244 } |
231 if (locations.return_count_ > 2) { | 245 if (locations.return_count_ > 2) { |
232 locations.AddReturn(regloc(kReturnRegister2)); | 246 locations.AddReturn(regloc(kReturnRegister2, MachineType::AnyTagged())); |
233 } | |
234 for (size_t i = 0; i < return_count; i++) { | |
235 types.AddReturn(MachineType::AnyTagged()); | |
236 } | 247 } |
237 | 248 |
238 // All parameters to the runtime call go on the stack. | 249 // All parameters to the runtime call go on the stack. |
239 for (int i = 0; i < js_parameter_count; i++) { | 250 for (int i = 0; i < js_parameter_count; i++) { |
240 locations.AddParam( | 251 locations.AddParam(LinkageLocation::ForCallerFrameSlot( |
241 LinkageLocation::ForCallerFrameSlot(i - js_parameter_count)); | 252 i - js_parameter_count, MachineType::AnyTagged())); |
242 types.AddParam(MachineType::AnyTagged()); | |
243 } | 253 } |
244 // Add runtime function itself. | 254 // Add runtime function itself. |
245 locations.AddParam(regloc(kRuntimeCallFunctionRegister)); | 255 locations.AddParam( |
246 types.AddParam(MachineType::AnyTagged()); | 256 regloc(kRuntimeCallFunctionRegister, MachineType::AnyTagged())); |
247 | 257 |
248 // Add runtime call argument count. | 258 // Add runtime call argument count. |
249 locations.AddParam(regloc(kRuntimeCallArgCountRegister)); | 259 locations.AddParam( |
250 types.AddParam(MachineType::Pointer()); | 260 regloc(kRuntimeCallArgCountRegister, MachineType::AnyTagged())); |
251 | 261 |
252 // Add context. | 262 // Add context. |
253 locations.AddParam(regloc(kContextRegister)); | 263 locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged())); |
254 types.AddParam(MachineType::AnyTagged()); | |
255 | 264 |
256 if (!Linkage::NeedsFrameStateInput(function_id)) { | 265 if (!Linkage::NeedsFrameStateInput(function_id)) { |
257 flags = static_cast<CallDescriptor::Flags>( | 266 flags = static_cast<CallDescriptor::Flags>( |
258 flags & ~CallDescriptor::kNeedsFrameState); | 267 flags & ~CallDescriptor::kNeedsFrameState); |
259 } | 268 } |
260 | 269 |
261 // The target for runtime calls is a code object. | 270 // The target for runtime calls is a code object. |
262 MachineType target_type = MachineType::AnyTagged(); | 271 MachineType target_type = MachineType::AnyTagged(); |
263 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); | 272 LinkageLocation target_loc = |
| 273 LinkageLocation::ForAnyRegister(MachineType::AnyTagged()); |
264 return new (zone) CallDescriptor( // -- | 274 return new (zone) CallDescriptor( // -- |
265 CallDescriptor::kCallCodeObject, // kind | 275 CallDescriptor::kCallCodeObject, // kind |
266 target_type, // target MachineType | 276 target_type, // target MachineType |
267 target_loc, // target location | 277 target_loc, // target location |
268 types.Build(), // machine_sig | |
269 locations.Build(), // location_sig | 278 locations.Build(), // location_sig |
270 js_parameter_count, // stack_parameter_count | 279 js_parameter_count, // stack_parameter_count |
271 properties, // properties | 280 properties, // properties |
272 kNoCalleeSaved, // callee-saved | 281 kNoCalleeSaved, // callee-saved |
273 kNoCalleeSaved, // callee-saved fp | 282 kNoCalleeSaved, // callee-saved fp |
274 flags, // flags | 283 flags, // flags |
275 function->name); // debug name | 284 function->name); // debug name |
276 } | 285 } |
277 | 286 |
278 | 287 |
279 CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr, | 288 CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr, |
280 int js_parameter_count, | 289 int js_parameter_count, |
281 CallDescriptor::Flags flags) { | 290 CallDescriptor::Flags flags) { |
282 const size_t return_count = 1; | 291 const size_t return_count = 1; |
283 const size_t context_count = 1; | 292 const size_t context_count = 1; |
284 const size_t new_target_count = 1; | 293 const size_t new_target_count = 1; |
285 const size_t num_args_count = 1; | 294 const size_t num_args_count = 1; |
286 const size_t parameter_count = | 295 const size_t parameter_count = |
287 js_parameter_count + new_target_count + num_args_count + context_count; | 296 js_parameter_count + new_target_count + num_args_count + context_count; |
288 | 297 |
289 LocationSignature::Builder locations(zone, return_count, parameter_count); | 298 LocationSignature::Builder locations(zone, return_count, parameter_count); |
290 MachineSignature::Builder types(zone, return_count, parameter_count); | |
291 | 299 |
292 // All JS calls have exactly one return value. | 300 // All JS calls have exactly one return value. |
293 locations.AddReturn(regloc(kReturnRegister0)); | 301 locations.AddReturn(regloc(kReturnRegister0, MachineType::AnyTagged())); |
294 types.AddReturn(MachineType::AnyTagged()); | |
295 | 302 |
296 // All parameters to JS calls go on the stack. | 303 // All parameters to JS calls go on the stack. |
297 for (int i = 0; i < js_parameter_count; i++) { | 304 for (int i = 0; i < js_parameter_count; i++) { |
298 int spill_slot_index = i - js_parameter_count; | 305 int spill_slot_index = i - js_parameter_count; |
299 locations.AddParam(LinkageLocation::ForCallerFrameSlot(spill_slot_index)); | 306 locations.AddParam(LinkageLocation::ForCallerFrameSlot( |
300 types.AddParam(MachineType::AnyTagged()); | 307 spill_slot_index, MachineType::AnyTagged())); |
301 } | 308 } |
302 | 309 |
303 // Add JavaScript call new target value. | 310 // Add JavaScript call new target value. |
304 locations.AddParam(regloc(kJavaScriptCallNewTargetRegister)); | 311 locations.AddParam( |
305 types.AddParam(MachineType::AnyTagged()); | 312 regloc(kJavaScriptCallNewTargetRegister, MachineType::AnyTagged())); |
306 | 313 |
307 // Add JavaScript call argument count. | 314 // Add JavaScript call argument count. |
308 locations.AddParam(regloc(kJavaScriptCallArgCountRegister)); | 315 locations.AddParam( |
309 types.AddParam(MachineType::Int32()); | 316 regloc(kJavaScriptCallArgCountRegister, MachineType::Int32())); |
310 | 317 |
311 // Add context. | 318 // Add context. |
312 locations.AddParam(regloc(kContextRegister)); | 319 locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged())); |
313 types.AddParam(MachineType::AnyTagged()); | |
314 | 320 |
315 // The target for JS function calls is the JSFunction object. | 321 // The target for JS function calls is the JSFunction object. |
316 MachineType target_type = MachineType::AnyTagged(); | 322 MachineType target_type = MachineType::AnyTagged(); |
317 // When entering into an OSR function from unoptimized code the JSFunction | 323 // When entering into an OSR function from unoptimized code the JSFunction |
318 // is not in a register, but it is on the stack in the marker spill slot. | 324 // is not in a register, but it is on the stack in the marker spill slot. |
319 LinkageLocation target_loc = is_osr | 325 LinkageLocation target_loc = |
320 ? LinkageLocation::ForSavedCallerFunction() | 326 is_osr ? LinkageLocation::ForSavedCallerFunction() |
321 : regloc(kJSFunctionRegister); | 327 : regloc(kJSFunctionRegister, MachineType::AnyTagged()); |
322 return new (zone) CallDescriptor( // -- | 328 return new (zone) CallDescriptor( // -- |
323 CallDescriptor::kCallJSFunction, // kind | 329 CallDescriptor::kCallJSFunction, // kind |
324 target_type, // target MachineType | 330 target_type, // target MachineType |
325 target_loc, // target location | 331 target_loc, // target location |
326 types.Build(), // machine_sig | |
327 locations.Build(), // location_sig | 332 locations.Build(), // location_sig |
328 js_parameter_count, // stack_parameter_count | 333 js_parameter_count, // stack_parameter_count |
329 Operator::kNoProperties, // properties | 334 Operator::kNoProperties, // properties |
330 kNoCalleeSaved, // callee-saved | 335 kNoCalleeSaved, // callee-saved |
331 kNoCalleeSaved, // callee-saved fp | 336 kNoCalleeSaved, // callee-saved fp |
332 CallDescriptor::kCanUseRoots | // flags | 337 CallDescriptor::kCanUseRoots | // flags |
333 flags, // flags | 338 flags, // flags |
334 "js-call"); | 339 "js-call"); |
335 } | 340 } |
336 | 341 |
337 // TODO(all): Add support for return representations/locations to | 342 // TODO(all): Add support for return representations/locations to |
338 // CallInterfaceDescriptor. | 343 // CallInterfaceDescriptor. |
339 // TODO(turbofan): cache call descriptors for code stub calls. | 344 // TODO(turbofan): cache call descriptors for code stub calls. |
340 CallDescriptor* Linkage::GetStubCallDescriptor( | 345 CallDescriptor* Linkage::GetStubCallDescriptor( |
341 Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, | 346 Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, |
342 int stack_parameter_count, CallDescriptor::Flags flags, | 347 int stack_parameter_count, CallDescriptor::Flags flags, |
343 Operator::Properties properties, MachineType return_type, | 348 Operator::Properties properties, MachineType return_type, |
344 size_t return_count) { | 349 size_t return_count) { |
345 const int register_parameter_count = descriptor.GetRegisterParameterCount(); | 350 const int register_parameter_count = descriptor.GetRegisterParameterCount(); |
346 const int js_parameter_count = | 351 const int js_parameter_count = |
347 register_parameter_count + stack_parameter_count; | 352 register_parameter_count + stack_parameter_count; |
348 const int context_count = 1; | 353 const int context_count = 1; |
349 const size_t parameter_count = | 354 const size_t parameter_count = |
350 static_cast<size_t>(js_parameter_count + context_count); | 355 static_cast<size_t>(js_parameter_count + context_count); |
351 | 356 |
352 LocationSignature::Builder locations(zone, return_count, parameter_count); | 357 LocationSignature::Builder locations(zone, return_count, parameter_count); |
353 MachineSignature::Builder types(zone, return_count, parameter_count); | |
354 | 358 |
355 // Add returns. | 359 // Add returns. |
356 if (locations.return_count_ > 0) { | 360 if (locations.return_count_ > 0) { |
357 locations.AddReturn(regloc(kReturnRegister0)); | 361 locations.AddReturn(regloc(kReturnRegister0, return_type)); |
358 } | 362 } |
359 if (locations.return_count_ > 1) { | 363 if (locations.return_count_ > 1) { |
360 locations.AddReturn(regloc(kReturnRegister1)); | 364 locations.AddReturn(regloc(kReturnRegister1, return_type)); |
361 } | 365 } |
362 if (locations.return_count_ > 2) { | 366 if (locations.return_count_ > 2) { |
363 locations.AddReturn(regloc(kReturnRegister2)); | 367 locations.AddReturn(regloc(kReturnRegister2, return_type)); |
364 } | |
365 for (size_t i = 0; i < return_count; i++) { | |
366 types.AddReturn(return_type); | |
367 } | 368 } |
368 | 369 |
369 // Add parameters in registers and on the stack. | 370 // Add parameters in registers and on the stack. |
370 for (int i = 0; i < js_parameter_count; i++) { | 371 for (int i = 0; i < js_parameter_count; i++) { |
371 if (i < register_parameter_count) { | 372 if (i < register_parameter_count) { |
372 // The first parameters go in registers. | 373 // The first parameters go in registers. |
373 Register reg = descriptor.GetRegisterParameter(i); | 374 Register reg = descriptor.GetRegisterParameter(i); |
374 Representation rep = | 375 MachineType type = |
375 RepresentationFromType(descriptor.GetParameterType(i)); | 376 reptyp(RepresentationFromType(descriptor.GetParameterType(i))); |
376 locations.AddParam(regloc(reg)); | 377 locations.AddParam(regloc(reg, type)); |
377 types.AddParam(reptyp(rep)); | |
378 } else { | 378 } else { |
379 // The rest of the parameters go on the stack. | 379 // The rest of the parameters go on the stack. |
380 int stack_slot = i - register_parameter_count - stack_parameter_count; | 380 int stack_slot = i - register_parameter_count - stack_parameter_count; |
381 locations.AddParam(LinkageLocation::ForCallerFrameSlot(stack_slot)); | 381 locations.AddParam(LinkageLocation::ForCallerFrameSlot( |
382 types.AddParam(MachineType::AnyTagged()); | 382 stack_slot, MachineType::AnyTagged())); |
383 } | 383 } |
384 } | 384 } |
385 // Add context. | 385 // Add context. |
386 locations.AddParam(regloc(kContextRegister)); | 386 locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged())); |
387 types.AddParam(MachineType::AnyTagged()); | |
388 | 387 |
389 // The target for stub calls is a code object. | 388 // The target for stub calls is a code object. |
390 MachineType target_type = MachineType::AnyTagged(); | 389 MachineType target_type = MachineType::AnyTagged(); |
391 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); | 390 LinkageLocation target_loc = |
| 391 LinkageLocation::ForAnyRegister(MachineType::AnyTagged()); |
392 return new (zone) CallDescriptor( // -- | 392 return new (zone) CallDescriptor( // -- |
393 CallDescriptor::kCallCodeObject, // kind | 393 CallDescriptor::kCallCodeObject, // kind |
394 target_type, // target MachineType | 394 target_type, // target MachineType |
395 target_loc, // target location | 395 target_loc, // target location |
396 types.Build(), // machine_sig | |
397 locations.Build(), // location_sig | 396 locations.Build(), // location_sig |
398 stack_parameter_count, // stack_parameter_count | 397 stack_parameter_count, // stack_parameter_count |
399 properties, // properties | 398 properties, // properties |
400 kNoCalleeSaved, // callee-saved registers | 399 kNoCalleeSaved, // callee-saved registers |
401 kNoCalleeSaved, // callee-saved fp | 400 kNoCalleeSaved, // callee-saved fp |
402 CallDescriptor::kCanUseRoots | // flags | 401 CallDescriptor::kCanUseRoots | // flags |
403 flags, // flags | 402 flags, // flags |
404 descriptor.DebugName(isolate)); | 403 descriptor.DebugName(isolate)); |
405 } | 404 } |
406 | 405 |
407 // static | 406 // static |
408 CallDescriptor* Linkage::GetAllocateCallDescriptor(Zone* zone) { | 407 CallDescriptor* Linkage::GetAllocateCallDescriptor(Zone* zone) { |
409 LocationSignature::Builder locations(zone, 1, 1); | 408 LocationSignature::Builder locations(zone, 1, 1); |
410 MachineSignature::Builder types(zone, 1, 1); | |
411 | 409 |
412 locations.AddParam(regloc(kAllocateSizeRegister)); | 410 locations.AddParam(regloc(kAllocateSizeRegister, MachineType::Int32())); |
413 types.AddParam(MachineType::Int32()); | |
414 | 411 |
415 locations.AddReturn(regloc(kReturnRegister0)); | 412 locations.AddReturn(regloc(kReturnRegister0, MachineType::AnyTagged())); |
416 types.AddReturn(MachineType::AnyTagged()); | |
417 | 413 |
418 // The target for allocate calls is a code object. | 414 // The target for allocate calls is a code object. |
419 MachineType target_type = MachineType::AnyTagged(); | 415 MachineType target_type = MachineType::AnyTagged(); |
420 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); | 416 LinkageLocation target_loc = |
| 417 LinkageLocation::ForAnyRegister(MachineType::AnyTagged()); |
421 return new (zone) CallDescriptor( // -- | 418 return new (zone) CallDescriptor( // -- |
422 CallDescriptor::kCallCodeObject, // kind | 419 CallDescriptor::kCallCodeObject, // kind |
423 target_type, // target MachineType | 420 target_type, // target MachineType |
424 target_loc, // target location | 421 target_loc, // target location |
425 types.Build(), // machine_sig | |
426 locations.Build(), // location_sig | 422 locations.Build(), // location_sig |
427 0, // stack_parameter_count | 423 0, // stack_parameter_count |
428 Operator::kNoThrow, // properties | 424 Operator::kNoThrow, // properties |
429 kNoCalleeSaved, // callee-saved registers | 425 kNoCalleeSaved, // callee-saved registers |
430 kNoCalleeSaved, // callee-saved fp | 426 kNoCalleeSaved, // callee-saved fp |
431 CallDescriptor::kCanUseRoots, // flags | 427 CallDescriptor::kCanUseRoots, // flags |
432 "Allocate"); | 428 "Allocate"); |
433 } | 429 } |
434 | 430 |
435 // static | 431 // static |
436 CallDescriptor* Linkage::GetBytecodeDispatchCallDescriptor( | 432 CallDescriptor* Linkage::GetBytecodeDispatchCallDescriptor( |
437 Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, | 433 Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, |
438 int stack_parameter_count) { | 434 int stack_parameter_count) { |
439 const int register_parameter_count = descriptor.GetRegisterParameterCount(); | 435 const int register_parameter_count = descriptor.GetRegisterParameterCount(); |
440 const int parameter_count = register_parameter_count + stack_parameter_count; | 436 const int parameter_count = register_parameter_count + stack_parameter_count; |
441 | 437 |
442 LocationSignature::Builder locations(zone, 0, parameter_count); | 438 LocationSignature::Builder locations(zone, 0, parameter_count); |
443 MachineSignature::Builder types(zone, 0, parameter_count); | |
444 | 439 |
445 // Add parameters in registers and on the stack. | 440 // Add parameters in registers and on the stack. |
446 for (int i = 0; i < parameter_count; i++) { | 441 for (int i = 0; i < parameter_count; i++) { |
447 if (i < register_parameter_count) { | 442 if (i < register_parameter_count) { |
448 // The first parameters go in registers. | 443 // The first parameters go in registers. |
449 Register reg = descriptor.GetRegisterParameter(i); | 444 Register reg = descriptor.GetRegisterParameter(i); |
450 Representation rep = | 445 MachineType type = |
451 RepresentationFromType(descriptor.GetParameterType(i)); | 446 reptyp(RepresentationFromType(descriptor.GetParameterType(i))); |
452 locations.AddParam(regloc(reg)); | 447 locations.AddParam(regloc(reg, type)); |
453 types.AddParam(reptyp(rep)); | |
454 } else { | 448 } else { |
455 // The rest of the parameters go on the stack. | 449 // The rest of the parameters go on the stack. |
456 int stack_slot = i - register_parameter_count - stack_parameter_count; | 450 int stack_slot = i - register_parameter_count - stack_parameter_count; |
457 locations.AddParam(LinkageLocation::ForCallerFrameSlot(stack_slot)); | 451 locations.AddParam(LinkageLocation::ForCallerFrameSlot( |
458 types.AddParam(MachineType::AnyTagged()); | 452 stack_slot, MachineType::AnyTagged())); |
459 } | 453 } |
460 } | 454 } |
461 | 455 |
462 // The target for interpreter dispatches is a code entry address. | 456 // The target for interpreter dispatches is a code entry address. |
463 MachineType target_type = MachineType::Pointer(); | 457 MachineType target_type = MachineType::Pointer(); |
464 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); | 458 LinkageLocation target_loc = LinkageLocation::ForAnyRegister(target_type); |
465 return new (zone) CallDescriptor( // -- | 459 return new (zone) CallDescriptor( // -- |
466 CallDescriptor::kCallAddress, // kind | 460 CallDescriptor::kCallAddress, // kind |
467 target_type, // target MachineType | 461 target_type, // target MachineType |
468 target_loc, // target location | 462 target_loc, // target location |
469 types.Build(), // machine_sig | |
470 locations.Build(), // location_sig | 463 locations.Build(), // location_sig |
471 stack_parameter_count, // stack_parameter_count | 464 stack_parameter_count, // stack_parameter_count |
472 Operator::kNoProperties, // properties | 465 Operator::kNoProperties, // properties |
473 kNoCalleeSaved, // callee-saved registers | 466 kNoCalleeSaved, // callee-saved registers |
474 kNoCalleeSaved, // callee-saved fp | 467 kNoCalleeSaved, // callee-saved fp |
475 CallDescriptor::kCanUseRoots | // flags | 468 CallDescriptor::kCanUseRoots | // flags |
476 CallDescriptor::kSupportsTailCalls, // flags | 469 CallDescriptor::kSupportsTailCalls, // flags |
477 descriptor.DebugName(isolate)); | 470 descriptor.DebugName(isolate)); |
478 } | 471 } |
479 | 472 |
480 LinkageLocation Linkage::GetOsrValueLocation(int index) const { | 473 LinkageLocation Linkage::GetOsrValueLocation(int index) const { |
481 CHECK(incoming_->IsJSFunctionCall()); | 474 CHECK(incoming_->IsJSFunctionCall()); |
482 int parameter_count = static_cast<int>(incoming_->JSParameterCount() - 1); | 475 int parameter_count = static_cast<int>(incoming_->JSParameterCount() - 1); |
483 int first_stack_slot = OsrHelper::FirstStackSlotIndex(parameter_count); | 476 int first_stack_slot = OsrHelper::FirstStackSlotIndex(parameter_count); |
484 | 477 |
485 if (index == kOsrContextSpillSlotIndex) { | 478 if (index == kOsrContextSpillSlotIndex) { |
486 // Context. Use the parameter location of the context spill slot. | 479 // Context. Use the parameter location of the context spill slot. |
487 // Parameter (arity + 2) is special for the context of the function frame. | 480 // Parameter (arity + 2) is special for the context of the function frame. |
488 // >> context_index = target + receiver + params + new_target + #args | 481 // >> context_index = target + receiver + params + new_target + #args |
489 int context_index = 1 + 1 + parameter_count + 1 + 1; | 482 int context_index = 1 + 1 + parameter_count + 1 + 1; |
490 return incoming_->GetInputLocation(context_index); | 483 return incoming_->GetInputLocation(context_index); |
491 } else if (index >= first_stack_slot) { | 484 } else if (index >= first_stack_slot) { |
492 // Local variable stored in this (callee) stack. | 485 // Local variable stored in this (callee) stack. |
493 int spill_index = | 486 int spill_index = |
494 index - first_stack_slot + StandardFrameConstants::kFixedSlotCount; | 487 index - first_stack_slot + StandardFrameConstants::kFixedSlotCount; |
495 return LinkageLocation::ForCalleeFrameSlot(spill_index); | 488 return LinkageLocation::ForCalleeFrameSlot(spill_index, |
| 489 MachineType::AnyTagged()); |
496 } else { | 490 } else { |
497 // Parameter. Use the assigned location from the incoming call descriptor. | 491 // Parameter. Use the assigned location from the incoming call descriptor. |
498 int parameter_index = 1 + index; // skip index 0, which is the target. | 492 int parameter_index = 1 + index; // skip index 0, which is the target. |
499 return incoming_->GetInputLocation(parameter_index); | 493 return incoming_->GetInputLocation(parameter_index); |
500 } | 494 } |
501 } | 495 } |
502 | 496 |
503 | 497 |
504 bool Linkage::ParameterHasSecondaryLocation(int index) const { | 498 bool Linkage::ParameterHasSecondaryLocation(int index) const { |
505 if (!incoming_->IsJSFunctionCall()) return false; | 499 if (!incoming_->IsJSFunctionCall()) return false; |
506 LinkageLocation loc = GetParameterLocation(index); | 500 LinkageLocation loc = GetParameterLocation(index); |
507 return (loc == regloc(kJSFunctionRegister) || | 501 return (loc == regloc(kJSFunctionRegister, MachineType::AnyTagged()) || |
508 loc == regloc(kContextRegister)); | 502 loc == regloc(kContextRegister, MachineType::AnyTagged())); |
509 } | 503 } |
510 | 504 |
511 LinkageLocation Linkage::GetParameterSecondaryLocation(int index) const { | 505 LinkageLocation Linkage::GetParameterSecondaryLocation(int index) const { |
512 DCHECK(ParameterHasSecondaryLocation(index)); | 506 DCHECK(ParameterHasSecondaryLocation(index)); |
513 LinkageLocation loc = GetParameterLocation(index); | 507 LinkageLocation loc = GetParameterLocation(index); |
514 | 508 |
515 if (loc == regloc(kJSFunctionRegister)) { | 509 if (loc == regloc(kJSFunctionRegister, MachineType::AnyTagged())) { |
516 return LinkageLocation::ForCalleeFrameSlot(Frame::kJSFunctionSlot); | 510 return LinkageLocation::ForCalleeFrameSlot(Frame::kJSFunctionSlot, |
| 511 MachineType::AnyTagged()); |
517 } else { | 512 } else { |
518 DCHECK(loc == regloc(kContextRegister)); | 513 DCHECK(loc == regloc(kContextRegister, MachineType::AnyTagged())); |
519 return LinkageLocation::ForCalleeFrameSlot(Frame::kContextSlot); | 514 return LinkageLocation::ForCalleeFrameSlot(Frame::kContextSlot, |
| 515 MachineType::AnyTagged()); |
520 } | 516 } |
521 } | 517 } |
522 | 518 |
523 | 519 |
524 } // namespace compiler | 520 } // namespace compiler |
525 } // namespace internal | 521 } // namespace internal |
526 } // namespace v8 | 522 } // namespace v8 |
OLD | NEW |