Add CodeItemDebugInfoAccessor
Use it in places where DecodeDebugPositionInfo is called.
Motivation: Abstract away calls to GetDebugInfoOffset.
Bug: 63756964
Test: test-art-host
Test: art/tools/run-jdwp-tests.sh '--mode=host' --debug
Change-Id: I3ab2eff56c472cc717f49d17fd17eb0b8fde4062
diff --git a/compiler/debug/elf_debug_info_writer.h b/compiler/debug/elf_debug_info_writer.h
index d599994..81a0a69 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 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 @@
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 @@
// 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 @@
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 @@
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 943e03a..c7224fc 100644
--- a/compiler/debug/elf_debug_line_writer.h
+++ b/compiler/debug/elf_debug_line_writer.h
@@ -159,9 +159,9 @@
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 782546c..fc7b28c 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -442,17 +442,15 @@
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 @@
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 b5c5d98..260888e 100644
--- a/dex2oat/linker/oat_writer.cc
+++ b/dex2oat/linker/oat_writer.cc
@@ -2694,7 +2694,8 @@
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 a7af193..527a5b9 100644
--- a/dexdump/dexdump.cc
+++ b/dexdump/dexdump.cc
@@ -1203,10 +1203,16 @@
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 3bd903d..4bf0475 100644
--- a/dexlist/dexlist.cc
+++ b/dexlist/dexlist.cc
@@ -121,7 +121,7 @@
// 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 448ce41..4444853 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 @@
}
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 @@
};
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 @@
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 @@
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 @@
/*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 @@
};
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 d04849d..4f4d8cc 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 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 @@
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 aa1305a..a089a27 100644
--- a/runtime/code_item_accessors.h
+++ b/runtime/code_item_accessors.h
@@ -132,6 +132,30 @@
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 13029fb..541bd1d 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -1661,16 +1661,16 @@
}
};
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 @@
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 @@
}
};
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 @@
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 @@
// 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 @@
~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 @@
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 @@
// 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 1880968..1c76a32 100644
--- a/runtime/dex_file-inl.h
+++ b/runtime/dex_file-inl.h
@@ -385,13 +385,16 @@
}
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;
@@ -399,15 +402,15 @@
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));
},
@@ -488,13 +491,9 @@
}
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 944a308..91ec630 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -954,7 +954,9 @@
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,
@@ -968,8 +970,7 @@
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 b44bd51..837291b 100644
--- a/runtime/dex_file_annotations.cc
+++ b/runtime/dex_file_annotations.cc
@@ -1567,14 +1567,12 @@
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 14c36b4..6905504 100644
--- a/runtime/dex_file_test.cc
+++ b/runtime/dex_file_test.cc
@@ -731,7 +731,14 @@
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