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