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