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

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: Rebasing 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: {
546 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
547 AssembleDeconstructActivationRecord(stack_param_delta);
548 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
549 i.TempRegister(0), i.TempRegister(1),
550 i.TempRegister(2));
551 if (instr->InputAt(0)->IsImmediate()) {
552 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
553 RelocInfo::CODE_TARGET);
554 } else {
555 Register target = i.InputRegister(0);
556 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
557 __ Jump(target);
558 }
559 frame_access_state()->ClearSPDelta();
560 break;
561 }
521 case kArchTailCallCodeObject: { 562 case kArchTailCallCodeObject: {
522 int stack_param_delta = i.InputInt32(instr->InputCount() - 1); 563 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
523 AssembleDeconstructActivationRecord(stack_param_delta); 564 AssembleDeconstructActivationRecord(stack_param_delta);
524 if (instr->InputAt(0)->IsImmediate()) { 565 if (instr->InputAt(0)->IsImmediate()) {
525 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), 566 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
526 RelocInfo::CODE_TARGET); 567 RelocInfo::CODE_TARGET);
527 } else { 568 } else {
528 Register target = i.InputRegister(0); 569 Register target = i.InputRegister(0);
529 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag); 570 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
530 __ Jump(target); 571 __ Jump(target);
(...skipping 19 matching lines...) Expand all
550 // allocator. 591 // allocator.
551 CallDescriptor::Flags flags = 592 CallDescriptor::Flags flags =
552 static_cast<CallDescriptor::Flags>(MiscField::decode(opcode)); 593 static_cast<CallDescriptor::Flags>(MiscField::decode(opcode));
553 if (flags & CallDescriptor::kRestoreJSSP) { 594 if (flags & CallDescriptor::kRestoreJSSP) {
554 __ mov(jssp, csp); 595 __ mov(jssp, csp);
555 } 596 }
556 frame_access_state()->ClearSPDelta(); 597 frame_access_state()->ClearSPDelta();
557 RecordCallPosition(instr); 598 RecordCallPosition(instr);
558 break; 599 break;
559 } 600 }
601 case kArchTailCallJSFunctionFromJSFunction: {
602 Register func = i.InputRegister(0);
603 if (FLAG_debug_code) {
604 // Check the function's context matches the context argument.
605 UseScratchRegisterScope scope(masm());
606 Register temp = scope.AcquireX();
607 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset));
608 __ cmp(cp, temp);
609 __ Assert(eq, kWrongFunctionContext);
610 }
611 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
612 AssembleDeconstructActivationRecord(stack_param_delta);
613 AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
614 i.TempRegister(0), i.TempRegister(1),
615 i.TempRegister(2));
616 __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
617 __ Jump(x10);
618 frame_access_state()->ClearSPDelta();
619 break;
620 }
560 case kArchTailCallJSFunction: { 621 case kArchTailCallJSFunction: {
561 Register func = i.InputRegister(0); 622 Register func = i.InputRegister(0);
562 if (FLAG_debug_code) { 623 if (FLAG_debug_code) {
563 // Check the function's context matches the context argument. 624 // Check the function's context matches the context argument.
564 UseScratchRegisterScope scope(masm()); 625 UseScratchRegisterScope scope(masm());
565 Register temp = scope.AcquireX(); 626 Register temp = scope.AcquireX();
566 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset)); 627 __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset));
567 __ cmp(cp, temp); 628 __ cmp(cp, temp);
568 __ Assert(eq, kWrongFunctionContext); 629 __ Assert(eq, kWrongFunctionContext);
569 } 630 }
(...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 padding_size -= kInstructionSize; 1790 padding_size -= kInstructionSize;
1730 } 1791 }
1731 } 1792 }
1732 } 1793 }
1733 1794
1734 #undef __ 1795 #undef __
1735 1796
1736 } // namespace compiler 1797 } // namespace compiler
1737 } // namespace internal 1798 } // namespace internal
1738 } // namespace v8 1799 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698