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/compiler/osr.h" | 10 #include "src/compiler/osr.h" |
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 Register value = i.InputRegister(4); \ | 567 Register value = i.InputRegister(4); \ |
568 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register); \ | 568 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register); \ |
569 } else { \ | 569 } else { \ |
570 Immediate value = i.InputImmediate(4); \ | 570 Immediate value = i.InputImmediate(4); \ |
571 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \ | 571 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \ |
572 } \ | 572 } \ |
573 } while (false) | 573 } while (false) |
574 | 574 |
575 | 575 |
576 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { | 576 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { |
| 577 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
| 578 if (sp_slot_delta > 0) { |
| 579 __ addq(rsp, Immediate(sp_slot_delta * kPointerSize)); |
| 580 } |
577 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 581 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
578 int stack_slots = frame()->GetSpillSlotCount(); | 582 int spill_slots = frame()->GetSpillSlotCount(); |
579 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { | 583 bool has_frame = descriptor->IsJSFunctionCall() || spill_slots > 0; |
580 __ movq(rsp, rbp); | 584 if (has_frame) { |
581 __ popq(rbp); | 585 __ popq(rbp); |
582 } | 586 } |
583 if (stack_param_delta < 0) { | |
584 int offset = -(stack_param_delta + 1) * kPointerSize; | |
585 __ popq(Operand(rsp, offset)); | |
586 if (offset != 0) { | |
587 __ addq(rsp, Immediate(offset)); | |
588 } | |
589 } | |
590 } | 587 } |
591 | 588 |
| 589 |
| 590 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { |
| 591 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); |
| 592 if (sp_slot_delta < 0) { |
| 593 __ subq(rsp, Immediate(-sp_slot_delta * kPointerSize)); |
| 594 } |
| 595 } |
| 596 |
592 | 597 |
593 // Assembles an instruction after register allocation, producing machine code. | 598 // Assembles an instruction after register allocation, producing machine code. |
594 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 599 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
595 X64OperandConverter i(this, instr); | 600 X64OperandConverter i(this, instr); |
596 | 601 |
597 switch (ArchOpcodeField::decode(instr->opcode())) { | 602 switch (ArchOpcodeField::decode(instr->opcode())) { |
598 case kArchCallCodeObject: { | 603 case kArchCallCodeObject: { |
599 EnsureSpaceForLazyDeopt(); | 604 EnsureSpaceForLazyDeopt(); |
600 if (HasImmediateInput(instr, 0)) { | 605 if (HasImmediateInput(instr, 0)) { |
601 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 606 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 case kArchLazyBailout: { | 653 case kArchLazyBailout: { |
649 EnsureSpaceForLazyDeopt(); | 654 EnsureSpaceForLazyDeopt(); |
650 RecordCallPosition(instr); | 655 RecordCallPosition(instr); |
651 break; | 656 break; |
652 } | 657 } |
653 case kArchPrepareCallCFunction: { | 658 case kArchPrepareCallCFunction: { |
654 int const num_parameters = MiscField::decode(instr->opcode()); | 659 int const num_parameters = MiscField::decode(instr->opcode()); |
655 __ PrepareCallCFunction(num_parameters); | 660 __ PrepareCallCFunction(num_parameters); |
656 break; | 661 break; |
657 } | 662 } |
| 663 case kArchPrepareTailCall: |
| 664 AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1)); |
| 665 break; |
658 case kArchCallCFunction: { | 666 case kArchCallCFunction: { |
659 int const num_parameters = MiscField::decode(instr->opcode()); | 667 int const num_parameters = MiscField::decode(instr->opcode()); |
660 if (HasImmediateInput(instr, 0)) { | 668 if (HasImmediateInput(instr, 0)) { |
661 ExternalReference ref = i.InputExternalReference(0); | 669 ExternalReference ref = i.InputExternalReference(0); |
662 __ CallCFunction(ref, num_parameters); | 670 __ CallCFunction(ref, num_parameters); |
663 } else { | 671 } else { |
664 Register func = i.InputRegister(0); | 672 Register func = i.InputRegister(0); |
665 __ CallCFunction(func, num_parameters); | 673 __ CallCFunction(func, num_parameters); |
666 } | 674 } |
667 break; | 675 break; |
(...skipping 1272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1940 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 1948 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
1941 __ Nop(padding_size); | 1949 __ Nop(padding_size); |
1942 } | 1950 } |
1943 } | 1951 } |
1944 | 1952 |
1945 #undef __ | 1953 #undef __ |
1946 | 1954 |
1947 } // namespace compiler | 1955 } // namespace compiler |
1948 } // namespace internal | 1956 } // namespace internal |
1949 } // namespace v8 | 1957 } // namespace v8 |
OLD | NEW |