blob: 59ad17c88efaa855ea36be5239d5a40b7a4c66db [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 Geoffraye3884e32019-10-28 17:04:49 +000020#include <android-base/unique_fd.h>
21
Nicolas Geoffraya4f81542016-03-08 16:57:48 +000022#include "base/histogram-inl.h"
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080023#include "base/macros.h"
24#include "base/mutex.h"
David Srbecky21821472019-07-29 15:10:31 +010025#include "base/runtime_debug.h"
Mathieu Chartiera4885cb2015-03-09 15:38:54 -070026#include "base/timing_logger.h"
Nicolas Geoffray0d60a2b2020-06-17 14:31:56 +010027#include "compilation_kind.h"
Nicolas Geoffray9ac09ee2019-05-08 23:38:27 +010028#include "handle.h"
Nicolas Geoffray57cacb72019-12-08 22:07:08 +000029#include "offsets.h"
Nicolas Geoffray0315efa2020-06-26 11:42:39 +010030#include "interpreter/mterp/nterp.h"
David Srbecky8fc2f952019-07-31 18:40:09 +010031#include "jit/debugger_interface.h"
Mathieu Chartieref41db72016-10-25 15:08:01 -070032#include "jit/profile_saver_options.h"
33#include "obj_ptr.h"
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080034#include "thread_pool.h"
35
36namespace art {
37
Mathieu Chartiere401d142015-04-22 13:56:20 -070038class ArtMethod;
David Sehr9323e6e2016-09-13 08:58:35 -070039class ClassLinker;
Nicolas Geoffray9ac09ee2019-05-08 23:38:27 +010040class DexFile;
Nicolas Geoffraydc2fbb62019-04-11 22:55:50 +010041class OatDexFile;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080042struct RuntimeArgumentMap;
Vladimir Marko3a21e382016-09-02 12:38:38 +010043union JValue;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080044
David Sehr709b0702016-10-13 09:12:37 -070045namespace mirror {
46class Object;
47class Class;
Nicolas Geoffray9ac09ee2019-05-08 23:38:27 +010048class ClassLoader;
Nicolas Geoffray0f8950a2019-07-24 13:22:11 +010049class DexCache;
Nicolas Geoffraya48c3df2019-06-27 13:11:12 +000050class String;
David Sehr709b0702016-10-13 09:12:37 -070051} // namespace mirror
52
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080053namespace jit {
54
55class JitCodeCache;
Nicolas Geoffray7f7539b2019-06-06 16:20:54 +010056class JitMemoryRegion;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080057class JitOptions;
58
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010059static constexpr int16_t kJitCheckForOSR = -1;
60static constexpr int16_t kJitHotnessDisabled = -2;
Nicolas Geoffray47b95802018-05-16 15:42:17 +010061// At what priority to schedule jit threads. 9 is the lowest foreground priority on device.
62// See android/os/Process.java.
63static constexpr int kJitPoolThreadPthreadDefaultPriority = 9;
Nicolas Geoffray4bf753d2020-12-14 20:33:53 +000064// At what priority to schedule jit zygote threads compiling profiles in the background.
65// 19 is the lowest background priority on device.
66// See android/os/Process.java.
67static constexpr int kJitZygotePoolThreadPthreadDefaultPriority = 19;
David Srbecky81448a22019-08-01 14:29:53 +010068// We check whether to jit-compile the method every Nth invoke.
69// The tests often use threshold of 1000 (and thus 500 to start profiling).
70static constexpr uint32_t kJitSamplesBatchSize = 512; // Must be power of 2.
Nicolas Geoffray47b95802018-05-16 15:42:17 +010071
72class JitOptions {
73 public:
74 static JitOptions* CreateFromRuntimeArguments(const RuntimeArgumentMap& options);
75
76 uint16_t GetCompileThreshold() const {
77 return compile_threshold_;
78 }
79
80 uint16_t GetWarmupThreshold() const {
81 return warmup_threshold_;
82 }
83
84 uint16_t GetOsrThreshold() const {
85 return osr_threshold_;
86 }
87
88 uint16_t GetPriorityThreadWeight() const {
89 return priority_thread_weight_;
90 }
91
92 uint16_t GetInvokeTransitionWeight() const {
93 return invoke_transition_weight_;
94 }
95
96 size_t GetCodeCacheInitialCapacity() const {
97 return code_cache_initial_capacity_;
98 }
99
100 size_t GetCodeCacheMaxCapacity() const {
101 return code_cache_max_capacity_;
102 }
103
104 bool DumpJitInfoOnShutdown() const {
105 return dump_info_on_shutdown_;
106 }
107
108 const ProfileSaverOptions& GetProfileSaverOptions() const {
109 return profile_saver_options_;
110 }
111
112 bool GetSaveProfilingInfo() const {
113 return profile_saver_options_.IsEnabled();
114 }
115
116 int GetThreadPoolPthreadPriority() const {
117 return thread_pool_pthread_priority_;
118 }
119
Nicolas Geoffray4bf753d2020-12-14 20:33:53 +0000120 int GetZygoteThreadPoolPthreadPriority() const {
121 return zygote_thread_pool_pthread_priority_;
122 }
123
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100124 bool UseJitCompilation() const {
125 return use_jit_compilation_;
126 }
127
Nicolas Geoffray4bf753d2020-12-14 20:33:53 +0000128 bool UseProfiledJitCompilation() const {
129 return use_profiled_jit_compilation_;
130 }
131
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100132 void SetUseJitCompilation(bool b) {
133 use_jit_compilation_ = b;
134 }
135
136 void SetSaveProfilingInfo(bool save_profiling_info) {
137 profile_saver_options_.SetEnabled(save_profiling_info);
138 }
139
140 void SetWaitForJitNotificationsToSaveProfile(bool value) {
141 profile_saver_options_.SetWaitForJitNotificationsToSave(value);
142 }
143
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100144 void SetJitAtFirstUse() {
145 use_jit_compilation_ = true;
146 compile_threshold_ = 0;
147 }
148
Nicolas Geoffrayb0a97472019-12-05 15:17:46 +0000149 void SetUseBaselineCompiler() {
150 use_baseline_compiler_ = true;
151 }
152
153 bool UseBaselineCompiler() const {
154 return use_baseline_compiler_;
155 }
156
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100157 private:
David Srbeckye3fc2d12018-11-30 13:41:14 +0000158 // We add the sample in batches of size kJitSamplesBatchSize.
159 // This method rounds the threshold so that it is multiple of the batch size.
160 static uint32_t RoundUpThreshold(uint32_t threshold);
161
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100162 bool use_jit_compilation_;
Nicolas Geoffray4bf753d2020-12-14 20:33:53 +0000163 bool use_profiled_jit_compilation_;
Nicolas Geoffrayb0a97472019-12-05 15:17:46 +0000164 bool use_baseline_compiler_;
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100165 size_t code_cache_initial_capacity_;
166 size_t code_cache_max_capacity_;
David Srbeckye3fc2d12018-11-30 13:41:14 +0000167 uint32_t compile_threshold_;
168 uint32_t warmup_threshold_;
169 uint32_t osr_threshold_;
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100170 uint16_t priority_thread_weight_;
171 uint16_t invoke_transition_weight_;
172 bool dump_info_on_shutdown_;
173 int thread_pool_pthread_priority_;
Nicolas Geoffray4bf753d2020-12-14 20:33:53 +0000174 int zygote_thread_pool_pthread_priority_;
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100175 ProfileSaverOptions profile_saver_options_;
176
177 JitOptions()
178 : use_jit_compilation_(false),
Nicolas Geoffray4bf753d2020-12-14 20:33:53 +0000179 use_profiled_jit_compilation_(false),
Nicolas Geoffrayb0a97472019-12-05 15:17:46 +0000180 use_baseline_compiler_(false),
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100181 code_cache_initial_capacity_(0),
182 code_cache_max_capacity_(0),
183 compile_threshold_(0),
184 warmup_threshold_(0),
185 osr_threshold_(0),
186 priority_thread_weight_(0),
187 invoke_transition_weight_(0),
188 dump_info_on_shutdown_(false),
Nicolas Geoffray4bf753d2020-12-14 20:33:53 +0000189 thread_pool_pthread_priority_(kJitPoolThreadPthreadDefaultPriority),
190 zygote_thread_pool_pthread_priority_(kJitZygotePoolThreadPthreadDefaultPriority) {}
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100191
192 DISALLOW_COPY_AND_ASSIGN(JitOptions);
193};
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100194
David Srbecky46b53532019-08-06 13:39:05 +0100195// Implemented and provided by the compiler library.
196class JitCompilerInterface {
197 public:
198 virtual ~JitCompilerInterface() {}
199 virtual bool CompileMethod(
Nicolas Geoffray0d60a2b2020-06-17 14:31:56 +0100200 Thread* self, JitMemoryRegion* region, ArtMethod* method, CompilationKind compilation_kind)
David Srbeckyb41869a2019-08-07 12:12:52 +0100201 REQUIRES_SHARED(Locks::mutator_lock_) = 0;
David Srbecky46b53532019-08-06 13:39:05 +0100202 virtual void TypesLoaded(mirror::Class**, size_t count)
David Srbeckyb41869a2019-08-07 12:12:52 +0100203 REQUIRES_SHARED(Locks::mutator_lock_) = 0;
204 virtual bool GenerateDebugInfo() = 0;
205 virtual void ParseCompilerOptions() = 0;
David Srbecky8fc2f952019-07-31 18:40:09 +0100206
David Srbeckye09b87e2019-08-19 21:31:31 +0100207 virtual std::vector<uint8_t> PackElfFileForJIT(ArrayRef<const JITCodeEntry*> elf_files,
David Srbecky8fc2f952019-07-31 18:40:09 +0100208 ArrayRef<const void*> removed_symbols,
209 bool compress,
210 /*out*/ size_t* num_symbols) = 0;
David Srbecky46b53532019-08-06 13:39:05 +0100211};
212
Nicolas Geoffray57cacb72019-12-08 22:07:08 +0000213// Data structure holding information to perform an OSR.
214struct OsrData {
215 // The native PC to jump to.
216 const uint8_t* native_pc;
217
218 // The frame size of the compiled code to jump to.
219 size_t frame_size;
220
221 // The dynamically allocated memory of size `frame_size` to copy to stack.
222 void* memory[0];
223
224 static constexpr MemberOffset NativePcOffset() {
225 return MemberOffset(OFFSETOF_MEMBER(OsrData, native_pc));
226 }
227
228 static constexpr MemberOffset FrameSizeOffset() {
229 return MemberOffset(OFFSETOF_MEMBER(OsrData, frame_size));
230 }
231
232 static constexpr MemberOffset MemoryOffset() {
233 return MemberOffset(OFFSETOF_MEMBER(OsrData, memory));
234 }
235};
236
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800237class Jit {
238 public:
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100239 static constexpr size_t kDefaultPriorityThreadWeightRatio = 1000;
Nicolas Geoffraybd553eb2016-04-28 13:56:04 +0100240 static constexpr size_t kDefaultInvokeTransitionWeightRatio = 500;
buzbee42a09cb02017-02-01 09:08:31 -0800241 // How frequently should the interpreter check to see if OSR compilation is ready.
David Srbeckye3fc2d12018-11-30 13:41:14 +0000242 static constexpr int16_t kJitRecheckOSRThreshold = 101; // Prime number to avoid patterns.
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800243
David Srbecky21821472019-07-29 15:10:31 +0100244 DECLARE_RUNTIME_DEBUG_FLAG(kSlowMode);
245
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800246 virtual ~Jit();
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100247
248 // Create JIT itself.
249 static Jit* Create(JitCodeCache* code_cache, JitOptions* options);
250
Nicolas Geoffray0d60a2b2020-06-17 14:31:56 +0100251 bool CompileMethod(ArtMethod* method, Thread* self, CompilationKind compilation_kind, bool prejit)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700252 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100253
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800254 const JitCodeCache* GetCodeCache() const {
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100255 return code_cache_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800256 }
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100257
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800258 JitCodeCache* GetCodeCache() {
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100259 return code_cache_;
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800260 }
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100261
David Srbecky8fc2f952019-07-31 18:40:09 +0100262 JitCompilerInterface* GetJitCompiler() const {
263 return jit_compiler_;
264 }
265
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100266 void CreateThreadPool();
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800267 void DeleteThreadPool();
Mathieu Chartier93c21ba2018-12-10 13:08:30 -0800268 void WaitForWorkersToBeCreated();
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100269
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700270 // Dump interesting info: #methods compiled, code vs data size, compile / verify cumulative
271 // loggers.
Nicolas Geoffraya4f81542016-03-08 16:57:48 +0000272 void DumpInfo(std::ostream& os) REQUIRES(!lock_);
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700273 // Add a timing logger to cumulative_timings_.
274 void AddTimingLogger(const TimingLogger& logger);
Nicolas Geoffraya4f81542016-03-08 16:57:48 +0000275
276 void AddMemoryUsage(ArtMethod* method, size_t bytes)
277 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700278 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffraya4f81542016-03-08 16:57:48 +0000279
Nicolas Geoffrayf9dbb972020-08-27 15:21:11 +0100280 int GetThreadPoolPthreadPriority() const {
281 return options_->GetThreadPoolPthreadPriority();
282 }
283
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100284 uint16_t OSRMethodThreshold() const {
285 return options_->GetOsrThreshold();
Mathieu Chartiera50f9cf2015-09-25 11:34:45 -0700286 }
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800287
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100288 uint16_t HotMethodThreshold() const {
289 return options_->GetCompileThreshold();
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100290 }
291
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100292 uint16_t WarmMethodThreshold() const {
293 return options_->GetWarmupThreshold();
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100294 }
295
296 uint16_t PriorityThreadWeight() const {
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100297 return options_->GetPriorityThreadWeight();
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100298 }
299
Nicolas Geoffraya48c3df2019-06-27 13:11:12 +0000300 // Return whether we should do JIT compilation. Note this will returns false
301 // if we only need to save profile information and not compile methods.
Nicolas Geoffray2fef66b2019-06-26 22:00:02 +0000302 bool UseJitCompilation() const {
303 return options_->UseJitCompilation();
304 }
Calin Juravleffc87072016-04-20 14:22:09 +0100305
Calin Juravle138dbff2016-06-28 19:36:58 +0100306 bool GetSaveProfilingInfo() const {
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100307 return options_->GetSaveProfilingInfo();
Calin Juravleffc87072016-04-20 14:22:09 +0100308 }
309
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100310 // Wait until there is no more pending compilation tasks.
311 void WaitForCompilationToFinish(Thread* self);
312
313 // Profiling methods.
314 void MethodEntered(Thread* thread, ArtMethod* method)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700315 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100316
David Srbeckye3fc2d12018-11-30 13:41:14 +0000317 ALWAYS_INLINE void AddSamples(Thread* self,
318 ArtMethod* method,
319 uint16_t samples,
320 bool with_backedges)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700321 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100322
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100323 void NotifyInterpreterToCompiledCodeTransition(Thread* self, ArtMethod* caller)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700324 REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray60d4abc2020-07-27 13:58:51 +0000325 if (!IgnoreSamplesForMethod(caller)) {
326 AddSamples(self, caller, options_->GetInvokeTransitionWeight(), false);
327 }
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100328 }
329
330 void NotifyCompiledCodeToInterpreterTransition(Thread* self, ArtMethod* callee)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700331 REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray60d4abc2020-07-27 13:58:51 +0000332 if (!IgnoreSamplesForMethod(callee)) {
333 AddSamples(self, callee, options_->GetInvokeTransitionWeight(), false);
334 }
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100335 }
336
Calin Juravlec90bc922016-02-24 10:13:09 +0000337 // Starts the profile saver if the config options allow profile recording.
338 // The profile will be stored in the specified `filename` and will contain
339 // information collected from the given `code_paths` (a set of dex locations).
Calin Juravlec90bc922016-02-24 10:13:09 +0000340 void StartProfileSaver(const std::string& filename,
Calin Juravle77651c42017-03-03 18:04:02 -0800341 const std::vector<std::string>& code_paths);
Calin Juravle4d77b6a2015-12-01 18:38:09 +0000342 void StopProfileSaver();
Calin Juravle31f2c152015-10-23 17:56:15 +0100343
Calin Juravleb8e69992016-03-09 15:37:48 +0000344 void DumpForSigQuit(std::ostream& os) REQUIRES(!lock_);
Nicolas Geoffrayaee21562015-12-15 16:39:44 +0000345
Tamas Berghammer160e6df2016-01-05 14:29:02 +0000346 static void NewTypeLoadedIfUsingJit(mirror::Class* type)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700347 REQUIRES_SHARED(Locks::mutator_lock_);
Tamas Berghammer160e6df2016-01-05 14:29:02 +0000348
Tamas Berghammerfffbee42016-01-15 13:09:34 +0000349 // If debug info generation is turned on then write the type information for types already loaded
350 // into the specified class linker to the jit debug interface,
351 void DumpTypeInfoForLoadedTypes(ClassLinker* linker);
352
Nicolas Geoffray35122442016-03-02 12:05:30 +0000353 // Return whether we should try to JIT compiled code as soon as an ArtMethod is invoked.
Siva Chandra05d24152016-01-05 17:43:17 -0800354 bool JitAtFirstUse();
355
Nicolas Geoffray35122442016-03-02 12:05:30 +0000356 // Return whether we can invoke JIT code for `method`.
357 bool CanInvokeCompiledCode(ArtMethod* method);
358
Calin Juravleb2771b42016-04-07 17:09:25 +0100359 // Return whether the runtime should use a priority thread weight when sampling.
Vladimir Markoa710d912017-09-12 14:56:07 +0100360 static bool ShouldUsePriorityThreadWeight(Thread* self);
Calin Juravleb2771b42016-04-07 17:09:25 +0100361
Nicolas Geoffray57cacb72019-12-08 22:07:08 +0000362 // Return the information required to do an OSR jump. Return null if the OSR
363 // cannot be done.
364 OsrData* PrepareForOsr(ArtMethod* method, uint32_t dex_pc, uint32_t* vregs)
365 REQUIRES_SHARED(Locks::mutator_lock_);
366
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000367 // If an OSR compiled version is available for `method`,
368 // and `dex_pc + dex_pc_offset` is an entry point of that compiled
369 // version, this method will jump to the compiled code, let it run,
370 // and return true afterwards. Return false otherwise.
371 static bool MaybeDoOnStackReplacement(Thread* thread,
372 ArtMethod* method,
373 uint32_t dex_pc,
374 int32_t dex_pc_offset,
375 JValue* result)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700376 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000377
Nicolas Geoffraya7edd0d2018-11-07 03:18:16 +0000378 // Load the compiler library.
379 static bool LoadCompilerLibrary(std::string* error_msg);
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700380
Andreas Gampef149b3f2016-11-16 14:58:24 -0800381 ThreadPool* GetThreadPool() const {
382 return thread_pool_.get();
383 }
384
Nicolas Geoffray021c5f22016-12-16 11:22:05 +0000385 // Stop the JIT by waiting for all current compilations and enqueued compilations to finish.
386 void Stop();
387
388 // Start JIT threads.
389 void Start();
390
Nicolas Geoffrayce9ed362018-11-29 03:19:28 +0000391 // Transition to a child state.
Nicolas Geoffray0d54cfb2019-05-03 09:13:52 +0100392 void PostForkChildAction(bool is_system_server, bool is_zygote);
Nicolas Geoffrayce9ed362018-11-29 03:19:28 +0000393
394 // Prepare for forking.
395 void PreZygoteFork();
396
397 // Adjust state after forking.
398 void PostZygoteFork();
Nicolas Geoffrayc9de61c2018-11-27 17:34:31 +0000399
David Srbeckybfcea3d2019-08-05 15:44:00 +0100400 // Called when system finishes booting.
401 void BootCompleted();
402
Hans Boehmae7c8da2021-02-12 20:17:20 -0800403 // Are we in a zygote using JIT compilation?
404 static bool InZygoteUsingJit();
405
Nicolas Geoffray0f8950a2019-07-24 13:22:11 +0100406 // Compile methods from the given profile (.prof extension). If `add_to_queue`
407 // is true, methods in the profile are added to the JIT queue. Otherwise they are compiled
Nicolas Geoffray9ac09ee2019-05-08 23:38:27 +0100408 // directly.
Nicolas Geoffraye32d24c2019-07-05 10:28:59 +0100409 // Return the number of methods added to the queue.
410 uint32_t CompileMethodsFromProfile(Thread* self,
411 const std::vector<const DexFile*>& dex_files,
412 const std::string& profile_path,
413 Handle<mirror::ClassLoader> class_loader,
414 bool add_to_queue);
Nicolas Geoffray9ac09ee2019-05-08 23:38:27 +0100415
Nicolas Geoffray0f8950a2019-07-24 13:22:11 +0100416 // Compile methods from the given boot profile (.bprof extension). If `add_to_queue`
417 // is true, methods in the profile are added to the JIT queue. Otherwise they are compiled
418 // directly.
419 // Return the number of methods added to the queue.
420 uint32_t CompileMethodsFromBootProfile(Thread* self,
421 const std::vector<const DexFile*>& dex_files,
422 const std::string& profile_path,
423 Handle<mirror::ClassLoader> class_loader,
424 bool add_to_queue);
425
Nicolas Geoffray9ac09ee2019-05-08 23:38:27 +0100426 // Register the dex files to the JIT. This is to perform any compilation/optimization
427 // at the point of loading the dex files.
428 void RegisterDexFiles(const std::vector<std::unique_ptr<const DexFile>>& dex_files,
Nicolas Geoffray741a0702019-06-10 11:18:11 +0100429 jobject class_loader);
Nicolas Geoffrayde1b2a22019-02-27 09:10:57 +0000430
Nicolas Geoffraya48c3df2019-06-27 13:11:12 +0000431 // Called by the compiler to know whether it can directly encode the
432 // method/class/string.
Nicolas Geoffray05b41c42019-06-28 12:46:33 +0100433 bool CanEncodeMethod(ArtMethod* method, bool is_for_shared_region) const
434 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffraya48c3df2019-06-27 13:11:12 +0000435 bool CanEncodeClass(ObjPtr<mirror::Class> cls, bool is_for_shared_region) const
436 REQUIRES_SHARED(Locks::mutator_lock_);
437 bool CanEncodeString(ObjPtr<mirror::String> string, bool is_for_shared_region) const
438 REQUIRES_SHARED(Locks::mutator_lock_);
439 bool CanAssumeInitialized(ObjPtr<mirror::Class> cls, bool is_for_shared_region) const
440 REQUIRES_SHARED(Locks::mutator_lock_);
441
Nicolas Geoffray623d4f12019-09-30 13:45:51 +0100442 // Map boot image methods after all compilation in zygote has been done.
Nicolas Geoffray8e23d382019-10-30 13:53:01 +0000443 void MapBootImageMethods() REQUIRES(Locks::mutator_lock_);
Nicolas Geoffray623d4f12019-09-30 13:45:51 +0100444
Nicolas Geoffraye3884e32019-10-28 17:04:49 +0000445 // Notify to other processes that the zygote is done profile compiling boot
446 // class path methods.
447 void NotifyZygoteCompilationDone();
448
Nicolas Geoffraya59af8a2019-11-27 17:42:32 +0000449 void EnqueueOptimizedCompilation(ArtMethod* method, Thread* self);
450
Nicolas Geoffray00391822019-12-10 10:17:23 +0000451 void EnqueueCompilationFromNterp(ArtMethod* method, Thread* self)
452 REQUIRES_SHARED(Locks::mutator_lock_);
453
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800454 private:
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100455 Jit(JitCodeCache* code_cache, JitOptions* options);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800456
Nicolas Geoffray60d4abc2020-07-27 13:58:51 +0000457 // Whether we should not add hotness counts for the given method.
458 bool IgnoreSamplesForMethod(ArtMethod* method)
459 REQUIRES_SHARED(Locks::mutator_lock_);
460
Nicolas Geoffray0f8950a2019-07-24 13:22:11 +0100461 // Compile an individual method listed in a profile. If `add_to_queue` is
462 // true and the method was resolved, return true. Otherwise return false.
463 bool CompileMethodFromProfile(Thread* self,
464 ClassLinker* linker,
465 uint32_t method_idx,
466 Handle<mirror::DexCache> dex_cache,
467 Handle<mirror::ClassLoader> class_loader,
David Srbeckybfcea3d2019-08-05 15:44:00 +0100468 bool add_to_queue,
469 bool compile_after_boot)
Nicolas Geoffray0f8950a2019-07-24 13:22:11 +0100470 REQUIRES_SHARED(Locks::mutator_lock_);
471
David Srbeckye3fc2d12018-11-30 13:41:14 +0000472 // Compile the method if the number of samples passes a threshold.
473 // Returns false if we can not compile now - don't increment the counter and retry later.
474 bool MaybeCompileMethod(Thread* self,
475 ArtMethod* method,
476 uint32_t old_count,
477 uint32_t new_count,
478 bool with_backedges)
479 REQUIRES_SHARED(Locks::mutator_lock_);
480
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100481 static bool BindCompilerMethods(std::string* error_msg);
Mathieu Chartierc1bc4152016-03-24 17:22:52 -0700482
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800483 // JIT compiler
Mathieu Chartier72918ea2016-03-24 11:07:06 -0700484 static void* jit_library_handle_;
David Srbecky46b53532019-08-06 13:39:05 +0100485 static JitCompilerInterface* jit_compiler_;
486 static JitCompilerInterface* (*jit_load_)(void);
Nicolas Geoffrayc9de61c2018-11-27 17:34:31 +0000487 template <typename T> static bool LoadSymbol(T*, const char* symbol, std::string* error_msg);
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100488
Orion Hodsonad28f5e2018-10-17 09:08:17 +0100489 // JIT resources owned by runtime.
490 jit::JitCodeCache* const code_cache_;
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100491 const JitOptions* const options_;
492
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100493 std::unique_ptr<ThreadPool> thread_pool_;
Nicolas Geoffraydc2fbb62019-04-11 22:55:50 +0100494 std::vector<std::unique_ptr<OatDexFile>> type_lookup_tables_;
Nicolas Geoffray47b95802018-05-16 15:42:17 +0100495
David Srbeckybfcea3d2019-08-05 15:44:00 +0100496 Mutex boot_completed_lock_;
497 bool boot_completed_ GUARDED_BY(boot_completed_lock_) = false;
498 std::deque<Task*> tasks_after_boot_ GUARDED_BY(boot_completed_lock_);
499
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700500 // Performance monitoring.
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700501 CumulativeLogger cumulative_timings_;
Nicolas Geoffraya4f81542016-03-08 16:57:48 +0000502 Histogram<uint64_t> memory_use_ GUARDED_BY(lock_);
503 Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
Mathieu Chartiera4885cb2015-03-09 15:38:54 -0700504
Nicolas Geoffray623d4f12019-09-30 13:45:51 +0100505 // In the JIT zygote configuration, after all compilation is done, the zygote
506 // will copy its contents of the boot image to the zygote_mapping_methods_,
Nicolas Geoffraye3884e32019-10-28 17:04:49 +0000507 // which will be picked up by processes that will map the memory
Nicolas Geoffray623d4f12019-09-30 13:45:51 +0100508 // in-place within the boot image mapping.
509 //
Nicolas Geoffray623d4f12019-09-30 13:45:51 +0100510 // zygote_mapping_methods_ is shared memory only usable by the zygote and not
Nicolas Geoffraye3884e32019-10-28 17:04:49 +0000511 // inherited by child processes. We create it eagerly to ensure other
512 // processes cannot seal writable the file.
Nicolas Geoffray623d4f12019-09-30 13:45:51 +0100513 MemMap zygote_mapping_methods_;
Nicolas Geoffraye3884e32019-10-28 17:04:49 +0000514
515 // The file descriptor created through memfd_create pointing to memory holding
516 // boot image methods. Created by the zygote, and inherited by child
517 // processes. The descriptor will be closed in each process (including the
518 // zygote) once they don't need it.
519 android::base::unique_fd fd_methods_;
520
521 // The size of the memory pointed by `fd_methods_`. Cached here to avoid
522 // recomputing it.
523 size_t fd_methods_size_;
Nicolas Geoffray623d4f12019-09-30 13:45:51 +0100524
Mathieu Chartier3130cdf2015-05-03 15:20:23 -0700525 DISALLOW_COPY_AND_ASSIGN(Jit);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800526};
527
Andreas Gampef149b3f2016-11-16 14:58:24 -0800528// Helper class to stop the JIT for a given scope. This will wait for the JIT to quiesce.
529class ScopedJitSuspend {
530 public:
531 ScopedJitSuspend();
532 ~ScopedJitSuspend();
533
534 private:
535 bool was_on_;
536};
537
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800538} // namespace jit
539} // namespace art
540
541#endif // ART_RUNTIME_JIT_JIT_H_