oat_file_manager.cc revision 61d2b2d353ba4ab952247d2bff2c905598118bb4
1f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier/* 2f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier * Copyright (C) 2015 The Android Open Source Project 3f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier * 4f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier * Licensed under the Apache License, Version 2.0 (the "License"); 5f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier * you may not use this file except in compliance with the License. 6f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier * You may obtain a copy of the License at 7f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier * 8f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier * http://www.apache.org/licenses/LICENSE-2.0 9f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier * 10f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier * Unless required by applicable law or agreed to in writing, software 11f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier * distributed under the License is distributed on an "AS IS" BASIS, 12f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier * See the License for the specific language governing permissions and 14f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier * limitations under the License. 15f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier */ 16f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 17f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier#include "oat_file_manager.h" 18f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 19f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier#include <memory> 20f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier#include <queue> 21f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier#include <vector> 22f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 23f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier#include "base/logging.h" 24f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier#include "base/stl_util.h" 25fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier#include "class_linker.h" 2680b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier#include "dex_file-inl.h" 2761d2b2d353ba4ab952247d2bff2c905598118bb4Mathieu Chartier#include "gc/scoped_gc_critical_section.h" 28f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier#include "gc/space/image_space.h" 29fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier#include "handle_scope-inl.h" 30fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier#include "mirror/class_loader.h" 31f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier#include "oat_file_assistant.h" 32fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier#include "scoped_thread_state_change.h" 33f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier#include "thread-inl.h" 34a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier#include "thread_list.h" 35f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 36f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartiernamespace art { 37f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 38f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// For b/21333911. 3980b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier// Only enabled for debug builds to prevent bit rot. There are too many performance regressions for 4080b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier// normal builds. 4180b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartierstatic constexpr bool kDuplicateClassesCheck = kIsDebugBuild; 42f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 43fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier// If true, then we attempt to load the application image if it exists. 44fbc31087932a65e036a153afab3049dc5298656aMathieu Chartierstatic constexpr bool kEnableAppImage = true; 45fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier 46f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierconst OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oat_file) { 47e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 48f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier DCHECK(oat_file != nullptr); 49f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (kIsDebugBuild) { 50e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier CHECK(oat_files_.find(oat_file) == oat_files_.end()); 51f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier for (const std::unique_ptr<const OatFile>& existing : oat_files_) { 52f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier CHECK_NE(oat_file.get(), existing.get()) << oat_file->GetLocation(); 53f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Check that we don't have an oat file with the same address. Copies of the same oat file 54f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // should be loaded at different addresses. 55f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier CHECK_NE(oat_file->Begin(), existing->Begin()) << "Oat file already mapped at that location"; 56f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 57f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 58f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier have_non_pic_oat_file_ = have_non_pic_oat_file_ || !oat_file->IsPic(); 59e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier const OatFile* ret = oat_file.get(); 60e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier oat_files_.insert(std::move(oat_file)); 61e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier return ret; 62e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier} 63e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier 64e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartiervoid OatFileManager::UnRegisterAndDeleteOatFile(const OatFile* oat_file) { 65e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 66e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier DCHECK(oat_file != nullptr); 67e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier std::unique_ptr<const OatFile> compare(oat_file); 68e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier auto it = oat_files_.find(compare); 69e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier CHECK(it != oat_files_.end()); 70e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier oat_files_.erase(it); 71e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier compare.release(); 72f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 73f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 74f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierconst OatFile* OatFileManager::FindOpenedOatFileFromOatLocation(const std::string& oat_location) 75f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const { 76f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 77e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier return FindOpenedOatFileFromOatLocationLocked(oat_location); 78e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier} 79e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier 80e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartierconst OatFile* OatFileManager::FindOpenedOatFileFromOatLocationLocked( 81e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier const std::string& oat_location) const { 82f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) { 83f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (oat_file->GetLocation() == oat_location) { 84f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return oat_file.get(); 85f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 86f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 87f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return nullptr; 88f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 89f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 90dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Haostd::vector<const OatFile*> OatFileManager::GetBootOatFiles() const { 91dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao std::vector<const OatFile*> oat_files; 92dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao std::vector<gc::space::ImageSpace*> image_spaces = 93dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao Runtime::Current()->GetHeap()->GetBootImageSpaces(); 94dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao for (gc::space::ImageSpace* image_space : image_spaces) { 95dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao oat_files.push_back(image_space->GetOatFile()); 96dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao } 97dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao return oat_files; 98f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 99f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 100f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierconst OatFile* OatFileManager::GetPrimaryOatFile() const { 101f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 102dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao std::vector<const OatFile*> boot_oat_files = GetBootOatFiles(); 103dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao if (!boot_oat_files.empty()) { 104f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) { 105dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao if (std::find(boot_oat_files.begin(), boot_oat_files.end(), oat_file.get()) == 106dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao boot_oat_files.end()) { 107f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return oat_file.get(); 108f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 109f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 110f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 111f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return nullptr; 112f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 113f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 114f9c6fc610b27887f832e453a0da1789187293408Mathieu ChartierOatFileManager::~OatFileManager() { 115e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier // Explicitly clear oat_files_ since the OatFile destructor calls back into OatFileManager for 116e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier // UnRegisterOatFileLocation. 117e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier oat_files_.clear(); 118f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 119f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 120dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Haostd::vector<const OatFile*> OatFileManager::RegisterImageOatFiles( 121dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao std::vector<gc::space::ImageSpace*> spaces) { 122dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao std::vector<const OatFile*> oat_files; 123dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao for (gc::space::ImageSpace* space : spaces) { 124dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao oat_files.push_back(RegisterOatFile(space->ReleaseOatFile())); 125dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao } 126dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao return oat_files; 127f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 128f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 129f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierclass DexFileAndClassPair : ValueObject { 130f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier public: 131f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier DexFileAndClassPair(const DexFile* dex_file, size_t current_class_index, bool from_loaded_oat) 132f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier : cached_descriptor_(GetClassDescriptor(dex_file, current_class_index)), 133f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier dex_file_(dex_file), 134f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier current_class_index_(current_class_index), 135f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier from_loaded_oat_(from_loaded_oat) {} 136f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 13780b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier DexFileAndClassPair(const DexFileAndClassPair& rhs) = default; 138f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 13980b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier DexFileAndClassPair& operator=(const DexFileAndClassPair& rhs) = default; 140f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 141f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const char* GetCachedDescriptor() const { 142f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return cached_descriptor_; 143f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 144f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 145f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier bool operator<(const DexFileAndClassPair& rhs) const { 146f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const int cmp = strcmp(cached_descriptor_, rhs.cached_descriptor_); 147f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (cmp != 0) { 148f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Note that the order must be reversed. We want to iterate over the classes in dex files. 149f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // They are sorted lexicographically. Thus, the priority-queue must be a min-queue. 150f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return cmp > 0; 151f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 152f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return dex_file_ < rhs.dex_file_; 153f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 154f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 155f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier bool DexFileHasMoreClasses() const { 156f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return current_class_index_ + 1 < dex_file_->NumClassDefs(); 157f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 158f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 159f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier void Next() { 160f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier ++current_class_index_; 16180b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier cached_descriptor_ = GetClassDescriptor(dex_file_.get(), current_class_index_); 162f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 163f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 164f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier size_t GetCurrentClassIndex() const { 165f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return current_class_index_; 166f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 167f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 168f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier bool FromLoadedOat() const { 169f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return from_loaded_oat_; 170f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 171f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 172f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const DexFile* GetDexFile() const { 173f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return dex_file_.get(); 174f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 175f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 176f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier private: 177f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier static const char* GetClassDescriptor(const DexFile* dex_file, size_t index) { 178f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier DCHECK(IsUint<16>(index)); 179f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const DexFile::ClassDef& class_def = dex_file->GetClassDef(static_cast<uint16_t>(index)); 180f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return dex_file->StringByTypeIdx(class_def.class_idx_); 181f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 182f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 183f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const char* cached_descriptor_; 18480b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier std::shared_ptr<const DexFile> dex_file_; 185f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier size_t current_class_index_; 186f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier bool from_loaded_oat_; // We only need to compare mismatches between what we load now 187f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // and what was loaded before. Any old duplicates must have been 188f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // OK, and any new "internal" duplicates are as well (they must 189f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // be from multidex, which resolves correctly). 190f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier}; 191f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 192f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierstatic void AddDexFilesFromOat(const OatFile* oat_file, 193f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier bool already_loaded, 194f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier /*out*/std::priority_queue<DexFileAndClassPair>* heap) { 195f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier for (const OatDexFile* oat_dex_file : oat_file->GetOatDexFiles()) { 196f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::string error; 197f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::unique_ptr<const DexFile> dex_file = oat_dex_file->OpenDexFile(&error); 198f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (dex_file == nullptr) { 199f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier LOG(WARNING) << "Could not create dex file from oat file: " << error; 200f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } else if (dex_file->NumClassDefs() > 0U) { 201f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier heap->emplace(dex_file.release(), /*current_class_index*/0U, already_loaded); 202f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 203f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 204f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 205f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 206f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierstatic void AddNext(/*inout*/DexFileAndClassPair* original, 207f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier /*inout*/std::priority_queue<DexFileAndClassPair>* heap) { 208f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (original->DexFileHasMoreClasses()) { 209f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier original->Next(); 210f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier heap->push(std::move(*original)); 211f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 212f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 213f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 214f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// Check for class-def collisions in dex files. 215f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// 216f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// This works by maintaining a heap with one class from each dex file, sorted by the class 217f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// descriptor. Then a dex-file/class pair is continually removed from the heap and compared 218f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// against the following top element. If the descriptor is the same, it is now checked whether 219f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// the two elements agree on whether their dex file was from an already-loaded oat-file or the 220f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// new oat file. Any disagreement indicates a collision. 221f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierbool OatFileManager::HasCollisions(const OatFile* oat_file, 222f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::string* error_msg /*out*/) const { 223f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier DCHECK(oat_file != nullptr); 224f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier DCHECK(error_msg != nullptr); 225f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (!kDuplicateClassesCheck) { 226f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return false; 227f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 228f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 229f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Dex files are registered late - once a class is actually being loaded. We have to compare 230f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // against the open oat files. Take the oat_file_manager_lock_ that protects oat_files_ accesses. 231f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 232f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 233f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::priority_queue<DexFileAndClassPair> queue; 234f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 235f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Add dex files from already loaded oat files, but skip boot. 236dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao std::vector<const OatFile*> boot_oat_files = GetBootOatFiles(); 23780b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier // The same OatFile can be loaded multiple times at different addresses. In this case, we don't 23880b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier // need to check both against each other since they would have resolved the same way at compile 23980b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier // time. 24080b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier std::unordered_set<std::string> unique_locations; 241f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier for (const std::unique_ptr<const OatFile>& loaded_oat_file : oat_files_) { 24280b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier DCHECK_NE(loaded_oat_file.get(), oat_file); 24380b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier const std::string& location = loaded_oat_file->GetLocation(); 244dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao if (std::find(boot_oat_files.begin(), boot_oat_files.end(), loaded_oat_file.get()) == 245dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao boot_oat_files.end() && location != oat_file->GetLocation() && 24680b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier unique_locations.find(location) == unique_locations.end()) { 24780b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier unique_locations.insert(location); 248f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier AddDexFilesFromOat(loaded_oat_file.get(), /*already_loaded*/true, &queue); 249f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 250f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 251f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 252f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (queue.empty()) { 253f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // No other oat files, return early. 254f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return false; 255f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 256f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 257f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Add dex files from the oat file to check. 258f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier AddDexFilesFromOat(oat_file, /*already_loaded*/false, &queue); 259f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 260f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Now drain the queue. 261f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier while (!queue.empty()) { 262f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Modifying the top element is only safe if we pop right after. 26380b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier DexFileAndClassPair compare_pop(queue.top()); 264f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier queue.pop(); 265f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 266f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Compare against the following elements. 267f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier while (!queue.empty()) { 26880b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier DexFileAndClassPair top(queue.top()); 269f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 270f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (strcmp(compare_pop.GetCachedDescriptor(), top.GetCachedDescriptor()) == 0) { 271f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Same descriptor. Check whether it's crossing old-oat-files to new-oat-files. 272f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (compare_pop.FromLoadedOat() != top.FromLoadedOat()) { 273f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier *error_msg = 274f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier StringPrintf("Found duplicated class when checking oat files: '%s' in %s and %s", 275f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier compare_pop.GetCachedDescriptor(), 276f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier compare_pop.GetDexFile()->GetLocation().c_str(), 277f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier top.GetDexFile()->GetLocation().c_str()); 278f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return true; 279f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 280f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier queue.pop(); 281f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier AddNext(&top, &queue); 282f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } else { 283f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Something else. Done here. 284f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier break; 285f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 286f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 287f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier AddNext(&compare_pop, &queue); 288f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 289f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 290f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return false; 291f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 292f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 293f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierstd::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat( 294f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const char* dex_location, 295f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const char* oat_location, 296fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier jobject class_loader, 297fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier jobjectArray dex_elements, 298e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier const OatFile** out_oat_file, 299f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::vector<std::string>* error_msgs) { 300f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier CHECK(dex_location != nullptr); 301f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier CHECK(error_msgs != nullptr); 302f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 303f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Verify we aren't holding the mutator lock, which could starve GC if we 304f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // have to generate or relocate an oat file. 305fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier Thread* const self = Thread::Current(); 306fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier Locks::mutator_lock_->AssertNotHeld(self); 307fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier Runtime* const runtime = Runtime::Current(); 308f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier OatFileAssistant oat_file_assistant(dex_location, 309f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier oat_location, 310f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier kRuntimeISA, 311fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier !runtime->IsAotCompiler()); 312f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 313f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Lock the target oat location to avoid races generating and loading the 314f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // oat file. 315f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::string error_msg; 316f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (!oat_file_assistant.Lock(/*out*/&error_msg)) { 317f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Don't worry too much if this fails. If it does fail, it's unlikely we 318f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // can generate an oat file anyway. 319f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier VLOG(class_linker) << "OatFileAssistant::Lock: " << error_msg; 320f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 321f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 322f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const OatFile* source_oat_file = nullptr; 323f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 324e722d2921615102941ca4b6717c9d9e1edae1192Nicolas Geoffray // Update the oat file on disk if we can. This may fail, but that's okay. 325e722d2921615102941ca4b6717c9d9e1edae1192Nicolas Geoffray // Best effort is all that matters here. 326e722d2921615102941ca4b6717c9d9e1edae1192Nicolas Geoffray if (!oat_file_assistant.MakeUpToDate(/*out*/&error_msg)) { 327a28267fdbcafbbc08bae56c5997c8ffa9a008c50Nicolas Geoffray LOG(INFO) << error_msg; 328f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 329f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 330f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Get the oat file on disk. 331f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::unique_ptr<const OatFile> oat_file(oat_file_assistant.GetBestOatFile().release()); 332fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier 333f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (oat_file != nullptr) { 334f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Take the file only if it has no collisions, or we must take it because of preopting. 335f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier bool accept_oat_file = !HasCollisions(oat_file.get(), /*out*/ &error_msg); 336f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (!accept_oat_file) { 337f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Failed the collision check. Print warning. 338f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (Runtime::Current()->IsDexFileFallbackEnabled()) { 339f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier LOG(WARNING) << "Found duplicate classes, falling back to interpreter mode for " 340f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier << dex_location; 341f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } else { 342f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier LOG(WARNING) << "Found duplicate classes, dex-file-fallback disabled, will be failing to " 343f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier " load classes for " << dex_location; 344f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 345f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier LOG(WARNING) << error_msg; 346f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 347f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // However, if the app was part of /system and preopted, there is no original dex file 348f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // available. In that case grudgingly accept the oat file. 349f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (!DexFile::MaybeDex(dex_location)) { 350f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier accept_oat_file = true; 351f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier LOG(WARNING) << "Dex location " << dex_location << " does not seem to include dex file. " 352f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier << "Allow oat file use. This is potentially dangerous."; 353f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 354f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 355f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 356f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (accept_oat_file) { 357f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier VLOG(class_linker) << "Registering " << oat_file->GetLocation(); 358f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier source_oat_file = RegisterOatFile(std::move(oat_file)); 359e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier *out_oat_file = source_oat_file; 360f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 361f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 362f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 363f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::vector<std::unique_ptr<const DexFile>> dex_files; 364f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 365f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Load the dex files from the oat file. 366f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (source_oat_file != nullptr) { 367fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier bool added_image_space = false; 368fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier if (source_oat_file->IsExecutable()) { 369fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier std::unique_ptr<gc::space::ImageSpace> image_space( 370fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier kEnableAppImage ? oat_file_assistant.OpenImageSpace(source_oat_file) : nullptr); 371fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier if (image_space != nullptr) { 372fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier ScopedObjectAccess soa(self); 373fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier StackHandleScope<1> hs(self); 374fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier Handle<mirror::ClassLoader> h_loader( 375fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader))); 376fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier // Can not load app image without class loader. 377fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier if (h_loader.Get() != nullptr) { 378fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier std::string temp_error_msg; 379fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier // Add image space has a race condition since other threads could be reading from the 380fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier // spaces array. 381a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier { 382a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier ScopedThreadSuspension sts(self, kSuspended); 38361d2b2d353ba4ab952247d2bff2c905598118bb4Mathieu Chartier gc::ScopedGCCriticalSection gcs(self, 38461d2b2d353ba4ab952247d2bff2c905598118bb4Mathieu Chartier gc::kGcCauseAddRemoveAppImageSpace, 38561d2b2d353ba4ab952247d2bff2c905598118bb4Mathieu Chartier gc::kCollectorTypeAddRemoveAppImageSpace); 386a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier ScopedSuspendAll ssa("Add image space"); 387a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier runtime->GetHeap()->AddSpace(image_space.get()); 388a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier } 389fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier added_image_space = true; 390fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier if (!runtime->GetClassLinker()->AddImageSpace(image_space.get(), 391fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier h_loader, 392fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier dex_elements, 393fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier dex_location, 394fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*out*/&dex_files, 395fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*out*/&temp_error_msg)) { 396fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier LOG(INFO) << "Failed to add image file " << temp_error_msg; 397fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier dex_files.clear(); 398a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier { 399a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier ScopedThreadSuspension sts(self, kSuspended); 40061d2b2d353ba4ab952247d2bff2c905598118bb4Mathieu Chartier gc::ScopedGCCriticalSection gcs(self, 40161d2b2d353ba4ab952247d2bff2c905598118bb4Mathieu Chartier gc::kGcCauseAddRemoveAppImageSpace, 40261d2b2d353ba4ab952247d2bff2c905598118bb4Mathieu Chartier gc::kCollectorTypeAddRemoveAppImageSpace); 403a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier ScopedSuspendAll ssa("Remove image space"); 404a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier runtime->GetHeap()->RemoveSpace(image_space.get()); 405a9d82fe8bc6960b565245b920e99107a824ca515Mathieu Chartier } 406fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier added_image_space = false; 407fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier // Non-fatal, don't update error_msg. 408fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } 409fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier image_space.release(); 410fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } 411fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } 412fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } 413fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier if (!added_image_space) { 414fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier DCHECK(dex_files.empty()); 415fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier dex_files = oat_file_assistant.LoadDexFiles(*source_oat_file, dex_location); 416fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } 417f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (dex_files.empty()) { 418f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier error_msgs->push_back("Failed to open dex files from " + source_oat_file->GetLocation()); 419f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 420f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 421f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 422f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Fall back to running out of the original dex file if we couldn't load any 423f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // dex_files from the oat file. 424f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (dex_files.empty()) { 425f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (oat_file_assistant.HasOriginalDexFiles()) { 426f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (Runtime::Current()->IsDexFileFallbackEnabled()) { 427f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (!DexFile::Open(dex_location, dex_location, /*out*/ &error_msg, &dex_files)) { 428f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier LOG(WARNING) << error_msg; 429f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier error_msgs->push_back("Failed to open dex files from " + std::string(dex_location)); 430f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 431f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } else { 432f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier error_msgs->push_back("Fallback mode disabled, skipping dex files."); 433f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 434f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } else { 435f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier error_msgs->push_back("No original dex files found for dex location " 436f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier + std::string(dex_location)); 437f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 438f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 439f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return dex_files; 440f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 441f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 442e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartierbool OatFileManager::RegisterOatFileLocation(const std::string& oat_location) { 443e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier WriterMutexLock mu(Thread::Current(), *Locks::oat_file_count_lock_); 444e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier auto it = oat_file_count_.find(oat_location); 445e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier if (it != oat_file_count_.end()) { 446e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier ++it->second; 447e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier return false; 448e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier } 449e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier oat_file_count_.insert(std::pair<std::string, size_t>(oat_location, 1u)); 450e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier return true; 451e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier} 452e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier 453e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartiervoid OatFileManager::UnRegisterOatFileLocation(const std::string& oat_location) { 454e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier WriterMutexLock mu(Thread::Current(), *Locks::oat_file_count_lock_); 455e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier auto it = oat_file_count_.find(oat_location); 456e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier if (it != oat_file_count_.end()) { 457e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier --it->second; 458e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier if (it->second == 0) { 459e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier oat_file_count_.erase(it); 460e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier } 461e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier } 462e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier} 463e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier 464f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} // namespace art 465