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

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

Issue 1439613003: [turbofan] Better and more sane support for tail calls (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Skip test in ignition configuration Created 5 years, 1 month 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/linkage.cc ('k') | src/compiler/mips64/code-generator-mips64.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/compiler/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 #include "src/compiler/code-generator-impl.h" 6 #include "src/compiler/code-generator-impl.h"
7 #include "src/compiler/gap-resolver.h" 7 #include "src/compiler/gap-resolver.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/osr.h" 9 #include "src/compiler/osr.h"
10 #include "src/mips/macro-assembler-mips.h" 10 #include "src/mips/macro-assembler-mips.h"
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ 439 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
440 __ Move(at, kScratchReg2, i.OutputDoubleRegister()); \ 440 __ Move(at, kScratchReg2, i.OutputDoubleRegister()); \
441 __ or_(at, at, kScratchReg2); \ 441 __ or_(at, at, kScratchReg2); \
442 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \ 442 __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \
443 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ 443 __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \
444 __ bind(ool->exit()); \ 444 __ bind(ool->exit()); \
445 __ bind(&done); \ 445 __ bind(&done); \
446 } while (0) 446 } while (0)
447 447
448 448
449 void CodeGenerator::AssembleDeconstructActivationRecord() { 449 void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) {
450 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 450 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
451 int stack_slots = frame()->GetSpillSlotCount(); 451 int stack_slots = frame()->GetSpillSlotCount();
452 int stack_pointer_delta = 0;
452 if (descriptor->IsJSFunctionCall() || stack_slots > 0) { 453 if (descriptor->IsJSFunctionCall() || stack_slots > 0) {
453 __ LeaveFrame(StackFrame::MANUAL); 454 __ mov(sp, fp);
455 __ lw(fp, MemOperand(sp, 0 * kPointerSize));
456 __ lw(ra, MemOperand(sp, 1 * kPointerSize));
457 stack_pointer_delta = 2 * kPointerSize;
458 }
459 if (stack_param_delta < 0) {
460 stack_pointer_delta += -stack_param_delta * kPointerSize;
461 }
462 if (stack_pointer_delta != 0) {
463 __ addiu(sp, sp, stack_pointer_delta);
454 } 464 }
455 } 465 }
456 466
457 467
458 // Assembles an instruction after register allocation, producing machine code. 468 // Assembles an instruction after register allocation, producing machine code.
459 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { 469 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
460 MipsOperandConverter i(this, instr); 470 MipsOperandConverter i(this, instr);
461 InstructionCode opcode = instr->opcode(); 471 InstructionCode opcode = instr->opcode();
462 472
463 switch (ArchOpcodeField::decode(opcode)) { 473 switch (ArchOpcodeField::decode(opcode)) {
464 case kArchCallCodeObject: { 474 case kArchCallCodeObject: {
465 EnsureSpaceForLazyDeopt(); 475 EnsureSpaceForLazyDeopt();
466 if (instr->InputAt(0)->IsImmediate()) { 476 if (instr->InputAt(0)->IsImmediate()) {
467 __ Call(Handle<Code>::cast(i.InputHeapObject(0)), 477 __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
468 RelocInfo::CODE_TARGET); 478 RelocInfo::CODE_TARGET);
469 } else { 479 } else {
470 __ addiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag); 480 __ addiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
471 __ Call(at); 481 __ Call(at);
472 } 482 }
473 RecordCallPosition(instr); 483 RecordCallPosition(instr);
474 break; 484 break;
475 } 485 }
476 case kArchTailCallCodeObject: { 486 case kArchTailCallCodeObject: {
477 AssembleDeconstructActivationRecord(); 487 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
488 AssembleDeconstructActivationRecord(stack_param_delta);
478 if (instr->InputAt(0)->IsImmediate()) { 489 if (instr->InputAt(0)->IsImmediate()) {
479 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), 490 __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
480 RelocInfo::CODE_TARGET); 491 RelocInfo::CODE_TARGET);
481 } else { 492 } else {
482 __ addiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag); 493 __ addiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
483 __ Jump(at); 494 __ Jump(at);
484 } 495 }
485 break; 496 break;
486 } 497 }
487 case kArchCallJSFunction: { 498 case kArchCallJSFunction: {
(...skipping 11 matching lines...) Expand all
499 break; 510 break;
500 } 511 }
501 case kArchTailCallJSFunction: { 512 case kArchTailCallJSFunction: {
502 Register func = i.InputRegister(0); 513 Register func = i.InputRegister(0);
503 if (FLAG_debug_code) { 514 if (FLAG_debug_code) {
504 // Check the function's context matches the context argument. 515 // Check the function's context matches the context argument.
505 __ lw(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset)); 516 __ lw(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
506 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg)); 517 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg));
507 } 518 }
508 519
509 AssembleDeconstructActivationRecord(); 520 int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
521 AssembleDeconstructActivationRecord(stack_param_delta);
510 __ lw(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 522 __ lw(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
511 __ Jump(at); 523 __ Jump(at);
512 break; 524 break;
513 } 525 }
514 case kArchLazyBailout: { 526 case kArchLazyBailout: {
515 EnsureSpaceForLazyDeopt(); 527 EnsureSpaceForLazyDeopt();
516 RecordCallPosition(instr); 528 RecordCallPosition(instr);
517 break; 529 break;
518 } 530 }
519 case kArchPrepareCallCFunction: { 531 case kArchPrepareCallCFunction: {
(...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after
1564 padding_size -= v8::internal::Assembler::kInstrSize; 1576 padding_size -= v8::internal::Assembler::kInstrSize;
1565 } 1577 }
1566 } 1578 }
1567 } 1579 }
1568 1580
1569 #undef __ 1581 #undef __
1570 1582
1571 } // namespace compiler 1583 } // namespace compiler
1572 } // namespace internal 1584 } // namespace internal
1573 } // namespace v8 1585 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/linkage.cc ('k') | src/compiler/mips64/code-generator-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698