xref: /aosp_15_r20/art/runtime/jit/jit.cc (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 #include "jit.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <dlfcn.h>
20*795d594fSAndroid Build Coastguard Worker #include <sys/resource.h>
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include "app_info.h"
23*795d594fSAndroid Build Coastguard Worker #include "art_method-inl.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/file_utils.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/logging.h"  // For VLOG.
26*795d594fSAndroid Build Coastguard Worker #include "base/memfd.h"
27*795d594fSAndroid Build Coastguard Worker #include "base/memory_tool.h"
28*795d594fSAndroid Build Coastguard Worker #include "base/pointer_size.h"
29*795d594fSAndroid Build Coastguard Worker #include "base/runtime_debug.h"
30*795d594fSAndroid Build Coastguard Worker #include "base/scoped_flock.h"
31*795d594fSAndroid Build Coastguard Worker #include "base/utils.h"
32*795d594fSAndroid Build Coastguard Worker #include "class_root-inl.h"
33*795d594fSAndroid Build Coastguard Worker #include "compilation_kind.h"
34*795d594fSAndroid Build Coastguard Worker #include "debugger.h"
35*795d594fSAndroid Build Coastguard Worker #include "dex/type_lookup_table.h"
36*795d594fSAndroid Build Coastguard Worker #include "entrypoints/entrypoint_utils-inl.h"
37*795d594fSAndroid Build Coastguard Worker #include "entrypoints/runtime_asm_entrypoints.h"
38*795d594fSAndroid Build Coastguard Worker #include "gc/space/image_space.h"
39*795d594fSAndroid Build Coastguard Worker #include "gc/task_processor.h"
40*795d594fSAndroid Build Coastguard Worker #include "interpreter/interpreter.h"
41*795d594fSAndroid Build Coastguard Worker #include "jit-inl.h"
42*795d594fSAndroid Build Coastguard Worker #include "jit_code_cache.h"
43*795d594fSAndroid Build Coastguard Worker #include "jit_create.h"
44*795d594fSAndroid Build Coastguard Worker #include "jni/java_vm_ext.h"
45*795d594fSAndroid Build Coastguard Worker #include "mirror/method_handle_impl.h"
46*795d594fSAndroid Build Coastguard Worker #include "mirror/var_handle.h"
47*795d594fSAndroid Build Coastguard Worker #include "oat/image-inl.h"
48*795d594fSAndroid Build Coastguard Worker #include "oat/oat_file.h"
49*795d594fSAndroid Build Coastguard Worker #include "oat/oat_file_manager.h"
50*795d594fSAndroid Build Coastguard Worker #include "oat/oat_quick_method_header.h"
51*795d594fSAndroid Build Coastguard Worker #include "oat/stack_map.h"
52*795d594fSAndroid Build Coastguard Worker #include "profile/profile_boot_info.h"
53*795d594fSAndroid Build Coastguard Worker #include "profile/profile_compilation_info.h"
54*795d594fSAndroid Build Coastguard Worker #include "profile_saver.h"
55*795d594fSAndroid Build Coastguard Worker #include "runtime.h"
56*795d594fSAndroid Build Coastguard Worker #include "runtime_options.h"
57*795d594fSAndroid Build Coastguard Worker #include "small_pattern_matcher.h"
58*795d594fSAndroid Build Coastguard Worker #include "stack.h"
59*795d594fSAndroid Build Coastguard Worker #include "thread-inl.h"
60*795d594fSAndroid Build Coastguard Worker #include "thread_list.h"
61*795d594fSAndroid Build Coastguard Worker 
62*795d594fSAndroid Build Coastguard Worker using android::base::unique_fd;
63*795d594fSAndroid Build Coastguard Worker 
64*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
65*795d594fSAndroid Build Coastguard Worker namespace jit {
66*795d594fSAndroid Build Coastguard Worker 
67*795d594fSAndroid Build Coastguard Worker static constexpr bool kEnableOnStackReplacement = true;
68*795d594fSAndroid Build Coastguard Worker 
69*795d594fSAndroid Build Coastguard Worker // JIT compiler
70*795d594fSAndroid Build Coastguard Worker JitCompilerInterface* Jit::jit_compiler_ = nullptr;
71*795d594fSAndroid Build Coastguard Worker 
DumpInfo(std::ostream & os)72*795d594fSAndroid Build Coastguard Worker void Jit::DumpInfo(std::ostream& os) {
73*795d594fSAndroid Build Coastguard Worker   code_cache_->Dump(os);
74*795d594fSAndroid Build Coastguard Worker   cumulative_timings_.Dump(os);
75*795d594fSAndroid Build Coastguard Worker   MutexLock mu(Thread::Current(), lock_);
76*795d594fSAndroid Build Coastguard Worker   memory_use_.PrintMemoryUse(os);
77*795d594fSAndroid Build Coastguard Worker }
78*795d594fSAndroid Build Coastguard Worker 
DumpForSigQuit(std::ostream & os)79*795d594fSAndroid Build Coastguard Worker void Jit::DumpForSigQuit(std::ostream& os) {
80*795d594fSAndroid Build Coastguard Worker   DumpInfo(os);
81*795d594fSAndroid Build Coastguard Worker   ProfileSaver::DumpInstanceInfo(os);
82*795d594fSAndroid Build Coastguard Worker }
83*795d594fSAndroid Build Coastguard Worker 
AddTimingLogger(const TimingLogger & logger)84*795d594fSAndroid Build Coastguard Worker void Jit::AddTimingLogger(const TimingLogger& logger) {
85*795d594fSAndroid Build Coastguard Worker   cumulative_timings_.AddLogger(logger);
86*795d594fSAndroid Build Coastguard Worker }
87*795d594fSAndroid Build Coastguard Worker 
Jit(JitCodeCache * code_cache,JitOptions * options)88*795d594fSAndroid Build Coastguard Worker Jit::Jit(JitCodeCache* code_cache, JitOptions* options)
89*795d594fSAndroid Build Coastguard Worker     : code_cache_(code_cache),
90*795d594fSAndroid Build Coastguard Worker       options_(options),
91*795d594fSAndroid Build Coastguard Worker       boot_completed_lock_("Jit::boot_completed_lock_"),
92*795d594fSAndroid Build Coastguard Worker       cumulative_timings_("JIT timings"),
93*795d594fSAndroid Build Coastguard Worker       memory_use_("Memory used for compilation", 16),
94*795d594fSAndroid Build Coastguard Worker       lock_("JIT memory use lock"),
95*795d594fSAndroid Build Coastguard Worker       zygote_mapping_methods_(),
96*795d594fSAndroid Build Coastguard Worker       fd_methods_(-1),
97*795d594fSAndroid Build Coastguard Worker       fd_methods_size_(0) {}
98*795d594fSAndroid Build Coastguard Worker 
Create(JitCodeCache * code_cache,JitOptions * options)99*795d594fSAndroid Build Coastguard Worker std::unique_ptr<Jit> Jit::Create(JitCodeCache* code_cache, JitOptions* options) {
100*795d594fSAndroid Build Coastguard Worker   jit_compiler_ = jit_create();
101*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<Jit> jit(new Jit(code_cache, options));
102*795d594fSAndroid Build Coastguard Worker 
103*795d594fSAndroid Build Coastguard Worker   // If the code collector is enabled, check if that still holds:
104*795d594fSAndroid Build Coastguard Worker   // With 'perf', we want a 1-1 mapping between an address and a method.
105*795d594fSAndroid Build Coastguard Worker   // We aren't able to keep method pointers live during the instrumentation method entry trampoline
106*795d594fSAndroid Build Coastguard Worker   // so we will just disable jit-gc if we are doing that.
107*795d594fSAndroid Build Coastguard Worker   // JitAtFirstUse compiles the methods synchronously on mutator threads. While this should work
108*795d594fSAndroid Build Coastguard Worker   // in theory it is causing deadlocks in some jvmti tests related to Jit GC. Hence, disabling
109*795d594fSAndroid Build Coastguard Worker   // Jit GC for now (b/147208992).
110*795d594fSAndroid Build Coastguard Worker   if (code_cache->GetGarbageCollectCode()) {
111*795d594fSAndroid Build Coastguard Worker     code_cache->SetGarbageCollectCode(!jit_compiler_->GenerateDebugInfo() &&
112*795d594fSAndroid Build Coastguard Worker         !jit->JitAtFirstUse());
113*795d594fSAndroid Build Coastguard Worker   }
114*795d594fSAndroid Build Coastguard Worker 
115*795d594fSAndroid Build Coastguard Worker   VLOG(jit) << "JIT created with initial_capacity="
116*795d594fSAndroid Build Coastguard Worker       << PrettySize(options->GetCodeCacheInitialCapacity())
117*795d594fSAndroid Build Coastguard Worker       << ", max_capacity=" << PrettySize(options->GetCodeCacheMaxCapacity())
118*795d594fSAndroid Build Coastguard Worker       << ", warmup_threshold=" << options->GetWarmupThreshold()
119*795d594fSAndroid Build Coastguard Worker       << ", optimize_threshold=" << options->GetOptimizeThreshold()
120*795d594fSAndroid Build Coastguard Worker       << ", profile_saver_options=" << options->GetProfileSaverOptions();
121*795d594fSAndroid Build Coastguard Worker 
122*795d594fSAndroid Build Coastguard Worker   // We want to know whether the compiler is compiling baseline, as this
123*795d594fSAndroid Build Coastguard Worker   // affects how we GC ProfilingInfos.
124*795d594fSAndroid Build Coastguard Worker   for (const std::string& option : Runtime::Current()->GetCompilerOptions()) {
125*795d594fSAndroid Build Coastguard Worker     if (option == "--baseline") {
126*795d594fSAndroid Build Coastguard Worker       options->SetUseBaselineCompiler();
127*795d594fSAndroid Build Coastguard Worker       break;
128*795d594fSAndroid Build Coastguard Worker     }
129*795d594fSAndroid Build Coastguard Worker   }
130*795d594fSAndroid Build Coastguard Worker 
131*795d594fSAndroid Build Coastguard Worker   // Notify native debugger about the classes already loaded before the creation of the jit.
132*795d594fSAndroid Build Coastguard Worker   jit->DumpTypeInfoForLoadedTypes(Runtime::Current()->GetClassLinker());
133*795d594fSAndroid Build Coastguard Worker 
134*795d594fSAndroid Build Coastguard Worker   return jit;
135*795d594fSAndroid Build Coastguard Worker }
136*795d594fSAndroid Build Coastguard Worker 
137*795d594fSAndroid Build Coastguard Worker 
TryPatternMatch(ArtMethod * method_to_compile,CompilationKind compilation_kind)138*795d594fSAndroid Build Coastguard Worker bool Jit::TryPatternMatch(ArtMethod* method_to_compile, CompilationKind compilation_kind) {
139*795d594fSAndroid Build Coastguard Worker   // Try to pattern match the method. Only on arm and arm64 for now as we have
140*795d594fSAndroid Build Coastguard Worker   // sufficiently similar calling convention between C++ and managed code.
141*795d594fSAndroid Build Coastguard Worker   if (kRuntimeISA == InstructionSet::kArm || kRuntimeISA == InstructionSet::kArm64) {
142*795d594fSAndroid Build Coastguard Worker     if (!Runtime::Current()->IsJavaDebuggable() &&
143*795d594fSAndroid Build Coastguard Worker         compilation_kind == CompilationKind::kBaseline &&
144*795d594fSAndroid Build Coastguard Worker         !method_to_compile->StillNeedsClinitCheck()) {
145*795d594fSAndroid Build Coastguard Worker       const void* pattern = SmallPatternMatcher::TryMatch(method_to_compile);
146*795d594fSAndroid Build Coastguard Worker       if (pattern != nullptr) {
147*795d594fSAndroid Build Coastguard Worker         VLOG(jit) << "Successfully pattern matched " << method_to_compile->PrettyMethod();
148*795d594fSAndroid Build Coastguard Worker         Runtime::Current()->GetInstrumentation()->UpdateMethodsCode(method_to_compile, pattern);
149*795d594fSAndroid Build Coastguard Worker         return true;
150*795d594fSAndroid Build Coastguard Worker       }
151*795d594fSAndroid Build Coastguard Worker     }
152*795d594fSAndroid Build Coastguard Worker   }
153*795d594fSAndroid Build Coastguard Worker   return false;
154*795d594fSAndroid Build Coastguard Worker }
155*795d594fSAndroid Build Coastguard Worker 
CompileMethodInternal(ArtMethod * method,Thread * self,CompilationKind compilation_kind,bool prejit)156*795d594fSAndroid Build Coastguard Worker bool Jit::CompileMethodInternal(ArtMethod* method,
157*795d594fSAndroid Build Coastguard Worker                                 Thread* self,
158*795d594fSAndroid Build Coastguard Worker                                 CompilationKind compilation_kind,
159*795d594fSAndroid Build Coastguard Worker                                 bool prejit) {
160*795d594fSAndroid Build Coastguard Worker   DCHECK(Runtime::Current()->UseJitCompilation());
161*795d594fSAndroid Build Coastguard Worker   DCHECK(!method->IsRuntimeMethod());
162*795d594fSAndroid Build Coastguard Worker 
163*795d594fSAndroid Build Coastguard Worker   // If the baseline flag was explicitly passed in the compiler options, change the compilation kind
164*795d594fSAndroid Build Coastguard Worker   // from optimized to baseline.
165*795d594fSAndroid Build Coastguard Worker   if (jit_compiler_->IsBaselineCompiler() && compilation_kind == CompilationKind::kOptimized) {
166*795d594fSAndroid Build Coastguard Worker     compilation_kind = CompilationKind::kBaseline;
167*795d594fSAndroid Build Coastguard Worker   }
168*795d594fSAndroid Build Coastguard Worker 
169*795d594fSAndroid Build Coastguard Worker   if (method->IsPreCompiled() && !prejit) {
170*795d594fSAndroid Build Coastguard Worker     VLOG(jit) << "JIT not compiling " << method->PrettyMethod()
171*795d594fSAndroid Build Coastguard Worker               << " due to method marked pre-compile,"
172*795d594fSAndroid Build Coastguard Worker               << " and the compilation request isn't for pre-compilation.";
173*795d594fSAndroid Build Coastguard Worker     return false;
174*795d594fSAndroid Build Coastguard Worker   }
175*795d594fSAndroid Build Coastguard Worker 
176*795d594fSAndroid Build Coastguard Worker   // If we're asked to compile baseline, but we cannot allocate profiling infos,
177*795d594fSAndroid Build Coastguard Worker   // change the compilation kind to optimized.
178*795d594fSAndroid Build Coastguard Worker   if ((compilation_kind == CompilationKind::kBaseline) &&
179*795d594fSAndroid Build Coastguard Worker       !GetCodeCache()->CanAllocateProfilingInfo()) {
180*795d594fSAndroid Build Coastguard Worker     compilation_kind = CompilationKind::kOptimized;
181*795d594fSAndroid Build Coastguard Worker   }
182*795d594fSAndroid Build Coastguard Worker 
183*795d594fSAndroid Build Coastguard Worker   // Don't compile the method if it has breakpoints.
184*795d594fSAndroid Build Coastguard Worker   if (Runtime::Current()->GetInstrumentation()->IsDeoptimized(method)) {
185*795d594fSAndroid Build Coastguard Worker     VLOG(jit) << "JIT not compiling " << method->PrettyMethod()
186*795d594fSAndroid Build Coastguard Worker               << " due to not being safe to jit according to runtime-callbacks. For example, there"
187*795d594fSAndroid Build Coastguard Worker               << " could be breakpoints in this method.";
188*795d594fSAndroid Build Coastguard Worker     return false;
189*795d594fSAndroid Build Coastguard Worker   }
190*795d594fSAndroid Build Coastguard Worker 
191*795d594fSAndroid Build Coastguard Worker   if (!method->IsCompilable()) {
192*795d594fSAndroid Build Coastguard Worker     DCHECK(method->GetDeclaringClass()->IsObsoleteObject() ||
193*795d594fSAndroid Build Coastguard Worker            method->IsProxyMethod()) << method->PrettyMethod();
194*795d594fSAndroid Build Coastguard Worker     VLOG(jit) << "JIT not compiling " << method->PrettyMethod() << " due to method being made "
195*795d594fSAndroid Build Coastguard Worker               << "obsolete while waiting for JIT task to run. This probably happened due to "
196*795d594fSAndroid Build Coastguard Worker               << "concurrent structural class redefinition.";
197*795d594fSAndroid Build Coastguard Worker     return false;
198*795d594fSAndroid Build Coastguard Worker   }
199*795d594fSAndroid Build Coastguard Worker 
200*795d594fSAndroid Build Coastguard Worker   // Don't compile the method if we are supposed to be deoptimized.
201*795d594fSAndroid Build Coastguard Worker   instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
202*795d594fSAndroid Build Coastguard Worker   if (instrumentation->AreAllMethodsDeoptimized() || instrumentation->IsDeoptimized(method)) {
203*795d594fSAndroid Build Coastguard Worker     VLOG(jit) << "JIT not compiling " << method->PrettyMethod() << " due to deoptimization";
204*795d594fSAndroid Build Coastguard Worker     return false;
205*795d594fSAndroid Build Coastguard Worker   }
206*795d594fSAndroid Build Coastguard Worker 
207*795d594fSAndroid Build Coastguard Worker   JitMemoryRegion* region = GetCodeCache()->GetCurrentRegion();
208*795d594fSAndroid Build Coastguard Worker   if ((compilation_kind == CompilationKind::kOsr) && GetCodeCache()->IsSharedRegion(*region)) {
209*795d594fSAndroid Build Coastguard Worker     VLOG(jit) << "JIT not osr compiling "
210*795d594fSAndroid Build Coastguard Worker               << method->PrettyMethod()
211*795d594fSAndroid Build Coastguard Worker               << " due to using shared region";
212*795d594fSAndroid Build Coastguard Worker     return false;
213*795d594fSAndroid Build Coastguard Worker   }
214*795d594fSAndroid Build Coastguard Worker 
215*795d594fSAndroid Build Coastguard Worker   // If we get a request to compile a proxy method, we pass the actual Java method
216*795d594fSAndroid Build Coastguard Worker   // of that proxy method, as the compiler does not expect a proxy method.
217*795d594fSAndroid Build Coastguard Worker   ArtMethod* method_to_compile = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
218*795d594fSAndroid Build Coastguard Worker 
219*795d594fSAndroid Build Coastguard Worker   if (TryPatternMatch(method_to_compile, compilation_kind)) {
220*795d594fSAndroid Build Coastguard Worker     return true;
221*795d594fSAndroid Build Coastguard Worker   }
222*795d594fSAndroid Build Coastguard Worker 
223*795d594fSAndroid Build Coastguard Worker   if (!code_cache_->NotifyCompilationOf(method_to_compile, self, compilation_kind, prejit)) {
224*795d594fSAndroid Build Coastguard Worker     return false;
225*795d594fSAndroid Build Coastguard Worker   }
226*795d594fSAndroid Build Coastguard Worker 
227*795d594fSAndroid Build Coastguard Worker   VLOG(jit) << "Compiling method "
228*795d594fSAndroid Build Coastguard Worker             << ArtMethod::PrettyMethod(method_to_compile)
229*795d594fSAndroid Build Coastguard Worker             << " kind=" << compilation_kind;
230*795d594fSAndroid Build Coastguard Worker   bool success = jit_compiler_->CompileMethod(self, region, method_to_compile, compilation_kind);
231*795d594fSAndroid Build Coastguard Worker   code_cache_->DoneCompiling(method_to_compile, self);
232*795d594fSAndroid Build Coastguard Worker   if (!success) {
233*795d594fSAndroid Build Coastguard Worker     VLOG(jit) << "Failed to compile method "
234*795d594fSAndroid Build Coastguard Worker               << ArtMethod::PrettyMethod(method_to_compile)
235*795d594fSAndroid Build Coastguard Worker               << " kind=" << compilation_kind;
236*795d594fSAndroid Build Coastguard Worker   }
237*795d594fSAndroid Build Coastguard Worker   if (kIsDebugBuild) {
238*795d594fSAndroid Build Coastguard Worker     if (self->IsExceptionPending()) {
239*795d594fSAndroid Build Coastguard Worker       mirror::Throwable* exception = self->GetException();
240*795d594fSAndroid Build Coastguard Worker       LOG(FATAL) << "No pending exception expected after compiling "
241*795d594fSAndroid Build Coastguard Worker                  << ArtMethod::PrettyMethod(method)
242*795d594fSAndroid Build Coastguard Worker                  << ": "
243*795d594fSAndroid Build Coastguard Worker                  << exception->Dump();
244*795d594fSAndroid Build Coastguard Worker     }
245*795d594fSAndroid Build Coastguard Worker   }
246*795d594fSAndroid Build Coastguard Worker   return success;
247*795d594fSAndroid Build Coastguard Worker }
248*795d594fSAndroid Build Coastguard Worker 
WaitForWorkersToBeCreated()249*795d594fSAndroid Build Coastguard Worker void Jit::WaitForWorkersToBeCreated() {
250*795d594fSAndroid Build Coastguard Worker   if (thread_pool_ != nullptr) {
251*795d594fSAndroid Build Coastguard Worker     thread_pool_->WaitForWorkersToBeCreated();
252*795d594fSAndroid Build Coastguard Worker   }
253*795d594fSAndroid Build Coastguard Worker }
254*795d594fSAndroid Build Coastguard Worker 
DeleteThreadPool()255*795d594fSAndroid Build Coastguard Worker void Jit::DeleteThreadPool() {
256*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
257*795d594fSAndroid Build Coastguard Worker   if (thread_pool_ != nullptr) {
258*795d594fSAndroid Build Coastguard Worker     std::unique_ptr<JitThreadPool> pool;
259*795d594fSAndroid Build Coastguard Worker     {
260*795d594fSAndroid Build Coastguard Worker       ScopedSuspendAll ssa(__FUNCTION__);
261*795d594fSAndroid Build Coastguard Worker       // Clear thread_pool_ field while the threads are suspended.
262*795d594fSAndroid Build Coastguard Worker       // A mutator in the 'AddSamples' method will check against it.
263*795d594fSAndroid Build Coastguard Worker       pool = std::move(thread_pool_);
264*795d594fSAndroid Build Coastguard Worker     }
265*795d594fSAndroid Build Coastguard Worker 
266*795d594fSAndroid Build Coastguard Worker     // When running sanitized, let all tasks finish to not leak. Otherwise just clear the queue.
267*795d594fSAndroid Build Coastguard Worker     if (!kRunningOnMemoryTool) {
268*795d594fSAndroid Build Coastguard Worker       pool->StopWorkers(self);
269*795d594fSAndroid Build Coastguard Worker       pool->RemoveAllTasks(self);
270*795d594fSAndroid Build Coastguard Worker     }
271*795d594fSAndroid Build Coastguard Worker     // We could just suspend all threads, but we know those threads
272*795d594fSAndroid Build Coastguard Worker     // will finish in a short period, so it's not worth adding a suspend logic
273*795d594fSAndroid Build Coastguard Worker     // here. Besides, this is only done for shutdown.
274*795d594fSAndroid Build Coastguard Worker     pool->Wait(self, false, false);
275*795d594fSAndroid Build Coastguard Worker   }
276*795d594fSAndroid Build Coastguard Worker }
277*795d594fSAndroid Build Coastguard Worker 
StartProfileSaver(const std::string & profile_filename,const std::vector<std::string> & code_paths,const std::string & ref_profile_filename,AppInfo::CodeType code_type)278*795d594fSAndroid Build Coastguard Worker void Jit::StartProfileSaver(const std::string& profile_filename,
279*795d594fSAndroid Build Coastguard Worker                             const std::vector<std::string>& code_paths,
280*795d594fSAndroid Build Coastguard Worker                             const std::string& ref_profile_filename,
281*795d594fSAndroid Build Coastguard Worker                             AppInfo::CodeType code_type) {
282*795d594fSAndroid Build Coastguard Worker   if (options_->GetSaveProfilingInfo()) {
283*795d594fSAndroid Build Coastguard Worker     ProfileSaver::Start(options_->GetProfileSaverOptions(),
284*795d594fSAndroid Build Coastguard Worker                         profile_filename,
285*795d594fSAndroid Build Coastguard Worker                         code_cache_,
286*795d594fSAndroid Build Coastguard Worker                         code_paths,
287*795d594fSAndroid Build Coastguard Worker                         ref_profile_filename,
288*795d594fSAndroid Build Coastguard Worker                         code_type);
289*795d594fSAndroid Build Coastguard Worker   }
290*795d594fSAndroid Build Coastguard Worker }
291*795d594fSAndroid Build Coastguard Worker 
StopProfileSaver()292*795d594fSAndroid Build Coastguard Worker void Jit::StopProfileSaver() {
293*795d594fSAndroid Build Coastguard Worker   if (options_->GetSaveProfilingInfo() && ProfileSaver::IsStarted()) {
294*795d594fSAndroid Build Coastguard Worker     ProfileSaver::Stop(options_->DumpJitInfoOnShutdown());
295*795d594fSAndroid Build Coastguard Worker   }
296*795d594fSAndroid Build Coastguard Worker }
297*795d594fSAndroid Build Coastguard Worker 
JitAtFirstUse()298*795d594fSAndroid Build Coastguard Worker bool Jit::JitAtFirstUse() {
299*795d594fSAndroid Build Coastguard Worker   return HotMethodThreshold() == 0;
300*795d594fSAndroid Build Coastguard Worker }
301*795d594fSAndroid Build Coastguard Worker 
CanInvokeCompiledCode(ArtMethod * method)302*795d594fSAndroid Build Coastguard Worker bool Jit::CanInvokeCompiledCode(ArtMethod* method) {
303*795d594fSAndroid Build Coastguard Worker   return code_cache_->ContainsPc(method->GetEntryPointFromQuickCompiledCode());
304*795d594fSAndroid Build Coastguard Worker }
305*795d594fSAndroid Build Coastguard Worker 
~Jit()306*795d594fSAndroid Build Coastguard Worker Jit::~Jit() {
307*795d594fSAndroid Build Coastguard Worker   DCHECK_IMPLIES(options_->GetSaveProfilingInfo(), !ProfileSaver::IsStarted());
308*795d594fSAndroid Build Coastguard Worker   if (options_->DumpJitInfoOnShutdown()) {
309*795d594fSAndroid Build Coastguard Worker     DumpInfo(LOG_STREAM(INFO));
310*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->DumpDeoptimizations(LOG_STREAM(INFO));
311*795d594fSAndroid Build Coastguard Worker   }
312*795d594fSAndroid Build Coastguard Worker   DeleteThreadPool();
313*795d594fSAndroid Build Coastguard Worker   if (jit_compiler_ != nullptr) {
314*795d594fSAndroid Build Coastguard Worker     delete jit_compiler_;
315*795d594fSAndroid Build Coastguard Worker     jit_compiler_ = nullptr;
316*795d594fSAndroid Build Coastguard Worker   }
317*795d594fSAndroid Build Coastguard Worker }
318*795d594fSAndroid Build Coastguard Worker 
NewTypeLoadedIfUsingJit(mirror::Class * type)319*795d594fSAndroid Build Coastguard Worker void Jit::NewTypeLoadedIfUsingJit(mirror::Class* type) {
320*795d594fSAndroid Build Coastguard Worker   if (!Runtime::Current()->UseJitCompilation()) {
321*795d594fSAndroid Build Coastguard Worker     // No need to notify if we only use the JIT to save profiles.
322*795d594fSAndroid Build Coastguard Worker     return;
323*795d594fSAndroid Build Coastguard Worker   }
324*795d594fSAndroid Build Coastguard Worker   jit::Jit* jit = Runtime::Current()->GetJit();
325*795d594fSAndroid Build Coastguard Worker   if (jit->jit_compiler_->GenerateDebugInfo()) {
326*795d594fSAndroid Build Coastguard Worker     jit_compiler_->TypesLoaded(&type, 1);
327*795d594fSAndroid Build Coastguard Worker   }
328*795d594fSAndroid Build Coastguard Worker }
329*795d594fSAndroid Build Coastguard Worker 
DumpTypeInfoForLoadedTypes(ClassLinker * linker)330*795d594fSAndroid Build Coastguard Worker void Jit::DumpTypeInfoForLoadedTypes(ClassLinker* linker) {
331*795d594fSAndroid Build Coastguard Worker   struct CollectClasses : public ClassVisitor {
332*795d594fSAndroid Build Coastguard Worker     bool operator()(ObjPtr<mirror::Class> klass) override REQUIRES_SHARED(Locks::mutator_lock_) {
333*795d594fSAndroid Build Coastguard Worker       classes_.push_back(klass.Ptr());
334*795d594fSAndroid Build Coastguard Worker       return true;
335*795d594fSAndroid Build Coastguard Worker     }
336*795d594fSAndroid Build Coastguard Worker     std::vector<mirror::Class*> classes_;
337*795d594fSAndroid Build Coastguard Worker   };
338*795d594fSAndroid Build Coastguard Worker 
339*795d594fSAndroid Build Coastguard Worker   if (jit_compiler_->GenerateDebugInfo()) {
340*795d594fSAndroid Build Coastguard Worker     ScopedObjectAccess so(Thread::Current());
341*795d594fSAndroid Build Coastguard Worker 
342*795d594fSAndroid Build Coastguard Worker     CollectClasses visitor;
343*795d594fSAndroid Build Coastguard Worker     linker->VisitClasses(&visitor);
344*795d594fSAndroid Build Coastguard Worker     jit_compiler_->TypesLoaded(visitor.classes_.data(), visitor.classes_.size());
345*795d594fSAndroid Build Coastguard Worker   }
346*795d594fSAndroid Build Coastguard Worker }
347*795d594fSAndroid Build Coastguard Worker 
348*795d594fSAndroid Build Coastguard Worker extern "C" void art_quick_osr_stub(void** stack,
349*795d594fSAndroid Build Coastguard Worker                                    size_t stack_size_in_bytes,
350*795d594fSAndroid Build Coastguard Worker                                    const uint8_t* native_pc,
351*795d594fSAndroid Build Coastguard Worker                                    JValue* result,
352*795d594fSAndroid Build Coastguard Worker                                    const char* shorty,
353*795d594fSAndroid Build Coastguard Worker                                    Thread* self);
354*795d594fSAndroid Build Coastguard Worker 
PrepareForOsr(ArtMethod * method,uint32_t dex_pc,uint32_t * vregs)355*795d594fSAndroid Build Coastguard Worker OsrData* Jit::PrepareForOsr(ArtMethod* method, uint32_t dex_pc, uint32_t* vregs) {
356*795d594fSAndroid Build Coastguard Worker   if (!kEnableOnStackReplacement) {
357*795d594fSAndroid Build Coastguard Worker     return nullptr;
358*795d594fSAndroid Build Coastguard Worker   }
359*795d594fSAndroid Build Coastguard Worker 
360*795d594fSAndroid Build Coastguard Worker   // Cheap check if the method has been compiled already. That's an indicator that we should
361*795d594fSAndroid Build Coastguard Worker   // osr into it.
362*795d594fSAndroid Build Coastguard Worker   if (!GetCodeCache()->ContainsPc(method->GetEntryPointFromQuickCompiledCode())) {
363*795d594fSAndroid Build Coastguard Worker     return nullptr;
364*795d594fSAndroid Build Coastguard Worker   }
365*795d594fSAndroid Build Coastguard Worker 
366*795d594fSAndroid Build Coastguard Worker   // Fetch some data before looking up for an OSR method. We don't want thread
367*795d594fSAndroid Build Coastguard Worker   // suspension once we hold an OSR method, as the JIT code cache could delete the OSR
368*795d594fSAndroid Build Coastguard Worker   // method while we are being suspended.
369*795d594fSAndroid Build Coastguard Worker   CodeItemDataAccessor accessor(method->DexInstructionData());
370*795d594fSAndroid Build Coastguard Worker   const size_t number_of_vregs = accessor.RegistersSize();
371*795d594fSAndroid Build Coastguard Worker   std::string method_name(VLOG_IS_ON(jit) ? method->PrettyMethod() : "");
372*795d594fSAndroid Build Coastguard Worker   OsrData* osr_data = nullptr;
373*795d594fSAndroid Build Coastguard Worker 
374*795d594fSAndroid Build Coastguard Worker   {
375*795d594fSAndroid Build Coastguard Worker     ScopedAssertNoThreadSuspension sts("Holding OSR method");
376*795d594fSAndroid Build Coastguard Worker     const OatQuickMethodHeader* osr_method = GetCodeCache()->LookupOsrMethodHeader(method);
377*795d594fSAndroid Build Coastguard Worker     if (osr_method == nullptr) {
378*795d594fSAndroid Build Coastguard Worker       // No osr method yet, just return to the interpreter.
379*795d594fSAndroid Build Coastguard Worker       return nullptr;
380*795d594fSAndroid Build Coastguard Worker     }
381*795d594fSAndroid Build Coastguard Worker 
382*795d594fSAndroid Build Coastguard Worker     CodeInfo code_info(osr_method);
383*795d594fSAndroid Build Coastguard Worker 
384*795d594fSAndroid Build Coastguard Worker     // Find stack map starting at the target dex_pc.
385*795d594fSAndroid Build Coastguard Worker     StackMap stack_map = code_info.GetOsrStackMapForDexPc(dex_pc);
386*795d594fSAndroid Build Coastguard Worker     if (!stack_map.IsValid()) {
387*795d594fSAndroid Build Coastguard Worker       // There is no OSR stack map for this dex pc offset. Just return to the interpreter in the
388*795d594fSAndroid Build Coastguard Worker       // hope that the next branch has one.
389*795d594fSAndroid Build Coastguard Worker       return nullptr;
390*795d594fSAndroid Build Coastguard Worker     }
391*795d594fSAndroid Build Coastguard Worker 
392*795d594fSAndroid Build Coastguard Worker     // We found a stack map, now fill the frame with dex register values from the interpreter's
393*795d594fSAndroid Build Coastguard Worker     // shadow frame.
394*795d594fSAndroid Build Coastguard Worker     DexRegisterMap vreg_map = code_info.GetDexRegisterMapOf(stack_map);
395*795d594fSAndroid Build Coastguard Worker     DCHECK_EQ(vreg_map.size(), number_of_vregs);
396*795d594fSAndroid Build Coastguard Worker 
397*795d594fSAndroid Build Coastguard Worker     size_t frame_size = osr_method->GetFrameSizeInBytes();
398*795d594fSAndroid Build Coastguard Worker 
399*795d594fSAndroid Build Coastguard Worker     // Allocate memory to put shadow frame values. The osr stub will copy that memory to
400*795d594fSAndroid Build Coastguard Worker     // stack.
401*795d594fSAndroid Build Coastguard Worker     // Note that we could pass the shadow frame to the stub, and let it copy the values there,
402*795d594fSAndroid Build Coastguard Worker     // but that is engineering complexity not worth the effort for something like OSR.
403*795d594fSAndroid Build Coastguard Worker     osr_data = reinterpret_cast<OsrData*>(malloc(sizeof(OsrData) + frame_size));
404*795d594fSAndroid Build Coastguard Worker     if (osr_data == nullptr) {
405*795d594fSAndroid Build Coastguard Worker       return nullptr;
406*795d594fSAndroid Build Coastguard Worker     }
407*795d594fSAndroid Build Coastguard Worker     memset(osr_data, 0, sizeof(OsrData) + frame_size);
408*795d594fSAndroid Build Coastguard Worker     osr_data->frame_size = frame_size;
409*795d594fSAndroid Build Coastguard Worker 
410*795d594fSAndroid Build Coastguard Worker     // Art ABI: ArtMethod is at the bottom of the stack.
411*795d594fSAndroid Build Coastguard Worker     osr_data->memory[0] = method;
412*795d594fSAndroid Build Coastguard Worker 
413*795d594fSAndroid Build Coastguard Worker     if (vreg_map.empty()) {
414*795d594fSAndroid Build Coastguard Worker       // If we don't have a dex register map, then there are no live dex registers at
415*795d594fSAndroid Build Coastguard Worker       // this dex pc.
416*795d594fSAndroid Build Coastguard Worker     } else {
417*795d594fSAndroid Build Coastguard Worker       for (uint16_t vreg = 0; vreg < number_of_vregs; ++vreg) {
418*795d594fSAndroid Build Coastguard Worker         DexRegisterLocation::Kind location = vreg_map[vreg].GetKind();
419*795d594fSAndroid Build Coastguard Worker         if (location == DexRegisterLocation::Kind::kNone) {
420*795d594fSAndroid Build Coastguard Worker           // Dex register is dead or uninitialized.
421*795d594fSAndroid Build Coastguard Worker           continue;
422*795d594fSAndroid Build Coastguard Worker         }
423*795d594fSAndroid Build Coastguard Worker 
424*795d594fSAndroid Build Coastguard Worker         if (location == DexRegisterLocation::Kind::kConstant) {
425*795d594fSAndroid Build Coastguard Worker           // We skip constants because the compiled code knows how to handle them.
426*795d594fSAndroid Build Coastguard Worker           continue;
427*795d594fSAndroid Build Coastguard Worker         }
428*795d594fSAndroid Build Coastguard Worker 
429*795d594fSAndroid Build Coastguard Worker         DCHECK_EQ(location, DexRegisterLocation::Kind::kInStack);
430*795d594fSAndroid Build Coastguard Worker 
431*795d594fSAndroid Build Coastguard Worker         int32_t vreg_value = vregs[vreg];
432*795d594fSAndroid Build Coastguard Worker         int32_t slot_offset = vreg_map[vreg].GetStackOffsetInBytes();
433*795d594fSAndroid Build Coastguard Worker         DCHECK_LT(slot_offset, static_cast<int32_t>(frame_size));
434*795d594fSAndroid Build Coastguard Worker         DCHECK_GT(slot_offset, 0);
435*795d594fSAndroid Build Coastguard Worker         (reinterpret_cast<int32_t*>(osr_data->memory))[slot_offset / sizeof(int32_t)] = vreg_value;
436*795d594fSAndroid Build Coastguard Worker       }
437*795d594fSAndroid Build Coastguard Worker     }
438*795d594fSAndroid Build Coastguard Worker 
439*795d594fSAndroid Build Coastguard Worker     osr_data->native_pc = stack_map.GetNativePcOffset(kRuntimeQuickCodeISA) +
440*795d594fSAndroid Build Coastguard Worker         osr_method->GetEntryPoint();
441*795d594fSAndroid Build Coastguard Worker     VLOG(jit) << "Jumping to "
442*795d594fSAndroid Build Coastguard Worker               << method_name
443*795d594fSAndroid Build Coastguard Worker               << "@"
444*795d594fSAndroid Build Coastguard Worker               << std::hex << reinterpret_cast<uintptr_t>(osr_data->native_pc);
445*795d594fSAndroid Build Coastguard Worker   }
446*795d594fSAndroid Build Coastguard Worker   return osr_data;
447*795d594fSAndroid Build Coastguard Worker }
448*795d594fSAndroid Build Coastguard Worker 
MaybeDoOnStackReplacement(Thread * thread,ArtMethod * method,uint32_t dex_pc,int32_t dex_pc_offset,JValue * result)449*795d594fSAndroid Build Coastguard Worker bool Jit::MaybeDoOnStackReplacement(Thread* thread,
450*795d594fSAndroid Build Coastguard Worker                                     ArtMethod* method,
451*795d594fSAndroid Build Coastguard Worker                                     uint32_t dex_pc,
452*795d594fSAndroid Build Coastguard Worker                                     int32_t dex_pc_offset,
453*795d594fSAndroid Build Coastguard Worker                                     JValue* result) {
454*795d594fSAndroid Build Coastguard Worker   Jit* jit = Runtime::Current()->GetJit();
455*795d594fSAndroid Build Coastguard Worker   if (jit == nullptr) {
456*795d594fSAndroid Build Coastguard Worker     return false;
457*795d594fSAndroid Build Coastguard Worker   }
458*795d594fSAndroid Build Coastguard Worker 
459*795d594fSAndroid Build Coastguard Worker   if (UNLIKELY(__builtin_frame_address(0) < thread->GetStackEnd<kNativeStackType>())) {
460*795d594fSAndroid Build Coastguard Worker     // Don't attempt to do an OSR if we are close to the stack limit. Since
461*795d594fSAndroid Build Coastguard Worker     // the interpreter frames are still on stack, OSR has the potential
462*795d594fSAndroid Build Coastguard Worker     // to stack overflow even for a simple loop.
463*795d594fSAndroid Build Coastguard Worker     // b/27094810.
464*795d594fSAndroid Build Coastguard Worker     return false;
465*795d594fSAndroid Build Coastguard Worker   }
466*795d594fSAndroid Build Coastguard Worker 
467*795d594fSAndroid Build Coastguard Worker   // Get the actual Java method if this method is from a proxy class. The compiler
468*795d594fSAndroid Build Coastguard Worker   // and the JIT code cache do not expect methods from proxy classes.
469*795d594fSAndroid Build Coastguard Worker   method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
470*795d594fSAndroid Build Coastguard Worker 
471*795d594fSAndroid Build Coastguard Worker   // Before allowing the jump, make sure no code is actively inspecting the method to avoid
472*795d594fSAndroid Build Coastguard Worker   // jumping from interpreter to OSR while e.g. single stepping. Note that we could selectively
473*795d594fSAndroid Build Coastguard Worker   // disable OSR when single stepping, but that's currently hard to know at this point.
474*795d594fSAndroid Build Coastguard Worker   // Currently, HaveLocalsChanged is not frame specific. It is possible to make it frame specific
475*795d594fSAndroid Build Coastguard Worker   // to allow OSR of frames that don't have any locals changed but it isn't worth the additional
476*795d594fSAndroid Build Coastguard Worker   // complexity.
477*795d594fSAndroid Build Coastguard Worker   if (Runtime::Current()->GetInstrumentation()->NeedsSlowInterpreterForMethod(thread, method) ||
478*795d594fSAndroid Build Coastguard Worker       Runtime::Current()->GetRuntimeCallbacks()->HaveLocalsChanged()) {
479*795d594fSAndroid Build Coastguard Worker     return false;
480*795d594fSAndroid Build Coastguard Worker   }
481*795d594fSAndroid Build Coastguard Worker 
482*795d594fSAndroid Build Coastguard Worker   ShadowFrame* shadow_frame = thread->GetManagedStack()->GetTopShadowFrame();
483*795d594fSAndroid Build Coastguard Worker   OsrData* osr_data = jit->PrepareForOsr(method,
484*795d594fSAndroid Build Coastguard Worker                                          dex_pc + dex_pc_offset,
485*795d594fSAndroid Build Coastguard Worker                                          shadow_frame->GetVRegArgs(0));
486*795d594fSAndroid Build Coastguard Worker 
487*795d594fSAndroid Build Coastguard Worker   if (osr_data == nullptr) {
488*795d594fSAndroid Build Coastguard Worker     return false;
489*795d594fSAndroid Build Coastguard Worker   }
490*795d594fSAndroid Build Coastguard Worker 
491*795d594fSAndroid Build Coastguard Worker   {
492*795d594fSAndroid Build Coastguard Worker     thread->PopShadowFrame();
493*795d594fSAndroid Build Coastguard Worker     ManagedStack fragment;
494*795d594fSAndroid Build Coastguard Worker     thread->PushManagedStackFragment(&fragment);
495*795d594fSAndroid Build Coastguard Worker     (*art_quick_osr_stub)(osr_data->memory,
496*795d594fSAndroid Build Coastguard Worker                           osr_data->frame_size,
497*795d594fSAndroid Build Coastguard Worker                           osr_data->native_pc,
498*795d594fSAndroid Build Coastguard Worker                           result,
499*795d594fSAndroid Build Coastguard Worker                           method->GetShorty(),
500*795d594fSAndroid Build Coastguard Worker                           thread);
501*795d594fSAndroid Build Coastguard Worker 
502*795d594fSAndroid Build Coastguard Worker     if (UNLIKELY(thread->GetException() == Thread::GetDeoptimizationException())) {
503*795d594fSAndroid Build Coastguard Worker       thread->DeoptimizeWithDeoptimizationException(result);
504*795d594fSAndroid Build Coastguard Worker     }
505*795d594fSAndroid Build Coastguard Worker     thread->PopManagedStackFragment(fragment);
506*795d594fSAndroid Build Coastguard Worker   }
507*795d594fSAndroid Build Coastguard Worker   free(osr_data);
508*795d594fSAndroid Build Coastguard Worker   thread->PushShadowFrame(shadow_frame);
509*795d594fSAndroid Build Coastguard Worker   VLOG(jit) << "Done running OSR code for " << method->PrettyMethod();
510*795d594fSAndroid Build Coastguard Worker   return true;
511*795d594fSAndroid Build Coastguard Worker }
512*795d594fSAndroid Build Coastguard Worker 
AddMemoryUsage(ArtMethod * method,size_t bytes)513*795d594fSAndroid Build Coastguard Worker void Jit::AddMemoryUsage(ArtMethod* method, size_t bytes) {
514*795d594fSAndroid Build Coastguard Worker   if (bytes > 4 * MB) {
515*795d594fSAndroid Build Coastguard Worker     LOG(INFO) << "Compiler allocated "
516*795d594fSAndroid Build Coastguard Worker               << PrettySize(bytes)
517*795d594fSAndroid Build Coastguard Worker               << " to compile "
518*795d594fSAndroid Build Coastguard Worker               << ArtMethod::PrettyMethod(method);
519*795d594fSAndroid Build Coastguard Worker   }
520*795d594fSAndroid Build Coastguard Worker   MutexLock mu(Thread::Current(), lock_);
521*795d594fSAndroid Build Coastguard Worker   memory_use_.AddValue(bytes);
522*795d594fSAndroid Build Coastguard Worker }
523*795d594fSAndroid Build Coastguard Worker 
NotifyZygoteCompilationDone()524*795d594fSAndroid Build Coastguard Worker void Jit::NotifyZygoteCompilationDone() {
525*795d594fSAndroid Build Coastguard Worker   if (fd_methods_ == -1) {
526*795d594fSAndroid Build Coastguard Worker     return;
527*795d594fSAndroid Build Coastguard Worker   }
528*795d594fSAndroid Build Coastguard Worker 
529*795d594fSAndroid Build Coastguard Worker   size_t offset = 0;
530*795d594fSAndroid Build Coastguard Worker   for (gc::space::ImageSpace* space : Runtime::Current()->GetHeap()->GetBootImageSpaces()) {
531*795d594fSAndroid Build Coastguard Worker     const ImageHeader& header = space->GetImageHeader();
532*795d594fSAndroid Build Coastguard Worker     const ImageSection& section = header.GetMethodsSection();
533*795d594fSAndroid Build Coastguard Worker     // Because mremap works at page boundaries, we can only handle methods
534*795d594fSAndroid Build Coastguard Worker     // within a page range. For methods that falls above or below the range,
535*795d594fSAndroid Build Coastguard Worker     // the child processes will copy their contents to their private mapping
536*795d594fSAndroid Build Coastguard Worker     // in `child_mapping_methods`. See `MapBootImageMethods`.
537*795d594fSAndroid Build Coastguard Worker     uint8_t* page_start = AlignUp(header.GetImageBegin() + section.Offset(), gPageSize);
538*795d594fSAndroid Build Coastguard Worker     uint8_t* page_end =
539*795d594fSAndroid Build Coastguard Worker         AlignDown(header.GetImageBegin() + section.Offset() + section.Size(), gPageSize);
540*795d594fSAndroid Build Coastguard Worker     if (page_end > page_start) {
541*795d594fSAndroid Build Coastguard Worker       uint64_t capacity = page_end - page_start;
542*795d594fSAndroid Build Coastguard Worker       memcpy(zygote_mapping_methods_.Begin() + offset, page_start, capacity);
543*795d594fSAndroid Build Coastguard Worker       offset += capacity;
544*795d594fSAndroid Build Coastguard Worker     }
545*795d594fSAndroid Build Coastguard Worker   }
546*795d594fSAndroid Build Coastguard Worker 
547*795d594fSAndroid Build Coastguard Worker   // Do an msync to ensure we are not affected by writes still being in caches.
548*795d594fSAndroid Build Coastguard Worker   if (msync(zygote_mapping_methods_.Begin(), fd_methods_size_, MS_SYNC) != 0) {
549*795d594fSAndroid Build Coastguard Worker     PLOG(WARNING) << "Failed to sync boot image methods memory";
550*795d594fSAndroid Build Coastguard Worker     code_cache_->GetZygoteMap()->SetCompilationState(ZygoteCompilationState::kNotifiedFailure);
551*795d594fSAndroid Build Coastguard Worker     return;
552*795d594fSAndroid Build Coastguard Worker   }
553*795d594fSAndroid Build Coastguard Worker 
554*795d594fSAndroid Build Coastguard Worker   // We don't need the shared mapping anymore, and we need to drop it in case
555*795d594fSAndroid Build Coastguard Worker   // the file hasn't been sealed writable.
556*795d594fSAndroid Build Coastguard Worker   zygote_mapping_methods_ = MemMap::Invalid();
557*795d594fSAndroid Build Coastguard Worker 
558*795d594fSAndroid Build Coastguard Worker   // Seal writes now. Zygote and children will map the memory private in order
559*795d594fSAndroid Build Coastguard Worker   // to write to it.
560*795d594fSAndroid Build Coastguard Worker   if (fcntl(fd_methods_, F_ADD_SEALS, F_SEAL_SEAL | F_SEAL_WRITE) == -1) {
561*795d594fSAndroid Build Coastguard Worker     PLOG(WARNING) << "Failed to seal boot image methods file descriptor";
562*795d594fSAndroid Build Coastguard Worker     code_cache_->GetZygoteMap()->SetCompilationState(ZygoteCompilationState::kNotifiedFailure);
563*795d594fSAndroid Build Coastguard Worker     return;
564*795d594fSAndroid Build Coastguard Worker   }
565*795d594fSAndroid Build Coastguard Worker 
566*795d594fSAndroid Build Coastguard Worker   std::string error_str;
567*795d594fSAndroid Build Coastguard Worker   MemMap child_mapping_methods = MemMap::MapFile(
568*795d594fSAndroid Build Coastguard Worker       fd_methods_size_,
569*795d594fSAndroid Build Coastguard Worker       PROT_READ | PROT_WRITE,
570*795d594fSAndroid Build Coastguard Worker       MAP_PRIVATE,
571*795d594fSAndroid Build Coastguard Worker       fd_methods_,
572*795d594fSAndroid Build Coastguard Worker       /* start= */ 0,
573*795d594fSAndroid Build Coastguard Worker       /* low_4gb= */ false,
574*795d594fSAndroid Build Coastguard Worker       "boot-image-methods",
575*795d594fSAndroid Build Coastguard Worker       /* reuse= */ true,  // The mapping will be reused by the mremaps below.
576*795d594fSAndroid Build Coastguard Worker       &error_str);
577*795d594fSAndroid Build Coastguard Worker 
578*795d594fSAndroid Build Coastguard Worker   if (!child_mapping_methods.IsValid()) {
579*795d594fSAndroid Build Coastguard Worker     LOG(WARNING) << "Failed to create child mapping of boot image methods: " << error_str;
580*795d594fSAndroid Build Coastguard Worker     code_cache_->GetZygoteMap()->SetCompilationState(ZygoteCompilationState::kNotifiedFailure);
581*795d594fSAndroid Build Coastguard Worker     return;
582*795d594fSAndroid Build Coastguard Worker   }
583*795d594fSAndroid Build Coastguard Worker 
584*795d594fSAndroid Build Coastguard Worker   // Ensure the contents are the same as before: there was a window between
585*795d594fSAndroid Build Coastguard Worker   // the memcpy and the sealing where other processes could have changed the
586*795d594fSAndroid Build Coastguard Worker   // contents.
587*795d594fSAndroid Build Coastguard Worker   // Note this would not be needed if we could have used F_SEAL_FUTURE_WRITE,
588*795d594fSAndroid Build Coastguard Worker   // see b/143833776.
589*795d594fSAndroid Build Coastguard Worker   offset = 0;
590*795d594fSAndroid Build Coastguard Worker   for (gc::space::ImageSpace* space : Runtime::Current()->GetHeap()->GetBootImageSpaces()) {
591*795d594fSAndroid Build Coastguard Worker     const ImageHeader& header = space->GetImageHeader();
592*795d594fSAndroid Build Coastguard Worker     const ImageSection& section = header.GetMethodsSection();
593*795d594fSAndroid Build Coastguard Worker     // Because mremap works at page boundaries, we can only handle methods
594*795d594fSAndroid Build Coastguard Worker     // within a page range. For methods that falls above or below the range,
595*795d594fSAndroid Build Coastguard Worker     // the child processes will copy their contents to their private mapping
596*795d594fSAndroid Build Coastguard Worker     // in `child_mapping_methods`. See `MapBootImageMethods`.
597*795d594fSAndroid Build Coastguard Worker     uint8_t* page_start = AlignUp(header.GetImageBegin() + section.Offset(), gPageSize);
598*795d594fSAndroid Build Coastguard Worker     uint8_t* page_end =
599*795d594fSAndroid Build Coastguard Worker         AlignDown(header.GetImageBegin() + section.Offset() + section.Size(), gPageSize);
600*795d594fSAndroid Build Coastguard Worker     if (page_end > page_start) {
601*795d594fSAndroid Build Coastguard Worker       uint64_t capacity = page_end - page_start;
602*795d594fSAndroid Build Coastguard Worker       if (memcmp(child_mapping_methods.Begin() + offset, page_start, capacity) != 0) {
603*795d594fSAndroid Build Coastguard Worker         LOG(WARNING) << "Contents differ in boot image methods data";
604*795d594fSAndroid Build Coastguard Worker         code_cache_->GetZygoteMap()->SetCompilationState(
605*795d594fSAndroid Build Coastguard Worker             ZygoteCompilationState::kNotifiedFailure);
606*795d594fSAndroid Build Coastguard Worker         return;
607*795d594fSAndroid Build Coastguard Worker       }
608*795d594fSAndroid Build Coastguard Worker       offset += capacity;
609*795d594fSAndroid Build Coastguard Worker     }
610*795d594fSAndroid Build Coastguard Worker   }
611*795d594fSAndroid Build Coastguard Worker 
612*795d594fSAndroid Build Coastguard Worker   // Future spawned processes don't need the fd anymore.
613*795d594fSAndroid Build Coastguard Worker   fd_methods_.reset();
614*795d594fSAndroid Build Coastguard Worker 
615*795d594fSAndroid Build Coastguard Worker   // In order to have the zygote and children share the memory, we also remap
616*795d594fSAndroid Build Coastguard Worker   // the memory into the zygote process.
617*795d594fSAndroid Build Coastguard Worker   offset = 0;
618*795d594fSAndroid Build Coastguard Worker   for (gc::space::ImageSpace* space : Runtime::Current()->GetHeap()->GetBootImageSpaces()) {
619*795d594fSAndroid Build Coastguard Worker     const ImageHeader& header = space->GetImageHeader();
620*795d594fSAndroid Build Coastguard Worker     const ImageSection& section = header.GetMethodsSection();
621*795d594fSAndroid Build Coastguard Worker     // Because mremap works at page boundaries, we can only handle methods
622*795d594fSAndroid Build Coastguard Worker     // within a page range. For methods that falls above or below the range,
623*795d594fSAndroid Build Coastguard Worker     // the child processes will copy their contents to their private mapping
624*795d594fSAndroid Build Coastguard Worker     // in `child_mapping_methods`. See `MapBootImageMethods`.
625*795d594fSAndroid Build Coastguard Worker     uint8_t* page_start = AlignUp(header.GetImageBegin() + section.Offset(), gPageSize);
626*795d594fSAndroid Build Coastguard Worker     uint8_t* page_end =
627*795d594fSAndroid Build Coastguard Worker         AlignDown(header.GetImageBegin() + section.Offset() + section.Size(), gPageSize);
628*795d594fSAndroid Build Coastguard Worker     if (page_end > page_start) {
629*795d594fSAndroid Build Coastguard Worker       uint64_t capacity = page_end - page_start;
630*795d594fSAndroid Build Coastguard Worker       if (mremap(child_mapping_methods.Begin() + offset,
631*795d594fSAndroid Build Coastguard Worker                  capacity,
632*795d594fSAndroid Build Coastguard Worker                  capacity,
633*795d594fSAndroid Build Coastguard Worker                  MREMAP_FIXED | MREMAP_MAYMOVE,
634*795d594fSAndroid Build Coastguard Worker                  page_start) == MAP_FAILED) {
635*795d594fSAndroid Build Coastguard Worker         // Failing to remap is safe as the process will just use the old
636*795d594fSAndroid Build Coastguard Worker         // contents.
637*795d594fSAndroid Build Coastguard Worker         PLOG(WARNING) << "Failed mremap of boot image methods of " << space->GetImageFilename();
638*795d594fSAndroid Build Coastguard Worker       }
639*795d594fSAndroid Build Coastguard Worker       offset += capacity;
640*795d594fSAndroid Build Coastguard Worker     }
641*795d594fSAndroid Build Coastguard Worker   }
642*795d594fSAndroid Build Coastguard Worker 
643*795d594fSAndroid Build Coastguard Worker   LOG(INFO) << "Successfully notified child processes on sharing boot image methods";
644*795d594fSAndroid Build Coastguard Worker 
645*795d594fSAndroid Build Coastguard Worker   // Mark that compilation of boot classpath is done, and memory can now be
646*795d594fSAndroid Build Coastguard Worker   // shared. Other processes will pick up this information.
647*795d594fSAndroid Build Coastguard Worker   code_cache_->GetZygoteMap()->SetCompilationState(ZygoteCompilationState::kNotifiedOk);
648*795d594fSAndroid Build Coastguard Worker }
649*795d594fSAndroid Build Coastguard Worker 
650*795d594fSAndroid Build Coastguard Worker class JitCompileTask final : public Task {
651*795d594fSAndroid Build Coastguard Worker  public:
652*795d594fSAndroid Build Coastguard Worker   enum class TaskKind {
653*795d594fSAndroid Build Coastguard Worker     kCompile,
654*795d594fSAndroid Build Coastguard Worker     kPreCompile,
655*795d594fSAndroid Build Coastguard Worker   };
656*795d594fSAndroid Build Coastguard Worker 
JitCompileTask(ArtMethod * method,TaskKind task_kind,CompilationKind compilation_kind)657*795d594fSAndroid Build Coastguard Worker   JitCompileTask(ArtMethod* method,
658*795d594fSAndroid Build Coastguard Worker                  TaskKind task_kind,
659*795d594fSAndroid Build Coastguard Worker                  CompilationKind compilation_kind)
660*795d594fSAndroid Build Coastguard Worker       : method_(method),
661*795d594fSAndroid Build Coastguard Worker         kind_(task_kind),
662*795d594fSAndroid Build Coastguard Worker         compilation_kind_(compilation_kind) {
663*795d594fSAndroid Build Coastguard Worker   }
664*795d594fSAndroid Build Coastguard Worker 
Run(Thread * self)665*795d594fSAndroid Build Coastguard Worker   void Run(Thread* self) override {
666*795d594fSAndroid Build Coastguard Worker     {
667*795d594fSAndroid Build Coastguard Worker       ScopedObjectAccess soa(self);
668*795d594fSAndroid Build Coastguard Worker       switch (kind_) {
669*795d594fSAndroid Build Coastguard Worker         case TaskKind::kCompile:
670*795d594fSAndroid Build Coastguard Worker         case TaskKind::kPreCompile: {
671*795d594fSAndroid Build Coastguard Worker           Runtime::Current()->GetJit()->CompileMethodInternal(
672*795d594fSAndroid Build Coastguard Worker               method_,
673*795d594fSAndroid Build Coastguard Worker               self,
674*795d594fSAndroid Build Coastguard Worker               compilation_kind_,
675*795d594fSAndroid Build Coastguard Worker               /* prejit= */ (kind_ == TaskKind::kPreCompile));
676*795d594fSAndroid Build Coastguard Worker           break;
677*795d594fSAndroid Build Coastguard Worker         }
678*795d594fSAndroid Build Coastguard Worker       }
679*795d594fSAndroid Build Coastguard Worker     }
680*795d594fSAndroid Build Coastguard Worker     ProfileSaver::NotifyJitActivity();
681*795d594fSAndroid Build Coastguard Worker   }
682*795d594fSAndroid Build Coastguard Worker 
Finalize()683*795d594fSAndroid Build Coastguard Worker   void Finalize() override {
684*795d594fSAndroid Build Coastguard Worker     JitThreadPool* thread_pool = Runtime::Current()->GetJit()->GetThreadPool();
685*795d594fSAndroid Build Coastguard Worker     if (thread_pool != nullptr) {
686*795d594fSAndroid Build Coastguard Worker       thread_pool->Remove(this);
687*795d594fSAndroid Build Coastguard Worker     }
688*795d594fSAndroid Build Coastguard Worker     delete this;
689*795d594fSAndroid Build Coastguard Worker   }
690*795d594fSAndroid Build Coastguard Worker 
GetArtMethod() const691*795d594fSAndroid Build Coastguard Worker   ArtMethod* GetArtMethod() const {
692*795d594fSAndroid Build Coastguard Worker     return method_;
693*795d594fSAndroid Build Coastguard Worker   }
694*795d594fSAndroid Build Coastguard Worker 
GetCompilationKind() const695*795d594fSAndroid Build Coastguard Worker   CompilationKind GetCompilationKind() const {
696*795d594fSAndroid Build Coastguard Worker     return compilation_kind_;
697*795d594fSAndroid Build Coastguard Worker   }
698*795d594fSAndroid Build Coastguard Worker 
699*795d594fSAndroid Build Coastguard Worker  private:
700*795d594fSAndroid Build Coastguard Worker   ArtMethod* const method_;
701*795d594fSAndroid Build Coastguard Worker   const TaskKind kind_;
702*795d594fSAndroid Build Coastguard Worker   const CompilationKind compilation_kind_;
703*795d594fSAndroid Build Coastguard Worker 
704*795d594fSAndroid Build Coastguard Worker   DISALLOW_IMPLICIT_CONSTRUCTORS(JitCompileTask);
705*795d594fSAndroid Build Coastguard Worker };
706*795d594fSAndroid Build Coastguard Worker 
GetProfileFile(const std::string & dex_location)707*795d594fSAndroid Build Coastguard Worker static std::string GetProfileFile(const std::string& dex_location) {
708*795d594fSAndroid Build Coastguard Worker   // Hardcoded assumption where the profile file is.
709*795d594fSAndroid Build Coastguard Worker   // TODO(ngeoffray): this is brittle and we would need to change change if we
710*795d594fSAndroid Build Coastguard Worker   // wanted to do more eager JITting of methods in a profile. This is
711*795d594fSAndroid Build Coastguard Worker   // currently only for system server.
712*795d594fSAndroid Build Coastguard Worker   return dex_location + ".prof";
713*795d594fSAndroid Build Coastguard Worker }
714*795d594fSAndroid Build Coastguard Worker 
GetBootProfileFile(const std::string & profile)715*795d594fSAndroid Build Coastguard Worker static std::string GetBootProfileFile(const std::string& profile) {
716*795d594fSAndroid Build Coastguard Worker   // The boot profile can be found next to the compilation profile, with a
717*795d594fSAndroid Build Coastguard Worker   // different extension.
718*795d594fSAndroid Build Coastguard Worker   return ReplaceFileExtension(profile, "bprof");
719*795d594fSAndroid Build Coastguard Worker }
720*795d594fSAndroid Build Coastguard Worker 
721*795d594fSAndroid Build Coastguard Worker // Return whether the address is guaranteed to be backed by a file or is shared.
722*795d594fSAndroid Build Coastguard Worker // This information can be used to know whether MADV_DONTNEED will make
723*795d594fSAndroid Build Coastguard Worker // following accesses repopulate the memory or return zero.
IsAddressKnownBackedByFileOrShared(const void * addr)724*795d594fSAndroid Build Coastguard Worker static bool IsAddressKnownBackedByFileOrShared(const void* addr) {
725*795d594fSAndroid Build Coastguard Worker   // We use the Linux pagemap interface for knowing if an address is backed
726*795d594fSAndroid Build Coastguard Worker   // by a file or is shared. See:
727*795d594fSAndroid Build Coastguard Worker   // https://www.kernel.org/doc/Documentation/vm/pagemap.txt
728*795d594fSAndroid Build Coastguard Worker   const size_t page_size = MemMap::GetPageSize();
729*795d594fSAndroid Build Coastguard Worker   uintptr_t vmstart = reinterpret_cast<uintptr_t>(AlignDown(addr, page_size));
730*795d594fSAndroid Build Coastguard Worker   off_t index = (vmstart / page_size) * sizeof(uint64_t);
731*795d594fSAndroid Build Coastguard Worker   android::base::unique_fd pagemap(open("/proc/self/pagemap", O_RDONLY | O_CLOEXEC));
732*795d594fSAndroid Build Coastguard Worker   if (pagemap == -1) {
733*795d594fSAndroid Build Coastguard Worker     return false;
734*795d594fSAndroid Build Coastguard Worker   }
735*795d594fSAndroid Build Coastguard Worker   if (lseek(pagemap, index, SEEK_SET) != index) {
736*795d594fSAndroid Build Coastguard Worker     return false;
737*795d594fSAndroid Build Coastguard Worker   }
738*795d594fSAndroid Build Coastguard Worker   uint64_t flags;
739*795d594fSAndroid Build Coastguard Worker   if (read(pagemap, &flags, sizeof(uint64_t)) != sizeof(uint64_t)) {
740*795d594fSAndroid Build Coastguard Worker     return false;
741*795d594fSAndroid Build Coastguard Worker   }
742*795d594fSAndroid Build Coastguard Worker   // From https://www.kernel.org/doc/Documentation/vm/pagemap.txt:
743*795d594fSAndroid Build Coastguard Worker   //  * Bit  61    page is file-page or shared-anon (since 3.5)
744*795d594fSAndroid Build Coastguard Worker   return (flags & (1LL << 61)) != 0;
745*795d594fSAndroid Build Coastguard Worker }
746*795d594fSAndroid Build Coastguard Worker 
747*795d594fSAndroid Build Coastguard Worker /**
748*795d594fSAndroid Build Coastguard Worker  * A JIT task to run after all profile compilation is done.
749*795d594fSAndroid Build Coastguard Worker  */
750*795d594fSAndroid Build Coastguard Worker class JitDoneCompilingProfileTask final : public SelfDeletingTask {
751*795d594fSAndroid Build Coastguard Worker  public:
JitDoneCompilingProfileTask(const std::vector<const DexFile * > & dex_files)752*795d594fSAndroid Build Coastguard Worker   explicit JitDoneCompilingProfileTask(const std::vector<const DexFile*>& dex_files)
753*795d594fSAndroid Build Coastguard Worker       : dex_files_(dex_files) {}
754*795d594fSAndroid Build Coastguard Worker 
Run(Thread * self)755*795d594fSAndroid Build Coastguard Worker   void Run([[maybe_unused]] Thread* self) override {
756*795d594fSAndroid Build Coastguard Worker     // Madvise DONTNEED dex files now that we're done compiling methods.
757*795d594fSAndroid Build Coastguard Worker     for (const DexFile* dex_file : dex_files_) {
758*795d594fSAndroid Build Coastguard Worker       if (IsAddressKnownBackedByFileOrShared(dex_file->Begin())) {
759*795d594fSAndroid Build Coastguard Worker         int result = madvise(const_cast<uint8_t*>(AlignDown(dex_file->Begin(), gPageSize)),
760*795d594fSAndroid Build Coastguard Worker                              RoundUp(dex_file->Size(), gPageSize),
761*795d594fSAndroid Build Coastguard Worker                              MADV_DONTNEED);
762*795d594fSAndroid Build Coastguard Worker         if (result == -1) {
763*795d594fSAndroid Build Coastguard Worker           PLOG(WARNING) << "Madvise failed";
764*795d594fSAndroid Build Coastguard Worker         }
765*795d594fSAndroid Build Coastguard Worker       }
766*795d594fSAndroid Build Coastguard Worker     }
767*795d594fSAndroid Build Coastguard Worker   }
768*795d594fSAndroid Build Coastguard Worker 
769*795d594fSAndroid Build Coastguard Worker  private:
770*795d594fSAndroid Build Coastguard Worker   std::vector<const DexFile*> dex_files_;
771*795d594fSAndroid Build Coastguard Worker 
772*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(JitDoneCompilingProfileTask);
773*795d594fSAndroid Build Coastguard Worker };
774*795d594fSAndroid Build Coastguard Worker 
775*795d594fSAndroid Build Coastguard Worker class JitZygoteDoneCompilingTask final : public SelfDeletingTask {
776*795d594fSAndroid Build Coastguard Worker  public:
JitZygoteDoneCompilingTask()777*795d594fSAndroid Build Coastguard Worker   JitZygoteDoneCompilingTask() {}
778*795d594fSAndroid Build Coastguard Worker 
Run(Thread * self)779*795d594fSAndroid Build Coastguard Worker   void Run([[maybe_unused]] Thread* self) override {
780*795d594fSAndroid Build Coastguard Worker     DCHECK(Runtime::Current()->IsZygote());
781*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetJit()->GetCodeCache()->GetZygoteMap()->SetCompilationState(
782*795d594fSAndroid Build Coastguard Worker         ZygoteCompilationState::kDone);
783*795d594fSAndroid Build Coastguard Worker   }
784*795d594fSAndroid Build Coastguard Worker 
785*795d594fSAndroid Build Coastguard Worker  private:
786*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(JitZygoteDoneCompilingTask);
787*795d594fSAndroid Build Coastguard Worker };
788*795d594fSAndroid Build Coastguard Worker 
789*795d594fSAndroid Build Coastguard Worker /**
790*795d594fSAndroid Build Coastguard Worker  * A JIT task to run Java verification of boot classpath classes that were not
791*795d594fSAndroid Build Coastguard Worker  * verified at compile-time.
792*795d594fSAndroid Build Coastguard Worker  */
793*795d594fSAndroid Build Coastguard Worker class ZygoteVerificationTask final : public Task {
794*795d594fSAndroid Build Coastguard Worker  public:
ZygoteVerificationTask()795*795d594fSAndroid Build Coastguard Worker   ZygoteVerificationTask() {}
796*795d594fSAndroid Build Coastguard Worker 
Run(Thread * self)797*795d594fSAndroid Build Coastguard Worker   void Run(Thread* self) override {
798*795d594fSAndroid Build Coastguard Worker     // We are going to load class and run verification, which may also need to load
799*795d594fSAndroid Build Coastguard Worker     // classes. If the thread cannot load classes (typically when the runtime is
800*795d594fSAndroid Build Coastguard Worker     // debuggable), then just return.
801*795d594fSAndroid Build Coastguard Worker     if (!self->CanLoadClasses()) {
802*795d594fSAndroid Build Coastguard Worker       return;
803*795d594fSAndroid Build Coastguard Worker     }
804*795d594fSAndroid Build Coastguard Worker     Runtime* runtime = Runtime::Current();
805*795d594fSAndroid Build Coastguard Worker     ClassLinker* linker = runtime->GetClassLinker();
806*795d594fSAndroid Build Coastguard Worker     const std::vector<const DexFile*>& boot_class_path =
807*795d594fSAndroid Build Coastguard Worker         runtime->GetClassLinker()->GetBootClassPath();
808*795d594fSAndroid Build Coastguard Worker     ScopedObjectAccess soa(self);
809*795d594fSAndroid Build Coastguard Worker     StackHandleScope<2> hs(self);
810*795d594fSAndroid Build Coastguard Worker     MutableHandle<mirror::DexCache> dex_cache = hs.NewHandle<mirror::DexCache>(nullptr);
811*795d594fSAndroid Build Coastguard Worker     MutableHandle<mirror::Class> klass = hs.NewHandle<mirror::Class>(nullptr);
812*795d594fSAndroid Build Coastguard Worker     uint64_t start_ns = ThreadCpuNanoTime();
813*795d594fSAndroid Build Coastguard Worker     uint64_t number_of_classes = 0;
814*795d594fSAndroid Build Coastguard Worker     for (const DexFile* dex_file : boot_class_path) {
815*795d594fSAndroid Build Coastguard Worker       dex_cache.Assign(linker->FindDexCache(self, *dex_file));
816*795d594fSAndroid Build Coastguard Worker       for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
817*795d594fSAndroid Build Coastguard Worker         const dex::ClassDef& class_def = dex_file->GetClassDef(i);
818*795d594fSAndroid Build Coastguard Worker         klass.Assign(linker->LookupResolvedType(
819*795d594fSAndroid Build Coastguard Worker             class_def.class_idx_, dex_cache.Get(), /* class_loader= */ nullptr));
820*795d594fSAndroid Build Coastguard Worker         if (klass == nullptr) {
821*795d594fSAndroid Build Coastguard Worker           // Class not loaded yet.
822*795d594fSAndroid Build Coastguard Worker           DCHECK(!self->IsExceptionPending());
823*795d594fSAndroid Build Coastguard Worker           continue;
824*795d594fSAndroid Build Coastguard Worker         }
825*795d594fSAndroid Build Coastguard Worker         if (klass->IsVerified()) {
826*795d594fSAndroid Build Coastguard Worker           continue;
827*795d594fSAndroid Build Coastguard Worker         }
828*795d594fSAndroid Build Coastguard Worker         if (linker->VerifyClass(self, /* verifier_deps= */ nullptr, klass) ==
829*795d594fSAndroid Build Coastguard Worker                 verifier::FailureKind::kHardFailure) {
830*795d594fSAndroid Build Coastguard Worker           CHECK(self->IsExceptionPending());
831*795d594fSAndroid Build Coastguard Worker           LOG(WARNING) << "Methods in the boot classpath failed to verify: "
832*795d594fSAndroid Build Coastguard Worker                        << self->GetException()->Dump();
833*795d594fSAndroid Build Coastguard Worker           self->ClearException();
834*795d594fSAndroid Build Coastguard Worker         } else {
835*795d594fSAndroid Build Coastguard Worker           ++number_of_classes;
836*795d594fSAndroid Build Coastguard Worker         }
837*795d594fSAndroid Build Coastguard Worker         CHECK(!self->IsExceptionPending());
838*795d594fSAndroid Build Coastguard Worker       }
839*795d594fSAndroid Build Coastguard Worker     }
840*795d594fSAndroid Build Coastguard Worker     LOG(INFO) << "Background verification of "
841*795d594fSAndroid Build Coastguard Worker               << number_of_classes
842*795d594fSAndroid Build Coastguard Worker               << " classes from boot classpath took "
843*795d594fSAndroid Build Coastguard Worker               << PrettyDuration(ThreadCpuNanoTime() - start_ns);
844*795d594fSAndroid Build Coastguard Worker   }
845*795d594fSAndroid Build Coastguard Worker };
846*795d594fSAndroid Build Coastguard Worker 
847*795d594fSAndroid Build Coastguard Worker class ZygoteTask final : public Task {
848*795d594fSAndroid Build Coastguard Worker  public:
ZygoteTask()849*795d594fSAndroid Build Coastguard Worker   ZygoteTask() {}
850*795d594fSAndroid Build Coastguard Worker 
Run(Thread * self)851*795d594fSAndroid Build Coastguard Worker   void Run(Thread* self) override {
852*795d594fSAndroid Build Coastguard Worker     Runtime* runtime = Runtime::Current();
853*795d594fSAndroid Build Coastguard Worker     uint32_t added_to_queue = 0;
854*795d594fSAndroid Build Coastguard Worker     for (gc::space::ImageSpace* space : Runtime::Current()->GetHeap()->GetBootImageSpaces()) {
855*795d594fSAndroid Build Coastguard Worker       const std::vector<const DexFile*>& boot_class_path =
856*795d594fSAndroid Build Coastguard Worker           runtime->GetClassLinker()->GetBootClassPath();
857*795d594fSAndroid Build Coastguard Worker       ScopedNullHandle<mirror::ClassLoader> null_handle;
858*795d594fSAndroid Build Coastguard Worker       // We avoid doing compilation at boot for the secondary zygote, as apps forked from it are not
859*795d594fSAndroid Build Coastguard Worker       // critical for boot.
860*795d594fSAndroid Build Coastguard Worker       if (Runtime::Current()->IsPrimaryZygote()) {
861*795d594fSAndroid Build Coastguard Worker         for (const std::string& profile_file : space->GetProfileFiles()) {
862*795d594fSAndroid Build Coastguard Worker           std::string boot_profile = GetBootProfileFile(profile_file);
863*795d594fSAndroid Build Coastguard Worker           LOG(INFO) << "JIT Zygote looking at boot profile " << boot_profile;
864*795d594fSAndroid Build Coastguard Worker 
865*795d594fSAndroid Build Coastguard Worker           // We add to the queue for zygote so that we can fork processes in-between compilations.
866*795d594fSAndroid Build Coastguard Worker           added_to_queue += runtime->GetJit()->CompileMethodsFromBootProfile(
867*795d594fSAndroid Build Coastguard Worker               self, boot_class_path, boot_profile, null_handle, /* add_to_queue= */ true);
868*795d594fSAndroid Build Coastguard Worker         }
869*795d594fSAndroid Build Coastguard Worker       }
870*795d594fSAndroid Build Coastguard Worker       for (const std::string& profile_file : space->GetProfileFiles()) {
871*795d594fSAndroid Build Coastguard Worker         LOG(INFO) << "JIT Zygote looking at profile " << profile_file;
872*795d594fSAndroid Build Coastguard Worker 
873*795d594fSAndroid Build Coastguard Worker         added_to_queue += runtime->GetJit()->CompileMethodsFromProfile(
874*795d594fSAndroid Build Coastguard Worker             self, boot_class_path, profile_file, null_handle, /* add_to_queue= */ true);
875*795d594fSAndroid Build Coastguard Worker       }
876*795d594fSAndroid Build Coastguard Worker     }
877*795d594fSAndroid Build Coastguard Worker     DCHECK(runtime->GetJit()->InZygoteUsingJit());
878*795d594fSAndroid Build Coastguard Worker     runtime->GetJit()->AddPostBootTask(self, new JitZygoteDoneCompilingTask());
879*795d594fSAndroid Build Coastguard Worker 
880*795d594fSAndroid Build Coastguard Worker     JitCodeCache* code_cache = runtime->GetJit()->GetCodeCache();
881*795d594fSAndroid Build Coastguard Worker     code_cache->GetZygoteMap()->Initialize(added_to_queue);
882*795d594fSAndroid Build Coastguard Worker   }
883*795d594fSAndroid Build Coastguard Worker 
Finalize()884*795d594fSAndroid Build Coastguard Worker   void Finalize() override {
885*795d594fSAndroid Build Coastguard Worker     delete this;
886*795d594fSAndroid Build Coastguard Worker   }
887*795d594fSAndroid Build Coastguard Worker 
888*795d594fSAndroid Build Coastguard Worker  private:
889*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ZygoteTask);
890*795d594fSAndroid Build Coastguard Worker };
891*795d594fSAndroid Build Coastguard Worker 
892*795d594fSAndroid Build Coastguard Worker class JitProfileTask final : public Task {
893*795d594fSAndroid Build Coastguard Worker  public:
JitProfileTask(const std::vector<std::unique_ptr<const DexFile>> & dex_files,jobject class_loader)894*795d594fSAndroid Build Coastguard Worker   JitProfileTask(const std::vector<std::unique_ptr<const DexFile>>& dex_files,
895*795d594fSAndroid Build Coastguard Worker                  jobject class_loader) {
896*795d594fSAndroid Build Coastguard Worker     ScopedObjectAccess soa(Thread::Current());
897*795d594fSAndroid Build Coastguard Worker     StackHandleScope<1> hs(soa.Self());
898*795d594fSAndroid Build Coastguard Worker     Handle<mirror::ClassLoader> h_loader(hs.NewHandle(
899*795d594fSAndroid Build Coastguard Worker         soa.Decode<mirror::ClassLoader>(class_loader)));
900*795d594fSAndroid Build Coastguard Worker     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
901*795d594fSAndroid Build Coastguard Worker     for (const auto& dex_file : dex_files) {
902*795d594fSAndroid Build Coastguard Worker       dex_files_.push_back(dex_file.get());
903*795d594fSAndroid Build Coastguard Worker       // Register the dex file so that we can guarantee it doesn't get deleted
904*795d594fSAndroid Build Coastguard Worker       // while reading it during the task.
905*795d594fSAndroid Build Coastguard Worker       class_linker->RegisterDexFile(*dex_file.get(), h_loader.Get());
906*795d594fSAndroid Build Coastguard Worker     }
907*795d594fSAndroid Build Coastguard Worker     // We also create our own global ref to use this class loader later.
908*795d594fSAndroid Build Coastguard Worker     class_loader_ = soa.Vm()->AddGlobalRef(soa.Self(), h_loader.Get());
909*795d594fSAndroid Build Coastguard Worker   }
910*795d594fSAndroid Build Coastguard Worker 
Run(Thread * self)911*795d594fSAndroid Build Coastguard Worker   void Run(Thread* self) override {
912*795d594fSAndroid Build Coastguard Worker     ScopedObjectAccess soa(self);
913*795d594fSAndroid Build Coastguard Worker     StackHandleScope<1> hs(self);
914*795d594fSAndroid Build Coastguard Worker     Handle<mirror::ClassLoader> loader = hs.NewHandle<mirror::ClassLoader>(
915*795d594fSAndroid Build Coastguard Worker         soa.Decode<mirror::ClassLoader>(class_loader_));
916*795d594fSAndroid Build Coastguard Worker 
917*795d594fSAndroid Build Coastguard Worker     std::string profile = GetProfileFile(dex_files_[0]->GetLocation());
918*795d594fSAndroid Build Coastguard Worker     std::string boot_profile = GetBootProfileFile(profile);
919*795d594fSAndroid Build Coastguard Worker 
920*795d594fSAndroid Build Coastguard Worker     Jit* jit = Runtime::Current()->GetJit();
921*795d594fSAndroid Build Coastguard Worker 
922*795d594fSAndroid Build Coastguard Worker     jit->CompileMethodsFromBootProfile(
923*795d594fSAndroid Build Coastguard Worker         self,
924*795d594fSAndroid Build Coastguard Worker         dex_files_,
925*795d594fSAndroid Build Coastguard Worker         boot_profile,
926*795d594fSAndroid Build Coastguard Worker         loader,
927*795d594fSAndroid Build Coastguard Worker         /* add_to_queue= */ false);
928*795d594fSAndroid Build Coastguard Worker 
929*795d594fSAndroid Build Coastguard Worker     jit->CompileMethodsFromProfile(
930*795d594fSAndroid Build Coastguard Worker         self,
931*795d594fSAndroid Build Coastguard Worker         dex_files_,
932*795d594fSAndroid Build Coastguard Worker         profile,
933*795d594fSAndroid Build Coastguard Worker         loader,
934*795d594fSAndroid Build Coastguard Worker         /* add_to_queue= */ true);
935*795d594fSAndroid Build Coastguard Worker   }
936*795d594fSAndroid Build Coastguard Worker 
Finalize()937*795d594fSAndroid Build Coastguard Worker   void Finalize() override {
938*795d594fSAndroid Build Coastguard Worker     delete this;
939*795d594fSAndroid Build Coastguard Worker   }
940*795d594fSAndroid Build Coastguard Worker 
~JitProfileTask()941*795d594fSAndroid Build Coastguard Worker   ~JitProfileTask() {
942*795d594fSAndroid Build Coastguard Worker     ScopedObjectAccess soa(Thread::Current());
943*795d594fSAndroid Build Coastguard Worker     soa.Vm()->DeleteGlobalRef(soa.Self(), class_loader_);
944*795d594fSAndroid Build Coastguard Worker   }
945*795d594fSAndroid Build Coastguard Worker 
946*795d594fSAndroid Build Coastguard Worker  private:
947*795d594fSAndroid Build Coastguard Worker   std::vector<const DexFile*> dex_files_;
948*795d594fSAndroid Build Coastguard Worker   jobject class_loader_;
949*795d594fSAndroid Build Coastguard Worker 
950*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(JitProfileTask);
951*795d594fSAndroid Build Coastguard Worker };
952*795d594fSAndroid Build Coastguard Worker 
CopyIfDifferent(void * s1,const void * s2,size_t n)953*795d594fSAndroid Build Coastguard Worker static void CopyIfDifferent(void* s1, const void* s2, size_t n) {
954*795d594fSAndroid Build Coastguard Worker   if (memcmp(s1, s2, n) != 0) {
955*795d594fSAndroid Build Coastguard Worker     memcpy(s1, s2, n);
956*795d594fSAndroid Build Coastguard Worker   }
957*795d594fSAndroid Build Coastguard Worker }
958*795d594fSAndroid Build Coastguard Worker 
MapBootImageMethods()959*795d594fSAndroid Build Coastguard Worker void Jit::MapBootImageMethods() {
960*795d594fSAndroid Build Coastguard Worker   if (Runtime::Current()->IsJavaDebuggable()) {
961*795d594fSAndroid Build Coastguard Worker     LOG(INFO) << "Not mapping boot image methods due to process being debuggable";
962*795d594fSAndroid Build Coastguard Worker     return;
963*795d594fSAndroid Build Coastguard Worker   }
964*795d594fSAndroid Build Coastguard Worker   CHECK_NE(fd_methods_.get(), -1);
965*795d594fSAndroid Build Coastguard Worker   if (!code_cache_->GetZygoteMap()->CanMapBootImageMethods()) {
966*795d594fSAndroid Build Coastguard Worker     LOG(WARNING) << "Not mapping boot image methods due to error from zygote";
967*795d594fSAndroid Build Coastguard Worker     // We don't need the fd anymore.
968*795d594fSAndroid Build Coastguard Worker     fd_methods_.reset();
969*795d594fSAndroid Build Coastguard Worker     return;
970*795d594fSAndroid Build Coastguard Worker   }
971*795d594fSAndroid Build Coastguard Worker 
972*795d594fSAndroid Build Coastguard Worker   std::string error_str;
973*795d594fSAndroid Build Coastguard Worker   MemMap child_mapping_methods = MemMap::MapFile(
974*795d594fSAndroid Build Coastguard Worker       fd_methods_size_,
975*795d594fSAndroid Build Coastguard Worker       PROT_READ | PROT_WRITE,
976*795d594fSAndroid Build Coastguard Worker       MAP_PRIVATE,
977*795d594fSAndroid Build Coastguard Worker       fd_methods_,
978*795d594fSAndroid Build Coastguard Worker       /* start= */ 0,
979*795d594fSAndroid Build Coastguard Worker       /* low_4gb= */ false,
980*795d594fSAndroid Build Coastguard Worker       "boot-image-methods",
981*795d594fSAndroid Build Coastguard Worker       /* reuse= */ true,  // The mapping will be reused by the mremaps below.
982*795d594fSAndroid Build Coastguard Worker       &error_str);
983*795d594fSAndroid Build Coastguard Worker 
984*795d594fSAndroid Build Coastguard Worker   // We don't need the fd anymore.
985*795d594fSAndroid Build Coastguard Worker   fd_methods_.reset();
986*795d594fSAndroid Build Coastguard Worker 
987*795d594fSAndroid Build Coastguard Worker   if (!child_mapping_methods.IsValid()) {
988*795d594fSAndroid Build Coastguard Worker     LOG(WARNING) << "Failed to create child mapping of boot image methods: " << error_str;
989*795d594fSAndroid Build Coastguard Worker     return;
990*795d594fSAndroid Build Coastguard Worker   }
991*795d594fSAndroid Build Coastguard Worker   //  We are going to mremap the child mapping into the image:
992*795d594fSAndroid Build Coastguard Worker   //
993*795d594fSAndroid Build Coastguard Worker   //                            ImageSection       ChildMappingMethods
994*795d594fSAndroid Build Coastguard Worker   //
995*795d594fSAndroid Build Coastguard Worker   //         section start -->  -----------
996*795d594fSAndroid Build Coastguard Worker   //                            |         |
997*795d594fSAndroid Build Coastguard Worker   //                            |         |
998*795d594fSAndroid Build Coastguard Worker   //            page_start -->  |         |   <-----   -----------
999*795d594fSAndroid Build Coastguard Worker   //                            |         |            |         |
1000*795d594fSAndroid Build Coastguard Worker   //                            |         |            |         |
1001*795d594fSAndroid Build Coastguard Worker   //                            |         |            |         |
1002*795d594fSAndroid Build Coastguard Worker   //                            |         |            |         |
1003*795d594fSAndroid Build Coastguard Worker   //                            |         |            |         |
1004*795d594fSAndroid Build Coastguard Worker   //                            |         |            |         |
1005*795d594fSAndroid Build Coastguard Worker   //                            |         |            |         |
1006*795d594fSAndroid Build Coastguard Worker   //             page_end  -->  |         |   <-----   -----------
1007*795d594fSAndroid Build Coastguard Worker   //                            |         |
1008*795d594fSAndroid Build Coastguard Worker   //         section end   -->  -----------
1009*795d594fSAndroid Build Coastguard Worker   //
1010*795d594fSAndroid Build Coastguard Worker   size_t offset = 0;
1011*795d594fSAndroid Build Coastguard Worker   for (gc::space::ImageSpace* space : Runtime::Current()->GetHeap()->GetBootImageSpaces()) {
1012*795d594fSAndroid Build Coastguard Worker     const ImageHeader& header = space->GetImageHeader();
1013*795d594fSAndroid Build Coastguard Worker     const ImageSection& section = header.GetMethodsSection();
1014*795d594fSAndroid Build Coastguard Worker     uint8_t* page_start = AlignUp(header.GetImageBegin() + section.Offset(), gPageSize);
1015*795d594fSAndroid Build Coastguard Worker     uint8_t* page_end =
1016*795d594fSAndroid Build Coastguard Worker         AlignDown(header.GetImageBegin() + section.Offset() + section.Size(), gPageSize);
1017*795d594fSAndroid Build Coastguard Worker     if (page_end <= page_start) {
1018*795d594fSAndroid Build Coastguard Worker       // Section doesn't contain one aligned entire page.
1019*795d594fSAndroid Build Coastguard Worker       continue;
1020*795d594fSAndroid Build Coastguard Worker     }
1021*795d594fSAndroid Build Coastguard Worker     uint64_t capacity = page_end - page_start;
1022*795d594fSAndroid Build Coastguard Worker     // Walk over methods in the boot image, and check for:
1023*795d594fSAndroid Build Coastguard Worker     // 1) methods whose class is not initialized in the process, but are in the
1024*795d594fSAndroid Build Coastguard Worker     // zygote process. For such methods, we need their entrypoints to be stubs
1025*795d594fSAndroid Build Coastguard Worker     // that do the initialization check.
1026*795d594fSAndroid Build Coastguard Worker     // 2) native methods whose data pointer is different than the one in the
1027*795d594fSAndroid Build Coastguard Worker     // zygote. Such methods may have had custom native implementation provided
1028*795d594fSAndroid Build Coastguard Worker     // by JNI RegisterNatives.
1029*795d594fSAndroid Build Coastguard Worker     header.VisitPackedArtMethods([&](ArtMethod& method) NO_THREAD_SAFETY_ANALYSIS {
1030*795d594fSAndroid Build Coastguard Worker       // Methods in the boot image should never have their single
1031*795d594fSAndroid Build Coastguard Worker       // implementation flag set (and therefore never have a `data_` pointing
1032*795d594fSAndroid Build Coastguard Worker       // to an ArtMethod for single implementation).
1033*795d594fSAndroid Build Coastguard Worker       CHECK(method.IsIntrinsic() || !method.HasSingleImplementationFlag());
1034*795d594fSAndroid Build Coastguard Worker       if (method.IsRuntimeMethod()) {
1035*795d594fSAndroid Build Coastguard Worker         return;
1036*795d594fSAndroid Build Coastguard Worker       }
1037*795d594fSAndroid Build Coastguard Worker 
1038*795d594fSAndroid Build Coastguard Worker       // Pointer to the method we're currently using.
1039*795d594fSAndroid Build Coastguard Worker       uint8_t* pointer = reinterpret_cast<uint8_t*>(&method);
1040*795d594fSAndroid Build Coastguard Worker       // The data pointer of that method that we want to keep.
1041*795d594fSAndroid Build Coastguard Worker       uint8_t* data_pointer = pointer + ArtMethod::DataOffset(kRuntimePointerSize).Int32Value();
1042*795d594fSAndroid Build Coastguard Worker       if (method.IsNative() && data_pointer >= page_start && data_pointer < page_end) {
1043*795d594fSAndroid Build Coastguard Worker         // The data pointer of the ArtMethod in the shared memory we are going to remap into our
1044*795d594fSAndroid Build Coastguard Worker         // own mapping. This is the data that we will see after the remap.
1045*795d594fSAndroid Build Coastguard Worker         uint8_t* new_data_pointer =
1046*795d594fSAndroid Build Coastguard Worker             child_mapping_methods.Begin() + offset + (data_pointer - page_start);
1047*795d594fSAndroid Build Coastguard Worker         CopyIfDifferent(new_data_pointer, data_pointer, sizeof(void*));
1048*795d594fSAndroid Build Coastguard Worker       }
1049*795d594fSAndroid Build Coastguard Worker 
1050*795d594fSAndroid Build Coastguard Worker       // The entrypoint of the method we're currently using and that we want to
1051*795d594fSAndroid Build Coastguard Worker       // keep.
1052*795d594fSAndroid Build Coastguard Worker       uint8_t* entry_point_pointer = pointer +
1053*795d594fSAndroid Build Coastguard Worker           ArtMethod::EntryPointFromQuickCompiledCodeOffset(kRuntimePointerSize).Int32Value();
1054*795d594fSAndroid Build Coastguard Worker       if (!method.GetDeclaringClassUnchecked()->IsVisiblyInitialized() &&
1055*795d594fSAndroid Build Coastguard Worker           method.IsStatic() &&
1056*795d594fSAndroid Build Coastguard Worker           !method.IsConstructor() &&
1057*795d594fSAndroid Build Coastguard Worker           entry_point_pointer >= page_start &&
1058*795d594fSAndroid Build Coastguard Worker           entry_point_pointer < page_end) {
1059*795d594fSAndroid Build Coastguard Worker         // The entry point of the ArtMethod in the shared memory we are going to remap into our
1060*795d594fSAndroid Build Coastguard Worker         // own mapping. This is the entrypoint that we will see after the remap.
1061*795d594fSAndroid Build Coastguard Worker         uint8_t* new_entry_point_pointer =
1062*795d594fSAndroid Build Coastguard Worker             child_mapping_methods.Begin() + offset + (entry_point_pointer - page_start);
1063*795d594fSAndroid Build Coastguard Worker         CopyIfDifferent(new_entry_point_pointer, entry_point_pointer, sizeof(void*));
1064*795d594fSAndroid Build Coastguard Worker       }
1065*795d594fSAndroid Build Coastguard Worker     }, space->Begin(), kRuntimePointerSize);
1066*795d594fSAndroid Build Coastguard Worker 
1067*795d594fSAndroid Build Coastguard Worker     // Map the memory in the boot image range.
1068*795d594fSAndroid Build Coastguard Worker     if (mremap(child_mapping_methods.Begin() + offset,
1069*795d594fSAndroid Build Coastguard Worker                capacity,
1070*795d594fSAndroid Build Coastguard Worker                capacity,
1071*795d594fSAndroid Build Coastguard Worker                MREMAP_FIXED | MREMAP_MAYMOVE,
1072*795d594fSAndroid Build Coastguard Worker                page_start) == MAP_FAILED) {
1073*795d594fSAndroid Build Coastguard Worker       PLOG(WARNING) << "Fail to mremap boot image methods for " << space->GetImageFilename();
1074*795d594fSAndroid Build Coastguard Worker     }
1075*795d594fSAndroid Build Coastguard Worker     offset += capacity;
1076*795d594fSAndroid Build Coastguard Worker   }
1077*795d594fSAndroid Build Coastguard Worker 
1078*795d594fSAndroid Build Coastguard Worker   LOG(INFO) << "Successfully mapped boot image methods";
1079*795d594fSAndroid Build Coastguard Worker }
1080*795d594fSAndroid Build Coastguard Worker 
InZygoteUsingJit()1081*795d594fSAndroid Build Coastguard Worker bool Jit::InZygoteUsingJit() {
1082*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
1083*795d594fSAndroid Build Coastguard Worker   return runtime->IsZygote() && runtime->HasImageWithProfile() && runtime->UseJitCompilation();
1084*795d594fSAndroid Build Coastguard Worker }
1085*795d594fSAndroid Build Coastguard Worker 
CreateThreadPool()1086*795d594fSAndroid Build Coastguard Worker void Jit::CreateThreadPool() {
1087*795d594fSAndroid Build Coastguard Worker   // There is a DCHECK in the 'AddSamples' method to ensure the tread pool
1088*795d594fSAndroid Build Coastguard Worker   // is not null when we instrument.
1089*795d594fSAndroid Build Coastguard Worker 
1090*795d594fSAndroid Build Coastguard Worker   thread_pool_.reset(JitThreadPool::Create("Jit thread pool", 1));
1091*795d594fSAndroid Build Coastguard Worker 
1092*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
1093*795d594fSAndroid Build Coastguard Worker   thread_pool_->SetPthreadPriority(
1094*795d594fSAndroid Build Coastguard Worker       runtime->IsZygote()
1095*795d594fSAndroid Build Coastguard Worker           ? options_->GetZygoteThreadPoolPthreadPriority()
1096*795d594fSAndroid Build Coastguard Worker           : options_->GetThreadPoolPthreadPriority());
1097*795d594fSAndroid Build Coastguard Worker   Start();
1098*795d594fSAndroid Build Coastguard Worker 
1099*795d594fSAndroid Build Coastguard Worker   if (runtime->IsZygote()) {
1100*795d594fSAndroid Build Coastguard Worker     // To speed up class lookups, generate a type lookup table for
1101*795d594fSAndroid Build Coastguard Worker     // dex files not backed by oat file.
1102*795d594fSAndroid Build Coastguard Worker     for (const DexFile* dex_file : runtime->GetClassLinker()->GetBootClassPath()) {
1103*795d594fSAndroid Build Coastguard Worker       if (dex_file->GetOatDexFile() == nullptr) {
1104*795d594fSAndroid Build Coastguard Worker         TypeLookupTable type_lookup_table = TypeLookupTable::Create(*dex_file);
1105*795d594fSAndroid Build Coastguard Worker         type_lookup_tables_.push_back(
1106*795d594fSAndroid Build Coastguard Worker             std::make_unique<art::OatDexFile>(std::move(type_lookup_table)));
1107*795d594fSAndroid Build Coastguard Worker         dex_file->SetOatDexFile(type_lookup_tables_.back().get());
1108*795d594fSAndroid Build Coastguard Worker       }
1109*795d594fSAndroid Build Coastguard Worker     }
1110*795d594fSAndroid Build Coastguard Worker 
1111*795d594fSAndroid Build Coastguard Worker     // Add a task that will verify boot classpath jars that were not
1112*795d594fSAndroid Build Coastguard Worker     // pre-compiled.
1113*795d594fSAndroid Build Coastguard Worker     thread_pool_->AddTask(Thread::Current(), new ZygoteVerificationTask());
1114*795d594fSAndroid Build Coastguard Worker   }
1115*795d594fSAndroid Build Coastguard Worker 
1116*795d594fSAndroid Build Coastguard Worker   if (InZygoteUsingJit()) {
1117*795d594fSAndroid Build Coastguard Worker     // If we have an image with a profile, request a JIT task to
1118*795d594fSAndroid Build Coastguard Worker     // compile all methods in that profile.
1119*795d594fSAndroid Build Coastguard Worker     thread_pool_->AddTask(Thread::Current(), new ZygoteTask());
1120*795d594fSAndroid Build Coastguard Worker 
1121*795d594fSAndroid Build Coastguard Worker     // And create mappings to share boot image methods memory from the zygote to
1122*795d594fSAndroid Build Coastguard Worker     // child processes.
1123*795d594fSAndroid Build Coastguard Worker 
1124*795d594fSAndroid Build Coastguard Worker     // Compute the total capacity required for the boot image methods.
1125*795d594fSAndroid Build Coastguard Worker     uint64_t total_capacity = 0;
1126*795d594fSAndroid Build Coastguard Worker     for (gc::space::ImageSpace* space : Runtime::Current()->GetHeap()->GetBootImageSpaces()) {
1127*795d594fSAndroid Build Coastguard Worker       const ImageHeader& header = space->GetImageHeader();
1128*795d594fSAndroid Build Coastguard Worker       const ImageSection& section = header.GetMethodsSection();
1129*795d594fSAndroid Build Coastguard Worker       // Mappings need to be at the page level.
1130*795d594fSAndroid Build Coastguard Worker       uint8_t* page_start = AlignUp(header.GetImageBegin() + section.Offset(), gPageSize);
1131*795d594fSAndroid Build Coastguard Worker       uint8_t* page_end =
1132*795d594fSAndroid Build Coastguard Worker           AlignDown(header.GetImageBegin() + section.Offset() + section.Size(), gPageSize);
1133*795d594fSAndroid Build Coastguard Worker       if (page_end > page_start) {
1134*795d594fSAndroid Build Coastguard Worker         total_capacity += (page_end - page_start);
1135*795d594fSAndroid Build Coastguard Worker       }
1136*795d594fSAndroid Build Coastguard Worker     }
1137*795d594fSAndroid Build Coastguard Worker 
1138*795d594fSAndroid Build Coastguard Worker     // Create the child and zygote mappings to the boot image methods.
1139*795d594fSAndroid Build Coastguard Worker     if (total_capacity > 0) {
1140*795d594fSAndroid Build Coastguard Worker       // Start with '/boot' and end with '.art' to match the pattern recognized
1141*795d594fSAndroid Build Coastguard Worker       // by android_os_Debug.cpp for boot images.
1142*795d594fSAndroid Build Coastguard Worker       const char* name = "/boot-image-methods.art";
1143*795d594fSAndroid Build Coastguard Worker       unique_fd mem_fd =
1144*795d594fSAndroid Build Coastguard Worker           unique_fd(art::memfd_create(name, /* flags= */ MFD_ALLOW_SEALING | MFD_CLOEXEC));
1145*795d594fSAndroid Build Coastguard Worker       if (mem_fd.get() == -1) {
1146*795d594fSAndroid Build Coastguard Worker         PLOG(WARNING) << "Could not create boot image methods file descriptor";
1147*795d594fSAndroid Build Coastguard Worker         return;
1148*795d594fSAndroid Build Coastguard Worker       }
1149*795d594fSAndroid Build Coastguard Worker       if (ftruncate(mem_fd.get(), total_capacity) != 0) {
1150*795d594fSAndroid Build Coastguard Worker         PLOG(WARNING) << "Failed to truncate boot image methods file to " << total_capacity;
1151*795d594fSAndroid Build Coastguard Worker         return;
1152*795d594fSAndroid Build Coastguard Worker       }
1153*795d594fSAndroid Build Coastguard Worker       std::string error_str;
1154*795d594fSAndroid Build Coastguard Worker 
1155*795d594fSAndroid Build Coastguard Worker       // Create the shared mapping eagerly, as this prevents other processes
1156*795d594fSAndroid Build Coastguard Worker       // from adding the writable seal.
1157*795d594fSAndroid Build Coastguard Worker       zygote_mapping_methods_ = MemMap::MapFile(
1158*795d594fSAndroid Build Coastguard Worker         total_capacity,
1159*795d594fSAndroid Build Coastguard Worker         PROT_READ | PROT_WRITE,
1160*795d594fSAndroid Build Coastguard Worker         MAP_SHARED,
1161*795d594fSAndroid Build Coastguard Worker         mem_fd,
1162*795d594fSAndroid Build Coastguard Worker         /* start= */ 0,
1163*795d594fSAndroid Build Coastguard Worker         /* low_4gb= */ false,
1164*795d594fSAndroid Build Coastguard Worker         "boot-image-methods",
1165*795d594fSAndroid Build Coastguard Worker         &error_str);
1166*795d594fSAndroid Build Coastguard Worker 
1167*795d594fSAndroid Build Coastguard Worker       if (!zygote_mapping_methods_.IsValid()) {
1168*795d594fSAndroid Build Coastguard Worker         LOG(WARNING) << "Failed to create zygote mapping of boot image methods:  " << error_str;
1169*795d594fSAndroid Build Coastguard Worker         return;
1170*795d594fSAndroid Build Coastguard Worker       }
1171*795d594fSAndroid Build Coastguard Worker       if (zygote_mapping_methods_.MadviseDontFork() != 0) {
1172*795d594fSAndroid Build Coastguard Worker         LOG(WARNING) << "Failed to madvise dont fork boot image methods";
1173*795d594fSAndroid Build Coastguard Worker         zygote_mapping_methods_ = MemMap();
1174*795d594fSAndroid Build Coastguard Worker         return;
1175*795d594fSAndroid Build Coastguard Worker       }
1176*795d594fSAndroid Build Coastguard Worker 
1177*795d594fSAndroid Build Coastguard Worker       // We should use the F_SEAL_FUTURE_WRITE flag, but this has unexpected
1178*795d594fSAndroid Build Coastguard Worker       // behavior on private mappings after fork (the mapping becomes shared between
1179*795d594fSAndroid Build Coastguard Worker       // parent and children), see b/143833776.
1180*795d594fSAndroid Build Coastguard Worker       // We will seal the write once we are done writing to the shared mapping.
1181*795d594fSAndroid Build Coastguard Worker       if (fcntl(mem_fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW) == -1) {
1182*795d594fSAndroid Build Coastguard Worker         PLOG(WARNING) << "Failed to seal boot image methods file descriptor";
1183*795d594fSAndroid Build Coastguard Worker         zygote_mapping_methods_ = MemMap();
1184*795d594fSAndroid Build Coastguard Worker         return;
1185*795d594fSAndroid Build Coastguard Worker       }
1186*795d594fSAndroid Build Coastguard Worker       fd_methods_ = unique_fd(mem_fd.release());
1187*795d594fSAndroid Build Coastguard Worker       fd_methods_size_ = total_capacity;
1188*795d594fSAndroid Build Coastguard Worker     }
1189*795d594fSAndroid Build Coastguard Worker   }
1190*795d594fSAndroid Build Coastguard Worker }
1191*795d594fSAndroid Build Coastguard Worker 
RegisterDexFiles(const std::vector<std::unique_ptr<const DexFile>> & dex_files,jobject class_loader)1192*795d594fSAndroid Build Coastguard Worker void Jit::RegisterDexFiles(const std::vector<std::unique_ptr<const DexFile>>& dex_files,
1193*795d594fSAndroid Build Coastguard Worker                            jobject class_loader) {
1194*795d594fSAndroid Build Coastguard Worker   if (dex_files.empty()) {
1195*795d594fSAndroid Build Coastguard Worker     return;
1196*795d594fSAndroid Build Coastguard Worker   }
1197*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
1198*795d594fSAndroid Build Coastguard Worker   // If the runtime is debuggable, don't bother precompiling methods.
1199*795d594fSAndroid Build Coastguard Worker   // If system server is being profiled, don't precompile as we are going to use
1200*795d594fSAndroid Build Coastguard Worker   // the JIT to count hotness. Note that --count-hotness-in-compiled-code is
1201*795d594fSAndroid Build Coastguard Worker   // only forced when we also profile the boot classpath, see
1202*795d594fSAndroid Build Coastguard Worker   // AndroidRuntime.cpp.
1203*795d594fSAndroid Build Coastguard Worker   if (runtime->IsSystemServer() &&
1204*795d594fSAndroid Build Coastguard Worker       UseJitCompilation() &&
1205*795d594fSAndroid Build Coastguard Worker       options_->UseProfiledJitCompilation() &&
1206*795d594fSAndroid Build Coastguard Worker       runtime->HasImageWithProfile() &&
1207*795d594fSAndroid Build Coastguard Worker       !runtime->IsSystemServerProfiled() &&
1208*795d594fSAndroid Build Coastguard Worker       !runtime->IsJavaDebuggable()) {
1209*795d594fSAndroid Build Coastguard Worker     // Note: this precompilation is currently not running in production because:
1210*795d594fSAndroid Build Coastguard Worker     // - UseProfiledJitCompilation() is not set by default.
1211*795d594fSAndroid Build Coastguard Worker     // - System server dex files are registered *before* we set the runtime as
1212*795d594fSAndroid Build Coastguard Worker     //   system server (though we are in the system server process).
1213*795d594fSAndroid Build Coastguard Worker     thread_pool_->AddTask(Thread::Current(), new JitProfileTask(dex_files, class_loader));
1214*795d594fSAndroid Build Coastguard Worker   }
1215*795d594fSAndroid Build Coastguard Worker }
1216*795d594fSAndroid Build Coastguard Worker 
AddCompileTask(Thread * self,ArtMethod * method,CompilationKind compilation_kind)1217*795d594fSAndroid Build Coastguard Worker void Jit::AddCompileTask(Thread* self,
1218*795d594fSAndroid Build Coastguard Worker                          ArtMethod* method,
1219*795d594fSAndroid Build Coastguard Worker                          CompilationKind compilation_kind) {
1220*795d594fSAndroid Build Coastguard Worker   thread_pool_->AddTask(self, method, compilation_kind);
1221*795d594fSAndroid Build Coastguard Worker }
1222*795d594fSAndroid Build Coastguard Worker 
CompileMethodFromProfile(Thread * self,ClassLinker * class_linker,uint32_t method_idx,Handle<mirror::DexCache> dex_cache,Handle<mirror::ClassLoader> class_loader,bool add_to_queue,bool compile_after_boot)1223*795d594fSAndroid Build Coastguard Worker bool Jit::CompileMethodFromProfile(Thread* self,
1224*795d594fSAndroid Build Coastguard Worker                                    ClassLinker* class_linker,
1225*795d594fSAndroid Build Coastguard Worker                                    uint32_t method_idx,
1226*795d594fSAndroid Build Coastguard Worker                                    Handle<mirror::DexCache> dex_cache,
1227*795d594fSAndroid Build Coastguard Worker                                    Handle<mirror::ClassLoader> class_loader,
1228*795d594fSAndroid Build Coastguard Worker                                    bool add_to_queue,
1229*795d594fSAndroid Build Coastguard Worker                                    bool compile_after_boot) {
1230*795d594fSAndroid Build Coastguard Worker   ArtMethod* method = class_linker->ResolveMethodId(method_idx, dex_cache, class_loader);
1231*795d594fSAndroid Build Coastguard Worker   if (method == nullptr) {
1232*795d594fSAndroid Build Coastguard Worker     self->ClearException();
1233*795d594fSAndroid Build Coastguard Worker     return false;
1234*795d594fSAndroid Build Coastguard Worker   }
1235*795d594fSAndroid Build Coastguard Worker   if (!method->IsCompilable() || !method->IsInvokable()) {
1236*795d594fSAndroid Build Coastguard Worker     return false;
1237*795d594fSAndroid Build Coastguard Worker   }
1238*795d594fSAndroid Build Coastguard Worker   if (method->IsPreCompiled()) {
1239*795d594fSAndroid Build Coastguard Worker     // Already seen by another profile.
1240*795d594fSAndroid Build Coastguard Worker     return false;
1241*795d594fSAndroid Build Coastguard Worker   }
1242*795d594fSAndroid Build Coastguard Worker   CompilationKind compilation_kind = CompilationKind::kOptimized;
1243*795d594fSAndroid Build Coastguard Worker   const void* entry_point = method->GetEntryPointFromQuickCompiledCode();
1244*795d594fSAndroid Build Coastguard Worker   if (class_linker->IsQuickToInterpreterBridge(entry_point) ||
1245*795d594fSAndroid Build Coastguard Worker       class_linker->IsQuickGenericJniStub(entry_point) ||
1246*795d594fSAndroid Build Coastguard Worker       class_linker->IsNterpEntryPoint(entry_point) ||
1247*795d594fSAndroid Build Coastguard Worker       // We explicitly check for the resolution stub, and not the resolution trampoline.
1248*795d594fSAndroid Build Coastguard Worker       // The trampoline is for methods backed by a .oat file that has a compiled version of
1249*795d594fSAndroid Build Coastguard Worker       // the method.
1250*795d594fSAndroid Build Coastguard Worker       (entry_point == GetQuickResolutionStub())) {
1251*795d594fSAndroid Build Coastguard Worker     VLOG(jit) << "JIT Zygote processing method " << ArtMethod::PrettyMethod(method)
1252*795d594fSAndroid Build Coastguard Worker               << " from profile";
1253*795d594fSAndroid Build Coastguard Worker     method->SetPreCompiled();
1254*795d594fSAndroid Build Coastguard Worker     if (!add_to_queue) {
1255*795d594fSAndroid Build Coastguard Worker       CompileMethodInternal(method, self, compilation_kind, /* prejit= */ true);
1256*795d594fSAndroid Build Coastguard Worker     } else {
1257*795d594fSAndroid Build Coastguard Worker       Task* task = new JitCompileTask(
1258*795d594fSAndroid Build Coastguard Worker           method, JitCompileTask::TaskKind::kPreCompile, compilation_kind);
1259*795d594fSAndroid Build Coastguard Worker       if (compile_after_boot) {
1260*795d594fSAndroid Build Coastguard Worker         AddPostBootTask(self, task);
1261*795d594fSAndroid Build Coastguard Worker       } else {
1262*795d594fSAndroid Build Coastguard Worker         thread_pool_->AddTask(self, task);
1263*795d594fSAndroid Build Coastguard Worker       }
1264*795d594fSAndroid Build Coastguard Worker       return true;
1265*795d594fSAndroid Build Coastguard Worker     }
1266*795d594fSAndroid Build Coastguard Worker   }
1267*795d594fSAndroid Build Coastguard Worker   return false;
1268*795d594fSAndroid Build Coastguard Worker }
1269*795d594fSAndroid Build Coastguard Worker 
CompileMethodsFromBootProfile(Thread * self,const std::vector<const DexFile * > & dex_files,const std::string & profile_file,Handle<mirror::ClassLoader> class_loader,bool add_to_queue)1270*795d594fSAndroid Build Coastguard Worker uint32_t Jit::CompileMethodsFromBootProfile(
1271*795d594fSAndroid Build Coastguard Worker     Thread* self,
1272*795d594fSAndroid Build Coastguard Worker     const std::vector<const DexFile*>& dex_files,
1273*795d594fSAndroid Build Coastguard Worker     const std::string& profile_file,
1274*795d594fSAndroid Build Coastguard Worker     Handle<mirror::ClassLoader> class_loader,
1275*795d594fSAndroid Build Coastguard Worker     bool add_to_queue) {
1276*795d594fSAndroid Build Coastguard Worker   unix_file::FdFile profile(profile_file, O_RDONLY, true);
1277*795d594fSAndroid Build Coastguard Worker 
1278*795d594fSAndroid Build Coastguard Worker   if (profile.Fd() == -1) {
1279*795d594fSAndroid Build Coastguard Worker     PLOG(WARNING) << "No boot profile: " << profile_file;
1280*795d594fSAndroid Build Coastguard Worker     return 0u;
1281*795d594fSAndroid Build Coastguard Worker   }
1282*795d594fSAndroid Build Coastguard Worker 
1283*795d594fSAndroid Build Coastguard Worker   ProfileBootInfo profile_info;
1284*795d594fSAndroid Build Coastguard Worker   if (!profile_info.Load(profile.Fd(), dex_files)) {
1285*795d594fSAndroid Build Coastguard Worker     LOG(ERROR) << "Could not load profile file: " << profile_file;
1286*795d594fSAndroid Build Coastguard Worker     return 0u;
1287*795d594fSAndroid Build Coastguard Worker   }
1288*795d594fSAndroid Build Coastguard Worker 
1289*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
1290*795d594fSAndroid Build Coastguard Worker   VariableSizedHandleScope handles(self);
1291*795d594fSAndroid Build Coastguard Worker   std::vector<Handle<mirror::DexCache>> dex_caches;
1292*795d594fSAndroid Build Coastguard Worker   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1293*795d594fSAndroid Build Coastguard Worker   for (const DexFile* dex_file : profile_info.GetDexFiles()) {
1294*795d594fSAndroid Build Coastguard Worker     dex_caches.push_back(handles.NewHandle(class_linker->FindDexCache(self, *dex_file)));
1295*795d594fSAndroid Build Coastguard Worker   }
1296*795d594fSAndroid Build Coastguard Worker 
1297*795d594fSAndroid Build Coastguard Worker   uint32_t added_to_queue = 0;
1298*795d594fSAndroid Build Coastguard Worker   for (const std::pair<uint32_t, uint32_t>& pair : profile_info.GetMethods()) {
1299*795d594fSAndroid Build Coastguard Worker     if (CompileMethodFromProfile(self,
1300*795d594fSAndroid Build Coastguard Worker                                  class_linker,
1301*795d594fSAndroid Build Coastguard Worker                                  pair.second,
1302*795d594fSAndroid Build Coastguard Worker                                  dex_caches[pair.first],
1303*795d594fSAndroid Build Coastguard Worker                                  class_loader,
1304*795d594fSAndroid Build Coastguard Worker                                  add_to_queue,
1305*795d594fSAndroid Build Coastguard Worker                                  /*compile_after_boot=*/false)) {
1306*795d594fSAndroid Build Coastguard Worker       ++added_to_queue;
1307*795d594fSAndroid Build Coastguard Worker     }
1308*795d594fSAndroid Build Coastguard Worker   }
1309*795d594fSAndroid Build Coastguard Worker   return added_to_queue;
1310*795d594fSAndroid Build Coastguard Worker }
1311*795d594fSAndroid Build Coastguard Worker 
CompileMethodsFromProfile(Thread * self,const std::vector<const DexFile * > & dex_files,const std::string & profile_file,Handle<mirror::ClassLoader> class_loader,bool add_to_queue)1312*795d594fSAndroid Build Coastguard Worker uint32_t Jit::CompileMethodsFromProfile(
1313*795d594fSAndroid Build Coastguard Worker     Thread* self,
1314*795d594fSAndroid Build Coastguard Worker     const std::vector<const DexFile*>& dex_files,
1315*795d594fSAndroid Build Coastguard Worker     const std::string& profile_file,
1316*795d594fSAndroid Build Coastguard Worker     Handle<mirror::ClassLoader> class_loader,
1317*795d594fSAndroid Build Coastguard Worker     bool add_to_queue) {
1318*795d594fSAndroid Build Coastguard Worker 
1319*795d594fSAndroid Build Coastguard Worker   if (profile_file.empty()) {
1320*795d594fSAndroid Build Coastguard Worker     LOG(WARNING) << "Expected a profile file in JIT zygote mode";
1321*795d594fSAndroid Build Coastguard Worker     return 0u;
1322*795d594fSAndroid Build Coastguard Worker   }
1323*795d594fSAndroid Build Coastguard Worker 
1324*795d594fSAndroid Build Coastguard Worker   // We don't generate boot profiles on device, therefore we don't
1325*795d594fSAndroid Build Coastguard Worker   // need to lock the file.
1326*795d594fSAndroid Build Coastguard Worker   unix_file::FdFile profile(profile_file, O_RDONLY, true);
1327*795d594fSAndroid Build Coastguard Worker 
1328*795d594fSAndroid Build Coastguard Worker   if (profile.Fd() == -1) {
1329*795d594fSAndroid Build Coastguard Worker     PLOG(WARNING) << "No profile: " << profile_file;
1330*795d594fSAndroid Build Coastguard Worker     return 0u;
1331*795d594fSAndroid Build Coastguard Worker   }
1332*795d594fSAndroid Build Coastguard Worker 
1333*795d594fSAndroid Build Coastguard Worker   ProfileCompilationInfo profile_info(/* for_boot_image= */ class_loader.IsNull());
1334*795d594fSAndroid Build Coastguard Worker   if (!profile_info.Load(profile.Fd())) {
1335*795d594fSAndroid Build Coastguard Worker     LOG(ERROR) << "Could not load profile file";
1336*795d594fSAndroid Build Coastguard Worker     return 0u;
1337*795d594fSAndroid Build Coastguard Worker   }
1338*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
1339*795d594fSAndroid Build Coastguard Worker   StackHandleScope<1> hs(self);
1340*795d594fSAndroid Build Coastguard Worker   MutableHandle<mirror::DexCache> dex_cache = hs.NewHandle<mirror::DexCache>(nullptr);
1341*795d594fSAndroid Build Coastguard Worker   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1342*795d594fSAndroid Build Coastguard Worker   uint32_t added_to_queue = 0u;
1343*795d594fSAndroid Build Coastguard Worker   for (const DexFile* dex_file : dex_files) {
1344*795d594fSAndroid Build Coastguard Worker     std::set<dex::TypeIndex> class_types;
1345*795d594fSAndroid Build Coastguard Worker     std::set<uint16_t> all_methods;
1346*795d594fSAndroid Build Coastguard Worker     if (!profile_info.GetClassesAndMethods(*dex_file,
1347*795d594fSAndroid Build Coastguard Worker                                            &class_types,
1348*795d594fSAndroid Build Coastguard Worker                                            &all_methods,
1349*795d594fSAndroid Build Coastguard Worker                                            &all_methods,
1350*795d594fSAndroid Build Coastguard Worker                                            &all_methods)) {
1351*795d594fSAndroid Build Coastguard Worker       // This means the profile file did not reference the dex file, which is the case
1352*795d594fSAndroid Build Coastguard Worker       // if there's no classes and methods of that dex file in the profile.
1353*795d594fSAndroid Build Coastguard Worker       continue;
1354*795d594fSAndroid Build Coastguard Worker     }
1355*795d594fSAndroid Build Coastguard Worker     dex_cache.Assign(class_linker->FindDexCache(self, *dex_file));
1356*795d594fSAndroid Build Coastguard Worker     CHECK(dex_cache != nullptr) << "Could not find dex cache for " << dex_file->GetLocation();
1357*795d594fSAndroid Build Coastguard Worker 
1358*795d594fSAndroid Build Coastguard Worker     for (uint16_t method_idx : all_methods) {
1359*795d594fSAndroid Build Coastguard Worker       if (CompileMethodFromProfile(self,
1360*795d594fSAndroid Build Coastguard Worker                                    class_linker,
1361*795d594fSAndroid Build Coastguard Worker                                    method_idx,
1362*795d594fSAndroid Build Coastguard Worker                                    dex_cache,
1363*795d594fSAndroid Build Coastguard Worker                                    class_loader,
1364*795d594fSAndroid Build Coastguard Worker                                    add_to_queue,
1365*795d594fSAndroid Build Coastguard Worker                                    /*compile_after_boot=*/true)) {
1366*795d594fSAndroid Build Coastguard Worker         ++added_to_queue;
1367*795d594fSAndroid Build Coastguard Worker       }
1368*795d594fSAndroid Build Coastguard Worker     }
1369*795d594fSAndroid Build Coastguard Worker   }
1370*795d594fSAndroid Build Coastguard Worker 
1371*795d594fSAndroid Build Coastguard Worker   // Add a task to run when all compilation is done.
1372*795d594fSAndroid Build Coastguard Worker   AddPostBootTask(self, new JitDoneCompilingProfileTask(dex_files));
1373*795d594fSAndroid Build Coastguard Worker   return added_to_queue;
1374*795d594fSAndroid Build Coastguard Worker }
1375*795d594fSAndroid Build Coastguard Worker 
IgnoreSamplesForMethod(ArtMethod * method)1376*795d594fSAndroid Build Coastguard Worker bool Jit::IgnoreSamplesForMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) {
1377*795d594fSAndroid Build Coastguard Worker   if (method->IsClassInitializer() || !method->IsCompilable()) {
1378*795d594fSAndroid Build Coastguard Worker     // We do not want to compile such methods.
1379*795d594fSAndroid Build Coastguard Worker     return true;
1380*795d594fSAndroid Build Coastguard Worker   }
1381*795d594fSAndroid Build Coastguard Worker   if (method->IsNative()) {
1382*795d594fSAndroid Build Coastguard Worker     ObjPtr<mirror::Class> klass = method->GetDeclaringClass();
1383*795d594fSAndroid Build Coastguard Worker     if (klass == GetClassRoot<mirror::MethodHandle>() ||
1384*795d594fSAndroid Build Coastguard Worker         klass == GetClassRoot<mirror::VarHandle>()) {
1385*795d594fSAndroid Build Coastguard Worker       // MethodHandle and VarHandle invocation methods are required to throw an
1386*795d594fSAndroid Build Coastguard Worker       // UnsupportedOperationException if invoked reflectively. We achieve this by having native
1387*795d594fSAndroid Build Coastguard Worker       // implementations that raise the exception. We need to disable JIT compilation of these JNI
1388*795d594fSAndroid Build Coastguard Worker       // methods as it can lead to transitioning between JIT compiled JNI stubs and generic JNI
1389*795d594fSAndroid Build Coastguard Worker       // stubs. Since these stubs have different stack representations we can then crash in stack
1390*795d594fSAndroid Build Coastguard Worker       // walking (b/78151261).
1391*795d594fSAndroid Build Coastguard Worker       return true;
1392*795d594fSAndroid Build Coastguard Worker     }
1393*795d594fSAndroid Build Coastguard Worker   }
1394*795d594fSAndroid Build Coastguard Worker   return false;
1395*795d594fSAndroid Build Coastguard Worker }
1396*795d594fSAndroid Build Coastguard Worker 
EnqueueOptimizedCompilation(ArtMethod * method,Thread * self)1397*795d594fSAndroid Build Coastguard Worker void Jit::EnqueueOptimizedCompilation(ArtMethod* method, Thread* self) {
1398*795d594fSAndroid Build Coastguard Worker   // Note the hotness counter will be reset by the compiled code.
1399*795d594fSAndroid Build Coastguard Worker 
1400*795d594fSAndroid Build Coastguard Worker   if (thread_pool_ == nullptr) {
1401*795d594fSAndroid Build Coastguard Worker     return;
1402*795d594fSAndroid Build Coastguard Worker   }
1403*795d594fSAndroid Build Coastguard Worker 
1404*795d594fSAndroid Build Coastguard Worker   const void* entry_point = method->GetEntryPointFromQuickCompiledCode();
1405*795d594fSAndroid Build Coastguard Worker   // Check if we already have optimized code. We might still be executing baseline code even
1406*795d594fSAndroid Build Coastguard Worker   // when we have optimized code.
1407*795d594fSAndroid Build Coastguard Worker   if (GetCodeCache()->ContainsPc(entry_point) &&
1408*795d594fSAndroid Build Coastguard Worker       !CodeInfo::IsBaseline(
1409*795d594fSAndroid Build Coastguard Worker           OatQuickMethodHeader::FromEntryPoint(entry_point)->GetOptimizedCodeInfoPtr())) {
1410*795d594fSAndroid Build Coastguard Worker     return;
1411*795d594fSAndroid Build Coastguard Worker   }
1412*795d594fSAndroid Build Coastguard Worker 
1413*795d594fSAndroid Build Coastguard Worker   // We arrive here after a baseline compiled code has reached its baseline
1414*795d594fSAndroid Build Coastguard Worker   // hotness threshold. If we're not only using the baseline compiler, enqueue a compilation
1415*795d594fSAndroid Build Coastguard Worker   // task that will compile optimize the method.
1416*795d594fSAndroid Build Coastguard Worker   if (!options_->UseBaselineCompiler()) {
1417*795d594fSAndroid Build Coastguard Worker     AddCompileTask(self, method, CompilationKind::kOptimized);
1418*795d594fSAndroid Build Coastguard Worker   }
1419*795d594fSAndroid Build Coastguard Worker }
1420*795d594fSAndroid Build Coastguard Worker 
1421*795d594fSAndroid Build Coastguard Worker class ScopedSetRuntimeThread {
1422*795d594fSAndroid Build Coastguard Worker  public:
ScopedSetRuntimeThread(Thread * self)1423*795d594fSAndroid Build Coastguard Worker   explicit ScopedSetRuntimeThread(Thread* self)
1424*795d594fSAndroid Build Coastguard Worker       : self_(self), was_runtime_thread_(self_->IsRuntimeThread()) {
1425*795d594fSAndroid Build Coastguard Worker     self_->SetIsRuntimeThread(true);
1426*795d594fSAndroid Build Coastguard Worker   }
1427*795d594fSAndroid Build Coastguard Worker 
~ScopedSetRuntimeThread()1428*795d594fSAndroid Build Coastguard Worker   ~ScopedSetRuntimeThread() {
1429*795d594fSAndroid Build Coastguard Worker     self_->SetIsRuntimeThread(was_runtime_thread_);
1430*795d594fSAndroid Build Coastguard Worker   }
1431*795d594fSAndroid Build Coastguard Worker 
1432*795d594fSAndroid Build Coastguard Worker  private:
1433*795d594fSAndroid Build Coastguard Worker   Thread* self_;
1434*795d594fSAndroid Build Coastguard Worker   bool was_runtime_thread_;
1435*795d594fSAndroid Build Coastguard Worker };
1436*795d594fSAndroid Build Coastguard Worker 
MethodEntered(Thread * self,ArtMethod * method)1437*795d594fSAndroid Build Coastguard Worker void Jit::MethodEntered(Thread* self, ArtMethod* method) {
1438*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
1439*795d594fSAndroid Build Coastguard Worker   if (UNLIKELY(runtime->UseJitCompilation() && JitAtFirstUse())) {
1440*795d594fSAndroid Build Coastguard Worker     ArtMethod* np_method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
1441*795d594fSAndroid Build Coastguard Worker     if (np_method->IsCompilable()) {
1442*795d594fSAndroid Build Coastguard Worker       CompileMethod(method, self, CompilationKind::kOptimized, /* prejit= */ false);
1443*795d594fSAndroid Build Coastguard Worker     }
1444*795d594fSAndroid Build Coastguard Worker     return;
1445*795d594fSAndroid Build Coastguard Worker   }
1446*795d594fSAndroid Build Coastguard Worker 
1447*795d594fSAndroid Build Coastguard Worker   AddSamples(self, method);
1448*795d594fSAndroid Build Coastguard Worker }
1449*795d594fSAndroid Build Coastguard Worker 
WaitForCompilationToFinish(Thread * self)1450*795d594fSAndroid Build Coastguard Worker void Jit::WaitForCompilationToFinish(Thread* self) {
1451*795d594fSAndroid Build Coastguard Worker   if (thread_pool_ != nullptr) {
1452*795d594fSAndroid Build Coastguard Worker     thread_pool_->Wait(self, false, false);
1453*795d594fSAndroid Build Coastguard Worker   }
1454*795d594fSAndroid Build Coastguard Worker }
1455*795d594fSAndroid Build Coastguard Worker 
Stop()1456*795d594fSAndroid Build Coastguard Worker void Jit::Stop() {
1457*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
1458*795d594fSAndroid Build Coastguard Worker   // TODO(ngeoffray): change API to not require calling WaitForCompilationToFinish twice.
1459*795d594fSAndroid Build Coastguard Worker   WaitForCompilationToFinish(self);
1460*795d594fSAndroid Build Coastguard Worker   GetThreadPool()->StopWorkers(self);
1461*795d594fSAndroid Build Coastguard Worker   WaitForCompilationToFinish(self);
1462*795d594fSAndroid Build Coastguard Worker }
1463*795d594fSAndroid Build Coastguard Worker 
Start()1464*795d594fSAndroid Build Coastguard Worker void Jit::Start() {
1465*795d594fSAndroid Build Coastguard Worker   GetThreadPool()->StartWorkers(Thread::Current());
1466*795d594fSAndroid Build Coastguard Worker }
1467*795d594fSAndroid Build Coastguard Worker 
ScopedJitSuspend()1468*795d594fSAndroid Build Coastguard Worker ScopedJitSuspend::ScopedJitSuspend() {
1469*795d594fSAndroid Build Coastguard Worker   jit::Jit* jit = Runtime::Current()->GetJit();
1470*795d594fSAndroid Build Coastguard Worker   was_on_ = (jit != nullptr) && (jit->GetThreadPool() != nullptr);
1471*795d594fSAndroid Build Coastguard Worker   if (was_on_) {
1472*795d594fSAndroid Build Coastguard Worker     jit->Stop();
1473*795d594fSAndroid Build Coastguard Worker   }
1474*795d594fSAndroid Build Coastguard Worker }
1475*795d594fSAndroid Build Coastguard Worker 
~ScopedJitSuspend()1476*795d594fSAndroid Build Coastguard Worker ScopedJitSuspend::~ScopedJitSuspend() {
1477*795d594fSAndroid Build Coastguard Worker   if (was_on_) {
1478*795d594fSAndroid Build Coastguard Worker     DCHECK(Runtime::Current()->GetJit() != nullptr);
1479*795d594fSAndroid Build Coastguard Worker     DCHECK(Runtime::Current()->GetJit()->GetThreadPool() != nullptr);
1480*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetJit()->Start();
1481*795d594fSAndroid Build Coastguard Worker   }
1482*795d594fSAndroid Build Coastguard Worker }
1483*795d594fSAndroid Build Coastguard Worker 
1484*795d594fSAndroid Build Coastguard Worker class MapBootImageMethodsTask : public gc::HeapTask {
1485*795d594fSAndroid Build Coastguard Worker  public:
MapBootImageMethodsTask(uint64_t target_run_time)1486*795d594fSAndroid Build Coastguard Worker   explicit MapBootImageMethodsTask(uint64_t target_run_time) : gc::HeapTask(target_run_time) {}
1487*795d594fSAndroid Build Coastguard Worker 
Run(Thread * self ATTRIBUTE_UNUSED)1488*795d594fSAndroid Build Coastguard Worker   void Run(Thread* self ATTRIBUTE_UNUSED) override {
1489*795d594fSAndroid Build Coastguard Worker     Runtime* runtime = Runtime::Current();
1490*795d594fSAndroid Build Coastguard Worker     if (!runtime->GetJit()->GetCodeCache()->GetZygoteMap()->IsCompilationNotified()) {
1491*795d594fSAndroid Build Coastguard Worker       // Add a new task that will execute in 10 seconds.
1492*795d594fSAndroid Build Coastguard Worker       static constexpr uint64_t kWaitTimeNs = MsToNs(10000);  // 10 seconds
1493*795d594fSAndroid Build Coastguard Worker       runtime->GetHeap()->AddHeapTask(new MapBootImageMethodsTask(NanoTime() + kWaitTimeNs));
1494*795d594fSAndroid Build Coastguard Worker       return;
1495*795d594fSAndroid Build Coastguard Worker     }
1496*795d594fSAndroid Build Coastguard Worker     // Prevent other threads from running while we are remapping the boot image
1497*795d594fSAndroid Build Coastguard Worker     // ArtMethod's. Native threads might still be running, but they cannot
1498*795d594fSAndroid Build Coastguard Worker     // change the contents of ArtMethod's.
1499*795d594fSAndroid Build Coastguard Worker     ScopedSuspendAll ssa(__FUNCTION__);
1500*795d594fSAndroid Build Coastguard Worker     runtime->GetJit()->MapBootImageMethods();
1501*795d594fSAndroid Build Coastguard Worker   }
1502*795d594fSAndroid Build Coastguard Worker };
1503*795d594fSAndroid Build Coastguard Worker 
PostForkChildAction(bool is_system_server,bool is_zygote)1504*795d594fSAndroid Build Coastguard Worker void Jit::PostForkChildAction(bool is_system_server, bool is_zygote) {
1505*795d594fSAndroid Build Coastguard Worker   // Clear the potential boot tasks inherited from the zygote.
1506*795d594fSAndroid Build Coastguard Worker   {
1507*795d594fSAndroid Build Coastguard Worker     MutexLock mu(Thread::Current(), boot_completed_lock_);
1508*795d594fSAndroid Build Coastguard Worker     tasks_after_boot_.clear();
1509*795d594fSAndroid Build Coastguard Worker   }
1510*795d594fSAndroid Build Coastguard Worker 
1511*795d594fSAndroid Build Coastguard Worker   Runtime* const runtime = Runtime::Current();
1512*795d594fSAndroid Build Coastguard Worker   // Check if we'll need to remap the boot image methods.
1513*795d594fSAndroid Build Coastguard Worker   if (!is_zygote && fd_methods_ != -1) {
1514*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetHeap()->AddHeapTask(
1515*795d594fSAndroid Build Coastguard Worker         new MapBootImageMethodsTask(NanoTime() + MsToNs(10000)));
1516*795d594fSAndroid Build Coastguard Worker   }
1517*795d594fSAndroid Build Coastguard Worker 
1518*795d594fSAndroid Build Coastguard Worker   if (is_zygote || runtime->IsSafeMode()) {
1519*795d594fSAndroid Build Coastguard Worker     // Delete the thread pool, we are not going to JIT.
1520*795d594fSAndroid Build Coastguard Worker     thread_pool_.reset(nullptr);
1521*795d594fSAndroid Build Coastguard Worker     return;
1522*795d594fSAndroid Build Coastguard Worker   }
1523*795d594fSAndroid Build Coastguard Worker   // At this point, the compiler options have been adjusted to the particular configuration
1524*795d594fSAndroid Build Coastguard Worker   // of the forked child. Parse them again.
1525*795d594fSAndroid Build Coastguard Worker   jit_compiler_->ParseCompilerOptions();
1526*795d594fSAndroid Build Coastguard Worker 
1527*795d594fSAndroid Build Coastguard Worker   // Adjust the status of code cache collection: the status from zygote was to not collect.
1528*795d594fSAndroid Build Coastguard Worker   // JitAtFirstUse compiles the methods synchronously on mutator threads. While this should work
1529*795d594fSAndroid Build Coastguard Worker   // in theory it is causing deadlocks in some jvmti tests related to Jit GC. Hence, disabling
1530*795d594fSAndroid Build Coastguard Worker   // Jit GC for now (b/147208992).
1531*795d594fSAndroid Build Coastguard Worker   code_cache_->SetGarbageCollectCode(
1532*795d594fSAndroid Build Coastguard Worker       !jit_compiler_->GenerateDebugInfo() &&
1533*795d594fSAndroid Build Coastguard Worker       !JitAtFirstUse());
1534*795d594fSAndroid Build Coastguard Worker 
1535*795d594fSAndroid Build Coastguard Worker   if (is_system_server && runtime->HasImageWithProfile()) {
1536*795d594fSAndroid Build Coastguard Worker     // Disable garbage collection: we don't want it to delete methods we're compiling
1537*795d594fSAndroid Build Coastguard Worker     // through boot and system server profiles.
1538*795d594fSAndroid Build Coastguard Worker     // TODO(ngeoffray): Fix this so we still collect deoptimized and unused code.
1539*795d594fSAndroid Build Coastguard Worker     code_cache_->SetGarbageCollectCode(false);
1540*795d594fSAndroid Build Coastguard Worker   }
1541*795d594fSAndroid Build Coastguard Worker 
1542*795d594fSAndroid Build Coastguard Worker   // We do this here instead of PostZygoteFork, as NativeDebugInfoPostFork only
1543*795d594fSAndroid Build Coastguard Worker   // applies to a child.
1544*795d594fSAndroid Build Coastguard Worker   NativeDebugInfoPostFork();
1545*795d594fSAndroid Build Coastguard Worker }
1546*795d594fSAndroid Build Coastguard Worker 
PreZygoteFork()1547*795d594fSAndroid Build Coastguard Worker void Jit::PreZygoteFork() {
1548*795d594fSAndroid Build Coastguard Worker   if (thread_pool_ == nullptr) {
1549*795d594fSAndroid Build Coastguard Worker     return;
1550*795d594fSAndroid Build Coastguard Worker   }
1551*795d594fSAndroid Build Coastguard Worker   thread_pool_->DeleteThreads();
1552*795d594fSAndroid Build Coastguard Worker 
1553*795d594fSAndroid Build Coastguard Worker   NativeDebugInfoPreFork();
1554*795d594fSAndroid Build Coastguard Worker }
1555*795d594fSAndroid Build Coastguard Worker 
1556*795d594fSAndroid Build Coastguard Worker // Returns the number of threads running.
GetTaskCount()1557*795d594fSAndroid Build Coastguard Worker static int GetTaskCount() {
1558*795d594fSAndroid Build Coastguard Worker   DIR* directory = opendir("/proc/self/task");
1559*795d594fSAndroid Build Coastguard Worker   if (directory == nullptr) {
1560*795d594fSAndroid Build Coastguard Worker     return -1;
1561*795d594fSAndroid Build Coastguard Worker   }
1562*795d594fSAndroid Build Coastguard Worker 
1563*795d594fSAndroid Build Coastguard Worker   uint32_t count = 0;
1564*795d594fSAndroid Build Coastguard Worker   struct dirent* entry = nullptr;
1565*795d594fSAndroid Build Coastguard Worker   while ((entry = readdir(directory)) != nullptr) {
1566*795d594fSAndroid Build Coastguard Worker     if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) {
1567*795d594fSAndroid Build Coastguard Worker       continue;
1568*795d594fSAndroid Build Coastguard Worker     }
1569*795d594fSAndroid Build Coastguard Worker     ++count;
1570*795d594fSAndroid Build Coastguard Worker   }
1571*795d594fSAndroid Build Coastguard Worker   closedir(directory);
1572*795d594fSAndroid Build Coastguard Worker   return count;
1573*795d594fSAndroid Build Coastguard Worker }
1574*795d594fSAndroid Build Coastguard Worker 
PostZygoteFork()1575*795d594fSAndroid Build Coastguard Worker void Jit::PostZygoteFork() {
1576*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
1577*795d594fSAndroid Build Coastguard Worker   if (thread_pool_ == nullptr) {
1578*795d594fSAndroid Build Coastguard Worker     // If this is a child zygote, check if we need to remap the boot image
1579*795d594fSAndroid Build Coastguard Worker     // methods.
1580*795d594fSAndroid Build Coastguard Worker     if (runtime->IsZygote() &&
1581*795d594fSAndroid Build Coastguard Worker         fd_methods_ != -1 &&
1582*795d594fSAndroid Build Coastguard Worker         code_cache_->GetZygoteMap()->IsCompilationNotified()) {
1583*795d594fSAndroid Build Coastguard Worker       ScopedSuspendAll ssa(__FUNCTION__);
1584*795d594fSAndroid Build Coastguard Worker       MapBootImageMethods();
1585*795d594fSAndroid Build Coastguard Worker     }
1586*795d594fSAndroid Build Coastguard Worker     return;
1587*795d594fSAndroid Build Coastguard Worker   }
1588*795d594fSAndroid Build Coastguard Worker   if (runtime->IsZygote() && code_cache_->GetZygoteMap()->IsCompilationDoneButNotNotified()) {
1589*795d594fSAndroid Build Coastguard Worker     // Copy the boot image methods data to the mappings we created to share
1590*795d594fSAndroid Build Coastguard Worker     // with the children. We do this here as we are the only thread running and
1591*795d594fSAndroid Build Coastguard Worker     // we don't risk other threads concurrently updating the ArtMethod's.
1592*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(GetTaskCount(), 1);
1593*795d594fSAndroid Build Coastguard Worker     NotifyZygoteCompilationDone();
1594*795d594fSAndroid Build Coastguard Worker     CHECK(code_cache_->GetZygoteMap()->IsCompilationNotified());
1595*795d594fSAndroid Build Coastguard Worker   }
1596*795d594fSAndroid Build Coastguard Worker   thread_pool_->CreateThreads();
1597*795d594fSAndroid Build Coastguard Worker   thread_pool_->SetPthreadPriority(
1598*795d594fSAndroid Build Coastguard Worker       runtime->IsZygote()
1599*795d594fSAndroid Build Coastguard Worker           ? options_->GetZygoteThreadPoolPthreadPriority()
1600*795d594fSAndroid Build Coastguard Worker           : options_->GetThreadPoolPthreadPriority());
1601*795d594fSAndroid Build Coastguard Worker }
1602*795d594fSAndroid Build Coastguard Worker 
AddPostBootTask(Thread * self,Task * task)1603*795d594fSAndroid Build Coastguard Worker void Jit::AddPostBootTask(Thread* self, Task* task) {
1604*795d594fSAndroid Build Coastguard Worker   MutexLock mu(self, boot_completed_lock_);
1605*795d594fSAndroid Build Coastguard Worker   if (boot_completed_) {
1606*795d594fSAndroid Build Coastguard Worker     thread_pool_->AddTask(self, task);
1607*795d594fSAndroid Build Coastguard Worker   } else {
1608*795d594fSAndroid Build Coastguard Worker     tasks_after_boot_.push_back(task);
1609*795d594fSAndroid Build Coastguard Worker   }
1610*795d594fSAndroid Build Coastguard Worker }
1611*795d594fSAndroid Build Coastguard Worker 
BootCompleted()1612*795d594fSAndroid Build Coastguard Worker void Jit::BootCompleted() {
1613*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
1614*795d594fSAndroid Build Coastguard Worker   std::deque<Task*> tasks;
1615*795d594fSAndroid Build Coastguard Worker   {
1616*795d594fSAndroid Build Coastguard Worker     MutexLock mu(self, boot_completed_lock_);
1617*795d594fSAndroid Build Coastguard Worker     tasks = std::move(tasks_after_boot_);
1618*795d594fSAndroid Build Coastguard Worker     boot_completed_ = true;
1619*795d594fSAndroid Build Coastguard Worker   }
1620*795d594fSAndroid Build Coastguard Worker   for (Task* task : tasks) {
1621*795d594fSAndroid Build Coastguard Worker     thread_pool_->AddTask(self, task);
1622*795d594fSAndroid Build Coastguard Worker   }
1623*795d594fSAndroid Build Coastguard Worker }
1624*795d594fSAndroid Build Coastguard Worker 
CanEncodeMethod(ArtMethod * method,bool is_for_shared_region) const1625*795d594fSAndroid Build Coastguard Worker bool Jit::CanEncodeMethod(ArtMethod* method, bool is_for_shared_region) const {
1626*795d594fSAndroid Build Coastguard Worker   return !is_for_shared_region ||
1627*795d594fSAndroid Build Coastguard Worker       Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(method->GetDeclaringClass());
1628*795d594fSAndroid Build Coastguard Worker }
1629*795d594fSAndroid Build Coastguard Worker 
CanEncodeClass(ObjPtr<mirror::Class> cls,bool is_for_shared_region) const1630*795d594fSAndroid Build Coastguard Worker bool Jit::CanEncodeClass(ObjPtr<mirror::Class> cls, bool is_for_shared_region) const {
1631*795d594fSAndroid Build Coastguard Worker   return !is_for_shared_region || Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(cls);
1632*795d594fSAndroid Build Coastguard Worker }
1633*795d594fSAndroid Build Coastguard Worker 
CanEncodeString(ObjPtr<mirror::String> string,bool is_for_shared_region) const1634*795d594fSAndroid Build Coastguard Worker bool Jit::CanEncodeString(ObjPtr<mirror::String> string, bool is_for_shared_region) const {
1635*795d594fSAndroid Build Coastguard Worker   return !is_for_shared_region || Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(string);
1636*795d594fSAndroid Build Coastguard Worker }
1637*795d594fSAndroid Build Coastguard Worker 
CanAssumeInitialized(ObjPtr<mirror::Class> cls,bool is_for_shared_region) const1638*795d594fSAndroid Build Coastguard Worker bool Jit::CanAssumeInitialized(ObjPtr<mirror::Class> cls, bool is_for_shared_region) const {
1639*795d594fSAndroid Build Coastguard Worker   if (!is_for_shared_region) {
1640*795d594fSAndroid Build Coastguard Worker     return cls->IsInitialized();
1641*795d594fSAndroid Build Coastguard Worker   } else {
1642*795d594fSAndroid Build Coastguard Worker     // Look up the class status in the oat file.
1643*795d594fSAndroid Build Coastguard Worker     const DexFile& dex_file = *cls->GetDexCache()->GetDexFile();
1644*795d594fSAndroid Build Coastguard Worker     const OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
1645*795d594fSAndroid Build Coastguard Worker     // In case we run without an image there won't be a backing oat file.
1646*795d594fSAndroid Build Coastguard Worker     if (oat_dex_file == nullptr || oat_dex_file->GetOatFile() == nullptr) {
1647*795d594fSAndroid Build Coastguard Worker       return false;
1648*795d594fSAndroid Build Coastguard Worker     }
1649*795d594fSAndroid Build Coastguard Worker     uint16_t class_def_index = cls->GetDexClassDefIndex();
1650*795d594fSAndroid Build Coastguard Worker     return oat_dex_file->GetOatClass(class_def_index).GetStatus() >= ClassStatus::kInitialized;
1651*795d594fSAndroid Build Coastguard Worker   }
1652*795d594fSAndroid Build Coastguard Worker }
1653*795d594fSAndroid Build Coastguard Worker 
MaybeEnqueueCompilation(ArtMethod * method,Thread * self)1654*795d594fSAndroid Build Coastguard Worker void Jit::MaybeEnqueueCompilation(ArtMethod* method, Thread* self) {
1655*795d594fSAndroid Build Coastguard Worker   if (thread_pool_ == nullptr) {
1656*795d594fSAndroid Build Coastguard Worker     return;
1657*795d594fSAndroid Build Coastguard Worker   }
1658*795d594fSAndroid Build Coastguard Worker 
1659*795d594fSAndroid Build Coastguard Worker   if (JitAtFirstUse()) {
1660*795d594fSAndroid Build Coastguard Worker     // Tests might request JIT on first use (compiled synchronously in the interpreter).
1661*795d594fSAndroid Build Coastguard Worker     return;
1662*795d594fSAndroid Build Coastguard Worker   }
1663*795d594fSAndroid Build Coastguard Worker 
1664*795d594fSAndroid Build Coastguard Worker   if (!UseJitCompilation()) {
1665*795d594fSAndroid Build Coastguard Worker     return;
1666*795d594fSAndroid Build Coastguard Worker   }
1667*795d594fSAndroid Build Coastguard Worker 
1668*795d594fSAndroid Build Coastguard Worker   if (IgnoreSamplesForMethod(method)) {
1669*795d594fSAndroid Build Coastguard Worker     return;
1670*795d594fSAndroid Build Coastguard Worker   }
1671*795d594fSAndroid Build Coastguard Worker 
1672*795d594fSAndroid Build Coastguard Worker   if (GetCodeCache()->ContainsPc(method->GetEntryPointFromQuickCompiledCode())) {
1673*795d594fSAndroid Build Coastguard Worker     if (!method->IsNative() && !code_cache_->IsOsrCompiled(method)) {
1674*795d594fSAndroid Build Coastguard Worker       // If we already have compiled code for it, nterp may be stuck in a loop.
1675*795d594fSAndroid Build Coastguard Worker       // Compile OSR.
1676*795d594fSAndroid Build Coastguard Worker       AddCompileTask(self, method, CompilationKind::kOsr);
1677*795d594fSAndroid Build Coastguard Worker     }
1678*795d594fSAndroid Build Coastguard Worker     return;
1679*795d594fSAndroid Build Coastguard Worker   }
1680*795d594fSAndroid Build Coastguard Worker 
1681*795d594fSAndroid Build Coastguard Worker   // Check if we have precompiled this method.
1682*795d594fSAndroid Build Coastguard Worker   if (UNLIKELY(method->IsPreCompiled())) {
1683*795d594fSAndroid Build Coastguard Worker     if (!method->StillNeedsClinitCheck()) {
1684*795d594fSAndroid Build Coastguard Worker       const void* entry_point = code_cache_->GetSavedEntryPointOfPreCompiledMethod(method);
1685*795d594fSAndroid Build Coastguard Worker       if (entry_point != nullptr) {
1686*795d594fSAndroid Build Coastguard Worker         Runtime::Current()->GetInstrumentation()->UpdateMethodsCode(method, entry_point);
1687*795d594fSAndroid Build Coastguard Worker       }
1688*795d594fSAndroid Build Coastguard Worker     }
1689*795d594fSAndroid Build Coastguard Worker     return;
1690*795d594fSAndroid Build Coastguard Worker   }
1691*795d594fSAndroid Build Coastguard Worker 
1692*795d594fSAndroid Build Coastguard Worker   static constexpr size_t kIndividualSharedMethodHotnessThreshold = 0x3f;
1693*795d594fSAndroid Build Coastguard Worker   // Intrinsics are always in the boot image and considered hot.
1694*795d594fSAndroid Build Coastguard Worker   if (method->IsMemorySharedMethod() && !method->IsIntrinsic()) {
1695*795d594fSAndroid Build Coastguard Worker     MutexLock mu(self, lock_);
1696*795d594fSAndroid Build Coastguard Worker     auto it = shared_method_counters_.find(method);
1697*795d594fSAndroid Build Coastguard Worker     if (it == shared_method_counters_.end()) {
1698*795d594fSAndroid Build Coastguard Worker       shared_method_counters_[method] = kIndividualSharedMethodHotnessThreshold;
1699*795d594fSAndroid Build Coastguard Worker       return;
1700*795d594fSAndroid Build Coastguard Worker     } else if (it->second != 0) {
1701*795d594fSAndroid Build Coastguard Worker       DCHECK_LE(it->second, kIndividualSharedMethodHotnessThreshold);
1702*795d594fSAndroid Build Coastguard Worker       shared_method_counters_[method] = it->second - 1;
1703*795d594fSAndroid Build Coastguard Worker       return;
1704*795d594fSAndroid Build Coastguard Worker     } else {
1705*795d594fSAndroid Build Coastguard Worker       shared_method_counters_[method] = kIndividualSharedMethodHotnessThreshold;
1706*795d594fSAndroid Build Coastguard Worker     }
1707*795d594fSAndroid Build Coastguard Worker   }
1708*795d594fSAndroid Build Coastguard Worker 
1709*795d594fSAndroid Build Coastguard Worker   if (!method->IsNative() && GetCodeCache()->CanAllocateProfilingInfo()) {
1710*795d594fSAndroid Build Coastguard Worker     AddCompileTask(self, method, CompilationKind::kBaseline);
1711*795d594fSAndroid Build Coastguard Worker   } else {
1712*795d594fSAndroid Build Coastguard Worker     AddCompileTask(self, method, CompilationKind::kOptimized);
1713*795d594fSAndroid Build Coastguard Worker   }
1714*795d594fSAndroid Build Coastguard Worker }
1715*795d594fSAndroid Build Coastguard Worker 
CompileMethod(ArtMethod * method,Thread * self,CompilationKind compilation_kind,bool prejit)1716*795d594fSAndroid Build Coastguard Worker bool Jit::CompileMethod(ArtMethod* method,
1717*795d594fSAndroid Build Coastguard Worker                         Thread* self,
1718*795d594fSAndroid Build Coastguard Worker                         CompilationKind compilation_kind,
1719*795d594fSAndroid Build Coastguard Worker                         bool prejit) {
1720*795d594fSAndroid Build Coastguard Worker   // Fake being in a runtime thread so that class-load behavior will be the same as normal jit.
1721*795d594fSAndroid Build Coastguard Worker   ScopedSetRuntimeThread ssrt(self);
1722*795d594fSAndroid Build Coastguard Worker   // TODO(ngeoffray): For JIT at first use, use kPreCompile. Currently we don't due to
1723*795d594fSAndroid Build Coastguard Worker   // conflicts with jitzygote optimizations.
1724*795d594fSAndroid Build Coastguard Worker   return CompileMethodInternal(method, self, compilation_kind, prejit);
1725*795d594fSAndroid Build Coastguard Worker }
1726*795d594fSAndroid Build Coastguard Worker 
GetTaskCount(Thread * self)1727*795d594fSAndroid Build Coastguard Worker size_t JitThreadPool::GetTaskCount(Thread* self) {
1728*795d594fSAndroid Build Coastguard Worker   MutexLock mu(self, task_queue_lock_);
1729*795d594fSAndroid Build Coastguard Worker   return generic_queue_.size() +
1730*795d594fSAndroid Build Coastguard Worker       baseline_queue_.size() +
1731*795d594fSAndroid Build Coastguard Worker       optimized_queue_.size() +
1732*795d594fSAndroid Build Coastguard Worker       osr_queue_.size();
1733*795d594fSAndroid Build Coastguard Worker }
1734*795d594fSAndroid Build Coastguard Worker 
RemoveAllTasks(Thread * self)1735*795d594fSAndroid Build Coastguard Worker void JitThreadPool::RemoveAllTasks(Thread* self) {
1736*795d594fSAndroid Build Coastguard Worker   // The ThreadPool is responsible for calling Finalize (which usually deletes
1737*795d594fSAndroid Build Coastguard Worker   // the task memory) on all the tasks.
1738*795d594fSAndroid Build Coastguard Worker   Task* task = nullptr;
1739*795d594fSAndroid Build Coastguard Worker   do {
1740*795d594fSAndroid Build Coastguard Worker     {
1741*795d594fSAndroid Build Coastguard Worker       MutexLock mu(self, task_queue_lock_);
1742*795d594fSAndroid Build Coastguard Worker       if (generic_queue_.empty()) {
1743*795d594fSAndroid Build Coastguard Worker         break;
1744*795d594fSAndroid Build Coastguard Worker       }
1745*795d594fSAndroid Build Coastguard Worker       task = generic_queue_.front();
1746*795d594fSAndroid Build Coastguard Worker       generic_queue_.pop_front();
1747*795d594fSAndroid Build Coastguard Worker     }
1748*795d594fSAndroid Build Coastguard Worker     task->Finalize();
1749*795d594fSAndroid Build Coastguard Worker   } while (true);
1750*795d594fSAndroid Build Coastguard Worker 
1751*795d594fSAndroid Build Coastguard Worker   MutexLock mu(self, task_queue_lock_);
1752*795d594fSAndroid Build Coastguard Worker   baseline_queue_.clear();
1753*795d594fSAndroid Build Coastguard Worker   optimized_queue_.clear();
1754*795d594fSAndroid Build Coastguard Worker   osr_queue_.clear();
1755*795d594fSAndroid Build Coastguard Worker }
1756*795d594fSAndroid Build Coastguard Worker 
~JitThreadPool()1757*795d594fSAndroid Build Coastguard Worker JitThreadPool::~JitThreadPool() {
1758*795d594fSAndroid Build Coastguard Worker   DeleteThreads();
1759*795d594fSAndroid Build Coastguard Worker   RemoveAllTasks(Thread::Current());
1760*795d594fSAndroid Build Coastguard Worker }
1761*795d594fSAndroid Build Coastguard Worker 
AddTask(Thread * self,Task * task)1762*795d594fSAndroid Build Coastguard Worker void JitThreadPool::AddTask(Thread* self, Task* task) {
1763*795d594fSAndroid Build Coastguard Worker   MutexLock mu(self, task_queue_lock_);
1764*795d594fSAndroid Build Coastguard Worker   // We don't want to enqueue any new tasks when thread pool has stopped. This simplifies
1765*795d594fSAndroid Build Coastguard Worker   // the implementation of redefinition feature in jvmti.
1766*795d594fSAndroid Build Coastguard Worker   if (!started_) {
1767*795d594fSAndroid Build Coastguard Worker     task->Finalize();
1768*795d594fSAndroid Build Coastguard Worker     return;
1769*795d594fSAndroid Build Coastguard Worker   }
1770*795d594fSAndroid Build Coastguard Worker   generic_queue_.push_back(task);
1771*795d594fSAndroid Build Coastguard Worker   // If we have any waiters, signal one.
1772*795d594fSAndroid Build Coastguard Worker   if (waiting_count_ != 0) {
1773*795d594fSAndroid Build Coastguard Worker     task_queue_condition_.Signal(self);
1774*795d594fSAndroid Build Coastguard Worker   }
1775*795d594fSAndroid Build Coastguard Worker }
1776*795d594fSAndroid Build Coastguard Worker 
AddTask(Thread * self,ArtMethod * method,CompilationKind kind)1777*795d594fSAndroid Build Coastguard Worker void JitThreadPool::AddTask(Thread* self, ArtMethod* method, CompilationKind kind) {
1778*795d594fSAndroid Build Coastguard Worker   MutexLock mu(self, task_queue_lock_);
1779*795d594fSAndroid Build Coastguard Worker   // We don't want to enqueue any new tasks when thread pool has stopped. This simplifies
1780*795d594fSAndroid Build Coastguard Worker   // the implementation of redefinition feature in jvmti.
1781*795d594fSAndroid Build Coastguard Worker   if (!started_) {
1782*795d594fSAndroid Build Coastguard Worker     return;
1783*795d594fSAndroid Build Coastguard Worker   }
1784*795d594fSAndroid Build Coastguard Worker   switch (kind) {
1785*795d594fSAndroid Build Coastguard Worker     case CompilationKind::kOsr:
1786*795d594fSAndroid Build Coastguard Worker       if (ContainsElement(osr_enqueued_methods_, method)) {
1787*795d594fSAndroid Build Coastguard Worker         return;
1788*795d594fSAndroid Build Coastguard Worker       }
1789*795d594fSAndroid Build Coastguard Worker       osr_enqueued_methods_.insert(method);
1790*795d594fSAndroid Build Coastguard Worker       osr_queue_.push_back(method);
1791*795d594fSAndroid Build Coastguard Worker       break;
1792*795d594fSAndroid Build Coastguard Worker     case CompilationKind::kBaseline:
1793*795d594fSAndroid Build Coastguard Worker       if (ContainsElement(baseline_enqueued_methods_, method)) {
1794*795d594fSAndroid Build Coastguard Worker         return;
1795*795d594fSAndroid Build Coastguard Worker       }
1796*795d594fSAndroid Build Coastguard Worker       baseline_enqueued_methods_.insert(method);
1797*795d594fSAndroid Build Coastguard Worker       baseline_queue_.push_back(method);
1798*795d594fSAndroid Build Coastguard Worker       break;
1799*795d594fSAndroid Build Coastguard Worker     case CompilationKind::kOptimized:
1800*795d594fSAndroid Build Coastguard Worker       if (ContainsElement(optimized_enqueued_methods_, method)) {
1801*795d594fSAndroid Build Coastguard Worker         return;
1802*795d594fSAndroid Build Coastguard Worker       }
1803*795d594fSAndroid Build Coastguard Worker       optimized_enqueued_methods_.insert(method);
1804*795d594fSAndroid Build Coastguard Worker       optimized_queue_.push_back(method);
1805*795d594fSAndroid Build Coastguard Worker       break;
1806*795d594fSAndroid Build Coastguard Worker   }
1807*795d594fSAndroid Build Coastguard Worker   // If we have any waiters, signal one.
1808*795d594fSAndroid Build Coastguard Worker   if (waiting_count_ != 0) {
1809*795d594fSAndroid Build Coastguard Worker     task_queue_condition_.Signal(self);
1810*795d594fSAndroid Build Coastguard Worker   }
1811*795d594fSAndroid Build Coastguard Worker }
1812*795d594fSAndroid Build Coastguard Worker 
TryGetTaskLocked()1813*795d594fSAndroid Build Coastguard Worker Task* JitThreadPool::TryGetTaskLocked() {
1814*795d594fSAndroid Build Coastguard Worker   if (!started_) {
1815*795d594fSAndroid Build Coastguard Worker     return nullptr;
1816*795d594fSAndroid Build Coastguard Worker   }
1817*795d594fSAndroid Build Coastguard Worker 
1818*795d594fSAndroid Build Coastguard Worker   // Fetch generic tasks first.
1819*795d594fSAndroid Build Coastguard Worker   if (!generic_queue_.empty()) {
1820*795d594fSAndroid Build Coastguard Worker     Task* task = generic_queue_.front();
1821*795d594fSAndroid Build Coastguard Worker     generic_queue_.pop_front();
1822*795d594fSAndroid Build Coastguard Worker     return task;
1823*795d594fSAndroid Build Coastguard Worker   }
1824*795d594fSAndroid Build Coastguard Worker 
1825*795d594fSAndroid Build Coastguard Worker   // OSR requests second, then baseline and finally optimized.
1826*795d594fSAndroid Build Coastguard Worker   Task* task = FetchFrom(osr_queue_, CompilationKind::kOsr);
1827*795d594fSAndroid Build Coastguard Worker   if (task == nullptr) {
1828*795d594fSAndroid Build Coastguard Worker     task = FetchFrom(baseline_queue_, CompilationKind::kBaseline);
1829*795d594fSAndroid Build Coastguard Worker     if (task == nullptr) {
1830*795d594fSAndroid Build Coastguard Worker       task = FetchFrom(optimized_queue_, CompilationKind::kOptimized);
1831*795d594fSAndroid Build Coastguard Worker     }
1832*795d594fSAndroid Build Coastguard Worker   }
1833*795d594fSAndroid Build Coastguard Worker   return task;
1834*795d594fSAndroid Build Coastguard Worker }
1835*795d594fSAndroid Build Coastguard Worker 
FetchFrom(std::deque<ArtMethod * > & methods,CompilationKind kind)1836*795d594fSAndroid Build Coastguard Worker Task* JitThreadPool::FetchFrom(std::deque<ArtMethod*>& methods, CompilationKind kind) {
1837*795d594fSAndroid Build Coastguard Worker   if (!methods.empty()) {
1838*795d594fSAndroid Build Coastguard Worker     ArtMethod* method = methods.front();
1839*795d594fSAndroid Build Coastguard Worker     methods.pop_front();
1840*795d594fSAndroid Build Coastguard Worker     JitCompileTask* task = new JitCompileTask(method, JitCompileTask::TaskKind::kCompile, kind);
1841*795d594fSAndroid Build Coastguard Worker     current_compilations_.insert(task);
1842*795d594fSAndroid Build Coastguard Worker     return task;
1843*795d594fSAndroid Build Coastguard Worker   }
1844*795d594fSAndroid Build Coastguard Worker   return nullptr;
1845*795d594fSAndroid Build Coastguard Worker }
1846*795d594fSAndroid Build Coastguard Worker 
Remove(JitCompileTask * task)1847*795d594fSAndroid Build Coastguard Worker void JitThreadPool::Remove(JitCompileTask* task) {
1848*795d594fSAndroid Build Coastguard Worker   MutexLock mu(Thread::Current(), task_queue_lock_);
1849*795d594fSAndroid Build Coastguard Worker   current_compilations_.erase(task);
1850*795d594fSAndroid Build Coastguard Worker   switch (task->GetCompilationKind()) {
1851*795d594fSAndroid Build Coastguard Worker     case CompilationKind::kOsr: {
1852*795d594fSAndroid Build Coastguard Worker       osr_enqueued_methods_.erase(task->GetArtMethod());
1853*795d594fSAndroid Build Coastguard Worker       break;
1854*795d594fSAndroid Build Coastguard Worker     }
1855*795d594fSAndroid Build Coastguard Worker     case CompilationKind::kBaseline: {
1856*795d594fSAndroid Build Coastguard Worker       baseline_enqueued_methods_.erase(task->GetArtMethod());
1857*795d594fSAndroid Build Coastguard Worker       break;
1858*795d594fSAndroid Build Coastguard Worker     }
1859*795d594fSAndroid Build Coastguard Worker     case CompilationKind::kOptimized: {
1860*795d594fSAndroid Build Coastguard Worker       optimized_enqueued_methods_.erase(task->GetArtMethod());
1861*795d594fSAndroid Build Coastguard Worker       break;
1862*795d594fSAndroid Build Coastguard Worker     }
1863*795d594fSAndroid Build Coastguard Worker   }
1864*795d594fSAndroid Build Coastguard Worker }
1865*795d594fSAndroid Build Coastguard Worker 
VisitRoots(RootVisitor * visitor)1866*795d594fSAndroid Build Coastguard Worker void Jit::VisitRoots(RootVisitor* visitor) {
1867*795d594fSAndroid Build Coastguard Worker   if (thread_pool_ != nullptr) {
1868*795d594fSAndroid Build Coastguard Worker     thread_pool_->VisitRoots(visitor);
1869*795d594fSAndroid Build Coastguard Worker   }
1870*795d594fSAndroid Build Coastguard Worker }
1871*795d594fSAndroid Build Coastguard Worker 
VisitRoots(RootVisitor * visitor)1872*795d594fSAndroid Build Coastguard Worker void JitThreadPool::VisitRoots(RootVisitor* visitor) {
1873*795d594fSAndroid Build Coastguard Worker   if (Runtime::Current()->GetHeap()->IsPerformingUffdCompaction()) {
1874*795d594fSAndroid Build Coastguard Worker     // In case of userfaultfd compaction, ArtMethods are updated concurrently
1875*795d594fSAndroid Build Coastguard Worker     // via linear-alloc.
1876*795d594fSAndroid Build Coastguard Worker     return;
1877*795d594fSAndroid Build Coastguard Worker   }
1878*795d594fSAndroid Build Coastguard Worker   // Fetch all ArtMethod first, to avoid holding `task_queue_lock_` for too
1879*795d594fSAndroid Build Coastguard Worker   // long.
1880*795d594fSAndroid Build Coastguard Worker   std::vector<ArtMethod*> methods;
1881*795d594fSAndroid Build Coastguard Worker   {
1882*795d594fSAndroid Build Coastguard Worker     MutexLock mu(Thread::Current(), task_queue_lock_);
1883*795d594fSAndroid Build Coastguard Worker     // We don't look at `generic_queue_` because it contains:
1884*795d594fSAndroid Build Coastguard Worker     // - Generic tasks like `ZygoteVerificationTask` which don't hold any root.
1885*795d594fSAndroid Build Coastguard Worker     // - `JitCompileTask` for precompiled methods, which we know are live, being
1886*795d594fSAndroid Build Coastguard Worker     //   part of the boot classpath or system server classpath.
1887*795d594fSAndroid Build Coastguard Worker     methods.insert(methods.end(), osr_queue_.begin(), osr_queue_.end());
1888*795d594fSAndroid Build Coastguard Worker     methods.insert(methods.end(), baseline_queue_.begin(), baseline_queue_.end());
1889*795d594fSAndroid Build Coastguard Worker     methods.insert(methods.end(), optimized_queue_.begin(), optimized_queue_.end());
1890*795d594fSAndroid Build Coastguard Worker     for (JitCompileTask* task : current_compilations_) {
1891*795d594fSAndroid Build Coastguard Worker       methods.push_back(task->GetArtMethod());
1892*795d594fSAndroid Build Coastguard Worker     }
1893*795d594fSAndroid Build Coastguard Worker   }
1894*795d594fSAndroid Build Coastguard Worker   UnbufferedRootVisitor root_visitor(visitor, RootInfo(kRootStickyClass));
1895*795d594fSAndroid Build Coastguard Worker   for (ArtMethod* method : methods) {
1896*795d594fSAndroid Build Coastguard Worker     method->VisitRoots(root_visitor, kRuntimePointerSize);
1897*795d594fSAndroid Build Coastguard Worker   }
1898*795d594fSAndroid Build Coastguard Worker }
1899*795d594fSAndroid Build Coastguard Worker 
1900*795d594fSAndroid Build Coastguard Worker }  // namespace jit
1901*795d594fSAndroid Build Coastguard Worker }  // namespace art
1902