Revert "Revert "Unload oat files""
Fixed a race where two threads calling OatFile::Open could both use
dlopen on the host.
Bug: 22720414
This reverts commit 72da5e7461fec3b1e116050f2e6f233efb9c54f3.
Change-Id: I1636045b724944d2a09417527280784967957095
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index 73b065f..3371a39 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -33,9 +33,10 @@
static constexpr bool kDuplicateClassesCheck = false;
const OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oat_file) {
- ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
+ WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
DCHECK(oat_file != nullptr);
if (kIsDebugBuild) {
+ CHECK(oat_files_.find(oat_file) == oat_files_.end());
for (const std::unique_ptr<const OatFile>& existing : oat_files_) {
CHECK_NE(oat_file.get(), existing.get()) << oat_file->GetLocation();
// Check that we don't have an oat file with the same address. Copies of the same oat file
@@ -44,13 +45,29 @@
}
}
have_non_pic_oat_file_ = have_non_pic_oat_file_ || !oat_file->IsPic();
- oat_files_.push_back(std::move(oat_file));
- return oat_files_.back().get();
+ const OatFile* ret = oat_file.get();
+ oat_files_.insert(std::move(oat_file));
+ return ret;
+}
+
+void OatFileManager::UnRegisterAndDeleteOatFile(const OatFile* oat_file) {
+ WriterMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
+ DCHECK(oat_file != nullptr);
+ std::unique_ptr<const OatFile> compare(oat_file);
+ auto it = oat_files_.find(compare);
+ CHECK(it != oat_files_.end());
+ oat_files_.erase(it);
+ compare.release();
}
const OatFile* OatFileManager::FindOpenedOatFileFromOatLocation(const std::string& oat_location)
const {
ReaderMutexLock mu(Thread::Current(), *Locks::oat_file_manager_lock_);
+ return FindOpenedOatFileFromOatLocationLocked(oat_location);
+}
+
+const OatFile* OatFileManager::FindOpenedOatFileFromOatLocationLocked(
+ const std::string& oat_location) const {
for (const std::unique_ptr<const OatFile>& oat_file : oat_files_) {
if (oat_file->GetLocation() == oat_location) {
return oat_file.get();
@@ -81,6 +98,9 @@
}
OatFileManager::~OatFileManager() {
+ // Explicitly clear oat_files_ since the OatFile destructor calls back into OatFileManager for
+ // UnRegisterOatFileLocation.
+ oat_files_.clear();
}
const OatFile* OatFileManager::RegisterImageOatFile(gc::space::ImageSpace* space) {
@@ -95,17 +115,9 @@
current_class_index_(current_class_index),
from_loaded_oat_(from_loaded_oat) {}
- DexFileAndClassPair(DexFileAndClassPair&& rhs) {
- *this = std::move(rhs);
- }
+ DexFileAndClassPair(DexFileAndClassPair&& rhs) = default;
- DexFileAndClassPair& operator=(DexFileAndClassPair&& rhs) {
- cached_descriptor_ = rhs.cached_descriptor_;
- dex_file_ = std::move(rhs.dex_file_);
- current_class_index_ = rhs.current_class_index_;
- from_loaded_oat_ = rhs.from_loaded_oat_;
- return *this;
- }
+ DexFileAndClassPair& operator=(DexFileAndClassPair&& rhs) = default;
const char* GetCachedDescriptor() const {
return cached_descriptor_;
@@ -127,6 +139,7 @@
void Next() {
++current_class_index_;
+ cached_descriptor_ = nullptr;
}
size_t GetCurrentClassIndex() const {
@@ -253,6 +266,7 @@
std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat(
const char* dex_location,
const char* oat_location,
+ const OatFile** out_oat_file,
std::vector<std::string>* error_msgs) {
CHECK(dex_location != nullptr);
CHECK(error_msgs != nullptr);
@@ -311,6 +325,7 @@
if (accept_oat_file) {
VLOG(class_linker) << "Registering " << oat_file->GetLocation();
source_oat_file = RegisterOatFile(std::move(oat_file));
+ *out_oat_file = source_oat_file;
}
}
@@ -344,4 +359,26 @@
return dex_files;
}
+bool OatFileManager::RegisterOatFileLocation(const std::string& oat_location) {
+ WriterMutexLock mu(Thread::Current(), *Locks::oat_file_count_lock_);
+ auto it = oat_file_count_.find(oat_location);
+ if (it != oat_file_count_.end()) {
+ ++it->second;
+ return false;
+ }
+ oat_file_count_.insert(std::pair<std::string, size_t>(oat_location, 1u));
+ return true;
+}
+
+void OatFileManager::UnRegisterOatFileLocation(const std::string& oat_location) {
+ WriterMutexLock mu(Thread::Current(), *Locks::oat_file_count_lock_);
+ auto it = oat_file_count_.find(oat_location);
+ if (it != oat_file_count_.end()) {
+ --it->second;
+ if (it->second == 0) {
+ oat_file_count_.erase(it);
+ }
+ }
+}
+
} // namespace art