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); |