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

Side by Side Diff: src/compiler/arm64/code-generator-arm64.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 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 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 __ Claim(-sp_slot_delta); 482 __ Claim(-sp_slot_delta);
483 frame_access_state()->IncreaseSPDelta(-sp_slot_delta); 483 frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
484 } 484 }
485 if (frame()->needs_frame()) { 485 if (frame()->needs_frame()) {
486 __ Ldr(lr, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); 486 __ Ldr(lr, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
487 __ Ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 487 __ Ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
488 } 488 }
489 frame_access_state()->SetFrameAccessToSP(); 489 frame_access_state()->SetFrameAccessToSP();
490 } 490 }
491 491
492 void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
493 Register scratch1,
494 Register scratch2,
495 Register scratch3) {
496 DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
497 Label done;
498
499 // Check if current frame is an arguments adaptor frame.
500 __ Ldr(scratch1, MemOperand(fp, StandardFrameConstants::kContextOffset));
501 __ Cmp(scratch1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
502 __ B(ne, &done);
503
504 // Load arguments count from current arguments adaptor frame (note, it
505 // does not include receiver).
506 Register caller_args_count_reg = scratch1;
507 __ Ldr(caller_args_count_reg,
508 MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
509 __ SmiUntag(caller_args_count_reg);
510
511 ParameterCount callee_args_count(args_reg);
512 __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
513 scratch3);
514 __ bind(&done);
515 }
492 516
493 // Assembles an instruction after register allocation, producing machine code. 517 // Assembles an instruction after register allocation, producing machine code.
494 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { 518 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
495 Arm64OperandConverter i(this, instr); 519 Arm64OperandConverter i(this, instr);
496 InstructionCode opcode = instr->opcode(); 520 InstructionCode opcode = instr->opcode();
497 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); 521 ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
498 switch (arch_opcode) { 522 switch (arch_opcode) {
499 case kArchCallCodeObject: { 523 case kArchCallCodeObject: {
500 EnsureSpaceForLazyDeopt(); 524 EnsureSpaceForLazyDeopt();
501 if (instr->InputAt(0)->IsImmediate()) { 525 if (instr->InputAt(0)->IsImmediate()) {
502 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), 526 __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
503 RelocInfo::CODE_TARGET); 527 RelocInfo::CODE_TARGET);
504 } else { 528 } else {
505 Register target = i.InputRegister(0); 529 Register target = i.InputRegister(0);
506 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); 530 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
507 __ Call(target); 531 __ Call(target);
508 } 532 }
509 // TODO(titzer): this is ugly. JSSP should be a caller-save register 533 // TODO(titzer): this is ugly. JSSP should be a caller-save register
510 // in this case, but it is not possible to express in the register 534 // in this case, but it is not possible to express in the register
511 // allocator. 535 // allocator.
512 CallDescriptor::Flags flags = 536 CallDescriptor::Flags flags =
513 static_cast<CallDescriptor::Flags>(MiscField::decode(opcode)); 537 static_cast<CallDescriptor::Flags>(MiscField::decode(opcode));
514 if (flags & CallDescriptor::kRestoreJSSP) { 538 if (flags & CallDescriptor::kRestoreJSSP) {
515 __ mov(jssp, csp); 539 __ mov(jssp, csp);
516 } 540 }
517 frame_access_state()->ClearSPDelta(); 541 frame_access_state()->ClearSPDelta();
518 RecordCallPosition(instr); 542 RecordCallPosition(instr);
519 break; 543 break;
520 } 544 }
545 case kArchTailCallCodeObjectFromJSFunction:
521 case kArchTailCallCodeObject: { 546 case kArchTailCallCodeObject: {
522 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); 547 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
523 AssembleDeconstructActivationRecord(stack_param_delta); 548 AssembleDeconstructActivationRecord(stack_param_delta);
549 if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
550 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
551 i.TempRegister(0), i.TempRegister(1),
552 i.TempRegister(2));
553 }
524 if (instr->InputAt(0)->IsImmediate()) { 554 if (instr->InputAt(0)->IsImmediate()) {
525 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), 555 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
526 RelocInfo::CODE_TARGET); 556 RelocInfo::CODE_TARGET);
527 } else { 557 } else {
528 Register target = i.InputRegister(0); 558 Register target = i.InputRegister(0);
529 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); 559 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
530 __ Jump(target); 560 __ Jump(target);
531 } 561 }
532 frame_access_state()->ClearSPDelta(); 562 frame_access_state()->ClearSPDelta();
533 break; 563 break;
(...skipping 16 matching lines...) Expand all
550 // allocator. 580 // allocator.
551 CallDescriptor::Flags flags = 581 CallDescriptor::Flags flags =
552 static_cast<CallDescriptor::Flags>(MiscField::decode(opcode)); 582 static_cast<CallDescriptor::Flags>(MiscField::decode(opcode));
553 if (flags & CallDescriptor::kRestoreJSSP) { 583 if (flags & CallDescriptor::kRestoreJSSP) {
554 __ mov(jssp, csp); 584 __ mov(jssp, csp);
555 } 585 }
556 frame_access_state()->ClearSPDelta(); 586 frame_access_state()->ClearSPDelta();
557 RecordCallPosition(instr); 587 RecordCallPosition(instr);
558 break; 588 break;
559 } 589 }
590 case kArchTailCallJSFunctionFromJSFunction:
560 case kArchTailCallJSFunction: { 591 case kArchTailCallJSFunction: {
561 Register func = i.InputRegister(0); 592 Register func = i.InputRegister(0);
562 if (FLAG_debug_code) { 593 if (FLAG_debug_code) {
563 // Check the function's context matches the context argument. 594 // Check the function's context matches the context argument.
564 UseScratchRegisterScope scope(masm()); 595 UseScratchRegisterScope scope(masm());
565 Register temp = scope.AcquireX(); 596 Register temp = scope.AcquireX();
566 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset)); 597 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset));
567 __ cmp(cp, temp); 598 __ cmp(cp, temp);
568 __ Assert(eq, kWrongFunctionContext); 599 __ Assert(eq, kWrongFunctionContext);
569 } 600 }
570 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); 601 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
571 AssembleDeconstructActivationRecord(stack_param_delta); 602 AssembleDeconstructActivationRecord(stack_param_delta);
603 if (arch_opcode == kArchTailCallJSFunctionFromJSFunction) {
604 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
605 i.TempRegister(0), i.TempRegister(1),
606 i.TempRegister(2));
607 }
572 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 608 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
573 __ Jump(x10); 609 __ Jump(x10);
574 frame_access_state()->ClearSPDelta(); 610 frame_access_state()->ClearSPDelta();
575 break; 611 break;
576 } 612 }
577 case kArchPrepareCallCFunction: 613 case kArchPrepareCallCFunction:
578 // We don't need kArchPrepareCallCFunction on arm64 as the instruction 614 // We don't need kArchPrepareCallCFunction on arm64 as the instruction
579 // selector already perform a Claim to reserve space on the stack and 615 // selector already perform a Claim to reserve space on the stack and
580 // guarantee correct alignment of stack pointer. 616 // guarantee correct alignment of stack pointer.
581 UNREACHABLE(); 617 UNREACHABLE();
(...skipping 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 padding_size -= kInstructionSize; 1765 padding_size -= kInstructionSize;
1730 } 1766 }
1731 } 1767 }
1732 } 1768 }
1733 1769
1734 #undef __ 1770 #undef __
1735 1771
1736 } // namespace compiler 1772 } // namespace compiler
1737 } // namespace internal 1773 } // namespace internal
1738 } // namespace v8 1774 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/arm/instruction-selector-arm.cc ('k') | src/compiler/arm64/instruction-selector-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698