| 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 |