• 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/arm/unwinding-info-writer-arm.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->saved_lr_ != saved_lr_) {
24     eh_frame_writer_.AdvanceLocation(pc_offset);
25     if (initial_state->saved_lr_) {
26       eh_frame_writer_.RecordRegisterSavedToStack(lr, kSystemPointerSize);
27     } else {
28       eh_frame_writer_.RecordRegisterFollowsInitialRule(lr);
29     }
30     saved_lr_ = initial_state->saved_lr_;
31   }
32 }
33 
EndInstructionBlock(const InstructionBlock * block)34 void UnwindingInfoWriter::EndInstructionBlock(const InstructionBlock* block) {
35   if (!enabled() || block_will_exit_) return;
36 
37   for (const RpoNumber& successor : block->successors()) {
38     int successor_index = successor.ToInt();
39     DCHECK_LT(successor_index, static_cast<int>(block_initial_states_.size()));
40     const BlockInitialState* existing_state =
41         block_initial_states_[successor_index];
42 
43     // If we already had an entry for this BB, check that the values are the
44     // same we are trying to insert.
45     if (existing_state) {
46       DCHECK_EQ(existing_state->saved_lr_, saved_lr_);
47     } else {
48       block_initial_states_[successor_index] =
49           zone_->New<BlockInitialState>(saved_lr_);
50     }
51   }
52 }
53 
MarkFrameConstructed(int at_pc)54 void UnwindingInfoWriter::MarkFrameConstructed(int at_pc) {
55   if (!enabled()) return;
56 
57   // Regardless of the type of frame constructed, the relevant part of the
58   // layout is always the one in the diagram:
59   //
60   // |   ....   |         higher addresses
61   // +----------+               ^
62   // |    LR    |               |            |
63   // +----------+               |            |
64   // | saved FP |               |            |
65   // +----------+ <-- FP                     v
66   // |   ....   |                       stack growth
67   //
68   // The LR is pushed on the stack, and we can record this fact at the end of
69   // the construction, since the LR itself is not modified in the process.
70   eh_frame_writer_.AdvanceLocation(at_pc);
71   eh_frame_writer_.RecordRegisterSavedToStack(lr, kSystemPointerSize);
72   saved_lr_ = true;
73 }
74 
MarkFrameDeconstructed(int at_pc)75 void UnwindingInfoWriter::MarkFrameDeconstructed(int at_pc) {
76   if (!enabled()) return;
77 
78   // The lr is restored by the last operation in LeaveFrame().
79   eh_frame_writer_.AdvanceLocation(at_pc);
80   eh_frame_writer_.RecordRegisterFollowsInitialRule(lr);
81   saved_lr_ = false;
82 }
83 
MarkLinkRegisterOnTopOfStack(int pc_offset)84 void UnwindingInfoWriter::MarkLinkRegisterOnTopOfStack(int pc_offset) {
85   if (!enabled()) return;
86 
87   eh_frame_writer_.AdvanceLocation(pc_offset);
88   eh_frame_writer_.SetBaseAddressRegisterAndOffset(sp, 0);
89   eh_frame_writer_.RecordRegisterSavedToStack(lr, 0);
90 }
91 
MarkPopLinkRegisterFromTopOfStack(int pc_offset)92 void UnwindingInfoWriter::MarkPopLinkRegisterFromTopOfStack(int pc_offset) {
93   if (!enabled()) return;
94 
95   eh_frame_writer_.AdvanceLocation(pc_offset);
96   eh_frame_writer_.SetBaseAddressRegisterAndOffset(fp, 0);
97   eh_frame_writer_.RecordRegisterFollowsInitialRule(lr);
98 }
99 
100 }  // namespace compiler
101 }  // namespace internal
102 }  // namespace v8
103