summaryrefslogtreecommitdiff
path: root/runtime/jit/jit.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/jit/jit.cc')
-rw-r--r--runtime/jit/jit.cc87
1 files changed, 50 insertions, 37 deletions
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index d67d9dced8..4a3ef07819 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -56,10 +56,12 @@ static constexpr size_t kJitSlowStressDefaultCompileThreshold = 2; // Slow-
// JIT compiler
void* Jit::jit_library_handle_ = nullptr;
void* Jit::jit_compiler_handle_ = nullptr;
-void* (*Jit::jit_load_)(bool*) = nullptr;
+void* (*Jit::jit_load_)(void) = nullptr;
void (*Jit::jit_unload_)(void*) = nullptr;
bool (*Jit::jit_compile_method_)(void*, ArtMethod*, Thread*, 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;
struct StressModeHelper {
DECLARE_RUNTIME_DEBUG_FLAG(kSlowMode);
@@ -179,20 +181,21 @@ Jit* Jit::Create(JitCodeCache* code_cache, JitOptions* options) {
LOG(WARNING) << "Not creating JIT: library not loaded";
return nullptr;
}
- bool will_generate_debug_symbols = false;
- jit_compiler_handle_ = (jit_load_)(&will_generate_debug_symbols);
+ jit_compiler_handle_ = (jit_load_)();
if (jit_compiler_handle_ == nullptr) {
LOG(WARNING) << "Not creating JIT: failed to allocate a compiler";
return nullptr;
}
std::unique_ptr<Jit> jit(new Jit(code_cache, options));
- jit->generate_debug_info_ = will_generate_debug_symbols;
+ // If the code collector is enabled, check if that still holds:
// With 'perf', we want a 1-1 mapping between an address and a method.
// 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.
- code_cache->SetGarbageCollectCode(!jit->generate_debug_info_ &&
- !Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled());
+ if (code_cache->GetGarbageCollectCode()) {
+ code_cache->SetGarbageCollectCode(!jit_generate_debug_info_(jit_compiler_handle_) &&
+ !Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled());
+ }
VLOG(jit) << "JIT created with initial_capacity="
<< PrettySize(options->GetCodeCacheInitialCapacity())
@@ -200,13 +203,21 @@ Jit* Jit::Create(JitCodeCache* code_cache, JitOptions* options) {
<< ", compile_threshold=" << options->GetCompileThreshold()
<< ", profile_saver_options=" << options->GetProfileSaverOptions();
- jit->CreateThreadPool();
-
// Notify native debugger about the classes already loaded before the creation of the jit.
jit->DumpTypeInfoForLoadedTypes(Runtime::Current()->GetClassLinker());
return jit.release();
}
+template <typename T>
+bool Jit::LoadSymbol(T* address, const char* name, std::string* error_msg) {
+ *address = reinterpret_cast<T>(dlsym(jit_library_handle_, name));
+ if (*address == nullptr) {
+ *error_msg = std::string("JIT couldn't find ") + name + std::string(" entry point");
+ return false;
+ }
+ return true;
+}
+
bool Jit::LoadCompilerLibrary(std::string* error_msg) {
jit_library_handle_ = dlopen(
kIsDebugBuild ? "libartd-compiler.so" : "libart-compiler.so", RTLD_NOW);
@@ -216,31 +227,16 @@ bool Jit::LoadCompilerLibrary(std::string* error_msg) {
*error_msg = oss.str();
return false;
}
- jit_load_ = reinterpret_cast<void* (*)(bool*)>(dlsym(jit_library_handle_, "jit_load"));
- if (jit_load_ == nullptr) {
- dlclose(jit_library_handle_);
- *error_msg = "JIT couldn't find jit_load entry point";
- return false;
- }
- jit_unload_ = reinterpret_cast<void (*)(void*)>(
- dlsym(jit_library_handle_, "jit_unload"));
- if (jit_unload_ == nullptr) {
+ 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) {
dlclose(jit_library_handle_);
- *error_msg = "JIT couldn't find jit_unload entry point";
- return false;
- }
- jit_compile_method_ = reinterpret_cast<bool (*)(void*, ArtMethod*, Thread*, bool)>(
- dlsym(jit_library_handle_, "jit_compile_method"));
- if (jit_compile_method_ == nullptr) {
- dlclose(jit_library_handle_);
- *error_msg = "JIT couldn't find jit_compile_method entry point";
- return false;
- }
- 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_types_loaded entry point";
return false;
}
return true;
@@ -296,7 +292,11 @@ bool Jit::CompileMethod(ArtMethod* method, Thread* self, bool osr) {
}
void Jit::CreateThreadPool() {
- // There is a DCHECK in the 'AddSamples' method to ensure the tread pool
+ if (Runtime::Current()->IsSafeMode()) {
+ // Never create the pool in safe mode.
+ return;
+ }
+ // There is a DCHECK in the 'AddSamples' method to ensure the thread pool
// is not null when we instrument.
// We need peers as we may report the JIT thread, e.g., in the debugger.
@@ -375,7 +375,7 @@ void Jit::NewTypeLoadedIfUsingJit(mirror::Class* type) {
return;
}
jit::Jit* jit = Runtime::Current()->GetJit();
- if (jit->generate_debug_info_) {
+ 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);
}
@@ -390,7 +390,7 @@ void Jit::DumpTypeInfoForLoadedTypes(ClassLinker* linker) {
std::vector<mirror::Class*> classes_;
};
- if (generate_debug_info_) {
+ if (jit_generate_debug_info_(jit_compiler_handle_)) {
ScopedObjectAccess so(Thread::Current());
CollectClasses visitor;
@@ -630,8 +630,11 @@ static bool IgnoreSamplesForMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mut
void Jit::AddSamples(Thread* self, ArtMethod* method, uint16_t count, bool with_backedges) {
if (thread_pool_ == nullptr) {
- // Should only see this when shutting down.
- DCHECK(Runtime::Current()->IsShuttingDown(self));
+ // Should only see this when shutting down, starting up, or in zygote, which doesn't
+ // have a thread pool.
+ DCHECK(Runtime::Current()->IsShuttingDown(self) ||
+ !Runtime::Current()->IsFinishedStarting() ||
+ Runtime::Current()->IsZygote());
return;
}
if (IgnoreSamplesForMethod(method)) {
@@ -795,5 +798,15 @@ ScopedJitSuspend::~ScopedJitSuspend() {
}
}
+void Jit::PostForkChildAction() {
+ // 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_);
+
+ // 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_) &&
+ !Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled());
+}
+
} // namespace jit
} // namespace art