xref: /aosp_15_r20/art/runtime/oat/oat_file_manager.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2015 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 "oat_file_manager.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <stdlib.h>
20*795d594fSAndroid Build Coastguard Worker #include <sys/stat.h>
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include <memory>
23*795d594fSAndroid Build Coastguard Worker #include <queue>
24*795d594fSAndroid Build Coastguard Worker #include <vector>
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker #include "android-base/file.h"
27*795d594fSAndroid Build Coastguard Worker #include "android-base/stringprintf.h"
28*795d594fSAndroid Build Coastguard Worker #include "android-base/strings.h"
29*795d594fSAndroid Build Coastguard Worker #include "art_field-inl.h"
30*795d594fSAndroid Build Coastguard Worker #include "base/bit_vector-inl.h"
31*795d594fSAndroid Build Coastguard Worker #include "base/file_utils.h"
32*795d594fSAndroid Build Coastguard Worker #include "base/logging.h"  // For VLOG.
33*795d594fSAndroid Build Coastguard Worker #include "base/mutex-inl.h"
34*795d594fSAndroid Build Coastguard Worker #include "base/sdk_version.h"
35*795d594fSAndroid Build Coastguard Worker #include "base/stl_util.h"
36*795d594fSAndroid Build Coastguard Worker #include "base/systrace.h"
37*795d594fSAndroid Build Coastguard Worker #include "class_linker.h"
38*795d594fSAndroid Build Coastguard Worker #include "class_loader_context.h"
39*795d594fSAndroid Build Coastguard Worker #include "dex/art_dex_file_loader.h"
40*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file-inl.h"
41*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_loader.h"
42*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_tracking_registrar.h"
43*795d594fSAndroid Build Coastguard Worker #include "gc/scoped_gc_critical_section.h"
44*795d594fSAndroid Build Coastguard Worker #include "gc/space/image_space.h"
45*795d594fSAndroid Build Coastguard Worker #include "handle_scope-inl.h"
46*795d594fSAndroid Build Coastguard Worker #include "jit/jit.h"
47*795d594fSAndroid Build Coastguard Worker #include "jni/java_vm_ext.h"
48*795d594fSAndroid Build Coastguard Worker #include "jni/jni_internal.h"
49*795d594fSAndroid Build Coastguard Worker #include "mirror/class_loader.h"
50*795d594fSAndroid Build Coastguard Worker #include "mirror/object-inl.h"
51*795d594fSAndroid Build Coastguard Worker #include "oat_file.h"
52*795d594fSAndroid Build Coastguard Worker #include "oat_file_assistant.h"
53*795d594fSAndroid Build Coastguard Worker #include "obj_ptr-inl.h"
54*795d594fSAndroid Build Coastguard Worker #include "runtime_image.h"
55*795d594fSAndroid Build Coastguard Worker #include "scoped_thread_state_change-inl.h"
56*795d594fSAndroid Build Coastguard Worker #include "thread-current-inl.h"
57*795d594fSAndroid Build Coastguard Worker #include "thread_list.h"
58*795d594fSAndroid Build Coastguard Worker #include "thread_pool.h"
59*795d594fSAndroid Build Coastguard Worker #include "vdex_file.h"
60*795d594fSAndroid Build Coastguard Worker #include "verifier/verifier_deps.h"
61*795d594fSAndroid Build Coastguard Worker #include "well_known_classes.h"
62*795d594fSAndroid Build Coastguard Worker 
63*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
64*795d594fSAndroid Build Coastguard Worker 
65*795d594fSAndroid Build Coastguard Worker using android::base::StringPrintf;
66*795d594fSAndroid Build Coastguard Worker 
67*795d594fSAndroid Build Coastguard Worker // If true, we attempt to load the application image if it exists.
68*795d594fSAndroid Build Coastguard Worker static constexpr bool kEnableAppImage = true;
69*795d594fSAndroid Build Coastguard Worker 
70*795d594fSAndroid Build Coastguard Worker // If true, we attempt to load an app image generated by the runtime.
71*795d594fSAndroid Build Coastguard Worker static const bool kEnableRuntimeAppImage = true;
72*795d594fSAndroid Build Coastguard Worker 
73*795d594fSAndroid Build Coastguard Worker #if defined(__ANDROID__)
74*795d594fSAndroid Build Coastguard Worker static const char* kDisableAppImageKeyword = "_disable_art_image_";
75*795d594fSAndroid Build Coastguard Worker #endif
76*795d594fSAndroid Build Coastguard Worker 
RegisterOatFile(std::unique_ptr<const OatFile> oat_file,bool in_memory)77*795d594fSAndroid Build Coastguard Worker const OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oat_file,
78*795d594fSAndroid Build Coastguard Worker                                                bool in_memory) {
79*795d594fSAndroid Build Coastguard Worker   // Use class_linker vlog to match the log for dex file registration.
80*795d594fSAndroid Build Coastguard Worker   VLOG(class_linker) << "Registered oat file " << oat_file->GetLocation();
81*795d594fSAndroid Build Coastguard Worker   PaletteNotifyOatFileLoaded(oat_file->GetLocation().c_str());
82*795d594fSAndroid Build Coastguard Worker 
83*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
84*795d594fSAndroid Build Coastguard Worker   CHECK(in_memory ||
85*795d594fSAndroid Build Coastguard Worker         !only_use_system_oat_files_ ||
86*795d594fSAndroid Build Coastguard Worker         LocationIsTrusted(oat_file->GetLocation(), !Runtime::Current()->DenyArtApexDataFiles()) ||
87*795d594fSAndroid Build Coastguard Worker         !oat_file->IsExecutable())
88*795d594fSAndroid Build Coastguard Worker       << "Registering a non /system oat file: " << oat_file->GetLocation() << " android-root="
89*795d594fSAndroid Build Coastguard Worker       << GetAndroidRoot();
90*795d594fSAndroid Build Coastguard Worker   DCHECK(oat_file != nullptr);
91*795d594fSAndroid Build Coastguard Worker   if (kIsDebugBuild) {
92*795d594fSAndroid Build Coastguard Worker     CHECK(oat_files_.find(oat_file) == oat_files_.end());
93*795d594fSAndroid Build Coastguard Worker     for (const std::unique_ptr<const OatFile>& existing : oat_files_) {
94*795d594fSAndroid Build Coastguard Worker       CHECK_NE(oat_file.get(), existing.get()) << oat_file->GetLocation();
95*795d594fSAndroid Build Coastguard Worker       // Check that we don't have an oat file with the same address. Copies of the same oat file
96*795d594fSAndroid Build Coastguard Worker       // should be loaded at different addresses.
97*795d594fSAndroid Build Coastguard Worker       CHECK_NE(oat_file->Begin(), existing->Begin()) << "Oat file already mapped at that location";
98*795d594fSAndroid Build Coastguard Worker     }
99*795d594fSAndroid Build Coastguard Worker   }
100*795d594fSAndroid Build Coastguard Worker   const OatFile* ret = oat_file.get();
101*795d594fSAndroid Build Coastguard Worker   oat_files_.insert(std::move(oat_file));
102*795d594fSAndroid Build Coastguard Worker   return ret;
103*795d594fSAndroid Build Coastguard Worker }
104*795d594fSAndroid Build Coastguard Worker 
UnRegisterAndDeleteOatFile(const OatFile * oat_file)105*795d594fSAndroid Build Coastguard Worker void OatFileManager::UnRegisterAndDeleteOatFile(const OatFile* oat_file) {
106*795d594fSAndroid Build Coastguard Worker   WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
107*795d594fSAndroid Build Coastguard Worker   DCHECK(oat_file != nullptr);
108*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const OatFile> compare(oat_file);
109*795d594fSAndroid Build Coastguard Worker   auto it = oat_files_.find(compare);
110*795d594fSAndroid Build Coastguard Worker   CHECK(it != oat_files_.end());
111*795d594fSAndroid Build Coastguard Worker   oat_files_.erase(it);
112*795d594fSAndroid Build Coastguard Worker   compare.release();  // NOLINT b/117926937
113*795d594fSAndroid Build Coastguard Worker }
114*795d594fSAndroid Build Coastguard Worker 
FindOpenedOatFileFromDexLocation(const std::string & dex_base_location) const115*795d594fSAndroid Build Coastguard Worker const OatFile* OatFileManager::FindOpenedOatFileFromDexLocation(
116*795d594fSAndroid Build Coastguard Worker     const std::string& dex_base_location) const {
117*795d594fSAndroid Build Coastguard Worker   ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
118*795d594fSAndroid Build Coastguard Worker   for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
119*795d594fSAndroid Build Coastguard Worker     const std::vector<const OatDexFile*>& oat_dex_files = oat_file->GetOatDexFiles();
120*795d594fSAndroid Build Coastguard Worker     for (const OatDexFile* oat_dex_file : oat_dex_files) {
121*795d594fSAndroid Build Coastguard Worker       if (DexFileLoader::GetBaseLocation(oat_dex_file->GetDexFileLocation()) == dex_base_location) {
122*795d594fSAndroid Build Coastguard Worker         return oat_file.get();
123*795d594fSAndroid Build Coastguard Worker       }
124*795d594fSAndroid Build Coastguard Worker     }
125*795d594fSAndroid Build Coastguard Worker   }
126*795d594fSAndroid Build Coastguard Worker   return nullptr;
127*795d594fSAndroid Build Coastguard Worker }
128*795d594fSAndroid Build Coastguard Worker 
FindOpenedOatFileFromOatLocation(const std::string & oat_location) const129*795d594fSAndroid Build Coastguard Worker const OatFile* OatFileManager::FindOpenedOatFileFromOatLocation(const std::string& oat_location)
130*795d594fSAndroid Build Coastguard Worker     const {
131*795d594fSAndroid Build Coastguard Worker   ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
132*795d594fSAndroid Build Coastguard Worker   return FindOpenedOatFileFromOatLocationLocked(oat_location);
133*795d594fSAndroid Build Coastguard Worker }
134*795d594fSAndroid Build Coastguard Worker 
FindOpenedOatFileFromOatLocationLocked(const std::string & oat_location) const135*795d594fSAndroid Build Coastguard Worker const OatFile* OatFileManager::FindOpenedOatFileFromOatLocationLocked(
136*795d594fSAndroid Build Coastguard Worker     const std::string& oat_location) const {
137*795d594fSAndroid Build Coastguard Worker   for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
138*795d594fSAndroid Build Coastguard Worker     if (oat_file->GetLocation() == oat_location) {
139*795d594fSAndroid Build Coastguard Worker       return oat_file.get();
140*795d594fSAndroid Build Coastguard Worker     }
141*795d594fSAndroid Build Coastguard Worker   }
142*795d594fSAndroid Build Coastguard Worker   return nullptr;
143*795d594fSAndroid Build Coastguard Worker }
144*795d594fSAndroid Build Coastguard Worker 
GetBootOatFiles() const145*795d594fSAndroid Build Coastguard Worker std::vector<const OatFile*> OatFileManager::GetBootOatFiles() const {
146*795d594fSAndroid Build Coastguard Worker   std::vector<gc::space::ImageSpace*> image_spaces =
147*795d594fSAndroid Build Coastguard Worker       Runtime::Current()->GetHeap()->GetBootImageSpaces();
148*795d594fSAndroid Build Coastguard Worker   std::vector<const OatFile*> oat_files;
149*795d594fSAndroid Build Coastguard Worker   oat_files.reserve(image_spaces.size());
150*795d594fSAndroid Build Coastguard Worker   for (gc::space::ImageSpace* image_space : image_spaces) {
151*795d594fSAndroid Build Coastguard Worker     oat_files.push_back(image_space->GetOatFile());
152*795d594fSAndroid Build Coastguard Worker   }
153*795d594fSAndroid Build Coastguard Worker   return oat_files;
154*795d594fSAndroid Build Coastguard Worker }
155*795d594fSAndroid Build Coastguard Worker 
OatFileManager()156*795d594fSAndroid Build Coastguard Worker OatFileManager::OatFileManager()
157*795d594fSAndroid Build Coastguard Worker     : only_use_system_oat_files_(false) {}
158*795d594fSAndroid Build Coastguard Worker 
~OatFileManager()159*795d594fSAndroid Build Coastguard Worker OatFileManager::~OatFileManager() {
160*795d594fSAndroid Build Coastguard Worker   // Explicitly clear oat_files_ since the OatFile destructor calls back into OatFileManager for
161*795d594fSAndroid Build Coastguard Worker   // UnRegisterOatFileLocation.
162*795d594fSAndroid Build Coastguard Worker   oat_files_.clear();
163*795d594fSAndroid Build Coastguard Worker }
164*795d594fSAndroid Build Coastguard Worker 
RegisterImageOatFiles(const std::vector<gc::space::ImageSpace * > & spaces)165*795d594fSAndroid Build Coastguard Worker std::vector<const OatFile*> OatFileManager::RegisterImageOatFiles(
166*795d594fSAndroid Build Coastguard Worker     const std::vector<gc::space::ImageSpace*>& spaces) {
167*795d594fSAndroid Build Coastguard Worker   std::vector<const OatFile*> oat_files;
168*795d594fSAndroid Build Coastguard Worker   oat_files.reserve(spaces.size());
169*795d594fSAndroid Build Coastguard Worker   for (gc::space::ImageSpace* space : spaces) {
170*795d594fSAndroid Build Coastguard Worker     // The oat file was generated in memory if the image space has a profile.
171*795d594fSAndroid Build Coastguard Worker     bool in_memory = !space->GetProfileFiles().empty();
172*795d594fSAndroid Build Coastguard Worker     oat_files.push_back(RegisterOatFile(space->ReleaseOatFile(), in_memory));
173*795d594fSAndroid Build Coastguard Worker   }
174*795d594fSAndroid Build Coastguard Worker   return oat_files;
175*795d594fSAndroid Build Coastguard Worker }
176*795d594fSAndroid Build Coastguard Worker 
ShouldLoadAppImage() const177*795d594fSAndroid Build Coastguard Worker bool OatFileManager::ShouldLoadAppImage() const {
178*795d594fSAndroid Build Coastguard Worker   Runtime* const runtime = Runtime::Current();
179*795d594fSAndroid Build Coastguard Worker   if (!kEnableAppImage || runtime->IsJavaDebuggableAtInit()) {
180*795d594fSAndroid Build Coastguard Worker     return false;
181*795d594fSAndroid Build Coastguard Worker   }
182*795d594fSAndroid Build Coastguard Worker 
183*795d594fSAndroid Build Coastguard Worker #if defined(__ANDROID__)
184*795d594fSAndroid Build Coastguard Worker   const char* process_name = getprogname();
185*795d594fSAndroid Build Coastguard Worker   // Some processes would rather take the runtime impact in the interest of memory (b/292210260)
186*795d594fSAndroid Build Coastguard Worker   if (process_name != nullptr && strstr(process_name, kDisableAppImageKeyword) != nullptr) {
187*795d594fSAndroid Build Coastguard Worker     LOG(INFO) << "Skipping app image load for " << process_name;
188*795d594fSAndroid Build Coastguard Worker     return false;
189*795d594fSAndroid Build Coastguard Worker   }
190*795d594fSAndroid Build Coastguard Worker #endif
191*795d594fSAndroid Build Coastguard Worker 
192*795d594fSAndroid Build Coastguard Worker   return true;
193*795d594fSAndroid Build Coastguard Worker }
194*795d594fSAndroid Build Coastguard Worker 
OpenDexFilesFromOat(const char * dex_location,jobject class_loader,jobjectArray dex_elements,const OatFile ** out_oat_file,std::vector<std::string> * error_msgs)195*795d594fSAndroid Build Coastguard Worker std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
196*795d594fSAndroid Build Coastguard Worker     const char* dex_location,
197*795d594fSAndroid Build Coastguard Worker     jobject class_loader,
198*795d594fSAndroid Build Coastguard Worker     jobjectArray dex_elements,
199*795d594fSAndroid Build Coastguard Worker     const OatFile** out_oat_file,
200*795d594fSAndroid Build Coastguard Worker     std::vector<std::string>* error_msgs) {
201*795d594fSAndroid Build Coastguard Worker   ScopedTrace trace(StringPrintf("%s(%s)", __FUNCTION__, dex_location));
202*795d594fSAndroid Build Coastguard Worker   CHECK(dex_location != nullptr);
203*795d594fSAndroid Build Coastguard Worker   CHECK(error_msgs != nullptr);
204*795d594fSAndroid Build Coastguard Worker 
205*795d594fSAndroid Build Coastguard Worker   // Verify we aren't holding the mutator lock, which could starve GC when
206*795d594fSAndroid Build Coastguard Worker   // hitting the disk.
207*795d594fSAndroid Build Coastguard Worker   Thread* const self = Thread::Current();
208*795d594fSAndroid Build Coastguard Worker   Locks::mutator_lock_->AssertNotHeld(self);
209*795d594fSAndroid Build Coastguard Worker   Runtime* const runtime = Runtime::Current();
210*795d594fSAndroid Build Coastguard Worker 
211*795d594fSAndroid Build Coastguard Worker   std::vector<std::unique_ptr<const DexFile>> dex_files;
212*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<ClassLoaderContext> context(
213*795d594fSAndroid Build Coastguard Worker       ClassLoaderContext::CreateContextForClassLoader(class_loader, dex_elements));
214*795d594fSAndroid Build Coastguard Worker 
215*795d594fSAndroid Build Coastguard Worker   // If the class_loader is null there's not much we can do. This happens if a dex files is loaded
216*795d594fSAndroid Build Coastguard Worker   // directly with DexFile APIs instead of using class loaders.
217*795d594fSAndroid Build Coastguard Worker   if (class_loader == nullptr) {
218*795d594fSAndroid Build Coastguard Worker     LOG(WARNING) << "Opening an oat file without a class loader. "
219*795d594fSAndroid Build Coastguard Worker                  << "Are you using the deprecated DexFile APIs?";
220*795d594fSAndroid Build Coastguard Worker   } else if (context != nullptr) {
221*795d594fSAndroid Build Coastguard Worker     auto oat_file_assistant = std::make_unique<OatFileAssistant>(dex_location,
222*795d594fSAndroid Build Coastguard Worker                                                                  kRuntimeQuickCodeISA,
223*795d594fSAndroid Build Coastguard Worker                                                                  context.get(),
224*795d594fSAndroid Build Coastguard Worker                                                                  runtime->GetOatFilesExecutable(),
225*795d594fSAndroid Build Coastguard Worker                                                                  only_use_system_oat_files_);
226*795d594fSAndroid Build Coastguard Worker 
227*795d594fSAndroid Build Coastguard Worker     // Get the current optimization status for trace debugging.
228*795d594fSAndroid Build Coastguard Worker     // Implementation detail note: GetOptimizationStatus will select the same
229*795d594fSAndroid Build Coastguard Worker     // oat file as GetBestOatFile used below, and in doing so it already pre-populates
230*795d594fSAndroid Build Coastguard Worker     // some OatFileAssistant internal fields.
231*795d594fSAndroid Build Coastguard Worker     std::string odex_location;
232*795d594fSAndroid Build Coastguard Worker     std::string compilation_filter;
233*795d594fSAndroid Build Coastguard Worker     std::string compilation_reason;
234*795d594fSAndroid Build Coastguard Worker     std::string odex_status;
235*795d594fSAndroid Build Coastguard Worker     OatFileAssistant::Location ignored_location;
236*795d594fSAndroid Build Coastguard Worker     oat_file_assistant->GetOptimizationStatus(
237*795d594fSAndroid Build Coastguard Worker         &odex_location, &compilation_filter, &compilation_reason, &odex_status, &ignored_location);
238*795d594fSAndroid Build Coastguard Worker 
239*795d594fSAndroid Build Coastguard Worker     ScopedTrace odex_loading(StringPrintf(
240*795d594fSAndroid Build Coastguard Worker         "location=%s status=%s filter=%s reason=%s",
241*795d594fSAndroid Build Coastguard Worker         odex_location.c_str(),
242*795d594fSAndroid Build Coastguard Worker         odex_status.c_str(),
243*795d594fSAndroid Build Coastguard Worker         compilation_filter.c_str(),
244*795d594fSAndroid Build Coastguard Worker         compilation_reason.c_str()));
245*795d594fSAndroid Build Coastguard Worker 
246*795d594fSAndroid Build Coastguard Worker     const bool has_registered_app_info = Runtime::Current()->GetAppInfo()->HasRegisteredAppInfo();
247*795d594fSAndroid Build Coastguard Worker     const AppInfo::CodeType code_type =
248*795d594fSAndroid Build Coastguard Worker         Runtime::Current()->GetAppInfo()->GetRegisteredCodeType(dex_location);
249*795d594fSAndroid Build Coastguard Worker     // We only want to madvise primary/split dex artifacts as a startup optimization. However,
250*795d594fSAndroid Build Coastguard Worker     // as the code_type for those artifacts may not be set until the initial app info registration,
251*795d594fSAndroid Build Coastguard Worker     // we conservatively madvise everything until the app info registration is complete.
252*795d594fSAndroid Build Coastguard Worker     const bool should_madvise = !has_registered_app_info ||
253*795d594fSAndroid Build Coastguard Worker                                 code_type == AppInfo::CodeType::kPrimaryApk ||
254*795d594fSAndroid Build Coastguard Worker                                 code_type == AppInfo::CodeType::kSplitApk;
255*795d594fSAndroid Build Coastguard Worker 
256*795d594fSAndroid Build Coastguard Worker     // Proceed with oat file loading.
257*795d594fSAndroid Build Coastguard Worker     std::unique_ptr<const OatFile> oat_file(oat_file_assistant->GetBestOatFile().release());
258*795d594fSAndroid Build Coastguard Worker     VLOG(oat) << "OatFileAssistant(" << dex_location << ").GetBestOatFile()="
259*795d594fSAndroid Build Coastguard Worker               << (oat_file != nullptr ? oat_file->GetLocation() : "")
260*795d594fSAndroid Build Coastguard Worker               << " (executable=" << (oat_file != nullptr ? oat_file->IsExecutable() : false) << ")";
261*795d594fSAndroid Build Coastguard Worker 
262*795d594fSAndroid Build Coastguard Worker     CHECK(oat_file == nullptr || odex_location == oat_file->GetLocation())
263*795d594fSAndroid Build Coastguard Worker         << "OatFileAssistant non-determinism in choosing best oat files. "
264*795d594fSAndroid Build Coastguard Worker         << "optimization-status-location=" << odex_location
265*795d594fSAndroid Build Coastguard Worker         << " best_oat_file-location=" << oat_file->GetLocation();
266*795d594fSAndroid Build Coastguard Worker 
267*795d594fSAndroid Build Coastguard Worker     if (oat_file != nullptr) {
268*795d594fSAndroid Build Coastguard Worker       bool compilation_enabled =
269*795d594fSAndroid Build Coastguard Worker           CompilerFilter::IsAotCompilationEnabled(oat_file->GetCompilerFilter());
270*795d594fSAndroid Build Coastguard Worker       // Load the dex files from the oat file.
271*795d594fSAndroid Build Coastguard Worker       bool added_image_space = false;
272*795d594fSAndroid Build Coastguard Worker       if (should_madvise) {
273*795d594fSAndroid Build Coastguard Worker         VLOG(oat) << "Madvising oat file: " << oat_file->GetLocation();
274*795d594fSAndroid Build Coastguard Worker         size_t madvise_size_limit = runtime->GetMadviseWillNeedSizeOdex();
275*795d594fSAndroid Build Coastguard Worker         Runtime::MadviseFileForRange(madvise_size_limit,
276*795d594fSAndroid Build Coastguard Worker                                      oat_file->Size(),
277*795d594fSAndroid Build Coastguard Worker                                      oat_file->Begin(),
278*795d594fSAndroid Build Coastguard Worker                                      oat_file->End(),
279*795d594fSAndroid Build Coastguard Worker                                      oat_file->GetLocation());
280*795d594fSAndroid Build Coastguard Worker       }
281*795d594fSAndroid Build Coastguard Worker 
282*795d594fSAndroid Build Coastguard Worker       ScopedTrace app_image_timing("AppImage:Loading");
283*795d594fSAndroid Build Coastguard Worker 
284*795d594fSAndroid Build Coastguard Worker       // We need to throw away the image space if we are debuggable but the oat-file source of the
285*795d594fSAndroid Build Coastguard Worker       // image is not otherwise we might get classes with inlined methods or other such things.
286*795d594fSAndroid Build Coastguard Worker       std::unique_ptr<gc::space::ImageSpace> image_space;
287*795d594fSAndroid Build Coastguard Worker       if (ShouldLoadAppImage()) {
288*795d594fSAndroid Build Coastguard Worker         if (oat_file->IsExecutable()) {
289*795d594fSAndroid Build Coastguard Worker           // App images generated by the compiler can only be used if the oat file
290*795d594fSAndroid Build Coastguard Worker           // is executable.
291*795d594fSAndroid Build Coastguard Worker           image_space = oat_file_assistant->OpenImageSpace(oat_file.get());
292*795d594fSAndroid Build Coastguard Worker         }
293*795d594fSAndroid Build Coastguard Worker         // Load the runtime image. This logic must be aligned with the one that determines when to
294*795d594fSAndroid Build Coastguard Worker         // keep runtime images in `ArtManagerLocal.cleanup` in
295*795d594fSAndroid Build Coastguard Worker         // `art/libartservice/service/java/com/android/server/art/ArtManagerLocal.java`.
296*795d594fSAndroid Build Coastguard Worker         if (kEnableRuntimeAppImage && image_space == nullptr && !compilation_enabled) {
297*795d594fSAndroid Build Coastguard Worker           std::string art_file = RuntimeImage::GetRuntimeImagePath(dex_location);
298*795d594fSAndroid Build Coastguard Worker           std::string error_msg;
299*795d594fSAndroid Build Coastguard Worker           image_space = gc::space::ImageSpace::CreateFromAppImage(
300*795d594fSAndroid Build Coastguard Worker               art_file.c_str(), oat_file.get(), &error_msg);
301*795d594fSAndroid Build Coastguard Worker           if (image_space == nullptr) {
302*795d594fSAndroid Build Coastguard Worker             (OS::FileExists(art_file.c_str()) ? LOG_STREAM(INFO) : VLOG_STREAM(image))
303*795d594fSAndroid Build Coastguard Worker                 << "Could not load runtime generated app image: " << error_msg;
304*795d594fSAndroid Build Coastguard Worker           }
305*795d594fSAndroid Build Coastguard Worker         }
306*795d594fSAndroid Build Coastguard Worker       }
307*795d594fSAndroid Build Coastguard Worker       if (image_space != nullptr) {
308*795d594fSAndroid Build Coastguard Worker         ScopedObjectAccess soa(self);
309*795d594fSAndroid Build Coastguard Worker         StackHandleScope<1> hs(self);
310*795d594fSAndroid Build Coastguard Worker         Handle<mirror::ClassLoader> h_loader(
311*795d594fSAndroid Build Coastguard Worker             hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
312*795d594fSAndroid Build Coastguard Worker         // Can not load app image without class loader.
313*795d594fSAndroid Build Coastguard Worker         if (h_loader != nullptr) {
314*795d594fSAndroid Build Coastguard Worker           oat_file->SetAppImageBegin(image_space->Begin());
315*795d594fSAndroid Build Coastguard Worker           std::string temp_error_msg;
316*795d594fSAndroid Build Coastguard Worker           // Add image space has a race condition since other threads could be reading from the
317*795d594fSAndroid Build Coastguard Worker           // spaces array.
318*795d594fSAndroid Build Coastguard Worker           {
319*795d594fSAndroid Build Coastguard Worker             ScopedThreadSuspension sts(self, ThreadState::kSuspended);
320*795d594fSAndroid Build Coastguard Worker             gc::ScopedGCCriticalSection gcs(self,
321*795d594fSAndroid Build Coastguard Worker                                             gc::kGcCauseAddRemoveAppImageSpace,
322*795d594fSAndroid Build Coastguard Worker                                             gc::kCollectorTypeAddRemoveAppImageSpace);
323*795d594fSAndroid Build Coastguard Worker             ScopedSuspendAll ssa("Add image space");
324*795d594fSAndroid Build Coastguard Worker             runtime->GetHeap()->AddSpace(image_space.get());
325*795d594fSAndroid Build Coastguard Worker           }
326*795d594fSAndroid Build Coastguard Worker           {
327*795d594fSAndroid Build Coastguard Worker             ScopedTrace image_space_timing("Adding image space");
328*795d594fSAndroid Build Coastguard Worker             gc::space::ImageSpace* space_ptr = image_space.get();
329*795d594fSAndroid Build Coastguard Worker             added_image_space = runtime->GetClassLinker()->AddImageSpaces(
330*795d594fSAndroid Build Coastguard Worker                 ArrayRef<gc::space::ImageSpace*>(&space_ptr, /*size=*/1),
331*795d594fSAndroid Build Coastguard Worker                 h_loader,
332*795d594fSAndroid Build Coastguard Worker                 context.get(),
333*795d594fSAndroid Build Coastguard Worker                 /*out*/ &dex_files,
334*795d594fSAndroid Build Coastguard Worker                 /*out*/ &temp_error_msg);
335*795d594fSAndroid Build Coastguard Worker           }
336*795d594fSAndroid Build Coastguard Worker           if (added_image_space) {
337*795d594fSAndroid Build Coastguard Worker             // Successfully added image space to heap, release the map so that it does not get
338*795d594fSAndroid Build Coastguard Worker             // freed.
339*795d594fSAndroid Build Coastguard Worker             image_space.release();  // NOLINT b/117926937
340*795d594fSAndroid Build Coastguard Worker 
341*795d594fSAndroid Build Coastguard Worker             // Register for tracking.
342*795d594fSAndroid Build Coastguard Worker             for (const auto& dex_file : dex_files) {
343*795d594fSAndroid Build Coastguard Worker               dex::tracking::RegisterDexFile(dex_file.get());
344*795d594fSAndroid Build Coastguard Worker             }
345*795d594fSAndroid Build Coastguard Worker           } else {
346*795d594fSAndroid Build Coastguard Worker             LOG(INFO) << "Failed to add image file: " << temp_error_msg;
347*795d594fSAndroid Build Coastguard Worker             oat_file->SetAppImageBegin(nullptr);
348*795d594fSAndroid Build Coastguard Worker             dex_files.clear();
349*795d594fSAndroid Build Coastguard Worker             {
350*795d594fSAndroid Build Coastguard Worker               ScopedThreadSuspension sts(self, ThreadState::kSuspended);
351*795d594fSAndroid Build Coastguard Worker               gc::ScopedGCCriticalSection gcs(self,
352*795d594fSAndroid Build Coastguard Worker                                               gc::kGcCauseAddRemoveAppImageSpace,
353*795d594fSAndroid Build Coastguard Worker                                               gc::kCollectorTypeAddRemoveAppImageSpace);
354*795d594fSAndroid Build Coastguard Worker               ScopedSuspendAll ssa("Remove image space");
355*795d594fSAndroid Build Coastguard Worker               runtime->GetHeap()->RemoveSpace(image_space.get());
356*795d594fSAndroid Build Coastguard Worker             }
357*795d594fSAndroid Build Coastguard Worker             // Non-fatal, don't update error_msg.
358*795d594fSAndroid Build Coastguard Worker           }
359*795d594fSAndroid Build Coastguard Worker         }
360*795d594fSAndroid Build Coastguard Worker       }
361*795d594fSAndroid Build Coastguard Worker       if (!added_image_space) {
362*795d594fSAndroid Build Coastguard Worker         DCHECK(dex_files.empty());
363*795d594fSAndroid Build Coastguard Worker 
364*795d594fSAndroid Build Coastguard Worker         if (oat_file->RequiresImage()) {
365*795d594fSAndroid Build Coastguard Worker           LOG(WARNING) << "Loading "
366*795d594fSAndroid Build Coastguard Worker                        << oat_file->GetLocation()
367*795d594fSAndroid Build Coastguard Worker                        << " non-executable as it requires an image which we failed to load";
368*795d594fSAndroid Build Coastguard Worker           // file as non-executable.
369*795d594fSAndroid Build Coastguard Worker           auto nonexecutable_oat_file_assistant =
370*795d594fSAndroid Build Coastguard Worker               std::make_unique<OatFileAssistant>(dex_location,
371*795d594fSAndroid Build Coastguard Worker                                                  kRuntimeQuickCodeISA,
372*795d594fSAndroid Build Coastguard Worker                                                  context.get(),
373*795d594fSAndroid Build Coastguard Worker                                                  /*load_executable=*/false,
374*795d594fSAndroid Build Coastguard Worker                                                  only_use_system_oat_files_);
375*795d594fSAndroid Build Coastguard Worker           oat_file.reset(nonexecutable_oat_file_assistant->GetBestOatFile().release());
376*795d594fSAndroid Build Coastguard Worker 
377*795d594fSAndroid Build Coastguard Worker           // The file could be deleted concurrently (for example background
378*795d594fSAndroid Build Coastguard Worker           // dexopt, or secondary oat file being deleted by the app).
379*795d594fSAndroid Build Coastguard Worker           if (oat_file == nullptr) {
380*795d594fSAndroid Build Coastguard Worker             LOG(WARNING) << "Failed to reload oat file non-executable " << dex_location;
381*795d594fSAndroid Build Coastguard Worker           }
382*795d594fSAndroid Build Coastguard Worker         }
383*795d594fSAndroid Build Coastguard Worker 
384*795d594fSAndroid Build Coastguard Worker         if (oat_file != nullptr) {
385*795d594fSAndroid Build Coastguard Worker           dex_files = oat_file_assistant->LoadDexFiles(*oat_file.get(), dex_location);
386*795d594fSAndroid Build Coastguard Worker 
387*795d594fSAndroid Build Coastguard Worker           // Register for tracking.
388*795d594fSAndroid Build Coastguard Worker           for (const auto& dex_file : dex_files) {
389*795d594fSAndroid Build Coastguard Worker             dex::tracking::RegisterDexFile(dex_file.get());
390*795d594fSAndroid Build Coastguard Worker           }
391*795d594fSAndroid Build Coastguard Worker         }
392*795d594fSAndroid Build Coastguard Worker       }
393*795d594fSAndroid Build Coastguard Worker       if (dex_files.empty()) {
394*795d594fSAndroid Build Coastguard Worker         ScopedTrace failed_to_open_dex_files("FailedToOpenDexFilesFromOat");
395*795d594fSAndroid Build Coastguard Worker         error_msgs->push_back("Failed to open dex files from " + odex_location);
396*795d594fSAndroid Build Coastguard Worker       } else if (should_madvise) {
397*795d594fSAndroid Build Coastguard Worker         size_t madvise_size_limit = Runtime::Current()->GetMadviseWillNeedTotalDexSize();
398*795d594fSAndroid Build Coastguard Worker         for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
399*795d594fSAndroid Build Coastguard Worker           // Prefetch the dex file based on vdex size limit (name should
400*795d594fSAndroid Build Coastguard Worker           // have been dex size limit).
401*795d594fSAndroid Build Coastguard Worker           VLOG(oat) << "Madvising dex file: " << dex_file->GetLocation();
402*795d594fSAndroid Build Coastguard Worker           Runtime::MadviseFileForRange(madvise_size_limit,
403*795d594fSAndroid Build Coastguard Worker                                        dex_file->Size(),
404*795d594fSAndroid Build Coastguard Worker                                        dex_file->Begin(),
405*795d594fSAndroid Build Coastguard Worker                                        dex_file->Begin() + dex_file->Size(),
406*795d594fSAndroid Build Coastguard Worker                                        dex_file->GetLocation());
407*795d594fSAndroid Build Coastguard Worker           if (dex_file->Size() >= madvise_size_limit) {
408*795d594fSAndroid Build Coastguard Worker             break;
409*795d594fSAndroid Build Coastguard Worker           }
410*795d594fSAndroid Build Coastguard Worker           madvise_size_limit -= dex_file->Size();
411*795d594fSAndroid Build Coastguard Worker         }
412*795d594fSAndroid Build Coastguard Worker       }
413*795d594fSAndroid Build Coastguard Worker 
414*795d594fSAndroid Build Coastguard Worker       if (oat_file != nullptr) {
415*795d594fSAndroid Build Coastguard Worker         VLOG(class_linker) << "Registering " << oat_file->GetLocation();
416*795d594fSAndroid Build Coastguard Worker         *out_oat_file = RegisterOatFile(std::move(oat_file));
417*795d594fSAndroid Build Coastguard Worker       }
418*795d594fSAndroid Build Coastguard Worker     } else {
419*795d594fSAndroid Build Coastguard Worker       // oat_file == nullptr
420*795d594fSAndroid Build Coastguard Worker       // Verify if any of the dex files being loaded is already in the class path.
421*795d594fSAndroid Build Coastguard Worker       // If so, report an error with the current stack trace.
422*795d594fSAndroid Build Coastguard Worker       // Most likely the developer didn't intend to do this because it will waste
423*795d594fSAndroid Build Coastguard Worker       // performance and memory.
424*795d594fSAndroid Build Coastguard Worker       if (oat_file_assistant->GetBestStatus() == OatFileAssistant::kOatContextOutOfDate) {
425*795d594fSAndroid Build Coastguard Worker         std::set<const DexFile*> already_exists_in_classpath =
426*795d594fSAndroid Build Coastguard Worker             context->CheckForDuplicateDexFiles(MakeNonOwningPointerVector(dex_files));
427*795d594fSAndroid Build Coastguard Worker         if (!already_exists_in_classpath.empty()) {
428*795d594fSAndroid Build Coastguard Worker           ScopedTrace duplicate_dex_files("DuplicateDexFilesInContext");
429*795d594fSAndroid Build Coastguard Worker           auto duplicate_it = already_exists_in_classpath.begin();
430*795d594fSAndroid Build Coastguard Worker           std::string duplicates = (*duplicate_it)->GetLocation();
431*795d594fSAndroid Build Coastguard Worker           for (duplicate_it++ ; duplicate_it != already_exists_in_classpath.end(); duplicate_it++) {
432*795d594fSAndroid Build Coastguard Worker             duplicates += "," + (*duplicate_it)->GetLocation();
433*795d594fSAndroid Build Coastguard Worker           }
434*795d594fSAndroid Build Coastguard Worker 
435*795d594fSAndroid Build Coastguard Worker           std::ostringstream out;
436*795d594fSAndroid Build Coastguard Worker           out << "Trying to load dex files which is already loaded in the same ClassLoader "
437*795d594fSAndroid Build Coastguard Worker               << "hierarchy.\n"
438*795d594fSAndroid Build Coastguard Worker               << "This is a strong indication of bad ClassLoader construct which leads to poor "
439*795d594fSAndroid Build Coastguard Worker               << "performance and wastes memory.\n"
440*795d594fSAndroid Build Coastguard Worker               << "The list of duplicate dex files is: " << duplicates << "\n"
441*795d594fSAndroid Build Coastguard Worker               << "The current class loader context is: "
442*795d594fSAndroid Build Coastguard Worker               << context->EncodeContextForOatFile("") << "\n"
443*795d594fSAndroid Build Coastguard Worker               << "Java stack trace:\n";
444*795d594fSAndroid Build Coastguard Worker 
445*795d594fSAndroid Build Coastguard Worker           {
446*795d594fSAndroid Build Coastguard Worker             ScopedObjectAccess soa(self);
447*795d594fSAndroid Build Coastguard Worker             self->DumpJavaStack(out);
448*795d594fSAndroid Build Coastguard Worker           }
449*795d594fSAndroid Build Coastguard Worker 
450*795d594fSAndroid Build Coastguard Worker           // We log this as an ERROR to stress the fact that this is most likely unintended.
451*795d594fSAndroid Build Coastguard Worker           // Note that ART cannot do anything about it. It is up to the app to fix their logic.
452*795d594fSAndroid Build Coastguard Worker           // Here we are trying to give a heads up on why the app might have performance issues.
453*795d594fSAndroid Build Coastguard Worker           LOG(ERROR) << out.str();
454*795d594fSAndroid Build Coastguard Worker         }
455*795d594fSAndroid Build Coastguard Worker       }
456*795d594fSAndroid Build Coastguard Worker     }
457*795d594fSAndroid Build Coastguard Worker 
458*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetAppInfo()->RegisterOdexStatus(
459*795d594fSAndroid Build Coastguard Worker         dex_location,
460*795d594fSAndroid Build Coastguard Worker         compilation_filter,
461*795d594fSAndroid Build Coastguard Worker         compilation_reason,
462*795d594fSAndroid Build Coastguard Worker         odex_status);
463*795d594fSAndroid Build Coastguard Worker   }
464*795d594fSAndroid Build Coastguard Worker 
465*795d594fSAndroid Build Coastguard Worker   // If we arrive here with an empty dex files list, it means we fail to load
466*795d594fSAndroid Build Coastguard Worker   // it/them through an .oat file.
467*795d594fSAndroid Build Coastguard Worker   if (dex_files.empty()) {
468*795d594fSAndroid Build Coastguard Worker     std::string error_msg;
469*795d594fSAndroid Build Coastguard Worker     static constexpr bool kVerifyChecksum = true;
470*795d594fSAndroid Build Coastguard Worker     ArtDexFileLoader dex_file_loader(dex_location);
471*795d594fSAndroid Build Coastguard Worker     if (!dex_file_loader.Open(Runtime::Current()->IsVerificationEnabled(),
472*795d594fSAndroid Build Coastguard Worker                               kVerifyChecksum,
473*795d594fSAndroid Build Coastguard Worker                               /*out*/ &error_msg,
474*795d594fSAndroid Build Coastguard Worker                               &dex_files)) {
475*795d594fSAndroid Build Coastguard Worker       ScopedTrace fail_to_open_dex_from_apk("FailedToOpenDexFilesFromApk");
476*795d594fSAndroid Build Coastguard Worker       LOG(WARNING) << error_msg;
477*795d594fSAndroid Build Coastguard Worker       error_msgs->push_back("Failed to open dex files from " + std::string(dex_location)
478*795d594fSAndroid Build Coastguard Worker                             + " because: " + error_msg);
479*795d594fSAndroid Build Coastguard Worker     }
480*795d594fSAndroid Build Coastguard Worker   }
481*795d594fSAndroid Build Coastguard Worker 
482*795d594fSAndroid Build Coastguard Worker   if (Runtime::Current()->GetJit() != nullptr) {
483*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetJit()->RegisterDexFiles(dex_files, class_loader);
484*795d594fSAndroid Build Coastguard Worker   }
485*795d594fSAndroid Build Coastguard Worker 
486*795d594fSAndroid Build Coastguard Worker   // Now that we loaded the dex/odex files, notify the runtime.
487*795d594fSAndroid Build Coastguard Worker   // Note that we do this everytime we load dex files.
488*795d594fSAndroid Build Coastguard Worker   Runtime::Current()->NotifyDexFileLoaded();
489*795d594fSAndroid Build Coastguard Worker 
490*795d594fSAndroid Build Coastguard Worker   return dex_files;
491*795d594fSAndroid Build Coastguard Worker }
492*795d594fSAndroid Build Coastguard Worker 
GetDexFileHeaders(const std::vector<MemMap> & maps)493*795d594fSAndroid Build Coastguard Worker static std::vector<const DexFile::Header*> GetDexFileHeaders(const std::vector<MemMap>& maps) {
494*795d594fSAndroid Build Coastguard Worker   std::vector<const DexFile::Header*> headers;
495*795d594fSAndroid Build Coastguard Worker   headers.reserve(maps.size());
496*795d594fSAndroid Build Coastguard Worker   for (const MemMap& map : maps) {
497*795d594fSAndroid Build Coastguard Worker     DCHECK(map.IsValid());
498*795d594fSAndroid Build Coastguard Worker     headers.push_back(reinterpret_cast<const DexFile::Header*>(map.Begin()));
499*795d594fSAndroid Build Coastguard Worker   }
500*795d594fSAndroid Build Coastguard Worker   return headers;
501*795d594fSAndroid Build Coastguard Worker }
502*795d594fSAndroid Build Coastguard Worker 
OpenDexFilesFromOat(std::vector<MemMap> && dex_mem_maps,jobject class_loader,jobjectArray dex_elements,const OatFile ** out_oat_file,std::vector<std::string> * error_msgs)503*795d594fSAndroid Build Coastguard Worker std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
504*795d594fSAndroid Build Coastguard Worker     std::vector<MemMap>&& dex_mem_maps,
505*795d594fSAndroid Build Coastguard Worker     jobject class_loader,
506*795d594fSAndroid Build Coastguard Worker     jobjectArray dex_elements,
507*795d594fSAndroid Build Coastguard Worker     const OatFile** out_oat_file,
508*795d594fSAndroid Build Coastguard Worker     std::vector<std::string>* error_msgs) {
509*795d594fSAndroid Build Coastguard Worker   std::vector<std::unique_ptr<const DexFile>> dex_files = OpenDexFilesFromOat_Impl(
510*795d594fSAndroid Build Coastguard Worker       std::move(dex_mem_maps),
511*795d594fSAndroid Build Coastguard Worker       class_loader,
512*795d594fSAndroid Build Coastguard Worker       dex_elements,
513*795d594fSAndroid Build Coastguard Worker       out_oat_file,
514*795d594fSAndroid Build Coastguard Worker       error_msgs);
515*795d594fSAndroid Build Coastguard Worker 
516*795d594fSAndroid Build Coastguard Worker   if (error_msgs->empty()) {
517*795d594fSAndroid Build Coastguard Worker     // Remove write permission from DexFile pages. We do this at the end because
518*795d594fSAndroid Build Coastguard Worker     // OatFile assigns OatDexFile pointer in the DexFile objects.
519*795d594fSAndroid Build Coastguard Worker     for (std::unique_ptr<const DexFile>& dex_file : dex_files) {
520*795d594fSAndroid Build Coastguard Worker       if (!dex_file->DisableWrite()) {
521*795d594fSAndroid Build Coastguard Worker         error_msgs->push_back("Failed to make dex file " + dex_file->GetLocation() + " read-only");
522*795d594fSAndroid Build Coastguard Worker       }
523*795d594fSAndroid Build Coastguard Worker     }
524*795d594fSAndroid Build Coastguard Worker   }
525*795d594fSAndroid Build Coastguard Worker 
526*795d594fSAndroid Build Coastguard Worker   if (!error_msgs->empty()) {
527*795d594fSAndroid Build Coastguard Worker     return std::vector<std::unique_ptr<const DexFile>>();
528*795d594fSAndroid Build Coastguard Worker   }
529*795d594fSAndroid Build Coastguard Worker 
530*795d594fSAndroid Build Coastguard Worker   return dex_files;
531*795d594fSAndroid Build Coastguard Worker }
532*795d594fSAndroid Build Coastguard Worker 
OpenDexFilesFromOat_Impl(std::vector<MemMap> && dex_mem_maps,jobject class_loader,jobjectArray dex_elements,const OatFile ** out_oat_file,std::vector<std::string> * error_msgs)533*795d594fSAndroid Build Coastguard Worker std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat_Impl(
534*795d594fSAndroid Build Coastguard Worker     std::vector<MemMap>&& dex_mem_maps,
535*795d594fSAndroid Build Coastguard Worker     jobject class_loader,
536*795d594fSAndroid Build Coastguard Worker     jobjectArray dex_elements,
537*795d594fSAndroid Build Coastguard Worker     const OatFile** out_oat_file,
538*795d594fSAndroid Build Coastguard Worker     std::vector<std::string>* error_msgs) {
539*795d594fSAndroid Build Coastguard Worker   ScopedTrace trace(__FUNCTION__);
540*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
541*795d594fSAndroid Build Coastguard Worker   DCHECK(error_msgs != nullptr);
542*795d594fSAndroid Build Coastguard Worker 
543*795d594fSAndroid Build Coastguard Worker   // Extract dex file headers from `dex_mem_maps`.
544*795d594fSAndroid Build Coastguard Worker   const std::vector<const DexFile::Header*> dex_headers = GetDexFileHeaders(dex_mem_maps);
545*795d594fSAndroid Build Coastguard Worker 
546*795d594fSAndroid Build Coastguard Worker   // Determine dex/vdex locations and the combined location checksum.
547*795d594fSAndroid Build Coastguard Worker   std::string dex_location;
548*795d594fSAndroid Build Coastguard Worker   std::string vdex_path;
549*795d594fSAndroid Build Coastguard Worker   bool has_vdex = OatFileAssistant::AnonymousDexVdexLocation(dex_headers,
550*795d594fSAndroid Build Coastguard Worker                                                              kRuntimeQuickCodeISA,
551*795d594fSAndroid Build Coastguard Worker                                                              &dex_location,
552*795d594fSAndroid Build Coastguard Worker                                                              &vdex_path);
553*795d594fSAndroid Build Coastguard Worker 
554*795d594fSAndroid Build Coastguard Worker   // Attempt to open an existing vdex and check dex file checksums match.
555*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<VdexFile> vdex_file = nullptr;
556*795d594fSAndroid Build Coastguard Worker   if (has_vdex && OS::FileExists(vdex_path.c_str())) {
557*795d594fSAndroid Build Coastguard Worker     vdex_file = VdexFile::Open(vdex_path,
558*795d594fSAndroid Build Coastguard Worker                                /* writable= */ false,
559*795d594fSAndroid Build Coastguard Worker                                /* low_4gb= */ false,
560*795d594fSAndroid Build Coastguard Worker                                &error_msg);
561*795d594fSAndroid Build Coastguard Worker     if (vdex_file == nullptr) {
562*795d594fSAndroid Build Coastguard Worker       LOG(WARNING) << "Failed to open vdex " << vdex_path << ": " << error_msg;
563*795d594fSAndroid Build Coastguard Worker     } else if (!vdex_file->MatchesDexFileChecksums(dex_headers)) {
564*795d594fSAndroid Build Coastguard Worker       LOG(WARNING) << "Failed to open vdex " << vdex_path << ": dex file checksum mismatch";
565*795d594fSAndroid Build Coastguard Worker       vdex_file.reset(nullptr);
566*795d594fSAndroid Build Coastguard Worker     }
567*795d594fSAndroid Build Coastguard Worker   }
568*795d594fSAndroid Build Coastguard Worker 
569*795d594fSAndroid Build Coastguard Worker   // Load dex files. Skip structural dex file verification if vdex was found
570*795d594fSAndroid Build Coastguard Worker   // and dex checksums matched.
571*795d594fSAndroid Build Coastguard Worker   std::vector<std::unique_ptr<const DexFile>> dex_files;
572*795d594fSAndroid Build Coastguard Worker   for (size_t i = 0; i < dex_mem_maps.size(); ++i) {
573*795d594fSAndroid Build Coastguard Worker     static constexpr bool kVerifyChecksum = true;
574*795d594fSAndroid Build Coastguard Worker     ArtDexFileLoader dex_file_loader(std::move(dex_mem_maps[i]),
575*795d594fSAndroid Build Coastguard Worker                                      DexFileLoader::GetMultiDexLocation(i, dex_location.c_str()));
576*795d594fSAndroid Build Coastguard Worker     std::unique_ptr<const DexFile> dex_file(dex_file_loader.Open(
577*795d594fSAndroid Build Coastguard Worker         dex_headers[i]->checksum_,
578*795d594fSAndroid Build Coastguard Worker         /* verify= */ (vdex_file == nullptr) && Runtime::Current()->IsVerificationEnabled(),
579*795d594fSAndroid Build Coastguard Worker         kVerifyChecksum,
580*795d594fSAndroid Build Coastguard Worker         &error_msg));
581*795d594fSAndroid Build Coastguard Worker     if (dex_file != nullptr) {
582*795d594fSAndroid Build Coastguard Worker       dex::tracking::RegisterDexFile(dex_file.get());  // Register for tracking.
583*795d594fSAndroid Build Coastguard Worker       dex_files.push_back(std::move(dex_file));
584*795d594fSAndroid Build Coastguard Worker     } else {
585*795d594fSAndroid Build Coastguard Worker       error_msgs->push_back("Failed to open dex files from memory: " + error_msg);
586*795d594fSAndroid Build Coastguard Worker     }
587*795d594fSAndroid Build Coastguard Worker   }
588*795d594fSAndroid Build Coastguard Worker 
589*795d594fSAndroid Build Coastguard Worker   // Check if we should proceed to creating an OatFile instance backed by the vdex.
590*795d594fSAndroid Build Coastguard Worker   // We need: (a) an existing vdex, (b) class loader (can be null if invoked via reflection),
591*795d594fSAndroid Build Coastguard Worker   // and (c) no errors during dex file loading.
592*795d594fSAndroid Build Coastguard Worker   if (vdex_file == nullptr || class_loader == nullptr || !error_msgs->empty()) {
593*795d594fSAndroid Build Coastguard Worker     return dex_files;
594*795d594fSAndroid Build Coastguard Worker   }
595*795d594fSAndroid Build Coastguard Worker 
596*795d594fSAndroid Build Coastguard Worker   // Attempt to create a class loader context, check OpenDexFiles succeeds (prerequisite
597*795d594fSAndroid Build Coastguard Worker   // for using the context later).
598*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::CreateContextForClassLoader(
599*795d594fSAndroid Build Coastguard Worker       class_loader,
600*795d594fSAndroid Build Coastguard Worker       dex_elements);
601*795d594fSAndroid Build Coastguard Worker   if (context == nullptr) {
602*795d594fSAndroid Build Coastguard Worker     LOG(ERROR) << "Could not create class loader context for " << vdex_path;
603*795d594fSAndroid Build Coastguard Worker     return dex_files;
604*795d594fSAndroid Build Coastguard Worker   }
605*795d594fSAndroid Build Coastguard Worker   DCHECK(context->OpenDexFiles())
606*795d594fSAndroid Build Coastguard Worker       << "Context created from already opened dex files should not attempt to open again";
607*795d594fSAndroid Build Coastguard Worker 
608*795d594fSAndroid Build Coastguard Worker   // Initialize an OatFile instance backed by the loaded vdex.
609*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<OatFile> oat_file(OatFile::OpenFromVdex(MakeNonOwningPointerVector(dex_files),
610*795d594fSAndroid Build Coastguard Worker                                                           std::move(vdex_file),
611*795d594fSAndroid Build Coastguard Worker                                                           dex_location,
612*795d594fSAndroid Build Coastguard Worker                                                           context.get()));
613*795d594fSAndroid Build Coastguard Worker   if (oat_file != nullptr) {
614*795d594fSAndroid Build Coastguard Worker     VLOG(class_linker) << "Registering " << oat_file->GetLocation();
615*795d594fSAndroid Build Coastguard Worker     *out_oat_file = RegisterOatFile(std::move(oat_file));
616*795d594fSAndroid Build Coastguard Worker   }
617*795d594fSAndroid Build Coastguard Worker   return dex_files;
618*795d594fSAndroid Build Coastguard Worker }
619*795d594fSAndroid Build Coastguard Worker 
620*795d594fSAndroid Build Coastguard Worker // Check how many vdex files exist in the same directory as the vdex file we are about
621*795d594fSAndroid Build Coastguard Worker // to write. If more than or equal to kAnonymousVdexCacheSize, unlink the least
622*795d594fSAndroid Build Coastguard Worker // recently used one(s) (according to stat-reported atime).
UnlinkLeastRecentlyUsedVdexIfNeeded(const std::string & vdex_path_to_add,std::string * error_msg)623*795d594fSAndroid Build Coastguard Worker static bool UnlinkLeastRecentlyUsedVdexIfNeeded(const std::string& vdex_path_to_add,
624*795d594fSAndroid Build Coastguard Worker                                                 std::string* error_msg) {
625*795d594fSAndroid Build Coastguard Worker   std::string basename = android::base::Basename(vdex_path_to_add);
626*795d594fSAndroid Build Coastguard Worker   if (!OatFileAssistant::IsAnonymousVdexBasename(basename)) {
627*795d594fSAndroid Build Coastguard Worker     // File is not for in memory dex files.
628*795d594fSAndroid Build Coastguard Worker     return true;
629*795d594fSAndroid Build Coastguard Worker   }
630*795d594fSAndroid Build Coastguard Worker 
631*795d594fSAndroid Build Coastguard Worker   if (OS::FileExists(vdex_path_to_add.c_str())) {
632*795d594fSAndroid Build Coastguard Worker     // File already exists and will be overwritten.
633*795d594fSAndroid Build Coastguard Worker     // This will not change the number of entries in the cache.
634*795d594fSAndroid Build Coastguard Worker     return true;
635*795d594fSAndroid Build Coastguard Worker   }
636*795d594fSAndroid Build Coastguard Worker 
637*795d594fSAndroid Build Coastguard Worker   auto last_slash = vdex_path_to_add.rfind('/');
638*795d594fSAndroid Build Coastguard Worker   CHECK(last_slash != std::string::npos);
639*795d594fSAndroid Build Coastguard Worker   std::string vdex_dir = vdex_path_to_add.substr(0, last_slash + 1);
640*795d594fSAndroid Build Coastguard Worker 
641*795d594fSAndroid Build Coastguard Worker   if (!OS::DirectoryExists(vdex_dir.c_str())) {
642*795d594fSAndroid Build Coastguard Worker     // Folder does not exist yet. Cache has zero entries.
643*795d594fSAndroid Build Coastguard Worker     return true;
644*795d594fSAndroid Build Coastguard Worker   }
645*795d594fSAndroid Build Coastguard Worker 
646*795d594fSAndroid Build Coastguard Worker   std::vector<std::pair<time_t, std::string>> cache;
647*795d594fSAndroid Build Coastguard Worker 
648*795d594fSAndroid Build Coastguard Worker   DIR* c_dir = opendir(vdex_dir.c_str());
649*795d594fSAndroid Build Coastguard Worker   if (c_dir == nullptr) {
650*795d594fSAndroid Build Coastguard Worker     *error_msg = "Unable to open " + vdex_dir + " to delete unused vdex files";
651*795d594fSAndroid Build Coastguard Worker     return false;
652*795d594fSAndroid Build Coastguard Worker   }
653*795d594fSAndroid Build Coastguard Worker   for (struct dirent* de = readdir(c_dir); de != nullptr; de = readdir(c_dir)) {
654*795d594fSAndroid Build Coastguard Worker     if (de->d_type != DT_REG) {
655*795d594fSAndroid Build Coastguard Worker       continue;
656*795d594fSAndroid Build Coastguard Worker     }
657*795d594fSAndroid Build Coastguard Worker     basename = de->d_name;
658*795d594fSAndroid Build Coastguard Worker     if (!OatFileAssistant::IsAnonymousVdexBasename(basename)) {
659*795d594fSAndroid Build Coastguard Worker       continue;
660*795d594fSAndroid Build Coastguard Worker     }
661*795d594fSAndroid Build Coastguard Worker     std::string fullname = vdex_dir + basename;
662*795d594fSAndroid Build Coastguard Worker 
663*795d594fSAndroid Build Coastguard Worker     struct stat s;
664*795d594fSAndroid Build Coastguard Worker     int rc = TEMP_FAILURE_RETRY(stat(fullname.c_str(), &s));
665*795d594fSAndroid Build Coastguard Worker     if (rc == -1) {
666*795d594fSAndroid Build Coastguard Worker       *error_msg = "Failed to stat() anonymous vdex file " + fullname;
667*795d594fSAndroid Build Coastguard Worker       return false;
668*795d594fSAndroid Build Coastguard Worker     }
669*795d594fSAndroid Build Coastguard Worker 
670*795d594fSAndroid Build Coastguard Worker     cache.push_back(std::make_pair(s.st_atime, fullname));
671*795d594fSAndroid Build Coastguard Worker   }
672*795d594fSAndroid Build Coastguard Worker   CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory.";
673*795d594fSAndroid Build Coastguard Worker 
674*795d594fSAndroid Build Coastguard Worker   if (cache.size() < OatFileManager::kAnonymousVdexCacheSize) {
675*795d594fSAndroid Build Coastguard Worker     return true;
676*795d594fSAndroid Build Coastguard Worker   }
677*795d594fSAndroid Build Coastguard Worker 
678*795d594fSAndroid Build Coastguard Worker   std::sort(cache.begin(),
679*795d594fSAndroid Build Coastguard Worker             cache.end(),
680*795d594fSAndroid Build Coastguard Worker             [](const auto& a, const auto& b) { return a.first < b.first; });
681*795d594fSAndroid Build Coastguard Worker   for (size_t i = OatFileManager::kAnonymousVdexCacheSize - 1; i < cache.size(); ++i) {
682*795d594fSAndroid Build Coastguard Worker     if (unlink(cache[i].second.c_str()) != 0) {
683*795d594fSAndroid Build Coastguard Worker       *error_msg = "Could not unlink anonymous vdex file " + cache[i].second;
684*795d594fSAndroid Build Coastguard Worker       return false;
685*795d594fSAndroid Build Coastguard Worker     }
686*795d594fSAndroid Build Coastguard Worker   }
687*795d594fSAndroid Build Coastguard Worker 
688*795d594fSAndroid Build Coastguard Worker   return true;
689*795d594fSAndroid Build Coastguard Worker }
690*795d594fSAndroid Build Coastguard Worker 
691*795d594fSAndroid Build Coastguard Worker class BackgroundVerificationTask final : public Task {
692*795d594fSAndroid Build Coastguard Worker  public:
BackgroundVerificationTask(const std::vector<const DexFile * > & dex_files,jobject class_loader,const std::string & vdex_path)693*795d594fSAndroid Build Coastguard Worker   BackgroundVerificationTask(const std::vector<const DexFile*>& dex_files,
694*795d594fSAndroid Build Coastguard Worker                              jobject class_loader,
695*795d594fSAndroid Build Coastguard Worker                              const std::string& vdex_path)
696*795d594fSAndroid Build Coastguard Worker       : dex_files_(dex_files),
697*795d594fSAndroid Build Coastguard Worker         vdex_path_(vdex_path) {
698*795d594fSAndroid Build Coastguard Worker     Thread* const self = Thread::Current();
699*795d594fSAndroid Build Coastguard Worker     ScopedObjectAccess soa(self);
700*795d594fSAndroid Build Coastguard Worker     // Create a global ref for `class_loader` because it will be accessed from a different thread.
701*795d594fSAndroid Build Coastguard Worker     class_loader_ = soa.Vm()->AddGlobalRef(self, soa.Decode<mirror::ClassLoader>(class_loader));
702*795d594fSAndroid Build Coastguard Worker     CHECK(class_loader_ != nullptr);
703*795d594fSAndroid Build Coastguard Worker   }
704*795d594fSAndroid Build Coastguard Worker 
~BackgroundVerificationTask()705*795d594fSAndroid Build Coastguard Worker   ~BackgroundVerificationTask() {
706*795d594fSAndroid Build Coastguard Worker     Thread* const self = Thread::Current();
707*795d594fSAndroid Build Coastguard Worker     ScopedObjectAccess soa(self);
708*795d594fSAndroid Build Coastguard Worker     soa.Vm()->DeleteGlobalRef(self, class_loader_);
709*795d594fSAndroid Build Coastguard Worker   }
710*795d594fSAndroid Build Coastguard Worker 
Run(Thread * self)711*795d594fSAndroid Build Coastguard Worker   void Run(Thread* self) override {
712*795d594fSAndroid Build Coastguard Worker     std::string error_msg;
713*795d594fSAndroid Build Coastguard Worker     ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
714*795d594fSAndroid Build Coastguard Worker     verifier::VerifierDeps verifier_deps(dex_files_);
715*795d594fSAndroid Build Coastguard Worker 
716*795d594fSAndroid Build Coastguard Worker     // Iterate over all classes and verify them.
717*795d594fSAndroid Build Coastguard Worker     for (const DexFile* dex_file : dex_files_) {
718*795d594fSAndroid Build Coastguard Worker       for (uint32_t cdef_idx = 0; cdef_idx < dex_file->NumClassDefs(); cdef_idx++) {
719*795d594fSAndroid Build Coastguard Worker         const dex::ClassDef& class_def = dex_file->GetClassDef(cdef_idx);
720*795d594fSAndroid Build Coastguard Worker 
721*795d594fSAndroid Build Coastguard Worker         // Take handles inside the loop. The background verification is low priority
722*795d594fSAndroid Build Coastguard Worker         // and we want to minimize the risk of blocking anyone else.
723*795d594fSAndroid Build Coastguard Worker         ScopedObjectAccess soa(self);
724*795d594fSAndroid Build Coastguard Worker         StackHandleScope<2> hs(self);
725*795d594fSAndroid Build Coastguard Worker         Handle<mirror::ClassLoader> h_loader(hs.NewHandle(
726*795d594fSAndroid Build Coastguard Worker             soa.Decode<mirror::ClassLoader>(class_loader_)));
727*795d594fSAndroid Build Coastguard Worker         Handle<mirror::Class> h_class =
728*795d594fSAndroid Build Coastguard Worker             hs.NewHandle(class_linker->FindClass(self, *dex_file, class_def.class_idx_, h_loader));
729*795d594fSAndroid Build Coastguard Worker 
730*795d594fSAndroid Build Coastguard Worker         if (h_class == nullptr) {
731*795d594fSAndroid Build Coastguard Worker           DCHECK(self->IsExceptionPending());
732*795d594fSAndroid Build Coastguard Worker           self->ClearException();
733*795d594fSAndroid Build Coastguard Worker           continue;
734*795d594fSAndroid Build Coastguard Worker         }
735*795d594fSAndroid Build Coastguard Worker 
736*795d594fSAndroid Build Coastguard Worker         if (&h_class->GetDexFile() != dex_file) {
737*795d594fSAndroid Build Coastguard Worker           // There is a different class in the class path or a parent class loader
738*795d594fSAndroid Build Coastguard Worker           // with the same descriptor. This `h_class` is not resolvable, skip it.
739*795d594fSAndroid Build Coastguard Worker           continue;
740*795d594fSAndroid Build Coastguard Worker         }
741*795d594fSAndroid Build Coastguard Worker 
742*795d594fSAndroid Build Coastguard Worker         DCHECK(h_class->IsResolved()) << h_class->PrettyDescriptor();
743*795d594fSAndroid Build Coastguard Worker         class_linker->VerifyClass(self, &verifier_deps, h_class);
744*795d594fSAndroid Build Coastguard Worker         if (self->IsExceptionPending()) {
745*795d594fSAndroid Build Coastguard Worker           // ClassLinker::VerifyClass can throw, but the exception isn't useful here.
746*795d594fSAndroid Build Coastguard Worker           self->ClearException();
747*795d594fSAndroid Build Coastguard Worker         }
748*795d594fSAndroid Build Coastguard Worker 
749*795d594fSAndroid Build Coastguard Worker         DCHECK(h_class->IsVerified() || h_class->IsErroneous())
750*795d594fSAndroid Build Coastguard Worker             << h_class->PrettyDescriptor() << ": state=" << h_class->GetStatus();
751*795d594fSAndroid Build Coastguard Worker 
752*795d594fSAndroid Build Coastguard Worker         if (h_class->IsVerified()) {
753*795d594fSAndroid Build Coastguard Worker           verifier_deps.RecordClassVerified(*dex_file, class_def);
754*795d594fSAndroid Build Coastguard Worker         }
755*795d594fSAndroid Build Coastguard Worker       }
756*795d594fSAndroid Build Coastguard Worker     }
757*795d594fSAndroid Build Coastguard Worker 
758*795d594fSAndroid Build Coastguard Worker     // Delete old vdex files if there are too many in the folder.
759*795d594fSAndroid Build Coastguard Worker     if (!UnlinkLeastRecentlyUsedVdexIfNeeded(vdex_path_, &error_msg)) {
760*795d594fSAndroid Build Coastguard Worker       LOG(ERROR) << "Could not unlink old vdex files " << vdex_path_ << ": " << error_msg;
761*795d594fSAndroid Build Coastguard Worker       return;
762*795d594fSAndroid Build Coastguard Worker     }
763*795d594fSAndroid Build Coastguard Worker 
764*795d594fSAndroid Build Coastguard Worker     // Construct a vdex file and write `verifier_deps` into it.
765*795d594fSAndroid Build Coastguard Worker     if (!VdexFile::WriteToDisk(vdex_path_,
766*795d594fSAndroid Build Coastguard Worker                                dex_files_,
767*795d594fSAndroid Build Coastguard Worker                                verifier_deps,
768*795d594fSAndroid Build Coastguard Worker                                &error_msg)) {
769*795d594fSAndroid Build Coastguard Worker       LOG(ERROR) << "Could not write anonymous vdex " << vdex_path_ << ": " << error_msg;
770*795d594fSAndroid Build Coastguard Worker       return;
771*795d594fSAndroid Build Coastguard Worker     }
772*795d594fSAndroid Build Coastguard Worker   }
773*795d594fSAndroid Build Coastguard Worker 
Finalize()774*795d594fSAndroid Build Coastguard Worker   void Finalize() override {
775*795d594fSAndroid Build Coastguard Worker     delete this;
776*795d594fSAndroid Build Coastguard Worker   }
777*795d594fSAndroid Build Coastguard Worker 
778*795d594fSAndroid Build Coastguard Worker  private:
779*795d594fSAndroid Build Coastguard Worker   const std::vector<const DexFile*> dex_files_;
780*795d594fSAndroid Build Coastguard Worker   jobject class_loader_;
781*795d594fSAndroid Build Coastguard Worker   const std::string vdex_path_;
782*795d594fSAndroid Build Coastguard Worker 
783*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(BackgroundVerificationTask);
784*795d594fSAndroid Build Coastguard Worker };
785*795d594fSAndroid Build Coastguard Worker 
RunBackgroundVerification(const std::vector<const DexFile * > & dex_files,jobject class_loader)786*795d594fSAndroid Build Coastguard Worker void OatFileManager::RunBackgroundVerification(const std::vector<const DexFile*>& dex_files,
787*795d594fSAndroid Build Coastguard Worker                                                jobject class_loader) {
788*795d594fSAndroid Build Coastguard Worker   Runtime* const runtime = Runtime::Current();
789*795d594fSAndroid Build Coastguard Worker   Thread* const self = Thread::Current();
790*795d594fSAndroid Build Coastguard Worker 
791*795d594fSAndroid Build Coastguard Worker   if (runtime->IsJavaDebuggable()) {
792*795d594fSAndroid Build Coastguard Worker     // Threads created by ThreadPool ("runtime threads") are not allowed to load
793*795d594fSAndroid Build Coastguard Worker     // classes when debuggable to match class-initialization semantics
794*795d594fSAndroid Build Coastguard Worker     // expectations. Do not verify in the background.
795*795d594fSAndroid Build Coastguard Worker     return;
796*795d594fSAndroid Build Coastguard Worker   }
797*795d594fSAndroid Build Coastguard Worker 
798*795d594fSAndroid Build Coastguard Worker   {
799*795d594fSAndroid Build Coastguard Worker     // Temporarily create a class loader context to see if we recognize the
800*795d594fSAndroid Build Coastguard Worker     // chain.
801*795d594fSAndroid Build Coastguard Worker     std::unique_ptr<ClassLoaderContext> context(
802*795d594fSAndroid Build Coastguard Worker         ClassLoaderContext::CreateContextForClassLoader(class_loader, nullptr));
803*795d594fSAndroid Build Coastguard Worker     if (context == nullptr) {
804*795d594fSAndroid Build Coastguard Worker       // We only run background verification for class loaders we know the lookup
805*795d594fSAndroid Build Coastguard Worker       // chain. Because the background verification runs on runtime threads,
806*795d594fSAndroid Build Coastguard Worker       // which do not call Java, we won't be able to load classes when
807*795d594fSAndroid Build Coastguard Worker       // verifying, which is something the current verifier relies on.
808*795d594fSAndroid Build Coastguard Worker       return;
809*795d594fSAndroid Build Coastguard Worker     }
810*795d594fSAndroid Build Coastguard Worker   }
811*795d594fSAndroid Build Coastguard Worker 
812*795d594fSAndroid Build Coastguard Worker   if (!IsSdkVersionSetAndAtLeast(runtime->GetTargetSdkVersion(), SdkVersion::kQ)) {
813*795d594fSAndroid Build Coastguard Worker     // Do not run for legacy apps as they may depend on the previous class loader behaviour.
814*795d594fSAndroid Build Coastguard Worker     return;
815*795d594fSAndroid Build Coastguard Worker   }
816*795d594fSAndroid Build Coastguard Worker 
817*795d594fSAndroid Build Coastguard Worker   if (runtime->IsShuttingDown(self)) {
818*795d594fSAndroid Build Coastguard Worker     // Not allowed to create new threads during runtime shutdown.
819*795d594fSAndroid Build Coastguard Worker     return;
820*795d594fSAndroid Build Coastguard Worker   }
821*795d594fSAndroid Build Coastguard Worker 
822*795d594fSAndroid Build Coastguard Worker   if (dex_files.size() < 1) {
823*795d594fSAndroid Build Coastguard Worker     // Nothing to verify.
824*795d594fSAndroid Build Coastguard Worker     return;
825*795d594fSAndroid Build Coastguard Worker   }
826*795d594fSAndroid Build Coastguard Worker 
827*795d594fSAndroid Build Coastguard Worker   std::string dex_location = dex_files[0]->GetLocation();
828*795d594fSAndroid Build Coastguard Worker   const std::string& data_dir = Runtime::Current()->GetProcessDataDirectory();
829*795d594fSAndroid Build Coastguard Worker   if (!dex_location.starts_with(data_dir)) {
830*795d594fSAndroid Build Coastguard Worker     // For now, we only run background verification for secondary dex files.
831*795d594fSAndroid Build Coastguard Worker     // Running it for primary or split APKs could have some undesirable
832*795d594fSAndroid Build Coastguard Worker     // side-effects, like overloading the device on app startup.
833*795d594fSAndroid Build Coastguard Worker     return;
834*795d594fSAndroid Build Coastguard Worker   }
835*795d594fSAndroid Build Coastguard Worker 
836*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
837*795d594fSAndroid Build Coastguard Worker   std::string odex_filename;
838*795d594fSAndroid Build Coastguard Worker   if (!OatFileAssistant::DexLocationToOdexFilename(dex_location,
839*795d594fSAndroid Build Coastguard Worker                                                    kRuntimeQuickCodeISA,
840*795d594fSAndroid Build Coastguard Worker                                                    &odex_filename,
841*795d594fSAndroid Build Coastguard Worker                                                    &error_msg)) {
842*795d594fSAndroid Build Coastguard Worker     LOG(WARNING) << "Could not get odex filename for " << dex_location << ": " << error_msg;
843*795d594fSAndroid Build Coastguard Worker     return;
844*795d594fSAndroid Build Coastguard Worker   }
845*795d594fSAndroid Build Coastguard Worker 
846*795d594fSAndroid Build Coastguard Worker   if (LocationIsOnArtApexData(odex_filename) && Runtime::Current()->DenyArtApexDataFiles()) {
847*795d594fSAndroid Build Coastguard Worker     // Ignore vdex file associated with this odex file as the odex file is not trustworthy.
848*795d594fSAndroid Build Coastguard Worker     return;
849*795d594fSAndroid Build Coastguard Worker   }
850*795d594fSAndroid Build Coastguard Worker 
851*795d594fSAndroid Build Coastguard Worker   {
852*795d594fSAndroid Build Coastguard Worker     WriterMutexLock mu(self, *Locks::oat_file_manager_lock_);
853*795d594fSAndroid Build Coastguard Worker     if (verification_thread_pool_ == nullptr) {
854*795d594fSAndroid Build Coastguard Worker       verification_thread_pool_.reset(
855*795d594fSAndroid Build Coastguard Worker           ThreadPool::Create("Verification thread pool", /* num_threads= */ 1));
856*795d594fSAndroid Build Coastguard Worker       verification_thread_pool_->StartWorkers(self);
857*795d594fSAndroid Build Coastguard Worker     }
858*795d594fSAndroid Build Coastguard Worker   }
859*795d594fSAndroid Build Coastguard Worker   verification_thread_pool_->AddTask(self, new BackgroundVerificationTask(
860*795d594fSAndroid Build Coastguard Worker       dex_files,
861*795d594fSAndroid Build Coastguard Worker       class_loader,
862*795d594fSAndroid Build Coastguard Worker       GetVdexFilename(odex_filename)));
863*795d594fSAndroid Build Coastguard Worker }
864*795d594fSAndroid Build Coastguard Worker 
WaitForWorkersToBeCreated()865*795d594fSAndroid Build Coastguard Worker void OatFileManager::WaitForWorkersToBeCreated() {
866*795d594fSAndroid Build Coastguard Worker   DCHECK(!Runtime::Current()->IsShuttingDown(Thread::Current()))
867*795d594fSAndroid Build Coastguard Worker       << "Cannot create new threads during runtime shutdown";
868*795d594fSAndroid Build Coastguard Worker   if (verification_thread_pool_ != nullptr) {
869*795d594fSAndroid Build Coastguard Worker     verification_thread_pool_->WaitForWorkersToBeCreated();
870*795d594fSAndroid Build Coastguard Worker   }
871*795d594fSAndroid Build Coastguard Worker }
872*795d594fSAndroid Build Coastguard Worker 
DeleteThreadPool()873*795d594fSAndroid Build Coastguard Worker void OatFileManager::DeleteThreadPool() {
874*795d594fSAndroid Build Coastguard Worker   verification_thread_pool_.reset(nullptr);
875*795d594fSAndroid Build Coastguard Worker }
876*795d594fSAndroid Build Coastguard Worker 
WaitForBackgroundVerificationTasksToFinish()877*795d594fSAndroid Build Coastguard Worker void OatFileManager::WaitForBackgroundVerificationTasksToFinish() {
878*795d594fSAndroid Build Coastguard Worker   if (verification_thread_pool_ == nullptr) {
879*795d594fSAndroid Build Coastguard Worker     return;
880*795d594fSAndroid Build Coastguard Worker   }
881*795d594fSAndroid Build Coastguard Worker 
882*795d594fSAndroid Build Coastguard Worker   Thread* const self = Thread::Current();
883*795d594fSAndroid Build Coastguard Worker   verification_thread_pool_->Wait(self, /* do_work= */ true, /* may_hold_locks= */ false);
884*795d594fSAndroid Build Coastguard Worker }
885*795d594fSAndroid Build Coastguard Worker 
WaitForBackgroundVerificationTasks()886*795d594fSAndroid Build Coastguard Worker void OatFileManager::WaitForBackgroundVerificationTasks() {
887*795d594fSAndroid Build Coastguard Worker   if (verification_thread_pool_ != nullptr) {
888*795d594fSAndroid Build Coastguard Worker     Thread* const self = Thread::Current();
889*795d594fSAndroid Build Coastguard Worker     verification_thread_pool_->WaitForWorkersToBeCreated();
890*795d594fSAndroid Build Coastguard Worker     verification_thread_pool_->Wait(self, /* do_work= */ true, /* may_hold_locks= */ false);
891*795d594fSAndroid Build Coastguard Worker   }
892*795d594fSAndroid Build Coastguard Worker }
893*795d594fSAndroid Build Coastguard Worker 
ClearOnlyUseTrustedOatFiles()894*795d594fSAndroid Build Coastguard Worker void OatFileManager::ClearOnlyUseTrustedOatFiles() {
895*795d594fSAndroid Build Coastguard Worker   only_use_system_oat_files_ = false;
896*795d594fSAndroid Build Coastguard Worker }
897*795d594fSAndroid Build Coastguard Worker 
SetOnlyUseTrustedOatFiles()898*795d594fSAndroid Build Coastguard Worker void OatFileManager::SetOnlyUseTrustedOatFiles() {
899*795d594fSAndroid Build Coastguard Worker   ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
900*795d594fSAndroid Build Coastguard Worker   if (!oat_files_.empty()) {
901*795d594fSAndroid Build Coastguard Worker     LOG(FATAL) << "Unexpected non-empty loaded oat files ";
902*795d594fSAndroid Build Coastguard Worker   }
903*795d594fSAndroid Build Coastguard Worker   only_use_system_oat_files_ = true;
904*795d594fSAndroid Build Coastguard Worker }
905*795d594fSAndroid Build Coastguard Worker 
DumpForSigQuit(std::ostream & os)906*795d594fSAndroid Build Coastguard Worker void OatFileManager::DumpForSigQuit(std::ostream& os) {
907*795d594fSAndroid Build Coastguard Worker   ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
908*795d594fSAndroid Build Coastguard Worker   std::vector<const OatFile*> boot_oat_files = GetBootOatFiles();
909*795d594fSAndroid Build Coastguard Worker   for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
910*795d594fSAndroid Build Coastguard Worker     if (ContainsElement(boot_oat_files, oat_file.get())) {
911*795d594fSAndroid Build Coastguard Worker       continue;
912*795d594fSAndroid Build Coastguard Worker     }
913*795d594fSAndroid Build Coastguard Worker     os << oat_file->GetLocation() << ": " << oat_file->GetCompilerFilter() << "\n";
914*795d594fSAndroid Build Coastguard Worker   }
915*795d594fSAndroid Build Coastguard Worker }
916*795d594fSAndroid Build Coastguard Worker 
ContainsPc(const void * code)917*795d594fSAndroid Build Coastguard Worker bool OatFileManager::ContainsPc(const void* code) {
918*795d594fSAndroid Build Coastguard Worker   ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
919*795d594fSAndroid Build Coastguard Worker   std::vector<const OatFile*> boot_oat_files = GetBootOatFiles();
920*795d594fSAndroid Build Coastguard Worker   for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
921*795d594fSAndroid Build Coastguard Worker     if (oat_file->Contains(code)) {
922*795d594fSAndroid Build Coastguard Worker       return true;
923*795d594fSAndroid Build Coastguard Worker     }
924*795d594fSAndroid Build Coastguard Worker   }
925*795d594fSAndroid Build Coastguard Worker   return false;
926*795d594fSAndroid Build Coastguard Worker }
927*795d594fSAndroid Build Coastguard Worker 
928*795d594fSAndroid Build Coastguard Worker }  // namespace art
929