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/compiler/instruction-selector.h" | 5 #include "src/compiler/instruction-selector.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/adapters.h" | 9 #include "src/base/adapters.h" |
10 #include "src/compiler/instruction-selector-impl.h" | 10 #include "src/compiler/instruction-selector-impl.h" |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 } | 500 } |
501 DCHECK(!buffer->pushed_nodes[stack_index]); | 501 DCHECK(!buffer->pushed_nodes[stack_index]); |
502 buffer->pushed_nodes[stack_index] = *iter; | 502 buffer->pushed_nodes[stack_index] = *iter; |
503 pushed_count++; | 503 pushed_count++; |
504 } else { | 504 } else { |
505 buffer->instruction_args.push_back(op); | 505 buffer->instruction_args.push_back(op); |
506 } | 506 } |
507 } | 507 } |
508 DCHECK_EQ(input_count, buffer->instruction_args.size() + pushed_count - | 508 DCHECK_EQ(input_count, buffer->instruction_args.size() + pushed_count - |
509 buffer->frame_state_value_count()); | 509 buffer->frame_state_value_count()); |
| 510 if (call_tail && stack_param_delta != 0) { |
| 511 // For tail calls that change the size of their parameter list, move the |
| 512 // saved caller return address, parent frame pointer and parent constant |
| 513 // pool pointer to just above the parameters. |
| 514 |
| 515 // Return address |
| 516 LinkageLocation saved_return_location = |
| 517 LinkageLocation::ForSavedCallerReturnAddress(); |
| 518 InstructionOperand return_address = |
| 519 g.UsePointerLocation(LinkageLocation::ConvertToTailCallerLocation( |
| 520 saved_return_location, stack_param_delta), |
| 521 saved_return_location); |
| 522 buffer->instruction_args.push_back(return_address); |
| 523 |
| 524 // Parent frame pointer |
| 525 LinkageLocation saved_frame_location = |
| 526 LinkageLocation::ForSavedCallerFramePtr(); |
| 527 InstructionOperand saved_frame = |
| 528 g.UsePointerLocation(LinkageLocation::ConvertToTailCallerLocation( |
| 529 saved_frame_location, stack_param_delta), |
| 530 saved_frame_location); |
| 531 buffer->instruction_args.push_back(saved_frame); |
| 532 |
| 533 if (V8_EMBEDDED_CONSTANT_POOL) { |
| 534 // Constant pool pointer |
| 535 LinkageLocation saved_cp_location = |
| 536 LinkageLocation::ForSavedCallerConstantPool(); |
| 537 InstructionOperand saved_cp = |
| 538 g.UsePointerLocation(LinkageLocation::ConvertToTailCallerLocation( |
| 539 saved_cp_location, stack_param_delta), |
| 540 saved_cp_location); |
| 541 buffer->instruction_args.push_back(saved_cp); |
| 542 } |
| 543 } |
510 } | 544 } |
511 | 545 |
512 | 546 |
513 void InstructionSelector::VisitBlock(BasicBlock* block) { | 547 void InstructionSelector::VisitBlock(BasicBlock* block) { |
514 DCHECK(!current_block_); | 548 DCHECK(!current_block_); |
515 current_block_ = block; | 549 current_block_ = block; |
516 int current_block_end = static_cast<int>(instructions_.size()); | 550 int current_block_end = static_cast<int>(instructions_.size()); |
517 | 551 |
518 // Generate code for the block control "top down", but schedule the code | 552 // Generate code for the block control "top down", but schedule the code |
519 // "bottom up". | 553 // "bottom up". |
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1280 opcode = kArchTailCallJSFunction; | 1314 opcode = kArchTailCallJSFunction; |
1281 break; | 1315 break; |
1282 default: | 1316 default: |
1283 UNREACHABLE(); | 1317 UNREACHABLE(); |
1284 return; | 1318 return; |
1285 } | 1319 } |
1286 opcode |= MiscField::encode(descriptor->flags()); | 1320 opcode |= MiscField::encode(descriptor->flags()); |
1287 | 1321 |
1288 buffer.instruction_args.push_back(g.TempImmediate(stack_param_delta)); | 1322 buffer.instruction_args.push_back(g.TempImmediate(stack_param_delta)); |
1289 | 1323 |
| 1324 Emit(kArchPrepareTailCall, g.NoOutput(), |
| 1325 g.TempImmediate(stack_param_delta)); |
| 1326 |
1290 // Emit the tailcall instruction. | 1327 // Emit the tailcall instruction. |
1291 Emit(opcode, 0, nullptr, buffer.instruction_args.size(), | 1328 Emit(opcode, 0, nullptr, buffer.instruction_args.size(), |
1292 &buffer.instruction_args.front()); | 1329 &buffer.instruction_args.front()); |
1293 } else { | 1330 } else { |
1294 FrameStateDescriptor* frame_state_descriptor = | 1331 FrameStateDescriptor* frame_state_descriptor = |
1295 descriptor->NeedsFrameState() | 1332 descriptor->NeedsFrameState() |
1296 ? GetFrameStateDescriptor( | 1333 ? GetFrameStateDescriptor( |
1297 node->InputAt(static_cast<int>(descriptor->InputCount()))) | 1334 node->InputAt(static_cast<int>(descriptor->InputCount()))) |
1298 : nullptr; | 1335 : nullptr; |
1299 | 1336 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1411 return new (instruction_zone()) FrameStateDescriptor( | 1448 return new (instruction_zone()) FrameStateDescriptor( |
1412 instruction_zone(), state_info.type(), state_info.bailout_id(), | 1449 instruction_zone(), state_info.type(), state_info.bailout_id(), |
1413 state_info.state_combine(), parameters, locals, stack, | 1450 state_info.state_combine(), parameters, locals, stack, |
1414 state_info.shared_info(), outer_state); | 1451 state_info.shared_info(), outer_state); |
1415 } | 1452 } |
1416 | 1453 |
1417 | 1454 |
1418 } // namespace compiler | 1455 } // namespace compiler |
1419 } // namespace internal | 1456 } // namespace internal |
1420 } // namespace v8 | 1457 } // namespace v8 |
OLD | NEW |