1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "lazy_debug_frame_opcode_writer.h" 18#include "mir_to_lir.h" 19 20namespace art { 21namespace dwarf { 22 23const ArenaVector<uint8_t>* LazyDebugFrameOpCodeWriter::Patch(size_t code_size) { 24 if (!this->enabled_) { 25 DCHECK(this->data()->empty()); 26 return this->data(); 27 } 28 if (!patched_) { 29 patched_ = true; 30 // Move our data buffer to temporary variable. 31 ArenaVector<uint8_t> old_opcodes(this->opcodes_.get_allocator()); 32 old_opcodes.swap(this->opcodes_); 33 // Refill our data buffer with patched opcodes. 34 this->opcodes_.reserve(old_opcodes.size() + advances_.size() + 4); 35 size_t pos = 0; 36 for (auto advance : advances_) { 37 DCHECK_GE(advance.pos, pos); 38 // Copy old data up to the point when advance was issued. 39 this->opcodes_.insert(this->opcodes_.end(), 40 old_opcodes.begin() + pos, 41 old_opcodes.begin() + advance.pos); 42 pos = advance.pos; 43 // This may be null if there is no slow-path code after return. 44 LIR* next_lir = NEXT_LIR(advance.last_lir_insn); 45 // Insert the advance command with its final offset. 46 Base::AdvancePC(next_lir != nullptr ? next_lir->offset : code_size); 47 } 48 // Copy the final segment. 49 this->opcodes_.insert(this->opcodes_.end(), 50 old_opcodes.begin() + pos, 51 old_opcodes.end()); 52 Base::AdvancePC(code_size); 53 } 54 return this->data(); 55} 56 57} // namespace dwarf 58} // namespace art 59