Index: src/compiler/x64/unwinding-info-writer-x64.cc |
diff --git a/src/compiler/x64/unwinding-info-writer-x64.cc b/src/compiler/x64/unwinding-info-writer-x64.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ebe2aa2b18f71c4243673d8c0b753243ddf3be87 |
--- /dev/null |
+++ b/src/compiler/x64/unwinding-info-writer-x64.cc |
@@ -0,0 +1,85 @@ |
+// Copyright 2016 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "src/compiler/x64/unwinding-info-writer-x64.h" |
+#include "src/compiler/instruction.h" |
+ |
+namespace v8 { |
+namespace internal { |
+namespace compiler { |
+ |
+void UnwindingInfoWriter::BeginInstructionBlock(int pc_offset, |
+ const InstructionBlock* block) { |
+ block_will_exit_ = false; |
+ |
+ auto lookup = block_initial_states_.find(block->rpo_number().ToInt()); |
+ if (lookup != block_initial_states_.end()) { |
+ if (!lookup->second.register_.is(eh_frame_writer_.base_register()) && |
+ lookup->second.offset_ != eh_frame_writer_.base_offset()) { |
+ eh_frame_writer_.AdvanceLocation(pc_offset); |
+ eh_frame_writer_.SetBaseAddressRegisterAndOffset(lookup->second.register_, |
+ lookup->second.offset_); |
+ } else if (!lookup->second.register_.is(eh_frame_writer_.base_register())) { |
+ eh_frame_writer_.AdvanceLocation(pc_offset); |
+ eh_frame_writer_.SetBaseAddressRegister(lookup->second.register_); |
+ } else if (lookup->second.offset_ != eh_frame_writer_.base_offset()) { |
+ eh_frame_writer_.AdvanceLocation(pc_offset); |
+ eh_frame_writer_.SetBaseAddressOffset(lookup->second.offset_); |
+ } |
+ |
+ tracking_fp_ = lookup->second.tracking_fp_; |
+ } else { |
+ // The entry block always lacks an explicit initial state. |
+ // The exit block may lack an explicit state, if it is only reached by |
+ // the block ending in a ret. |
+ // All the other blocks must have an explicit initial state. |
+ DCHECK(block->predecessors().empty() || block->successors().empty()); |
+ } |
+} |
+ |
+void UnwindingInfoWriter::EndInstructionBlock(const InstructionBlock* block) { |
+ if (block_will_exit_) return; |
+ |
+ for (const RpoNumber& successor : block->successors()) { |
+ BlockInitialState state = {eh_frame_writer_.base_register(), |
+ eh_frame_writer_.base_offset(), tracking_fp_}; |
+ auto inserted = block_initial_states_.insert({successor.ToInt(), state}); |
+ // If we already had an entry for this BB, check that the values are the |
+ // same we were trying to insert. |
+ if (!inserted.second) { |
+ DCHECK(inserted.first->second.register_.is(state.register_)); |
+ DCHECK_EQ(inserted.first->second.offset_, state.offset_); |
+ DCHECK_EQ(inserted.first->second.tracking_fp_, state.tracking_fp_); |
+ } |
+ } |
+} |
+ |
+void UnwindingInfoWriter::MarkFrameConstructed(int pc_base) { |
+ // push rbp |
+ eh_frame_writer_.AdvanceLocation(pc_base + 1); |
+ eh_frame_writer_.IncreaseBaseAddressOffset(kInt64Size); |
+ eh_frame_writer_.RecordRegisterSavedToStack(rbp); |
+ |
+ // mov rbp, rsp |
+ eh_frame_writer_.AdvanceLocation(pc_base + 4); |
+ eh_frame_writer_.SetBaseAddressRegister(rbp); |
+ |
+ tracking_fp_ = true; |
+} |
+ |
+void UnwindingInfoWriter::MarkFrameDeconstructed(int pc_base) { |
+ // mov rsp, rbp |
+ eh_frame_writer_.AdvanceLocation(pc_base + 3); |
+ eh_frame_writer_.SetBaseAddressRegister(rsp); |
+ |
+ // pop rbp |
+ eh_frame_writer_.AdvanceLocation(pc_base + 4); |
+ eh_frame_writer_.IncreaseBaseAddressOffset(-kInt64Size); |
+ |
+ tracking_fp_ = false; |
+} |
+ |
+} // namespace compiler |
+} // namespace internal |
+} // namespace v8 |