diff options
Diffstat (limited to 'runtime/jit/jit.cc')
-rw-r--r-- | runtime/jit/jit.cc | 87 |
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 |