jit.cc revision d9994f069dfeaa32ba929ca78816b5b83e2a4134
1e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier/* 2e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * Copyright 2014 The Android Open Source Project 3e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * 4e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * Licensed under the Apache License, Version 2.0 (the "License"); 5e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * you may not use this file except in compliance with the License. 6e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * You may obtain a copy of the License at 7e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * 8e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * http://www.apache.org/licenses/LICENSE-2.0 9e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * 10e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * Unless required by applicable law or agreed to in writing, software 11e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * distributed under the License is distributed on an "AS IS" BASIS, 12e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * See the License for the specific language governing permissions and 14e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier * limitations under the License. 15e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier */ 16e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 17e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "jit.h" 18e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 19e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include <dlfcn.h> 20e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 21e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "art_method-inl.h" 222a5c4681ba19411c1cb22e9a7ab446dab910af1cAndreas Gampe#include "debugger.h" 23e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "entrypoints/runtime_asm_entrypoints.h" 24e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "interpreter/interpreter.h" 25e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "jit_code_cache.h" 26e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "jit_instrumentation.h" 2731f2c155975c5794d481df03eb0947cb48d2c6b5Calin Juravle#include "oat_file_manager.h" 28b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray#include "oat_quick_method_header.h" 2931f2c155975c5794d481df03eb0947cb48d2c6b5Calin Juravle#include "offline_profiling_info.h" 304d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle#include "profile_saver.h" 31e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "runtime.h" 32e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "runtime_options.h" 33b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray#include "stack_map.h" 34e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier#include "utils.h" 35e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 36e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartiernamespace art { 37e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartiernamespace jit { 38e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 39e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu ChartierJitOptions* JitOptions::CreateFromRuntimeArguments(const RuntimeArgumentMap& options) { 40e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier auto* jit_options = new JitOptions; 41455f67c4cf0b4f04e117db3024fd189fa1c7dab9Mathieu Chartier jit_options->use_jit_ = options.GetOrDefault(RuntimeArgumentMap::UseJIT); 420a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray jit_options->code_cache_initial_capacity_ = 430a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray options.GetOrDefault(RuntimeArgumentMap::JITCodeCacheInitialCapacity); 440a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray jit_options->code_cache_max_capacity_ = 450a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray options.GetOrDefault(RuntimeArgumentMap::JITCodeCacheMaxCapacity); 46e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier jit_options->compile_threshold_ = 47e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier options.GetOrDefault(RuntimeArgumentMap::JITCompileThreshold); 48b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // TODO(ngeoffray): Make this a proper option. 49b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray jit_options->osr_threshold_ = jit_options->compile_threshold_ * 2; 505550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray jit_options->warmup_threshold_ = 515550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray options.GetOrDefault(RuntimeArgumentMap::JITWarmupThreshold); 52a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier jit_options->dump_info_on_shutdown_ = 53a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier options.Exists(RuntimeArgumentMap::DumpJITInfoOnShutdown); 5431f2c155975c5794d481df03eb0947cb48d2c6b5Calin Juravle jit_options->save_profiling_info_ = 5531f2c155975c5794d481df03eb0947cb48d2c6b5Calin Juravle options.GetOrDefault(RuntimeArgumentMap::JITSaveProfilingInfo);; 56e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return jit_options; 57e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 58e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 59a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartiervoid Jit::DumpInfo(std::ostream& os) { 60aee2156e308f3f346ac4df76ba1d33ee9b11be84Nicolas Geoffray os << "JIT code cache size=" << PrettySize(code_cache_->CodeCacheSize()) << "\n" 61aee2156e308f3f346ac4df76ba1d33ee9b11be84Nicolas Geoffray << "JIT data cache size=" << PrettySize(code_cache_->DataCacheSize()) << "\n" 62aee2156e308f3f346ac4df76ba1d33ee9b11be84Nicolas Geoffray << "JIT current capacity=" << PrettySize(code_cache_->GetCurrentCapacity()) << "\n" 630a52223d9173315aeaca05217b8c792b3088ea7dNicolas Geoffray << "JIT number of compiled code=" << code_cache_->NumberOfCompiledCode() << "\n" 640a52223d9173315aeaca05217b8c792b3088ea7dNicolas Geoffray << "JIT total number of compilations=" << code_cache_->NumberOfCompilations() << "\n"; 65a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier cumulative_timings_.Dump(os); 66a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier} 67a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier 68a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartiervoid Jit::AddTimingLogger(const TimingLogger& logger) { 69a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier cumulative_timings_.AddLogger(logger); 70a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier} 71a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier 72a25dce9b452ba17ef7cef768926c884177a3025eNicolas GeoffrayJit::Jit() : jit_library_handle_(nullptr), 73a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray jit_compiler_handle_(nullptr), 74a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray jit_load_(nullptr), 75a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray jit_compile_method_(nullptr), 76a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray dump_info_on_shutdown_(false), 77a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray cumulative_timings_("JIT timings"), 78a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray save_profiling_info_(false), 79a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray generate_debug_info_(false) { 80e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 81e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 82e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu ChartierJit* Jit::Create(JitOptions* options, std::string* error_msg) { 83e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier std::unique_ptr<Jit> jit(new Jit); 84a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier jit->dump_info_on_shutdown_ = options->DumpJitInfoOnShutdown(); 85e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (!jit->LoadCompiler(error_msg)) { 86e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return nullptr; 87e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 880a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray jit->code_cache_.reset(JitCodeCache::Create( 89a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray options->GetCodeCacheInitialCapacity(), 90a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray options->GetCodeCacheMaxCapacity(), 91a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray jit->generate_debug_info_, 92a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray error_msg)); 93e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit->GetCodeCache() == nullptr) { 94e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return nullptr; 95e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 964d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle jit->save_profiling_info_ = options->GetSaveProfilingInfo(); 970a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray LOG(INFO) << "JIT created with initial_capacity=" 980a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray << PrettySize(options->GetCodeCacheInitialCapacity()) 990a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray << ", max_capacity=" << PrettySize(options->GetCodeCacheMaxCapacity()) 1004d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle << ", compile_threshold=" << options->GetCompileThreshold() 1014d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle << ", save_profiling_info=" << options->GetSaveProfilingInfo(); 102e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return jit.release(); 103e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 104e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 105e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartierbool Jit::LoadCompiler(std::string* error_msg) { 106e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier jit_library_handle_ = dlopen( 107e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier kIsDebugBuild ? "libartd-compiler.so" : "libart-compiler.so", RTLD_NOW); 108e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit_library_handle_ == nullptr) { 109e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier std::ostringstream oss; 110e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier oss << "JIT could not load libart-compiler.so: " << dlerror(); 111e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *error_msg = oss.str(); 112e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return false; 113e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 114a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray jit_load_ = reinterpret_cast<void* (*)(CompilerCallbacks**, bool*)>( 115e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlsym(jit_library_handle_, "jit_load")); 116e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit_load_ == nullptr) { 117e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlclose(jit_library_handle_); 118e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *error_msg = "JIT couldn't find jit_load entry point"; 119e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return false; 120e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 121e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier jit_unload_ = reinterpret_cast<void (*)(void*)>( 122e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlsym(jit_library_handle_, "jit_unload")); 123e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit_unload_ == nullptr) { 124e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlclose(jit_library_handle_); 125e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *error_msg = "JIT couldn't find jit_unload entry point"; 126e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return false; 127e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 128b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray jit_compile_method_ = reinterpret_cast<bool (*)(void*, ArtMethod*, Thread*, bool)>( 129e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlsym(jit_library_handle_, "jit_compile_method")); 130e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit_compile_method_ == nullptr) { 131e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlclose(jit_library_handle_); 132e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *error_msg = "JIT couldn't find jit_compile_method entry point"; 133e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return false; 134e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 135fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer jit_types_loaded_ = reinterpret_cast<void (*)(void*, mirror::Class**, size_t)>( 136fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer dlsym(jit_library_handle_, "jit_types_loaded")); 137fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer if (jit_types_loaded_ == nullptr) { 138160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer dlclose(jit_library_handle_); 139fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer *error_msg = "JIT couldn't find jit_types_loaded entry point"; 140160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer return false; 141160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer } 142e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier CompilerCallbacks* callbacks = nullptr; 143a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray bool will_generate_debug_symbols = false; 144e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier VLOG(jit) << "Calling JitLoad interpreter_only=" 145e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier << Runtime::Current()->GetInstrumentation()->InterpretOnly(); 146a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray jit_compiler_handle_ = (jit_load_)(&callbacks, &will_generate_debug_symbols); 147e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit_compiler_handle_ == nullptr) { 148e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlclose(jit_library_handle_); 149e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *error_msg = "JIT couldn't load compiler"; 150e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return false; 151e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 152e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (callbacks == nullptr) { 153e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlclose(jit_library_handle_); 154e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *error_msg = "JIT compiler callbacks were not set"; 155e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier jit_compiler_handle_ = nullptr; 156e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return false; 157e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 158e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier compiler_callbacks_ = callbacks; 159a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray generate_debug_info_ = will_generate_debug_symbols; 160e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return true; 161e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 162e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 163b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffraybool Jit::CompileMethod(ArtMethod* method, Thread* self, bool osr) { 164e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier DCHECK(!method->IsRuntimeMethod()); 165d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray 16673be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray // Don't compile the method if it has breakpoints. 167d8565456d29f4ad05f11cf84d2d2dac488508e06Mathieu Chartier if (Dbg::IsDebuggerActive() && Dbg::MethodHasAnyBreakpoints(method)) { 168d8565456d29f4ad05f11cf84d2d2dac488508e06Mathieu Chartier VLOG(jit) << "JIT not compiling " << PrettyMethod(method) << " due to breakpoint"; 169d8565456d29f4ad05f11cf84d2d2dac488508e06Mathieu Chartier return false; 170d8565456d29f4ad05f11cf84d2d2dac488508e06Mathieu Chartier } 17173be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray 17273be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray // Don't compile the method if we are supposed to be deoptimized. 17373be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 17473be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray if (instrumentation->AreAllMethodsDeoptimized() || instrumentation->IsDeoptimized(method)) { 175a42363f79832a6e14f348514664dc6dc3edf9da2Nicolas Geoffray VLOG(jit) << "JIT not compiling " << PrettyMethod(method) << " due to deoptimization"; 17673be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray return false; 17773be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray } 17873be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray 179d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray // If we get a request to compile a proxy method, we pass the actual Java method 180d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray // of that proxy method, as the compiler does not expect a proxy method. 181d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray ArtMethod* method_to_compile = method->GetInterfaceMethodIfProxy(sizeof(void*)); 182d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray if (!code_cache_->NotifyCompilationOf(method_to_compile, self, osr)) { 183b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray VLOG(jit) << "JIT not compiling " << PrettyMethod(method) << " due to code cache"; 18473be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray return false; 18573be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray } 186d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray bool success = jit_compile_method_(jit_compiler_handle_, method_to_compile, self, osr); 187d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray code_cache_->DoneCompiling(method_to_compile, self); 18873be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray return success; 189e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 190e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 191e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartiervoid Jit::CreateThreadPool() { 192e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier CHECK(instrumentation_cache_.get() != nullptr); 193e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier instrumentation_cache_->CreateThreadPool(); 194e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 195e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 196e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartiervoid Jit::DeleteThreadPool() { 197e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (instrumentation_cache_.get() != nullptr) { 198629e9350b0b72998416504f7a6fb95b6086daca8Nicolas Geoffray instrumentation_cache_->DeleteThreadPool(Thread::Current()); 199e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 200e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 201e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 2024d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravlevoid Jit::StartProfileSaver(const std::string& filename, 2034d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle const std::vector<std::string>& code_paths) { 2044d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle if (save_profiling_info_) { 2054d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle ProfileSaver::Start(filename, code_cache_.get(), code_paths); 2064d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle } 2074d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle} 2084d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle 2094d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravlevoid Jit::StopProfileSaver() { 2104d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle if (save_profiling_info_ && ProfileSaver::IsStarted()) { 2114d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle ProfileSaver::Stop(); 21231f2c155975c5794d481df03eb0947cb48d2c6b5Calin Juravle } 21331f2c155975c5794d481df03eb0947cb48d2c6b5Calin Juravle} 21431f2c155975c5794d481df03eb0947cb48d2c6b5Calin Juravle 21505d241565f36df825cf56a4f1b61bfb7e4dcb056Siva Chandrabool Jit::JitAtFirstUse() { 21605d241565f36df825cf56a4f1b61bfb7e4dcb056Siva Chandra if (instrumentation_cache_ != nullptr) { 21705d241565f36df825cf56a4f1b61bfb7e4dcb056Siva Chandra return instrumentation_cache_->HotMethodThreshold() == 0; 21805d241565f36df825cf56a4f1b61bfb7e4dcb056Siva Chandra } 21905d241565f36df825cf56a4f1b61bfb7e4dcb056Siva Chandra return false; 22005d241565f36df825cf56a4f1b61bfb7e4dcb056Siva Chandra} 22105d241565f36df825cf56a4f1b61bfb7e4dcb056Siva Chandra 222e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu ChartierJit::~Jit() { 2234d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle DCHECK(!save_profiling_info_ || !ProfileSaver::IsStarted()); 224a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier if (dump_info_on_shutdown_) { 225a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier DumpInfo(LOG(INFO)); 226a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier } 227e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier DeleteThreadPool(); 228e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit_compiler_handle_ != nullptr) { 229e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier jit_unload_(jit_compiler_handle_); 230e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 231e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit_library_handle_ != nullptr) { 232e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlclose(jit_library_handle_); 233e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 234e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 235e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 236b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffrayvoid Jit::CreateInstrumentationCache(size_t compile_threshold, 237b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray size_t warmup_threshold, 238b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray size_t osr_threshold) { 2395550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray instrumentation_cache_.reset( 240b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray new jit::JitInstrumentationCache(compile_threshold, warmup_threshold, osr_threshold)); 241e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 242e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 243160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammervoid Jit::NewTypeLoadedIfUsingJit(mirror::Class* type) { 244160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer jit::Jit* jit = Runtime::Current()->GetJit(); 245160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer if (jit != nullptr && jit->generate_debug_info_) { 246fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer DCHECK(jit->jit_types_loaded_ != nullptr); 247fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer jit->jit_types_loaded_(jit->jit_compiler_handle_, &type, 1); 248fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer } 249fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer} 250fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer 251fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammervoid Jit::DumpTypeInfoForLoadedTypes(ClassLinker* linker) { 252fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer struct CollectClasses : public ClassVisitor { 2531aa8ec2ccdd7bedb6d30d91c89f1e94ab23c4439Mathieu Chartier bool operator()(mirror::Class* klass) override { 254fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer classes_.push_back(klass); 255fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer return true; 256fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer } 2579b1c9b761dea9bc48a2994e3d4de46fc10343a25Mathieu Chartier std::vector<mirror::Class*> classes_; 258fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer }; 259fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer 260fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer if (generate_debug_info_) { 261fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer ScopedObjectAccess so(Thread::Current()); 262fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer 263fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer CollectClasses visitor; 264fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer linker->VisitClasses(&visitor); 265fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer jit_types_loaded_(jit_compiler_handle_, visitor.classes_.data(), visitor.classes_.size()); 266160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer } 267160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer} 268160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer 269b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffrayextern "C" void art_quick_osr_stub(void** stack, 270b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray uint32_t stack_size_in_bytes, 271b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray const uint8_t* native_pc, 272b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray JValue* result, 273b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray const char* shorty, 274b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray Thread* self); 275b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 276b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffraybool Jit::MaybeDoOnStackReplacement(Thread* thread, 277b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray ArtMethod* method, 278b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray uint32_t dex_pc, 279b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray int32_t dex_pc_offset, 280b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray JValue* result) { 281b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray Jit* jit = Runtime::Current()->GetJit(); 282b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray if (jit == nullptr) { 283b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray return false; 284b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 285b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 286b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray if (kRuntimeISA == kMips || kRuntimeISA == kMips64) { 287b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray VLOG(jit) << "OSR not supported on this platform"; 288b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray return false; 289b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 290b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 291d9bc433a89c41a255d1b669d075f802597839bdcNicolas Geoffray // Get the actual Java method if this method is from a proxy class. The compiler 292d9bc433a89c41a255d1b669d075f802597839bdcNicolas Geoffray // and the JIT code cache do not expect methods from proxy classes. 293d9bc433a89c41a255d1b669d075f802597839bdcNicolas Geoffray method = method->GetInterfaceMethodIfProxy(sizeof(void*)); 294d9bc433a89c41a255d1b669d075f802597839bdcNicolas Geoffray 295b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // Cheap check if the method has been compiled already. That's an indicator that we should 296b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // osr into it. 297b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray if (!jit->GetCodeCache()->ContainsPc(method->GetEntryPointFromQuickCompiledCode())) { 298b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray return false; 299b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 300b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 301b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray const OatQuickMethodHeader* osr_method = jit->GetCodeCache()->LookupOsrMethodHeader(method); 302b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray if (osr_method == nullptr) { 303b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // No osr method yet, just return to the interpreter. 304b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray return false; 305b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 306b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 307b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray const size_t number_of_vregs = method->GetCodeItem()->registers_size_; 308b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray CodeInfo code_info = osr_method->GetOptimizedCodeInfo(); 309b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray StackMapEncoding encoding = code_info.ExtractEncoding(); 310b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 311b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // Find stack map starting at the target dex_pc. 312b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray StackMap stack_map = code_info.GetOsrStackMapForDexPc(dex_pc + dex_pc_offset, encoding); 313b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray if (!stack_map.IsValid()) { 314b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // There is no OSR stack map for this dex pc offset. Just return to the interpreter in the 315b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // hope that the next branch has one. 316b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray return false; 317b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 318b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 319b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // We found a stack map, now fill the frame with dex register values from the interpreter's 320b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // shadow frame. 321b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray DexRegisterMap vreg_map = 322b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_vregs); 323b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 324b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray ShadowFrame* shadow_frame = thread->PopShadowFrame(); 325b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 326b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray size_t frame_size = osr_method->GetFrameSizeInBytes(); 327d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray 328d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray // Allocate memory to put shadow frame values. The osr stub will copy that memory to 329d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray // stack. 330d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray // Note that we could pass the shadow frame to the stub, and let it copy the values there, 331d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray // but that is engineering complexity not worth the effort for something like OSR. 332b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray void** memory = reinterpret_cast<void**>(malloc(frame_size)); 333d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray CHECK(memory != nullptr); 334b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray memset(memory, 0, frame_size); 335b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 336b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // Art ABI: ArtMethod is at the bottom of the stack. 337b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray memory[0] = method; 338b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 339b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray if (!vreg_map.IsValid()) { 340b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // If we don't have a dex register map, then there are no live dex registers at 341b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // this dex pc. 342b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } else { 343b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray for (uint16_t vreg = 0; vreg < number_of_vregs; ++vreg) { 344b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray DexRegisterLocation::Kind location = 345b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray vreg_map.GetLocationKind(vreg, number_of_vregs, code_info, encoding); 346b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray if (location == DexRegisterLocation::Kind::kNone) { 347b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // Dex register is dead or unitialized. 348b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray continue; 349b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 350b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 351b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray if (location == DexRegisterLocation::Kind::kConstant) { 352b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // We skip constants because the compiled code knows how to handle them. 353b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray continue; 354b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 355b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 356b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray DCHECK(location == DexRegisterLocation::Kind::kInStack); 357b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 358b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray int32_t vreg_value = shadow_frame->GetVReg(vreg); 359b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray int32_t slot_offset = vreg_map.GetStackOffsetInBytes(vreg, 360b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray number_of_vregs, 361b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray code_info, 362b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray encoding); 363b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray DCHECK_LT(slot_offset, static_cast<int32_t>(frame_size)); 364b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray DCHECK_GT(slot_offset, 0); 365b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray (reinterpret_cast<int32_t*>(memory))[slot_offset / sizeof(int32_t)] = vreg_value; 366b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 367b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 368b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 369b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray const uint8_t* native_pc = stack_map.GetNativePcOffset(encoding) + osr_method->GetEntryPoint(); 370b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray VLOG(jit) << "Jumping to " 371b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray << PrettyMethod(method) 372b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray << "@" 373b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray << std::hex << reinterpret_cast<uintptr_t>(native_pc); 374b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray { 375b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray ManagedStack fragment; 376b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray thread->PushManagedStackFragment(&fragment); 377b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray (*art_quick_osr_stub)(memory, 378b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray frame_size, 379b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray native_pc, 380b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray result, 381b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty(), 382b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray thread); 383b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray if (UNLIKELY(thread->GetException() == Thread::GetDeoptimizationException())) { 384b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray thread->DeoptimizeWithDeoptimizationException(result); 385b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 386b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray thread->PopManagedStackFragment(fragment); 387b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 388b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray free(memory); 389b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray thread->PushShadowFrame(shadow_frame); 390b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray VLOG(jit) << "Done running OSR code for " << PrettyMethod(method); 391b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray return true; 392b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray} 393b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 394e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} // namespace jit 395e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} // namespace art 396