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