Simplify JIT compiler interface usage from the runtime.
Avoid the excessive use of externs and reinterpret_casts.
Test: test.py -b --host --64 --jit
Change-Id: I179656a3a7c4e59d12c8f6d189c937ce07e0f122
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index f19de4e..d84a132 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -115,7 +115,7 @@
}
}
-extern "C" void* jit_load() {
+extern "C" JitCompilerInterface* jit_load() {
VLOG(jit) << "Create jit compiler";
auto* const jit_compiler = JitCompiler::Create();
CHECK(jit_compiler != nullptr);
@@ -123,24 +123,9 @@
return jit_compiler;
}
-extern "C" void jit_unload(void* handle) {
- DCHECK(handle != nullptr);
- delete reinterpret_cast<JitCompiler*>(handle);
-}
-
-extern "C" bool jit_compile_method(
- void* handle, JitMemoryRegion* region, ArtMethod* method, Thread* self, bool baseline, bool osr)
+void JitCompiler::TypesLoaded(mirror::Class** types, size_t count)
REQUIRES_SHARED(Locks::mutator_lock_) {
- auto* jit_compiler = reinterpret_cast<JitCompiler*>(handle);
- DCHECK(jit_compiler != nullptr);
- return jit_compiler->CompileMethod(self, region, method, baseline, osr);
-}
-
-extern "C" void jit_types_loaded(void* handle, mirror::Class** types, size_t count)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- auto* jit_compiler = reinterpret_cast<JitCompiler*>(handle);
- DCHECK(jit_compiler != nullptr);
- const CompilerOptions& compiler_options = jit_compiler->GetCompilerOptions();
+ const CompilerOptions& compiler_options = GetCompilerOptions();
if (compiler_options.GetGenerateDebugInfo()) {
const ArrayRef<mirror::Class*> types_array(types, count);
std::vector<uint8_t> elf_file = debug::WriteDebugElfFileForClasses(
@@ -156,16 +141,8 @@
}
}
-extern "C" void jit_update_options(void* handle) {
- JitCompiler* jit_compiler = reinterpret_cast<JitCompiler*>(handle);
- DCHECK(jit_compiler != nullptr);
- jit_compiler->ParseCompilerOptions();
-}
-
-extern "C" bool jit_generate_debug_info(void* handle) {
- JitCompiler* jit_compiler = reinterpret_cast<JitCompiler*>(handle);
- DCHECK(jit_compiler != nullptr);
- return jit_compiler->GetCompilerOptions().GetGenerateDebugInfo();
+bool JitCompiler::GenerateDebugInfo() {
+ return GetCompilerOptions().GetGenerateDebugInfo();
}
JitCompiler::JitCompiler() {
diff --git a/compiler/jit/jit_compiler.h b/compiler/jit/jit_compiler.h
index 06315a5..737771f 100644
--- a/compiler/jit/jit_compiler.h
+++ b/compiler/jit/jit_compiler.h
@@ -19,6 +19,8 @@
#include "base/mutex.h"
+#include "jit/jit.h"
+
namespace art {
class ArtMethod;
@@ -31,7 +33,7 @@
class JitLogger;
class JitMemoryRegion;
-class JitCompiler {
+class JitCompiler : public JitCompilerInterface {
public:
static JitCompiler* Create();
virtual ~JitCompiler();
@@ -39,13 +41,17 @@
// Compilation entrypoint. Returns whether the compilation succeeded.
bool CompileMethod(
Thread* self, JitMemoryRegion* region, ArtMethod* method, bool baseline, bool osr)
- REQUIRES_SHARED(Locks::mutator_lock_);
+ REQUIRES_SHARED(Locks::mutator_lock_) override;
const CompilerOptions& GetCompilerOptions() const {
return *compiler_options_.get();
}
- void ParseCompilerOptions();
+ bool GenerateDebugInfo() override;
+
+ void ParseCompilerOptions() override;
+
+ void TypesLoaded(mirror::Class**, size_t count) REQUIRES_SHARED(Locks::mutator_lock_) override;
private:
std::unique_ptr<CompilerOptions> compiler_options_;
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 902d924..3eeb0fa 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -63,14 +63,8 @@
// JIT compiler
void* Jit::jit_library_handle_ = nullptr;
-void* Jit::jit_compiler_handle_ = nullptr;
-void* (*Jit::jit_load_)(void) = nullptr;
-void (*Jit::jit_unload_)(void*) = nullptr;
-bool (*Jit::jit_compile_method_)(void*, JitMemoryRegion*, ArtMethod*, Thread*, bool, bool)
- = nullptr;
-void (*Jit::jit_types_loaded_)(void*, mirror::Class**, size_t count) = nullptr;
-bool (*Jit::jit_generate_debug_info_)(void*) = nullptr;
-void (*Jit::jit_update_options_)(void*) = nullptr;
+JitCompilerInterface* Jit::jit_compiler_ = nullptr;
+JitCompilerInterface* (*Jit::jit_load_)(void) = nullptr;
uint32_t JitOptions::RoundUpThreshold(uint32_t threshold) {
if (!Jit::kSlowMode) {
@@ -184,8 +178,8 @@
LOG(WARNING) << "Not creating JIT: library not loaded";
return nullptr;
}
- jit_compiler_handle_ = (jit_load_)();
- if (jit_compiler_handle_ == nullptr) {
+ jit_compiler_ = (jit_load_)();
+ if (jit_compiler_ == nullptr) {
LOG(WARNING) << "Not creating JIT: failed to allocate a compiler";
return nullptr;
}
@@ -196,7 +190,7 @@
// We aren't able to keep method pointers live during the instrumentation method entry trampoline
// so we will just disable jit-gc if we are doing that.
if (code_cache->GetGarbageCollectCode()) {
- code_cache->SetGarbageCollectCode(!jit_generate_debug_info_(jit_compiler_handle_) &&
+ code_cache->SetGarbageCollectCode(!jit_compiler_->GenerateDebugInfo() &&
!Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled());
}
@@ -230,15 +224,7 @@
*error_msg = oss.str();
return false;
}
- bool all_resolved = true;
- all_resolved = all_resolved && LoadSymbol(&jit_load_, "jit_load", error_msg);
- all_resolved = all_resolved && LoadSymbol(&jit_unload_, "jit_unload", error_msg);
- all_resolved = all_resolved && LoadSymbol(&jit_compile_method_, "jit_compile_method", error_msg);
- all_resolved = all_resolved && LoadSymbol(&jit_types_loaded_, "jit_types_loaded", error_msg);
- all_resolved = all_resolved && LoadSymbol(&jit_update_options_, "jit_update_options", error_msg);
- all_resolved = all_resolved &&
- LoadSymbol(&jit_generate_debug_info_, "jit_generate_debug_info", error_msg);
- if (!all_resolved) {
+ if (!LoadSymbol(&jit_load_, "jit_load", error_msg)) {
dlclose(jit_library_handle_);
return false;
}
@@ -283,8 +269,7 @@
VLOG(jit) << "Compiling method "
<< ArtMethod::PrettyMethod(method_to_compile)
<< " osr=" << std::boolalpha << osr;
- bool success = jit_compile_method_(
- jit_compiler_handle_, region, method_to_compile, self, baseline, osr);
+ bool success = jit_compiler_->CompileMethod(self, region, method_to_compile, baseline, osr);
code_cache_->DoneCompiling(method_to_compile, self, osr);
if (!success) {
VLOG(jit) << "Failed to compile method "
@@ -360,9 +345,9 @@
Runtime::Current()->DumpDeoptimizations(LOG_STREAM(INFO));
}
DeleteThreadPool();
- if (jit_compiler_handle_ != nullptr) {
- jit_unload_(jit_compiler_handle_);
- jit_compiler_handle_ = nullptr;
+ if (jit_compiler_ != nullptr) {
+ delete jit_compiler_;
+ jit_compiler_ = nullptr;
}
if (jit_library_handle_ != nullptr) {
dlclose(jit_library_handle_);
@@ -376,9 +361,8 @@
return;
}
jit::Jit* jit = Runtime::Current()->GetJit();
- if (jit_generate_debug_info_(jit->jit_compiler_handle_)) {
- DCHECK(jit->jit_types_loaded_ != nullptr);
- jit->jit_types_loaded_(jit->jit_compiler_handle_, &type, 1);
+ if (jit->jit_compiler_->GenerateDebugInfo()) {
+ jit_compiler_->TypesLoaded(&type, 1);
}
}
@@ -391,12 +375,12 @@
std::vector<mirror::Class*> classes_;
};
- if (jit_generate_debug_info_(jit_compiler_handle_)) {
+ if (jit_compiler_->GenerateDebugInfo()) {
ScopedObjectAccess so(Thread::Current());
CollectClasses visitor;
linker->VisitClasses(&visitor);
- jit_types_loaded_(jit_compiler_handle_, visitor.classes_.data(), visitor.classes_.size());
+ jit_compiler_->TypesLoaded(visitor.classes_.data(), visitor.classes_.size());
}
}
@@ -1122,10 +1106,10 @@
}
// At this point, the compiler options have been adjusted to the particular configuration
// of the forked child. Parse them again.
- jit_update_options_(jit_compiler_handle_);
+ jit_compiler_->ParseCompilerOptions();
// Adjust the status of code cache collection: the status from zygote was to not collect.
- code_cache_->SetGarbageCollectCode(!jit_generate_debug_info_(jit_compiler_handle_) &&
+ code_cache_->SetGarbageCollectCode(!jit_compiler_->GenerateDebugInfo() &&
!Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled());
if (thread_pool_ != nullptr) {
diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h
index 8cf37fb..36a1d3e 100644
--- a/runtime/jit/jit.h
+++ b/runtime/jit/jit.h
@@ -164,6 +164,19 @@
DISALLOW_COPY_AND_ASSIGN(JitOptions);
};
+// Implemented and provided by the compiler library.
+class JitCompilerInterface {
+ public:
+ virtual ~JitCompilerInterface() {}
+ virtual bool CompileMethod(
+ Thread* self, JitMemoryRegion* region, ArtMethod* method, bool baseline, bool osr)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+ virtual void TypesLoaded(mirror::Class**, size_t count)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+ virtual bool GenerateDebugInfo();
+ virtual void ParseCompilerOptions();
+};
+
class Jit {
public:
static constexpr size_t kDefaultPriorityThreadWeightRatio = 1000;
@@ -378,13 +391,8 @@
// JIT compiler
static void* jit_library_handle_;
- static void* jit_compiler_handle_;
- static void* (*jit_load_)(void);
- static void (*jit_unload_)(void*);
- static bool (*jit_compile_method_)(void*, JitMemoryRegion*, ArtMethod*, Thread*, bool, bool);
- static void (*jit_types_loaded_)(void*, mirror::Class**, size_t count);
- static void (*jit_update_options_)(void*);
- static bool (*jit_generate_debug_info_)(void*);
+ static JitCompilerInterface* jit_compiler_;
+ static JitCompilerInterface* (*jit_load_)(void);
template <typename T> static bool LoadSymbol(T*, const char* symbol, std::string* error_msg);
// JIT resources owned by runtime.