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

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

Issue 2082263002: [turbofan]: Support using push instructions for setting up tail call parameters (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Review feedback Created 4 years, 5 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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/arm64/frames-arm64.h" 7 #include "src/arm64/frames-arm64.h"
8 #include "src/arm64/macro-assembler-arm64.h" 8 #include "src/arm64/macro-assembler-arm64.h"
9 #include "src/ast/scopes.h" 9 #include "src/ast/scopes.h"
10 #include "src/compiler/code-generator-impl.h" 10 #include "src/compiler/code-generator-impl.h"
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 void CodeGenerator::AssembleDeconstructFrame() { 530 void CodeGenerator::AssembleDeconstructFrame() {
531 const CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 531 const CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
532 if (descriptor->IsCFunctionCall() || descriptor->UseNativeStack()) { 532 if (descriptor->IsCFunctionCall() || descriptor->UseNativeStack()) {
533 __ Mov(csp, fp); 533 __ Mov(csp, fp);
534 } else { 534 } else {
535 __ Mov(jssp, fp); 535 __ Mov(jssp, fp);
536 } 536 }
537 __ Pop(fp, lr); 537 __ Pop(fp, lr);
538 } 538 }
539 539
540 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { 540 void CodeGenerator::AssemblePrepareTailCall() {
541 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
542 if (sp_slot_delta > 0) {
543 __ Drop(sp_slot_delta);
544 }
545 frame_access_state()->SetFrameAccessToDefault();
546 }
547
548
549 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
550 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
551 if (sp_slot_delta < 0) {
552 __ Claim(-sp_slot_delta);
553 frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
554 }
555 if (frame_access_state()->has_frame()) { 541 if (frame_access_state()->has_frame()) {
556 __ Ldr(lr, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); 542 __ Ldr(lr, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
557 __ Ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 543 __ Ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
558 } 544 }
559 frame_access_state()->SetFrameAccessToSP(); 545 frame_access_state()->SetFrameAccessToSP();
560 } 546 }
561 547
562 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, 548 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
563 Register scratch1, 549 Register scratch1,
564 Register scratch2, 550 Register scratch2,
(...skipping 12 matching lines...) Expand all
577 __ Ldr(caller_args_count_reg, 563 __ Ldr(caller_args_count_reg,
578 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); 564 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
579 __ SmiUntag(caller_args_count_reg); 565 __ SmiUntag(caller_args_count_reg);
580 566
581 ParameterCount callee_args_count(args_reg); 567 ParameterCount callee_args_count(args_reg);
582 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, 568 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
583 scratch3); 569 scratch3);
584 __ bind(&done); 570 __ bind(&done);
585 } 571 }
586 572
573 namespace {
574
575 void AdjustStackPointerForGap(MacroAssembler* masm, FrameAccessState* state,
576 int new_slot_above_sp,
577 bool allow_shrinkage = true) {
578 int current_sp_offset = state->GetSPToFPSlotCount() +
579 StandardFrameConstants::kFixedSlotCountAboveFp;
580 int stack_slot_delta = new_slot_above_sp - current_sp_offset;
581 if (stack_slot_delta > 0) {
582 masm->Claim(stack_slot_delta);
583 state->IncreaseSPDelta(stack_slot_delta);
584 } else if (allow_shrinkage && stack_slot_delta < 0) {
585 masm->Drop(-stack_slot_delta);
586 state->IncreaseSPDelta(stack_slot_delta);
587 }
588 }
589
590 } // namespace
591
592 void CodeGenerator::AssemblePreGaps(Instruction* instr) {
593 int first_unused_stack_slot;
594 if (!GetSlotAboveSPAfterGap(instr, &first_unused_stack_slot)) return;
595 AdjustStackPointerForGap(masm(), frame_access_state(),
596 first_unused_stack_slot, false);
597 }
598
599 void CodeGenerator::AssemblePostGaps(Instruction* instr) {
600 int first_unused_stack_slot;
601 if (!GetSlotAboveSPAfterGap(instr, &first_unused_stack_slot)) return;
602 AdjustStackPointerForGap(masm(), frame_access_state(),
603 first_unused_stack_slot);
604 }
605
587 // Assembles an instruction after register allocation, producing machine code. 606 // Assembles an instruction after register allocation, producing machine code.
588 CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( 607 CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
589 Instruction* instr) { 608 Instruction* instr) {
590 Arm64OperandConverter i(this, instr); 609 Arm64OperandConverter i(this, instr);
591 InstructionCode opcode = instr->opcode(); 610 InstructionCode opcode = instr->opcode();
592 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); 611 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
593 switch (arch_opcode) { 612 switch (arch_opcode) {
594 case kArchCallCodeObject: { 613 case kArchCallCodeObject: {
595 EnsureSpaceForLazyDeopt(); 614 EnsureSpaceForLazyDeopt();
596 if (instr->InputAt(0)->IsImmediate()) { 615 if (instr->InputAt(0)->IsImmediate()) {
(...skipping 15 matching lines...) Expand all
612 } 631 }
613 if (flags & CallDescriptor::kRestoreCSP) { 632 if (flags & CallDescriptor::kRestoreCSP) {
614 __ Mov(csp, jssp); 633 __ Mov(csp, jssp);
615 __ AssertCspAligned(); 634 __ AssertCspAligned();
616 } 635 }
617 frame_access_state()->ClearSPDelta(); 636 frame_access_state()->ClearSPDelta();
618 break; 637 break;
619 } 638 }
620 case kArchTailCallCodeObjectFromJSFunction: 639 case kArchTailCallCodeObjectFromJSFunction:
621 case kArchTailCallCodeObject: { 640 case kArchTailCallCodeObject: {
622 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
623 AssembleDeconstructActivationRecord(stack_param_delta);
624 if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) { 641 if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
625 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 642 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
626 i.TempRegister(0), i.TempRegister(1), 643 i.TempRegister(0), i.TempRegister(1),
627 i.TempRegister(2)); 644 i.TempRegister(2));
628 } 645 }
629 if (instr->InputAt(0)->IsImmediate()) { 646 if (instr->InputAt(0)->IsImmediate()) {
630 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), 647 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
631 RelocInfo::CODE_TARGET); 648 RelocInfo::CODE_TARGET);
632 } else { 649 } else {
633 Register target = i.InputRegister(0); 650 Register target = i.InputRegister(0);
634 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); 651 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
635 __ Jump(target); 652 __ Jump(target);
636 } 653 }
637 frame_access_state()->ClearSPDelta(); 654 frame_access_state()->ClearSPDelta();
655 frame_access_state()->SetFrameAccessToDefault();
638 break; 656 break;
639 } 657 }
640 case kArchTailCallAddress: { 658 case kArchTailCallAddress: {
641 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
642 AssembleDeconstructActivationRecord(stack_param_delta);
643 CHECK(!instr->InputAt(0)->IsImmediate()); 659 CHECK(!instr->InputAt(0)->IsImmediate());
644 __ Jump(i.InputRegister(0)); 660 __ Jump(i.InputRegister(0));
645 frame_access_state()->ClearSPDelta(); 661 frame_access_state()->ClearSPDelta();
662 frame_access_state()->SetFrameAccessToDefault();
646 break; 663 break;
647 } 664 }
648 case kArchCallJSFunction: { 665 case kArchCallJSFunction: {
649 EnsureSpaceForLazyDeopt(); 666 EnsureSpaceForLazyDeopt();
650 Register func = i.InputRegister(0); 667 Register func = i.InputRegister(0);
651 if (FLAG_debug_code) { 668 if (FLAG_debug_code) {
652 // Check the function's context matches the context argument. 669 // Check the function's context matches the context argument.
653 UseScratchRegisterScope scope(masm()); 670 UseScratchRegisterScope scope(masm());
654 Register temp = scope.AcquireX(); 671 Register temp = scope.AcquireX();
655 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset)); 672 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset));
(...skipping 22 matching lines...) Expand all
678 case kArchTailCallJSFunction: { 695 case kArchTailCallJSFunction: {
679 Register func = i.InputRegister(0); 696 Register func = i.InputRegister(0);
680 if (FLAG_debug_code) { 697 if (FLAG_debug_code) {
681 // Check the function's context matches the context argument. 698 // Check the function's context matches the context argument.
682 UseScratchRegisterScope scope(masm()); 699 UseScratchRegisterScope scope(masm());
683 Register temp = scope.AcquireX(); 700 Register temp = scope.AcquireX();
684 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset)); 701 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset));
685 __ cmp(cp, temp); 702 __ cmp(cp, temp);
686 __ Assert(eq, kWrongFunctionContext); 703 __ Assert(eq, kWrongFunctionContext);
687 } 704 }
688 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
689 AssembleDeconstructActivationRecord(stack_param_delta);
690 if (arch_opcode == kArchTailCallJSFunctionFromJSFunction) { 705 if (arch_opcode == kArchTailCallJSFunctionFromJSFunction) {
691 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 706 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
692 i.TempRegister(0), i.TempRegister(1), 707 i.TempRegister(0), i.TempRegister(1),
693 i.TempRegister(2)); 708 i.TempRegister(2));
694 } 709 }
695 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 710 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
696 __ Jump(x10); 711 __ Jump(x10);
697 frame_access_state()->ClearSPDelta(); 712 frame_access_state()->ClearSPDelta();
713 frame_access_state()->SetFrameAccessToDefault();
698 break; 714 break;
699 } 715 }
700 case kArchPrepareCallCFunction: 716 case kArchPrepareCallCFunction:
701 // We don't need kArchPrepareCallCFunction on arm64 as the instruction 717 // We don't need kArchPrepareCallCFunction on arm64 as the instruction
702 // selector already perform a Claim to reserve space on the stack and 718 // selector already perform a Claim to reserve space on the stack and
703 // guarantee correct alignment of stack pointer. 719 // guarantee correct alignment of stack pointer.
704 UNREACHABLE(); 720 UNREACHABLE();
705 break; 721 break;
706 case kArchPrepareTailCall: 722 case kArchPrepareTailCall:
707 AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1)); 723 AssemblePrepareTailCall();
708 break; 724 break;
709 case kArchCallCFunction: { 725 case kArchCallCFunction: {
710 int const num_parameters = MiscField::decode(instr->opcode()); 726 int const num_parameters = MiscField::decode(instr->opcode());
711 if (instr->InputAt(0)->IsImmediate()) { 727 if (instr->InputAt(0)->IsImmediate()) {
712 ExternalReference ref = i.InputExternalReference(0); 728 ExternalReference ref = i.InputExternalReference(0);
713 __ CallCFunction(ref, num_parameters, 0); 729 __ CallCFunction(ref, num_parameters, 0);
714 } else { 730 } else {
715 Register func = i.InputRegister(0); 731 Register func = i.InputRegister(0);
716 __ CallCFunction(func, num_parameters, 0); 732 __ CallCFunction(func, num_parameters, 0);
717 } 733 }
(...skipping 1269 matching lines...) Expand 10 before | Expand all | Expand 10 after
1987 padding_size -= kInstructionSize; 2003 padding_size -= kInstructionSize;
1988 } 2004 }
1989 } 2005 }
1990 } 2006 }
1991 2007
1992 #undef __ 2008 #undef __
1993 2009
1994 } // namespace compiler 2010 } // namespace compiler
1995 } // namespace internal 2011 } // namespace internal
1996 } // namespace v8 2012 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698