diff options
author | 2017-12-12 21:37:59 +0000 | |
---|---|---|
committer | 2017-12-12 21:37:59 +0000 | |
commit | 702f6f276d2b81ae27bce51c2e78b04aa45a5796 (patch) | |
tree | 84e1e493074878447cf1fe01ece97b9eff8b5f52 | |
parent | 6f05cca7f37eba9f831c811af044bfe735acb8cd (diff) | |
parent | 31f4c9f86522061d682fd0e2c6003043cec496dc (diff) |
Merge "Add CodeItemDebugInfoAccessor"
-rw-r--r-- | compiler/debug/elf_debug_info_writer.h | 34 | ||||
-rw-r--r-- | compiler/debug/elf_debug_line_writer.h | 6 | ||||
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 12 | ||||
-rw-r--r-- | dex2oat/linker/oat_writer.cc | 3 | ||||
-rw-r--r-- | dexdump/dexdump.cc | 12 | ||||
-rw-r--r-- | dexlist/dexlist.cc | 2 | ||||
-rw-r--r-- | openjdkjvmti/ti_method.cc | 44 | ||||
-rw-r--r-- | runtime/code_item_accessors-inl.h | 28 | ||||
-rw-r--r-- | runtime/code_item_accessors.h | 24 | ||||
-rw-r--r-- | runtime/debugger.cc | 49 | ||||
-rw-r--r-- | runtime/dex_file-inl.h | 21 | ||||
-rw-r--r-- | runtime/dex_file.h | 7 | ||||
-rw-r--r-- | runtime/dex_file_annotations.cc | 8 | ||||
-rw-r--r-- | runtime/dex_file_test.cc | 9 |
14 files changed, 167 insertions, 92 deletions
diff --git a/compiler/debug/elf_debug_info_writer.h b/compiler/debug/elf_debug_info_writer.h index d5999941d7..81a0a69bfa 100644 --- a/compiler/debug/elf_debug_info_writer.h +++ b/compiler/debug/elf_debug_info_writer.h @@ -22,6 +22,7 @@ #include <vector> #include "art_field-inl.h" +#include "code_item_accessors-inl.h" #include "debug/dwarf/debug_abbrev_writer.h" #include "debug/dwarf/debug_info_entry_writer.h" #include "debug/elf_compilation_unit.h" @@ -48,10 +49,10 @@ static void LocalInfoCallback(void* ctx, const DexFile::LocalInfo& entry) { static std::vector<const char*> GetParamNames(const MethodDebugInfo* mi) { std::vector<const char*> names; - if (mi->code_item != nullptr) { + CodeItemDebugInfoAccessor accessor(mi->dex_file, mi->code_item); + if (accessor.HasCodeItem()) { DCHECK(mi->dex_file != nullptr); - uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*mi->dex_file, mi->code_item); - const uint8_t* stream = mi->dex_file->GetDebugInfoStream(debug_info_offset); + const uint8_t* stream = mi->dex_file->GetDebugInfoStream(accessor.DebugInfoOffset()); if (stream != nullptr) { DecodeUnsignedLeb128(&stream); // line. uint32_t parameters_size = DecodeUnsignedLeb128(&stream); @@ -162,7 +163,7 @@ class ElfCompilationUnitWriter { for (auto mi : compilation_unit.methods) { DCHECK(mi->dex_file != nullptr); const DexFile* dex = mi->dex_file; - const DexFile::CodeItem* dex_code = mi->code_item; + CodeItemDebugInfoAccessor accessor(dex, mi->code_item); const DexFile::MethodId& dex_method = dex->GetMethodId(mi->dex_method_index); const DexFile::ProtoId& dex_proto = dex->GetMethodPrototype(dex_method); const DexFile::TypeList* dex_params = dex->GetProtoParameters(dex_proto); @@ -204,13 +205,13 @@ class ElfCompilationUnitWriter { // 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 (dex_code != nullptr && mi->code_info != nullptr) { + if (accessor.HasCodeItem() && mi->code_info != nullptr) { const CodeInfo code_info(mi->code_info); CodeInfoEncoding encoding = code_info.ExtractEncoding(); for (size_t s = 0; s < code_info.GetNumberOfStackMaps(encoding); ++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_)); + stack_map, encoding, accessor.RegistersSize())); } } @@ -224,9 +225,9 @@ class ElfCompilationUnitWriter { WriteName("this"); info_.WriteFlagPresent(DW_AT_artificial); WriteLazyType(dex_class_desc); - if (dex_code != nullptr) { + if (accessor.HasCodeItem()) { // Write the stack location of the parameter. - const uint32_t vreg = dex_code->registers_size_ - dex_code->ins_size_ + arg_reg; + const uint32_t vreg = accessor.RegistersSize() - accessor.InsSize() + arg_reg; const bool is64bitValue = false; WriteRegLocation(mi, dex_reg_maps, vreg, is64bitValue, compilation_unit.code_address); } @@ -244,30 +245,31 @@ class ElfCompilationUnitWriter { const char* type_desc = dex->StringByTypeIdx(dex_params->GetTypeItem(i).type_idx_); WriteLazyType(type_desc); const bool is64bitValue = type_desc[0] == 'D' || type_desc[0] == 'J'; - if (dex_code != nullptr) { + if (accessor.HasCodeItem()) { // Write the stack location of the parameter. - const uint32_t vreg = dex_code->registers_size_ - dex_code->ins_size_ + arg_reg; + const uint32_t vreg = accessor.RegistersSize() - accessor.InsSize() + arg_reg; WriteRegLocation(mi, dex_reg_maps, vreg, is64bitValue, compilation_unit.code_address); } arg_reg += is64bitValue ? 2 : 1; info_.EndTag(); } - if (dex_code != nullptr) { - DCHECK_EQ(arg_reg, dex_code->ins_size_); + if (accessor.HasCodeItem()) { + DCHECK_EQ(arg_reg, accessor.InsSize()); } } // Write local variables. LocalInfos local_infos; - uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*dex, dex_code); - if (dex->DecodeDebugLocalInfo(dex_code, - debug_info_offset, + if (dex->DecodeDebugLocalInfo(accessor.RegistersSize(), + accessor.InsSize(), + accessor.InsnsSizeInCodeUnits(), + accessor.DebugInfoOffset(), is_static, mi->dex_method_index, LocalInfoCallback, &local_infos)) { for (const DexFile::LocalInfo& var : local_infos) { - if (var.reg_ < dex_code->registers_size_ - dex_code->ins_size_) { + if (var.reg_ < accessor.RegistersSize() - accessor.InsSize()) { info_.StartTag(DW_TAG_variable); WriteName(var.name_); WriteLazyType(var.descriptor_); diff --git a/compiler/debug/elf_debug_line_writer.h b/compiler/debug/elf_debug_line_writer.h index 943e03a765..c7224fc94a 100644 --- a/compiler/debug/elf_debug_line_writer.h +++ b/compiler/debug/elf_debug_line_writer.h @@ -159,9 +159,9 @@ class ElfDebugLineWriter { PositionInfos dex2line_map; DCHECK(mi->dex_file != nullptr); const DexFile* dex = mi->dex_file; - uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*dex, mi->code_item); - if (!dex->DecodeDebugPositionInfo( - mi->code_item, debug_info_offset, PositionInfoCallback, &dex2line_map)) { + CodeItemDebugInfoAccessor accessor(dex, mi->code_item); + const uint32_t debug_info_offset = accessor.DebugInfoOffset(); + if (!dex->DecodeDebugPositionInfo(debug_info_offset, PositionInfoCallback, &dex2line_map)) { continue; } diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 710c2efd5f..e36d91fb05 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -442,17 +442,15 @@ ArenaBitVector* HInstructionBuilder::FindNativeDebugInfoLocations() { return false; } }; - const uint32_t num_instructions = code_item_->insns_size_in_code_units_; + CodeItemDebugInfoAccessor accessor(dex_file_, code_item_); ArenaBitVector* locations = ArenaBitVector::Create(local_allocator_, - num_instructions, + accessor.InsnsSizeInCodeUnits(), /* expandable */ false, kArenaAllocGraphBuilder); locations->ClearAllBits(); - uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*dex_file_, code_item_); - dex_file_->DecodeDebugPositionInfo(code_item_, debug_info_offset, Callback::Position, locations); + dex_file_->DecodeDebugPositionInfo(accessor.DebugInfoOffset(), Callback::Position, locations); // Instruction-specific tweaks. - IterationRange<DexInstructionIterator> instructions = code_item_->Instructions(); - for (const DexInstructionPcPair& inst : instructions) { + for (const DexInstructionPcPair& inst : accessor) { switch (inst->Opcode()) { case Instruction::MOVE_EXCEPTION: { // Stop in native debugger after the exception has been moved. @@ -461,7 +459,7 @@ ArenaBitVector* HInstructionBuilder::FindNativeDebugInfoLocations() { locations->ClearBit(inst.DexPc()); DexInstructionIterator next = std::next(DexInstructionIterator(inst)); DCHECK(next.DexPc() != inst.DexPc()); - if (next != instructions.end()) { + if (next != accessor.end()) { locations->SetBit(next.DexPc()); } break; diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc index 786acce8ee..d4fc59c6c2 100644 --- a/dex2oat/linker/oat_writer.cc +++ b/dex2oat/linker/oat_writer.cc @@ -2696,7 +2696,8 @@ class OatWriter::WriteQuickeningIndicesMethodVisitor { CompiledMethod* compiled_method = driver.GetCompiledMethod(MethodReference(dex_file, method_idx)); const DexFile::CodeItem* code_item = class_it.GetMethodCodeItem(); - uint32_t existing_debug_info_offset = OatFile::GetDebugInfoOffset(*dex_file, code_item); + CodeItemDebugInfoAccessor accessor(dex_file, code_item); + const uint32_t existing_debug_info_offset = accessor.DebugInfoOffset(); // If the existing offset is already out of bounds (and not magic marker 0xFFFFFFFF) // we will pretend the method has been quickened. bool existing_offset_out_of_bounds = diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc index a7af193f0a..527a5b993c 100644 --- a/dexdump/dexdump.cc +++ b/dexdump/dexdump.cc @@ -1203,10 +1203,16 @@ static void dumpCode(const DexFile* pDexFile, u4 idx, u4 flags, bool is_static = (flags & kAccStatic) != 0; fprintf(gOutFile, " positions : \n"); uint32_t debug_info_offset = pDexFile->GetDebugInfoOffset(pCode); - pDexFile->DecodeDebugPositionInfo(pCode, debug_info_offset, dumpPositionsCb, nullptr); + pDexFile->DecodeDebugPositionInfo(debug_info_offset, dumpPositionsCb, nullptr); fprintf(gOutFile, " locals : \n"); - pDexFile->DecodeDebugLocalInfo( - pCode, debug_info_offset, is_static, idx, dumpLocalsCb, nullptr); + pDexFile->DecodeDebugLocalInfo(pCode->registers_size_, + pCode->ins_size_, + pCode->insns_size_in_code_units_, + debug_info_offset, + is_static, + idx, + dumpLocalsCb, + nullptr); } /* diff --git a/dexlist/dexlist.cc b/dexlist/dexlist.cc index 630eacba9b..4c13ed6410 100644 --- a/dexlist/dexlist.cc +++ b/dexlist/dexlist.cc @@ -122,7 +122,7 @@ static void dumpMethod(const DexFile* pDexFile, // Find the first line. int firstLine = -1; uint32_t debug_info_offset = pDexFile->GetDebugInfoOffset(pCode); - pDexFile->DecodeDebugPositionInfo(pCode, debug_info_offset, positionsCb, &firstLine); + pDexFile->DecodeDebugPositionInfo(debug_info_offset, positionsCb, &firstLine); // Method signature. const Signature signature = pDexFile->GetMethodSignature(pMethodId); diff --git a/openjdkjvmti/ti_method.cc b/openjdkjvmti/ti_method.cc index 448ce41d0f..4444853427 100644 --- a/openjdkjvmti/ti_method.cc +++ b/openjdkjvmti/ti_method.cc @@ -37,6 +37,7 @@ #include "art_method-inl.h" #include "base/enums.h" #include "base/mutex-inl.h" +#include "code_item_accessors-inl.h" #include "dex_file_annotations.h" #include "dex_file_types.h" #include "events-inl.h" @@ -190,12 +191,17 @@ jvmtiError MethodUtil::GetLocalVariableTable(jvmtiEnv* env, } art::ScopedObjectAccess soa(art::Thread::Current()); - const art::DexFile* dex_file = art_method->GetDexFile(); - const art::DexFile::CodeItem* code_item = art_method->GetCodeItem(); - // TODO code_item == nullptr means that the method is abstract (or native, but we check that + + const art::DexFile* const dex_file = art_method->GetDexFile(); + if (dex_file == nullptr) { + return ERR(ABSENT_INFORMATION); + } + + // TODO HasCodeItem == false means that the method is abstract (or native, but we check that // earlier). We should check what is returned by the RI in this situation since it's not clear // what the appropriate return value is from the spec. - if (dex_file == nullptr || code_item == nullptr) { + art::CodeItemDebugInfoAccessor accessor(art_method); + if (!accessor.HasCodeItem()) { return ERR(ABSENT_INFORMATION); } @@ -260,9 +266,10 @@ jvmtiError MethodUtil::GetLocalVariableTable(jvmtiEnv* env, }; LocalVariableContext context(env); - uint32_t debug_info_offset = art::OatFile::GetDebugInfoOffset(*dex_file, code_item); - if (!dex_file->DecodeDebugLocalInfo(code_item, - debug_info_offset, + if (!dex_file->DecodeDebugLocalInfo(accessor.RegistersSize(), + accessor.InsSize(), + accessor.InsnsSizeInCodeUnits(), + accessor.DebugInfoOffset(), art_method->IsStatic(), art_method->GetDexMethodIndex(), LocalVariableContext::Callback, @@ -462,7 +469,7 @@ jvmtiError MethodUtil::GetLineNumberTable(jvmtiEnv* env, art::ArtMethod* art_method = art::jni::DecodeArtMethod(method); DCHECK(!art_method->IsRuntimeMethod()); - const art::DexFile::CodeItem* code_item; + art::CodeItemDebugInfoAccessor accessor; const art::DexFile* dex_file; { art::ScopedObjectAccess soa(art::Thread::Current()); @@ -477,15 +484,14 @@ jvmtiError MethodUtil::GetLineNumberTable(jvmtiEnv* env, return ERR(NULL_POINTER); } - code_item = art_method->GetCodeItem(); + accessor = art::CodeItemDebugInfoAccessor(art_method); dex_file = art_method->GetDexFile(); - DCHECK(code_item != nullptr) << art_method->PrettyMethod() << " " << dex_file->GetLocation(); + DCHECK(accessor.HasCodeItem()) << art_method->PrettyMethod() << " " << dex_file->GetLocation(); } LineNumberContext context; - uint32_t debug_info_offset = art::OatFile::GetDebugInfoOffset(*dex_file, code_item); bool success = dex_file->DecodeDebugPositionInfo( - code_item, debug_info_offset, CollectLineNumbers, &context); + accessor.DebugInfoOffset(), CollectLineNumbers, &context); if (!success) { return ERR(ABSENT_INFORMATION); } @@ -613,8 +619,11 @@ class CommonLocalVariableClosure : public art::Closure { /*out*/art::Primitive::Type* type) REQUIRES(art::Locks::mutator_lock_) { const art::DexFile* dex_file = method->GetDexFile(); - const art::DexFile::CodeItem* code_item = method->GetCodeItem(); - if (dex_file == nullptr || code_item == nullptr) { + if (dex_file == nullptr) { + return ERR(OPAQUE_FRAME); + } + art::CodeItemDebugInfoAccessor accessor(method); + if (!accessor.HasCodeItem()) { return ERR(OPAQUE_FRAME); } @@ -653,9 +662,10 @@ class CommonLocalVariableClosure : public art::Closure { }; GetLocalVariableInfoContext context(slot_, dex_pc, descriptor, type); - uint32_t debug_info_offset = art::OatFile::GetDebugInfoOffset(*dex_file, code_item); - if (!dex_file->DecodeDebugLocalInfo(code_item, - debug_info_offset, + if (!dex_file->DecodeDebugLocalInfo(accessor.RegistersSize(), + accessor.InsSize(), + accessor.InsnsSizeInCodeUnits(), + accessor.DebugInfoOffset(), method->IsStatic(), method->GetDexMethodIndex(), GetLocalVariableInfoContext::Callback, diff --git a/runtime/code_item_accessors-inl.h b/runtime/code_item_accessors-inl.h index d04849d09a..4f4d8cc86e 100644 --- a/runtime/code_item_accessors-inl.h +++ b/runtime/code_item_accessors-inl.h @@ -22,6 +22,7 @@ #include "art_method-inl.h" #include "cdex/compact_dex_file.h" #include "dex_file-inl.h" +#include "oat_file.h" #include "standard_dex_file.h" namespace art { @@ -37,7 +38,7 @@ inline void CodeItemInstructionAccessor::Init(const StandardDexFile::CodeItem& c } inline void CodeItemInstructionAccessor::Init(const DexFile* dex_file, - const DexFile::CodeItem* code_item) { + const DexFile::CodeItem* code_item) { DCHECK(dex_file != nullptr); DCHECK(code_item != nullptr); if (dex_file->IsCompactDexFile()) { @@ -150,6 +151,31 @@ inline const DexFile::TryItem* CodeItemDataAccessor::FindTryItem(uint32_t try_de return index != -1 ? &try_items.begin()[index] : nullptr; } +inline CodeItemDebugInfoAccessor::CodeItemDebugInfoAccessor(ArtMethod* method) + : CodeItemDebugInfoAccessor(method->GetDexFile(), method->GetCodeItem()) {} + +inline CodeItemDebugInfoAccessor::CodeItemDebugInfoAccessor(const DexFile* dex_file, + const DexFile::CodeItem* code_item) { + if (code_item == nullptr) { + return; + } + debug_info_offset_ = OatFile::GetDebugInfoOffset(*dex_file, code_item); + if (dex_file->IsCompactDexFile()) { + Init(down_cast<const CompactDexFile::CodeItem&>(*code_item)); + } else { + DCHECK(dex_file->IsStandardDexFile()); + Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); + } +} + +inline void CodeItemDebugInfoAccessor::Init(const CompactDexFile::CodeItem& code_item) { + CodeItemDataAccessor::Init(code_item); +} + +inline void CodeItemDebugInfoAccessor::Init(const StandardDexFile::CodeItem& code_item) { + CodeItemDataAccessor::Init(code_item); +} + } // namespace art #endif // ART_RUNTIME_CODE_ITEM_ACCESSORS_INL_H_ diff --git a/runtime/code_item_accessors.h b/runtime/code_item_accessors.h index aa1305acad..a089a276de 100644 --- a/runtime/code_item_accessors.h +++ b/runtime/code_item_accessors.h @@ -132,6 +132,30 @@ class CodeItemDataAccessor : public CodeItemInstructionAccessor { uint16_t tries_size_; }; +// Abstract accesses to code item data including debug info offset. More heavy weight than the other +// helpers. +class CodeItemDebugInfoAccessor : public CodeItemDataAccessor { + public: + CodeItemDebugInfoAccessor() = default; + + // Handles null code items, but not null dex files. + ALWAYS_INLINE CodeItemDebugInfoAccessor(const DexFile* dex_file, + const DexFile::CodeItem* code_item); + + ALWAYS_INLINE explicit CodeItemDebugInfoAccessor(ArtMethod* method); + + uint32_t DebugInfoOffset() const { + return debug_info_offset_; + } + + protected: + ALWAYS_INLINE void Init(const CompactDexFile::CodeItem& code_item); + ALWAYS_INLINE void Init(const StandardDexFile::CodeItem& code_item); + + private: + uint32_t debug_info_offset_ = 0u; +}; + } // namespace art #endif // ART_RUNTIME_CODE_ITEM_ACCESSORS_H_ diff --git a/runtime/debugger.cc b/runtime/debugger.cc index 13029fb958..541bd1da81 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -1661,16 +1661,16 @@ void Dbg::OutputLineTable(JDWP::RefTypeId, JDWP::MethodId method_id, JDWP::Expan } }; ArtMethod* m = FromMethodId(method_id); - const DexFile::CodeItem* code_item = m->GetCodeItem(); + CodeItemDebugInfoAccessor accessor(m); uint64_t start, end; - if (code_item == nullptr) { + if (!accessor.HasCodeItem()) { DCHECK(m->IsNative() || m->IsProxyMethod()); start = -1; end = -1; } else { start = 0; // Return the index of the last instruction - end = code_item->insns_size_in_code_units_ - 1; + end = accessor.InsnsSizeInCodeUnits() - 1; } expandBufAdd8BE(pReply, start); @@ -1684,10 +1684,10 @@ void Dbg::OutputLineTable(JDWP::RefTypeId, JDWP::MethodId method_id, JDWP::Expan context.numItems = 0; context.pReply = pReply; - if (code_item != nullptr) { - uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*(m->GetDexFile()), code_item); - m->GetDexFile()->DecodeDebugPositionInfo( - code_item, debug_info_offset, DebugCallbackContext::Callback, &context); + if (accessor.HasCodeItem()) { + m->GetDexFile()->DecodeDebugPositionInfo(accessor.DebugInfoOffset(), + DebugCallbackContext::Callback, + &context); } JDWP::Set4BE(expandBufGetBuffer(pReply) + numLinesOffset, context.numItems); @@ -1727,6 +1727,7 @@ void Dbg::OutputVariableTable(JDWP::RefTypeId, JDWP::MethodId method_id, bool wi } }; ArtMethod* m = FromMethodId(method_id); + CodeItemDebugInfoAccessor accessor(m); // arg_count considers doubles and longs to take 2 units. // variable_count considers everything to take 1 unit. @@ -1742,12 +1743,15 @@ void Dbg::OutputVariableTable(JDWP::RefTypeId, JDWP::MethodId method_id, bool wi context.variable_count = 0; context.with_generic = with_generic; - const DexFile::CodeItem* code_item = m->GetCodeItem(); - if (code_item != nullptr) { - uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*(m->GetDexFile()), code_item); - m->GetDexFile()->DecodeDebugLocalInfo( - code_item, debug_info_offset, m->IsStatic(), m->GetDexMethodIndex(), - DebugCallbackContext::Callback, &context); + if (accessor.HasCodeItem()) { + m->GetDexFile()->DecodeDebugLocalInfo(accessor.RegistersSize(), + accessor.InsSize(), + accessor.InsnsSizeInCodeUnits(), + accessor.DebugInfoOffset(), + m->IsStatic(), + m->GetDexMethodIndex(), + DebugCallbackContext::Callback, + &context); } JDWP::Set4BE(expandBufGetBuffer(pReply) + variable_count_offset, context.variable_count); @@ -3836,9 +3840,9 @@ JDWP::JdwpError Dbg::ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize // Find the dex_pc values that correspond to the current line, for line-based single-stepping. struct DebugCallbackContext { DebugCallbackContext(SingleStepControl* single_step_control_cb, - int32_t line_number_cb, const DexFile::CodeItem* code_item) + int32_t line_number_cb, uint32_t num_insns_in_code_units) : single_step_control_(single_step_control_cb), line_number_(line_number_cb), - code_item_(code_item), last_pc_valid(false), last_pc(0) { + num_insns_in_code_units_(num_insns_in_code_units), last_pc_valid(false), last_pc(0) { } static bool Callback(void* raw_context, const DexFile::PositionInfo& entry) { @@ -3864,8 +3868,7 @@ JDWP::JdwpError Dbg::ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize ~DebugCallbackContext() { // If the line number was the last in the position table... if (last_pc_valid) { - size_t end = code_item_->insns_size_in_code_units_; - for (uint32_t dex_pc = last_pc; dex_pc < end; ++dex_pc) { + for (uint32_t dex_pc = last_pc; dex_pc < num_insns_in_code_units_; ++dex_pc) { single_step_control_->AddDexPc(dex_pc); } } @@ -3873,7 +3876,7 @@ JDWP::JdwpError Dbg::ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize SingleStepControl* const single_step_control_; const int32_t line_number_; - const DexFile::CodeItem* const code_item_; + const uint32_t num_insns_in_code_units_; bool last_pc_valid; uint32_t last_pc; }; @@ -3892,11 +3895,11 @@ JDWP::JdwpError Dbg::ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize // Note: if the thread is not running Java code (pure native thread), there is no "current" // method on the stack (and no line number either). if (m != nullptr && !m->IsNative()) { - const DexFile::CodeItem* const code_item = m->GetCodeItem(); - DebugCallbackContext context(single_step_control, line_number, code_item); - uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*(m->GetDexFile()), code_item); - m->GetDexFile()->DecodeDebugPositionInfo( - code_item, debug_info_offset, DebugCallbackContext::Callback, &context); + CodeItemDebugInfoAccessor accessor(m); + DebugCallbackContext context(single_step_control, line_number, accessor.InsnsSizeInCodeUnits()); + m->GetDexFile()->DecodeDebugPositionInfo(accessor.DebugInfoOffset(), + DebugCallbackContext::Callback, + &context); } // Activate single-step in the thread. diff --git a/runtime/dex_file-inl.h b/runtime/dex_file-inl.h index 4025a1a0f9..a6f762120c 100644 --- a/runtime/dex_file-inl.h +++ b/runtime/dex_file-inl.h @@ -384,13 +384,16 @@ bool DexFile::DecodeDebugLocalInfo(const uint8_t* stream, } template<typename NewLocalCallback> -bool DexFile::DecodeDebugLocalInfo(const CodeItem* code_item, +bool DexFile::DecodeDebugLocalInfo(uint32_t registers_size, + uint32_t ins_size, + uint32_t insns_size_in_code_units, uint32_t debug_info_offset, bool is_static, uint32_t method_idx, NewLocalCallback new_local_callback, void* context) const { - if (code_item == nullptr) { + const uint8_t* const stream = GetDebugInfoStream(debug_info_offset); + if (stream == nullptr) { return false; } std::vector<const char*> arg_descriptors; @@ -398,15 +401,15 @@ bool DexFile::DecodeDebugLocalInfo(const CodeItem* code_item, for (; it.HasNext(); it.Next()) { arg_descriptors.push_back(it.GetDescriptor()); } - return DecodeDebugLocalInfo(GetDebugInfoStream(debug_info_offset), + return DecodeDebugLocalInfo(stream, GetLocation(), GetMethodDeclaringClassDescriptor(GetMethodId(method_idx)), arg_descriptors, this->PrettyMethod(method_idx), is_static, - code_item->registers_size_, - code_item->ins_size_, - code_item->insns_size_in_code_units_, + registers_size, + ins_size, + insns_size_in_code_units, [this](uint32_t idx) { return StringDataByIdx(dex::StringIndex(idx)); }, @@ -487,13 +490,9 @@ bool DexFile::DecodeDebugPositionInfo(const uint8_t* stream, } template<typename DexDebugNewPosition> -bool DexFile::DecodeDebugPositionInfo(const CodeItem* code_item, - uint32_t debug_info_offset, +bool DexFile::DecodeDebugPositionInfo(uint32_t debug_info_offset, DexDebugNewPosition position_functor, void* context) const { - if (code_item == nullptr) { - return false; - } return DecodeDebugPositionInfo(GetDebugInfoStream(debug_info_offset), [this](uint32_t idx) { return StringDataByIdx(dex::StringIndex(idx)); diff --git a/runtime/dex_file.h b/runtime/dex_file.h index 561b3678b4..de3af8a289 100644 --- a/runtime/dex_file.h +++ b/runtime/dex_file.h @@ -956,7 +956,9 @@ class DexFile { NewLocalCallback new_local, void* context); template<typename NewLocalCallback> - bool DecodeDebugLocalInfo(const CodeItem* code_item, + bool DecodeDebugLocalInfo(uint32_t registers_size, + uint32_t ins_size, + uint32_t insns_size_in_code_units, uint32_t debug_info_offset, bool is_static, uint32_t method_idx, @@ -970,8 +972,7 @@ class DexFile { DexDebugNewPosition position_functor, void* context); template<typename DexDebugNewPosition> - bool DecodeDebugPositionInfo(const CodeItem* code_item, - uint32_t debug_info_offset, + bool DecodeDebugPositionInfo(uint32_t debug_info_offset, DexDebugNewPosition position_functor, void* context) const; diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc index bc7b985b41..72b18fb420 100644 --- a/runtime/dex_file_annotations.cc +++ b/runtime/dex_file_annotations.cc @@ -1559,14 +1559,12 @@ int32_t GetLineNumFromPC(const DexFile* dex_file, ArtMethod* method, uint32_t re return -2; } - const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset()); - DCHECK(code_item != nullptr) << method->PrettyMethod() << " " << dex_file->GetLocation(); + CodeItemDebugInfoAccessor accessor(method); + DCHECK(accessor.HasCodeItem()) << method->PrettyMethod() << " " << dex_file->GetLocation(); // A method with no line number info should return -1 DexFile::LineNumFromPcContext context(rel_pc, -1); - uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*dex_file, code_item); - dex_file->DecodeDebugPositionInfo( - code_item, debug_info_offset, DexFile::LineNumForPcCb, &context); + dex_file->DecodeDebugPositionInfo(accessor.DebugInfoOffset(), DexFile::LineNumForPcCb, &context); return context.line_num_; } diff --git a/runtime/dex_file_test.cc b/runtime/dex_file_test.cc index 14c36b4538..69055041e5 100644 --- a/runtime/dex_file_test.cc +++ b/runtime/dex_file_test.cc @@ -731,7 +731,14 @@ TEST_F(DexFileTest, OpenDexDebugInfoLocalNullType) { const DexFile::ClassDef& class_def = raw->GetClassDef(0); const DexFile::CodeItem* code_item = raw->GetCodeItem(raw->FindCodeItemOffset(class_def, 1)); uint32_t debug_info_offset = raw->GetDebugInfoOffset(code_item); - ASSERT_TRUE(raw->DecodeDebugLocalInfo(code_item, debug_info_offset, true, 1, Callback, nullptr)); + ASSERT_TRUE(raw->DecodeDebugLocalInfo(code_item->registers_size_, + code_item->ins_size_, + code_item->insns_size_in_code_units_, + debug_info_offset, + true, + 1, + Callback, + nullptr)); } } // namespace art |