Cache DexRegisterMaps when writing native debug info.
I might make the function more expensive in the future so I want
to make sure it gets called only the minimum number of times.
Change-Id: I1d09ecf1db7b54d28aaa11a152226d469f514fe7
diff --git a/compiler/debug/elf_debug_info_writer.h b/compiler/debug/elf_debug_info_writer.h
index eed032f..bddb054 100644
--- a/compiler/debug/elf_debug_info_writer.h
+++ b/compiler/debug/elf_debug_info_writer.h
@@ -173,6 +173,19 @@
info_.WriteExprLoc(DW_AT_frame_base, expr);
WriteLazyType(dex->GetReturnTypeDescriptor(dex_proto));
+ // Decode dex register locations for all stack maps.
+ // It might be expensive, so do it just once and reuse the result.
+ std::vector<DexRegisterMap> dex_reg_maps;
+ if (mi->IsFromOptimizingCompiler()) {
+ const CodeInfo code_info(mi->compiled_method->GetVmapTable().data());
+ StackMapEncoding encoding = code_info.ExtractEncoding();
+ for (size_t s = 0; s < code_info.GetNumberOfStackMaps(); ++s) {
+ const StackMap& stack_map = code_info.GetStackMapAt(s, encoding);
+ dex_reg_maps.push_back(code_info.GetDexRegisterMapOf(
+ stack_map, encoding, dex_code->registers_size_));
+ }
+ }
+
// Write parameters. DecodeDebugLocalInfo returns them as well, but it does not
// guarantee order or uniqueness so it is safer to iterate over them manually.
// DecodeDebugLocalInfo might not also be available if there is no debug info.
@@ -187,7 +200,7 @@
// Write the stack location of the parameter.
const uint32_t vreg = dex_code->registers_size_ - dex_code->ins_size_ + arg_reg;
const bool is64bitValue = false;
- WriteRegLocation(mi, vreg, is64bitValue, compilation_unit.low_pc);
+ WriteRegLocation(mi, dex_reg_maps, vreg, is64bitValue, compilation_unit.low_pc);
}
arg_reg++;
info_.EndTag();
@@ -206,7 +219,7 @@
if (dex_code != nullptr) {
// Write the stack location of the parameter.
const uint32_t vreg = dex_code->registers_size_ - dex_code->ins_size_ + arg_reg;
- WriteRegLocation(mi, vreg, is64bitValue, compilation_unit.low_pc);
+ WriteRegLocation(mi, dex_reg_maps, vreg, is64bitValue, compilation_unit.low_pc);
}
arg_reg += is64bitValue ? 2 : 1;
info_.EndTag();
@@ -229,8 +242,13 @@
WriteName(var.name_);
WriteLazyType(var.descriptor_);
bool is64bitValue = var.descriptor_[0] == 'D' || var.descriptor_[0] == 'J';
- WriteRegLocation(mi, var.reg_, is64bitValue, compilation_unit.low_pc,
- var.start_address_, var.end_address_);
+ WriteRegLocation(mi,
+ dex_reg_maps,
+ var.reg_,
+ is64bitValue,
+ compilation_unit.low_pc,
+ var.start_address_,
+ var.end_address_);
info_.EndTag();
}
}
@@ -424,12 +442,14 @@
// The dex register might be valid only at some points and it might
// move between machine registers and stack.
void WriteRegLocation(const MethodDebugInfo* method_info,
+ const std::vector<DexRegisterMap>& dex_register_maps,
uint16_t vreg,
bool is64bitValue,
uint32_t compilation_unit_low_pc,
uint32_t dex_pc_low = 0,
uint32_t dex_pc_high = 0xFFFFFFFF) {
WriteDebugLocEntry(method_info,
+ dex_register_maps,
vreg,
is64bitValue,
compilation_unit_low_pc,