Chromium Code Reviews| Index: src/compiler/arm/unwinding-info-writer-arm.cc |
| diff --git a/src/compiler/arm/unwinding-info-writer-arm.cc b/src/compiler/arm/unwinding-info-writer-arm.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..209f81833712d09f21087f27591366ffc507241a |
| --- /dev/null |
| +++ b/src/compiler/arm/unwinding-info-writer-arm.cc |
| @@ -0,0 +1,90 @@ |
| +// 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/arm/unwinding-info-writer-arm.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.saved_lr_ != saved_lr_) { |
| + eh_frame_writer_.AdvanceLocation(pc_offset); |
| + if (lookup->second.saved_lr_) { |
| + 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.
|
| + } else { |
| + eh_frame_writer_.RecordRegisterIsValid(lr); |
| + } |
| + saved_lr_ = lookup->second.saved_lr_; |
| + } |
| + } 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 bx lr. |
| + // 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 = {saved_lr_}; |
| + 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_EQ(inserted.first->second.saved_lr_, state.saved_lr_); |
| + } |
| + } |
| +} |
| + |
| +void UnwindingInfoWriter::MarkFrameConstructed(int at_pc) { |
| + // Regardless of the type of frame constructed, the relevant part of the |
| + // layout is always the one in the diagram: |
| + // |
| + // | .... | higher addresses |
| + // +----------+ ^ |
| + // | LR | | | |
| + // +----------+ | | |
| + // | saved FP | | | |
| + // +----------+ <-- FP v |
| + // | .... | stack growth |
| + // |
| + // The LR is pushed on the stack, and we can record this fact at the end of |
| + // the construction, since the LR itself is not modified in the process. |
| + eh_frame_writer_.AdvanceLocation(at_pc); |
| + eh_frame_writer_.RecordRegisterSavedToStack(lr, -4); |
| + saved_lr_ = true; |
| +} |
| + |
| +void UnwindingInfoWriter::MarkFrameDeconstructed(int at_pc) { |
| + // The lr is restored by the last operation in LeaveFrame(). |
| + eh_frame_writer_.AdvanceLocation(at_pc); |
| + eh_frame_writer_.RecordRegisterIsValid(lr); |
| + saved_lr_ = false; |
| +} |
| + |
| +void UnwindingInfoWriter::MarkLinkRegisterOnTopOfStack(int pc_offset) { |
| + eh_frame_writer_.AdvanceLocation(pc_offset); |
| + eh_frame_writer_.SetBaseAddressRegisterAndOffset(sp, 0); |
| + eh_frame_writer_.RecordRegisterSavedToStack(lr, 0); |
| +} |
| + |
| +void UnwindingInfoWriter::MarkPopLinkRegisterFromTopOfStack(int pc_offset) { |
| + eh_frame_writer_.AdvanceLocation(pc_offset); |
| + eh_frame_writer_.SetBaseAddressRegisterAndOffset(fp, 0); |
| + eh_frame_writer_.RecordRegisterIsValid(lr); |
| +} |
| + |
| +} // namespace compiler |
| +} // namespace internal |
| +} // namespace v8 |