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

Unified Diff: src/compiler/x64/code-generator-x64.cc

Issue 2026313002: Emit unwinding information for TurboFan code. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@eh-frame
Patch Set: Clarify assumptions on frame ction/dtion routines in arm/arm64. Created 4 years, 5 months 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 side-by-side diff with in-line comments
Download patch
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);

Powered by Google App Engine
This is Rietveld 408576698