From 58cc1cb66c1a96ffba4a314edb2c5b4e8b235d5b Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Mon, 20 Nov 2017 13:27:29 +0000 Subject: Pass the debug_info_offset explicitly. In order to use debug_info_offset for encoding implementation details, rewrite all indirect users of it to fetch it before calling DexFile methods. This allows keeping the DexFile interface clean of runtime considerations. Test: test.py Change-Id: I4591e0039b5f822f4409aae411071ecbe97082b1 --- compiler/debug/elf_debug_info_writer.h | 6 +++++- compiler/debug/elf_debug_line_writer.h | 5 ++++- compiler/optimizing/instruction_builder.cc | 4 +++- dexdump/dexdump.cc | 6 ++++-- dexlayout/dex_ir.cc | 7 ++++--- dexlist/Android.bp | 2 +- dexlist/dexlist.cc | 3 ++- openjdkjvmti/ti_method.cc | 9 ++++++++- runtime/debugger.cc | 14 ++++++++++---- runtime/dex_file-inl.h | 6 ++++-- runtime/dex_file.h | 14 ++++++++++++-- runtime/dex_file_annotations.cc | 5 ++++- runtime/dex_file_test.cc | 3 ++- runtime/oat_file.cc | 8 ++++++++ runtime/oat_file.h | 6 +++++- 15 files changed, 76 insertions(+), 22 deletions(-) diff --git a/compiler/debug/elf_debug_info_writer.h b/compiler/debug/elf_debug_info_writer.h index 37c2d32091..d5999941d7 100644 --- a/compiler/debug/elf_debug_info_writer.h +++ b/compiler/debug/elf_debug_info_writer.h @@ -35,6 +35,7 @@ #include "mirror/array.h" #include "mirror/class-inl.h" #include "mirror/class.h" +#include "oat_file.h" namespace art { namespace debug { @@ -49,7 +50,8 @@ static std::vector GetParamNames(const MethodDebugInfo* mi) { std::vector names; if (mi->code_item != nullptr) { DCHECK(mi->dex_file != nullptr); - const uint8_t* stream = mi->dex_file->GetDebugInfoStream(mi->code_item); + uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*mi->dex_file, mi->code_item); + const uint8_t* stream = mi->dex_file->GetDebugInfoStream(debug_info_offset); if (stream != nullptr) { DecodeUnsignedLeb128(&stream); // line. uint32_t parameters_size = DecodeUnsignedLeb128(&stream); @@ -257,7 +259,9 @@ class ElfCompilationUnitWriter { // Write local variables. LocalInfos local_infos; + uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*dex, dex_code); if (dex->DecodeDebugLocalInfo(dex_code, + debug_info_offset, is_static, mi->dex_method_index, LocalInfoCallback, diff --git a/compiler/debug/elf_debug_line_writer.h b/compiler/debug/elf_debug_line_writer.h index 6e72b46174..943e03a765 100644 --- a/compiler/debug/elf_debug_line_writer.h +++ b/compiler/debug/elf_debug_line_writer.h @@ -26,6 +26,7 @@ #include "debug/src_map_elem.h" #include "dex_file-inl.h" #include "linker/elf_builder.h" +#include "oat_file.h" #include "stack_map.h" namespace art { @@ -158,7 +159,9 @@ class ElfDebugLineWriter { PositionInfos dex2line_map; DCHECK(mi->dex_file != nullptr); const DexFile* dex = mi->dex_file; - if (!dex->DecodeDebugPositionInfo(mi->code_item, PositionInfoCallback, &dex2line_map)) { + uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*dex, mi->code_item); + if (!dex->DecodeDebugPositionInfo( + mi->code_item, debug_info_offset, PositionInfoCallback, &dex2line_map)) { continue; } diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 61840cc20f..978d0c2225 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -29,6 +29,7 @@ #include "driver/compiler_options.h" #include "imtable-inl.h" #include "mirror/dex_cache.h" +#include "oat_file.h" #include "optimizing_compiler_stats.h" #include "quicken_info.h" #include "scoped_thread_state_change-inl.h" @@ -447,7 +448,8 @@ ArenaBitVector* HInstructionBuilder::FindNativeDebugInfoLocations() { /* expandable */ false, kArenaAllocGraphBuilder); locations->ClearAllBits(); - dex_file_->DecodeDebugPositionInfo(code_item_, Callback::Position, locations); + uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*dex_file_, code_item_); + dex_file_->DecodeDebugPositionInfo(code_item_, debug_info_offset, Callback::Position, locations); // Instruction-specific tweaks. IterationRange instructions = code_item_->Instructions(); for (const DexInstructionPcPair& inst : instructions) { diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc index 84ccaa03ab..a7af193f0a 100644 --- a/dexdump/dexdump.cc +++ b/dexdump/dexdump.cc @@ -1202,9 +1202,11 @@ static void dumpCode(const DexFile* pDexFile, u4 idx, u4 flags, // Positions and locals table in the debug info. bool is_static = (flags & kAccStatic) != 0; fprintf(gOutFile, " positions : \n"); - pDexFile->DecodeDebugPositionInfo(pCode, dumpPositionsCb, nullptr); + uint32_t debug_info_offset = pDexFile->GetDebugInfoOffset(pCode); + pDexFile->DecodeDebugPositionInfo(pCode, debug_info_offset, dumpPositionsCb, nullptr); fprintf(gOutFile, " locals : \n"); - pDexFile->DecodeDebugLocalInfo(pCode, is_static, idx, dumpLocalsCb, nullptr); + pDexFile->DecodeDebugLocalInfo( + pCode, debug_info_offset, is_static, idx, dumpLocalsCb, nullptr); } /* diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc index a8ba950c28..2af579c73c 100644 --- a/dexlayout/dex_ir.cc +++ b/dexlayout/dex_ir.cc @@ -570,16 +570,17 @@ CodeItem* Collections::CreateCodeItem(const DexFile& dex_file, uint32_t tries_size = disk_code_item.tries_size_; // TODO: Calculate the size of the debug info. - const uint8_t* debug_info_stream = dex_file.GetDebugInfoStream(&disk_code_item); + uint32_t debug_info_offset = dex_file.GetDebugInfoOffset(&disk_code_item); + const uint8_t* debug_info_stream = dex_file.GetDebugInfoStream(debug_info_offset); DebugInfoItem* debug_info = nullptr; if (debug_info_stream != nullptr) { - debug_info = debug_info_items_map_.GetExistingObject(disk_code_item.debug_info_off_); + debug_info = debug_info_items_map_.GetExistingObject(debug_info_offset); if (debug_info == nullptr) { uint32_t debug_info_size = GetDebugInfoStreamSize(debug_info_stream); uint8_t* debug_info_buffer = new uint8_t[debug_info_size]; memcpy(debug_info_buffer, debug_info_stream, debug_info_size); debug_info = new DebugInfoItem(debug_info_size, debug_info_buffer); - AddItem(debug_info_items_map_, debug_info_items_, debug_info, disk_code_item.debug_info_off_); + AddItem(debug_info_items_map_, debug_info_items_, debug_info, debug_info_offset); } } diff --git a/dexlist/Android.bp b/dexlist/Android.bp index 03943bf0f2..8ecff4210e 100644 --- a/dexlist/Android.bp +++ b/dexlist/Android.bp @@ -17,7 +17,7 @@ art_cc_binary { host_supported: true, srcs: ["dexlist.cc"], cflags: ["-Wall", "-Werror"], - shared_libs: ["libart"], + shared_libs: ["libart", "libbase"], } art_cc_test { diff --git a/dexlist/dexlist.cc b/dexlist/dexlist.cc index e3ca59c8bf..3bd903de5b 100644 --- a/dexlist/dexlist.cc +++ b/dexlist/dexlist.cc @@ -120,7 +120,8 @@ static void dumpMethod(const DexFile* pDexFile, // Find the first line. int firstLine = -1; - pDexFile->DecodeDebugPositionInfo(pCode, positionsCb, &firstLine); + uint32_t debug_info_offset = pDexFile->GetDebugInfoOffset(pCode); + pDexFile->DecodeDebugPositionInfo(pCode, 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 cf93bf0fb0..448ce41d0f 100644 --- a/openjdkjvmti/ti_method.cc +++ b/openjdkjvmti/ti_method.cc @@ -48,6 +48,7 @@ #include "mirror/object_array-inl.h" #include "modifiers.h" #include "nativehelper/scoped_local_ref.h" +#include "oat_file.h" #include "runtime_callbacks.h" #include "scoped_thread_state_change-inl.h" #include "stack.h" @@ -259,7 +260,9 @@ 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, art_method->IsStatic(), art_method->GetDexMethodIndex(), LocalVariableContext::Callback, @@ -480,7 +483,9 @@ jvmtiError MethodUtil::GetLineNumberTable(jvmtiEnv* env, } LineNumberContext context; - bool success = dex_file->DecodeDebugPositionInfo(code_item, CollectLineNumbers, &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); if (!success) { return ERR(ABSENT_INFORMATION); } @@ -648,7 +653,9 @@ 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, method->IsStatic(), method->GetDexMethodIndex(), GetLocalVariableInfoContext::Callback, diff --git a/runtime/debugger.cc b/runtime/debugger.cc index 3784212ef0..1dcd935eea 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -58,6 +58,7 @@ #include "mirror/throwable.h" #include "nativehelper/scoped_local_ref.h" #include "nativehelper/scoped_primitive_array.h" +#include "oat_file.h" #include "obj_ptr-inl.h" #include "reflection.h" #include "safe_map.h" @@ -1680,7 +1681,9 @@ void Dbg::OutputLineTable(JDWP::RefTypeId, JDWP::MethodId method_id, JDWP::Expan context.pReply = pReply; if (code_item != nullptr) { - m->GetDexFile()->DecodeDebugPositionInfo(code_item, DebugCallbackContext::Callback, &context); + uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*(m->GetDexFile()), code_item); + m->GetDexFile()->DecodeDebugPositionInfo( + code_item, debug_info_offset, DebugCallbackContext::Callback, &context); } JDWP::Set4BE(expandBufGetBuffer(pReply) + numLinesOffset, context.numItems); @@ -1737,9 +1740,10 @@ void Dbg::OutputVariableTable(JDWP::RefTypeId, JDWP::MethodId method_id, bool wi 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, m->IsStatic(), m->GetDexMethodIndex(), DebugCallbackContext::Callback, - &context); + code_item, debug_info_offset, m->IsStatic(), m->GetDexMethodIndex(), + DebugCallbackContext::Callback, &context); } JDWP::Set4BE(expandBufGetBuffer(pReply) + variable_count_offset, context.variable_count); @@ -3886,7 +3890,9 @@ JDWP::JdwpError Dbg::ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize if (m != nullptr && !m->IsNative()) { const DexFile::CodeItem* const code_item = m->GetCodeItem(); DebugCallbackContext context(single_step_control, line_number, code_item); - m->GetDexFile()->DecodeDebugPositionInfo(code_item, DebugCallbackContext::Callback, &context); + uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*(m->GetDexFile()), code_item); + m->GetDexFile()->DecodeDebugPositionInfo( + code_item, debug_info_offset, DebugCallbackContext::Callback, &context); } // Activate single-step in the thread. diff --git a/runtime/dex_file-inl.h b/runtime/dex_file-inl.h index c926a0d7fc..18809683cc 100644 --- a/runtime/dex_file-inl.h +++ b/runtime/dex_file-inl.h @@ -386,6 +386,7 @@ bool DexFile::DecodeDebugLocalInfo(const uint8_t* stream, template bool DexFile::DecodeDebugLocalInfo(const CodeItem* code_item, + uint32_t debug_info_offset, bool is_static, uint32_t method_idx, NewLocalCallback new_local_callback, @@ -398,7 +399,7 @@ bool DexFile::DecodeDebugLocalInfo(const CodeItem* code_item, for (; it.HasNext(); it.Next()) { arg_descriptors.push_back(it.GetDescriptor()); } - return DecodeDebugLocalInfo(GetDebugInfoStream(code_item), + return DecodeDebugLocalInfo(GetDebugInfoStream(debug_info_offset), GetLocation(), GetMethodDeclaringClassDescriptor(GetMethodId(method_idx)), arg_descriptors, @@ -488,12 +489,13 @@ bool DexFile::DecodeDebugPositionInfo(const uint8_t* stream, template bool DexFile::DecodeDebugPositionInfo(const CodeItem* code_item, + uint32_t debug_info_offset, DexDebugNewPosition position_functor, void* context) const { if (code_item == nullptr) { return false; } - return DecodeDebugPositionInfo(GetDebugInfoStream(code_item), + 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 cdefb23400..2166ed15e6 100644 --- a/runtime/dex_file.h +++ b/runtime/dex_file.h @@ -698,6 +698,15 @@ class DexFile { return reinterpret_cast(addr); } + uint32_t GetDebugInfoOffset(const CodeItem* code_item) const { + if (code_item == nullptr) { + return 0; + } + CHECK(oat_dex_file_ == nullptr) + << "Should only use GetDebugInfoOffset in a non runtime setup"; + return code_item->debug_info_off_; + } + const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const; // Returns the number of prototype identifiers in the .dex file. @@ -775,11 +784,10 @@ class DexFile { static int32_t FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address); // Get the pointer to the start of the debugging data - const uint8_t* GetDebugInfoStream(const CodeItem* code_item) const { + const uint8_t* GetDebugInfoStream(uint32_t debug_info_off) const { // Check that the offset is in bounds. // Note that although the specification says that 0 should be used if there // is no debug information, some applications incorrectly use 0xFFFFFFFF. - const uint32_t debug_info_off = code_item->debug_info_off_; return (debug_info_off == 0 || debug_info_off >= size_) ? nullptr : begin_ + debug_info_off; } @@ -936,6 +944,7 @@ class DexFile { void* context); template bool DecodeDebugLocalInfo(const CodeItem* code_item, + uint32_t debug_info_offset, bool is_static, uint32_t method_idx, NewLocalCallback new_local, @@ -949,6 +958,7 @@ class DexFile { void* context); template bool DecodeDebugPositionInfo(const CodeItem* code_item, + 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 27060aeff6..b44bd51643 100644 --- a/runtime/dex_file_annotations.cc +++ b/runtime/dex_file_annotations.cc @@ -28,6 +28,7 @@ #include "jvalue-inl.h" #include "mirror/field.h" #include "mirror/method.h" +#include "oat_file.h" #include "reflection.h" #include "thread.h" #include "well_known_classes.h" @@ -1571,7 +1572,9 @@ int32_t GetLineNumFromPC(const DexFile* dex_file, ArtMethod* method, uint32_t re // A method with no line number info should return -1 DexFile::LineNumFromPcContext context(rel_pc, -1); - dex_file->DecodeDebugPositionInfo(code_item, DexFile::LineNumForPcCb, &context); + uint32_t debug_info_offset = OatFile::GetDebugInfoOffset(*dex_file, code_item); + dex_file->DecodeDebugPositionInfo( + code_item, debug_info_offset, DexFile::LineNumForPcCb, &context); return context.line_num_; } diff --git a/runtime/dex_file_test.cc b/runtime/dex_file_test.cc index c963f6e111..14c36b4538 100644 --- a/runtime/dex_file_test.cc +++ b/runtime/dex_file_test.cc @@ -730,7 +730,8 @@ TEST_F(DexFileTest, OpenDexDebugInfoLocalNullType) { kRawDexDebugInfoLocalNullType, tmp.GetFilename().c_str(), 0xf25f2b38U, true); const DexFile::ClassDef& class_def = raw->GetClassDef(0); const DexFile::CodeItem* code_item = raw->GetCodeItem(raw->FindCodeItemOffset(class_def, 1)); - ASSERT_TRUE(raw->DecodeDebugLocalInfo(code_item, true, 1, Callback, nullptr)); + uint32_t debug_info_offset = raw->GetDebugInfoOffset(code_item); + ASSERT_TRUE(raw->DecodeDebugLocalInfo(code_item, debug_info_offset, true, 1, Callback, nullptr)); } } // namespace art diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc index 69bd46d4c1..726fbd0b0e 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -1455,6 +1455,14 @@ ArrayRef> OatFile::GetBssGcRoots() const { } } +uint32_t OatFile::GetDebugInfoOffset(const DexFile& dex_file ATTRIBUTE_UNUSED, + const DexFile::CodeItem* code_item) { + if (code_item == nullptr) { + return 0; + } + return code_item->debug_info_off_; +} + const OatFile::OatDexFile* OatFile::GetOatDexFile(const char* dex_location, const uint32_t* dex_location_checksum, std::string* error_msg) const { diff --git a/runtime/oat_file.h b/runtime/oat_file.h index 7d4e6dfd6b..73d64e0df1 100644 --- a/runtime/oat_file.h +++ b/runtime/oat_file.h @@ -109,11 +109,15 @@ class OatFile { static OatFile* OpenWritable(File* file, const std::string& location, const char* abs_dex_location, std::string* error_msg); - // Opens an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE. + // Open an oat file from an already opened File. Maps it PROT_READ, MAP_PRIVATE. static OatFile* OpenReadable(File* file, const std::string& location, const char* abs_dex_location, std::string* error_msg); + // Return the debug info offset of the code item `item` located in `dex_file`. + static uint32_t GetDebugInfoOffset(const DexFile& dex_file, + const DexFile::CodeItem* item); + virtual ~OatFile(); bool IsExecutable() const { -- cgit v1.2.3