xref: /aosp_15_r20/art/runtime/jit/jit.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_JIT_JIT_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_JIT_JIT_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include <unordered_set>
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker #include "app_info.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/histogram-inl.h"
26*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
27*795d594fSAndroid Build Coastguard Worker #include "base/mutex.h"
28*795d594fSAndroid Build Coastguard Worker #include "base/timing_logger.h"
29*795d594fSAndroid Build Coastguard Worker #include "compilation_kind.h"
30*795d594fSAndroid Build Coastguard Worker #include "handle.h"
31*795d594fSAndroid Build Coastguard Worker #include "interpreter/mterp/nterp.h"
32*795d594fSAndroid Build Coastguard Worker #include "jit/debugger_interface.h"
33*795d594fSAndroid Build Coastguard Worker #include "jit_options.h"
34*795d594fSAndroid Build Coastguard Worker #include "obj_ptr.h"
35*795d594fSAndroid Build Coastguard Worker #include "offsets.h"
36*795d594fSAndroid Build Coastguard Worker #include "thread_pool.h"
37*795d594fSAndroid Build Coastguard Worker 
38*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
39*795d594fSAndroid Build Coastguard Worker 
40*795d594fSAndroid Build Coastguard Worker class ArtMethod;
41*795d594fSAndroid Build Coastguard Worker class ClassLinker;
42*795d594fSAndroid Build Coastguard Worker class DexFile;
43*795d594fSAndroid Build Coastguard Worker class OatDexFile;
44*795d594fSAndroid Build Coastguard Worker class RootVisitor;
45*795d594fSAndroid Build Coastguard Worker struct RuntimeArgumentMap;
46*795d594fSAndroid Build Coastguard Worker union JValue;
47*795d594fSAndroid Build Coastguard Worker 
48*795d594fSAndroid Build Coastguard Worker namespace mirror {
49*795d594fSAndroid Build Coastguard Worker class Object;
50*795d594fSAndroid Build Coastguard Worker class Class;
51*795d594fSAndroid Build Coastguard Worker class ClassLoader;
52*795d594fSAndroid Build Coastguard Worker class DexCache;
53*795d594fSAndroid Build Coastguard Worker class String;
54*795d594fSAndroid Build Coastguard Worker }   // namespace mirror
55*795d594fSAndroid Build Coastguard Worker 
56*795d594fSAndroid Build Coastguard Worker namespace jit {
57*795d594fSAndroid Build Coastguard Worker 
58*795d594fSAndroid Build Coastguard Worker class JitCodeCache;
59*795d594fSAndroid Build Coastguard Worker class JitCompileTask;
60*795d594fSAndroid Build Coastguard Worker class JitMemoryRegion;
61*795d594fSAndroid Build Coastguard Worker class JitOptions;
62*795d594fSAndroid Build Coastguard Worker 
63*795d594fSAndroid Build Coastguard Worker static constexpr int16_t kJitCheckForOSR = -1;
64*795d594fSAndroid Build Coastguard Worker static constexpr int16_t kJitHotnessDisabled = -2;
65*795d594fSAndroid Build Coastguard Worker 
66*795d594fSAndroid Build Coastguard Worker // Implemented and provided by the compiler library.
67*795d594fSAndroid Build Coastguard Worker class JitCompilerInterface {
68*795d594fSAndroid Build Coastguard Worker  public:
~JitCompilerInterface()69*795d594fSAndroid Build Coastguard Worker   virtual ~JitCompilerInterface() {}
70*795d594fSAndroid Build Coastguard Worker   virtual bool CompileMethod(
71*795d594fSAndroid Build Coastguard Worker       Thread* self, JitMemoryRegion* region, ArtMethod* method, CompilationKind compilation_kind)
72*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
73*795d594fSAndroid Build Coastguard Worker   virtual void TypesLoaded(mirror::Class**, size_t count)
74*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
75*795d594fSAndroid Build Coastguard Worker   virtual bool GenerateDebugInfo() = 0;
76*795d594fSAndroid Build Coastguard Worker   virtual void ParseCompilerOptions() = 0;
77*795d594fSAndroid Build Coastguard Worker   virtual bool IsBaselineCompiler() const = 0;
78*795d594fSAndroid Build Coastguard Worker   virtual void SetDebuggableCompilerOption(bool value) = 0;
79*795d594fSAndroid Build Coastguard Worker   virtual uint32_t GetInlineMaxCodeUnits() const = 0;
80*795d594fSAndroid Build Coastguard Worker 
81*795d594fSAndroid Build Coastguard Worker   virtual std::vector<uint8_t> PackElfFileForJIT(ArrayRef<const JITCodeEntry*> elf_files,
82*795d594fSAndroid Build Coastguard Worker                                                  ArrayRef<const void*> removed_symbols,
83*795d594fSAndroid Build Coastguard Worker                                                  bool compress,
84*795d594fSAndroid Build Coastguard Worker                                                  /*out*/ size_t* num_symbols) = 0;
85*795d594fSAndroid Build Coastguard Worker };
86*795d594fSAndroid Build Coastguard Worker 
87*795d594fSAndroid Build Coastguard Worker // Data structure holding information to perform an OSR.
88*795d594fSAndroid Build Coastguard Worker struct OsrData {
89*795d594fSAndroid Build Coastguard Worker   // The native PC to jump to.
90*795d594fSAndroid Build Coastguard Worker   const uint8_t* native_pc;
91*795d594fSAndroid Build Coastguard Worker 
92*795d594fSAndroid Build Coastguard Worker   // The frame size of the compiled code to jump to.
93*795d594fSAndroid Build Coastguard Worker   size_t frame_size;
94*795d594fSAndroid Build Coastguard Worker 
95*795d594fSAndroid Build Coastguard Worker   // The dynamically allocated memory of size `frame_size` to copy to stack.
96*795d594fSAndroid Build Coastguard Worker   void* memory[0];
97*795d594fSAndroid Build Coastguard Worker 
NativePcOffsetOsrData98*795d594fSAndroid Build Coastguard Worker   static constexpr MemberOffset NativePcOffset() {
99*795d594fSAndroid Build Coastguard Worker     return MemberOffset(OFFSETOF_MEMBER(OsrData, native_pc));
100*795d594fSAndroid Build Coastguard Worker   }
101*795d594fSAndroid Build Coastguard Worker 
FrameSizeOffsetOsrData102*795d594fSAndroid Build Coastguard Worker   static constexpr MemberOffset FrameSizeOffset() {
103*795d594fSAndroid Build Coastguard Worker     return MemberOffset(OFFSETOF_MEMBER(OsrData, frame_size));
104*795d594fSAndroid Build Coastguard Worker   }
105*795d594fSAndroid Build Coastguard Worker 
MemoryOffsetOsrData106*795d594fSAndroid Build Coastguard Worker   static constexpr MemberOffset MemoryOffset() {
107*795d594fSAndroid Build Coastguard Worker     return MemberOffset(OFFSETOF_MEMBER(OsrData, memory));
108*795d594fSAndroid Build Coastguard Worker   }
109*795d594fSAndroid Build Coastguard Worker };
110*795d594fSAndroid Build Coastguard Worker 
111*795d594fSAndroid Build Coastguard Worker /**
112*795d594fSAndroid Build Coastguard Worker  * A customized thread pool for the JIT, to prioritize compilation kinds, and
113*795d594fSAndroid Build Coastguard Worker  * simplify root visiting.
114*795d594fSAndroid Build Coastguard Worker  */
115*795d594fSAndroid Build Coastguard Worker class JitThreadPool : public AbstractThreadPool {
116*795d594fSAndroid Build Coastguard Worker  public:
117*795d594fSAndroid Build Coastguard Worker   static JitThreadPool* Create(const char* name,
118*795d594fSAndroid Build Coastguard Worker                                size_t num_threads,
119*795d594fSAndroid Build Coastguard Worker                                size_t worker_stack_size = ThreadPoolWorker::kDefaultStackSize) {
120*795d594fSAndroid Build Coastguard Worker     JitThreadPool* pool = new JitThreadPool(name, num_threads, worker_stack_size);
121*795d594fSAndroid Build Coastguard Worker     pool->CreateThreads();
122*795d594fSAndroid Build Coastguard Worker     return pool;
123*795d594fSAndroid Build Coastguard Worker   }
124*795d594fSAndroid Build Coastguard Worker 
125*795d594fSAndroid Build Coastguard Worker   // Add a task to the generic queue. This is for tasks like
126*795d594fSAndroid Build Coastguard Worker   // ZygoteVerificationTask, or JitCompileTask for precompile.
127*795d594fSAndroid Build Coastguard Worker   void AddTask(Thread* self, Task* task) REQUIRES(!task_queue_lock_) override;
128*795d594fSAndroid Build Coastguard Worker   size_t GetTaskCount(Thread* self) REQUIRES(!task_queue_lock_) override;
129*795d594fSAndroid Build Coastguard Worker   void RemoveAllTasks(Thread* self) REQUIRES(!task_queue_lock_) override;
130*795d594fSAndroid Build Coastguard Worker   ~JitThreadPool() override;
131*795d594fSAndroid Build Coastguard Worker 
132*795d594fSAndroid Build Coastguard Worker   // Remove the task from the list of compiling tasks.
133*795d594fSAndroid Build Coastguard Worker   void Remove(JitCompileTask* task) REQUIRES(!task_queue_lock_);
134*795d594fSAndroid Build Coastguard Worker 
135*795d594fSAndroid Build Coastguard Worker   // Add a custom compilation task in the right queue.
136*795d594fSAndroid Build Coastguard Worker   void AddTask(Thread* self, ArtMethod* method, CompilationKind kind) REQUIRES(!task_queue_lock_);
137*795d594fSAndroid Build Coastguard Worker 
138*795d594fSAndroid Build Coastguard Worker   // Visit the ArtMethods stored in the various queues.
139*795d594fSAndroid Build Coastguard Worker   void VisitRoots(RootVisitor* visitor);
140*795d594fSAndroid Build Coastguard Worker 
141*795d594fSAndroid Build Coastguard Worker  protected:
142*795d594fSAndroid Build Coastguard Worker   Task* TryGetTaskLocked() REQUIRES(task_queue_lock_) override;
143*795d594fSAndroid Build Coastguard Worker 
HasOutstandingTasks()144*795d594fSAndroid Build Coastguard Worker   bool HasOutstandingTasks() const REQUIRES(task_queue_lock_) override {
145*795d594fSAndroid Build Coastguard Worker     return started_ &&
146*795d594fSAndroid Build Coastguard Worker         (!generic_queue_.empty() ||
147*795d594fSAndroid Build Coastguard Worker          !baseline_queue_.empty() ||
148*795d594fSAndroid Build Coastguard Worker          !optimized_queue_.empty() ||
149*795d594fSAndroid Build Coastguard Worker          !osr_queue_.empty());
150*795d594fSAndroid Build Coastguard Worker   }
151*795d594fSAndroid Build Coastguard Worker 
152*795d594fSAndroid Build Coastguard Worker  private:
JitThreadPool(const char * name,size_t num_threads,size_t worker_stack_size)153*795d594fSAndroid Build Coastguard Worker   JitThreadPool(const char* name,
154*795d594fSAndroid Build Coastguard Worker                 size_t num_threads,
155*795d594fSAndroid Build Coastguard Worker                 size_t worker_stack_size)
156*795d594fSAndroid Build Coastguard Worker       // We need peers as we may report the JIT thread, e.g., in the debugger.
157*795d594fSAndroid Build Coastguard Worker       : AbstractThreadPool(name, num_threads, /* create_peers= */ true, worker_stack_size) {}
158*795d594fSAndroid Build Coastguard Worker 
159*795d594fSAndroid Build Coastguard Worker   // Try to fetch an entry from `methods`. Return null if `methods` is empty.
160*795d594fSAndroid Build Coastguard Worker   Task* FetchFrom(std::deque<ArtMethod*>& methods, CompilationKind kind) REQUIRES(task_queue_lock_);
161*795d594fSAndroid Build Coastguard Worker 
162*795d594fSAndroid Build Coastguard Worker   std::deque<Task*> generic_queue_ GUARDED_BY(task_queue_lock_);
163*795d594fSAndroid Build Coastguard Worker 
164*795d594fSAndroid Build Coastguard Worker   std::deque<ArtMethod*> osr_queue_ GUARDED_BY(task_queue_lock_);
165*795d594fSAndroid Build Coastguard Worker   std::deque<ArtMethod*> baseline_queue_ GUARDED_BY(task_queue_lock_);
166*795d594fSAndroid Build Coastguard Worker   std::deque<ArtMethod*> optimized_queue_ GUARDED_BY(task_queue_lock_);
167*795d594fSAndroid Build Coastguard Worker 
168*795d594fSAndroid Build Coastguard Worker   // We track the methods that are currently enqueued to avoid
169*795d594fSAndroid Build Coastguard Worker   // adding them to the queue multiple times, which could bloat the
170*795d594fSAndroid Build Coastguard Worker   // queues.
171*795d594fSAndroid Build Coastguard Worker   std::set<ArtMethod*> osr_enqueued_methods_ GUARDED_BY(task_queue_lock_);
172*795d594fSAndroid Build Coastguard Worker   std::set<ArtMethod*> baseline_enqueued_methods_ GUARDED_BY(task_queue_lock_);
173*795d594fSAndroid Build Coastguard Worker   std::set<ArtMethod*> optimized_enqueued_methods_ GUARDED_BY(task_queue_lock_);
174*795d594fSAndroid Build Coastguard Worker 
175*795d594fSAndroid Build Coastguard Worker   // A set to keep track of methods that are currently being compiled. Entries
176*795d594fSAndroid Build Coastguard Worker   // will be removed when JitCompileTask->Finalize is called.
177*795d594fSAndroid Build Coastguard Worker   std::unordered_set<JitCompileTask*> current_compilations_ GUARDED_BY(task_queue_lock_);
178*795d594fSAndroid Build Coastguard Worker 
179*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(JitThreadPool);
180*795d594fSAndroid Build Coastguard Worker };
181*795d594fSAndroid Build Coastguard Worker 
182*795d594fSAndroid Build Coastguard Worker class Jit {
183*795d594fSAndroid Build Coastguard Worker  public:
184*795d594fSAndroid Build Coastguard Worker   // How frequently should the interpreter check to see if OSR compilation is ready.
185*795d594fSAndroid Build Coastguard Worker   static constexpr int16_t kJitRecheckOSRThreshold = 101;  // Prime number to avoid patterns.
186*795d594fSAndroid Build Coastguard Worker 
187*795d594fSAndroid Build Coastguard Worker   virtual ~Jit();
188*795d594fSAndroid Build Coastguard Worker 
189*795d594fSAndroid Build Coastguard Worker   // Create JIT itself.
190*795d594fSAndroid Build Coastguard Worker   static std::unique_ptr<Jit> Create(JitCodeCache* code_cache, JitOptions* options);
191*795d594fSAndroid Build Coastguard Worker 
192*795d594fSAndroid Build Coastguard Worker   EXPORT bool CompileMethod(ArtMethod* method,
193*795d594fSAndroid Build Coastguard Worker                             Thread* self,
194*795d594fSAndroid Build Coastguard Worker                             CompilationKind compilation_kind,
195*795d594fSAndroid Build Coastguard Worker                             bool prejit) REQUIRES_SHARED(Locks::mutator_lock_);
196*795d594fSAndroid Build Coastguard Worker 
197*795d594fSAndroid Build Coastguard Worker   void VisitRoots(RootVisitor* visitor);
198*795d594fSAndroid Build Coastguard Worker 
GetCodeCache()199*795d594fSAndroid Build Coastguard Worker   const JitCodeCache* GetCodeCache() const {
200*795d594fSAndroid Build Coastguard Worker     return code_cache_;
201*795d594fSAndroid Build Coastguard Worker   }
202*795d594fSAndroid Build Coastguard Worker 
GetCodeCache()203*795d594fSAndroid Build Coastguard Worker   JitCodeCache* GetCodeCache() {
204*795d594fSAndroid Build Coastguard Worker     return code_cache_;
205*795d594fSAndroid Build Coastguard Worker   }
206*795d594fSAndroid Build Coastguard Worker 
GetJitCompiler()207*795d594fSAndroid Build Coastguard Worker   JitCompilerInterface* GetJitCompiler() const {
208*795d594fSAndroid Build Coastguard Worker     return jit_compiler_;
209*795d594fSAndroid Build Coastguard Worker   }
210*795d594fSAndroid Build Coastguard Worker 
211*795d594fSAndroid Build Coastguard Worker   void CreateThreadPool();
212*795d594fSAndroid Build Coastguard Worker   void DeleteThreadPool();
213*795d594fSAndroid Build Coastguard Worker   void WaitForWorkersToBeCreated();
214*795d594fSAndroid Build Coastguard Worker 
215*795d594fSAndroid Build Coastguard Worker   // Dump interesting info: #methods compiled, code vs data size, compile / verify cumulative
216*795d594fSAndroid Build Coastguard Worker   // loggers.
217*795d594fSAndroid Build Coastguard Worker   void DumpInfo(std::ostream& os) REQUIRES(!lock_);
218*795d594fSAndroid Build Coastguard Worker   // Add a timing logger to cumulative_timings_.
219*795d594fSAndroid Build Coastguard Worker   void AddTimingLogger(const TimingLogger& logger);
220*795d594fSAndroid Build Coastguard Worker 
221*795d594fSAndroid Build Coastguard Worker   void AddMemoryUsage(ArtMethod* method, size_t bytes)
222*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
223*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
224*795d594fSAndroid Build Coastguard Worker 
GetThreadPoolPthreadPriority()225*795d594fSAndroid Build Coastguard Worker   int GetThreadPoolPthreadPriority() const {
226*795d594fSAndroid Build Coastguard Worker     return options_->GetThreadPoolPthreadPriority();
227*795d594fSAndroid Build Coastguard Worker   }
228*795d594fSAndroid Build Coastguard Worker 
GetZygoteThreadPoolPthreadPriority()229*795d594fSAndroid Build Coastguard Worker   int GetZygoteThreadPoolPthreadPriority() const {
230*795d594fSAndroid Build Coastguard Worker     return options_->GetZygoteThreadPoolPthreadPriority();
231*795d594fSAndroid Build Coastguard Worker   }
232*795d594fSAndroid Build Coastguard Worker 
HotMethodThreshold()233*795d594fSAndroid Build Coastguard Worker   uint16_t HotMethodThreshold() const {
234*795d594fSAndroid Build Coastguard Worker     return options_->GetOptimizeThreshold();
235*795d594fSAndroid Build Coastguard Worker   }
236*795d594fSAndroid Build Coastguard Worker 
WarmMethodThreshold()237*795d594fSAndroid Build Coastguard Worker   uint16_t WarmMethodThreshold() const {
238*795d594fSAndroid Build Coastguard Worker     return options_->GetWarmupThreshold();
239*795d594fSAndroid Build Coastguard Worker   }
240*795d594fSAndroid Build Coastguard Worker 
PriorityThreadWeight()241*795d594fSAndroid Build Coastguard Worker   uint16_t PriorityThreadWeight() const {
242*795d594fSAndroid Build Coastguard Worker     return options_->GetPriorityThreadWeight();
243*795d594fSAndroid Build Coastguard Worker   }
244*795d594fSAndroid Build Coastguard Worker 
245*795d594fSAndroid Build Coastguard Worker   // Return whether we should do JIT compilation. Note this will returns false
246*795d594fSAndroid Build Coastguard Worker   // if we only need to save profile information and not compile methods.
UseJitCompilation()247*795d594fSAndroid Build Coastguard Worker   bool UseJitCompilation() const {
248*795d594fSAndroid Build Coastguard Worker     return options_->UseJitCompilation();
249*795d594fSAndroid Build Coastguard Worker   }
250*795d594fSAndroid Build Coastguard Worker 
GetSaveProfilingInfo()251*795d594fSAndroid Build Coastguard Worker   bool GetSaveProfilingInfo() const {
252*795d594fSAndroid Build Coastguard Worker     return options_->GetSaveProfilingInfo();
253*795d594fSAndroid Build Coastguard Worker   }
254*795d594fSAndroid Build Coastguard Worker 
255*795d594fSAndroid Build Coastguard Worker   // Wait until there is no more pending compilation tasks.
256*795d594fSAndroid Build Coastguard Worker   EXPORT void WaitForCompilationToFinish(Thread* self);
257*795d594fSAndroid Build Coastguard Worker 
258*795d594fSAndroid Build Coastguard Worker   // Profiling methods.
259*795d594fSAndroid Build Coastguard Worker   void MethodEntered(Thread* thread, ArtMethod* method)
260*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
261*795d594fSAndroid Build Coastguard Worker 
262*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void AddSamples(Thread* self, ArtMethod* method)
263*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
264*795d594fSAndroid Build Coastguard Worker 
NotifyInterpreterToCompiledCodeTransition(Thread * self,ArtMethod * caller)265*795d594fSAndroid Build Coastguard Worker   void NotifyInterpreterToCompiledCodeTransition(Thread* self, ArtMethod* caller)
266*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
267*795d594fSAndroid Build Coastguard Worker     AddSamples(self, caller);
268*795d594fSAndroid Build Coastguard Worker   }
269*795d594fSAndroid Build Coastguard Worker 
NotifyCompiledCodeToInterpreterTransition(Thread * self,ArtMethod * callee)270*795d594fSAndroid Build Coastguard Worker   void NotifyCompiledCodeToInterpreterTransition(Thread* self, ArtMethod* callee)
271*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
272*795d594fSAndroid Build Coastguard Worker     AddSamples(self, callee);
273*795d594fSAndroid Build Coastguard Worker   }
274*795d594fSAndroid Build Coastguard Worker 
275*795d594fSAndroid Build Coastguard Worker   // Starts the profile saver if the config options allow profile recording.
276*795d594fSAndroid Build Coastguard Worker   // The profile will be stored in the specified `profile_filename` and will contain
277*795d594fSAndroid Build Coastguard Worker   // information collected from the given `code_paths` (a set of dex locations).
278*795d594fSAndroid Build Coastguard Worker   //
279*795d594fSAndroid Build Coastguard Worker   // The `ref_profile_filename` denotes the path to the reference profile which
280*795d594fSAndroid Build Coastguard Worker   // might be queried to determine if an initial save should be done earlier.
281*795d594fSAndroid Build Coastguard Worker   // It can be empty indicating there is no reference profile.
282*795d594fSAndroid Build Coastguard Worker   void StartProfileSaver(const std::string& profile_filename,
283*795d594fSAndroid Build Coastguard Worker                          const std::vector<std::string>& code_paths,
284*795d594fSAndroid Build Coastguard Worker                          const std::string& ref_profile_filename,
285*795d594fSAndroid Build Coastguard Worker                          AppInfo::CodeType code_type);
286*795d594fSAndroid Build Coastguard Worker   void StopProfileSaver();
287*795d594fSAndroid Build Coastguard Worker 
288*795d594fSAndroid Build Coastguard Worker   void DumpForSigQuit(std::ostream& os) REQUIRES(!lock_);
289*795d594fSAndroid Build Coastguard Worker 
290*795d594fSAndroid Build Coastguard Worker   static void NewTypeLoadedIfUsingJit(mirror::Class* type)
291*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
292*795d594fSAndroid Build Coastguard Worker 
293*795d594fSAndroid Build Coastguard Worker   // If debug info generation is turned on then write the type information for types already loaded
294*795d594fSAndroid Build Coastguard Worker   // into the specified class linker to the jit debug interface,
295*795d594fSAndroid Build Coastguard Worker   void DumpTypeInfoForLoadedTypes(ClassLinker* linker);
296*795d594fSAndroid Build Coastguard Worker 
297*795d594fSAndroid Build Coastguard Worker   // Return whether we should try to JIT compiled code as soon as an ArtMethod is invoked.
298*795d594fSAndroid Build Coastguard Worker   EXPORT bool JitAtFirstUse();
299*795d594fSAndroid Build Coastguard Worker 
300*795d594fSAndroid Build Coastguard Worker   // Return whether we can invoke JIT code for `method`.
301*795d594fSAndroid Build Coastguard Worker   bool CanInvokeCompiledCode(ArtMethod* method);
302*795d594fSAndroid Build Coastguard Worker 
303*795d594fSAndroid Build Coastguard Worker   // Return the information required to do an OSR jump. Return null if the OSR
304*795d594fSAndroid Build Coastguard Worker   // cannot be done.
305*795d594fSAndroid Build Coastguard Worker   OsrData* PrepareForOsr(ArtMethod* method, uint32_t dex_pc, uint32_t* vregs)
306*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
307*795d594fSAndroid Build Coastguard Worker 
308*795d594fSAndroid Build Coastguard Worker   // If an OSR compiled version is available for `method`,
309*795d594fSAndroid Build Coastguard Worker   // and `dex_pc + dex_pc_offset` is an entry point of that compiled
310*795d594fSAndroid Build Coastguard Worker   // version, this method will jump to the compiled code, let it run,
311*795d594fSAndroid Build Coastguard Worker   // and return true afterwards. Return false otherwise.
312*795d594fSAndroid Build Coastguard Worker   static bool MaybeDoOnStackReplacement(Thread* thread,
313*795d594fSAndroid Build Coastguard Worker                                         ArtMethod* method,
314*795d594fSAndroid Build Coastguard Worker                                         uint32_t dex_pc,
315*795d594fSAndroid Build Coastguard Worker                                         int32_t dex_pc_offset,
316*795d594fSAndroid Build Coastguard Worker                                         JValue* result)
317*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
318*795d594fSAndroid Build Coastguard Worker 
GetThreadPool()319*795d594fSAndroid Build Coastguard Worker   JitThreadPool* GetThreadPool() const {
320*795d594fSAndroid Build Coastguard Worker     return thread_pool_.get();
321*795d594fSAndroid Build Coastguard Worker   }
322*795d594fSAndroid Build Coastguard Worker 
323*795d594fSAndroid Build Coastguard Worker   // Stop the JIT by waiting for all current compilations and enqueued compilations to finish.
324*795d594fSAndroid Build Coastguard Worker   EXPORT void Stop();
325*795d594fSAndroid Build Coastguard Worker 
326*795d594fSAndroid Build Coastguard Worker   // Start JIT threads.
327*795d594fSAndroid Build Coastguard Worker   EXPORT void Start();
328*795d594fSAndroid Build Coastguard Worker 
329*795d594fSAndroid Build Coastguard Worker   // Transition to a child state.
330*795d594fSAndroid Build Coastguard Worker   EXPORT void PostForkChildAction(bool is_system_server, bool is_zygote);
331*795d594fSAndroid Build Coastguard Worker 
332*795d594fSAndroid Build Coastguard Worker   // Prepare for forking.
333*795d594fSAndroid Build Coastguard Worker   EXPORT void PreZygoteFork();
334*795d594fSAndroid Build Coastguard Worker 
335*795d594fSAndroid Build Coastguard Worker   // Adjust state after forking.
336*795d594fSAndroid Build Coastguard Worker   void PostZygoteFork();
337*795d594fSAndroid Build Coastguard Worker 
338*795d594fSAndroid Build Coastguard Worker   // Add a task to the queue, ensuring it runs after boot is finished.
339*795d594fSAndroid Build Coastguard Worker   void AddPostBootTask(Thread* self, Task* task);
340*795d594fSAndroid Build Coastguard Worker 
341*795d594fSAndroid Build Coastguard Worker   // Called when system finishes booting.
342*795d594fSAndroid Build Coastguard Worker   void BootCompleted();
343*795d594fSAndroid Build Coastguard Worker 
344*795d594fSAndroid Build Coastguard Worker   // Are we in a zygote using JIT compilation?
345*795d594fSAndroid Build Coastguard Worker   static bool InZygoteUsingJit();
346*795d594fSAndroid Build Coastguard Worker 
347*795d594fSAndroid Build Coastguard Worker   // Compile methods from the given profile (.prof extension). If `add_to_queue`
348*795d594fSAndroid Build Coastguard Worker   // is true, methods in the profile are added to the JIT queue. Otherwise they are compiled
349*795d594fSAndroid Build Coastguard Worker   // directly.
350*795d594fSAndroid Build Coastguard Worker   // Return the number of methods added to the queue.
351*795d594fSAndroid Build Coastguard Worker   uint32_t CompileMethodsFromProfile(Thread* self,
352*795d594fSAndroid Build Coastguard Worker                                      const std::vector<const DexFile*>& dex_files,
353*795d594fSAndroid Build Coastguard Worker                                      const std::string& profile_path,
354*795d594fSAndroid Build Coastguard Worker                                      Handle<mirror::ClassLoader> class_loader,
355*795d594fSAndroid Build Coastguard Worker                                      bool add_to_queue);
356*795d594fSAndroid Build Coastguard Worker 
357*795d594fSAndroid Build Coastguard Worker   // Compile methods from the given boot profile (.bprof extension). If `add_to_queue`
358*795d594fSAndroid Build Coastguard Worker   // is true, methods in the profile are added to the JIT queue. Otherwise they are compiled
359*795d594fSAndroid Build Coastguard Worker   // directly.
360*795d594fSAndroid Build Coastguard Worker   // Return the number of methods added to the queue.
361*795d594fSAndroid Build Coastguard Worker   uint32_t CompileMethodsFromBootProfile(Thread* self,
362*795d594fSAndroid Build Coastguard Worker                                          const std::vector<const DexFile*>& dex_files,
363*795d594fSAndroid Build Coastguard Worker                                          const std::string& profile_path,
364*795d594fSAndroid Build Coastguard Worker                                          Handle<mirror::ClassLoader> class_loader,
365*795d594fSAndroid Build Coastguard Worker                                          bool add_to_queue);
366*795d594fSAndroid Build Coastguard Worker 
367*795d594fSAndroid Build Coastguard Worker   // Register the dex files to the JIT. This is to perform any compilation/optimization
368*795d594fSAndroid Build Coastguard Worker   // at the point of loading the dex files.
369*795d594fSAndroid Build Coastguard Worker   void RegisterDexFiles(const std::vector<std::unique_ptr<const DexFile>>& dex_files,
370*795d594fSAndroid Build Coastguard Worker                         jobject class_loader);
371*795d594fSAndroid Build Coastguard Worker 
372*795d594fSAndroid Build Coastguard Worker   // Called by the compiler to know whether it can directly encode the
373*795d594fSAndroid Build Coastguard Worker   // method/class/string.
374*795d594fSAndroid Build Coastguard Worker   bool CanEncodeMethod(ArtMethod* method, bool is_for_shared_region) const
375*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
376*795d594fSAndroid Build Coastguard Worker   bool CanEncodeClass(ObjPtr<mirror::Class> cls, bool is_for_shared_region) const
377*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
378*795d594fSAndroid Build Coastguard Worker   bool CanEncodeString(ObjPtr<mirror::String> string, bool is_for_shared_region) const
379*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
380*795d594fSAndroid Build Coastguard Worker   bool CanAssumeInitialized(ObjPtr<mirror::Class> cls, bool is_for_shared_region) const
381*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
382*795d594fSAndroid Build Coastguard Worker 
383*795d594fSAndroid Build Coastguard Worker   // Map boot image methods after all compilation in zygote has been done.
384*795d594fSAndroid Build Coastguard Worker   void MapBootImageMethods() REQUIRES(Locks::mutator_lock_);
385*795d594fSAndroid Build Coastguard Worker 
386*795d594fSAndroid Build Coastguard Worker   // Notify to other processes that the zygote is done profile compiling boot
387*795d594fSAndroid Build Coastguard Worker   // class path methods.
388*795d594fSAndroid Build Coastguard Worker   void NotifyZygoteCompilationDone();
389*795d594fSAndroid Build Coastguard Worker 
390*795d594fSAndroid Build Coastguard Worker   EXPORT void EnqueueOptimizedCompilation(ArtMethod* method, Thread* self);
391*795d594fSAndroid Build Coastguard Worker 
392*795d594fSAndroid Build Coastguard Worker   EXPORT void MaybeEnqueueCompilation(ArtMethod* method, Thread* self)
393*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
394*795d594fSAndroid Build Coastguard Worker 
395*795d594fSAndroid Build Coastguard Worker   EXPORT static bool TryPatternMatch(ArtMethod* method, CompilationKind compilation_kind)
396*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
397*795d594fSAndroid Build Coastguard Worker 
398*795d594fSAndroid Build Coastguard Worker  private:
399*795d594fSAndroid Build Coastguard Worker   Jit(JitCodeCache* code_cache, JitOptions* options);
400*795d594fSAndroid Build Coastguard Worker 
401*795d594fSAndroid Build Coastguard Worker   // Whether we should not add hotness counts for the given method.
402*795d594fSAndroid Build Coastguard Worker   bool IgnoreSamplesForMethod(ArtMethod* method)
403*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
404*795d594fSAndroid Build Coastguard Worker 
405*795d594fSAndroid Build Coastguard Worker   // Compile an individual method listed in a profile. If `add_to_queue` is
406*795d594fSAndroid Build Coastguard Worker   // true and the method was resolved, return true. Otherwise return false.
407*795d594fSAndroid Build Coastguard Worker   bool CompileMethodFromProfile(Thread* self,
408*795d594fSAndroid Build Coastguard Worker                                 ClassLinker* linker,
409*795d594fSAndroid Build Coastguard Worker                                 uint32_t method_idx,
410*795d594fSAndroid Build Coastguard Worker                                 Handle<mirror::DexCache> dex_cache,
411*795d594fSAndroid Build Coastguard Worker                                 Handle<mirror::ClassLoader> class_loader,
412*795d594fSAndroid Build Coastguard Worker                                 bool add_to_queue,
413*795d594fSAndroid Build Coastguard Worker                                 bool compile_after_boot)
414*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
415*795d594fSAndroid Build Coastguard Worker 
416*795d594fSAndroid Build Coastguard Worker   static bool BindCompilerMethods(std::string* error_msg);
417*795d594fSAndroid Build Coastguard Worker 
418*795d594fSAndroid Build Coastguard Worker   void AddCompileTask(Thread* self,
419*795d594fSAndroid Build Coastguard Worker                       ArtMethod* method,
420*795d594fSAndroid Build Coastguard Worker                       CompilationKind compilation_kind);
421*795d594fSAndroid Build Coastguard Worker 
422*795d594fSAndroid Build Coastguard Worker   bool CompileMethodInternal(ArtMethod* method,
423*795d594fSAndroid Build Coastguard Worker                              Thread* self,
424*795d594fSAndroid Build Coastguard Worker                              CompilationKind compilation_kind,
425*795d594fSAndroid Build Coastguard Worker                              bool prejit)
426*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
427*795d594fSAndroid Build Coastguard Worker 
428*795d594fSAndroid Build Coastguard Worker   // JIT compiler
429*795d594fSAndroid Build Coastguard Worker   EXPORT static JitCompilerInterface* jit_compiler_;
430*795d594fSAndroid Build Coastguard Worker 
431*795d594fSAndroid Build Coastguard Worker   // JIT resources owned by runtime.
432*795d594fSAndroid Build Coastguard Worker   jit::JitCodeCache* const code_cache_;
433*795d594fSAndroid Build Coastguard Worker   const JitOptions* const options_;
434*795d594fSAndroid Build Coastguard Worker 
435*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<JitThreadPool> thread_pool_;
436*795d594fSAndroid Build Coastguard Worker   std::vector<std::unique_ptr<OatDexFile>> type_lookup_tables_;
437*795d594fSAndroid Build Coastguard Worker 
438*795d594fSAndroid Build Coastguard Worker   Mutex boot_completed_lock_;
439*795d594fSAndroid Build Coastguard Worker   bool boot_completed_ GUARDED_BY(boot_completed_lock_) = false;
440*795d594fSAndroid Build Coastguard Worker   std::deque<Task*> tasks_after_boot_ GUARDED_BY(boot_completed_lock_);
441*795d594fSAndroid Build Coastguard Worker 
442*795d594fSAndroid Build Coastguard Worker   // Performance monitoring.
443*795d594fSAndroid Build Coastguard Worker   CumulativeLogger cumulative_timings_;
444*795d594fSAndroid Build Coastguard Worker   Histogram<uint64_t> memory_use_ GUARDED_BY(lock_);
445*795d594fSAndroid Build Coastguard Worker   Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
446*795d594fSAndroid Build Coastguard Worker 
447*795d594fSAndroid Build Coastguard Worker   // In the JIT zygote configuration, after all compilation is done, the zygote
448*795d594fSAndroid Build Coastguard Worker   // will copy its contents of the boot image to the zygote_mapping_methods_,
449*795d594fSAndroid Build Coastguard Worker   // which will be picked up by processes that will map the memory
450*795d594fSAndroid Build Coastguard Worker   // in-place within the boot image mapping.
451*795d594fSAndroid Build Coastguard Worker   //
452*795d594fSAndroid Build Coastguard Worker   // zygote_mapping_methods_ is shared memory only usable by the zygote and not
453*795d594fSAndroid Build Coastguard Worker   // inherited by child processes. We create it eagerly to ensure other
454*795d594fSAndroid Build Coastguard Worker   // processes cannot seal writable the file.
455*795d594fSAndroid Build Coastguard Worker   MemMap zygote_mapping_methods_;
456*795d594fSAndroid Build Coastguard Worker 
457*795d594fSAndroid Build Coastguard Worker   // The file descriptor created through memfd_create pointing to memory holding
458*795d594fSAndroid Build Coastguard Worker   // boot image methods. Created by the zygote, and inherited by child
459*795d594fSAndroid Build Coastguard Worker   // processes. The descriptor will be closed in each process (including the
460*795d594fSAndroid Build Coastguard Worker   // zygote) once they don't need it.
461*795d594fSAndroid Build Coastguard Worker   android::base::unique_fd fd_methods_;
462*795d594fSAndroid Build Coastguard Worker 
463*795d594fSAndroid Build Coastguard Worker   // The size of the memory pointed by `fd_methods_`. Cached here to avoid
464*795d594fSAndroid Build Coastguard Worker   // recomputing it.
465*795d594fSAndroid Build Coastguard Worker   size_t fd_methods_size_;
466*795d594fSAndroid Build Coastguard Worker 
467*795d594fSAndroid Build Coastguard Worker   // Map of hotness counters for methods which we want to share the memory
468*795d594fSAndroid Build Coastguard Worker   // between the zygote and apps.
469*795d594fSAndroid Build Coastguard Worker   std::map<ArtMethod*, uint16_t> shared_method_counters_;
470*795d594fSAndroid Build Coastguard Worker 
471*795d594fSAndroid Build Coastguard Worker   friend class art::jit::JitCompileTask;
472*795d594fSAndroid Build Coastguard Worker 
473*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(Jit);
474*795d594fSAndroid Build Coastguard Worker };
475*795d594fSAndroid Build Coastguard Worker 
476*795d594fSAndroid Build Coastguard Worker // Helper class to stop the JIT for a given scope. This will wait for the JIT to quiesce.
477*795d594fSAndroid Build Coastguard Worker class EXPORT ScopedJitSuspend {
478*795d594fSAndroid Build Coastguard Worker  public:
479*795d594fSAndroid Build Coastguard Worker   ScopedJitSuspend();
480*795d594fSAndroid Build Coastguard Worker   ~ScopedJitSuspend();
481*795d594fSAndroid Build Coastguard Worker 
482*795d594fSAndroid Build Coastguard Worker  private:
483*795d594fSAndroid Build Coastguard Worker   bool was_on_;
484*795d594fSAndroid Build Coastguard Worker };
485*795d594fSAndroid Build Coastguard Worker 
486*795d594fSAndroid Build Coastguard Worker }  // namespace jit
487*795d594fSAndroid Build Coastguard Worker }  // namespace art
488*795d594fSAndroid Build Coastguard Worker 
489*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_JIT_JIT_H_
490