blob: 635122038a2b6e3eac08ea11e7e4e8c17b5e26d2 [file] [log] [blame]
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "oat_file_manager.h"
18
19#include <memory>
20#include <queue>
21#include <vector>
David Brazdil35a3f6a2019-03-04 15:59:06 +000022#include <sys/stat.h>
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070023
Nicolas Geoffray9bc364b2021-03-29 10:41:39 +010024#include "android-base/file.h"
Andreas Gampe46ee31b2016-12-14 10:11:49 -080025#include "android-base/stringprintf.h"
Nicolas Geoffray68bf3902017-09-07 14:40:48 +010026#include "android-base/strings.h"
Andreas Gampe46ee31b2016-12-14 10:11:49 -080027
Andreas Gampe90b936d2017-01-31 08:58:55 -080028#include "art_field-inl.h"
Jeff Hao8ec0a202017-03-07 21:56:31 -080029#include "base/bit_vector-inl.h"
David Sehr891a50e2017-10-27 17:01:07 -070030#include "base/file_utils.h"
Andreas Gampe57943812017-12-06 21:39:13 -080031#include "base/logging.h" // For VLOG.
Andreas Gampe7fbc4a52018-11-28 08:26:47 -080032#include "base/mutex-inl.h"
David Brazdil527072e2019-04-03 15:15:40 +010033#include "base/sdk_version.h"
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070034#include "base/stl_util.h"
Mathieu Chartier32ce2ad2016-03-04 14:58:03 -080035#include "base/systrace.h"
Mathieu Chartierfbc31082016-01-24 11:59:56 -080036#include "class_linker.h"
Calin Juravle7b0648a2017-07-07 18:40:50 -070037#include "class_loader_context.h"
David Sehr013fd802018-01-11 22:55:24 -080038#include "dex/art_dex_file_loader.h"
David Sehr9e734c72018-01-04 17:56:19 -080039#include "dex/dex_file-inl.h"
40#include "dex/dex_file_loader.h"
41#include "dex/dex_file_tracking_registrar.h"
Mathieu Chartier61d2b2d2016-02-04 13:31:46 -080042#include "gc/scoped_gc_critical_section.h"
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070043#include "gc/space/image_space.h"
Mathieu Chartierfbc31082016-01-24 11:59:56 -080044#include "handle_scope-inl.h"
Nicolas Geoffray9ac09ee2019-05-08 23:38:27 +010045#include "jit/jit.h"
David Brazdil331a5e12019-04-01 22:46:16 +000046#include "jni/java_vm_ext.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010047#include "jni/jni_internal.h"
Mathieu Chartierfbc31082016-01-24 11:59:56 -080048#include "mirror/class_loader.h"
Andreas Gampe90b936d2017-01-31 08:58:55 -080049#include "mirror/object-inl.h"
Alex Light2ce6fc82017-12-18 16:42:36 -080050#include "oat_file.h"
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070051#include "oat_file_assistant.h"
Mathieu Chartier3398c782016-09-30 10:27:43 -070052#include "obj_ptr-inl.h"
Nicolas Geoffray5d3a23d2022-12-08 14:51:25 +000053#include "runtime_image.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070054#include "scoped_thread_state_change-inl.h"
Andreas Gampeb486a982017-06-01 13:45:54 -070055#include "thread-current-inl.h"
Mathieu Chartiera9d82fe2016-01-25 20:06:11 -080056#include "thread_list.h"
David Brazdil331a5e12019-04-01 22:46:16 +000057#include "thread_pool.h"
David Brazdil35a3f6a2019-03-04 15:59:06 +000058#include "vdex_file.h"
59#include "verifier/verifier_deps.h"
Andreas Gampe90b936d2017-01-31 08:58:55 -080060#include "well_known_classes.h"
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070061
62namespace art {
63
Andreas Gampe46ee31b2016-12-14 10:11:49 -080064using android::base::StringPrintf;
65
Mathieu Chartier120aa282017-08-05 16:03:03 -070066// If true, we attempt to load the application image if it exists.
Mathieu Chartierfbc31082016-01-24 11:59:56 -080067static constexpr bool kEnableAppImage = true;
68
Nicolas Geoffrayea55f3d2021-09-07 12:16:56 +010069const OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oat_file,
70 bool in_memory) {
Nicolas Geoffray1d4f0092020-08-07 14:01:05 +010071 // Use class_linker vlog to match the log for dex file registration.
72 VLOG(class_linker) << "Registered oat file " << oat_file->GetLocation();
Nicolas Geoffray4f6bb442021-06-02 18:05:51 +010073 PaletteNotifyOatFileLoaded(oat_file->GetLocation().c_str());
Nicolas Geoffray1d4f0092020-08-07 14:01:05 +010074
Mathieu Chartiere58991b2015-10-13 07:59:34 -070075 WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
Nicolas Geoffrayea55f3d2021-09-07 12:16:56 +010076 CHECK(in_memory ||
77 !only_use_system_oat_files_ ||
Orion Hodson971068d2021-06-30 21:17:53 +010078 LocationIsTrusted(oat_file->GetLocation(), !Runtime::Current()->DenyArtApexDataFiles()) ||
Nicolas Geoffray29742602017-12-14 10:09:03 +000079 !oat_file->IsExecutable())
Nicolas Geoffrayea55f3d2021-09-07 12:16:56 +010080 << "Registering a non /system oat file: " << oat_file->GetLocation() << " android-root="
81 << GetAndroidRoot();
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070082 DCHECK(oat_file != nullptr);
83 if (kIsDebugBuild) {
Mathieu Chartiere58991b2015-10-13 07:59:34 -070084 CHECK(oat_files_.find(oat_file) == oat_files_.end());
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070085 for (const std::unique_ptr<const OatFile>& existing : oat_files_) {
86 CHECK_NE(oat_file.get(), existing.get()) << oat_file->GetLocation();
87 // Check that we don't have an oat file with the same address. Copies of the same oat file
88 // should be loaded at different addresses.
89 CHECK_NE(oat_file->Begin(), existing->Begin()) << "Oat file already mapped at that location";
90 }
91 }
Mathieu Chartiere58991b2015-10-13 07:59:34 -070092 const OatFile* ret = oat_file.get();
93 oat_files_.insert(std::move(oat_file));
94 return ret;
95}
96
97void OatFileManager::UnRegisterAndDeleteOatFile(const OatFile* oat_file) {
98 WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
99 DCHECK(oat_file != nullptr);
100 std::unique_ptr<const OatFile> compare(oat_file);
101 auto it = oat_files_.find(compare);
102 CHECK(it != oat_files_.end());
103 oat_files_.erase(it);
Andreas Gampeafaf7f82018-10-16 11:32:38 -0700104 compare.release(); // NOLINT b/117926937
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700105}
106
Calin Juravle0b791272016-04-18 16:38:27 +0100107const OatFile* OatFileManager::FindOpenedOatFileFromDexLocation(
108 const std::string& dex_base_location) const {
109 ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
110 for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
111 const std::vector<const OatDexFile*>& oat_dex_files = oat_file->GetOatDexFiles();
112 for (const OatDexFile* oat_dex_file : oat_dex_files) {
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700113 if (DexFileLoader::GetBaseLocation(oat_dex_file->GetDexFileLocation()) == dex_base_location) {
Calin Juravle0b791272016-04-18 16:38:27 +0100114 return oat_file.get();
115 }
116 }
117 }
118 return nullptr;
119}
120
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700121const OatFile* OatFileManager::FindOpenedOatFileFromOatLocation(const std::string& oat_location)
122 const {
123 ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700124 return FindOpenedOatFileFromOatLocationLocked(oat_location);
125}
126
127const OatFile* OatFileManager::FindOpenedOatFileFromOatLocationLocked(
128 const std::string& oat_location) const {
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700129 for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
130 if (oat_file->GetLocation() == oat_location) {
131 return oat_file.get();
132 }
133 }
134 return nullptr;
135}
136
Jeff Haodcdc85b2015-12-04 14:06:18 -0800137std::vector<const OatFile*> OatFileManager::GetBootOatFiles() const {
Jeff Haodcdc85b2015-12-04 14:06:18 -0800138 std::vector<gc::space::ImageSpace*> image_spaces =
139 Runtime::Current()->GetHeap()->GetBootImageSpaces();
Andreas Gampe2a487eb2018-11-19 11:41:22 -0800140 std::vector<const OatFile*> oat_files;
141 oat_files.reserve(image_spaces.size());
Jeff Haodcdc85b2015-12-04 14:06:18 -0800142 for (gc::space::ImageSpace* image_space : image_spaces) {
143 oat_files.push_back(image_space->GetOatFile());
144 }
145 return oat_files;
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700146}
147
Vladimir Markob0b68cf2017-11-14 18:11:50 +0000148OatFileManager::OatFileManager()
Vladimir Markoe0669322018-09-03 15:44:54 +0100149 : only_use_system_oat_files_(false) {}
Vladimir Markob0b68cf2017-11-14 18:11:50 +0000150
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700151OatFileManager::~OatFileManager() {
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700152 // Explicitly clear oat_files_ since the OatFile destructor calls back into OatFileManager for
153 // UnRegisterOatFileLocation.
154 oat_files_.clear();
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700155}
156
Jeff Haodcdc85b2015-12-04 14:06:18 -0800157std::vector<const OatFile*> OatFileManager::RegisterImageOatFiles(
Stephen Hines48ba1972018-09-24 13:35:54 -0700158 const std::vector<gc::space::ImageSpace*>& spaces) {
Jeff Haodcdc85b2015-12-04 14:06:18 -0800159 std::vector<const OatFile*> oat_files;
Andreas Gampe2a487eb2018-11-19 11:41:22 -0800160 oat_files.reserve(spaces.size());
Jeff Haodcdc85b2015-12-04 14:06:18 -0800161 for (gc::space::ImageSpace* space : spaces) {
Nicolas Geoffrayea55f3d2021-09-07 12:16:56 +0100162 // The oat file was generated in memory if the image space has a profile.
Jiakai Zhangfb8cdb52021-12-06 18:51:28 +0000163 bool in_memory = !space->GetProfileFiles().empty();
Nicolas Geoffrayea55f3d2021-09-07 12:16:56 +0100164 oat_files.push_back(RegisterOatFile(space->ReleaseOatFile(), in_memory));
Jeff Haodcdc85b2015-12-04 14:06:18 -0800165 }
166 return oat_files;
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700167}
168
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100169bool OatFileManager::ShouldLoadAppImage(const OatFile* source_oat_file) const {
Mathieu Chartieradc90862018-05-11 13:03:06 -0700170 Runtime* const runtime = Runtime::Current();
Mythri Allebe282e12022-10-06 12:05:26 +0000171 return kEnableAppImage && (!runtime->IsJavaDebuggableAtInit() || source_oat_file->IsDebuggable());
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700172}
173
174std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
175 const char* dex_location,
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800176 jobject class_loader,
177 jobjectArray dex_elements,
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700178 const OatFile** out_oat_file,
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700179 std::vector<std::string>* error_msgs) {
Calin Juravle98071152021-01-27 18:41:58 -0800180 ScopedTrace trace(StringPrintf("%s(%s)", __FUNCTION__, dex_location));
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700181 CHECK(dex_location != nullptr);
182 CHECK(error_msgs != nullptr);
183
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100184 // Verify we aren't holding the mutator lock, which could starve GC when
185 // hitting the disk.
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800186 Thread* const self = Thread::Current();
187 Locks::mutator_lock_->AssertNotHeld(self);
188 Runtime* const runtime = Runtime::Current();
Calin Juravleb077e152016-02-18 18:47:37 +0000189
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100190 std::vector<std::unique_ptr<const DexFile>> dex_files;
Nicolas Geoffray525fa422021-04-19 07:50:35 +0000191 std::unique_ptr<ClassLoaderContext> context(
192 ClassLoaderContext::CreateContextForClassLoader(class_loader, dex_elements));
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100193
Calin Juravle27e0d1f2017-07-26 00:16:07 -0700194 // If the class_loader is null there's not much we can do. This happens if a dex files is loaded
195 // directly with DexFile APIs instead of using class loaders.
196 if (class_loader == nullptr) {
197 LOG(WARNING) << "Opening an oat file without a class loader. "
198 << "Are you using the deprecated DexFile APIs?";
Nicolas Geoffray525fa422021-04-19 07:50:35 +0000199 } else if (context != nullptr) {
Jiakai Zhang78d86b52022-05-26 17:24:17 +0100200 auto oat_file_assistant = std::make_unique<OatFileAssistant>(dex_location,
201 kRuntimeISA,
202 context.get(),
203 runtime->GetOatFilesExecutable(),
204 only_use_system_oat_files_);
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700205
Calin Juravle98071152021-01-27 18:41:58 -0800206 // Get the current optimization status for trace debugging.
207 // Implementation detail note: GetOptimizationStatus will select the same
208 // oat file as GetBestOatFile used below, and in doing so it already pre-populates
209 // some OatFileAssistant internal fields.
210 std::string odex_location;
211 std::string compilation_filter;
212 std::string compilation_reason;
213 std::string odex_status;
Jiakai Zhang78d86b52022-05-26 17:24:17 +0100214 oat_file_assistant->GetOptimizationStatus(
215 &odex_location, &compilation_filter, &compilation_reason, &odex_status);
Calin Juravle98071152021-01-27 18:41:58 -0800216
217 ScopedTrace odex_loading(StringPrintf(
218 "location=%s status=%s filter=%s reason=%s",
219 odex_location.c_str(),
220 odex_status.c_str(),
221 compilation_filter.c_str(),
222 compilation_reason.c_str()));
223
Jared Duke761f31a2022-06-10 11:18:59 -0700224 const bool has_registered_app_info = Runtime::Current()->GetAppInfo()->HasRegisteredAppInfo();
225 const AppInfo::CodeType code_type =
226 Runtime::Current()->GetAppInfo()->GetRegisteredCodeType(dex_location);
227 // We only want to madvise primary/split dex artifacts as a startup optimization. However,
228 // as the code_type for those artifacts may not be set until the initial app info registration,
229 // we conservatively madvise everything until the app info registration is complete.
230 const bool should_madvise_vdex_and_odex = !has_registered_app_info ||
231 code_type == AppInfo::CodeType::kPrimaryApk ||
232 code_type == AppInfo::CodeType::kSplitApk;
233
Calin Juravle98071152021-01-27 18:41:58 -0800234 // Proceed with oat file loading.
Jiakai Zhang78d86b52022-05-26 17:24:17 +0100235 std::unique_ptr<const OatFile> oat_file(oat_file_assistant->GetBestOatFile().release());
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100236 VLOG(oat) << "OatFileAssistant(" << dex_location << ").GetBestOatFile()="
Nicolas Geoffray16f60dc2021-02-16 15:35:16 +0000237 << (oat_file != nullptr ? oat_file->GetLocation() : "")
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100238 << " (executable=" << (oat_file != nullptr ? oat_file->IsExecutable() : false) << ")";
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800239
Calin Juravle98071152021-01-27 18:41:58 -0800240 CHECK(oat_file == nullptr || odex_location == oat_file->GetLocation())
241 << "OatFileAssistant non-determinism in choosing best oat files. "
242 << "optimization-status-location=" << odex_location
243 << " best_oat_file-location=" << oat_file->GetLocation();
244
Nicolas Geoffray525fa422021-04-19 07:50:35 +0000245 if (oat_file != nullptr) {
Nicolas Geoffray5d3a23d2022-12-08 14:51:25 +0000246 bool compilation_enabled =
247 CompilerFilter::IsAotCompilationEnabled(oat_file->GetCompilerFilter());
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100248 // Load the dex files from the oat file.
249 bool added_image_space = false;
Nicolas Geoffray5d3a23d2022-12-08 14:51:25 +0000250 if (should_madvise_vdex_and_odex) {
251 VLOG(oat) << "Madvising oat file: " << oat_file->GetLocation();
252 size_t madvise_size_limit = runtime->GetMadviseWillNeedSizeOdex();
253 Runtime::MadviseFileForRange(madvise_size_limit,
254 oat_file->Size(),
255 oat_file->Begin(),
256 oat_file->End(),
257 oat_file->GetLocation());
258 }
Jared Duke761f31a2022-06-10 11:18:59 -0700259
Nicolas Geoffray5d3a23d2022-12-08 14:51:25 +0000260 ScopedTrace app_image_timing("AppImage:Loading");
Narayan Kamath5c525742017-04-28 10:19:29 +0100261
Nicolas Geoffray5d3a23d2022-12-08 14:51:25 +0000262 // We need to throw away the image space if we are debuggable but the oat-file source of the
263 // image is not otherwise we might get classes with inlined methods or other such things.
264 std::unique_ptr<gc::space::ImageSpace> image_space;
265 if (ShouldLoadAppImage(oat_file.get())) {
266 if (oat_file->IsExecutable()) {
267 // App images generated by the compiler can only be used if the oat file
268 // is executable.
Jiakai Zhang78d86b52022-05-26 17:24:17 +0100269 image_space = oat_file_assistant->OpenImageSpace(oat_file.get());
Narayan Kamath5c525742017-04-28 10:19:29 +0100270 }
Nicolas Geoffray5d3a23d2022-12-08 14:51:25 +0000271 if (image_space == nullptr && !compilation_enabled) {
272 std::string art_file = RuntimeImage::GetRuntimeImagePath(dex_location);
273 std::string error_msg;
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100274 ScopedObjectAccess soa(self);
Nicolas Geoffray5d3a23d2022-12-08 14:51:25 +0000275 image_space = gc::space::ImageSpace::CreateFromAppImage(
276 art_file.c_str(), oat_file.get(), &error_msg);
277 if (image_space == nullptr) {
278 VLOG(image) << "Could not load runtime generated app image: " << error_msg;
279 }
280 }
281 }
282 if (image_space != nullptr) {
283 ScopedObjectAccess soa(self);
284 StackHandleScope<1> hs(self);
285 Handle<mirror::ClassLoader> h_loader(
286 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
287 // Can not load app image without class loader.
288 if (h_loader != nullptr) {
289 std::string temp_error_msg;
290 // Add image space has a race condition since other threads could be reading from the
291 // spaces array.
292 {
293 ScopedThreadSuspension sts(self, ThreadState::kSuspended);
294 gc::ScopedGCCriticalSection gcs(self,
295 gc::kGcCauseAddRemoveAppImageSpace,
296 gc::kCollectorTypeAddRemoveAppImageSpace);
297 ScopedSuspendAll ssa("Add image space");
298 runtime->GetHeap()->AddSpace(image_space.get());
299 }
300 {
301 ScopedTrace image_space_timing("Adding image space");
302 added_image_space = runtime->GetClassLinker()->AddImageSpace(image_space.get(),
303 h_loader,
304 /*out*/&dex_files,
305 /*out*/&temp_error_msg);
306 }
307 if (added_image_space) {
308 // Successfully added image space to heap, release the map so that it does not get
309 // freed.
310 image_space.release(); // NOLINT b/117926937
311
312 // Register for tracking.
313 for (const auto& dex_file : dex_files) {
314 dex::tracking::RegisterDexFile(dex_file.get());
315 }
316
317 if (!compilation_enabled) {
318 // Update the filter we are going to report to 'speed-profile'.
319 // Ideally, we would also update the compiler filter of the odex
320 // file, but at this point it's just too late.
321 compilation_filter = CompilerFilter::NameOfFilter(CompilerFilter::kSpeedProfile);
322 }
323 } else {
324 LOG(INFO) << "Failed to add image file: " << temp_error_msg;
325 dex_files.clear();
Mathieu Chartiera9d82fe2016-01-25 20:06:11 -0800326 {
Vladimir Markoddf4fd32021-11-22 16:31:57 +0000327 ScopedThreadSuspension sts(self, ThreadState::kSuspended);
Mathieu Chartier61d2b2d2016-02-04 13:31:46 -0800328 gc::ScopedGCCriticalSection gcs(self,
329 gc::kGcCauseAddRemoveAppImageSpace,
330 gc::kCollectorTypeAddRemoveAppImageSpace);
Nicolas Geoffray5d3a23d2022-12-08 14:51:25 +0000331 ScopedSuspendAll ssa("Remove image space");
332 runtime->GetHeap()->RemoveSpace(image_space.get());
Mathieu Chartiera9d82fe2016-01-25 20:06:11 -0800333 }
Nicolas Geoffray5d3a23d2022-12-08 14:51:25 +0000334 // Non-fatal, don't update error_msg.
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800335 }
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800336 }
337 }
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100338 if (!added_image_space) {
339 DCHECK(dex_files.empty());
Eric Holkbc89ed42020-04-29 19:59:24 +0000340
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100341 if (oat_file->RequiresImage()) {
Nicolas Geoffray107d22b2021-05-04 10:57:36 +0100342 LOG(WARNING) << "Loading "
343 << oat_file->GetLocation()
Nicolas Geoffrayfc1ba6d2022-03-23 14:18:23 +0000344 << " non-executable as it requires an image which we failed to load";
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100345 // file as non-executable.
Jiakai Zhang78d86b52022-05-26 17:24:17 +0100346 auto nonexecutable_oat_file_assistant =
347 std::make_unique<OatFileAssistant>(dex_location,
348 kRuntimeISA,
349 context.get(),
350 /*load_executable=*/false,
351 only_use_system_oat_files_);
352 oat_file.reset(nonexecutable_oat_file_assistant->GetBestOatFile().release());
Nicolas Geoffray107d22b2021-05-04 10:57:36 +0100353
354 // The file could be deleted concurrently (for example background
355 // dexopt, or secondary oat file being deleted by the app).
356 if (oat_file == nullptr) {
357 LOG(WARNING) << "Failed to reload oat file non-executable " << dex_location;
358 }
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100359 }
360
Nicolas Geoffray107d22b2021-05-04 10:57:36 +0100361 if (oat_file != nullptr) {
Jiakai Zhang78d86b52022-05-26 17:24:17 +0100362 dex_files = oat_file_assistant->LoadDexFiles(*oat_file.get(), dex_location);
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100363
Nicolas Geoffray107d22b2021-05-04 10:57:36 +0100364 // Register for tracking.
365 for (const auto& dex_file : dex_files) {
366 dex::tracking::RegisterDexFile(dex_file.get());
367 }
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100368 }
369 }
370 if (dex_files.empty()) {
Calin Juravle98071152021-01-27 18:41:58 -0800371 ScopedTrace failed_to_open_dex_files("FailedToOpenDexFilesFromOat");
Nicolas Geoffrayc07e8732021-05-18 14:26:42 +0100372 error_msgs->push_back("Failed to open dex files from " + odex_location);
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100373 } else {
374 // Opened dex files from an oat file, madvise them to their loaded state.
375 for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
Jared Duke95bb9952021-08-11 15:07:25 -0700376 OatDexFile::MadviseDexFileAtLoad(*dex_file);
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100377 }
Eric Holkbc89ed42020-04-29 19:59:24 +0000378 }
379
Nicolas Geoffray107d22b2021-05-04 10:57:36 +0100380 if (oat_file != nullptr) {
Jared Duke2ad8b262021-11-29 16:51:45 -0800381 VdexFile* vdex_file = oat_file->GetVdexFile();
Jared Duke761f31a2022-06-10 11:18:59 -0700382 if (should_madvise_vdex_and_odex && vdex_file != nullptr) {
383 VLOG(oat) << "Madvising vdex file: " << vdex_file->GetName();
Jared Duke2ad8b262021-11-29 16:51:45 -0800384 // Opened vdex file from an oat file, madvise it to its loaded state.
385 // TODO(b/196052575): Unify dex and vdex madvise knobs and behavior.
386 const size_t madvise_size_limit = Runtime::Current()->GetMadviseWillNeedSizeVdex();
387 Runtime::MadviseFileForRange(madvise_size_limit,
388 vdex_file->Size(),
389 vdex_file->Begin(),
390 vdex_file->End(),
391 vdex_file->GetName());
392 }
393
Nicolas Geoffray107d22b2021-05-04 10:57:36 +0100394 VLOG(class_linker) << "Registering " << oat_file->GetLocation();
395 *out_oat_file = RegisterOatFile(std::move(oat_file));
396 }
Nicolas Geoffray525fa422021-04-19 07:50:35 +0000397 } else {
398 // oat_file == nullptr
399 // Verify if any of the dex files being loaded is already in the class path.
400 // If so, report an error with the current stack trace.
401 // Most likely the developer didn't intend to do this because it will waste
402 // performance and memory.
Jiakai Zhang78d86b52022-05-26 17:24:17 +0100403 if (oat_file_assistant->GetBestStatus() == OatFileAssistant::kOatContextOutOfDate) {
Nicolas Geoffray525fa422021-04-19 07:50:35 +0000404 std::set<const DexFile*> already_exists_in_classpath =
405 context->CheckForDuplicateDexFiles(MakeNonOwningPointerVector(dex_files));
406 if (!already_exists_in_classpath.empty()) {
407 ScopedTrace duplicate_dex_files("DuplicateDexFilesInContext");
408 auto duplicate_it = already_exists_in_classpath.begin();
409 std::string duplicates = (*duplicate_it)->GetLocation();
410 for (duplicate_it++ ; duplicate_it != already_exists_in_classpath.end(); duplicate_it++) {
411 duplicates += "," + (*duplicate_it)->GetLocation();
412 }
Bharadwaj Kalandhabhatta0bb40312017-06-01 10:47:00 -0700413
Nicolas Geoffray525fa422021-04-19 07:50:35 +0000414 std::ostringstream out;
415 out << "Trying to load dex files which is already loaded in the same ClassLoader "
416 << "hierarchy.\n"
417 << "This is a strong indication of bad ClassLoader construct which leads to poor "
418 << "performance and wastes memory.\n"
419 << "The list of duplicate dex files is: " << duplicates << "\n"
420 << "The current class loader context is: "
421 << context->EncodeContextForOatFile("") << "\n"
422 << "Java stack trace:\n";
423
424 {
425 ScopedObjectAccess soa(self);
426 self->DumpJavaStack(out);
427 }
428
429 // We log this as an ERROR to stress the fact that this is most likely unintended.
430 // Note that ART cannot do anything about it. It is up to the app to fix their logic.
431 // Here we are trying to give a heads up on why the app might have performance issues.
432 LOG(ERROR) << out.str();
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100433 }
Bharadwaj Kalandhabhatta0bb40312017-06-01 10:47:00 -0700434 }
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800435 }
Nicolas Geoffray5d3a23d2022-12-08 14:51:25 +0000436
437 Runtime::Current()->GetAppInfo()->RegisterOdexStatus(
438 dex_location,
439 compilation_filter,
440 compilation_reason,
441 odex_status);
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700442 }
443
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100444 // If we arrive here with an empty dex files list, it means we fail to load
445 // it/them through an .oat file.
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700446 if (dex_files.empty()) {
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100447 std::string error_msg;
448 static constexpr bool kVerifyChecksum = true;
449 const ArtDexFileLoader dex_file_loader;
450 if (!dex_file_loader.Open(dex_location,
451 dex_location,
452 Runtime::Current()->IsVerificationEnabled(),
453 kVerifyChecksum,
454 /*out*/ &error_msg,
455 &dex_files)) {
Calin Juravle98071152021-01-27 18:41:58 -0800456 ScopedTrace fail_to_open_dex_from_apk("FailedToOpenDexFilesFromApk");
Nicolas Geoffray90a18cf2020-06-25 15:12:59 +0100457 LOG(WARNING) << error_msg;
458 error_msgs->push_back("Failed to open dex files from " + std::string(dex_location)
459 + " because: " + error_msg);
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700460 }
461 }
Calin Juravlec90bc922016-02-24 10:13:09 +0000462
Nicolas Geoffray9ac09ee2019-05-08 23:38:27 +0100463 if (Runtime::Current()->GetJit() != nullptr) {
Nicolas Geoffray741a0702019-06-10 11:18:11 +0100464 Runtime::Current()->GetJit()->RegisterDexFiles(dex_files, class_loader);
Nicolas Geoffray9ac09ee2019-05-08 23:38:27 +0100465 }
466
Calin Juravlec2753e62021-06-25 15:34:09 -0700467 // Now that we loaded the dex/odex files, notify the runtime.
468 // Note that we do this everytime we load dex files.
469 Runtime::Current()->NotifyDexFileLoaded();
470
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700471 return dex_files;
472}
473
David Brazdil7126c5b2019-03-05 00:02:51 +0000474static std::vector<const DexFile::Header*> GetDexFileHeaders(const std::vector<MemMap>& maps) {
475 std::vector<const DexFile::Header*> headers;
476 headers.reserve(maps.size());
477 for (const MemMap& map : maps) {
478 DCHECK(map.IsValid());
479 headers.push_back(reinterpret_cast<const DexFile::Header*>(map.Begin()));
480 }
481 return headers;
482}
483
David Brazdil7126c5b2019-03-05 00:02:51 +0000484std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
485 std::vector<MemMap>&& dex_mem_maps,
486 jobject class_loader,
487 jobjectArray dex_elements,
488 const OatFile** out_oat_file,
489 std::vector<std::string>* error_msgs) {
490 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenDexFilesFromOat_Impl(
491 std::move(dex_mem_maps),
492 class_loader,
493 dex_elements,
494 out_oat_file,
495 error_msgs);
496
497 if (error_msgs->empty()) {
498 // Remove write permission from DexFile pages. We do this at the end because
499 // OatFile assigns OatDexFile pointer in the DexFile objects.
500 for (std::unique_ptr<const DexFile>& dex_file : dex_files) {
501 if (!dex_file->DisableWrite()) {
502 error_msgs->push_back("Failed to make dex file " + dex_file->GetLocation() + " read-only");
503 }
504 }
505 }
506
507 if (!error_msgs->empty()) {
508 return std::vector<std::unique_ptr<const DexFile>>();
509 }
510
511 return dex_files;
512}
513
514std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat_Impl(
515 std::vector<MemMap>&& dex_mem_maps,
516 jobject class_loader,
517 jobjectArray dex_elements,
518 const OatFile** out_oat_file,
519 std::vector<std::string>* error_msgs) {
520 ScopedTrace trace(__FUNCTION__);
521 std::string error_msg;
522 DCHECK(error_msgs != nullptr);
523
524 // Extract dex file headers from `dex_mem_maps`.
525 const std::vector<const DexFile::Header*> dex_headers = GetDexFileHeaders(dex_mem_maps);
526
527 // Determine dex/vdex locations and the combined location checksum.
David Brazdil7126c5b2019-03-05 00:02:51 +0000528 std::string dex_location;
529 std::string vdex_path;
530 bool has_vdex = OatFileAssistant::AnonymousDexVdexLocation(dex_headers,
531 kRuntimeISA,
David Brazdil7126c5b2019-03-05 00:02:51 +0000532 &dex_location,
533 &vdex_path);
534
535 // Attempt to open an existing vdex and check dex file checksums match.
536 std::unique_ptr<VdexFile> vdex_file = nullptr;
537 if (has_vdex && OS::FileExists(vdex_path.c_str())) {
538 vdex_file = VdexFile::Open(vdex_path,
539 /* writable= */ false,
540 /* low_4gb= */ false,
David Brazdil7126c5b2019-03-05 00:02:51 +0000541 &error_msg);
542 if (vdex_file == nullptr) {
543 LOG(WARNING) << "Failed to open vdex " << vdex_path << ": " << error_msg;
544 } else if (!vdex_file->MatchesDexFileChecksums(dex_headers)) {
545 LOG(WARNING) << "Failed to open vdex " << vdex_path << ": dex file checksum mismatch";
546 vdex_file.reset(nullptr);
547 }
548 }
549
550 // Load dex files. Skip structural dex file verification if vdex was found
551 // and dex checksums matched.
552 std::vector<std::unique_ptr<const DexFile>> dex_files;
553 for (size_t i = 0; i < dex_mem_maps.size(); ++i) {
554 static constexpr bool kVerifyChecksum = true;
555 const ArtDexFileLoader dex_file_loader;
556 std::unique_ptr<const DexFile> dex_file(dex_file_loader.Open(
557 DexFileLoader::GetMultiDexLocation(i, dex_location.c_str()),
Nicolas Geoffray88566952021-02-16 15:51:18 +0000558 dex_headers[i]->checksum_,
David Brazdil7126c5b2019-03-05 00:02:51 +0000559 std::move(dex_mem_maps[i]),
560 /* verify= */ (vdex_file == nullptr) && Runtime::Current()->IsVerificationEnabled(),
561 kVerifyChecksum,
562 &error_msg));
563 if (dex_file != nullptr) {
564 dex::tracking::RegisterDexFile(dex_file.get()); // Register for tracking.
565 dex_files.push_back(std::move(dex_file));
566 } else {
567 error_msgs->push_back("Failed to open dex files from memory: " + error_msg);
568 }
569 }
570
571 // Check if we should proceed to creating an OatFile instance backed by the vdex.
572 // We need: (a) an existing vdex, (b) class loader (can be null if invoked via reflection),
573 // and (c) no errors during dex file loading.
574 if (vdex_file == nullptr || class_loader == nullptr || !error_msgs->empty()) {
575 return dex_files;
576 }
577
578 // Attempt to create a class loader context, check OpenDexFiles succeeds (prerequisite
579 // for using the context later).
580 std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::CreateContextForClassLoader(
581 class_loader,
582 dex_elements);
583 if (context == nullptr) {
584 LOG(ERROR) << "Could not create class loader context for " << vdex_path;
585 return dex_files;
586 }
Calin Juravle5ff23932020-12-11 18:26:14 -0800587 DCHECK(context->OpenDexFiles())
David Brazdil7126c5b2019-03-05 00:02:51 +0000588 << "Context created from already opened dex files should not attempt to open again";
589
David Brazdil7126c5b2019-03-05 00:02:51 +0000590 // Initialize an OatFile instance backed by the loaded vdex.
591 std::unique_ptr<OatFile> oat_file(OatFile::OpenFromVdex(MakeNonOwningPointerVector(dex_files),
592 std::move(vdex_file),
593 dex_location));
Vladimir Markoc3908792020-04-06 14:52:04 +0100594 if (oat_file != nullptr) {
595 VLOG(class_linker) << "Registering " << oat_file->GetLocation();
596 *out_oat_file = RegisterOatFile(std::move(oat_file));
597 }
David Brazdil7126c5b2019-03-05 00:02:51 +0000598 return dex_files;
599}
600
David Brazdil35a3f6a2019-03-04 15:59:06 +0000601// Check how many vdex files exist in the same directory as the vdex file we are about
602// to write. If more than or equal to kAnonymousVdexCacheSize, unlink the least
603// recently used one(s) (according to stat-reported atime).
604static bool UnlinkLeastRecentlyUsedVdexIfNeeded(const std::string& vdex_path_to_add,
605 std::string* error_msg) {
Nicolas Geoffray9bc364b2021-03-29 10:41:39 +0100606 std::string basename = android::base::Basename(vdex_path_to_add);
607 if (!OatFileAssistant::IsAnonymousVdexBasename(basename)) {
608 // File is not for in memory dex files.
609 return true;
610 }
611
David Brazdil35a3f6a2019-03-04 15:59:06 +0000612 if (OS::FileExists(vdex_path_to_add.c_str())) {
613 // File already exists and will be overwritten.
614 // This will not change the number of entries in the cache.
615 return true;
616 }
617
618 auto last_slash = vdex_path_to_add.rfind('/');
619 CHECK(last_slash != std::string::npos);
620 std::string vdex_dir = vdex_path_to_add.substr(0, last_slash + 1);
621
622 if (!OS::DirectoryExists(vdex_dir.c_str())) {
623 // Folder does not exist yet. Cache has zero entries.
624 return true;
625 }
626
627 std::vector<std::pair<time_t, std::string>> cache;
628
629 DIR* c_dir = opendir(vdex_dir.c_str());
630 if (c_dir == nullptr) {
631 *error_msg = "Unable to open " + vdex_dir + " to delete unused vdex files";
632 return false;
633 }
634 for (struct dirent* de = readdir(c_dir); de != nullptr; de = readdir(c_dir)) {
635 if (de->d_type != DT_REG) {
636 continue;
637 }
Nicolas Geoffray9bc364b2021-03-29 10:41:39 +0100638 basename = de->d_name;
David Brazdil35a3f6a2019-03-04 15:59:06 +0000639 if (!OatFileAssistant::IsAnonymousVdexBasename(basename)) {
640 continue;
641 }
642 std::string fullname = vdex_dir + basename;
643
644 struct stat s;
645 int rc = TEMP_FAILURE_RETRY(stat(fullname.c_str(), &s));
646 if (rc == -1) {
647 *error_msg = "Failed to stat() anonymous vdex file " + fullname;
648 return false;
649 }
650
651 cache.push_back(std::make_pair(s.st_atime, fullname));
652 }
653 CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory.";
654
655 if (cache.size() < OatFileManager::kAnonymousVdexCacheSize) {
656 return true;
657 }
658
659 std::sort(cache.begin(),
660 cache.end(),
661 [](const auto& a, const auto& b) { return a.first < b.first; });
662 for (size_t i = OatFileManager::kAnonymousVdexCacheSize - 1; i < cache.size(); ++i) {
663 if (unlink(cache[i].second.c_str()) != 0) {
664 *error_msg = "Could not unlink anonymous vdex file " + cache[i].second;
665 return false;
666 }
667 }
668
669 return true;
670}
671
David Brazdil331a5e12019-04-01 22:46:16 +0000672class BackgroundVerificationTask final : public Task {
673 public:
David Brazdil35a3f6a2019-03-04 15:59:06 +0000674 BackgroundVerificationTask(const std::vector<const DexFile*>& dex_files,
675 jobject class_loader,
David Brazdil35a3f6a2019-03-04 15:59:06 +0000676 const std::string& vdex_path)
677 : dex_files_(dex_files),
David Brazdil35a3f6a2019-03-04 15:59:06 +0000678 vdex_path_(vdex_path) {
David Brazdil331a5e12019-04-01 22:46:16 +0000679 Thread* const self = Thread::Current();
680 ScopedObjectAccess soa(self);
681 // Create a global ref for `class_loader` because it will be accessed from a different thread.
682 class_loader_ = soa.Vm()->AddGlobalRef(self, soa.Decode<mirror::ClassLoader>(class_loader));
683 CHECK(class_loader_ != nullptr);
684 }
685
686 ~BackgroundVerificationTask() {
687 Thread* const self = Thread::Current();
688 ScopedObjectAccess soa(self);
689 soa.Vm()->DeleteGlobalRef(self, class_loader_);
690 }
691
692 void Run(Thread* self) override {
David Brazdil35a3f6a2019-03-04 15:59:06 +0000693 std::string error_msg;
David Brazdil331a5e12019-04-01 22:46:16 +0000694 ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
David Brazdil35a3f6a2019-03-04 15:59:06 +0000695 verifier::VerifierDeps verifier_deps(dex_files_);
David Brazdil331a5e12019-04-01 22:46:16 +0000696
697 // Iterate over all classes and verify them.
698 for (const DexFile* dex_file : dex_files_) {
699 for (uint32_t cdef_idx = 0; cdef_idx < dex_file->NumClassDefs(); cdef_idx++) {
David Brazdil35a3f6a2019-03-04 15:59:06 +0000700 const dex::ClassDef& class_def = dex_file->GetClassDef(cdef_idx);
701
David Brazdil331a5e12019-04-01 22:46:16 +0000702 // Take handles inside the loop. The background verification is low priority
703 // and we want to minimize the risk of blocking anyone else.
704 ScopedObjectAccess soa(self);
705 StackHandleScope<2> hs(self);
706 Handle<mirror::ClassLoader> h_loader(hs.NewHandle(
707 soa.Decode<mirror::ClassLoader>(class_loader_)));
708 Handle<mirror::Class> h_class(hs.NewHandle<mirror::Class>(class_linker->FindClass(
709 self,
David Brazdil35a3f6a2019-03-04 15:59:06 +0000710 dex_file->GetClassDescriptor(class_def),
David Brazdil331a5e12019-04-01 22:46:16 +0000711 h_loader)));
712
713 if (h_class == nullptr) {
Nicolas Geoffray3cde18d2023-01-04 10:13:40 +0000714 DCHECK(self->IsExceptionPending());
David Brazdil331a5e12019-04-01 22:46:16 +0000715 self->ClearException();
716 continue;
717 }
718
719 if (&h_class->GetDexFile() != dex_file) {
720 // There is a different class in the class path or a parent class loader
721 // with the same descriptor. This `h_class` is not resolvable, skip it.
722 continue;
723 }
724
Nicolas Geoffray3cde18d2023-01-04 10:13:40 +0000725 DCHECK(h_class->IsResolved()) << h_class->PrettyDescriptor();
Nicolas Geoffray5b0b2e12021-03-19 14:48:40 +0000726 class_linker->VerifyClass(self, &verifier_deps, h_class);
Nicolas Geoffray3cde18d2023-01-04 10:13:40 +0000727 if (self->IsExceptionPending()) {
728 // ClassLinker::VerifyClass can throw, but the exception isn't useful here.
729 self->ClearException();
David Brazdil331a5e12019-04-01 22:46:16 +0000730 }
731
Nicolas Geoffray3cde18d2023-01-04 10:13:40 +0000732 DCHECK(h_class->IsVerified() || h_class->IsErroneous())
David Brazdil331a5e12019-04-01 22:46:16 +0000733 << h_class->PrettyDescriptor() << ": state=" << h_class->GetStatus();
David Brazdil35a3f6a2019-03-04 15:59:06 +0000734
735 if (h_class->IsVerified()) {
736 verifier_deps.RecordClassVerified(*dex_file, class_def);
737 }
David Brazdil331a5e12019-04-01 22:46:16 +0000738 }
739 }
David Brazdil35a3f6a2019-03-04 15:59:06 +0000740
741 // Delete old vdex files if there are too many in the folder.
742 if (!UnlinkLeastRecentlyUsedVdexIfNeeded(vdex_path_, &error_msg)) {
743 LOG(ERROR) << "Could not unlink old vdex files " << vdex_path_ << ": " << error_msg;
744 return;
745 }
746
747 // Construct a vdex file and write `verifier_deps` into it.
748 if (!VdexFile::WriteToDisk(vdex_path_,
749 dex_files_,
750 verifier_deps,
David Brazdil35a3f6a2019-03-04 15:59:06 +0000751 &error_msg)) {
752 LOG(ERROR) << "Could not write anonymous vdex " << vdex_path_ << ": " << error_msg;
753 return;
754 }
David Brazdil331a5e12019-04-01 22:46:16 +0000755 }
756
757 void Finalize() override {
758 delete this;
759 }
760
761 private:
762 const std::vector<const DexFile*> dex_files_;
763 jobject class_loader_;
David Brazdil35a3f6a2019-03-04 15:59:06 +0000764 const std::string vdex_path_;
David Brazdil331a5e12019-04-01 22:46:16 +0000765
766 DISALLOW_COPY_AND_ASSIGN(BackgroundVerificationTask);
767};
768
769void OatFileManager::RunBackgroundVerification(const std::vector<const DexFile*>& dex_files,
Nicolas Geoffray9bc364b2021-03-29 10:41:39 +0100770 jobject class_loader) {
David Brazdil527072e2019-04-03 15:15:40 +0100771 Runtime* const runtime = Runtime::Current();
772 Thread* const self = Thread::Current();
773
774 if (runtime->IsJavaDebuggable()) {
David Brazdil331a5e12019-04-01 22:46:16 +0000775 // Threads created by ThreadPool ("runtime threads") are not allowed to load
776 // classes when debuggable to match class-initialization semantics
777 // expectations. Do not verify in the background.
778 return;
779 }
780
Nicolas Geoffrayc29b49e2021-10-13 15:37:55 +0100781 {
782 // Temporarily create a class loader context to see if we recognize the
783 // chain.
784 std::unique_ptr<ClassLoaderContext> context(
785 ClassLoaderContext::CreateContextForClassLoader(class_loader, nullptr));
786 if (context == nullptr) {
787 // We only run background verification for class loaders we know the lookup
788 // chain. Because the background verification runs on runtime threads,
789 // which do not call Java, we won't be able to load classes when
790 // verifying, which is something the current verifier relies on.
791 return;
792 }
793 }
794
David Brazdil527072e2019-04-03 15:15:40 +0100795 if (!IsSdkVersionSetAndAtLeast(runtime->GetTargetSdkVersion(), SdkVersion::kQ)) {
796 // Do not run for legacy apps as they may depend on the previous class loader behaviour.
797 return;
798 }
799
800 if (runtime->IsShuttingDown(self)) {
David Brazdil331a5e12019-04-01 22:46:16 +0000801 // Not allowed to create new threads during runtime shutdown.
802 return;
803 }
804
Nicolas Geoffray9bc364b2021-03-29 10:41:39 +0100805 if (dex_files.size() < 1) {
806 // Nothing to verify.
807 return;
David Brazdil331a5e12019-04-01 22:46:16 +0000808 }
Nicolas Geoffray9bc364b2021-03-29 10:41:39 +0100809
810 std::string dex_location = dex_files[0]->GetLocation();
811 const std::string& data_dir = Runtime::Current()->GetProcessDataDirectory();
812 if (!android::base::StartsWith(dex_location, data_dir)) {
813 // For now, we only run background verification for secondary dex files.
814 // Running it for primary or split APKs could have some undesirable
815 // side-effects, like overloading the device on app startup.
816 return;
817 }
818
819 std::string error_msg;
820 std::string odex_filename;
821 if (!OatFileAssistant::DexLocationToOdexFilename(dex_location,
822 kRuntimeISA,
823 &odex_filename,
824 &error_msg)) {
825 LOG(WARNING) << "Could not get odex filename for " << dex_location << ": " << error_msg;
826 return;
827 }
828
Orion Hodson971068d2021-06-30 21:17:53 +0100829 if (LocationIsOnArtApexData(odex_filename) && Runtime::Current()->DenyArtApexDataFiles()) {
830 // Ignore vdex file associated with this odex file as the odex file is not trustworthy.
831 return;
832 }
833
Nicolas Geoffray30ba3a02021-03-31 14:11:58 +0100834 {
835 WriterMutexLock mu(self, *Locks::oat_file_manager_lock_);
836 if (verification_thread_pool_ == nullptr) {
837 verification_thread_pool_.reset(
838 new ThreadPool("Verification thread pool", /* num_threads= */ 1));
839 verification_thread_pool_->StartWorkers(self);
840 }
Nicolas Geoffray9bc364b2021-03-29 10:41:39 +0100841 }
842 verification_thread_pool_->AddTask(self, new BackgroundVerificationTask(
843 dex_files,
844 class_loader,
Nicolas Geoffray30ba3a02021-03-31 14:11:58 +0100845 GetVdexFilename(odex_filename)));
David Brazdil331a5e12019-04-01 22:46:16 +0000846}
847
848void OatFileManager::WaitForWorkersToBeCreated() {
849 DCHECK(!Runtime::Current()->IsShuttingDown(Thread::Current()))
850 << "Cannot create new threads during runtime shutdown";
851 if (verification_thread_pool_ != nullptr) {
852 verification_thread_pool_->WaitForWorkersToBeCreated();
853 }
854}
855
856void OatFileManager::DeleteThreadPool() {
857 verification_thread_pool_.reset(nullptr);
858}
859
Mythri Allebe282e12022-10-06 12:05:26 +0000860void OatFileManager::WaitForBackgroundVerificationTasksToFinish() {
861 if (verification_thread_pool_ == nullptr) {
862 return;
863 }
864
865 Thread* const self = Thread::Current();
866 verification_thread_pool_->Wait(self, /* do_work= */ true, /* may_hold_locks= */ false);
867}
868
David Brazdil331a5e12019-04-01 22:46:16 +0000869void OatFileManager::WaitForBackgroundVerificationTasks() {
870 if (verification_thread_pool_ != nullptr) {
871 Thread* const self = Thread::Current();
872 verification_thread_pool_->WaitForWorkersToBeCreated();
873 verification_thread_pool_->Wait(self, /* do_work= */ true, /* may_hold_locks= */ false);
874 }
875}
876
Nicolas Geoffrayea55f3d2021-09-07 12:16:56 +0100877void OatFileManager::ClearOnlyUseTrustedOatFiles() {
878 only_use_system_oat_files_ = false;
879}
880
Orion Hodson094b1cf2021-06-08 09:28:28 +0100881void OatFileManager::SetOnlyUseTrustedOatFiles() {
Nicolas Geoffray68bf3902017-09-07 14:40:48 +0100882 ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
Nicolas Geoffrayea55f3d2021-09-07 12:16:56 +0100883 if (!oat_files_.empty()) {
884 LOG(FATAL) << "Unexpected non-empty loaded oat files ";
Andreas Gampe3383f9c2019-03-15 11:46:08 -0700885 }
Nicolas Geoffraye5c48f72020-03-11 11:28:43 +0000886 only_use_system_oat_files_ = true;
Nicolas Geoffray68bf3902017-09-07 14:40:48 +0100887}
888
Nicolas Geoffray04680f32016-03-17 11:56:54 +0000889void OatFileManager::DumpForSigQuit(std::ostream& os) {
890 ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
891 std::vector<const OatFile*> boot_oat_files = GetBootOatFiles();
892 for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
893 if (ContainsElement(boot_oat_files, oat_file.get())) {
894 continue;
895 }
Andreas Gampe29d38e72016-03-23 15:31:51 +0000896 os << oat_file->GetLocation() << ": " << oat_file->GetCompilerFilter() << "\n";
Nicolas Geoffray04680f32016-03-17 11:56:54 +0000897 }
898}
899
Nicolas Geoffrayc25a9f92021-12-13 17:22:43 +0000900bool OatFileManager::ContainsPc(const void* code) {
901 ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
902 std::vector<const OatFile*> boot_oat_files = GetBootOatFiles();
903 for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
904 if (oat_file->Contains(code)) {
905 return true;
906 }
907 }
908 return false;
909}
910
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -0700911} // namespace art