• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
20 #include <android-base/unique_fd.h>
21 
22 #include "base/histogram-inl.h"
23 #include "base/macros.h"
24 #include "base/mutex.h"
25 #include "base/runtime_debug.h"
26 #include "base/timing_logger.h"
27 #include "compilation_kind.h"
28 #include "handle.h"
29 #include "offsets.h"
30 #include "interpreter/mterp/nterp.h"
31 #include "jit/debugger_interface.h"
32 #include "jit/profile_saver_options.h"
33 #include "obj_ptr.h"
34 #include "thread_pool.h"
35 
36 namespace art {
37 
38 class ArtMethod;
39 class ClassLinker;
40 class DexFile;
41 class OatDexFile;
42 struct RuntimeArgumentMap;
43 union JValue;
44 
45 namespace mirror {
46 class Object;
47 class Class;
48 class ClassLoader;
49 class DexCache;
50 class String;
51 }   // namespace mirror
52 
53 namespace jit {
54 
55 class JitCodeCache;
56 class JitMemoryRegion;
57 class JitOptions;
58 
59 static constexpr int16_t kJitCheckForOSR = -1;
60 static constexpr int16_t kJitHotnessDisabled = -2;
61 // At what priority to schedule jit threads. 9 is the lowest foreground priority on device.
62 // See android/os/Process.java.
63 static constexpr int kJitPoolThreadPthreadDefaultPriority = 9;
64 // 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.
67 static constexpr int kJitZygotePoolThreadPthreadDefaultPriority = 19;
68 // 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).
70 static constexpr uint32_t kJitSamplesBatchSize = 512;  // Must be power of 2.
71 
72 class JitOptions {
73  public:
74   static JitOptions* CreateFromRuntimeArguments(const RuntimeArgumentMap& options);
75 
GetCompileThreshold()76   uint16_t GetCompileThreshold() const {
77     return compile_threshold_;
78   }
79 
GetWarmupThreshold()80   uint16_t GetWarmupThreshold() const {
81     return warmup_threshold_;
82   }
83 
GetOsrThreshold()84   uint16_t GetOsrThreshold() const {
85     return osr_threshold_;
86   }
87 
GetPriorityThreadWeight()88   uint16_t GetPriorityThreadWeight() const {
89     return priority_thread_weight_;
90   }
91 
GetInvokeTransitionWeight()92   uint16_t GetInvokeTransitionWeight() const {
93     return invoke_transition_weight_;
94   }
95 
GetCodeCacheInitialCapacity()96   size_t GetCodeCacheInitialCapacity() const {
97     return code_cache_initial_capacity_;
98   }
99 
GetCodeCacheMaxCapacity()100   size_t GetCodeCacheMaxCapacity() const {
101     return code_cache_max_capacity_;
102   }
103 
DumpJitInfoOnShutdown()104   bool DumpJitInfoOnShutdown() const {
105     return dump_info_on_shutdown_;
106   }
107 
GetProfileSaverOptions()108   const ProfileSaverOptions& GetProfileSaverOptions() const {
109     return profile_saver_options_;
110   }
111 
GetSaveProfilingInfo()112   bool GetSaveProfilingInfo() const {
113     return profile_saver_options_.IsEnabled();
114   }
115 
GetThreadPoolPthreadPriority()116   int GetThreadPoolPthreadPriority() const {
117     return thread_pool_pthread_priority_;
118   }
119 
GetZygoteThreadPoolPthreadPriority()120   int GetZygoteThreadPoolPthreadPriority() const {
121     return zygote_thread_pool_pthread_priority_;
122   }
123 
UseJitCompilation()124   bool UseJitCompilation() const {
125     return use_jit_compilation_;
126   }
127 
UseProfiledJitCompilation()128   bool UseProfiledJitCompilation() const {
129     return use_profiled_jit_compilation_;
130   }
131 
SetUseJitCompilation(bool b)132   void SetUseJitCompilation(bool b) {
133     use_jit_compilation_ = b;
134   }
135 
SetSaveProfilingInfo(bool save_profiling_info)136   void SetSaveProfilingInfo(bool save_profiling_info) {
137     profile_saver_options_.SetEnabled(save_profiling_info);
138   }
139 
SetWaitForJitNotificationsToSaveProfile(bool value)140   void SetWaitForJitNotificationsToSaveProfile(bool value) {
141     profile_saver_options_.SetWaitForJitNotificationsToSave(value);
142   }
143 
SetJitAtFirstUse()144   void SetJitAtFirstUse() {
145     use_jit_compilation_ = true;
146     compile_threshold_ = 0;
147   }
148 
SetUseBaselineCompiler()149   void SetUseBaselineCompiler() {
150     use_baseline_compiler_ = true;
151   }
152 
UseBaselineCompiler()153   bool UseBaselineCompiler() const {
154     return use_baseline_compiler_;
155   }
156 
157  private:
158   // 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 
162   bool use_jit_compilation_;
163   bool use_profiled_jit_compilation_;
164   bool use_baseline_compiler_;
165   size_t code_cache_initial_capacity_;
166   size_t code_cache_max_capacity_;
167   uint32_t compile_threshold_;
168   uint32_t warmup_threshold_;
169   uint32_t osr_threshold_;
170   uint16_t priority_thread_weight_;
171   uint16_t invoke_transition_weight_;
172   bool dump_info_on_shutdown_;
173   int thread_pool_pthread_priority_;
174   int zygote_thread_pool_pthread_priority_;
175   ProfileSaverOptions profile_saver_options_;
176 
JitOptions()177   JitOptions()
178       : use_jit_compilation_(false),
179         use_profiled_jit_compilation_(false),
180         use_baseline_compiler_(false),
181         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),
189         thread_pool_pthread_priority_(kJitPoolThreadPthreadDefaultPriority),
190         zygote_thread_pool_pthread_priority_(kJitZygotePoolThreadPthreadDefaultPriority) {}
191 
192   DISALLOW_COPY_AND_ASSIGN(JitOptions);
193 };
194 
195 // Implemented and provided by the compiler library.
196 class JitCompilerInterface {
197  public:
~JitCompilerInterface()198   virtual ~JitCompilerInterface() {}
199   virtual bool CompileMethod(
200       Thread* self, JitMemoryRegion* region, ArtMethod* method, CompilationKind compilation_kind)
201       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
202   virtual void TypesLoaded(mirror::Class**, size_t count)
203       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
204   virtual bool GenerateDebugInfo() = 0;
205   virtual void ParseCompilerOptions() = 0;
206 
207   virtual std::vector<uint8_t> PackElfFileForJIT(ArrayRef<const JITCodeEntry*> elf_files,
208                                                  ArrayRef<const void*> removed_symbols,
209                                                  bool compress,
210                                                  /*out*/ size_t* num_symbols) = 0;
211 };
212 
213 // Data structure holding information to perform an OSR.
214 struct 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 
NativePcOffsetOsrData224   static constexpr MemberOffset NativePcOffset() {
225     return MemberOffset(OFFSETOF_MEMBER(OsrData, native_pc));
226   }
227 
FrameSizeOffsetOsrData228   static constexpr MemberOffset FrameSizeOffset() {
229     return MemberOffset(OFFSETOF_MEMBER(OsrData, frame_size));
230   }
231 
MemoryOffsetOsrData232   static constexpr MemberOffset MemoryOffset() {
233     return MemberOffset(OFFSETOF_MEMBER(OsrData, memory));
234   }
235 };
236 
237 class Jit {
238  public:
239   static constexpr size_t kDefaultPriorityThreadWeightRatio = 1000;
240   static constexpr size_t kDefaultInvokeTransitionWeightRatio = 500;
241   // How frequently should the interpreter check to see if OSR compilation is ready.
242   static constexpr int16_t kJitRecheckOSRThreshold = 101;  // Prime number to avoid patterns.
243 
244   DECLARE_RUNTIME_DEBUG_FLAG(kSlowMode);
245 
246   virtual ~Jit();
247 
248   // Create JIT itself.
249   static Jit* Create(JitCodeCache* code_cache, JitOptions* options);
250 
251   bool CompileMethod(ArtMethod* method, Thread* self, CompilationKind compilation_kind, bool prejit)
252       REQUIRES_SHARED(Locks::mutator_lock_);
253 
GetCodeCache()254   const JitCodeCache* GetCodeCache() const {
255     return code_cache_;
256   }
257 
GetCodeCache()258   JitCodeCache* GetCodeCache() {
259     return code_cache_;
260   }
261 
GetJitCompiler()262   JitCompilerInterface* GetJitCompiler() const {
263     return jit_compiler_;
264   }
265 
266   void CreateThreadPool();
267   void DeleteThreadPool();
268   void WaitForWorkersToBeCreated();
269 
270   // Dump interesting info: #methods compiled, code vs data size, compile / verify cumulative
271   // loggers.
272   void DumpInfo(std::ostream& os) REQUIRES(!lock_);
273   // Add a timing logger to cumulative_timings_.
274   void AddTimingLogger(const TimingLogger& logger);
275 
276   void AddMemoryUsage(ArtMethod* method, size_t bytes)
277       REQUIRES(!lock_)
278       REQUIRES_SHARED(Locks::mutator_lock_);
279 
GetThreadPoolPthreadPriority()280   int GetThreadPoolPthreadPriority() const {
281     return options_->GetThreadPoolPthreadPriority();
282   }
283 
OSRMethodThreshold()284   uint16_t OSRMethodThreshold() const {
285     return options_->GetOsrThreshold();
286   }
287 
HotMethodThreshold()288   uint16_t HotMethodThreshold() const {
289     return options_->GetCompileThreshold();
290   }
291 
WarmMethodThreshold()292   uint16_t WarmMethodThreshold() const {
293     return options_->GetWarmupThreshold();
294   }
295 
PriorityThreadWeight()296   uint16_t PriorityThreadWeight() const {
297     return options_->GetPriorityThreadWeight();
298   }
299 
300   // 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.
UseJitCompilation()302   bool UseJitCompilation() const {
303     return options_->UseJitCompilation();
304   }
305 
GetSaveProfilingInfo()306   bool GetSaveProfilingInfo() const {
307     return options_->GetSaveProfilingInfo();
308   }
309 
310   // 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)
315       REQUIRES_SHARED(Locks::mutator_lock_);
316 
317   ALWAYS_INLINE void AddSamples(Thread* self,
318                                 ArtMethod* method,
319                                 uint16_t samples,
320                                 bool with_backedges)
321       REQUIRES_SHARED(Locks::mutator_lock_);
322 
NotifyInterpreterToCompiledCodeTransition(Thread * self,ArtMethod * caller)323   void NotifyInterpreterToCompiledCodeTransition(Thread* self, ArtMethod* caller)
324       REQUIRES_SHARED(Locks::mutator_lock_) {
325     if (!IgnoreSamplesForMethod(caller)) {
326       AddSamples(self, caller, options_->GetInvokeTransitionWeight(), false);
327     }
328   }
329 
NotifyCompiledCodeToInterpreterTransition(Thread * self,ArtMethod * callee)330   void NotifyCompiledCodeToInterpreterTransition(Thread* self, ArtMethod* callee)
331       REQUIRES_SHARED(Locks::mutator_lock_) {
332     if (!IgnoreSamplesForMethod(callee)) {
333       AddSamples(self, callee, options_->GetInvokeTransitionWeight(), false);
334     }
335   }
336 
337   // Starts the profile saver if the config options allow profile recording.
338   // The profile will be stored in the specified `profile_filename` and will contain
339   // information collected from the given `code_paths` (a set of dex locations).
340   //
341   // The `ref_profile_filename` denotes the path to the reference profile which
342   // might be queried to determine if an initial save should be done earlier.
343   // It can be empty indicating there is no reference profile.
344   void StartProfileSaver(const std::string& profile_filename,
345                          const std::vector<std::string>& code_paths,
346                          const std::string& ref_profile_filename);
347   void StopProfileSaver();
348 
349   void DumpForSigQuit(std::ostream& os) REQUIRES(!lock_);
350 
351   static void NewTypeLoadedIfUsingJit(mirror::Class* type)
352       REQUIRES_SHARED(Locks::mutator_lock_);
353 
354   // If debug info generation is turned on then write the type information for types already loaded
355   // into the specified class linker to the jit debug interface,
356   void DumpTypeInfoForLoadedTypes(ClassLinker* linker);
357 
358   // Return whether we should try to JIT compiled code as soon as an ArtMethod is invoked.
359   bool JitAtFirstUse();
360 
361   // Return whether we can invoke JIT code for `method`.
362   bool CanInvokeCompiledCode(ArtMethod* method);
363 
364   // Return whether the runtime should use a priority thread weight when sampling.
365   static bool ShouldUsePriorityThreadWeight(Thread* self);
366 
367   // Return the information required to do an OSR jump. Return null if the OSR
368   // cannot be done.
369   OsrData* PrepareForOsr(ArtMethod* method, uint32_t dex_pc, uint32_t* vregs)
370       REQUIRES_SHARED(Locks::mutator_lock_);
371 
372   // If an OSR compiled version is available for `method`,
373   // and `dex_pc + dex_pc_offset` is an entry point of that compiled
374   // version, this method will jump to the compiled code, let it run,
375   // and return true afterwards. Return false otherwise.
376   static bool MaybeDoOnStackReplacement(Thread* thread,
377                                         ArtMethod* method,
378                                         uint32_t dex_pc,
379                                         int32_t dex_pc_offset,
380                                         JValue* result)
381       REQUIRES_SHARED(Locks::mutator_lock_);
382 
383   // Load the compiler library.
384   static bool LoadCompilerLibrary(std::string* error_msg);
385 
GetThreadPool()386   ThreadPool* GetThreadPool() const {
387     return thread_pool_.get();
388   }
389 
390   // Stop the JIT by waiting for all current compilations and enqueued compilations to finish.
391   void Stop();
392 
393   // Start JIT threads.
394   void Start();
395 
396   // Transition to a child state.
397   void PostForkChildAction(bool is_system_server, bool is_zygote);
398 
399   // Prepare for forking.
400   void PreZygoteFork();
401 
402   // Adjust state after forking.
403   void PostZygoteFork();
404 
405   // Called when system finishes booting.
406   void BootCompleted();
407 
408   // Are we in a zygote using JIT compilation?
409   static bool InZygoteUsingJit();
410 
411   // Compile methods from the given profile (.prof extension). If `add_to_queue`
412   // is true, methods in the profile are added to the JIT queue. Otherwise they are compiled
413   // directly.
414   // Return the number of methods added to the queue.
415   uint32_t CompileMethodsFromProfile(Thread* self,
416                                      const std::vector<const DexFile*>& dex_files,
417                                      const std::string& profile_path,
418                                      Handle<mirror::ClassLoader> class_loader,
419                                      bool add_to_queue);
420 
421   // Compile methods from the given boot profile (.bprof extension). If `add_to_queue`
422   // is true, methods in the profile are added to the JIT queue. Otherwise they are compiled
423   // directly.
424   // Return the number of methods added to the queue.
425   uint32_t CompileMethodsFromBootProfile(Thread* self,
426                                          const std::vector<const DexFile*>& dex_files,
427                                          const std::string& profile_path,
428                                          Handle<mirror::ClassLoader> class_loader,
429                                          bool add_to_queue);
430 
431   // Register the dex files to the JIT. This is to perform any compilation/optimization
432   // at the point of loading the dex files.
433   void RegisterDexFiles(const std::vector<std::unique_ptr<const DexFile>>& dex_files,
434                         jobject class_loader);
435 
436   // Called by the compiler to know whether it can directly encode the
437   // method/class/string.
438   bool CanEncodeMethod(ArtMethod* method, bool is_for_shared_region) const
439       REQUIRES_SHARED(Locks::mutator_lock_);
440   bool CanEncodeClass(ObjPtr<mirror::Class> cls, bool is_for_shared_region) const
441       REQUIRES_SHARED(Locks::mutator_lock_);
442   bool CanEncodeString(ObjPtr<mirror::String> string, bool is_for_shared_region) const
443       REQUIRES_SHARED(Locks::mutator_lock_);
444   bool CanAssumeInitialized(ObjPtr<mirror::Class> cls, bool is_for_shared_region) const
445       REQUIRES_SHARED(Locks::mutator_lock_);
446 
447   // Map boot image methods after all compilation in zygote has been done.
448   void MapBootImageMethods() REQUIRES(Locks::mutator_lock_);
449 
450   // Notify to other processes that the zygote is done profile compiling boot
451   // class path methods.
452   void NotifyZygoteCompilationDone();
453 
454   void EnqueueOptimizedCompilation(ArtMethod* method, Thread* self);
455 
456   void EnqueueCompilationFromNterp(ArtMethod* method, Thread* self)
457       REQUIRES_SHARED(Locks::mutator_lock_);
458 
459  private:
460   Jit(JitCodeCache* code_cache, JitOptions* options);
461 
462   // Whether we should not add hotness counts for the given method.
463   bool IgnoreSamplesForMethod(ArtMethod* method)
464       REQUIRES_SHARED(Locks::mutator_lock_);
465 
466   // Compile an individual method listed in a profile. If `add_to_queue` is
467   // true and the method was resolved, return true. Otherwise return false.
468   bool CompileMethodFromProfile(Thread* self,
469                                 ClassLinker* linker,
470                                 uint32_t method_idx,
471                                 Handle<mirror::DexCache> dex_cache,
472                                 Handle<mirror::ClassLoader> class_loader,
473                                 bool add_to_queue,
474                                 bool compile_after_boot)
475       REQUIRES_SHARED(Locks::mutator_lock_);
476 
477   // Compile the method if the number of samples passes a threshold.
478   // Returns false if we can not compile now - don't increment the counter and retry later.
479   bool MaybeCompileMethod(Thread* self,
480                           ArtMethod* method,
481                           uint32_t old_count,
482                           uint32_t new_count,
483                           bool with_backedges)
484       REQUIRES_SHARED(Locks::mutator_lock_);
485 
486   static bool BindCompilerMethods(std::string* error_msg);
487 
488   // JIT compiler
489   static void* jit_library_handle_;
490   static JitCompilerInterface* jit_compiler_;
491   static JitCompilerInterface* (*jit_load_)(void);
492   template <typename T> static bool LoadSymbol(T*, const char* symbol, std::string* error_msg);
493 
494   // JIT resources owned by runtime.
495   jit::JitCodeCache* const code_cache_;
496   const JitOptions* const options_;
497 
498   std::unique_ptr<ThreadPool> thread_pool_;
499   std::vector<std::unique_ptr<OatDexFile>> type_lookup_tables_;
500 
501   Mutex boot_completed_lock_;
502   bool boot_completed_ GUARDED_BY(boot_completed_lock_) = false;
503   std::deque<Task*> tasks_after_boot_ GUARDED_BY(boot_completed_lock_);
504 
505   // Performance monitoring.
506   CumulativeLogger cumulative_timings_;
507   Histogram<uint64_t> memory_use_ GUARDED_BY(lock_);
508   Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
509 
510   // In the JIT zygote configuration, after all compilation is done, the zygote
511   // will copy its contents of the boot image to the zygote_mapping_methods_,
512   // which will be picked up by processes that will map the memory
513   // in-place within the boot image mapping.
514   //
515   // zygote_mapping_methods_ is shared memory only usable by the zygote and not
516   // inherited by child processes. We create it eagerly to ensure other
517   // processes cannot seal writable the file.
518   MemMap zygote_mapping_methods_;
519 
520   // The file descriptor created through memfd_create pointing to memory holding
521   // boot image methods. Created by the zygote, and inherited by child
522   // processes. The descriptor will be closed in each process (including the
523   // zygote) once they don't need it.
524   android::base::unique_fd fd_methods_;
525 
526   // The size of the memory pointed by `fd_methods_`. Cached here to avoid
527   // recomputing it.
528   size_t fd_methods_size_;
529 
530   DISALLOW_COPY_AND_ASSIGN(Jit);
531 };
532 
533 // Helper class to stop the JIT for a given scope. This will wait for the JIT to quiesce.
534 class ScopedJitSuspend {
535  public:
536   ScopedJitSuspend();
537   ~ScopedJitSuspend();
538 
539  private:
540   bool was_on_;
541 };
542 
543 }  // namespace jit
544 }  // namespace art
545 
546 #endif  // ART_RUNTIME_JIT_JIT_H_
547