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

Side by Side Diff: src/compiler/mips64/code-generator-mips64.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: Fix comments 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
« no previous file with comments | « src/compiler/mips/code-generator-mips.cc ('k') | src/compiler/move-optimizer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/ast/scopes.h" 5 #include "src/ast/scopes.h"
6 #include "src/compiler/code-generator.h" 6 #include "src/compiler/code-generator.h"
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 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 0, 1); \ 517 0, 1); \
518 /* Move the result in the double result register. */ \ 518 /* Move the result in the double result register. */ \
519 __ MovFromFloatResult(i.OutputDoubleRegister()); \ 519 __ MovFromFloatResult(i.OutputDoubleRegister()); \
520 } while (0) 520 } while (0)
521 521
522 void CodeGenerator::AssembleDeconstructFrame() { 522 void CodeGenerator::AssembleDeconstructFrame() {
523 __ mov(sp, fp); 523 __ mov(sp, fp);
524 __ Pop(ra, fp); 524 __ Pop(ra, fp);
525 } 525 }
526 526
527 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { 527 void CodeGenerator::AssemblePrepareTailCall() {
528 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
529 if (sp_slot_delta > 0) {
530 __ daddiu(sp, sp, sp_slot_delta * kPointerSize);
531 }
532 frame_access_state()->SetFrameAccessToDefault();
533 }
534
535
536 void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
537 int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
538 if (sp_slot_delta < 0) {
539 __ Dsubu(sp, sp, Operand(-sp_slot_delta * kPointerSize));
540 frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
541 }
542 if (frame_access_state()->has_frame()) { 528 if (frame_access_state()->has_frame()) {
543 __ ld(ra, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); 529 __ ld(ra, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
544 __ ld(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 530 __ ld(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
545 } 531 }
546 frame_access_state()->SetFrameAccessToSP(); 532 frame_access_state()->SetFrameAccessToSP();
547 } 533 }
548 534
549 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, 535 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
550 Register scratch1, 536 Register scratch1,
551 Register scratch2, 537 Register scratch2,
(...skipping 12 matching lines...) Expand all
564 __ ld(caller_args_count_reg, 550 __ ld(caller_args_count_reg,
565 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); 551 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
566 __ SmiUntag(caller_args_count_reg); 552 __ SmiUntag(caller_args_count_reg);
567 553
568 ParameterCount callee_args_count(args_reg); 554 ParameterCount callee_args_count(args_reg);
569 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, 555 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
570 scratch3); 556 scratch3);
571 __ bind(&done); 557 __ bind(&done);
572 } 558 }
573 559
560 namespace {
561
562 void AdjustStackPointerForTailCall(MacroAssembler* masm,
563 FrameAccessState* state,
564 int new_slot_above_sp,
565 bool allow_shrinkage = true) {
566 int current_sp_offset = state->GetSPToFPSlotCount() +
567 StandardFrameConstants::kFixedSlotCountAboveFp;
568 int stack_slot_delta = new_slot_above_sp - current_sp_offset;
569 if (stack_slot_delta > 0) {
570 masm->Dsubu(sp, sp, stack_slot_delta * kPointerSize);
571 state->IncreaseSPDelta(stack_slot_delta);
572 } else if (allow_shrinkage && stack_slot_delta < 0) {
573 masm->Daddu(sp, sp, stack_slot_delta * kPointerSize);
574 state->IncreaseSPDelta(stack_slot_delta);
575 }
576 }
577
578 } // namespace
579
580 void CodeGenerator::AssembleTailCallBeforeGap(Instruction* instr,
581 int first_unused_stack_slot) {
582 AdjustStackPointerForTailCall(masm(), frame_access_state(),
583 first_unused_stack_slot, false);
584 }
585
586 void CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
587 int first_unused_stack_slot) {
588 AdjustStackPointerForTailCall(masm(), frame_access_state(),
589 first_unused_stack_slot);
590 }
591
574 // Assembles an instruction after register allocation, producing machine code. 592 // Assembles an instruction after register allocation, producing machine code.
575 CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( 593 CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
576 Instruction* instr) { 594 Instruction* instr) {
577 MipsOperandConverter i(this, instr); 595 MipsOperandConverter i(this, instr);
578 InstructionCode opcode = instr->opcode(); 596 InstructionCode opcode = instr->opcode();
579 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); 597 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
580 switch (arch_opcode) { 598 switch (arch_opcode) {
581 case kArchCallCodeObject: { 599 case kArchCallCodeObject: {
582 EnsureSpaceForLazyDeopt(); 600 EnsureSpaceForLazyDeopt();
583 if (instr->InputAt(0)->IsImmediate()) { 601 if (instr->InputAt(0)->IsImmediate()) {
584 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), 602 __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
585 RelocInfo::CODE_TARGET); 603 RelocInfo::CODE_TARGET);
586 } else { 604 } else {
587 __ daddiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag); 605 __ daddiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
588 __ Call(at); 606 __ Call(at);
589 } 607 }
590 RecordCallPosition(instr); 608 RecordCallPosition(instr);
591 frame_access_state()->ClearSPDelta(); 609 frame_access_state()->ClearSPDelta();
592 break; 610 break;
593 } 611 }
594 case kArchTailCallCodeObjectFromJSFunction: 612 case kArchTailCallCodeObjectFromJSFunction:
595 case kArchTailCallCodeObject: { 613 case kArchTailCallCodeObject: {
596 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
597 AssembleDeconstructActivationRecord(stack_param_delta);
598 if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) { 614 if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
599 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 615 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
600 i.TempRegister(0), i.TempRegister(1), 616 i.TempRegister(0), i.TempRegister(1),
601 i.TempRegister(2)); 617 i.TempRegister(2));
602 } 618 }
603 if (instr->InputAt(0)->IsImmediate()) { 619 if (instr->InputAt(0)->IsImmediate()) {
604 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), 620 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
605 RelocInfo::CODE_TARGET); 621 RelocInfo::CODE_TARGET);
606 } else { 622 } else {
607 __ daddiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag); 623 __ daddiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
608 __ Jump(at); 624 __ Jump(at);
609 } 625 }
610 frame_access_state()->ClearSPDelta(); 626 frame_access_state()->ClearSPDelta();
627 frame_access_state()->SetFrameAccessToDefault();
611 break; 628 break;
612 } 629 }
613 case kArchTailCallAddress: { 630 case kArchTailCallAddress: {
614 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
615 AssembleDeconstructActivationRecord(stack_param_delta);
616 CHECK(!instr->InputAt(0)->IsImmediate()); 631 CHECK(!instr->InputAt(0)->IsImmediate());
617 __ Jump(i.InputRegister(0)); 632 __ Jump(i.InputRegister(0));
618 frame_access_state()->ClearSPDelta(); 633 frame_access_state()->ClearSPDelta();
634 frame_access_state()->SetFrameAccessToDefault();
619 break; 635 break;
620 } 636 }
621 case kArchCallJSFunction: { 637 case kArchCallJSFunction: {
622 EnsureSpaceForLazyDeopt(); 638 EnsureSpaceForLazyDeopt();
623 Register func = i.InputRegister(0); 639 Register func = i.InputRegister(0);
624 if (FLAG_debug_code) { 640 if (FLAG_debug_code) {
625 // Check the function's context matches the context argument. 641 // Check the function's context matches the context argument.
626 __ ld(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset)); 642 __ ld(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
627 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg)); 643 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg));
628 } 644 }
629 __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 645 __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
630 __ Call(at); 646 __ Call(at);
631 RecordCallPosition(instr); 647 RecordCallPosition(instr);
632 frame_access_state()->ClearSPDelta(); 648 frame_access_state()->ClearSPDelta();
633 break; 649 break;
634 } 650 }
635 case kArchTailCallJSFunctionFromJSFunction: 651 case kArchTailCallJSFunctionFromJSFunction:
636 case kArchTailCallJSFunction: { 652 case kArchTailCallJSFunction: {
637 Register func = i.InputRegister(0); 653 Register func = i.InputRegister(0);
638 if (FLAG_debug_code) { 654 if (FLAG_debug_code) {
639 // Check the function's context matches the context argument. 655 // Check the function's context matches the context argument.
640 __ ld(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset)); 656 __ ld(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
641 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg)); 657 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg));
642 } 658 }
643 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
644 AssembleDeconstructActivationRecord(stack_param_delta);
645 if (arch_opcode == kArchTailCallJSFunctionFromJSFunction) { 659 if (arch_opcode == kArchTailCallJSFunctionFromJSFunction) {
646 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 660 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
647 i.TempRegister(0), i.TempRegister(1), 661 i.TempRegister(0), i.TempRegister(1),
648 i.TempRegister(2)); 662 i.TempRegister(2));
649 } 663 }
650 __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 664 __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
651 __ Jump(at); 665 __ Jump(at);
652 frame_access_state()->ClearSPDelta(); 666 frame_access_state()->ClearSPDelta();
667 frame_access_state()->SetFrameAccessToDefault();
653 break; 668 break;
654 } 669 }
655 case kArchPrepareCallCFunction: { 670 case kArchPrepareCallCFunction: {
656 int const num_parameters = MiscField::decode(instr->opcode()); 671 int const num_parameters = MiscField::decode(instr->opcode());
657 __ PrepareCallCFunction(num_parameters, kScratchReg); 672 __ PrepareCallCFunction(num_parameters, kScratchReg);
658 // Frame alignment requires using FP-relative frame addressing. 673 // Frame alignment requires using FP-relative frame addressing.
659 frame_access_state()->SetFrameAccessToFP(); 674 frame_access_state()->SetFrameAccessToFP();
660 break; 675 break;
661 } 676 }
662 case kArchPrepareTailCall: 677 case kArchPrepareTailCall:
663 AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1)); 678 AssemblePrepareTailCall();
664 break; 679 break;
665 case kArchCallCFunction: { 680 case kArchCallCFunction: {
666 int const num_parameters = MiscField::decode(instr->opcode()); 681 int const num_parameters = MiscField::decode(instr->opcode());
667 if (instr->InputAt(0)->IsImmediate()) { 682 if (instr->InputAt(0)->IsImmediate()) {
668 ExternalReference ref = i.InputExternalReference(0); 683 ExternalReference ref = i.InputExternalReference(0);
669 __ CallCFunction(ref, num_parameters); 684 __ CallCFunction(ref, num_parameters);
670 } else { 685 } else {
671 Register func = i.InputRegister(0); 686 Register func = i.InputRegister(0);
672 __ CallCFunction(func, num_parameters); 687 __ CallCFunction(func, num_parameters);
673 } 688 }
(...skipping 1671 matching lines...) Expand 10 before | Expand all | Expand 10 after
2345 padding_size -= v8::internal::Assembler::kInstrSize; 2360 padding_size -= v8::internal::Assembler::kInstrSize;
2346 } 2361 }
2347 } 2362 }
2348 } 2363 }
2349 2364
2350 #undef __ 2365 #undef __
2351 2366
2352 } // namespace compiler 2367 } // namespace compiler
2353 } // namespace internal 2368 } // namespace internal
2354 } // namespace v8 2369 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/mips/code-generator-mips.cc ('k') | src/compiler/move-optimizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698