Chromium Code Reviews| Index: src/compiler/arm64/unwinding-info-writer-arm64.cc | 
| diff --git a/src/compiler/arm64/unwinding-info-writer-arm64.cc b/src/compiler/arm64/unwinding-info-writer-arm64.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..f430b7cf99a9c037daad522a535488bc23cac44a | 
| --- /dev/null | 
| +++ b/src/compiler/arm64/unwinding-info-writer-arm64.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/arm64/unwinding-info-writer-arm64.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, -8); | 
| 
 
Jarin
2016/07/06 07:09:42
8 ==> kPointerSize?
 
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 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 = {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 is not modified in the process. | 
| + eh_frame_writer_.AdvanceLocation(at_pc); | 
| + eh_frame_writer_.RecordRegisterSavedToStack(lr, -8); | 
| + 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(fp, 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 |