summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/elf_writer_debug.cc46
-rw-r--r--compiler/elf_writer_debug.h4
-rw-r--r--compiler/elf_writer_quick.cc2
-rw-r--r--compiler/jit/jit_compiler.cc5
-rw-r--r--runtime/jit/jit.cc30
-rw-r--r--runtime/jit/jit.h6
-rw-r--r--runtime/runtime.cc3
7 files changed, 47 insertions, 49 deletions
diff --git a/compiler/elf_writer_debug.cc b/compiler/elf_writer_debug.cc
index 4eb1ca2f03..3e64762096 100644
--- a/compiler/elf_writer_debug.cc
+++ b/compiler/elf_writer_debug.cc
@@ -1243,26 +1243,8 @@ class DebugLineWriter {
std::vector<uintptr_t> debug_line_patches;
};
-// Get all types loaded by the runtime.
-static std::vector<mirror::Class*> GetLoadedRuntimeTypes() SHARED_REQUIRES(Locks::mutator_lock_) {
- std::vector<mirror::Class*> result;
- class CollectClasses : public ClassVisitor {
- public:
- virtual bool Visit(mirror::Class* klass) {
- classes_->push_back(klass);
- return true;
- }
- std::vector<mirror::Class*>* classes_;
- };
- CollectClasses visitor;
- visitor.classes_ = &result;
- Runtime::Current()->GetClassLinker()->VisitClasses(&visitor);
- return result;
-}
-
template<typename ElfTypes>
static void WriteDebugSections(ElfBuilder<ElfTypes>* builder,
- bool write_loaded_runtime_types,
const ArrayRef<const MethodDebugInfo>& method_infos) {
// Group the methods into compilation units based on source file.
std::vector<CompilationUnit> compilation_units;
@@ -1291,19 +1273,12 @@ static void WriteDebugSections(ElfBuilder<ElfTypes>* builder,
}
// Write .debug_info section.
- if (!compilation_units.empty() || write_loaded_runtime_types) {
+ if (!compilation_units.empty()) {
DebugInfoWriter<ElfTypes> info_writer(builder);
info_writer.Start();
for (const auto& compilation_unit : compilation_units) {
info_writer.WriteCompilationUnit(compilation_unit);
}
- if (write_loaded_runtime_types) {
- Thread* self = Thread::Current();
- // The lock prevents the classes being moved by the GC.
- ReaderMutexLock mu(self, *Locks::mutator_lock_);
- std::vector<mirror::Class*> types = GetLoadedRuntimeTypes();
- info_writer.WriteTypes(ArrayRef<mirror::Class*>(types.data(), types.size()));
- }
info_writer.End();
}
}
@@ -1370,7 +1345,6 @@ void WriteDebugSymbols(ElfBuilder<ElfTypes>* builder,
template <typename ElfTypes>
void WriteDebugInfo(ElfBuilder<ElfTypes>* builder,
- bool write_loaded_runtime_types,
const ArrayRef<const MethodDebugInfo>& method_infos,
CFIFormat cfi_format) {
// Add methods to .symtab.
@@ -1378,7 +1352,7 @@ void WriteDebugInfo(ElfBuilder<ElfTypes>* builder,
// Generate CFI (stack unwinding information).
WriteCFISection(builder, method_infos, cfi_format);
// Write DWARF .debug_* sections.
- WriteDebugSections(builder, write_loaded_runtime_types, method_infos);
+ WriteDebugSections(builder, method_infos);
}
template <typename ElfTypes>
@@ -1391,7 +1365,6 @@ static ArrayRef<const uint8_t> WriteDebugElfFileForMethodInternal(
std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
builder->Start();
WriteDebugInfo(builder.get(),
- false,
ArrayRef<const MethodDebugInfo>(&method_info, 1),
DW_DEBUG_FRAME_FORMAT);
builder->End();
@@ -1413,8 +1386,8 @@ ArrayRef<const uint8_t> WriteDebugElfFileForMethod(const dwarf::MethodDebugInfo&
}
template <typename ElfTypes>
-static ArrayRef<const uint8_t> WriteDebugElfFileForClassInternal(const InstructionSet isa,
- mirror::Class* type)
+static ArrayRef<const uint8_t> WriteDebugElfFileForClassesInternal(
+ const InstructionSet isa, const ArrayRef<mirror::Class*>& types)
SHARED_REQUIRES(Locks::mutator_lock_) {
std::vector<uint8_t> buffer;
buffer.reserve(KB);
@@ -1424,7 +1397,7 @@ static ArrayRef<const uint8_t> WriteDebugElfFileForClassInternal(const Instructi
DebugInfoWriter<ElfTypes> info_writer(builder.get());
info_writer.Start();
- info_writer.WriteTypes(ArrayRef<mirror::Class*>(&type, 1));
+ info_writer.WriteTypes(types);
info_writer.End();
builder->End();
@@ -1436,23 +1409,22 @@ static ArrayRef<const uint8_t> WriteDebugElfFileForClassInternal(const Instructi
return ArrayRef<const uint8_t>(result, buffer.size());
}
-ArrayRef<const uint8_t> WriteDebugElfFileForClass(const InstructionSet isa, mirror::Class* type) {
+ArrayRef<const uint8_t> WriteDebugElfFileForClasses(const InstructionSet isa,
+ const ArrayRef<mirror::Class*>& types) {
if (Is64BitInstructionSet(isa)) {
- return WriteDebugElfFileForClassInternal<ElfTypes64>(isa, type);
+ return WriteDebugElfFileForClassesInternal<ElfTypes64>(isa, types);
} else {
- return WriteDebugElfFileForClassInternal<ElfTypes32>(isa, type);
+ return WriteDebugElfFileForClassesInternal<ElfTypes32>(isa, types);
}
}
// Explicit instantiations
template void WriteDebugInfo<ElfTypes32>(
ElfBuilder<ElfTypes32>* builder,
- bool write_loaded_runtime_types,
const ArrayRef<const MethodDebugInfo>& method_infos,
CFIFormat cfi_format);
template void WriteDebugInfo<ElfTypes64>(
ElfBuilder<ElfTypes64>* builder,
- bool write_loaded_runtime_types,
const ArrayRef<const MethodDebugInfo>& method_infos,
CFIFormat cfi_format);
diff --git a/compiler/elf_writer_debug.h b/compiler/elf_writer_debug.h
index 91da00f97a..e4bc856c5e 100644
--- a/compiler/elf_writer_debug.h
+++ b/compiler/elf_writer_debug.h
@@ -32,13 +32,13 @@ struct MethodDebugInfo;
template <typename ElfTypes>
void WriteDebugInfo(ElfBuilder<ElfTypes>* builder,
- bool write_loaded_runtime_types,
const ArrayRef<const MethodDebugInfo>& method_infos,
CFIFormat cfi_format);
ArrayRef<const uint8_t> WriteDebugElfFileForMethod(const dwarf::MethodDebugInfo& method_info);
-ArrayRef<const uint8_t> WriteDebugElfFileForClass(const InstructionSet isa, mirror::Class* type)
+ArrayRef<const uint8_t> WriteDebugElfFileForClasses(const InstructionSet isa,
+ const ArrayRef<mirror::Class*>& types)
SHARED_REQUIRES(Locks::mutator_lock_);
} // namespace dwarf
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index a67f3bd1a9..7b1bdd72e5 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -152,7 +152,7 @@ template <typename ElfTypes>
void ElfWriterQuick<ElfTypes>::WriteDebugInfo(
const ArrayRef<const dwarf::MethodDebugInfo>& method_infos) {
if (compiler_options_->GetGenerateDebugInfo()) {
- dwarf::WriteDebugInfo(builder_.get(), /* write_types */ true, method_infos, kCFIFormat);
+ dwarf::WriteDebugInfo(builder_.get(), method_infos, kCFIFormat);
}
}
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index a4b9c6c0b9..8fdbf4a3f7 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -67,12 +67,13 @@ extern "C" bool jit_compile_method(void* handle, ArtMethod* method, Thread* self
return jit_compiler->CompileMethod(self, method);
}
-extern "C" void jit_type_loaded(void* handle, mirror::Class* type)
+extern "C" void jit_types_loaded(void* handle, mirror::Class** types, size_t count)
SHARED_REQUIRES(Locks::mutator_lock_) {
auto* jit_compiler = reinterpret_cast<JitCompiler*>(handle);
DCHECK(jit_compiler != nullptr);
if (jit_compiler->GetCompilerOptions()->GetGenerateDebugInfo()) {
- ArrayRef<const uint8_t> elf_file = dwarf::WriteDebugElfFileForClass(kRuntimeISA, type);
+ const ArrayRef<mirror::Class*> types_array(types, count);
+ ArrayRef<const uint8_t> elf_file = dwarf::WriteDebugElfFileForClasses(kRuntimeISA, types_array);
CreateJITCodeEntry(std::unique_ptr<const uint8_t[]>(elf_file.data()), elf_file.size());
}
}
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 2a89077388..5c9dab2f38 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -127,11 +127,11 @@ bool Jit::LoadCompiler(std::string* error_msg) {
*error_msg = "JIT couldn't find jit_compile_method entry point";
return false;
}
- jit_type_loaded_ = reinterpret_cast<void (*)(void*, mirror::Class*)>(
- dlsym(jit_library_handle_, "jit_type_loaded"));
- if (jit_type_loaded_ == nullptr) {
+ jit_types_loaded_ = reinterpret_cast<void (*)(void*, mirror::Class**, size_t)>(
+ dlsym(jit_library_handle_, "jit_types_loaded"));
+ if (jit_types_loaded_ == nullptr) {
dlclose(jit_library_handle_);
- *error_msg = "JIT couldn't find jit_type_loaded entry point";
+ *error_msg = "JIT couldn't find jit_types_loaded entry point";
return false;
}
CompilerCallbacks* callbacks = nullptr;
@@ -224,8 +224,26 @@ void Jit::CreateInstrumentationCache(size_t compile_threshold, size_t warmup_thr
void Jit::NewTypeLoadedIfUsingJit(mirror::Class* type) {
jit::Jit* jit = Runtime::Current()->GetJit();
if (jit != nullptr && jit->generate_debug_info_) {
- DCHECK(jit->jit_type_loaded_ != nullptr);
- jit->jit_type_loaded_(jit->jit_compiler_handle_, type);
+ DCHECK(jit->jit_types_loaded_ != nullptr);
+ jit->jit_types_loaded_(jit->jit_compiler_handle_, &type, 1);
+ }
+}
+
+void Jit::DumpTypeInfoForLoadedTypes(ClassLinker* linker) {
+ struct CollectClasses : public ClassVisitor {
+ bool Visit(mirror::Class* klass) override {
+ classes_.push_back(klass);
+ return true;
+ }
+ std::vector<mirror::Class*> classes_;
+ };
+
+ if (generate_debug_info_) {
+ ScopedObjectAccess so(Thread::Current());
+
+ CollectClasses visitor;
+ linker->VisitClasses(&visitor);
+ jit_types_loaded_(jit_compiler_handle_, visitor.classes_.data(), visitor.classes_.size());
}
}
diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h
index 443ebe8025..429edf65a6 100644
--- a/runtime/jit/jit.h
+++ b/runtime/jit/jit.h
@@ -82,6 +82,10 @@ class Jit {
static void NewTypeLoadedIfUsingJit(mirror::Class* type)
SHARED_REQUIRES(Locks::mutator_lock_);
+ // If debug info generation is turned on then write the type information for types already loaded
+ // into the specified class linker to the jit debug interface,
+ void DumpTypeInfoForLoadedTypes(ClassLinker* linker);
+
private:
Jit();
bool LoadCompiler(std::string* error_msg);
@@ -92,7 +96,7 @@ class Jit {
void* (*jit_load_)(CompilerCallbacks**, bool*);
void (*jit_unload_)(void*);
bool (*jit_compile_method_)(void*, ArtMethod*, Thread*);
- void (*jit_type_loaded_)(void*, mirror::Class*);
+ void (*jit_types_loaded_)(void*, mirror::Class**, size_t count);
// Performance monitoring.
bool dump_info_on_shutdown_;
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index c4694ee291..1101acdf61 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1881,6 +1881,9 @@ void Runtime::CreateJit() {
jit_->CreateInstrumentationCache(jit_options_->GetCompileThreshold(),
jit_options_->GetWarmupThreshold());
jit_->CreateThreadPool();
+
+ // Notify native debugger about the classes already loaded before the creation of the jit.
+ jit_->DumpTypeInfoForLoadedTypes(GetClassLinker());
} else {
LOG(WARNING) << "Failed to create JIT " << error_msg;
}