• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/compiler/backend/x64/unwinding-info-writer-x64.h"
6 #include "src/compiler/backend/instruction.h"
7 
8 namespace v8 {
9 namespace internal {
10 namespace compiler {
11 
BeginInstructionBlock(int pc_offset,const InstructionBlock * block)12 void UnwindingInfoWriter::BeginInstructionBlock(int pc_offset,
13                                                 const InstructionBlock* block) {
14   if (!enabled()) return;
15 
16   block_will_exit_ = false;
17 
18   DCHECK_LT(block->rpo_number().ToInt(),
19             static_cast<int>(block_initial_states_.size()));
20   const BlockInitialState* initial_state =
21       block_initial_states_[block->rpo_number().ToInt()];
22   if (!initial_state) return;
23   if (initial_state->register_ != eh_frame_writer_.base_register() &&
24       initial_state->offset_ != eh_frame_writer_.base_offset()) {
25     eh_frame_writer_.AdvanceLocation(pc_offset);
26     eh_frame_writer_.SetBaseAddressRegisterAndOffset(initial_state->register_,
27                                                      initial_state->offset_);
28   } else if (initial_state->register_ != eh_frame_writer_.base_register()) {
29     eh_frame_writer_.AdvanceLocation(pc_offset);
30     eh_frame_writer_.SetBaseAddressRegister(initial_state->register_);
31   } else if (initial_state->offset_ != eh_frame_writer_.base_offset()) {
32     eh_frame_writer_.AdvanceLocation(pc_offset);
33     eh_frame_writer_.SetBaseAddressOffset(initial_state->offset_);
34   }
35 
36     tracking_fp_ = initial_state->tracking_fp_;
37 }
38 
EndInstructionBlock(const InstructionBlock * block)39 void UnwindingInfoWriter::EndInstructionBlock(const InstructionBlock* block) {
40   if (!enabled() || block_will_exit_) return;
41 
42   for (const RpoNumber& successor : block->successors()) {
43     int successor_index = successor.ToInt();
44     DCHECK_LT(successor_index, static_cast<int>(block_initial_states_.size()));
45     const BlockInitialState* existing_state =
46         block_initial_states_[successor_index];
47     // If we already had an entry for this BB, check that the values are the
48     // same we are trying to insert.
49     if (existing_state) {
50       DCHECK(existing_state->register_ == eh_frame_writer_.base_register());
51       DCHECK_EQ(existing_state->offset_, eh_frame_writer_.base_offset());
52       DCHECK_EQ(existing_state->tracking_fp_, tracking_fp_);
53     } else {
54       block_initial_states_[successor_index] = zone_->New<BlockInitialState>(
55           eh_frame_writer_.base_register(), eh_frame_writer_.base_offset(),
56           tracking_fp_);
57     }
58   }
59 }
60 
MarkFrameConstructed(int pc_base)61 void UnwindingInfoWriter::MarkFrameConstructed(int pc_base) {
62   if (!enabled()) return;
63 
64   // push rbp
65   eh_frame_writer_.AdvanceLocation(pc_base + 1);
66   eh_frame_writer_.IncreaseBaseAddressOffset(kInt64Size);
67   // <base address> points at the bottom of the current frame on x64 and
68   // <base register> is rsp, which points to the top of the frame by definition.
69   // Thus, the distance between <base address> and the top is -<base offset>.
70   int top_of_stack = -eh_frame_writer_.base_offset();
71   eh_frame_writer_.RecordRegisterSavedToStack(rbp, top_of_stack);
72 
73   // mov rbp, rsp
74   eh_frame_writer_.AdvanceLocation(pc_base + 4);
75   eh_frame_writer_.SetBaseAddressRegister(rbp);
76 
77   tracking_fp_ = true;
78 }
79 
MarkFrameDeconstructed(int pc_base)80 void UnwindingInfoWriter::MarkFrameDeconstructed(int pc_base) {
81   if (!enabled()) return;
82 
83   // mov rsp, rbp
84   eh_frame_writer_.AdvanceLocation(pc_base + 3);
85   eh_frame_writer_.SetBaseAddressRegister(rsp);
86 
87   // pop rbp
88   eh_frame_writer_.AdvanceLocation(pc_base + 4);
89   eh_frame_writer_.IncreaseBaseAddressOffset(-kInt64Size);
90 
91   tracking_fp_ = false;
92 }
93 
94 }  // namespace compiler
95 }  // namespace internal
96 }  // namespace v8
97