| 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/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
| 9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 if (sp_slot_delta < 0) { | 614 if (sp_slot_delta < 0) { |
| 615 __ subq(rsp, Immediate(-sp_slot_delta * kPointerSize)); | 615 __ subq(rsp, Immediate(-sp_slot_delta * kPointerSize)); |
| 616 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); | 616 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); |
| 617 } | 617 } |
| 618 if (frame()->needs_frame()) { | 618 if (frame()->needs_frame()) { |
| 619 __ movq(rbp, MemOperand(rbp, 0)); | 619 __ movq(rbp, MemOperand(rbp, 0)); |
| 620 } | 620 } |
| 621 frame_access_state()->SetFrameAccessToSP(); | 621 frame_access_state()->SetFrameAccessToSP(); |
| 622 } | 622 } |
| 623 | 623 |
| 624 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, |
| 625 Register scratch1, |
| 626 Register scratch2, |
| 627 Register scratch3) { |
| 628 DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3)); |
| 629 Label done; |
| 630 |
| 631 // Check if current frame is an arguments adaptor frame. |
| 632 __ Cmp(Operand(rbp, StandardFrameConstants::kContextOffset), |
| 633 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
| 634 __ j(not_equal, &done, Label::kNear); |
| 635 |
| 636 // Load arguments count from current arguments adaptor frame (note, it |
| 637 // does not include receiver). |
| 638 Register caller_args_count_reg = scratch1; |
| 639 __ SmiToInteger32( |
| 640 caller_args_count_reg, |
| 641 Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 642 |
| 643 ParameterCount callee_args_count(args_reg); |
| 644 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, |
| 645 scratch3, ReturnAddressState::kOnStack); |
| 646 __ bind(&done); |
| 647 } |
| 624 | 648 |
| 625 // Assembles an instruction after register allocation, producing machine code. | 649 // Assembles an instruction after register allocation, producing machine code. |
| 626 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 650 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
| 627 X64OperandConverter i(this, instr); | 651 X64OperandConverter i(this, instr); |
| 628 | 652 InstructionCode opcode = instr->opcode(); |
| 629 switch (ArchOpcodeField::decode(instr->opcode())) { | 653 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); |
| 654 switch (arch_opcode) { |
| 630 case kArchCallCodeObject: { | 655 case kArchCallCodeObject: { |
| 631 EnsureSpaceForLazyDeopt(); | 656 EnsureSpaceForLazyDeopt(); |
| 632 if (HasImmediateInput(instr, 0)) { | 657 if (HasImmediateInput(instr, 0)) { |
| 633 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 658 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
| 634 __ Call(code, RelocInfo::CODE_TARGET); | 659 __ Call(code, RelocInfo::CODE_TARGET); |
| 635 } else { | 660 } else { |
| 636 Register reg = i.InputRegister(0); | 661 Register reg = i.InputRegister(0); |
| 637 __ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 662 __ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 638 __ call(reg); | 663 __ call(reg); |
| 639 } | 664 } |
| 640 RecordCallPosition(instr); | 665 RecordCallPosition(instr); |
| 641 frame_access_state()->ClearSPDelta(); | 666 frame_access_state()->ClearSPDelta(); |
| 642 break; | 667 break; |
| 643 } | 668 } |
| 669 case kArchTailCallCodeObjectFromJSFunction: |
| 644 case kArchTailCallCodeObject: { | 670 case kArchTailCallCodeObject: { |
| 645 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); | 671 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); |
| 646 AssembleDeconstructActivationRecord(stack_param_delta); | 672 AssembleDeconstructActivationRecord(stack_param_delta); |
| 673 if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) { |
| 674 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, |
| 675 i.TempRegister(0), i.TempRegister(1), |
| 676 i.TempRegister(2)); |
| 677 } |
| 647 if (HasImmediateInput(instr, 0)) { | 678 if (HasImmediateInput(instr, 0)) { |
| 648 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 679 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
| 649 __ jmp(code, RelocInfo::CODE_TARGET); | 680 __ jmp(code, RelocInfo::CODE_TARGET); |
| 650 } else { | 681 } else { |
| 651 Register reg = i.InputRegister(0); | 682 Register reg = i.InputRegister(0); |
| 652 __ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 683 __ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 653 __ jmp(reg); | 684 __ jmp(reg); |
| 654 } | 685 } |
| 655 frame_access_state()->ClearSPDelta(); | 686 frame_access_state()->ClearSPDelta(); |
| 656 break; | 687 break; |
| 657 } | 688 } |
| 658 case kArchCallJSFunction: { | 689 case kArchCallJSFunction: { |
| 659 EnsureSpaceForLazyDeopt(); | 690 EnsureSpaceForLazyDeopt(); |
| 660 Register func = i.InputRegister(0); | 691 Register func = i.InputRegister(0); |
| 661 if (FLAG_debug_code) { | 692 if (FLAG_debug_code) { |
| 662 // Check the function's context matches the context argument. | 693 // Check the function's context matches the context argument. |
| 663 __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); | 694 __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); |
| 664 __ Assert(equal, kWrongFunctionContext); | 695 __ Assert(equal, kWrongFunctionContext); |
| 665 } | 696 } |
| 666 __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset)); | 697 __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset)); |
| 667 frame_access_state()->ClearSPDelta(); | 698 frame_access_state()->ClearSPDelta(); |
| 668 RecordCallPosition(instr); | 699 RecordCallPosition(instr); |
| 669 break; | 700 break; |
| 670 } | 701 } |
| 702 case kArchTailCallJSFunctionFromJSFunction: |
| 671 case kArchTailCallJSFunction: { | 703 case kArchTailCallJSFunction: { |
| 672 Register func = i.InputRegister(0); | 704 Register func = i.InputRegister(0); |
| 673 if (FLAG_debug_code) { | 705 if (FLAG_debug_code) { |
| 674 // Check the function's context matches the context argument. | 706 // Check the function's context matches the context argument. |
| 675 __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); | 707 __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); |
| 676 __ Assert(equal, kWrongFunctionContext); | 708 __ Assert(equal, kWrongFunctionContext); |
| 677 } | 709 } |
| 678 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); | 710 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); |
| 679 AssembleDeconstructActivationRecord(stack_param_delta); | 711 AssembleDeconstructActivationRecord(stack_param_delta); |
| 712 if (arch_opcode == kArchTailCallJSFunctionFromJSFunction) { |
| 713 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, |
| 714 i.TempRegister(0), i.TempRegister(1), |
| 715 i.TempRegister(2)); |
| 716 } |
| 680 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); | 717 __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); |
| 681 frame_access_state()->ClearSPDelta(); | 718 frame_access_state()->ClearSPDelta(); |
| 682 break; | 719 break; |
| 683 } | 720 } |
| 684 case kArchPrepareCallCFunction: { | 721 case kArchPrepareCallCFunction: { |
| 685 // Frame alignment requires using FP-relative frame addressing. | 722 // Frame alignment requires using FP-relative frame addressing. |
| 686 frame_access_state()->SetFrameAccessToFP(); | 723 frame_access_state()->SetFrameAccessToFP(); |
| 687 int const num_parameters = MiscField::decode(instr->opcode()); | 724 int const num_parameters = MiscField::decode(instr->opcode()); |
| 688 __ PrepareCallCFunction(num_parameters); | 725 __ PrepareCallCFunction(num_parameters); |
| 689 break; | 726 break; |
| (...skipping 1501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2191 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2228 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
| 2192 __ Nop(padding_size); | 2229 __ Nop(padding_size); |
| 2193 } | 2230 } |
| 2194 } | 2231 } |
| 2195 | 2232 |
| 2196 #undef __ | 2233 #undef __ |
| 2197 | 2234 |
| 2198 } // namespace compiler | 2235 } // namespace compiler |
| 2199 } // namespace internal | 2236 } // namespace internal |
| 2200 } // namespace v8 | 2237 } // namespace v8 |
| OLD | NEW |