jit.cc revision b2771b41a956b50266d4d83fbb067f99faf7b7dc
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 39d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffraystatic constexpr bool kEnableOnStackReplacement = true; 40e86621386d18a3a7178af6cfc2c05d1b34c3b995Nicolas Geoffray 4172918ea854d182ef25b2352bfe1c46c1e916a141Mathieu Chartier// JIT compiler 4272918ea854d182ef25b2352bfe1c46c1e916a141Mathieu Chartiervoid* Jit::jit_library_handle_= nullptr; 4372918ea854d182ef25b2352bfe1c46c1e916a141Mathieu Chartiervoid* Jit::jit_compiler_handle_ = nullptr; 4472918ea854d182ef25b2352bfe1c46c1e916a141Mathieu Chartiervoid* (*Jit::jit_load_)(bool*) = nullptr; 4572918ea854d182ef25b2352bfe1c46c1e916a141Mathieu Chartiervoid (*Jit::jit_unload_)(void*) = nullptr; 4672918ea854d182ef25b2352bfe1c46c1e916a141Mathieu Chartierbool (*Jit::jit_compile_method_)(void*, ArtMethod*, Thread*, bool) = nullptr; 4772918ea854d182ef25b2352bfe1c46c1e916a141Mathieu Chartiervoid (*Jit::jit_types_loaded_)(void*, mirror::Class**, size_t count) = nullptr; 4872918ea854d182ef25b2352bfe1c46c1e916a141Mathieu Chartierbool Jit::generate_debug_info_ = false; 4972918ea854d182ef25b2352bfe1c46c1e916a141Mathieu Chartier 50e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu ChartierJitOptions* JitOptions::CreateFromRuntimeArguments(const RuntimeArgumentMap& options) { 51e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier auto* jit_options = new JitOptions; 52455f67c4cf0b4f04e117db3024fd189fa1c7dab9Mathieu Chartier jit_options->use_jit_ = options.GetOrDefault(RuntimeArgumentMap::UseJIT); 5383f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray 540a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray jit_options->code_cache_initial_capacity_ = 550a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray options.GetOrDefault(RuntimeArgumentMap::JITCodeCacheInitialCapacity); 560a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray jit_options->code_cache_max_capacity_ = 570a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray options.GetOrDefault(RuntimeArgumentMap::JITCodeCacheMaxCapacity); 58a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier jit_options->dump_info_on_shutdown_ = 59a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier options.Exists(RuntimeArgumentMap::DumpJITInfoOnShutdown); 6031f2c155975c5794d481df03eb0947cb48d2c6b5Calin Juravle jit_options->save_profiling_info_ = 6183f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray options.GetOrDefault(RuntimeArgumentMap::JITSaveProfilingInfo); 6283f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray 6383f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray jit_options->compile_threshold_ = options.GetOrDefault(RuntimeArgumentMap::JITCompileThreshold); 6483f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray if (jit_options->compile_threshold_ > std::numeric_limits<uint16_t>::max()) { 6583f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray LOG(FATAL) << "Method compilation threshold is above its internal limit."; 6683f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray } 6783f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray 6883f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray if (options.Exists(RuntimeArgumentMap::JITWarmupThreshold)) { 6983f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray jit_options->warmup_threshold_ = *options.Get(RuntimeArgumentMap::JITWarmupThreshold); 7083f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray if (jit_options->warmup_threshold_ > std::numeric_limits<uint16_t>::max()) { 7183f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray LOG(FATAL) << "Method warmup threshold is above its internal limit."; 7283f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray } 7383f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray } else { 7483f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray jit_options->warmup_threshold_ = jit_options->compile_threshold_ / 2; 7583f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray } 7683f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray 7783f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray if (options.Exists(RuntimeArgumentMap::JITOsrThreshold)) { 7883f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray jit_options->osr_threshold_ = *options.Get(RuntimeArgumentMap::JITOsrThreshold); 7983f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray if (jit_options->osr_threshold_ > std::numeric_limits<uint16_t>::max()) { 8083f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray LOG(FATAL) << "Method on stack replacement threshold is above its internal limit."; 8183f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray } 8283f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray } else { 8383f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray jit_options->osr_threshold_ = jit_options->compile_threshold_ * 2; 8483f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray if (jit_options->osr_threshold_ > std::numeric_limits<uint16_t>::max()) { 8583f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray jit_options->osr_threshold_ = std::numeric_limits<uint16_t>::max(); 8683f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray } 8783f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray } 8883f080ac824d0964941c3fbaa957cac874f827b0Nicolas Geoffray 89b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle if (options.Exists(RuntimeArgumentMap::JITPriorityThreadWeight)) { 90b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle jit_options->priority_thread_weight_ = 91b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle *options.Get(RuntimeArgumentMap::JITPriorityThreadWeight); 92b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle if (jit_options->priority_thread_weight_ > jit_options->warmup_threshold_) { 93b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle LOG(FATAL) << "Priority thread weight is above the warmup threshold."; 94b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle } else if (jit_options->priority_thread_weight_ == 0) { 95b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle LOG(FATAL) << "Priority thread weight cannot be 0."; 96b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle } 97b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle } else { 98b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle jit_options->priority_thread_weight_ = 99b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle std::max(jit_options->compile_threshold_ / 2000, static_cast<size_t>(1)); 100b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle } 101b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle 102e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return jit_options; 103e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 104e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 105b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravlebool Jit::ShouldUsePriorityThreadWeight() { 106b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle // TODO(calin): verify that IsSensitiveThread covers only the cases we are interested on. 107b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle // In particular if apps can set StrictMode policies for any of their threads, case in which 108b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle // we need to find another way to track sensitive threads. 109b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle return Runtime::Current()->InJankPerceptibleProcessState() && Thread::IsSensitiveThread(); 110b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle} 111b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle 112a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartiervoid Jit::DumpInfo(std::ostream& os) { 113bcd94c8ea9bde4e075c25fbdfb3a2ef6858eed7bNicolas Geoffray code_cache_->Dump(os); 114a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier cumulative_timings_.Dump(os); 115a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffray MutexLock mu(Thread::Current(), lock_); 116a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffray memory_use_.PrintMemoryUse(os); 117a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier} 118a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier 119a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartiervoid Jit::AddTimingLogger(const TimingLogger& logger) { 120a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier cumulative_timings_.AddLogger(logger); 121a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier} 122a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier 12372918ea854d182ef25b2352bfe1c46c1e916a141Mathieu ChartierJit::Jit() : dump_info_on_shutdown_(false), 124a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray cumulative_timings_("JIT timings"), 125a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffray memory_use_("Memory used for compilation", 16), 126a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffray lock_("JIT memory use lock"), 12772918ea854d182ef25b2352bfe1c46c1e916a141Mathieu Chartier save_profiling_info_(false) {} 128e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 129e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu ChartierJit* Jit::Create(JitOptions* options, std::string* error_msg) { 130e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier std::unique_ptr<Jit> jit(new Jit); 131a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier jit->dump_info_on_shutdown_ = options->DumpJitInfoOnShutdown(); 13272918ea854d182ef25b2352bfe1c46c1e916a141Mathieu Chartier if (jit_compiler_handle_ == nullptr && !LoadCompiler(error_msg)) { 133e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return nullptr; 134e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 1350a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray jit->code_cache_.reset(JitCodeCache::Create( 136a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray options->GetCodeCacheInitialCapacity(), 137a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray options->GetCodeCacheMaxCapacity(), 138a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray jit->generate_debug_info_, 139a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray error_msg)); 140e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit->GetCodeCache() == nullptr) { 141e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return nullptr; 142e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 1434d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle jit->save_profiling_info_ = options->GetSaveProfilingInfo(); 144bcd94c8ea9bde4e075c25fbdfb3a2ef6858eed7bNicolas Geoffray VLOG(jit) << "JIT created with initial_capacity=" 1450a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray << PrettySize(options->GetCodeCacheInitialCapacity()) 1460a3be1620a3560253cfa789cb9819013293c5654Nicolas Geoffray << ", max_capacity=" << PrettySize(options->GetCodeCacheMaxCapacity()) 1474d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle << ", compile_threshold=" << options->GetCompileThreshold() 1484d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle << ", save_profiling_info=" << options->GetSaveProfilingInfo(); 149e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return jit.release(); 150e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 151e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 152c1bc4150415686e6240343c7345c49d80e351df3Mathieu Chartierbool Jit::LoadCompilerLibrary(std::string* error_msg) { 153e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier jit_library_handle_ = dlopen( 154e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier kIsDebugBuild ? "libartd-compiler.so" : "libart-compiler.so", RTLD_NOW); 155e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit_library_handle_ == nullptr) { 156e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier std::ostringstream oss; 157e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier oss << "JIT could not load libart-compiler.so: " << dlerror(); 158e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *error_msg = oss.str(); 159e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return false; 160e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 1615b82d339955d1a0dc23eeb8d2d5659459ff987baNicolas Geoffray jit_load_ = reinterpret_cast<void* (*)(bool*)>(dlsym(jit_library_handle_, "jit_load")); 162e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit_load_ == nullptr) { 163e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlclose(jit_library_handle_); 164e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *error_msg = "JIT couldn't find jit_load entry point"; 165e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return false; 166e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 167e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier jit_unload_ = reinterpret_cast<void (*)(void*)>( 168e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlsym(jit_library_handle_, "jit_unload")); 169e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit_unload_ == nullptr) { 170e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlclose(jit_library_handle_); 171e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *error_msg = "JIT couldn't find jit_unload entry point"; 172e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return false; 173e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 174b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray jit_compile_method_ = reinterpret_cast<bool (*)(void*, ArtMethod*, Thread*, bool)>( 175e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlsym(jit_library_handle_, "jit_compile_method")); 176e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit_compile_method_ == nullptr) { 177e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlclose(jit_library_handle_); 178e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *error_msg = "JIT couldn't find jit_compile_method entry point"; 179e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return false; 180e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 181fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer jit_types_loaded_ = reinterpret_cast<void (*)(void*, mirror::Class**, size_t)>( 182fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer dlsym(jit_library_handle_, "jit_types_loaded")); 183fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer if (jit_types_loaded_ == nullptr) { 184160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer dlclose(jit_library_handle_); 185fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer *error_msg = "JIT couldn't find jit_types_loaded entry point"; 186160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer return false; 187160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer } 188c1bc4150415686e6240343c7345c49d80e351df3Mathieu Chartier return true; 189c1bc4150415686e6240343c7345c49d80e351df3Mathieu Chartier} 190c1bc4150415686e6240343c7345c49d80e351df3Mathieu Chartier 191c1bc4150415686e6240343c7345c49d80e351df3Mathieu Chartierbool Jit::LoadCompiler(std::string* error_msg) { 192c1bc4150415686e6240343c7345c49d80e351df3Mathieu Chartier if (jit_library_handle_ == nullptr && !LoadCompilerLibrary(error_msg)) { 193c1bc4150415686e6240343c7345c49d80e351df3Mathieu Chartier return false; 194c1bc4150415686e6240343c7345c49d80e351df3Mathieu Chartier } 195a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray bool will_generate_debug_symbols = false; 196e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier VLOG(jit) << "Calling JitLoad interpreter_only=" 197e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier << Runtime::Current()->GetInstrumentation()->InterpretOnly(); 1985b82d339955d1a0dc23eeb8d2d5659459ff987baNicolas Geoffray jit_compiler_handle_ = (jit_load_)(&will_generate_debug_symbols); 199e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit_compiler_handle_ == nullptr) { 200e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlclose(jit_library_handle_); 201e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier *error_msg = "JIT couldn't load compiler"; 202e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return false; 203e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 204a25dce9b452ba17ef7cef768926c884177a3025eNicolas Geoffray generate_debug_info_ = will_generate_debug_symbols; 205e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier return true; 206e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 207e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 208b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffraybool Jit::CompileMethod(ArtMethod* method, Thread* self, bool osr) { 209e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier DCHECK(!method->IsRuntimeMethod()); 210d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray 21173be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray // Don't compile the method if it has breakpoints. 212d8565456d29f4ad05f11cf84d2d2dac488508e06Mathieu Chartier if (Dbg::IsDebuggerActive() && Dbg::MethodHasAnyBreakpoints(method)) { 213d8565456d29f4ad05f11cf84d2d2dac488508e06Mathieu Chartier VLOG(jit) << "JIT not compiling " << PrettyMethod(method) << " due to breakpoint"; 214d8565456d29f4ad05f11cf84d2d2dac488508e06Mathieu Chartier return false; 215d8565456d29f4ad05f11cf84d2d2dac488508e06Mathieu Chartier } 21673be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray 21773be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray // Don't compile the method if we are supposed to be deoptimized. 21873be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 21973be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray if (instrumentation->AreAllMethodsDeoptimized() || instrumentation->IsDeoptimized(method)) { 220a42363f79832a6e14f348514664dc6dc3edf9da2Nicolas Geoffray VLOG(jit) << "JIT not compiling " << PrettyMethod(method) << " due to deoptimization"; 22173be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray return false; 22273be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray } 22373be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray 224d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray // If we get a request to compile a proxy method, we pass the actual Java method 225d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray // of that proxy method, as the compiler does not expect a proxy method. 226d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray ArtMethod* method_to_compile = method->GetInterfaceMethodIfProxy(sizeof(void*)); 227d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray if (!code_cache_->NotifyCompilationOf(method_to_compile, self, osr)) { 22873be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray return false; 22973be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray } 230d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray bool success = jit_compile_method_(jit_compiler_handle_, method_to_compile, self, osr); 231454b3b6774fe07765273b917ccc97da2eba776acbuzbee code_cache_->DoneCompiling(method_to_compile, self, osr); 23273be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray return success; 233e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 234e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 235e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartiervoid Jit::CreateThreadPool() { 236e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier CHECK(instrumentation_cache_.get() != nullptr); 237e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier instrumentation_cache_->CreateThreadPool(); 238e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 239e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 240e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartiervoid Jit::DeleteThreadPool() { 241e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (instrumentation_cache_.get() != nullptr) { 242629e9350b0b72998416504f7a6fb95b6086daca8Nicolas Geoffray instrumentation_cache_->DeleteThreadPool(Thread::Current()); 243e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 244e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 245e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 2464d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravlevoid Jit::StartProfileSaver(const std::string& filename, 247c90bc92bc577020ff4d3caced4cee1cdf41fa5deCalin Juravle const std::vector<std::string>& code_paths, 248c90bc92bc577020ff4d3caced4cee1cdf41fa5deCalin Juravle const std::string& foreign_dex_profile_path, 249c90bc92bc577020ff4d3caced4cee1cdf41fa5deCalin Juravle const std::string& app_dir) { 2504d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle if (save_profiling_info_) { 251c90bc92bc577020ff4d3caced4cee1cdf41fa5deCalin Juravle ProfileSaver::Start(filename, code_cache_.get(), code_paths, foreign_dex_profile_path, app_dir); 2524d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle } 2534d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle} 2544d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle 2554d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravlevoid Jit::StopProfileSaver() { 2564d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle if (save_profiling_info_ && ProfileSaver::IsStarted()) { 2574d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle ProfileSaver::Stop(); 25831f2c155975c5794d481df03eb0947cb48d2c6b5Calin Juravle } 25931f2c155975c5794d481df03eb0947cb48d2c6b5Calin Juravle} 26031f2c155975c5794d481df03eb0947cb48d2c6b5Calin Juravle 26105d241565f36df825cf56a4f1b61bfb7e4dcb056Siva Chandrabool Jit::JitAtFirstUse() { 26205d241565f36df825cf56a4f1b61bfb7e4dcb056Siva Chandra if (instrumentation_cache_ != nullptr) { 26305d241565f36df825cf56a4f1b61bfb7e4dcb056Siva Chandra return instrumentation_cache_->HotMethodThreshold() == 0; 26405d241565f36df825cf56a4f1b61bfb7e4dcb056Siva Chandra } 26505d241565f36df825cf56a4f1b61bfb7e4dcb056Siva Chandra return false; 26605d241565f36df825cf56a4f1b61bfb7e4dcb056Siva Chandra} 26705d241565f36df825cf56a4f1b61bfb7e4dcb056Siva Chandra 26835122443e5f8606cc5a660ac32745a06aefb341bNicolas Geoffraybool Jit::CanInvokeCompiledCode(ArtMethod* method) { 26935122443e5f8606cc5a660ac32745a06aefb341bNicolas Geoffray return code_cache_->ContainsPc(method->GetEntryPointFromQuickCompiledCode()); 27035122443e5f8606cc5a660ac32745a06aefb341bNicolas Geoffray} 27135122443e5f8606cc5a660ac32745a06aefb341bNicolas Geoffray 272e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu ChartierJit::~Jit() { 2734d77b6a511659f26fdc711e23825ffa6e7feed7aCalin Juravle DCHECK(!save_profiling_info_ || !ProfileSaver::IsStarted()); 274a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier if (dump_info_on_shutdown_) { 275a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier DumpInfo(LOG(INFO)); 276a4885cbaafd35fe9c60eb6cd95e41e2c86f54f66Mathieu Chartier } 277e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier DeleteThreadPool(); 278e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit_compiler_handle_ != nullptr) { 279e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier jit_unload_(jit_compiler_handle_); 28072918ea854d182ef25b2352bfe1c46c1e916a141Mathieu Chartier jit_compiler_handle_ = nullptr; 281e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 282e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (jit_library_handle_ != nullptr) { 283e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier dlclose(jit_library_handle_); 28472918ea854d182ef25b2352bfe1c46c1e916a141Mathieu Chartier jit_library_handle_ = nullptr; 285e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 286e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 287e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 288b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffrayvoid Jit::CreateInstrumentationCache(size_t compile_threshold, 289b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray size_t warmup_threshold, 290b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle size_t osr_threshold, 291b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle uint16_t priority_thread_weight) { 2925550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray instrumentation_cache_.reset( 293b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle new jit::JitInstrumentationCache(compile_threshold, 294b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle warmup_threshold, 295b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle osr_threshold, 296b2771b41a956b50266d4d83fbb067f99faf7b7dcCalin Juravle priority_thread_weight)); 297e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} 298e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier 299160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammervoid Jit::NewTypeLoadedIfUsingJit(mirror::Class* type) { 300160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer jit::Jit* jit = Runtime::Current()->GetJit(); 301160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer if (jit != nullptr && jit->generate_debug_info_) { 302fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer DCHECK(jit->jit_types_loaded_ != nullptr); 303fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer jit->jit_types_loaded_(jit->jit_compiler_handle_, &type, 1); 304fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer } 305fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer} 306fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer 307fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammervoid Jit::DumpTypeInfoForLoadedTypes(ClassLinker* linker) { 308fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer struct CollectClasses : public ClassVisitor { 3091aa8ec2ccdd7bedb6d30d91c89f1e94ab23c4439Mathieu Chartier bool operator()(mirror::Class* klass) override { 310fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer classes_.push_back(klass); 311fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer return true; 312fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer } 3139b1c9b761dea9bc48a2994e3d4de46fc10343a25Mathieu Chartier std::vector<mirror::Class*> classes_; 314fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer }; 315fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer 316fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer if (generate_debug_info_) { 317fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer ScopedObjectAccess so(Thread::Current()); 318fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer 319fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer CollectClasses visitor; 320fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer linker->VisitClasses(&visitor); 321fffbee4d158259633ec7b7f712eaf75be86bd4e5Tamas Berghammer jit_types_loaded_(jit_compiler_handle_, visitor.classes_.data(), visitor.classes_.size()); 322160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer } 323160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer} 324160e6df5debaf77223eebddb8a4e3f7c5e729ad0Tamas Berghammer 325b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffrayextern "C" void art_quick_osr_stub(void** stack, 326b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray uint32_t stack_size_in_bytes, 327b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray const uint8_t* native_pc, 328b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray JValue* result, 329b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray const char* shorty, 330b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray Thread* self); 331b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 332b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffraybool Jit::MaybeDoOnStackReplacement(Thread* thread, 333b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray ArtMethod* method, 334b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray uint32_t dex_pc, 335b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray int32_t dex_pc_offset, 336b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray JValue* result) { 337e86621386d18a3a7178af6cfc2c05d1b34c3b995Nicolas Geoffray if (!kEnableOnStackReplacement) { 338e86621386d18a3a7178af6cfc2c05d1b34c3b995Nicolas Geoffray return false; 339e86621386d18a3a7178af6cfc2c05d1b34c3b995Nicolas Geoffray } 340e86621386d18a3a7178af6cfc2c05d1b34c3b995Nicolas Geoffray 341b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray Jit* jit = Runtime::Current()->GetJit(); 342b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray if (jit == nullptr) { 343b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray return false; 344b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 345b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 346b88d59ef4fe611fe47e50a6a19785e03bbd5f93bNicolas Geoffray if (UNLIKELY(__builtin_frame_address(0) < thread->GetStackEnd())) { 347b88d59ef4fe611fe47e50a6a19785e03bbd5f93bNicolas Geoffray // Don't attempt to do an OSR if we are close to the stack limit. Since 348b88d59ef4fe611fe47e50a6a19785e03bbd5f93bNicolas Geoffray // the interpreter frames are still on stack, OSR has the potential 349b88d59ef4fe611fe47e50a6a19785e03bbd5f93bNicolas Geoffray // to stack overflow even for a simple loop. 350b88d59ef4fe611fe47e50a6a19785e03bbd5f93bNicolas Geoffray // b/27094810. 351b88d59ef4fe611fe47e50a6a19785e03bbd5f93bNicolas Geoffray return false; 352b88d59ef4fe611fe47e50a6a19785e03bbd5f93bNicolas Geoffray } 353b88d59ef4fe611fe47e50a6a19785e03bbd5f93bNicolas Geoffray 354d9bc433a89c41a255d1b669d075f802597839bdcNicolas Geoffray // Get the actual Java method if this method is from a proxy class. The compiler 355d9bc433a89c41a255d1b669d075f802597839bdcNicolas Geoffray // and the JIT code cache do not expect methods from proxy classes. 356d9bc433a89c41a255d1b669d075f802597839bdcNicolas Geoffray method = method->GetInterfaceMethodIfProxy(sizeof(void*)); 357d9bc433a89c41a255d1b669d075f802597839bdcNicolas Geoffray 358b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // Cheap check if the method has been compiled already. That's an indicator that we should 359b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // osr into it. 360b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray if (!jit->GetCodeCache()->ContainsPc(method->GetEntryPointFromQuickCompiledCode())) { 361b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray return false; 362b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 363b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 364c0b2796ec2056a6ea15c67df1251db250ba7e9a2Nicolas Geoffray // Fetch some data before looking up for an OSR method. We don't want thread 365c0b2796ec2056a6ea15c67df1251db250ba7e9a2Nicolas Geoffray // suspension once we hold an OSR method, as the JIT code cache could delete the OSR 366c0b2796ec2056a6ea15c67df1251db250ba7e9a2Nicolas Geoffray // method while we are being suspended. 367b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray const size_t number_of_vregs = method->GetCodeItem()->registers_size_; 368d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray const char* shorty = method->GetShorty(); 369d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray std::string method_name(VLOG_IS_ON(jit) ? PrettyMethod(method) : ""); 370d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray void** memory = nullptr; 371d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray size_t frame_size = 0; 372d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray ShadowFrame* shadow_frame = nullptr; 373d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray const uint8_t* native_pc = nullptr; 374b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 375d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray { 376d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray ScopedAssertNoThreadSuspension sts(thread, "Holding OSR method"); 377d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray const OatQuickMethodHeader* osr_method = jit->GetCodeCache()->LookupOsrMethodHeader(method); 378d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray if (osr_method == nullptr) { 379d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray // No osr method yet, just return to the interpreter. 380d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray return false; 381d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray } 382b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 383d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray CodeInfo code_info = osr_method->GetOptimizedCodeInfo(); 38409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky CodeInfoEncoding encoding = code_info.ExtractEncoding(); 385b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 386d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray // Find stack map starting at the target dex_pc. 387d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray StackMap stack_map = code_info.GetOsrStackMapForDexPc(dex_pc + dex_pc_offset, encoding); 388d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray if (!stack_map.IsValid()) { 389d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray // There is no OSR stack map for this dex pc offset. Just return to the interpreter in the 390d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray // hope that the next branch has one. 391d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray return false; 392d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray } 393b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 394d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray // We found a stack map, now fill the frame with dex register values from the interpreter's 395d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray // shadow frame. 396d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray DexRegisterMap vreg_map = 397d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_vregs); 398d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray 399d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray frame_size = osr_method->GetFrameSizeInBytes(); 400d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray 401d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray // Allocate memory to put shadow frame values. The osr stub will copy that memory to 402d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray // stack. 403d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray // Note that we could pass the shadow frame to the stub, and let it copy the values there, 404d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray // but that is engineering complexity not worth the effort for something like OSR. 405d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray memory = reinterpret_cast<void**>(malloc(frame_size)); 406d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray CHECK(memory != nullptr); 407d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray memset(memory, 0, frame_size); 408d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray 409d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray // Art ABI: ArtMethod is at the bottom of the stack. 410d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray memory[0] = method; 411d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray 412d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray shadow_frame = thread->PopShadowFrame(); 413d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray if (!vreg_map.IsValid()) { 414d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray // If we don't have a dex register map, then there are no live dex registers at 415d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray // this dex pc. 416d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray } else { 417d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray for (uint16_t vreg = 0; vreg < number_of_vregs; ++vreg) { 418d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray DexRegisterLocation::Kind location = 419d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray vreg_map.GetLocationKind(vreg, number_of_vregs, code_info, encoding); 420d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray if (location == DexRegisterLocation::Kind::kNone) { 421c0b2796ec2056a6ea15c67df1251db250ba7e9a2Nicolas Geoffray // Dex register is dead or uninitialized. 422d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray continue; 423d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray } 424d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray 425d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray if (location == DexRegisterLocation::Kind::kConstant) { 426d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray // We skip constants because the compiled code knows how to handle them. 427d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray continue; 428d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray } 429d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray 4307dc11782ff0a5dffcd8108f256f8975f0b3e8076David Srbecky DCHECK_EQ(location, DexRegisterLocation::Kind::kInStack); 431d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray 432d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray int32_t vreg_value = shadow_frame->GetVReg(vreg); 433d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray int32_t slot_offset = vreg_map.GetStackOffsetInBytes(vreg, 434d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray number_of_vregs, 435d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray code_info, 436d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray encoding); 437d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray DCHECK_LT(slot_offset, static_cast<int32_t>(frame_size)); 438d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray DCHECK_GT(slot_offset, 0); 439d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray (reinterpret_cast<int32_t*>(memory))[slot_offset / sizeof(int32_t)] = vreg_value; 440d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray } 441b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 442d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray 44309ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky native_pc = stack_map.GetNativePcOffset(encoding.stack_map_encoding) + 44409ed09866da6d8c7448ef297c148bfa577a247c2David Srbecky osr_method->GetEntryPoint(); 445d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray VLOG(jit) << "Jumping to " 446d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray << method_name 447d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray << "@" 448d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray << std::hex << reinterpret_cast<uintptr_t>(native_pc); 449b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 450b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 451b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray { 452b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray ManagedStack fragment; 453b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray thread->PushManagedStackFragment(&fragment); 454b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray (*art_quick_osr_stub)(memory, 455b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray frame_size, 456b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray native_pc, 457b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray result, 458d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray shorty, 459b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray thread); 460d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray 461b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray if (UNLIKELY(thread->GetException() == Thread::GetDeoptimizationException())) { 462b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray thread->DeoptimizeWithDeoptimizationException(result); 463b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 464b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray thread->PopManagedStackFragment(fragment); 465b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray } 466b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray free(memory); 467b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray thread->PushShadowFrame(shadow_frame); 468d186dd8ecb1f25d3786d6b27adcd6b0b9ca04ea0Nicolas Geoffray VLOG(jit) << "Done running OSR code for " << method_name; 469b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray return true; 470b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray} 471b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 472a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffrayvoid Jit::AddMemoryUsage(ArtMethod* method, size_t bytes) { 473a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffray if (bytes > 4 * MB) { 474a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffray LOG(INFO) << "Compiler allocated " 475a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffray << PrettySize(bytes) 476a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffray << " to compile " 477a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffray << PrettyMethod(method); 478a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffray } 479a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffray MutexLock mu(Thread::Current(), lock_); 480a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffray memory_use_.AddValue(bytes); 481a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffray} 482a4f81546373f4cb5fa6dfc135307ee0a1d930872Nicolas Geoffray 483e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} // namespace jit 484e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier} // namespace art 485