oat_file_manager.cc revision a28267fdbcafbbc08bae56c5997c8ffa9a008c50
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" 2580b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier#include "dex_file-inl.h" 26f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier#include "gc/space/image_space.h" 27f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier#include "oat_file_assistant.h" 28f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier#include "thread-inl.h" 29f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 30f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartiernamespace art { 31f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 32f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// For b/21333911. 3380b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier// Only enabled for debug builds to prevent bit rot. There are too many performance regressions for 3480b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier// normal builds. 3580b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartierstatic constexpr bool kDuplicateClassesCheck = kIsDebugBuild; 36f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 37f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierconst OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oat_file) { 38e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 39f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier DCHECK(oat_file != nullptr); 40f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (kIsDebugBuild) { 41e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier CHECK(oat_files_.find(oat_file) == oat_files_.end()); 42f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier for (const std::unique_ptr<const OatFile>& existing : oat_files_) { 43f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier CHECK_NE(oat_file.get(), existing.get()) << oat_file->GetLocation(); 44f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Check that we don't have an oat file with the same address. Copies of the same oat file 45f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // should be loaded at different addresses. 46f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier CHECK_NE(oat_file->Begin(), existing->Begin()) << "Oat file already mapped at that location"; 47f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 48f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 49f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier have_non_pic_oat_file_ = have_non_pic_oat_file_ || !oat_file->IsPic(); 50e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier const OatFile* ret = oat_file.get(); 51e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier oat_files_.insert(std::move(oat_file)); 52e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier return ret; 53e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier} 54e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier 55e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartiervoid OatFileManager::UnRegisterAndDeleteOatFile(const OatFile* oat_file) { 56e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 57e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier DCHECK(oat_file != nullptr); 58e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier std::unique_ptr<const OatFile> compare(oat_file); 59e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier auto it = oat_files_.find(compare); 60e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier CHECK(it != oat_files_.end()); 61e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier oat_files_.erase(it); 62e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier compare.release(); 63f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 64f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 65f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierconst OatFile* OatFileManager::FindOpenedOatFileFromOatLocation(const std::string& oat_location) 66f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const { 67f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 68e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier return FindOpenedOatFileFromOatLocationLocked(oat_location); 69e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier} 70e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier 71e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartierconst OatFile* OatFileManager::FindOpenedOatFileFromOatLocationLocked( 72e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier const std::string& oat_location) const { 73f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) { 74f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (oat_file->GetLocation() == oat_location) { 75f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return oat_file.get(); 76f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 77f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 78f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return nullptr; 79f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 80f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 81f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierconst OatFile* OatFileManager::GetBootOatFile() const { 82073b16c8429d302d5413e8ffc488b03b8f770780Mathieu Chartier gc::space::ImageSpace* image_space = Runtime::Current()->GetHeap()->GetBootImageSpace(); 83073b16c8429d302d5413e8ffc488b03b8f770780Mathieu Chartier return (image_space == nullptr) ? nullptr : image_space->GetOatFile(); 84f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 85f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 86f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierconst OatFile* OatFileManager::GetPrimaryOatFile() const { 87f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 88f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const OatFile* boot_oat_file = GetBootOatFile(); 89f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (boot_oat_file != nullptr) { 90f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) { 91f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (oat_file.get() != boot_oat_file) { 92f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return oat_file.get(); 93f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 94f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 95f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 96f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return nullptr; 97f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 98f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 99f9c6fc610b27887f832e453a0da1789187293408Mathieu ChartierOatFileManager::~OatFileManager() { 100e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier // Explicitly clear oat_files_ since the OatFile destructor calls back into OatFileManager for 101e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier // UnRegisterOatFileLocation. 102e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier oat_files_.clear(); 103f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 104f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 105f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierconst OatFile* OatFileManager::RegisterImageOatFile(gc::space::ImageSpace* space) { 106f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return RegisterOatFile(space->ReleaseOatFile()); 107f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 108f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 109f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierclass DexFileAndClassPair : ValueObject { 110f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier public: 111f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier DexFileAndClassPair(const DexFile* dex_file, size_t current_class_index, bool from_loaded_oat) 112f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier : cached_descriptor_(GetClassDescriptor(dex_file, current_class_index)), 113f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier dex_file_(dex_file), 114f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier current_class_index_(current_class_index), 115f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier from_loaded_oat_(from_loaded_oat) {} 116f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 11780b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier DexFileAndClassPair(const DexFileAndClassPair& rhs) = default; 118f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 11980b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier DexFileAndClassPair& operator=(const DexFileAndClassPair& rhs) = default; 120f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 121f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const char* GetCachedDescriptor() const { 122f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return cached_descriptor_; 123f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 124f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 125f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier bool operator<(const DexFileAndClassPair& rhs) const { 126f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const int cmp = strcmp(cached_descriptor_, rhs.cached_descriptor_); 127f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (cmp != 0) { 128f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Note that the order must be reversed. We want to iterate over the classes in dex files. 129f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // They are sorted lexicographically. Thus, the priority-queue must be a min-queue. 130f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return cmp > 0; 131f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 132f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return dex_file_ < rhs.dex_file_; 133f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 134f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 135f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier bool DexFileHasMoreClasses() const { 136f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return current_class_index_ + 1 < dex_file_->NumClassDefs(); 137f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 138f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 139f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier void Next() { 140f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier ++current_class_index_; 14180b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier cached_descriptor_ = GetClassDescriptor(dex_file_.get(), current_class_index_); 142f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 143f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 144f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier size_t GetCurrentClassIndex() const { 145f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return current_class_index_; 146f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 147f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 148f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier bool FromLoadedOat() const { 149f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return from_loaded_oat_; 150f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 151f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 152f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const DexFile* GetDexFile() const { 153f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return dex_file_.get(); 154f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 155f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 156f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier private: 157f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier static const char* GetClassDescriptor(const DexFile* dex_file, size_t index) { 158f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier DCHECK(IsUint<16>(index)); 159f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const DexFile::ClassDef& class_def = dex_file->GetClassDef(static_cast<uint16_t>(index)); 160f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return dex_file->StringByTypeIdx(class_def.class_idx_); 161f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 162f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 163f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const char* cached_descriptor_; 16480b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier std::shared_ptr<const DexFile> dex_file_; 165f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier size_t current_class_index_; 166f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier bool from_loaded_oat_; // We only need to compare mismatches between what we load now 167f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // and what was loaded before. Any old duplicates must have been 168f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // OK, and any new "internal" duplicates are as well (they must 169f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // be from multidex, which resolves correctly). 170f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier}; 171f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 172f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierstatic void AddDexFilesFromOat(const OatFile* oat_file, 173f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier bool already_loaded, 174f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier /*out*/std::priority_queue<DexFileAndClassPair>* heap) { 175f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier for (const OatDexFile* oat_dex_file : oat_file->GetOatDexFiles()) { 176f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::string error; 177f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::unique_ptr<const DexFile> dex_file = oat_dex_file->OpenDexFile(&error); 178f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (dex_file == nullptr) { 179f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier LOG(WARNING) << "Could not create dex file from oat file: " << error; 180f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } else if (dex_file->NumClassDefs() > 0U) { 181f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier heap->emplace(dex_file.release(), /*current_class_index*/0U, already_loaded); 182f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 183f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 184f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 185f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 186f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierstatic void AddNext(/*inout*/DexFileAndClassPair* original, 187f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier /*inout*/std::priority_queue<DexFileAndClassPair>* heap) { 188f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (original->DexFileHasMoreClasses()) { 189f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier original->Next(); 190f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier heap->push(std::move(*original)); 191f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 192f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 193f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 194f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// Check for class-def collisions in dex files. 195f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// 196f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// This works by maintaining a heap with one class from each dex file, sorted by the class 197f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// descriptor. Then a dex-file/class pair is continually removed from the heap and compared 198f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// against the following top element. If the descriptor is the same, it is now checked whether 199f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// the two elements agree on whether their dex file was from an already-loaded oat-file or the 200f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// new oat file. Any disagreement indicates a collision. 201f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierbool OatFileManager::HasCollisions(const OatFile* oat_file, 202f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::string* error_msg /*out*/) const { 203f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier DCHECK(oat_file != nullptr); 204f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier DCHECK(error_msg != nullptr); 205f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (!kDuplicateClassesCheck) { 206f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return false; 207f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 208f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 209f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Dex files are registered late - once a class is actually being loaded. We have to compare 210f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // against the open oat files. Take the oat_file_manager_lock_ that protects oat_files_ accesses. 211f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_); 212f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 213f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::priority_queue<DexFileAndClassPair> queue; 214f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 215f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Add dex files from already loaded oat files, but skip boot. 216f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const OatFile* boot_oat = GetBootOatFile(); 21780b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier // The same OatFile can be loaded multiple times at different addresses. In this case, we don't 21880b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier // need to check both against each other since they would have resolved the same way at compile 21980b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier // time. 22080b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier std::unordered_set<std::string> unique_locations; 221f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier for (const std::unique_ptr<const OatFile>& loaded_oat_file : oat_files_) { 22280b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier DCHECK_NE(loaded_oat_file.get(), oat_file); 22380b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier const std::string& location = loaded_oat_file->GetLocation(); 22480b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier if (loaded_oat_file.get() != boot_oat && 22580b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier location != oat_file->GetLocation() && 22680b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier unique_locations.find(location) == unique_locations.end()) { 22780b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier unique_locations.insert(location); 228f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier AddDexFilesFromOat(loaded_oat_file.get(), /*already_loaded*/true, &queue); 229f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 230f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 231f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 232f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (queue.empty()) { 233f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // No other oat files, return early. 234f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return false; 235f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 236f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 237f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Add dex files from the oat file to check. 238f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier AddDexFilesFromOat(oat_file, /*already_loaded*/false, &queue); 239f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 240f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Now drain the queue. 241f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier while (!queue.empty()) { 242f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Modifying the top element is only safe if we pop right after. 24380b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier DexFileAndClassPair compare_pop(queue.top()); 244f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier queue.pop(); 245f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 246f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Compare against the following elements. 247f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier while (!queue.empty()) { 24880b37b7e679a530738c9bcbd39873b6dacf177e5Mathieu Chartier DexFileAndClassPair top(queue.top()); 249f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 250f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (strcmp(compare_pop.GetCachedDescriptor(), top.GetCachedDescriptor()) == 0) { 251f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Same descriptor. Check whether it's crossing old-oat-files to new-oat-files. 252f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (compare_pop.FromLoadedOat() != top.FromLoadedOat()) { 253f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier *error_msg = 254f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier StringPrintf("Found duplicated class when checking oat files: '%s' in %s and %s", 255f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier compare_pop.GetCachedDescriptor(), 256f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier compare_pop.GetDexFile()->GetLocation().c_str(), 257f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier top.GetDexFile()->GetLocation().c_str()); 258f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return true; 259f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 260f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier queue.pop(); 261f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier AddNext(&top, &queue); 262f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } else { 263f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Something else. Done here. 264f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier break; 265f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 266f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 267f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier AddNext(&compare_pop, &queue); 268f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 269f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 270f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return false; 271f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 272f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 273f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartierstd::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat( 274f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const char* dex_location, 275f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const char* oat_location, 276e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier const OatFile** out_oat_file, 277f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::vector<std::string>* error_msgs) { 278f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier CHECK(dex_location != nullptr); 279f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier CHECK(error_msgs != nullptr); 280f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 281f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Verify we aren't holding the mutator lock, which could starve GC if we 282f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // have to generate or relocate an oat file. 283f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier Locks::mutator_lock_->AssertNotHeld(Thread::Current()); 284f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 285f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier OatFileAssistant oat_file_assistant(dex_location, 286f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier oat_location, 287f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier kRuntimeISA, 288f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier !Runtime::Current()->IsAotCompiler()); 289f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 290f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Lock the target oat location to avoid races generating and loading the 291f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // oat file. 292f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::string error_msg; 293f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (!oat_file_assistant.Lock(/*out*/&error_msg)) { 294f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Don't worry too much if this fails. If it does fail, it's unlikely we 295f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // can generate an oat file anyway. 296f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier VLOG(class_linker) << "OatFileAssistant::Lock: " << error_msg; 297f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 298f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 299f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const OatFile* source_oat_file = nullptr; 300f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 301e722d2921615102941ca4b6717c9d9e1edae1192Nicolas Geoffray // Update the oat file on disk if we can. This may fail, but that's okay. 302e722d2921615102941ca4b6717c9d9e1edae1192Nicolas Geoffray // Best effort is all that matters here. 303e722d2921615102941ca4b6717c9d9e1edae1192Nicolas Geoffray if (!oat_file_assistant.MakeUpToDate(/*out*/&error_msg)) { 304a28267fdbcafbbc08bae56c5997c8ffa9a008c50Nicolas Geoffray LOG(INFO) << error_msg; 305f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 306f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 307f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Get the oat file on disk. 308f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::unique_ptr<const OatFile> oat_file(oat_file_assistant.GetBestOatFile().release()); 309f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (oat_file != nullptr) { 310f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Take the file only if it has no collisions, or we must take it because of preopting. 311f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier bool accept_oat_file = !HasCollisions(oat_file.get(), /*out*/ &error_msg); 312f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (!accept_oat_file) { 313f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Failed the collision check. Print warning. 314f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (Runtime::Current()->IsDexFileFallbackEnabled()) { 315f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier LOG(WARNING) << "Found duplicate classes, falling back to interpreter mode for " 316f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier << dex_location; 317f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } else { 318f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier LOG(WARNING) << "Found duplicate classes, dex-file-fallback disabled, will be failing to " 319f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier " load classes for " << dex_location; 320f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 321f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier LOG(WARNING) << error_msg; 322f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 323f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // However, if the app was part of /system and preopted, there is no original dex file 324f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // available. In that case grudgingly accept the oat file. 325f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (!DexFile::MaybeDex(dex_location)) { 326f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier accept_oat_file = true; 327f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier LOG(WARNING) << "Dex location " << dex_location << " does not seem to include dex file. " 328f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier << "Allow oat file use. This is potentially dangerous."; 329f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 330f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 331f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 332f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (accept_oat_file) { 333f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier VLOG(class_linker) << "Registering " << oat_file->GetLocation(); 334f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier source_oat_file = RegisterOatFile(std::move(oat_file)); 335e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier *out_oat_file = source_oat_file; 336f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 337f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 338f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 339f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::vector<std::unique_ptr<const DexFile>> dex_files; 340f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 341f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Load the dex files from the oat file. 342f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (source_oat_file != nullptr) { 343f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier dex_files = oat_file_assistant.LoadDexFiles(*source_oat_file, dex_location); 344f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (dex_files.empty()) { 345f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier error_msgs->push_back("Failed to open dex files from " + source_oat_file->GetLocation()); 346f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 347f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 348f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 349f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Fall back to running out of the original dex file if we couldn't load any 350f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // dex_files from the oat file. 351f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (dex_files.empty()) { 352f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (oat_file_assistant.HasOriginalDexFiles()) { 353f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (Runtime::Current()->IsDexFileFallbackEnabled()) { 354f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier if (!DexFile::Open(dex_location, dex_location, /*out*/ &error_msg, &dex_files)) { 355f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier LOG(WARNING) << error_msg; 356f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier error_msgs->push_back("Failed to open dex files from " + std::string(dex_location)); 357f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 358f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } else { 359f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier error_msgs->push_back("Fallback mode disabled, skipping dex files."); 360f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 361f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } else { 362f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier error_msgs->push_back("No original dex files found for dex location " 363f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier + std::string(dex_location)); 364f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 365f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier } 366f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier return dex_files; 367f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} 368f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier 369e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartierbool OatFileManager::RegisterOatFileLocation(const std::string& oat_location) { 370e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier WriterMutexLock mu(Thread::Current(), *Locks::oat_file_count_lock_); 371e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier auto it = oat_file_count_.find(oat_location); 372e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier if (it != oat_file_count_.end()) { 373e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier ++it->second; 374e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier return false; 375e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier } 376e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier oat_file_count_.insert(std::pair<std::string, size_t>(oat_location, 1u)); 377e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier return true; 378e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier} 379e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier 380e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartiervoid OatFileManager::UnRegisterOatFileLocation(const std::string& oat_location) { 381e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier WriterMutexLock mu(Thread::Current(), *Locks::oat_file_count_lock_); 382e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier auto it = oat_file_count_.find(oat_location); 383e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier if (it != oat_file_count_.end()) { 384e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier --it->second; 385e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier if (it->second == 0) { 386e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier oat_file_count_.erase(it); 387e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier } 388e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier } 389e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier} 390e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier 391f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier} // namespace art 392