OLD | NEW |
---|---|
(Empty) | |
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/arm/unwinding-info-writer-arm.h" | |
6 #include "src/compiler/instruction.h" | |
7 | |
8 namespace v8 { | |
9 namespace internal { | |
10 namespace compiler { | |
11 | |
12 void UnwindingInfoWriter::BeginInstructionBlock(int pc_offset, | |
13 const InstructionBlock* block) { | |
14 block_will_exit_ = false; | |
15 | |
16 auto lookup = block_initial_states_.find(block->rpo_number().ToInt()); | |
17 if (lookup != block_initial_states_.end()) { | |
18 if (lookup->second.saved_lr_ != saved_lr_) { | |
19 eh_frame_writer_.AdvanceLocation(pc_offset); | |
20 if (lookup->second.saved_lr_) { | |
21 eh_frame_writer_.RecordRegisterSavedToStack(lr, -4); | |
Jarin
2016/07/06 07:09:42
-4 ==> -kPointerSize? (Here and below.)
Stefano Sanfilippo
2016/07/06 13:25:10
Done.
| |
22 } else { | |
23 eh_frame_writer_.RecordRegisterIsValid(lr); | |
24 } | |
25 saved_lr_ = lookup->second.saved_lr_; | |
26 } | |
27 } else { | |
28 // The entry block always lacks an explicit initial state. | |
29 // The exit block may lack an explicit state, if it is only reached by | |
30 // the block ending in a bx lr. | |
31 // All the other blocks must have an explicit initial state. | |
32 DCHECK(block->predecessors().empty() || block->successors().empty()); | |
33 } | |
34 } | |
35 | |
36 void UnwindingInfoWriter::EndInstructionBlock(const InstructionBlock* block) { | |
37 if (block_will_exit_) return; | |
38 | |
39 for (const RpoNumber& successor : block->successors()) { | |
40 BlockInitialState state = {saved_lr_}; | |
41 auto inserted = block_initial_states_.insert({successor.ToInt(), state}); | |
42 // If we already had an entry for this BB, check that the values are the | |
43 // same we were trying to insert. | |
44 if (!inserted.second) { | |
45 DCHECK_EQ(inserted.first->second.saved_lr_, state.saved_lr_); | |
46 } | |
47 } | |
48 } | |
49 | |
50 void UnwindingInfoWriter::MarkFrameConstructed(int at_pc) { | |
51 // Regardless of the type of frame constructed, the relevant part of the | |
52 // layout is always the one in the diagram: | |
53 // | |
54 // | .... | higher addresses | |
55 // +----------+ ^ | |
56 // | LR | | | | |
57 // +----------+ | | | |
58 // | saved FP | | | | |
59 // +----------+ <-- FP v | |
60 // | .... | stack growth | |
61 // | |
62 // The LR is pushed on the stack, and we can record this fact at the end of | |
63 // the construction, since the LR itself is not modified in the process. | |
64 eh_frame_writer_.AdvanceLocation(at_pc); | |
65 eh_frame_writer_.RecordRegisterSavedToStack(lr, -4); | |
66 saved_lr_ = true; | |
67 } | |
68 | |
69 void UnwindingInfoWriter::MarkFrameDeconstructed(int at_pc) { | |
70 // The lr is restored by the last operation in LeaveFrame(). | |
71 eh_frame_writer_.AdvanceLocation(at_pc); | |
72 eh_frame_writer_.RecordRegisterIsValid(lr); | |
73 saved_lr_ = false; | |
74 } | |
75 | |
76 void UnwindingInfoWriter::MarkLinkRegisterOnTopOfStack(int pc_offset) { | |
77 eh_frame_writer_.AdvanceLocation(pc_offset); | |
78 eh_frame_writer_.SetBaseAddressRegisterAndOffset(sp, 0); | |
79 eh_frame_writer_.RecordRegisterSavedToStack(lr, 0); | |
80 } | |
81 | |
82 void UnwindingInfoWriter::MarkPopLinkRegisterFromTopOfStack(int pc_offset) { | |
83 eh_frame_writer_.AdvanceLocation(pc_offset); | |
84 eh_frame_writer_.SetBaseAddressRegisterAndOffset(fp, 0); | |
85 eh_frame_writer_.RecordRegisterIsValid(lr); | |
86 } | |
87 | |
88 } // namespace compiler | |
89 } // namespace internal | |
90 } // namespace v8 | |
OLD | NEW |