Home | History | Annotate | Download | only in jit
      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 
     60   uint16_t GetCompileThreshold() const {
     61     return compile_threshold_;
     62   }
     63 
     64   uint16_t GetWarmupThreshold() const {
     65     return warmup_threshold_;
     66   }
     67 
     68   uint16_t GetOsrThreshold() const {
     69     return osr_threshold_;
     70   }
     71 
     72   uint16_t GetPriorityThreadWeight() const {
     73     return priority_thread_weight_;
     74   }
     75 
     76   uint16_t GetInvokeTransitionWeight() const {
     77     return invoke_transition_weight_;
     78   }
     79 
     80   size_t GetCodeCacheInitialCapacity() const {
     81     return code_cache_initial_capacity_;
     82   }
     83 
     84   size_t GetCodeCacheMaxCapacity() const {
     85     return code_cache_max_capacity_;
     86   }
     87 
     88   bool DumpJitInfoOnShutdown() const {
     89     return dump_info_on_shutdown_;
     90   }
     91 
     92   const ProfileSaverOptions& GetProfileSaverOptions() const {
     93     return profile_saver_options_;
     94   }
     95 
     96   bool GetSaveProfilingInfo() const {
     97     return profile_saver_options_.IsEnabled();
     98   }
     99 
    100   int GetThreadPoolPthreadPriority() const {
    101     return thread_pool_pthread_priority_;
    102   }
    103 
    104   bool UseJitCompilation() const {
    105     return use_jit_compilation_;
    106   }
    107 
    108   void SetUseJitCompilation(bool b) {
    109     use_jit_compilation_ = b;
    110   }
    111 
    112   void SetSaveProfilingInfo(bool save_profiling_info) {
    113     profile_saver_options_.SetEnabled(save_profiling_info);
    114   }
    115 
    116   void SetWaitForJitNotificationsToSaveProfile(bool value) {
    117     profile_saver_options_.SetWaitForJitNotificationsToSave(value);
    118   }
    119 
    120   void SetProfileAOTCode(bool value) {
    121     profile_saver_options_.SetProfileAOTCode(value);
    122   }
    123 
    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 
    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 
    176   const JitCodeCache* GetCodeCache() const {
    177     return code_cache_;
    178   }
    179 
    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 
    198   uint16_t OSRMethodThreshold() const {
    199     return options_->GetOsrThreshold();
    200   }
    201 
    202   uint16_t HotMethodThreshold() const {
    203     return options_->GetCompileThreshold();
    204   }
    205 
    206   uint16_t WarmMethodThreshold() const {
    207     return options_->GetWarmupThreshold();
    208   }
    209 
    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.
    215   bool UseJitCompilation() const {
    216     return options_->UseJitCompilation();
    217   }
    218 
    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 
    242   void NotifyInterpreterToCompiledCodeTransition(Thread* self, ArtMethod* caller)
    243       REQUIRES_SHARED(Locks::mutator_lock_) {
    244     AddSamples(self, caller, options_->GetInvokeTransitionWeight(), false);
    245   }
    246 
    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 
    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