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/arena_allocator.h"
     21 #include "base/histogram-inl.h"
     22 #include "base/macros.h"
     23 #include "base/mutex.h"
     24 #include "base/timing_logger.h"
     25 #include "object_callbacks.h"
     26 #include "offline_profiling_info.h"
     27 #include "thread_pool.h"
     28 
     29 namespace art {
     30 
     31 class ArtMethod;
     32 struct RuntimeArgumentMap;
     33 
     34 namespace jit {
     35 
     36 class JitCodeCache;
     37 class JitOptions;
     38 
     39 static constexpr int16_t kJitCheckForOSR = -1;
     40 static constexpr int16_t kJitHotnessDisabled = -2;
     41 
     42 class Jit {
     43  public:
     44   static constexpr bool kStressMode = kIsDebugBuild;
     45   static constexpr size_t kDefaultCompileThreshold = kStressMode ? 2 : 10000;
     46   static constexpr size_t kDefaultPriorityThreadWeightRatio = 1000;
     47   static constexpr size_t kDefaultInvokeTransitionWeightRatio = 500;
     48 
     49   virtual ~Jit();
     50   static Jit* Create(JitOptions* options, std::string* error_msg);
     51   bool CompileMethod(ArtMethod* method, Thread* self, bool osr)
     52       SHARED_REQUIRES(Locks::mutator_lock_);
     53   void CreateThreadPool();
     54 
     55   const JitCodeCache* GetCodeCache() const {
     56     return code_cache_.get();
     57   }
     58 
     59   JitCodeCache* GetCodeCache() {
     60     return code_cache_.get();
     61   }
     62 
     63   void DeleteThreadPool();
     64   // Dump interesting info: #methods compiled, code vs data size, compile / verify cumulative
     65   // loggers.
     66   void DumpInfo(std::ostream& os) REQUIRES(!lock_);
     67   // Add a timing logger to cumulative_timings_.
     68   void AddTimingLogger(const TimingLogger& logger);
     69 
     70   void AddMemoryUsage(ArtMethod* method, size_t bytes)
     71       REQUIRES(!lock_)
     72       SHARED_REQUIRES(Locks::mutator_lock_);
     73 
     74   size_t OSRMethodThreshold() const {
     75     return osr_method_threshold_;
     76   }
     77 
     78   size_t HotMethodThreshold() const {
     79     return hot_method_threshold_;
     80   }
     81 
     82   size_t WarmMethodThreshold() const {
     83     return warm_method_threshold_;
     84   }
     85 
     86   uint16_t PriorityThreadWeight() const {
     87     return priority_thread_weight_;
     88   }
     89 
     90   // Returns false if we only need to save profile information and not compile methods.
     91   bool UseJitCompilation() const {
     92     return use_jit_compilation_;
     93   }
     94 
     95   bool SaveProfilingInfo() const {
     96     return save_profiling_info_;
     97   }
     98 
     99   // Wait until there is no more pending compilation tasks.
    100   void WaitForCompilationToFinish(Thread* self);
    101 
    102   // Profiling methods.
    103   void MethodEntered(Thread* thread, ArtMethod* method)
    104       SHARED_REQUIRES(Locks::mutator_lock_);
    105 
    106   void AddSamples(Thread* self, ArtMethod* method, uint16_t samples, bool with_backedges)
    107       SHARED_REQUIRES(Locks::mutator_lock_);
    108 
    109   void InvokeVirtualOrInterface(Thread* thread,
    110                                 mirror::Object* this_object,
    111                                 ArtMethod* caller,
    112                                 uint32_t dex_pc,
    113                                 ArtMethod* callee)
    114       SHARED_REQUIRES(Locks::mutator_lock_);
    115 
    116   void NotifyInterpreterToCompiledCodeTransition(Thread* self, ArtMethod* caller)
    117       SHARED_REQUIRES(Locks::mutator_lock_) {
    118     AddSamples(self, caller, invoke_transition_weight_, false);
    119   }
    120 
    121   void NotifyCompiledCodeToInterpreterTransition(Thread* self, ArtMethod* callee)
    122       SHARED_REQUIRES(Locks::mutator_lock_) {
    123     AddSamples(self, callee, invoke_transition_weight_, false);
    124   }
    125 
    126   // Starts the profile saver if the config options allow profile recording.
    127   // The profile will be stored in the specified `filename` and will contain
    128   // information collected from the given `code_paths` (a set of dex locations).
    129   // The `foreign_dex_profile_path` is the path where the saver will put the
    130   // profile markers for loaded dex files which are not owned by the application.
    131   // The `app_dir` is the application directory and is used to decide which
    132   // dex files belong to the application.
    133   void StartProfileSaver(const std::string& filename,
    134                          const std::vector<std::string>& code_paths,
    135                          const std::string& foreign_dex_profile_path,
    136                          const std::string& app_dir);
    137   void StopProfileSaver();
    138 
    139   void DumpForSigQuit(std::ostream& os) REQUIRES(!lock_);
    140 
    141   static void NewTypeLoadedIfUsingJit(mirror::Class* type)
    142       SHARED_REQUIRES(Locks::mutator_lock_);
    143 
    144   // If debug info generation is turned on then write the type information for types already loaded
    145   // into the specified class linker to the jit debug interface,
    146   void DumpTypeInfoForLoadedTypes(ClassLinker* linker);
    147 
    148   // Return whether we should try to JIT compiled code as soon as an ArtMethod is invoked.
    149   bool JitAtFirstUse();
    150 
    151   // Return whether we can invoke JIT code for `method`.
    152   bool CanInvokeCompiledCode(ArtMethod* method);
    153 
    154   // Return whether the runtime should use a priority thread weight when sampling.
    155   static bool ShouldUsePriorityThreadWeight();
    156 
    157   // If an OSR compiled version is available for `method`,
    158   // and `dex_pc + dex_pc_offset` is an entry point of that compiled
    159   // version, this method will jump to the compiled code, let it run,
    160   // and return true afterwards. Return false otherwise.
    161   static bool MaybeDoOnStackReplacement(Thread* thread,
    162                                         ArtMethod* method,
    163                                         uint32_t dex_pc,
    164                                         int32_t dex_pc_offset,
    165                                         JValue* result)
    166       SHARED_REQUIRES(Locks::mutator_lock_);
    167 
    168   static bool LoadCompilerLibrary(std::string* error_msg);
    169 
    170  private:
    171   Jit();
    172 
    173   static bool LoadCompiler(std::string* error_msg);
    174 
    175   // JIT compiler
    176   static void* jit_library_handle_;
    177   static void* jit_compiler_handle_;
    178   static void* (*jit_load_)(bool*);
    179   static void (*jit_unload_)(void*);
    180   static bool (*jit_compile_method_)(void*, ArtMethod*, Thread*, bool);
    181   static void (*jit_types_loaded_)(void*, mirror::Class**, size_t count);
    182 
    183   // Performance monitoring.
    184   bool dump_info_on_shutdown_;
    185   CumulativeLogger cumulative_timings_;
    186   Histogram<uint64_t> memory_use_ GUARDED_BY(lock_);
    187   Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
    188 
    189   std::unique_ptr<jit::JitCodeCache> code_cache_;
    190 
    191   bool use_jit_compilation_;
    192   bool save_profiling_info_;
    193   static bool generate_debug_info_;
    194   uint16_t hot_method_threshold_;
    195   uint16_t warm_method_threshold_;
    196   uint16_t osr_method_threshold_;
    197   uint16_t priority_thread_weight_;
    198   uint16_t invoke_transition_weight_;
    199   std::unique_ptr<ThreadPool> thread_pool_;
    200 
    201   DISALLOW_COPY_AND_ASSIGN(Jit);
    202 };
    203 
    204 class JitOptions {
    205  public:
    206   static JitOptions* CreateFromRuntimeArguments(const RuntimeArgumentMap& options);
    207   size_t GetCompileThreshold() const {
    208     return compile_threshold_;
    209   }
    210   size_t GetWarmupThreshold() const {
    211     return warmup_threshold_;
    212   }
    213   size_t GetOsrThreshold() const {
    214     return osr_threshold_;
    215   }
    216   uint16_t GetPriorityThreadWeight() const {
    217     return priority_thread_weight_;
    218   }
    219   size_t GetInvokeTransitionWeight() const {
    220     return invoke_transition_weight_;
    221   }
    222   size_t GetCodeCacheInitialCapacity() const {
    223     return code_cache_initial_capacity_;
    224   }
    225   size_t GetCodeCacheMaxCapacity() const {
    226     return code_cache_max_capacity_;
    227   }
    228   bool DumpJitInfoOnShutdown() const {
    229     return dump_info_on_shutdown_;
    230   }
    231   bool GetSaveProfilingInfo() const {
    232     return save_profiling_info_;
    233   }
    234   bool UseJitCompilation() const {
    235     return use_jit_compilation_;
    236   }
    237   void SetUseJitCompilation(bool b) {
    238     use_jit_compilation_ = b;
    239   }
    240   void SetSaveProfilingInfo(bool b) {
    241     save_profiling_info_ = b;
    242   }
    243   void SetJitAtFirstUse() {
    244     use_jit_compilation_ = true;
    245     compile_threshold_ = 0;
    246   }
    247 
    248  private:
    249   bool use_jit_compilation_;
    250   size_t code_cache_initial_capacity_;
    251   size_t code_cache_max_capacity_;
    252   size_t compile_threshold_;
    253   size_t warmup_threshold_;
    254   size_t osr_threshold_;
    255   uint16_t priority_thread_weight_;
    256   size_t invoke_transition_weight_;
    257   bool dump_info_on_shutdown_;
    258   bool save_profiling_info_;
    259 
    260   JitOptions()
    261       : use_jit_compilation_(false),
    262         code_cache_initial_capacity_(0),
    263         code_cache_max_capacity_(0),
    264         compile_threshold_(0),
    265         dump_info_on_shutdown_(false),
    266         save_profiling_info_(false) { }
    267 
    268   DISALLOW_COPY_AND_ASSIGN(JitOptions);
    269 };
    270 
    271 }  // namespace jit
    272 }  // namespace art
    273 
    274 #endif  // ART_RUNTIME_JIT_JIT_H_
    275