diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/debug/elf_debug_writer.cc | 79 | ||||
-rw-r--r-- | compiler/debug/elf_debug_writer.h | 2 | ||||
-rw-r--r-- | compiler/dex/dex_to_dex_compiler.h | 1 | ||||
-rw-r--r-- | compiler/linker/elf_builder.h | 45 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 1 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 2 |
6 files changed, 45 insertions, 85 deletions
diff --git a/compiler/debug/elf_debug_writer.cc b/compiler/debug/elf_debug_writer.cc index 71422d48a5..baf8643e9b 100644 --- a/compiler/debug/elf_debug_writer.cc +++ b/compiler/debug/elf_debug_writer.cc @@ -16,8 +16,9 @@ #include "elf_debug_writer.h" -#include <vector> +#include <type_traits> #include <unordered_map> +#include <vector> #include "base/array_ref.h" #include "debug/dwarf/dwarf_constants.h" @@ -29,6 +30,7 @@ #include "debug/elf_symtab_writer.h" #include "debug/method_debug_info.h" #include "debug/xz_utils.h" +#include "elf.h" #include "linker/elf_builder.h" #include "linker/vector_output_stream.h" #include "oat.h" @@ -36,6 +38,8 @@ namespace art { namespace debug { +using ElfRuntimeTypes = std::conditional<sizeof(void*) == 4, ElfTypes32, ElfTypes64>::type; + template <typename ElfTypes> void WriteDebugInfo(linker::ElfBuilder<ElfTypes>* builder, const DebugInfo& debug_info, @@ -165,22 +169,16 @@ std::vector<uint8_t> MakeMiniDebugInfo( } } -template <typename ElfTypes> -static std::vector<uint8_t> MakeElfFileForJITInternal( +std::vector<uint8_t> MakeElfFileForJIT( InstructionSet isa, const InstructionSetFeatures* features, bool mini_debug_info, - ArrayRef<const MethodDebugInfo> method_infos) { - CHECK_GT(method_infos.size(), 0u); - uint64_t min_address = std::numeric_limits<uint64_t>::max(); - uint64_t max_address = 0; - for (const MethodDebugInfo& mi : method_infos) { - CHECK_EQ(mi.is_code_address_text_relative, false); - min_address = std::min(min_address, mi.code_address); - max_address = std::max(max_address, mi.code_address + mi.code_size); - } + const MethodDebugInfo& method_info) { + using ElfTypes = ElfRuntimeTypes; + CHECK_EQ(sizeof(ElfTypes::Addr), static_cast<size_t>(GetInstructionSetPointerSize(isa))); + CHECK_EQ(method_info.is_code_address_text_relative, false); DebugInfo debug_info{}; - debug_info.compiled_methods = method_infos; + debug_info.compiled_methods = ArrayRef<const MethodDebugInfo>(&method_info, 1); std::vector<uint8_t> buffer; buffer.reserve(KB); linker::VectorOutputStream out("Debug ELF file", &buffer); @@ -188,28 +186,16 @@ static std::vector<uint8_t> MakeElfFileForJITInternal( new linker::ElfBuilder<ElfTypes>(isa, features, &out)); // No program headers since the ELF file is not linked and has no allocated sections. builder->Start(false /* write_program_headers */); + builder->GetText()->AllocateVirtualMemory(method_info.code_address, method_info.code_size); if (mini_debug_info) { - if (method_infos.size() > 1) { - std::vector<uint8_t> mdi = MakeMiniDebugInfo(isa, - features, - min_address, - max_address - min_address, - /* dex_section_address */ 0, - /* dex_section_size */ 0, - debug_info); - builder->WriteSection(".gnu_debugdata", &mdi); - } else { - // The compression is great help for multiple methods but it is not worth it for a - // single method due to the overheads so skip the compression here for performance. - builder->GetText()->AllocateVirtualMemory(min_address, max_address - min_address); - WriteDebugSymbols(builder.get(), true /* mini-debug-info */, debug_info); - WriteCFISection(builder.get(), - debug_info.compiled_methods, - dwarf::DW_DEBUG_FRAME_FORMAT, - false /* write_oat_paches */); - } + // The compression is great help for multiple methods but it is not worth it for a + // single method due to the overheads so skip the compression here for performance. + WriteDebugSymbols(builder.get(), true /* mini-debug-info */, debug_info); + WriteCFISection(builder.get(), + debug_info.compiled_methods, + dwarf::DW_DEBUG_FRAME_FORMAT, + false /* write_oat_paches */); } else { - builder->GetText()->AllocateVirtualMemory(min_address, max_address - min_address); WriteDebugInfo(builder.get(), debug_info, dwarf::DW_DEBUG_FRAME_FORMAT, @@ -220,24 +206,13 @@ static std::vector<uint8_t> MakeElfFileForJITInternal( return buffer; } -std::vector<uint8_t> MakeElfFileForJIT( - InstructionSet isa, - const InstructionSetFeatures* features, - bool mini_debug_info, - ArrayRef<const MethodDebugInfo> method_infos) { - if (Is64BitInstructionSet(isa)) { - return MakeElfFileForJITInternal<ElfTypes64>(isa, features, mini_debug_info, method_infos); - } else { - return MakeElfFileForJITInternal<ElfTypes32>(isa, features, mini_debug_info, method_infos); - } -} - -template <typename ElfTypes> -static std::vector<uint8_t> WriteDebugElfFileForClassesInternal( +std::vector<uint8_t> WriteDebugElfFileForClasses( InstructionSet isa, const InstructionSetFeatures* features, const ArrayRef<mirror::Class*>& types) REQUIRES_SHARED(Locks::mutator_lock_) { + using ElfTypes = ElfRuntimeTypes; + CHECK_EQ(sizeof(ElfTypes::Addr), static_cast<size_t>(GetInstructionSetPointerSize(isa))); std::vector<uint8_t> buffer; buffer.reserve(KB); linker::VectorOutputStream out("Debug ELF file", &buffer); @@ -256,16 +231,6 @@ static std::vector<uint8_t> WriteDebugElfFileForClassesInternal( return buffer; } -std::vector<uint8_t> WriteDebugElfFileForClasses(InstructionSet isa, - const InstructionSetFeatures* features, - const ArrayRef<mirror::Class*>& types) { - if (Is64BitInstructionSet(isa)) { - return WriteDebugElfFileForClassesInternal<ElfTypes64>(isa, features, types); - } else { - return WriteDebugElfFileForClassesInternal<ElfTypes32>(isa, features, types); - } -} - // Explicit instantiations template void WriteDebugInfo<ElfTypes32>( linker::ElfBuilder<ElfTypes32>* builder, diff --git a/compiler/debug/elf_debug_writer.h b/compiler/debug/elf_debug_writer.h index e442e0016c..8ad0c4219a 100644 --- a/compiler/debug/elf_debug_writer.h +++ b/compiler/debug/elf_debug_writer.h @@ -54,7 +54,7 @@ std::vector<uint8_t> MakeElfFileForJIT( InstructionSet isa, const InstructionSetFeatures* features, bool mini_debug_info, - ArrayRef<const MethodDebugInfo> method_infos); + const MethodDebugInfo& method_info); std::vector<uint8_t> WriteDebugElfFileForClasses( InstructionSet isa, diff --git a/compiler/dex/dex_to_dex_compiler.h b/compiler/dex/dex_to_dex_compiler.h index 7536c3126a..7253488f79 100644 --- a/compiler/dex/dex_to_dex_compiler.h +++ b/compiler/dex/dex_to_dex_compiler.h @@ -22,6 +22,7 @@ #include <unordered_set> #include "base/bit_vector.h" +#include "base/mutex.h" #include "dex/dex_file.h" #include "dex/invoke_type.h" #include "dex/method_reference.h" diff --git a/compiler/linker/elf_builder.h b/compiler/linker/elf_builder.h index 81ecc175b5..44f3296e90 100644 --- a/compiler/linker/elf_builder.h +++ b/compiler/linker/elf_builder.h @@ -18,6 +18,7 @@ #define ART_COMPILER_LINKER_ELF_BUILDER_H_ #include <vector> +#include <deque> #include "arch/instruction_set.h" #include "arch/mips/instruction_set_features_mips.h" @@ -357,57 +358,49 @@ class ElfBuilder final { } // Buffer symbol for this section. It will be written later. - // If the symbol's section is null, it will be considered absolute (SHN_ABS). - // (we use this in JIT to reference code which is stored outside the debug ELF file) void Add(Elf_Word name, const Section* section, Elf_Addr addr, Elf_Word size, uint8_t binding, uint8_t type) { - Elf_Word section_index; - if (section != nullptr) { - DCHECK_LE(section->GetAddress(), addr); - DCHECK_LE(addr, section->GetAddress() + section->header_.sh_size); - section_index = section->GetSectionIndex(); - } else { - section_index = static_cast<Elf_Word>(SHN_ABS); - } - Add(name, section_index, addr, size, binding, type); - } - - // Buffer symbol for this section. It will be written later. - void Add(Elf_Word name, - Elf_Word section_index, - Elf_Addr addr, - Elf_Word size, - uint8_t binding, - uint8_t type) { Elf_Sym sym = Elf_Sym(); sym.st_name = name; sym.st_value = addr; sym.st_size = size; sym.st_other = 0; - sym.st_shndx = section_index; sym.st_info = (binding << 4) + (type & 0xf); - syms_.push_back(sym); + Add(sym, section); + } + + // Buffer symbol for this section. It will be written later. + void Add(Elf_Sym sym, const Section* section) { + DCHECK(section != nullptr); + DCHECK_LE(section->GetAddress(), sym.st_value); + DCHECK_LE(sym.st_value, section->GetAddress() + section->header_.sh_size); + sym.st_shndx = section->GetSectionIndex(); // The sh_info file must be set to index one-past the last local symbol. - if (binding == STB_LOCAL) { - this->header_.sh_info = syms_.size(); + if (sym.getBinding() == STB_LOCAL) { + DCHECK_EQ(syms_.back().getBinding(), STB_LOCAL); + this->header_.sh_info = syms_.size() + 1; } + + syms_.push_back(sym); } Elf_Word GetCacheSize() { return syms_.size() * sizeof(Elf_Sym); } void WriteCachedSection() { this->Start(); - this->WriteFully(syms_.data(), syms_.size() * sizeof(Elf_Sym)); + for (; !syms_.empty(); syms_.pop_front()) { + this->WriteFully(&syms_.front(), sizeof(Elf_Sym)); + } this->End(); } private: - std::vector<Elf_Sym> syms_; // Buffered/cached content of the whole section. + std::deque<Elf_Sym> syms_; // Buffered/cached content of the whole section. }; class AbiflagsSection final : public Section { diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 610852257b..13c8684cc0 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -26,6 +26,7 @@ #include "base/arena_object.h" #include "base/array_ref.h" #include "base/iteration_range.h" +#include "base/mutex.h" #include "base/quasi_atomic.h" #include "base/stl_util.h" #include "base/transform_array_ref.h" diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 52335d3a5d..92aaa19121 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -1469,7 +1469,7 @@ void OptimizingCompiler::GenerateJitDebugInfo( compiler_options.GetInstructionSet(), compiler_options.GetInstructionSetFeatures(), mini_debug_info, - ArrayRef<const debug::MethodDebugInfo>(&info, 1)); + info); MutexLock mu(Thread::Current(), *Locks::native_debug_interface_lock_); AddNativeDebugInfoForJit(reinterpret_cast<const void*>(info.code_address), elf_file); |