return AddWordData(constant_list_p, val_lo);
}
-static void Push32(std::vector<uint8_t>&buf, int data) {
- buf.push_back(data & 0xff);
- buf.push_back((data >> 8) & 0xff);
- buf.push_back((data >> 16) & 0xff);
- buf.push_back((data >> 24) & 0xff);
-}
-
/**
* @brief Push a compressed reference which needs patching at link/patchoat-time.
* @details This needs to be kept consistent with the code which actually does the patching in
* oat_writer.cc and in the patchoat tool.
*/
-static void PushUnpatchedReference(std::vector<uint8_t>&buf) {
+static void PushUnpatchedReference(CodeBuffer* buf) {
// Note that we can safely initialize the patches to zero. The code deduplication mechanism takes
// the patches into account when determining whether two pieces of codes are functionally
// equivalent.
Push32(buf, UINT32_C(0));
}
-static void AlignBuffer(std::vector<uint8_t>&buf, size_t offset) {
- while (buf.size() < offset) {
- buf.push_back(0);
- }
+static void AlignBuffer(CodeBuffer* buf, size_t offset) {
+ DCHECK_LE(buf->size(), offset);
+ buf->insert(buf->end(), offset - buf->size(), 0u);
}
/* Write the literal pool to the output stream */
void Mir2Lir::InstallLiteralPools() {
- AlignBuffer(code_buffer_, data_offset_);
+ AlignBuffer(&code_buffer_, data_offset_);
LIR* data_lir = literal_list_;
while (data_lir != nullptr) {
- Push32(code_buffer_, data_lir->operands[0]);
+ Push32(&code_buffer_, data_lir->operands[0]);
data_lir = NEXT_LIR(data_lir);
}
// TODO: patches_.reserve() as needed.
reinterpret_cast<const DexFile*>(UnwrapPointer(data_lir->operands[1]));
patches_.push_back(LinkerPatch::CodePatch(code_buffer_.size(),
target_dex_file, target_method_idx));
- PushUnpatchedReference(code_buffer_);
+ PushUnpatchedReference(&code_buffer_);
data_lir = NEXT_LIR(data_lir);
}
data_lir = method_literal_list_;
reinterpret_cast<const DexFile*>(UnwrapPointer(data_lir->operands[1]));
patches_.push_back(LinkerPatch::MethodPatch(code_buffer_.size(),
target_dex_file, target_method_idx));
- PushUnpatchedReference(code_buffer_);
+ PushUnpatchedReference(&code_buffer_);
data_lir = NEXT_LIR(data_lir);
}
// Push class literals.
reinterpret_cast<const DexFile*>(UnwrapPointer(data_lir->operands[1]));
patches_.push_back(LinkerPatch::TypePatch(code_buffer_.size(),
class_dex_file, target_type_idx));
- PushUnpatchedReference(code_buffer_);
+ PushUnpatchedReference(&code_buffer_);
data_lir = NEXT_LIR(data_lir);
}
}
/* Write the switch tables to the output stream */
void Mir2Lir::InstallSwitchTables() {
for (Mir2Lir::SwitchTable* tab_rec : switch_tables_) {
- AlignBuffer(code_buffer_, tab_rec->offset);
+ AlignBuffer(&code_buffer_, tab_rec->offset);
/*
* For Arm, our reference point is the address of the bx
* instruction that does the launch, so we have to subtract
LIR* boundary_lir = InsertCaseLabel(target, key);
DCHECK(boundary_lir != nullptr);
int disp = boundary_lir->offset - bx_offset;
- Push32(code_buffer_, key);
- Push32(code_buffer_, disp);
+ Push32(&code_buffer_, key);
+ Push32(&code_buffer_, disp);
if (cu_->verbose) {
LOG(INFO) << " Case[" << elems << "] key: 0x"
<< std::hex << key << ", disp: 0x"
LIR* boundary_lir = InsertCaseLabel(target, key);
DCHECK(boundary_lir != nullptr);
int disp = boundary_lir->offset - bx_offset;
- Push32(code_buffer_, disp);
+ Push32(&code_buffer_, disp);
if (cu_->verbose) {
LOG(INFO) << " Case[" << elems << "] disp: 0x"
<< std::hex << disp;
/* Write the fill array dta to the output stream */
void Mir2Lir::InstallFillArrayData() {
for (Mir2Lir::FillArrayData* tab_rec : fill_array_data_) {
- AlignBuffer(code_buffer_, tab_rec->offset);
+ AlignBuffer(&code_buffer_, tab_rec->offset);
for (int i = 0; i < (tab_rec->size + 1) / 2; i++) {
code_buffer_.push_back(tab_rec->table[i] & 0xFF);
code_buffer_.push_back((tab_rec->table[i] >> 8) & 0xFF);
estimated_native_code_size_(0),
reg_pool_(nullptr),
live_sreg_(0),
+ code_buffer_(mir_graph->GetArena()->Adapter()),
+ encoded_mapping_table_(mir_graph->GetArena()->Adapter()),
core_vmap_table_(mir_graph->GetArena()->Adapter()),
fp_vmap_table_(mir_graph->GetArena()->Adapter()),
+ native_gc_map_(mir_graph->GetArena()->Adapter()),
patches_(mir_graph->GetArena()->Adapter()),
num_core_spills_(0),
num_fp_spills_(0),
uint32_t method_idx, uintptr_t direct_code,
uintptr_t direct_method, InvokeType type);
-typedef std::vector<uint8_t> CodeBuffer;
+typedef ArenaVector<uint8_t> CodeBuffer;
typedef uint32_t CodeOffset; // Native code offset in bytes.
struct UseDefMasks {
// The source mapping table data (pc -> dex). More entries than in encoded_mapping_table_
DefaultSrcMap src_mapping_table_;
// The encoding mapping table data (dex -> pc offset and pc offset -> dex) with a size prefix.
- std::vector<uint8_t> encoded_mapping_table_;
+ ArenaVector<uint8_t> encoded_mapping_table_;
ArenaVector<uint32_t> core_vmap_table_;
ArenaVector<uint32_t> fp_vmap_table_;
- std::vector<uint8_t> native_gc_map_;
+ ArenaVector<uint8_t> native_gc_map_;
ArenaVector<LinkerPatch> patches_;
int num_core_spills_;
int num_fp_spills_;
}
for (LIR *p = const_vectors_; p != nullptr; p = p->next) {
- PushWord(&code_buffer_, p->operands[0]);
- PushWord(&code_buffer_, p->operands[1]);
- PushWord(&code_buffer_, p->operands[2]);
- PushWord(&code_buffer_, p->operands[3]);
+ Push32(&code_buffer_, p->operands[0]);
+ Push32(&code_buffer_, p->operands[1]);
+ Push32(&code_buffer_, p->operands[2]);
+ Push32(&code_buffer_, p->operands[3]);
}
}
// Length (will be filled in later in this routine).
if (is_x86_64) {
- PushWord(cfi_info, 0xffffffff); // Indicates 64bit
- PushWord(cfi_info, 0);
- PushWord(cfi_info, 0);
+ Push32(cfi_info, 0xffffffff); // Indicates 64bit
+ Push32(cfi_info, 0);
+ Push32(cfi_info, 0);
} else {
- PushWord(cfi_info, 0);
+ Push32(cfi_info, 0);
}
// CIE id: always 0.
if (is_x86_64) {
- PushWord(cfi_info, 0);
- PushWord(cfi_info, 0);
+ Push32(cfi_info, 0);
+ Push32(cfi_info, 0);
} else {
- PushWord(cfi_info, 0);
+ Push32(cfi_info, 0);
}
// Version: always 1.
PushByte(data_, 0); // extended opcode:
PushByte(data_, 1 + 4); // length: opcode_size + address_size
PushByte(data_, DW_LNE_set_address);
- PushWord(data_, addr);
+ Push32(data_, addr);
}
void SetLine(unsigned line) {
// Start the debug_info section with the header information
// 'unit_length' will be filled in later.
int cunit_length = dbg_info->size();
- PushWord(dbg_info, 0);
+ Push32(dbg_info, 0);
// 'version' - 3.
PushHalf(dbg_info, 3);
// Offset into .debug_abbrev section (always 0).
- PushWord(dbg_info, 0);
+ Push32(dbg_info, 0);
// Address size: 4.
PushByte(dbg_info, 4);
PushByte(dbg_info, 1);
// The producer is Android dex2oat.
- PushWord(dbg_info, producer_str_offset);
+ Push32(dbg_info, producer_str_offset);
// The language is Java.
PushByte(dbg_info, DW_LANG_Java);
uint32_t cunit_low_pc = 0 - 1;
uint32_t cunit_high_pc = 0;
int cunit_low_pc_pos = dbg_info->size();
- PushWord(dbg_info, 0);
- PushWord(dbg_info, 0);
+ Push32(dbg_info, 0);
+ Push32(dbg_info, 0);
if (dbg_line == nullptr) {
for (size_t i = 0; i < method_info.size(); ++i) {
PushByte(dbg_info, 2);
// Enter name, low_pc, high_pc.
- PushWord(dbg_info, PushStr(dbg_str, dbg.method_name_));
- PushWord(dbg_info, dbg.low_pc_ + text_section_offset);
- PushWord(dbg_info, dbg.high_pc_ + text_section_offset);
+ Push32(dbg_info, PushStr(dbg_str, dbg.method_name_));
+ Push32(dbg_info, dbg.low_pc_ + text_section_offset);
+ Push32(dbg_info, dbg.high_pc_ + text_section_offset);
}
} else {
// TODO: in gdb info functions <regexp> - reports Java functions, but
// method ranges.
// Line number table offset
- PushWord(dbg_info, dbg_line->size());
+ Push32(dbg_info, dbg_line->size());
size_t lnt_length = dbg_line->size();
- PushWord(dbg_line, 0);
+ Push32(dbg_line, 0);
PushHalf(dbg_line, 4); // LNT Version DWARF v4 => 4
size_t lnt_hdr_length = dbg_line->size();
- PushWord(dbg_line, 0); // TODO: 64-bit uses 8-byte here
+ Push32(dbg_line, 0); // TODO: 64-bit uses 8-byte here
PushByte(dbg_line, 1); // minimum_instruction_length (ubyte)
PushByte(dbg_line, 1); // maximum_operations_per_instruction (ubyte) = always 1
PushByte(dbg_info, 2);
// Enter name, low_pc, high_pc.
- PushWord(dbg_info, PushStr(dbg_str, dbg.method_name_));
- PushWord(dbg_info, dbg.low_pc_ + text_section_offset);
- PushWord(dbg_info, dbg.high_pc_ + text_section_offset);
+ Push32(dbg_info, PushStr(dbg_str, dbg.method_name_));
+ Push32(dbg_info, dbg.low_pc_ + text_section_offset);
+ Push32(dbg_info, dbg.high_pc_ + text_section_offset);
GetLineInfoForJava(dbg.dbgstream_, dbg.compiled_method_->GetSrcMappingTable(),
&pc2java_map, dbg.low_pc_);
class GcMapBuilder {
public:
- GcMapBuilder(std::vector<uint8_t>* table, size_t entries, uint32_t max_native_offset,
+ template <typename Alloc>
+ GcMapBuilder(std::vector<uint8_t, Alloc>* table, size_t entries, uint32_t max_native_offset,
size_t references_width)
: entries_(entries), references_width_(entries != 0u ? references_width : 0u),
native_offset_width_(entries != 0 && max_native_offset != 0
? sizeof(max_native_offset) - CLZ(max_native_offset) / 8u
: 0u),
- in_use_(entries), table_(table) {
+ in_use_(entries) {
// Resize table and set up header.
table->resize((EntryWidth() * entries) + sizeof(uint32_t));
+ table_ = table->data();
CHECK_LT(native_offset_width_, 1U << 3);
(*table)[0] = native_offset_width_ & 7;
CHECK_LT(references_width_, 1U << 13);
uint32_t native_offset = 0;
size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t);
for (size_t i = 0; i < native_offset_width_; i++) {
- native_offset |= (*table_)[table_offset + i] << (i * 8);
+ native_offset |= table_[table_offset + i] << (i * 8);
}
return native_offset;
}
void SetCodeOffset(size_t table_index, uint32_t native_offset) {
size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t);
for (size_t i = 0; i < native_offset_width_; i++) {
- (*table_)[table_offset + i] = (native_offset >> (i * 8)) & 0xFF;
+ table_[table_offset + i] = (native_offset >> (i * 8)) & 0xFF;
}
}
void SetReferences(size_t table_index, const uint8_t* references) {
size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t);
- memcpy(&(*table_)[table_offset + native_offset_width_], references, references_width_);
+ memcpy(&table_[table_offset + native_offset_width_], references, references_width_);
}
size_t EntryWidth() const {
// Entries that are in use.
std::vector<bool> in_use_;
// The table we're building.
- std::vector<uint8_t>* const table_;
+ uint8_t* table_;
};
} // namespace art
} else {
// Four byte delta.
buf->push_back(0x04);
- PushWord(buf, increment);
+ Push32(buf, increment);
}
}
void WriteFDEHeader(std::vector<uint8_t>* buf, bool is_64bit) {
// 'length' (filled in by other functions).
if (is_64bit) {
- PushWord(buf, 0xffffffff); // Indicates 64bit
- PushWord(buf, 0);
- PushWord(buf, 0);
+ Push32(buf, 0xffffffff); // Indicates 64bit
+ Push32(buf, 0);
+ Push32(buf, 0);
} else {
- PushWord(buf, 0);
+ Push32(buf, 0);
}
// 'CIE_pointer' (filled in by linker).
if (is_64bit) {
- PushWord(buf, 0);
- PushWord(buf, 0);
+ Push32(buf, 0);
+ Push32(buf, 0);
} else {
- PushWord(buf, 0);
+ Push32(buf, 0);
}
// 'initial_location' (filled in by linker).
if (is_64bit) {
- PushWord(buf, 0);
- PushWord(buf, 0);
+ Push32(buf, 0);
+ Push32(buf, 0);
} else {
- PushWord(buf, 0);
+ Push32(buf, 0);
}
// 'address_range' (filled in by other functions).
if (is_64bit) {
- PushWord(buf, 0);
- PushWord(buf, 0);
+ Push32(buf, 0);
+ Push32(buf, 0);
} else {
- PushWord(buf, 0);
+ Push32(buf, 0);
}
// Augmentation length: 0
Leb128Encoder(dst).PushBackSigned(data);
}
-void PushWord(std::vector<uint8_t>* buf, int data) {
- buf->push_back(data & 0xff);
- buf->push_back((data >> 8) & 0xff);
- buf->push_back((data >> 16) & 0xff);
- buf->push_back((data >> 24) & 0xff);
-}
-
std::string PrettyDescriptor(Primitive::Type type) {
return PrettyDescriptor(Primitive::Descriptor(type));
}
}
};
-void PushWord(std::vector<uint8_t>* buf, int32_t data);
+template <typename Alloc>
+void Push32(std::vector<uint8_t, Alloc>* buf, int32_t data) {
+ buf->push_back(data & 0xff);
+ buf->push_back((data >> 8) & 0xff);
+ buf->push_back((data >> 16) & 0xff);
+ buf->push_back((data >> 24) & 0xff);
+}
void EncodeUnsignedLeb128(uint32_t data, std::vector<uint8_t>* buf);
void EncodeSignedLeb128(int32_t data, std::vector<uint8_t>* buf);