blob: 417a1858535eb9d25da8cc5b87dd40d5b5147419 [file] [log] [blame]
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001/*
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
Nicolas Geoffraya4f81542016-03-08 16:57:48 +000020#include "base/arena_allocator.h"
21#include "base/histogram-inl.h"
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080022#include "base/macros.h"
23#include "base/mutex.h"
Mathieu Chartiera4885cb2015-03-09 15:38:54 -070024#include "base/timing_logger.h"
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080025#include "object_callbacks.h"
Calin Juravle31f2c152015-10-23 17:56:15 +010026#include "offline_profiling_info.h"
Calin Juravle138dbff2016-06-28 19:36:58 +010027#include "jit/profile_saver_options.h"
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080028#include "thread_pool.h"
29
30namespace art {
31
Mathieu Chartiere401d142015-04-22 13:56:20 -070032class ArtMethod;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080033struct RuntimeArgumentMap;
Vladimir Marko3a21e382016-09-02 12:38:38 +010034union JValue;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080035
36namespace jit {
37
38class JitCodeCache;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080039class JitOptions;
40
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010041static constexpr int16_t kJitCheckForOSR = -1;
42static constexpr int16_t kJitHotnessDisabled = -2;
43
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080044class Jit {
45 public:
46 static constexpr bool kStressMode = kIsDebugBuild;
Nicolas Geoffray83f080a2016-03-08 16:50:21 +000047 static constexpr size_t kDefaultCompileThreshold = kStressMode ? 2 : 10000;
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +010048 static constexpr size_t kDefaultPriorityThreadWeightRatio = 1000;
Nicolas Geoffraybd553eb2016-04-28 13:56:04 +010049 static constexpr size_t kDefaultInvokeTransitionWeightRatio = 500;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080050
51 virtual ~Jit();
52 static Jit* Create(JitOptions* options, std::string* error_msg);
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000053 bool CompileMethod(ArtMethod* method, Thread* self, bool osr)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070054 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080055 void CreateThreadPool();
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010056
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080057 const JitCodeCache* GetCodeCache() const {
58 return code_cache_.get();
59 }
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010060
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080061 JitCodeCache* GetCodeCache() {
62 return code_cache_.get();
63 }
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010064
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080065 void DeleteThreadPool();
Mathieu Chartiera4885cb2015-03-09 15:38:54 -070066 // Dump interesting info: #methods compiled, code vs data size, compile / verify cumulative
67 // loggers.
Nicolas Geoffraya4f81542016-03-08 16:57:48 +000068 void DumpInfo(std::ostream& os) REQUIRES(!lock_);
Mathieu Chartiera4885cb2015-03-09 15:38:54 -070069 // Add a timing logger to cumulative_timings_.
70 void AddTimingLogger(const TimingLogger& logger);
Nicolas Geoffraya4f81542016-03-08 16:57:48 +000071
72 void AddMemoryUsage(ArtMethod* method, size_t bytes)
73 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070074 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffraya4f81542016-03-08 16:57:48 +000075
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010076 size_t OSRMethodThreshold() const {
77 return osr_method_threshold_;
Mathieu Chartiera50f9cf2015-09-25 11:34:45 -070078 }
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080079
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010080 size_t HotMethodThreshold() const {
81 return hot_method_threshold_;
82 }
83
84 size_t WarmMethodThreshold() const {
85 return warm_method_threshold_;
86 }
87
88 uint16_t PriorityThreadWeight() const {
89 return priority_thread_weight_;
90 }
91
Calin Juravleffc87072016-04-20 14:22:09 +010092 // Returns false if we only need to save profile information and not compile methods.
93 bool UseJitCompilation() const {
94 return use_jit_compilation_;
95 }
96
Calin Juravle138dbff2016-06-28 19:36:58 +010097 bool GetSaveProfilingInfo() const {
98 return profile_saver_options_.IsEnabled();
Calin Juravleffc87072016-04-20 14:22:09 +010099 }
100
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100101 // Wait until there is no more pending compilation tasks.
102 void WaitForCompilationToFinish(Thread* self);
103
104 // Profiling methods.
105 void MethodEntered(Thread* thread, ArtMethod* method)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700106 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100107
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100108 void AddSamples(Thread* self, ArtMethod* method, uint16_t samples, bool with_backedges)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700109 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100110
111 void InvokeVirtualOrInterface(Thread* thread,
112 mirror::Object* this_object,
113 ArtMethod* caller,
114 uint32_t dex_pc,
115 ArtMethod* callee)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700116 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100117
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100118 void NotifyInterpreterToCompiledCodeTransition(Thread* self, ArtMethod* caller)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700119 REQUIRES_SHARED(Locks::mutator_lock_) {
Calin Juravle155ff3d2016-04-27 14:14:58 +0100120 AddSamples(self, caller, invoke_transition_weight_, false);
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100121 }
122
123 void NotifyCompiledCodeToInterpreterTransition(Thread* self, ArtMethod* callee)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700124 REQUIRES_SHARED(Locks::mutator_lock_) {
Calin Juravle155ff3d2016-04-27 14:14:58 +0100125 AddSamples(self, callee, invoke_transition_weight_, false);
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100126 }
127
Calin Juravlec90bc922016-02-24 10:13:09 +0000128 // Starts the profile saver if the config options allow profile recording.
129 // The profile will be stored in the specified `filename` and will contain
130 // information collected from the given `code_paths` (a set of dex locations).
131 // The `foreign_dex_profile_path` is the path where the saver will put the
132 // profile markers for loaded dex files which are not owned by the application.
133 // The `app_dir` is the application directory and is used to decide which
134 // dex files belong to the application.
135 void StartProfileSaver(const std::string& filename,
136 const std::vector<std::string>& code_paths,
137 const std::string& foreign_dex_profile_path,
138 const std::string& app_dir);
Calin Juravle4d77b6a2015-12-01 18:38:09 +0000139 void StopProfileSaver();
Calin Juravle31f2c152015-10-23 17:56:15 +0100140
Calin Juravleb8e69992016-03-09 15:37:48 +0000141 void DumpForSigQuit(std::ostream& os) REQUIRES(!lock_);
Nicolas Geoffrayaee21562015-12-15 16:39:44 +0000142
Tamas Berghammer160e6df2016-01-05 14:29:02 +0000143 static void NewTypeLoadedIfUsingJit(mirror::Class* type)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700144 REQUIRES_SHARED(Locks::mutator_lock_);
Tamas Berghammer160e6df2016-01-05 14:29:02 +0000145
Tamas Berghammerfffbee42016-01-15 13:09:34 +0000146 // If debug info generation is turned on then write the type information for types already loaded
147 // into the specified class linker to the jit debug interface,
148 void DumpTypeInfoForLoadedTypes(ClassLinker* linker);
149
Nicolas Geoffray35122442016-03-02 12:05:30 +0000150 // Return whether we should try to JIT compiled code as soon as an ArtMethod is invoked.
Siva Chandra05d24152016-01-05 17:43:17 -0800151 bool JitAtFirstUse();
152
Nicolas Geoffray35122442016-03-02 12:05:30 +0000153 // Return whether we can invoke JIT code for `method`.
154 bool CanInvokeCompiledCode(ArtMethod* method);
155
Calin Juravleb2771b42016-04-07 17:09:25 +0100156 // Return whether the runtime should use a priority thread weight when sampling.
157 static bool ShouldUsePriorityThreadWeight();
158
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000159 // If an OSR compiled version is available for `method`,
160 // and `dex_pc + dex_pc_offset` is an entry point of that compiled
161 // version, this method will jump to the compiled code, let it run,
162 // and return true afterwards. Return false otherwise.
163 static bool MaybeDoOnStackReplacement(Thread* thread,
164 ArtMethod* method,
165 uint32_t dex_pc,
166 int32_t dex_pc_offset,
167 JValue* result)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700168 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000169
Mathieu Chartierc1bc4152016-03-24 17:22:52 -0700170 static bool LoadCompilerLibrary(std::string* error_msg);
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700171
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800172 private:
173 Jit();
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800174
Mathieu Chartierc1bc4152016-03-24 17:22:52 -0700175 static bool LoadCompiler(std::string* error_msg);
176
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800177 // JIT compiler
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700178 static void* jit_library_handle_;
179 static void* jit_compiler_handle_;
180 static void* (*jit_load_)(bool*);
181 static void (*jit_unload_)(void*);
182 static bool (*jit_compile_method_)(void*, ArtMethod*, Thread*, bool);
183 static void (*jit_types_loaded_)(void*, mirror::Class**, size_t count);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800184
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700185 // Performance monitoring.
186 bool dump_info_on_shutdown_;
187 CumulativeLogger cumulative_timings_;
Nicolas Geoffraya4f81542016-03-08 16:57:48 +0000188 Histogram<uint64_t> memory_use_ GUARDED_BY(lock_);
189 Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700190
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800191 std::unique_ptr<jit::JitCodeCache> code_cache_;
Mathieu Chartier3130cdf2015-05-03 15:20:23 -0700192
Calin Juravleffc87072016-04-20 14:22:09 +0100193 bool use_jit_compilation_;
Calin Juravle138dbff2016-06-28 19:36:58 +0100194 ProfileSaverOptions profile_saver_options_;
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700195 static bool generate_debug_info_;
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100196 uint16_t hot_method_threshold_;
197 uint16_t warm_method_threshold_;
198 uint16_t osr_method_threshold_;
199 uint16_t priority_thread_weight_;
Calin Juravle155ff3d2016-04-27 14:14:58 +0100200 uint16_t invoke_transition_weight_;
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100201 std::unique_ptr<ThreadPool> thread_pool_;
Calin Juravle4d77b6a2015-12-01 18:38:09 +0000202
Mathieu Chartier3130cdf2015-05-03 15:20:23 -0700203 DISALLOW_COPY_AND_ASSIGN(Jit);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800204};
205
206class JitOptions {
207 public:
208 static JitOptions* CreateFromRuntimeArguments(const RuntimeArgumentMap& options);
209 size_t GetCompileThreshold() const {
210 return compile_threshold_;
211 }
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100212 size_t GetWarmupThreshold() const {
213 return warmup_threshold_;
214 }
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000215 size_t GetOsrThreshold() const {
216 return osr_threshold_;
217 }
Calin Juravleb2771b42016-04-07 17:09:25 +0100218 uint16_t GetPriorityThreadWeight() const {
219 return priority_thread_weight_;
220 }
Calin Juravle155ff3d2016-04-27 14:14:58 +0100221 size_t GetInvokeTransitionWeight() const {
222 return invoke_transition_weight_;
223 }
Nicolas Geoffray0a3be162015-11-18 11:15:22 +0000224 size_t GetCodeCacheInitialCapacity() const {
225 return code_cache_initial_capacity_;
226 }
227 size_t GetCodeCacheMaxCapacity() const {
228 return code_cache_max_capacity_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800229 }
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700230 bool DumpJitInfoOnShutdown() const {
231 return dump_info_on_shutdown_;
232 }
Calin Juravle138dbff2016-06-28 19:36:58 +0100233 const ProfileSaverOptions& GetProfileSaverOptions() const {
234 return profile_saver_options_;
235 }
Calin Juravle31f2c152015-10-23 17:56:15 +0100236 bool GetSaveProfilingInfo() const {
Calin Juravle138dbff2016-06-28 19:36:58 +0100237 return profile_saver_options_.IsEnabled();
Calin Juravle31f2c152015-10-23 17:56:15 +0100238 }
Calin Juravleffc87072016-04-20 14:22:09 +0100239 bool UseJitCompilation() const {
240 return use_jit_compilation_;
Mathieu Chartier455f67c2015-03-17 13:48:29 -0700241 }
Calin Juravleffc87072016-04-20 14:22:09 +0100242 void SetUseJitCompilation(bool b) {
243 use_jit_compilation_ = b;
Mathieu Chartier455f67c2015-03-17 13:48:29 -0700244 }
Calin Juravle138dbff2016-06-28 19:36:58 +0100245 void SetSaveProfilingInfo(bool save_profiling_info) {
246 profile_saver_options_.SetEnabled(save_profiling_info);
Calin Juravle31f2c152015-10-23 17:56:15 +0100247 }
Siva Chandra05d24152016-01-05 17:43:17 -0800248 void SetJitAtFirstUse() {
Calin Juravleffc87072016-04-20 14:22:09 +0100249 use_jit_compilation_ = true;
Siva Chandra05d24152016-01-05 17:43:17 -0800250 compile_threshold_ = 0;
251 }
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800252
253 private:
Calin Juravleffc87072016-04-20 14:22:09 +0100254 bool use_jit_compilation_;
Nicolas Geoffray0a3be162015-11-18 11:15:22 +0000255 size_t code_cache_initial_capacity_;
256 size_t code_cache_max_capacity_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800257 size_t compile_threshold_;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100258 size_t warmup_threshold_;
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000259 size_t osr_threshold_;
Calin Juravleb2771b42016-04-07 17:09:25 +0100260 uint16_t priority_thread_weight_;
Calin Juravle155ff3d2016-04-27 14:14:58 +0100261 size_t invoke_transition_weight_;
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700262 bool dump_info_on_shutdown_;
Calin Juravle138dbff2016-06-28 19:36:58 +0100263 ProfileSaverOptions profile_saver_options_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800264
Nicolas Geoffray0a3be162015-11-18 11:15:22 +0000265 JitOptions()
Calin Juravleffc87072016-04-20 14:22:09 +0100266 : use_jit_compilation_(false),
Nicolas Geoffray0a3be162015-11-18 11:15:22 +0000267 code_cache_initial_capacity_(0),
268 code_cache_max_capacity_(0),
269 compile_threshold_(0),
Calin Juravle138dbff2016-06-28 19:36:58 +0100270 dump_info_on_shutdown_(false) {}
Mathieu Chartier3130cdf2015-05-03 15:20:23 -0700271
272 DISALLOW_COPY_AND_ASSIGN(JitOptions);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800273};
274
275} // namespace jit
276} // namespace art
277
278#endif // ART_RUNTIME_JIT_JIT_H_