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 ecb04a2eaf4cda4c551bbdc4afec70c0aa9c599c..ff0f765c6a6e5769a2ea67dcb8fd3a2012f6e679 100644 |
--- a/src/compiler/x64/code-generator-x64.cc |
+++ b/src/compiler/x64/code-generator-x64.cc |
@@ -180,19 +180,28 @@ 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)); |
+ unwinding_info_writer_->MaybeIncreaseBaseOffsetAt(__ pc_offset(), |
+ kDoubleSize); |
__ Movsd(MemOperand(rsp, 0), input_); |
__ SlowTruncateToI(result_, rsp, 0); |
__ addp(rsp, Immediate(kDoubleSize)); |
+ unwinding_info_writer_->MaybeIncreaseBaseOffsetAt(__ pc_offset(), |
+ -kDoubleSize); |
} |
private: |
Register const result_; |
XMMRegister const input_; |
+ UnwindingInfoWriter* const unwinding_info_writer_; |
}; |
@@ -622,6 +631,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode { |
} while (false) |
void CodeGenerator::AssembleDeconstructFrame() { |
+ unwinding_info_writer_.MarkFrameDeconstructed(__ pc_offset()); |
__ movq(rsp, rbp); |
__ popq(rbp); |
} |
@@ -756,6 +766,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
__ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
__ jmp(reg); |
} |
+ unwinding_info_writer_.MarkBlockWillExit(); |
frame_access_state()->ClearSPDelta(); |
frame_access_state()->SetFrameAccessToDefault(); |
break; |
@@ -764,6 +775,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
CHECK(!HasImmediateInput(instr, 0)); |
Register reg = i.InputRegister(0); |
__ jmp(reg); |
+ unwinding_info_writer_.MarkBlockWillExit(); |
frame_access_state()->ClearSPDelta(); |
frame_access_state()->SetFrameAccessToDefault(); |
break; |
@@ -872,7 +884,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_); |
// 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 +1247,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
break; |
case kSSEFloat64Mod: { |
__ subq(rsp, Immediate(kDoubleSize)); |
+ unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ 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 +1269,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
__ shrl(rax, Immediate(8)); |
__ andl(rax, Immediate(0xFF)); |
__ pushq(rax); |
+ unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), |
+ kPointerSize); |
__ popfq(); |
+ unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), |
+ -kPointerSize); |
} |
__ j(parity_even, &mod_loop); |
// Move output to stack and clean up. |
@@ -1262,6 +1281,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
__ fstp_d(Operand(rsp, 0)); |
__ Movsd(i.OutputDoubleRegister(), Operand(rsp, 0)); |
__ addq(rsp, Immediate(kDoubleSize)); |
+ unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), |
+ -kDoubleSize); |
break; |
} |
case kSSEFloat64Max: |
@@ -1843,18 +1864,26 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
if (HasImmediateInput(instr, 0)) { |
__ pushq(i.InputImmediate(0)); |
frame_access_state()->IncreaseSPDelta(1); |
+ unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), |
+ kPointerSize); |
} else { |
if (instr->InputAt(0)->IsRegister()) { |
__ pushq(i.InputRegister(0)); |
frame_access_state()->IncreaseSPDelta(1); |
+ unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), |
+ kPointerSize); |
} else if (instr->InputAt(0)->IsFPRegister()) { |
// TODO(titzer): use another machine instruction? |
__ subq(rsp, Immediate(kDoubleSize)); |
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); |
+ unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), |
+ kDoubleSize); |
__ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0)); |
} else { |
__ pushq(i.InputOperand(0)); |
frame_access_state()->IncreaseSPDelta(1); |
+ unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), |
+ kPointerSize); |
} |
} |
break; |
@@ -2147,6 +2176,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 +2186,10 @@ void CodeGenerator::AssembleConstructFrame() { |
} else { |
__ StubPrologue(info()->GetOutputStackFrameType()); |
} |
+ |
+ if (!descriptor->IsJSFunctionCall() || !info()->GeneratePreagedPrologue()) { |
+ unwinding_info_writer_.MarkFrameConstructed(pc_base); |
+ } |
} |
int shrink_slots = frame()->GetSpillSlotCount(); |
@@ -2228,6 +2263,8 @@ void CodeGenerator::AssembleReturn() { |
__ addp(rsp, Immediate(stack_size)); |
} |
+ unwinding_info_writer_.MarkBlockWillExit(); |
+ |
if (descriptor->IsCFunctionCall()) { |
AssembleDeconstructFrame(); |
} else if (frame_access_state()->has_frame()) { |
@@ -2416,11 +2453,15 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source, |
Register src = g.ToRegister(source); |
__ pushq(src); |
frame_access_state()->IncreaseSPDelta(1); |
+ unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), |
+ kPointerSize); |
Operand dst = g.ToOperand(destination); |
__ movq(src, dst); |
frame_access_state()->IncreaseSPDelta(-1); |
dst = g.ToOperand(destination); |
__ popq(dst); |
+ unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), |
+ -kPointerSize); |
} else if ((source->IsStackSlot() && destination->IsStackSlot()) || |
(source->IsFPStackSlot() && destination->IsFPStackSlot())) { |
// Memory-memory. |
@@ -2431,12 +2472,16 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source, |
Register tmp = kScratchRegister; |
__ movq(tmp, dst); |
__ pushq(src); |
+ unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), |
+ kPointerSize); |
frame_access_state()->IncreaseSPDelta(1); |
src = g.ToOperand(source); |
__ movq(src, tmp); |
frame_access_state()->IncreaseSPDelta(-1); |
dst = g.ToOperand(destination); |
__ popq(dst); |
+ unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), |
+ -kPointerSize); |
} else { |
// Use the XOR trick to swap without a temporary. |
__ Movups(kScratchDoubleReg, src); |
@@ -2490,7 +2535,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); |