Chromium Code Reviews| Index: src/compiler/x64/code-generator-x64.cc |
| diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc |
| index 4dc75592ec2b189a5581a5ce1f89399cd40a02b2..3860ff3b198d127a6b9b57926e44d62a51de02a6 100644 |
| --- a/src/compiler/x64/code-generator-x64.cc |
| +++ b/src/compiler/x64/code-generator-x64.cc |
| @@ -180,19 +180,32 @@ class OutOfLineLoadNaN final : public OutOfLineCode { |
| class OutOfLineTruncateDoubleToI final : public OutOfLineCode { |
| public: |
| OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result, |
| - XMMRegister input) |
| - : OutOfLineCode(gen), result_(result), input_(input) {} |
| + XMMRegister input, |
| + UnwindingInfoWriter* unwinding_info_writer) |
| + : OutOfLineCode(gen), |
| + result_(result), |
| + input_(input), |
| + unwinding_info_writer_(unwinding_info_writer) {} |
| void Generate() final { |
| __ subp(rsp, Immediate(kDoubleSize)); |
| + if (unwinding_info_writer_) { |
| + unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), |
| + kDoubleSize); |
| + } |
| __ Movsd(MemOperand(rsp, 0), input_); |
| __ SlowTruncateToI(result_, rsp, 0); |
| __ addp(rsp, Immediate(kDoubleSize)); |
| + if (unwinding_info_writer_) { |
| + unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), |
| + -kDoubleSize); |
| + } |
| } |
| private: |
| Register const result_; |
| XMMRegister const input_; |
| + UnwindingInfoWriter* const unwinding_info_writer_; |
| }; |
| @@ -622,6 +635,9 @@ class OutOfLineRecordWrite final : public OutOfLineCode { |
| } while (false) |
| void CodeGenerator::AssembleDeconstructFrame() { |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MarkFrameDeconstructed(__ pc_offset()); |
| + } |
| __ movq(rsp, rbp); |
| __ popq(rbp); |
| } |
| @@ -756,6 +772,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
| __ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| __ jmp(reg); |
| } |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MarkBlockWillExit(); |
| + } |
| frame_access_state()->ClearSPDelta(); |
| frame_access_state()->SetFrameAccessToDefault(); |
| break; |
| @@ -764,6 +783,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
| CHECK(!HasImmediateInput(instr, 0)); |
| Register reg = i.InputRegister(0); |
| __ jmp(reg); |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MarkBlockWillExit(); |
| + } |
| frame_access_state()->ClearSPDelta(); |
| frame_access_state()->SetFrameAccessToDefault(); |
| break; |
| @@ -872,7 +894,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
| case kArchTruncateDoubleToI: { |
| auto result = i.OutputRegister(); |
| auto input = i.InputDoubleRegister(0); |
| - auto ool = new (zone()) OutOfLineTruncateDoubleToI(this, result, input); |
| + auto ool = new (zone()) OutOfLineTruncateDoubleToI( |
| + this, result, input, unwinding_info_writer_.get()); |
| // We use Cvttsd2siq instead of Cvttsd2si due to performance reasons. The |
| // use of Cvttsd2siq requires the movl below to avoid sign extension. |
| __ Cvttsd2siq(result, input); |
| @@ -1234,6 +1257,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
| break; |
| case kSSEFloat64Mod: { |
| __ subq(rsp, Immediate(kDoubleSize)); |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), |
| + kDoubleSize); |
| + } |
| // Move values to st(0) and st(1). |
| __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(1)); |
| __ fld_d(Operand(rsp, 0)); |
| @@ -1254,7 +1281,15 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
| __ shrl(rax, Immediate(8)); |
| __ andl(rax, Immediate(0xFF)); |
| __ pushq(rax); |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), |
| + kInt64Size); |
| + } |
| __ popfq(); |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), |
| + -kInt64Size); |
| + } |
| } |
| __ j(parity_even, &mod_loop); |
| // Move output to stack and clean up. |
| @@ -1262,6 +1297,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
| __ fstp_d(Operand(rsp, 0)); |
| __ Movsd(i.OutputDoubleRegister(), Operand(rsp, 0)); |
| __ addq(rsp, Immediate(kDoubleSize)); |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), |
| + -kDoubleSize); |
| + } |
| break; |
| } |
| case kSSEFloat64Max: |
| @@ -1843,18 +1882,34 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
| if (HasImmediateInput(instr, 0)) { |
| __ pushq(i.InputImmediate(0)); |
| frame_access_state()->IncreaseSPDelta(1); |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), |
| + kInt64Size); |
|
Jarin
2016/07/06 07:09:42
kInt64Size ==> kPointerSize (here and below)
Stefano Sanfilippo
2016/07/06 13:25:10
Done.
|
| + } |
| } else { |
| if (instr->InputAt(0)->IsRegister()) { |
| __ pushq(i.InputRegister(0)); |
| frame_access_state()->IncreaseSPDelta(1); |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt( |
| + __ pc_offset(), kInt64Size); |
| + } |
| } else if (instr->InputAt(0)->IsFPRegister()) { |
| // TODO(titzer): use another machine instruction? |
| __ subq(rsp, Immediate(kDoubleSize)); |
| frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt( |
| + __ pc_offset(), kDoubleSize); |
| + } |
| __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0)); |
| } else { |
| __ pushq(i.InputOperand(0)); |
| frame_access_state()->IncreaseSPDelta(1); |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt( |
| + __ pc_offset(), kInt64Size); |
| + } |
| } |
| } |
| break; |
| @@ -2147,6 +2202,8 @@ void CodeGenerator::FinishFrame(Frame* frame) { |
| void CodeGenerator::AssembleConstructFrame() { |
| CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
| if (frame_access_state()->has_frame()) { |
| + int pc_base = __ pc_offset(); |
| + |
| if (descriptor->IsCFunctionCall()) { |
| __ pushq(rbp); |
| __ movq(rbp, rsp); |
| @@ -2155,6 +2212,12 @@ void CodeGenerator::AssembleConstructFrame() { |
| } else { |
| __ StubPrologue(info()->GetOutputStackFrameType()); |
| } |
| + |
| + if (!unwinding_info_writer_.is_empty() && |
| + (!descriptor->IsJSFunctionCall() || |
| + !info()->GeneratePreagedPrologue())) { |
| + unwinding_info_writer_->MarkFrameConstructed(pc_base); |
| + } |
| } |
| int shrink_slots = frame()->GetSpillSlotCount(); |
| @@ -2228,6 +2291,10 @@ void CodeGenerator::AssembleReturn() { |
| __ addp(rsp, Immediate(stack_size)); |
| } |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MarkBlockWillExit(); |
| + } |
| + |
| if (descriptor->IsCFunctionCall()) { |
| AssembleDeconstructFrame(); |
| } else if (frame_access_state()->has_frame()) { |
| @@ -2400,11 +2467,19 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source, |
| Register src = g.ToRegister(source); |
| __ pushq(src); |
| frame_access_state()->IncreaseSPDelta(1); |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), |
| + kInt64Size); |
| + } |
| Operand dst = g.ToOperand(destination); |
| __ movq(src, dst); |
| frame_access_state()->IncreaseSPDelta(-1); |
| dst = g.ToOperand(destination); |
| __ popq(dst); |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), |
| + -kInt64Size); |
| + } |
| } else if ((source->IsStackSlot() && destination->IsStackSlot()) || |
| (source->IsFPStackSlot() && destination->IsFPStackSlot())) { |
| // Memory-memory. |
| @@ -2413,12 +2488,20 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source, |
| Operand dst = g.ToOperand(destination); |
| __ movq(tmp, dst); |
| __ pushq(src); |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), |
| + kInt64Size); |
| + } |
| frame_access_state()->IncreaseSPDelta(1); |
| src = g.ToOperand(source); |
| __ movq(src, tmp); |
| frame_access_state()->IncreaseSPDelta(-1); |
| dst = g.ToOperand(destination); |
| __ popq(dst); |
| + if (!unwinding_info_writer_.is_empty()) { |
| + unwinding_info_writer_->MaybeIncreaseFrameBaseOffsetAt(__ pc_offset(), |
| + -kInt64Size); |
| + } |
| } else if (source->IsFPRegister() && destination->IsFPRegister()) { |
| // XMM register-register swap. |
| XMMRegister src = g.ToDoubleRegister(source); |
| @@ -2455,7 +2538,7 @@ void CodeGenerator::EnsureSpaceForLazyDeopt() { |
| int space_needed = Deoptimizer::patch_size(); |
| // Ensure that we have enough space after the previous lazy-bailout |
| // instruction for patching the code here. |
| - int current_pc = masm()->pc_offset(); |
| + int current_pc = __ pc_offset(); |
| if (current_pc < last_lazy_deopt_pc_ + space_needed) { |
| int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
| __ Nop(padding_size); |