blob: 4b8b8919d11aed167dab1a91da26a40e6b956ff6 [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/histogram-inl.h"
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080021#include "base/macros.h"
22#include "base/mutex.h"
Mathieu Chartiera4885cb2015-03-09 15:38:54 -070023#include "base/timing_logger.h"
Mathieu Chartieref41db72016-10-25 15:08:01 -070024#include "jit/profile_saver_options.h"
25#include "obj_ptr.h"
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080026#include "thread_pool.h"
27
28namespace art {
29
Mathieu Chartiere401d142015-04-22 13:56:20 -070030class ArtMethod;
David Sehr9323e6e2016-09-13 08:58:35 -070031class ClassLinker;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080032struct RuntimeArgumentMap;
Vladimir Marko3a21e382016-09-02 12:38:38 +010033union JValue;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080034
David Sehr709b0702016-10-13 09:12:37 -070035namespace mirror {
36class Object;
37class Class;
38} // namespace mirror
39
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080040namespace jit {
41
42class JitCodeCache;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080043class JitOptions;
44
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010045static constexpr int16_t kJitCheckForOSR = -1;
46static constexpr int16_t kJitHotnessDisabled = -2;
47
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080048class Jit {
49 public:
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +010050 static constexpr size_t kDefaultPriorityThreadWeightRatio = 1000;
Nicolas Geoffraybd553eb2016-04-28 13:56:04 +010051 static constexpr size_t kDefaultInvokeTransitionWeightRatio = 500;
buzbee42a09cb02017-02-01 09:08:31 -080052 // How frequently should the interpreter check to see if OSR compilation is ready.
53 static constexpr int16_t kJitRecheckOSRThreshold = 100;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080054
55 virtual ~Jit();
56 static Jit* Create(JitOptions* options, std::string* error_msg);
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000057 bool CompileMethod(ArtMethod* method, Thread* self, bool osr)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070058 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080059 void CreateThreadPool();
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010060
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080061 const JitCodeCache* GetCodeCache() const {
62 return code_cache_.get();
63 }
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010064
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080065 JitCodeCache* GetCodeCache() {
66 return code_cache_.get();
67 }
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010068
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080069 void DeleteThreadPool();
Mathieu Chartiera4885cb2015-03-09 15:38:54 -070070 // Dump interesting info: #methods compiled, code vs data size, compile / verify cumulative
71 // loggers.
Nicolas Geoffraya4f81542016-03-08 16:57:48 +000072 void DumpInfo(std::ostream& os) REQUIRES(!lock_);
Mathieu Chartiera4885cb2015-03-09 15:38:54 -070073 // Add a timing logger to cumulative_timings_.
74 void AddTimingLogger(const TimingLogger& logger);
Nicolas Geoffraya4f81542016-03-08 16:57:48 +000075
76 void AddMemoryUsage(ArtMethod* method, size_t bytes)
77 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070078 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffraya4f81542016-03-08 16:57:48 +000079
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010080 size_t OSRMethodThreshold() const {
81 return osr_method_threshold_;
Mathieu Chartiera50f9cf2015-09-25 11:34:45 -070082 }
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080083
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010084 size_t HotMethodThreshold() const {
85 return hot_method_threshold_;
86 }
87
88 size_t WarmMethodThreshold() const {
89 return warm_method_threshold_;
90 }
91
92 uint16_t PriorityThreadWeight() const {
93 return priority_thread_weight_;
94 }
95
Calin Juravleffc87072016-04-20 14:22:09 +010096 // Returns false if we only need to save profile information and not compile methods.
97 bool UseJitCompilation() const {
98 return use_jit_compilation_;
99 }
100
Calin Juravle138dbff2016-06-28 19:36:58 +0100101 bool GetSaveProfilingInfo() const {
102 return profile_saver_options_.IsEnabled();
Calin Juravleffc87072016-04-20 14:22:09 +0100103 }
104
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100105 // Wait until there is no more pending compilation tasks.
106 void WaitForCompilationToFinish(Thread* self);
107
108 // Profiling methods.
109 void MethodEntered(Thread* thread, ArtMethod* method)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700110 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100111
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100112 void AddSamples(Thread* self, ArtMethod* method, uint16_t samples, bool with_backedges)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700113 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100114
Mathieu Chartieref41db72016-10-25 15:08:01 -0700115 void InvokeVirtualOrInterface(ObjPtr<mirror::Object> this_object,
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100116 ArtMethod* caller,
117 uint32_t dex_pc,
118 ArtMethod* callee)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700119 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100120
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100121 void NotifyInterpreterToCompiledCodeTransition(Thread* self, ArtMethod* caller)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700122 REQUIRES_SHARED(Locks::mutator_lock_) {
Calin Juravle155ff3d2016-04-27 14:14:58 +0100123 AddSamples(self, caller, invoke_transition_weight_, false);
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100124 }
125
126 void NotifyCompiledCodeToInterpreterTransition(Thread* self, ArtMethod* callee)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700127 REQUIRES_SHARED(Locks::mutator_lock_) {
Calin Juravle155ff3d2016-04-27 14:14:58 +0100128 AddSamples(self, callee, invoke_transition_weight_, false);
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100129 }
130
Calin Juravlec90bc922016-02-24 10:13:09 +0000131 // Starts the profile saver if the config options allow profile recording.
132 // The profile will be stored in the specified `filename` and will contain
133 // information collected from the given `code_paths` (a set of dex locations).
Calin Juravlec90bc922016-02-24 10:13:09 +0000134 void StartProfileSaver(const std::string& filename,
Calin Juravle77651c42017-03-03 18:04:02 -0800135 const std::vector<std::string>& code_paths);
Calin Juravle4d77b6a2015-12-01 18:38:09 +0000136 void StopProfileSaver();
Calin Juravle31f2c152015-10-23 17:56:15 +0100137
Calin Juravleb8e69992016-03-09 15:37:48 +0000138 void DumpForSigQuit(std::ostream& os) REQUIRES(!lock_);
Nicolas Geoffrayaee21562015-12-15 16:39:44 +0000139
Tamas Berghammer160e6df2016-01-05 14:29:02 +0000140 static void NewTypeLoadedIfUsingJit(mirror::Class* type)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700141 REQUIRES_SHARED(Locks::mutator_lock_);
Tamas Berghammer160e6df2016-01-05 14:29:02 +0000142
Tamas Berghammerfffbee42016-01-15 13:09:34 +0000143 // If debug info generation is turned on then write the type information for types already loaded
144 // into the specified class linker to the jit debug interface,
145 void DumpTypeInfoForLoadedTypes(ClassLinker* linker);
146
Nicolas Geoffray35122442016-03-02 12:05:30 +0000147 // Return whether we should try to JIT compiled code as soon as an ArtMethod is invoked.
Siva Chandra05d24152016-01-05 17:43:17 -0800148 bool JitAtFirstUse();
149
Nicolas Geoffray35122442016-03-02 12:05:30 +0000150 // Return whether we can invoke JIT code for `method`.
151 bool CanInvokeCompiledCode(ArtMethod* method);
152
Calin Juravleb2771b42016-04-07 17:09:25 +0100153 // Return whether the runtime should use a priority thread weight when sampling.
Vladimir Markoa710d912017-09-12 14:56:07 +0100154 static bool ShouldUsePriorityThreadWeight(Thread* self);
Calin Juravleb2771b42016-04-07 17:09:25 +0100155
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000156 // If an OSR compiled version is available for `method`,
157 // and `dex_pc + dex_pc_offset` is an entry point of that compiled
158 // version, this method will jump to the compiled code, let it run,
159 // and return true afterwards. Return false otherwise.
160 static bool MaybeDoOnStackReplacement(Thread* thread,
161 ArtMethod* method,
162 uint32_t dex_pc,
163 int32_t dex_pc_offset,
164 JValue* result)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700165 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000166
Mathieu Chartierc1bc4152016-03-24 17:22:52 -0700167 static bool LoadCompilerLibrary(std::string* error_msg);
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700168
Andreas Gampef149b3f2016-11-16 14:58:24 -0800169 ThreadPool* GetThreadPool() const {
170 return thread_pool_.get();
171 }
172
Nicolas Geoffray021c5f22016-12-16 11:22:05 +0000173 // Stop the JIT by waiting for all current compilations and enqueued compilations to finish.
174 void Stop();
175
176 // Start JIT threads.
177 void Start();
178
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800179 private:
180 Jit();
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800181
Mathieu Chartierc1bc4152016-03-24 17:22:52 -0700182 static bool LoadCompiler(std::string* error_msg);
183
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800184 // JIT compiler
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700185 static void* jit_library_handle_;
186 static void* jit_compiler_handle_;
187 static void* (*jit_load_)(bool*);
188 static void (*jit_unload_)(void*);
189 static bool (*jit_compile_method_)(void*, ArtMethod*, Thread*, bool);
190 static void (*jit_types_loaded_)(void*, mirror::Class**, size_t count);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800191
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700192 // Performance monitoring.
193 bool dump_info_on_shutdown_;
194 CumulativeLogger cumulative_timings_;
Nicolas Geoffraya4f81542016-03-08 16:57:48 +0000195 Histogram<uint64_t> memory_use_ GUARDED_BY(lock_);
196 Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700197
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800198 std::unique_ptr<jit::JitCodeCache> code_cache_;
Mathieu Chartier3130cdf2015-05-03 15:20:23 -0700199
Calin Juravleffc87072016-04-20 14:22:09 +0100200 bool use_jit_compilation_;
Calin Juravle138dbff2016-06-28 19:36:58 +0100201 ProfileSaverOptions profile_saver_options_;
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700202 static bool generate_debug_info_;
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100203 uint16_t hot_method_threshold_;
204 uint16_t warm_method_threshold_;
205 uint16_t osr_method_threshold_;
206 uint16_t priority_thread_weight_;
Calin Juravle155ff3d2016-04-27 14:14:58 +0100207 uint16_t invoke_transition_weight_;
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100208 std::unique_ptr<ThreadPool> thread_pool_;
Calin Juravle4d77b6a2015-12-01 18:38:09 +0000209
Mathieu Chartier3130cdf2015-05-03 15:20:23 -0700210 DISALLOW_COPY_AND_ASSIGN(Jit);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800211};
212
213class JitOptions {
214 public:
215 static JitOptions* CreateFromRuntimeArguments(const RuntimeArgumentMap& options);
216 size_t GetCompileThreshold() const {
217 return compile_threshold_;
218 }
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100219 size_t GetWarmupThreshold() const {
220 return warmup_threshold_;
221 }
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000222 size_t GetOsrThreshold() const {
223 return osr_threshold_;
224 }
Calin Juravleb2771b42016-04-07 17:09:25 +0100225 uint16_t GetPriorityThreadWeight() const {
226 return priority_thread_weight_;
227 }
Calin Juravle155ff3d2016-04-27 14:14:58 +0100228 size_t GetInvokeTransitionWeight() const {
229 return invoke_transition_weight_;
230 }
Nicolas Geoffray0a3be162015-11-18 11:15:22 +0000231 size_t GetCodeCacheInitialCapacity() const {
232 return code_cache_initial_capacity_;
233 }
234 size_t GetCodeCacheMaxCapacity() const {
235 return code_cache_max_capacity_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800236 }
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700237 bool DumpJitInfoOnShutdown() const {
238 return dump_info_on_shutdown_;
239 }
Calin Juravle138dbff2016-06-28 19:36:58 +0100240 const ProfileSaverOptions& GetProfileSaverOptions() const {
241 return profile_saver_options_;
242 }
Calin Juravle31f2c152015-10-23 17:56:15 +0100243 bool GetSaveProfilingInfo() const {
Calin Juravle138dbff2016-06-28 19:36:58 +0100244 return profile_saver_options_.IsEnabled();
Calin Juravle31f2c152015-10-23 17:56:15 +0100245 }
Calin Juravleffc87072016-04-20 14:22:09 +0100246 bool UseJitCompilation() const {
247 return use_jit_compilation_;
Mathieu Chartier455f67c2015-03-17 13:48:29 -0700248 }
Calin Juravleffc87072016-04-20 14:22:09 +0100249 void SetUseJitCompilation(bool b) {
250 use_jit_compilation_ = b;
Mathieu Chartier455f67c2015-03-17 13:48:29 -0700251 }
Calin Juravle138dbff2016-06-28 19:36:58 +0100252 void SetSaveProfilingInfo(bool save_profiling_info) {
253 profile_saver_options_.SetEnabled(save_profiling_info);
Calin Juravle31f2c152015-10-23 17:56:15 +0100254 }
Calin Juravleb3d1eee2018-05-03 22:28:03 -0700255 void SetWaitForJitNotificationsToSaveProfile(bool value) {
256 profile_saver_options_.SetWaitForJitNotificationsToSave(value);
257 }
258 void SetProfileAOTCode(bool value) {
259 profile_saver_options_.SetProfileAOTCode(value);
260 }
261
Siva Chandra05d24152016-01-05 17:43:17 -0800262 void SetJitAtFirstUse() {
Calin Juravleffc87072016-04-20 14:22:09 +0100263 use_jit_compilation_ = true;
Siva Chandra05d24152016-01-05 17:43:17 -0800264 compile_threshold_ = 0;
265 }
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800266
267 private:
Calin Juravleffc87072016-04-20 14:22:09 +0100268 bool use_jit_compilation_;
Nicolas Geoffray0a3be162015-11-18 11:15:22 +0000269 size_t code_cache_initial_capacity_;
270 size_t code_cache_max_capacity_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800271 size_t compile_threshold_;
Nicolas Geoffray5550ca82015-08-21 18:38:30 +0100272 size_t warmup_threshold_;
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000273 size_t osr_threshold_;
Calin Juravleb2771b42016-04-07 17:09:25 +0100274 uint16_t priority_thread_weight_;
Calin Juravle155ff3d2016-04-27 14:14:58 +0100275 size_t invoke_transition_weight_;
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700276 bool dump_info_on_shutdown_;
Calin Juravle138dbff2016-06-28 19:36:58 +0100277 ProfileSaverOptions profile_saver_options_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800278
Nicolas Geoffray0a3be162015-11-18 11:15:22 +0000279 JitOptions()
Calin Juravleffc87072016-04-20 14:22:09 +0100280 : use_jit_compilation_(false),
Nicolas Geoffray0a3be162015-11-18 11:15:22 +0000281 code_cache_initial_capacity_(0),
282 code_cache_max_capacity_(0),
283 compile_threshold_(0),
Andreas Gamped9911ee2017-03-27 13:27:24 -0700284 warmup_threshold_(0),
285 osr_threshold_(0),
286 priority_thread_weight_(0),
287 invoke_transition_weight_(0),
Calin Juravle138dbff2016-06-28 19:36:58 +0100288 dump_info_on_shutdown_(false) {}
Mathieu Chartier3130cdf2015-05-03 15:20:23 -0700289
290 DISALLOW_COPY_AND_ASSIGN(JitOptions);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800291};
292
Andreas Gampef149b3f2016-11-16 14:58:24 -0800293// Helper class to stop the JIT for a given scope. This will wait for the JIT to quiesce.
294class ScopedJitSuspend {
295 public:
296 ScopedJitSuspend();
297 ~ScopedJitSuspend();
298
299 private:
300 bool was_on_;
301};
302
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800303} // namespace jit
304} // namespace art
305
306#endif // ART_RUNTIME_JIT_JIT_H_