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 8namespace v8 { 9namespace internal { 10namespace compiler { 11 12void 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 34void 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 54void 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 75void 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 84void 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 92void 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