OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
8 #include "src/compiler/gap-resolver.h" | 8 #include "src/compiler/gap-resolver.h" |
9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
10 #include "src/scopes.h" | 10 #include "src/scopes.h" |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 if (instr->InputAt(4)->IsRegister()) { \ | 520 if (instr->InputAt(4)->IsRegister()) { \ |
521 Register value = i.InputRegister(4); \ | 521 Register value = i.InputRegister(4); \ |
522 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register); \ | 522 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register); \ |
523 } else { \ | 523 } else { \ |
524 Immediate value = i.InputImmediate(4); \ | 524 Immediate value = i.InputImmediate(4); \ |
525 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \ | 525 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \ |
526 } \ | 526 } \ |
527 } while (false) | 527 } while (false) |
528 | 528 |
529 | 529 |
| 530 void CodeGenerator::AssembleDeconstructActivationRecord() { |
| 531 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| 532 int stack_slots = frame()->GetSpillSlotCount(); |
| 533 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { |
| 534 __ movq(rsp, rbp); |
| 535 __ popq(rbp); |
| 536 int32_t bytes_to_pop = |
| 537 descriptor->IsJSFunctionCall() |
| 538 ? static_cast<int32_t>(descriptor->JSParameterCount() * |
| 539 kPointerSize) |
| 540 : 0; |
| 541 __ popq(Operand(rsp, bytes_to_pop)); |
| 542 __ addq(rsp, Immediate(bytes_to_pop)); |
| 543 } |
| 544 } |
| 545 |
| 546 |
530 // Assembles an instruction after register allocation, producing machine code. | 547 // Assembles an instruction after register allocation, producing machine code. |
531 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 548 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
532 X64OperandConverter i(this, instr); | 549 X64OperandConverter i(this, instr); |
533 | 550 |
534 switch (ArchOpcodeField::decode(instr->opcode())) { | 551 switch (ArchOpcodeField::decode(instr->opcode())) { |
535 case kArchCallCodeObject: { | 552 case kArchCallCodeObject: { |
536 EnsureSpaceForLazyDeopt(); | 553 EnsureSpaceForLazyDeopt(); |
537 if (HasImmediateInput(instr, 0)) { | 554 if (HasImmediateInput(instr, 0)) { |
538 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 555 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
539 __ Call(code, RelocInfo::CODE_TARGET); | 556 __ Call(code, RelocInfo::CODE_TARGET); |
540 } else { | 557 } else { |
541 Register reg = i.InputRegister(0); | 558 Register reg = i.InputRegister(0); |
542 int entry = Code::kHeaderSize - kHeapObjectTag; | 559 int entry = Code::kHeaderSize - kHeapObjectTag; |
543 __ Call(Operand(reg, entry)); | 560 __ Call(Operand(reg, entry)); |
544 } | 561 } |
545 RecordCallPosition(instr); | 562 RecordCallPosition(instr); |
546 break; | 563 break; |
547 } | 564 } |
| 565 case kArchTailCallCodeObject: { |
| 566 AssembleDeconstructActivationRecord(); |
| 567 if (HasImmediateInput(instr, 0)) { |
| 568 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
| 569 __ jmp(code, RelocInfo::CODE_TARGET); |
| 570 } else { |
| 571 Register reg = i.InputRegister(0); |
| 572 int entry = Code::kHeaderSize - kHeapObjectTag; |
| 573 __ jmp(Operand(reg, entry)); |
| 574 } |
| 575 break; |
| 576 } |
548 case kArchCallJSFunction: { | 577 case kArchCallJSFunction: { |
549 EnsureSpaceForLazyDeopt(); | 578 EnsureSpaceForLazyDeopt(); |
550 Register func = i.InputRegister(0); | 579 Register func = i.InputRegister(0); |
551 if (FLAG_debug_code) { | 580 if (FLAG_debug_code) { |
552 // Check the function's context matches the context argument. | 581 // Check the function's context matches the context argument. |
553 __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); | 582 __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); |
554 __ Assert(equal, kWrongFunctionContext); | 583 __ Assert(equal, kWrongFunctionContext); |
555 } | 584 } |
556 __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset)); | 585 __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset)); |
557 RecordCallPosition(instr); | 586 RecordCallPosition(instr); |
558 break; | 587 break; |
559 } | 588 } |
| 589 case kArchTailCallJSFunction: { |
| 590 Register func = i.InputRegister(0); |
| 591 if (FLAG_debug_code) { |
| 592 // Check the function's context matches the context argument. |
| 593 __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); |
| 594 __ Assert(equal, kWrongFunctionContext); |
| 595 } |
| 596 AssembleDeconstructActivationRecord(); |
| 597 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); |
| 598 break; |
| 599 } |
560 case kArchJmp: | 600 case kArchJmp: |
561 AssembleArchJump(i.InputRpo(0)); | 601 AssembleArchJump(i.InputRpo(0)); |
562 break; | 602 break; |
563 case kArchLookupSwitch: | 603 case kArchLookupSwitch: |
564 AssembleArchLookupSwitch(instr); | 604 AssembleArchLookupSwitch(instr); |
565 break; | 605 break; |
566 case kArchTableSwitch: | 606 case kArchTableSwitch: |
567 AssembleArchTableSwitch(instr); | 607 AssembleArchTableSwitch(instr); |
568 break; | 608 break; |
569 case kArchNop: | 609 case kArchNop: |
(...skipping 1095 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1665 } | 1705 } |
1666 } | 1706 } |
1667 MarkLazyDeoptSite(); | 1707 MarkLazyDeoptSite(); |
1668 } | 1708 } |
1669 | 1709 |
1670 #undef __ | 1710 #undef __ |
1671 | 1711 |
1672 } // namespace internal | 1712 } // namespace internal |
1673 } // namespace compiler | 1713 } // namespace compiler |
1674 } // namespace v8 | 1714 } // namespace v8 |
OLD | NEW |