Report loaded classes to native debugger.
Change-Id: Iee902a9ed8fa7545ba3e6afc32f285aa350a5383
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index bc51ed6..a4b9c6c 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -28,6 +28,8 @@
#include "dex/quick_compiler_callbacks.h"
#include "driver/compiler_driver.h"
#include "driver/compiler_options.h"
+#include "elf_writer_debug.h"
+#include "jit/debugger_interface.h"
#include "jit/jit.h"
#include "jit/jit_code_cache.h"
#include "oat_file-inl.h"
@@ -65,6 +67,16 @@
return jit_compiler->CompileMethod(self, method);
}
+extern "C" void jit_type_loaded(void* handle, mirror::Class* type)
+ 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);
+ CreateJITCodeEntry(std::unique_ptr<const uint8_t[]>(elf_file.data()), elf_file.size());
+ }
+}
+
// Callers of this method assume it has NO_RETURN.
NO_RETURN static void Usage(const char* fmt, ...) {
va_list ap;
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 41842e8..1299915 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1879,6 +1879,9 @@
*/
Dbg::PostClassPrepare(h_new_class.Get());
+ // Notify native debugger of the new class and its layout.
+ jit::Jit::NewTypeLoadedIfUsingJit(h_new_class.Get());
+
return h_new_class.Get();
}
@@ -2765,6 +2768,7 @@
mirror::Class* existing = InsertClass(descriptor, new_class.Get(), hash);
if (existing == nullptr) {
+ jit::Jit::NewTypeLoadedIfUsingJit(new_class.Get());
return new_class.Get();
}
// Another thread must have loaded the class after we
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 05668a9..2a89077 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -127,6 +127,13 @@
*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) {
+ dlclose(jit_library_handle_);
+ *error_msg = "JIT couldn't find jit_type_loaded entry point";
+ return false;
+ }
CompilerCallbacks* callbacks = nullptr;
bool will_generate_debug_symbols = false;
VLOG(jit) << "Calling JitLoad interpreter_only="
@@ -214,5 +221,13 @@
new jit::JitInstrumentationCache(compile_threshold, warmup_threshold));
}
+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);
+ }
+}
+
} // namespace jit
} // namespace art
diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h
index 42bbbe7..443ebe8 100644
--- a/runtime/jit/jit.h
+++ b/runtime/jit/jit.h
@@ -79,6 +79,9 @@
DumpInfo(os);
}
+ static void NewTypeLoadedIfUsingJit(mirror::Class* type)
+ SHARED_REQUIRES(Locks::mutator_lock_);
+
private:
Jit();
bool LoadCompiler(std::string* error_msg);
@@ -89,6 +92,7 @@
void* (*jit_load_)(CompilerCallbacks**, bool*);
void (*jit_unload_)(void*);
bool (*jit_compile_method_)(void*, ArtMethod*, Thread*);
+ void (*jit_type_loaded_)(void*, mirror::Class*);
// Performance monitoring.
bool dump_info_on_shutdown_;