summaryrefslogtreecommitdiff
path: root/runtime/stack_map.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/stack_map.cc')
-rw-r--r--runtime/stack_map.cc120
1 files changed, 64 insertions, 56 deletions
diff --git a/runtime/stack_map.cc b/runtime/stack_map.cc
index eebca853c6..d813fd5487 100644
--- a/runtime/stack_map.cc
+++ b/runtime/stack_map.cc
@@ -27,34 +27,66 @@
namespace art {
-CodeInfo::CodeInfo(const OatQuickMethodHeader* header, DecodeFlags flags)
- : CodeInfo(header->GetOptimizedCodeInfoPtr(), flags) {
-}
-
-void CodeInfo::Decode(const uint8_t* data, DecodeFlags flags) {
+// The callback is used to inform the caller about memory bounds of the bit-tables.
+template<typename DecodeCallback>
+CodeInfo::CodeInfo(const uint8_t* data, size_t* num_read_bits, DecodeCallback callback) {
BitMemoryReader reader(data);
std::array<uint32_t, kNumHeaders> header = reader.ReadInterleavedVarints<kNumHeaders>();
ForEachHeaderField([this, &header](size_t i, auto member_pointer) {
this->*member_pointer = header[i];
});
- ForEachBitTableField([this, &reader](size_t i, auto member_pointer) {
+ ForEachBitTableField([this, &reader, &callback](size_t i, auto member_pointer) {
auto& table = this->*member_pointer;
if (LIKELY(HasBitTable(i))) {
if (UNLIKELY(IsBitTableDeduped(i))) {
ssize_t bit_offset = reader.NumberOfReadBits() - reader.ReadVarint();
BitMemoryReader reader2(reader.data(), bit_offset); // The offset is negative.
table.Decode(reader2);
+ callback(i, &table, reader2.GetReadRegion());
} else {
+ ssize_t bit_offset = reader.NumberOfReadBits();
table.Decode(reader);
+ callback(i, &table, reader.GetReadRegion().Subregion(bit_offset));
}
}
- }, flags);
- size_in_bits_ = reader.NumberOfReadBits();
- if (flags == AllTables) {
- DCHECK_EQ(HasInlineInfo(data), HasInlineInfo());
+ });
+ if (num_read_bits != nullptr) {
+ *num_read_bits = reader.NumberOfReadBits();
}
}
+CodeInfo::CodeInfo(const uint8_t* data, size_t* num_read_bits)
+ : CodeInfo(data, num_read_bits, [](size_t, auto*, BitMemoryRegion){}) {}
+
+CodeInfo::CodeInfo(const OatQuickMethodHeader* header)
+ : CodeInfo(header->GetOptimizedCodeInfoPtr()) {}
+
+QuickMethodFrameInfo CodeInfo::DecodeFrameInfo(const uint8_t* data) {
+ CodeInfo code_info(data);
+ return QuickMethodFrameInfo(code_info.packed_frame_size_ * kStackAlignment,
+ code_info.core_spill_mask_,
+ code_info.fp_spill_mask_);
+}
+
+CodeInfo CodeInfo::DecodeGcMasksOnly(const OatQuickMethodHeader* header) {
+ CodeInfo code_info(header->GetOptimizedCodeInfoPtr());
+ CodeInfo copy; // Copy to dead-code-eliminate all fields that we do not need.
+ copy.stack_maps_ = code_info.stack_maps_;
+ copy.register_masks_ = code_info.register_masks_;
+ copy.stack_masks_ = code_info.stack_masks_;
+ return copy;
+}
+
+CodeInfo CodeInfo::DecodeInlineInfoOnly(const OatQuickMethodHeader* header) {
+ CodeInfo code_info(header->GetOptimizedCodeInfoPtr());
+ CodeInfo copy; // Copy to dead-code-eliminate all fields that we do not need.
+ copy.number_of_dex_registers_ = code_info.number_of_dex_registers_;
+ copy.stack_maps_ = code_info.stack_maps_;
+ copy.inline_infos_ = code_info.inline_infos_;
+ copy.method_infos_ = code_info.method_infos_;
+ return copy;
+}
+
size_t CodeInfo::Deduper::Dedupe(const uint8_t* code_info_data) {
writer_.ByteAlign();
size_t deduped_offset = writer_.NumberOfWrittenBits() / kBitsPerByte;
@@ -64,27 +96,16 @@ size_t CodeInfo::Deduper::Dedupe(const uint8_t* code_info_data) {
// Read the existing code info and find (and keep) dedup-map iterator for each table.
// The iterator stores BitMemoryRegion and bit_offset of previous identical BitTable.
- BitMemoryReader reader(code_info_data);
- CodeInfo code_info; // Temporary storage for decoded data.
- std::array<uint32_t, kNumHeaders> header = reader.ReadInterleavedVarints<kNumHeaders>();
- ForEachHeaderField([&code_info, &header](size_t i, auto member_pointer) {
- code_info.*member_pointer = header[i];
- });
std::map<BitMemoryRegion, uint32_t, BitMemoryRegion::Less>::iterator it[kNumBitTables];
- ForEachBitTableField([this, &reader, &code_info, &it](size_t i, auto member_pointer) {
- DCHECK(!code_info.IsBitTableDeduped(i));
- if (code_info.HasBitTable(i)) {
- size_t bit_table_start = reader.NumberOfReadBits();
- (code_info.*member_pointer).Decode(reader);
- BitMemoryRegion region = reader.GetReadRegion().Subregion(bit_table_start);
- it[i] = dedupe_map_.emplace(region, /* default bit_offset */ 0).first;
- if (it[i]->second != 0 && region.size_in_bits() > kMinDedupSize) { // Seen before and large?
- code_info.SetBitTableDeduped(i); // Mark as deduped before we write header.
- }
+ CodeInfo code_info(code_info_data, nullptr, [&](size_t i, auto*, BitMemoryRegion region) {
+ it[i] = dedupe_map_.emplace(region, /*bit_offset=*/0).first;
+ if (it[i]->second != 0 && region.size_in_bits() > kMinDedupSize) { // Seen before and large?
+ code_info.SetBitTableDeduped(i); // Mark as deduped before we write header.
}
});
// Write the code info back, but replace deduped tables with relative offsets.
+ std::array<uint32_t, kNumHeaders> header;
ForEachHeaderField([&code_info, &header](size_t i, auto member_pointer) {
header[i] = code_info.*member_pointer;
});
@@ -119,17 +140,15 @@ size_t CodeInfo::Deduper::Dedupe(const uint8_t* code_info_data) {
return deduped_offset;
}
-BitTable<StackMap>::const_iterator CodeInfo::BinarySearchNativePc(uint32_t packed_pc) const {
- return std::partition_point(
+StackMap CodeInfo::GetStackMapForNativePcOffset(uint32_t pc, InstructionSet isa) const {
+ uint32_t packed_pc = StackMap::PackNativePc(pc, isa);
+ // Binary search. All catch stack maps are stored separately at the end.
+ auto it = std::partition_point(
stack_maps_.begin(),
stack_maps_.end(),
[packed_pc](const StackMap& sm) {
return sm.GetPackedNativePc() < packed_pc && sm.GetKind() != StackMap::Kind::Catch;
});
-}
-
-StackMap CodeInfo::GetStackMapForNativePcOffset(uint32_t pc, InstructionSet isa) const {
- auto it = BinarySearchNativePc(StackMap::PackNativePc(pc, isa));
// Start at the lower bound and iterate over all stack maps with the given native pc.
for (; it != stack_maps_.end() && (*it).GetNativePcOffset(isa) == pc; ++it) {
StackMap::Kind kind = static_cast<StackMap::Kind>((*it).GetKind());
@@ -207,34 +226,23 @@ void CodeInfo::DecodeDexRegisterMap(uint32_t stack_map_index,
void CodeInfo::CollectSizeStats(const uint8_t* code_info_data, /*out*/ Stats* parent) {
Stats* codeinfo_stats = parent->Child("CodeInfo");
BitMemoryReader reader(code_info_data);
- CodeInfo code_info; // Temporary storage for decoded tables.
- std::array<uint32_t, kNumHeaders> header = reader.ReadInterleavedVarints<kNumHeaders>();
- ForEachHeaderField([&code_info, &header](size_t i, auto member_pointer) {
- code_info.*member_pointer = header[i];
- });
+ reader.ReadInterleavedVarints<kNumHeaders>();
codeinfo_stats->Child("Header")->AddBits(reader.NumberOfReadBits());
- ForEachBitTableField([codeinfo_stats, &reader, &code_info](size_t i, auto member_pointer) {
- auto& table = code_info.*member_pointer;
- size_t bit_offset = reader.NumberOfReadBits();
- if (code_info.HasBitTable(i)) {
- if (code_info.IsBitTableDeduped(i)) {
- reader.ReadVarint();
- codeinfo_stats->Child("DedupeOffset")->AddBits(reader.NumberOfReadBits() - bit_offset);
- } else {
- table.Decode(reader);
- Stats* table_stats = codeinfo_stats->Child(table.GetName());
- table_stats->AddBits(reader.NumberOfReadBits() - bit_offset);
- const char* const* column_names = table.GetColumnNames();
- for (size_t c = 0; c < table.NumColumns(); c++) {
- if (table.NumColumnBits(c) > 0) {
- Stats* column_stats = table_stats->Child(column_names[c]);
- column_stats->AddBits(table.NumRows() * table.NumColumnBits(c), table.NumRows());
- }
+ size_t num_bits;
+ CodeInfo code_info(code_info_data, &num_bits, [&](size_t i, auto* table, BitMemoryRegion region) {
+ if (!code_info.IsBitTableDeduped(i)) {
+ Stats* table_stats = codeinfo_stats->Child(table->GetName());
+ table_stats->AddBits(region.size_in_bits());
+ const char* const* column_names = table->GetColumnNames();
+ for (size_t c = 0; c < table->NumColumns(); c++) {
+ if (table->NumColumnBits(c) > 0) {
+ Stats* column_stats = table_stats->Child(column_names[c]);
+ column_stats->AddBits(table->NumRows() * table->NumColumnBits(c), table->NumRows());
}
}
}
});
- codeinfo_stats->AddBytes(BitsToBytesRoundUp(reader.NumberOfReadBits()));
+ codeinfo_stats->AddBytes(BitsToBytesRoundUp(num_bits));
}
void DexRegisterMap::Dump(VariableIndentationOutputStream* vios) const {
@@ -254,7 +262,7 @@ void CodeInfo::Dump(VariableIndentationOutputStream* vios,
uint32_t code_offset,
bool verbose,
InstructionSet instruction_set) const {
- vios->Stream() << "CodeInfo BitSize=" << size_in_bits_
+ vios->Stream() << "CodeInfo "
<< " FrameSize:" << packed_frame_size_ * kStackAlignment
<< " CoreSpillMask:" << std::hex << core_spill_mask_
<< " FpSpillMask:" << std::hex << fp_spill_mask_