blob: 485537ca89f9f6616a62ff7a2fba3377b1284ef5 [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;
Nicolas Geoffray47b95802018-05-16 15:42:17 +010047// At what priority to schedule jit threads. 9 is the lowest foreground priority on device.
48// See android/os/Process.java.
49static constexpr int kJitPoolThreadPthreadDefaultPriority = 9;
50
51class JitOptions {
52 public:
53 static JitOptions* CreateFromRuntimeArguments(const RuntimeArgumentMap& options);
54
55 uint16_t GetCompileThreshold() const {
56 return compile_threshold_;
57 }
58
59 uint16_t GetWarmupThreshold() const {
60 return warmup_threshold_;
61 }
62
63 uint16_t GetOsrThreshold() const {
64 return osr_threshold_;
65 }
66
67 uint16_t GetPriorityThreadWeight() const {
68 return priority_thread_weight_;
69 }
70
71 uint16_t GetInvokeTransitionWeight() const {
72 return invoke_transition_weight_;
73 }
74
75 size_t GetCodeCacheInitialCapacity() const {
76 return code_cache_initial_capacity_;
77 }
78
79 size_t GetCodeCacheMaxCapacity() const {
80 return code_cache_max_capacity_;
81 }
82
83 bool DumpJitInfoOnShutdown() const {
84 return dump_info_on_shutdown_;
85 }
86
87 const ProfileSaverOptions& GetProfileSaverOptions() const {
88 return profile_saver_options_;
89 }
90
91 bool GetSaveProfilingInfo() const {
92 return profile_saver_options_.IsEnabled();
93 }
94
95 int GetThreadPoolPthreadPriority() const {
96 return thread_pool_pthread_priority_;
97 }
98
99 bool UseJitCompilation() const {
100 return use_jit_compilation_;
101 }
102
103 void SetUseJitCompilation(bool b) {
104 use_jit_compilation_ = b;
105 }
106
107 void SetSaveProfilingInfo(bool save_profiling_info) {
108 profile_saver_options_.SetEnabled(save_profiling_info);
109 }
110
111 void SetWaitForJitNotificationsToSaveProfile(bool value) {
112 profile_saver_options_.SetWaitForJitNotificationsToSave(value);
113 }
114
115 void SetProfileAOTCode(bool value) {
116 profile_saver_options_.SetProfileAOTCode(value);
117 }
118
119 void SetJitAtFirstUse() {
120 use_jit_compilation_ = true;
121 compile_threshold_ = 0;
122 }
123
124 private:
125 bool use_jit_compilation_;
126 size_t code_cache_initial_capacity_;
127 size_t code_cache_max_capacity_;
128 uint16_t compile_threshold_;
129 uint16_t warmup_threshold_;
130 uint16_t osr_threshold_;
131 uint16_t priority_thread_weight_;
132 uint16_t invoke_transition_weight_;
133 bool dump_info_on_shutdown_;
134 int thread_pool_pthread_priority_;
135 ProfileSaverOptions profile_saver_options_;
136
137 JitOptions()
138 : use_jit_compilation_(false),
139 code_cache_initial_capacity_(0),
140 code_cache_max_capacity_(0),
141 compile_threshold_(0),
142 warmup_threshold_(0),
143 osr_threshold_(0),
144 priority_thread_weight_(0),
145 invoke_transition_weight_(0),
146 dump_info_on_shutdown_(false),
Nicolas Geoffrayc9de61c2018-11-27 17:34:31 +0000147 thread_pool_pthread_priority_(kJitPoolThreadPthreadDefaultPriority) {}
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100148
149 DISALLOW_COPY_AND_ASSIGN(JitOptions);
150};
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100151
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800152class Jit {
153 public:
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100154 static constexpr size_t kDefaultPriorityThreadWeightRatio = 1000;
Nicolas Geoffraybd553eb2016-04-28 13:56:04 +0100155 static constexpr size_t kDefaultInvokeTransitionWeightRatio = 500;
buzbee42a09cb02017-02-01 09:08:31 -0800156 // How frequently should the interpreter check to see if OSR compilation is ready.
157 static constexpr int16_t kJitRecheckOSRThreshold = 100;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800158
159 virtual ~Jit();
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100160
161 // Create JIT itself.
162 static Jit* Create(JitCodeCache* code_cache, JitOptions* options);
163
Nicolas Geoffray075456e2018-12-14 08:54:21 +0000164 bool CompileMethod(ArtMethod* method, Thread* self, bool baseline, bool osr)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700165 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100166
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800167 const JitCodeCache* GetCodeCache() const {
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100168 return code_cache_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800169 }
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100170
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800171 JitCodeCache* GetCodeCache() {
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100172 return code_cache_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800173 }
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100174
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100175 void CreateThreadPool();
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800176 void DeleteThreadPool();
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100177
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700178 // Dump interesting info: #methods compiled, code vs data size, compile / verify cumulative
179 // loggers.
Nicolas Geoffraya4f81542016-03-08 16:57:48 +0000180 void DumpInfo(std::ostream& os) REQUIRES(!lock_);
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700181 // Add a timing logger to cumulative_timings_.
182 void AddTimingLogger(const TimingLogger& logger);
Nicolas Geoffraya4f81542016-03-08 16:57:48 +0000183
184 void AddMemoryUsage(ArtMethod* method, size_t bytes)
185 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700186 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffraya4f81542016-03-08 16:57:48 +0000187
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100188 uint16_t OSRMethodThreshold() const {
189 return options_->GetOsrThreshold();
Mathieu Chartiera50f9cf2015-09-25 11:34:45 -0700190 }
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800191
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100192 uint16_t HotMethodThreshold() const {
193 return options_->GetCompileThreshold();
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100194 }
195
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100196 uint16_t WarmMethodThreshold() const {
197 return options_->GetWarmupThreshold();
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100198 }
199
200 uint16_t PriorityThreadWeight() const {
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100201 return options_->GetPriorityThreadWeight();
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100202 }
203
Calin Juravleffc87072016-04-20 14:22:09 +0100204 // Returns false if we only need to save profile information and not compile methods.
205 bool UseJitCompilation() const {
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100206 return options_->UseJitCompilation();
Calin Juravleffc87072016-04-20 14:22:09 +0100207 }
208
Calin Juravle138dbff2016-06-28 19:36:58 +0100209 bool GetSaveProfilingInfo() const {
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100210 return options_->GetSaveProfilingInfo();
Calin Juravleffc87072016-04-20 14:22:09 +0100211 }
212
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100213 // Wait until there is no more pending compilation tasks.
214 void WaitForCompilationToFinish(Thread* self);
215
216 // Profiling methods.
217 void MethodEntered(Thread* thread, ArtMethod* method)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700218 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100219
Nicolas Geoffray0402f4b2018-11-29 19:18:46 +0000220 void AddSamples(Thread* self, ArtMethod* method, uint16_t samples, bool with_backedges)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700221 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100222
Mathieu Chartieref41db72016-10-25 15:08:01 -0700223 void InvokeVirtualOrInterface(ObjPtr<mirror::Object> this_object,
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100224 ArtMethod* caller,
225 uint32_t dex_pc,
226 ArtMethod* callee)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700227 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100228
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100229 void NotifyInterpreterToCompiledCodeTransition(Thread* self, ArtMethod* caller)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700230 REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100231 AddSamples(self, caller, options_->GetInvokeTransitionWeight(), false);
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100232 }
233
234 void NotifyCompiledCodeToInterpreterTransition(Thread* self, ArtMethod* callee)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700235 REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100236 AddSamples(self, callee, options_->GetInvokeTransitionWeight(), false);
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100237 }
238
Calin Juravlec90bc922016-02-24 10:13:09 +0000239 // Starts the profile saver if the config options allow profile recording.
240 // The profile will be stored in the specified `filename` and will contain
241 // information collected from the given `code_paths` (a set of dex locations).
Calin Juravlec90bc922016-02-24 10:13:09 +0000242 void StartProfileSaver(const std::string& filename,
Calin Juravle77651c42017-03-03 18:04:02 -0800243 const std::vector<std::string>& code_paths);
Calin Juravle4d77b6a2015-12-01 18:38:09 +0000244 void StopProfileSaver();
Calin Juravle31f2c152015-10-23 17:56:15 +0100245
Calin Juravleb8e69992016-03-09 15:37:48 +0000246 void DumpForSigQuit(std::ostream& os) REQUIRES(!lock_);
Nicolas Geoffrayaee21562015-12-15 16:39:44 +0000247
Tamas Berghammer160e6df2016-01-05 14:29:02 +0000248 static void NewTypeLoadedIfUsingJit(mirror::Class* type)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700249 REQUIRES_SHARED(Locks::mutator_lock_);
Tamas Berghammer160e6df2016-01-05 14:29:02 +0000250
Tamas Berghammerfffbee42016-01-15 13:09:34 +0000251 // If debug info generation is turned on then write the type information for types already loaded
252 // into the specified class linker to the jit debug interface,
253 void DumpTypeInfoForLoadedTypes(ClassLinker* linker);
254
Nicolas Geoffray35122442016-03-02 12:05:30 +0000255 // Return whether we should try to JIT compiled code as soon as an ArtMethod is invoked.
Siva Chandra05d24152016-01-05 17:43:17 -0800256 bool JitAtFirstUse();
257
Nicolas Geoffray35122442016-03-02 12:05:30 +0000258 // Return whether we can invoke JIT code for `method`.
259 bool CanInvokeCompiledCode(ArtMethod* method);
260
Calin Juravleb2771b42016-04-07 17:09:25 +0100261 // Return whether the runtime should use a priority thread weight when sampling.
Vladimir Markoa710d912017-09-12 14:56:07 +0100262 static bool ShouldUsePriorityThreadWeight(Thread* self);
Calin Juravleb2771b42016-04-07 17:09:25 +0100263
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000264 // If an OSR compiled version is available for `method`,
265 // and `dex_pc + dex_pc_offset` is an entry point of that compiled
266 // version, this method will jump to the compiled code, let it run,
267 // and return true afterwards. Return false otherwise.
268 static bool MaybeDoOnStackReplacement(Thread* thread,
269 ArtMethod* method,
270 uint32_t dex_pc,
271 int32_t dex_pc_offset,
272 JValue* result)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700273 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000274
Nicolas Geoffraya7edd0d2018-11-07 03:18:16 +0000275 // Load the compiler library.
276 static bool LoadCompilerLibrary(std::string* error_msg);
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700277
Andreas Gampef149b3f2016-11-16 14:58:24 -0800278 ThreadPool* GetThreadPool() const {
279 return thread_pool_.get();
280 }
281
Nicolas Geoffray021c5f22016-12-16 11:22:05 +0000282 // Stop the JIT by waiting for all current compilations and enqueued compilations to finish.
283 void Stop();
284
285 // Start JIT threads.
286 void Start();
287
Nicolas Geoffrayce9ed362018-11-29 03:19:28 +0000288 // Transition to a child state.
289 void PostForkChildAction(bool is_zygote);
290
291 // Prepare for forking.
292 void PreZygoteFork();
293
294 // Adjust state after forking.
295 void PostZygoteFork();
Nicolas Geoffrayc9de61c2018-11-27 17:34:31 +0000296
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800297 private:
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100298 Jit(JitCodeCache* code_cache, JitOptions* options);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800299
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100300 static bool BindCompilerMethods(std::string* error_msg);
Mathieu Chartierc1bc4152016-03-24 17:22:52 -0700301
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800302 // JIT compiler
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700303 static void* jit_library_handle_;
304 static void* jit_compiler_handle_;
Nicolas Geoffrayc9de61c2018-11-27 17:34:31 +0000305 static void* (*jit_load_)(void);
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700306 static void (*jit_unload_)(void*);
Nicolas Geoffray075456e2018-12-14 08:54:21 +0000307 static bool (*jit_compile_method_)(void*, ArtMethod*, Thread*, bool, bool);
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700308 static void (*jit_types_loaded_)(void*, mirror::Class**, size_t count);
Nicolas Geoffrayc9de61c2018-11-27 17:34:31 +0000309 static void (*jit_update_options_)(void*);
310 static bool (*jit_generate_debug_info_)(void*);
311 template <typename T> static bool LoadSymbol(T*, const char* symbol, std::string* error_msg);
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100312
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100313 // JIT resources owned by runtime.
314 jit::JitCodeCache* const code_cache_;
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100315 const JitOptions* const options_;
316
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100317 std::unique_ptr<ThreadPool> thread_pool_;
318
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700319 // Performance monitoring.
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700320 CumulativeLogger cumulative_timings_;
Nicolas Geoffraya4f81542016-03-08 16:57:48 +0000321 Histogram<uint64_t> memory_use_ GUARDED_BY(lock_);
322 Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700323
Mathieu Chartier3130cdf2015-05-03 15:20:23 -0700324 DISALLOW_COPY_AND_ASSIGN(Jit);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800325};
326
Andreas Gampef149b3f2016-11-16 14:58:24 -0800327// Helper class to stop the JIT for a given scope. This will wait for the JIT to quiesce.
328class ScopedJitSuspend {
329 public:
330 ScopedJitSuspend();
331 ~ScopedJitSuspend();
332
333 private:
334 bool was_on_;
335};
336
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800337} // namespace jit
338} // namespace art
339
340#endif // ART_RUNTIME_JIT_JIT_H_