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

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: Remove stray test change 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 void AdjustStackPointerForGap(MacroAssembler* masm, FrameAccessState* state,
575 int new_slot_above_sp,
576 bool allow_shrinkage = true) {
577 int current_sp_offset = state->GetSPToFPSlotCount() +
578 StandardFrameConstants::kFixedSlotCountAboveFp;
579 int stack_slot_delta = new_slot_above_sp - current_sp_offset;
580 if (stack_slot_delta > 0) {
581 masm->Claim(stack_slot_delta);
582 state->IncreaseSPDelta(stack_slot_delta);
583 } else if (allow_shrinkage && stack_slot_delta < 0) {
584 masm->Drop(-stack_slot_delta);
585 state->IncreaseSPDelta(stack_slot_delta);
586 }
587 }
588 } // namespace
589
590 void CodeGenerator::AssemblePreGaps(Instruction* instr) {
591 int first_unused_stack_slot;
592 if (!GetSlotAboveSPAfterGap(instr, &first_unused_stack_slot)) return;
593 AdjustStackPointerForGap(masm(), frame_access_state(),
594 first_unused_stack_slot, false);
595 }
596
597 void CodeGenerator::AssemblePostGaps(Instruction* instr) {
598 int first_unused_stack_slot;
599 if (!GetSlotAboveSPAfterGap(instr, &first_unused_stack_slot)) return;
600 AdjustStackPointerForGap(masm(), frame_access_state(),
601 first_unused_stack_slot);
602 }
603
587 // Assembles an instruction after register allocation, producing machine code. 604 // Assembles an instruction after register allocation, producing machine code.
588 CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( 605 CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
589 Instruction* instr) { 606 Instruction* instr) {
590 Arm64OperandConverter i(this, instr); 607 Arm64OperandConverter i(this, instr);
591 InstructionCode opcode = instr->opcode(); 608 InstructionCode opcode = instr->opcode();
592 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); 609 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
593 switch (arch_opcode) { 610 switch (arch_opcode) {
594 case kArchCallCodeObject: { 611 case kArchCallCodeObject: {
595 EnsureSpaceForLazyDeopt(); 612 EnsureSpaceForLazyDeopt();
596 if (instr->InputAt(0)->IsImmediate()) { 613 if (instr->InputAt(0)->IsImmediate()) {
(...skipping 15 matching lines...) Expand all
612 } 629 }
613 if (flags & CallDescriptor::kRestoreCSP) { 630 if (flags & CallDescriptor::kRestoreCSP) {
614 __ Mov(csp, jssp); 631 __ Mov(csp, jssp);
615 __ AssertCspAligned(); 632 __ AssertCspAligned();
616 } 633 }
617 frame_access_state()->ClearSPDelta(); 634 frame_access_state()->ClearSPDelta();
618 break; 635 break;
619 } 636 }
620 case kArchTailCallCodeObjectFromJSFunction: 637 case kArchTailCallCodeObjectFromJSFunction:
621 case kArchTailCallCodeObject: { 638 case kArchTailCallCodeObject: {
622 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
623 AssembleDeconstructActivationRecord(stack_param_delta);
624 if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) { 639 if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
625 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 640 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
626 i.TempRegister(0), i.TempRegister(1), 641 i.TempRegister(0), i.TempRegister(1),
627 i.TempRegister(2)); 642 i.TempRegister(2));
628 } 643 }
629 if (instr->InputAt(0)->IsImmediate()) { 644 if (instr->InputAt(0)->IsImmediate()) {
630 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), 645 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
631 RelocInfo::CODE_TARGET); 646 RelocInfo::CODE_TARGET);
632 } else { 647 } else {
633 Register target = i.InputRegister(0); 648 Register target = i.InputRegister(0);
634 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); 649 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
635 __ Jump(target); 650 __ Jump(target);
636 } 651 }
637 frame_access_state()->ClearSPDelta(); 652 frame_access_state()->ClearSPDelta();
653 frame_access_state()->SetFrameAccessToDefault();
638 break; 654 break;
639 } 655 }
640 case kArchTailCallAddress: { 656 case kArchTailCallAddress: {
641 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
642 AssembleDeconstructActivationRecord(stack_param_delta);
643 CHECK(!instr->InputAt(0)->IsImmediate()); 657 CHECK(!instr->InputAt(0)->IsImmediate());
644 __ Jump(i.InputRegister(0)); 658 __ Jump(i.InputRegister(0));
645 frame_access_state()->ClearSPDelta(); 659 frame_access_state()->ClearSPDelta();
660 frame_access_state()->SetFrameAccessToDefault();
646 break; 661 break;
647 } 662 }
648 case kArchCallJSFunction: { 663 case kArchCallJSFunction: {
649 EnsureSpaceForLazyDeopt(); 664 EnsureSpaceForLazyDeopt();
650 Register func = i.InputRegister(0); 665 Register func = i.InputRegister(0);
651 if (FLAG_debug_code) { 666 if (FLAG_debug_code) {
652 // Check the function's context matches the context argument. 667 // Check the function's context matches the context argument.
653 UseScratchRegisterScope scope(masm()); 668 UseScratchRegisterScope scope(masm());
654 Register temp = scope.AcquireX(); 669 Register temp = scope.AcquireX();
655 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset)); 670 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset));
(...skipping 22 matching lines...) Expand all
678 case kArchTailCallJSFunction: { 693 case kArchTailCallJSFunction: {
679 Register func = i.InputRegister(0); 694 Register func = i.InputRegister(0);
680 if (FLAG_debug_code) { 695 if (FLAG_debug_code) {
681 // Check the function's context matches the context argument. 696 // Check the function's context matches the context argument.
682 UseScratchRegisterScope scope(masm()); 697 UseScratchRegisterScope scope(masm());
683 Register temp = scope.AcquireX(); 698 Register temp = scope.AcquireX();
684 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset)); 699 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset));
685 __ cmp(cp, temp); 700 __ cmp(cp, temp);
686 __ Assert(eq, kWrongFunctionContext); 701 __ Assert(eq, kWrongFunctionContext);
687 } 702 }
688 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
689 AssembleDeconstructActivationRecord(stack_param_delta);
690 if (arch_opcode == kArchTailCallJSFunctionFromJSFunction) { 703 if (arch_opcode == kArchTailCallJSFunctionFromJSFunction) {
691 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 704 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
692 i.TempRegister(0), i.TempRegister(1), 705 i.TempRegister(0), i.TempRegister(1),
693 i.TempRegister(2)); 706 i.TempRegister(2));
694 } 707 }
695 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 708 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
696 __ Jump(x10); 709 __ Jump(x10);
697 frame_access_state()->ClearSPDelta(); 710 frame_access_state()->ClearSPDelta();
711 frame_access_state()->SetFrameAccessToDefault();
698 break; 712 break;
699 } 713 }
700 case kArchPrepareCallCFunction: 714 case kArchPrepareCallCFunction:
701 // We don't need kArchPrepareCallCFunction on arm64 as the instruction 715 // We don't need kArchPrepareCallCFunction on arm64 as the instruction
702 // selector already perform a Claim to reserve space on the stack and 716 // selector already perform a Claim to reserve space on the stack and
703 // guarantee correct alignment of stack pointer. 717 // guarantee correct alignment of stack pointer.
704 UNREACHABLE(); 718 UNREACHABLE();
705 break; 719 break;
706 case kArchPrepareTailCall: 720 case kArchPrepareTailCall:
707 AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1)); 721 AssemblePrepareTailCall();
708 break; 722 break;
709 case kArchCallCFunction: { 723 case kArchCallCFunction: {
710 int const num_parameters = MiscField::decode(instr->opcode()); 724 int const num_parameters = MiscField::decode(instr->opcode());
711 if (instr->InputAt(0)->IsImmediate()) { 725 if (instr->InputAt(0)->IsImmediate()) {
712 ExternalReference ref = i.InputExternalReference(0); 726 ExternalReference ref = i.InputExternalReference(0);
713 __ CallCFunction(ref, num_parameters, 0); 727 __ CallCFunction(ref, num_parameters, 0);
714 } else { 728 } else {
715 Register func = i.InputRegister(0); 729 Register func = i.InputRegister(0);
716 __ CallCFunction(func, num_parameters, 0); 730 __ CallCFunction(func, num_parameters, 0);
717 } 731 }
(...skipping 1269 matching lines...) Expand 10 before | Expand all | Expand 10 after
1987 padding_size -= kInstructionSize; 2001 padding_size -= kInstructionSize;
1988 } 2002 }
1989 } 2003 }
1990 } 2004 }
1991 2005
1992 #undef __ 2006 #undef __
1993 2007
1994 } // namespace compiler 2008 } // namespace compiler
1995 } // namespace internal 2009 } // namespace internal
1996 } // namespace v8 2010 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698