diff options
Diffstat (limited to 'deps/v8/src/compiler/mips64/code-generator-mips64.cc')
-rw-r--r-- | deps/v8/src/compiler/mips64/code-generator-mips64.cc | 99 |
1 files changed, 72 insertions, 27 deletions
diff --git a/deps/v8/src/compiler/mips64/code-generator-mips64.cc b/deps/v8/src/compiler/mips64/code-generator-mips64.cc index 373a1a6abc..c6341b1210 100644 --- a/deps/v8/src/compiler/mips64/code-generator-mips64.cc +++ b/deps/v8/src/compiler/mips64/code-generator-mips64.cc @@ -120,8 +120,11 @@ class MipsOperandConverter final : public InstructionOperandConverter { MemOperand ToMemOperand(InstructionOperand* op) const { DCHECK_NOT_NULL(op); DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); - FrameOffset offset = frame_access_state()->GetFrameOffset( - AllocatedOperand::cast(op)->index()); + return SlotToMemOperand(AllocatedOperand::cast(op)->index()); + } + + MemOperand SlotToMemOperand(int slot) const { + FrameOffset offset = frame_access_state()->GetFrameOffset(slot); return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); } }; @@ -221,7 +224,8 @@ class OutOfLineRecordWrite final : public OutOfLineCode { value_(value), scratch0_(scratch0), scratch1_(scratch1), - mode_(mode) {} + mode_(mode), + must_save_lr_(!gen->frame_access_state()->has_frame()) {} void Generate() final { if (mode_ > RecordWriteMode::kValueIsPointer) { @@ -235,7 +239,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode { : OMIT_REMEMBERED_SET; SaveFPRegsMode const save_fp_mode = frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; - if (!frame()->needs_frame()) { + if (must_save_lr_) { // We need to save and restore ra if the frame was elided. __ Push(ra); } @@ -243,7 +247,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode { remembered_set_action, save_fp_mode); __ Daddu(scratch1_, object_, index_); __ CallStub(&stub); - if (!frame()->needs_frame()) { + if (must_save_lr_) { __ Pop(ra); } } @@ -255,6 +259,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode { Register const scratch0_; Register const scratch1_; RecordWriteMode const mode_; + bool must_save_lr_; }; @@ -479,6 +484,13 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate, __ bind(&done); \ } +void CodeGenerator::AssembleDeconstructFrame() { + __ mov(sp, fp); + __ Pop(ra, fp); +} + +void CodeGenerator::AssembleSetupStackPointer() {} + void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) { int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta); if (sp_slot_delta > 0) { @@ -494,20 +506,44 @@ void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) { __ Dsubu(sp, sp, Operand(-sp_slot_delta * kPointerSize)); frame_access_state()->IncreaseSPDelta(-sp_slot_delta); } - if (frame()->needs_frame()) { + if (frame_access_state()->has_frame()) { __ ld(ra, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); __ ld(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); } frame_access_state()->SetFrameAccessToSP(); } +void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, + Register scratch1, + Register scratch2, + Register scratch3) { + DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3)); + Label done; + + // Check if current frame is an arguments adaptor frame. + __ ld(scratch3, MemOperand(fp, StandardFrameConstants::kContextOffset)); + __ Branch(&done, ne, scratch3, + Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); + + // Load arguments count from current arguments adaptor frame (note, it + // does not include receiver). + Register caller_args_count_reg = scratch1; + __ ld(caller_args_count_reg, + MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); + __ SmiUntag(caller_args_count_reg); + + ParameterCount callee_args_count(args_reg); + __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, + scratch3); + __ bind(&done); +} // Assembles an instruction after register allocation, producing machine code. void CodeGenerator::AssembleArchInstruction(Instruction* instr) { MipsOperandConverter i(this, instr); InstructionCode opcode = instr->opcode(); - - switch (ArchOpcodeField::decode(opcode)) { + ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); + switch (arch_opcode) { case kArchCallCodeObject: { EnsureSpaceForLazyDeopt(); if (instr->InputAt(0)->IsImmediate()) { @@ -521,9 +557,15 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { frame_access_state()->ClearSPDelta(); break; } + case kArchTailCallCodeObjectFromJSFunction: case kArchTailCallCodeObject: { int stack_param_delta = i.InputInt32(instr->InputCount() - 1); AssembleDeconstructActivationRecord(stack_param_delta); + if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) { + AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, + i.TempRegister(0), i.TempRegister(1), + i.TempRegister(2)); + } if (instr->InputAt(0)->IsImmediate()) { __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), RelocInfo::CODE_TARGET); @@ -548,6 +590,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { frame_access_state()->ClearSPDelta(); break; } + case kArchTailCallJSFunctionFromJSFunction: case kArchTailCallJSFunction: { Register func = i.InputRegister(0); if (FLAG_debug_code) { @@ -557,6 +600,11 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { } int stack_param_delta = i.InputInt32(instr->InputCount() - 1); AssembleDeconstructActivationRecord(stack_param_delta); + if (arch_opcode == kArchTailCallJSFunctionFromJSFunction) { + AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, + i.TempRegister(0), i.TempRegister(1), + i.TempRegister(2)); + } __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); __ Jump(at); frame_access_state()->ClearSPDelta(); @@ -616,7 +664,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ mov(i.OutputRegister(), fp); break; case kArchParentFramePointer: - if (frame_access_state()->frame()->needs_frame()) { + if (frame_access_state()->has_frame()) { __ ld(i.OutputRegister(), MemOperand(fp, 0)); } else { __ mov(i.OutputRegister(), fp); @@ -1831,17 +1879,16 @@ void CodeGenerator::AssembleDeoptimizerCall( void CodeGenerator::AssemblePrologue() { CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); - if (descriptor->IsCFunctionCall()) { - __ Push(ra, fp); - __ mov(fp, sp); - } else if (descriptor->IsJSFunctionCall()) { - __ Prologue(this->info()->GeneratePreagedPrologue()); - } else if (frame()->needs_frame()) { - __ StubPrologue(); - } else { - frame()->SetElidedFrameSizeInSlots(0); + if (frame_access_state()->has_frame()) { + if (descriptor->IsCFunctionCall()) { + __ Push(ra, fp); + __ mov(fp, sp); + } else if (descriptor->IsJSFunctionCall()) { + __ Prologue(this->info()->GeneratePreagedPrologue()); + } else { + __ StubPrologue(info()->GetOutputStackFrameType()); + } } - frame_access_state()->SetFrameAccessToDefault(); int stack_shrink_slots = frame()->GetSpillSlotCount(); if (info()->is_osr()) { @@ -1900,17 +1947,15 @@ void CodeGenerator::AssembleReturn() { } if (descriptor->IsCFunctionCall()) { - __ mov(sp, fp); - __ Pop(ra, fp); - } else if (frame()->needs_frame()) { + AssembleDeconstructFrame(); + } else if (frame_access_state()->has_frame()) { // Canonicalize JSFunction return sites for now. if (return_label_.is_bound()) { __ Branch(&return_label_); return; } else { __ bind(&return_label_); - __ mov(sp, fp); - __ Pop(ra, fp); + AssembleDeconstructFrame(); } } int pop_count = static_cast<int>(descriptor->StackParameterCount()); @@ -1969,9 +2014,9 @@ void CodeGenerator::AssembleMove(InstructionOperand* source, case Constant::kHeapObject: { Handle<HeapObject> src_object = src.ToHeapObject(); Heap::RootListIndex index; - int offset; - if (IsMaterializableFromFrame(src_object, &offset)) { - __ ld(dst, MemOperand(fp, offset)); + int slot; + if (IsMaterializableFromFrame(src_object, &slot)) { + __ ld(dst, g.SlotToMemOperand(slot)); } else if (IsMaterializableFromRoot(src_object, &index)) { __ LoadRoot(dst, index); } else { |