diff options
-rw-r--r-- | compiler/elf_writer_debug.cc | 46 | ||||
-rw-r--r-- | compiler/elf_writer_debug.h | 4 | ||||
-rw-r--r-- | compiler/elf_writer_quick.cc | 2 | ||||
-rw-r--r-- | compiler/jit/jit_compiler.cc | 5 | ||||
-rw-r--r-- | runtime/jit/jit.cc | 30 | ||||
-rw-r--r-- | runtime/jit/jit.h | 6 | ||||
-rw-r--r-- | runtime/runtime.cc | 3 |
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; } |