summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/debug/elf_debug_writer.cc79
-rw-r--r--compiler/debug/elf_debug_writer.h2
-rw-r--r--compiler/dex/dex_to_dex_compiler.h1
-rw-r--r--compiler/linker/elf_builder.h45
-rw-r--r--compiler/optimizing/nodes.h1
-rw-r--r--compiler/optimizing/optimizing_compiler.cc2
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);