1 /* 2 * Copyright 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_JIT_JIT_H_ 18 #define ART_RUNTIME_JIT_JIT_H_ 19 20 #include "base/histogram-inl.h" 21 #include "base/macros.h" 22 #include "base/mutex.h" 23 #include "base/timing_logger.h" 24 #include "handle.h" 25 #include "jit/profile_saver_options.h" 26 #include "obj_ptr.h" 27 #include "thread_pool.h" 28 29 namespace art { 30 31 class ArtMethod; 32 class ClassLinker; 33 class DexFile; 34 class OatDexFile; 35 struct RuntimeArgumentMap; 36 union JValue; 37 38 namespace mirror { 39 class Object; 40 class Class; 41 class ClassLoader; 42 } // namespace mirror 43 44 namespace jit { 45 46 class JitCodeCache; 47 class JitOptions; 48 49 static constexpr int16_t kJitCheckForOSR = -1; 50 static constexpr int16_t kJitHotnessDisabled = -2; 51 // At what priority to schedule jit threads. 9 is the lowest foreground priority on device. 52 // See android/os/Process.java. 53 static constexpr int kJitPoolThreadPthreadDefaultPriority = 9; 54 static constexpr uint32_t kJitSamplesBatchSize = 32; // Must be power of 2. 55 56 class JitOptions { 57 public: 58 static JitOptions* CreateFromRuntimeArguments(const RuntimeArgumentMap& options); 59 GetCompileThreshold()60 uint16_t GetCompileThreshold() const { 61 return compile_threshold_; 62 } 63 GetWarmupThreshold()64 uint16_t GetWarmupThreshold() const { 65 return warmup_threshold_; 66 } 67 GetOsrThreshold()68 uint16_t GetOsrThreshold() const { 69 return osr_threshold_; 70 } 71 GetPriorityThreadWeight()72 uint16_t GetPriorityThreadWeight() const { 73 return priority_thread_weight_; 74 } 75 GetInvokeTransitionWeight()76 uint16_t GetInvokeTransitionWeight() const { 77 return invoke_transition_weight_; 78 } 79 GetCodeCacheInitialCapacity()80 size_t GetCodeCacheInitialCapacity() const { 81 return code_cache_initial_capacity_; 82 } 83 GetCodeCacheMaxCapacity()84 size_t GetCodeCacheMaxCapacity() const { 85 return code_cache_max_capacity_; 86 } 87 DumpJitInfoOnShutdown()88 bool DumpJitInfoOnShutdown() const { 89 return dump_info_on_shutdown_; 90 } 91 GetProfileSaverOptions()92 const ProfileSaverOptions& GetProfileSaverOptions() const { 93 return profile_saver_options_; 94 } 95 GetSaveProfilingInfo()96 bool GetSaveProfilingInfo() const { 97 return profile_saver_options_.IsEnabled(); 98 } 99 GetThreadPoolPthreadPriority()100 int GetThreadPoolPthreadPriority() const { 101 return thread_pool_pthread_priority_; 102 } 103 UseJitCompilation()104 bool UseJitCompilation() const { 105 return use_jit_compilation_; 106 } 107 SetUseJitCompilation(bool b)108 void SetUseJitCompilation(bool b) { 109 use_jit_compilation_ = b; 110 } 111 SetSaveProfilingInfo(bool save_profiling_info)112 void SetSaveProfilingInfo(bool save_profiling_info) { 113 profile_saver_options_.SetEnabled(save_profiling_info); 114 } 115 SetWaitForJitNotificationsToSaveProfile(bool value)116 void SetWaitForJitNotificationsToSaveProfile(bool value) { 117 profile_saver_options_.SetWaitForJitNotificationsToSave(value); 118 } 119 SetProfileAOTCode(bool value)120 void SetProfileAOTCode(bool value) { 121 profile_saver_options_.SetProfileAOTCode(value); 122 } 123 SetJitAtFirstUse()124 void SetJitAtFirstUse() { 125 use_jit_compilation_ = true; 126 compile_threshold_ = 0; 127 } 128 129 private: 130 // We add the sample in batches of size kJitSamplesBatchSize. 131 // This method rounds the threshold so that it is multiple of the batch size. 132 static uint32_t RoundUpThreshold(uint32_t threshold); 133 134 bool use_jit_compilation_; 135 size_t code_cache_initial_capacity_; 136 size_t code_cache_max_capacity_; 137 uint32_t compile_threshold_; 138 uint32_t warmup_threshold_; 139 uint32_t osr_threshold_; 140 uint16_t priority_thread_weight_; 141 uint16_t invoke_transition_weight_; 142 bool dump_info_on_shutdown_; 143 int thread_pool_pthread_priority_; 144 ProfileSaverOptions profile_saver_options_; 145 JitOptions()146 JitOptions() 147 : use_jit_compilation_(false), 148 code_cache_initial_capacity_(0), 149 code_cache_max_capacity_(0), 150 compile_threshold_(0), 151 warmup_threshold_(0), 152 osr_threshold_(0), 153 priority_thread_weight_(0), 154 invoke_transition_weight_(0), 155 dump_info_on_shutdown_(false), 156 thread_pool_pthread_priority_(kJitPoolThreadPthreadDefaultPriority) {} 157 158 DISALLOW_COPY_AND_ASSIGN(JitOptions); 159 }; 160 161 class Jit { 162 public: 163 static constexpr size_t kDefaultPriorityThreadWeightRatio = 1000; 164 static constexpr size_t kDefaultInvokeTransitionWeightRatio = 500; 165 // How frequently should the interpreter check to see if OSR compilation is ready. 166 static constexpr int16_t kJitRecheckOSRThreshold = 101; // Prime number to avoid patterns. 167 168 virtual ~Jit(); 169 170 // Create JIT itself. 171 static Jit* Create(JitCodeCache* code_cache, JitOptions* options); 172 173 bool CompileMethod(ArtMethod* method, Thread* self, bool baseline, bool osr) 174 REQUIRES_SHARED(Locks::mutator_lock_); 175 GetCodeCache()176 const JitCodeCache* GetCodeCache() const { 177 return code_cache_; 178 } 179 GetCodeCache()180 JitCodeCache* GetCodeCache() { 181 return code_cache_; 182 } 183 184 void CreateThreadPool(); 185 void DeleteThreadPool(); 186 void WaitForWorkersToBeCreated(); 187 188 // Dump interesting info: #methods compiled, code vs data size, compile / verify cumulative 189 // loggers. 190 void DumpInfo(std::ostream& os) REQUIRES(!lock_); 191 // Add a timing logger to cumulative_timings_. 192 void AddTimingLogger(const TimingLogger& logger); 193 194 void AddMemoryUsage(ArtMethod* method, size_t bytes) 195 REQUIRES(!lock_) 196 REQUIRES_SHARED(Locks::mutator_lock_); 197 OSRMethodThreshold()198 uint16_t OSRMethodThreshold() const { 199 return options_->GetOsrThreshold(); 200 } 201 HotMethodThreshold()202 uint16_t HotMethodThreshold() const { 203 return options_->GetCompileThreshold(); 204 } 205 WarmMethodThreshold()206 uint16_t WarmMethodThreshold() const { 207 return options_->GetWarmupThreshold(); 208 } 209 PriorityThreadWeight()210 uint16_t PriorityThreadWeight() const { 211 return options_->GetPriorityThreadWeight(); 212 } 213 214 // Returns false if we only need to save profile information and not compile methods. UseJitCompilation()215 bool UseJitCompilation() const { 216 return options_->UseJitCompilation(); 217 } 218 GetSaveProfilingInfo()219 bool GetSaveProfilingInfo() const { 220 return options_->GetSaveProfilingInfo(); 221 } 222 223 // Wait until there is no more pending compilation tasks. 224 void WaitForCompilationToFinish(Thread* self); 225 226 // Profiling methods. 227 void MethodEntered(Thread* thread, ArtMethod* method) 228 REQUIRES_SHARED(Locks::mutator_lock_); 229 230 ALWAYS_INLINE void AddSamples(Thread* self, 231 ArtMethod* method, 232 uint16_t samples, 233 bool with_backedges) 234 REQUIRES_SHARED(Locks::mutator_lock_); 235 236 void InvokeVirtualOrInterface(ObjPtr<mirror::Object> this_object, 237 ArtMethod* caller, 238 uint32_t dex_pc, 239 ArtMethod* callee) 240 REQUIRES_SHARED(Locks::mutator_lock_); 241 NotifyInterpreterToCompiledCodeTransition(Thread * self,ArtMethod * caller)242 void NotifyInterpreterToCompiledCodeTransition(Thread* self, ArtMethod* caller) 243 REQUIRES_SHARED(Locks::mutator_lock_) { 244 AddSamples(self, caller, options_->GetInvokeTransitionWeight(), false); 245 } 246 NotifyCompiledCodeToInterpreterTransition(Thread * self,ArtMethod * callee)247 void NotifyCompiledCodeToInterpreterTransition(Thread* self, ArtMethod* callee) 248 REQUIRES_SHARED(Locks::mutator_lock_) { 249 AddSamples(self, callee, options_->GetInvokeTransitionWeight(), false); 250 } 251 252 // Starts the profile saver if the config options allow profile recording. 253 // The profile will be stored in the specified `filename` and will contain 254 // information collected from the given `code_paths` (a set of dex locations). 255 void StartProfileSaver(const std::string& filename, 256 const std::vector<std::string>& code_paths); 257 void StopProfileSaver(); 258 259 void DumpForSigQuit(std::ostream& os) REQUIRES(!lock_); 260 261 static void NewTypeLoadedIfUsingJit(mirror::Class* type) 262 REQUIRES_SHARED(Locks::mutator_lock_); 263 264 // If debug info generation is turned on then write the type information for types already loaded 265 // into the specified class linker to the jit debug interface, 266 void DumpTypeInfoForLoadedTypes(ClassLinker* linker); 267 268 // Return whether we should try to JIT compiled code as soon as an ArtMethod is invoked. 269 bool JitAtFirstUse(); 270 271 // Return whether we can invoke JIT code for `method`. 272 bool CanInvokeCompiledCode(ArtMethod* method); 273 274 // Return whether the runtime should use a priority thread weight when sampling. 275 static bool ShouldUsePriorityThreadWeight(Thread* self); 276 277 // If an OSR compiled version is available for `method`, 278 // and `dex_pc + dex_pc_offset` is an entry point of that compiled 279 // version, this method will jump to the compiled code, let it run, 280 // and return true afterwards. Return false otherwise. 281 static bool MaybeDoOnStackReplacement(Thread* thread, 282 ArtMethod* method, 283 uint32_t dex_pc, 284 int32_t dex_pc_offset, 285 JValue* result) 286 REQUIRES_SHARED(Locks::mutator_lock_); 287 288 // Load the compiler library. 289 static bool LoadCompilerLibrary(std::string* error_msg); 290 GetThreadPool()291 ThreadPool* GetThreadPool() const { 292 return thread_pool_.get(); 293 } 294 295 // Stop the JIT by waiting for all current compilations and enqueued compilations to finish. 296 void Stop(); 297 298 // Start JIT threads. 299 void Start(); 300 301 // Transition to a child state. 302 void PostForkChildAction(bool is_system_server, bool is_zygote); 303 304 // Prepare for forking. 305 void PreZygoteFork(); 306 307 // Adjust state after forking. 308 void PostZygoteFork(); 309 310 // Compile methods from the given profile. If `add_to_queue` is true, methods 311 // in the profile are added to the JIT queue. Otherwise they are compiled 312 // directly. 313 void CompileMethodsFromProfile(Thread* self, 314 const std::vector<const DexFile*>& dex_files, 315 const std::string& profile_path, 316 Handle<mirror::ClassLoader> class_loader, 317 bool add_to_queue); 318 319 // Register the dex files to the JIT. This is to perform any compilation/optimization 320 // at the point of loading the dex files. 321 void RegisterDexFiles(const std::vector<std::unique_ptr<const DexFile>>& dex_files, 322 ObjPtr<mirror::ClassLoader> class_loader); 323 324 private: 325 Jit(JitCodeCache* code_cache, JitOptions* options); 326 327 // Compile the method if the number of samples passes a threshold. 328 // Returns false if we can not compile now - don't increment the counter and retry later. 329 bool MaybeCompileMethod(Thread* self, 330 ArtMethod* method, 331 uint32_t old_count, 332 uint32_t new_count, 333 bool with_backedges) 334 REQUIRES_SHARED(Locks::mutator_lock_); 335 336 static bool BindCompilerMethods(std::string* error_msg); 337 338 // JIT compiler 339 static void* jit_library_handle_; 340 static void* jit_compiler_handle_; 341 static void* (*jit_load_)(void); 342 static void (*jit_unload_)(void*); 343 static bool (*jit_compile_method_)(void*, ArtMethod*, Thread*, bool, bool); 344 static void (*jit_types_loaded_)(void*, mirror::Class**, size_t count); 345 static void (*jit_update_options_)(void*); 346 static bool (*jit_generate_debug_info_)(void*); 347 template <typename T> static bool LoadSymbol(T*, const char* symbol, std::string* error_msg); 348 349 // JIT resources owned by runtime. 350 jit::JitCodeCache* const code_cache_; 351 const JitOptions* const options_; 352 353 std::unique_ptr<ThreadPool> thread_pool_; 354 std::vector<std::unique_ptr<OatDexFile>> type_lookup_tables_; 355 356 // Performance monitoring. 357 CumulativeLogger cumulative_timings_; 358 Histogram<uint64_t> memory_use_ GUARDED_BY(lock_); 359 Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 360 361 DISALLOW_COPY_AND_ASSIGN(Jit); 362 }; 363 364 // Helper class to stop the JIT for a given scope. This will wait for the JIT to quiesce. 365 class ScopedJitSuspend { 366 public: 367 ScopedJitSuspend(); 368 ~ScopedJitSuspend(); 369 370 private: 371 bool was_on_; 372 }; 373 374 } // namespace jit 375 } // namespace art 376 377 #endif // ART_RUNTIME_JIT_JIT_H_ 378