diff options
| -rw-r--r-- | compiler/debug/elf_debug_info_writer.h | 28 | ||||
| -rw-r--r-- | compiler/debug/elf_debug_loc_writer.h | 27 |
2 files changed, 40 insertions, 15 deletions
diff --git a/compiler/debug/elf_debug_info_writer.h b/compiler/debug/elf_debug_info_writer.h index eed032f88d..bddb054b80 100644 --- a/compiler/debug/elf_debug_info_writer.h +++ b/compiler/debug/elf_debug_info_writer.h @@ -173,6 +173,19 @@ class ElfCompilationUnitWriter { 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 @@ class ElfCompilationUnitWriter { // 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 @@ class ElfCompilationUnitWriter { 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 @@ class ElfCompilationUnitWriter { 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 @@ class ElfCompilationUnitWriter { // 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, diff --git a/compiler/debug/elf_debug_loc_writer.h b/compiler/debug/elf_debug_loc_writer.h index 32f624acd3..c321b4bc4f 100644 --- a/compiler/debug/elf_debug_loc_writer.h +++ b/compiler/debug/elf_debug_loc_writer.h @@ -85,29 +85,32 @@ struct VariableLocation { // The result will cover all ranges where the variable is in scope. // PCs corresponding to stackmap with dex register map are accurate, // all other PCs are best-effort only. -std::vector<VariableLocation> GetVariableLocations(const MethodDebugInfo* method_info, - uint16_t vreg, - bool is64bitValue, - uint32_t dex_pc_low, - uint32_t dex_pc_high) { +std::vector<VariableLocation> GetVariableLocations( + const MethodDebugInfo* method_info, + const std::vector<DexRegisterMap>& dex_register_maps, + uint16_t vreg, + bool is64bitValue, + uint32_t dex_pc_low, + uint32_t dex_pc_high) { std::vector<VariableLocation> variable_locations; // Get stack maps sorted by pc (they might not be sorted internally). const CodeInfo code_info(method_info->compiled_method->GetVmapTable().data()); const StackMapEncoding encoding = code_info.ExtractEncoding(); - std::map<uint32_t, StackMap> stack_maps; + std::map<uint32_t, uint32_t> stack_maps; // low_pc -> stack_map_index. for (uint32_t s = 0; s < code_info.GetNumberOfStackMaps(); s++) { StackMap stack_map = code_info.GetStackMapAt(s, encoding); DCHECK(stack_map.IsValid()); const uint32_t low_pc = method_info->low_pc + stack_map.GetNativePcOffset(encoding); DCHECK_LE(low_pc, method_info->high_pc); - stack_maps.emplace(low_pc, stack_map); + stack_maps.emplace(low_pc, s); } // Create entries for the requested register based on stack map data. for (auto it = stack_maps.begin(); it != stack_maps.end(); it++) { - const StackMap& stack_map = it->second; const uint32_t low_pc = it->first; + const uint32_t stack_map_index = it->second; + const StackMap& stack_map = code_info.GetStackMapAt(stack_map_index, encoding); auto next_it = it; next_it++; const uint32_t high_pc = next_it != stack_maps.end() ? next_it->first @@ -126,9 +129,9 @@ std::vector<VariableLocation> GetVariableLocations(const MethodDebugInfo* method // Find the location of the dex register. DexRegisterLocation reg_lo = DexRegisterLocation::None(); DexRegisterLocation reg_hi = DexRegisterLocation::None(); - if (stack_map.HasDexRegisterMap(encoding)) { - DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf( - stack_map, encoding, method_info->code_item->registers_size_); + DCHECK_LT(stack_map_index, dex_register_maps.size()); + DexRegisterMap dex_register_map = dex_register_maps[stack_map_index]; + if (dex_register_map.IsValid()) { reg_lo = dex_register_map.GetDexRegisterLocation( vreg, method_info->code_item->registers_size_, code_info, encoding); if (is64bitValue) { @@ -159,6 +162,7 @@ std::vector<VariableLocation> GetVariableLocations(const MethodDebugInfo* method // The dex register might be valid only at some points and it might // move between machine registers and stack. static void WriteDebugLocEntry(const MethodDebugInfo* method_info, + const std::vector<DexRegisterMap>& dex_register_maps, uint16_t vreg, bool is64bitValue, uint32_t compilation_unit_low_pc, @@ -175,6 +179,7 @@ static void WriteDebugLocEntry(const MethodDebugInfo* method_info, std::vector<VariableLocation> variable_locations = GetVariableLocations( method_info, + dex_register_maps, vreg, is64bitValue, dex_pc_low, |