Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(709)

Side by Side Diff: src/compiler/x64/code-generator-x64.cc

Issue 1702423002: [turbofan] Further fixing ES6 tail call elimination in Turbofan. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@tco-turbo
Patch Set: Addressing comments Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/mips64/instruction-selector-mips64.cc ('k') | src/compiler/x64/instruction-selector-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698