Fix to prevent a dex file from being verified multiple times.
Instead of verifying a dex file whenever one is initialized, they're now
verified when not opened from memory. Also, the way dalvik_system_DexFile
opens dex files has been changed to check for an existing oat file and
get the corresponding dex file from there instead.
Change-Id: I75fc26247150107d628e2c4e364ef8a53fbf9481
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 5687453..2f1dc9a 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -749,7 +749,6 @@
if (oat_file.get() != NULL) {
const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation());
if (dex_file.GetHeader().checksum_ == oat_dex_file->GetDexFileChecksum()) {
- RegisterOatFileLocked(*oat_file.get());
return oat_file.release();
}
LOG(WARNING) << ".oat file " << oat_file->GetLocation()
@@ -817,7 +816,13 @@
}
const OatFile* ClassLinker::FindOatFileFromOatLocation(const std::string& oat_location) {
- const OatFile* oat_file = OatFile::Open(oat_location, "", NULL);
+ MutexLock mu(dex_lock_);
+ const OatFile* oat_file = FindOpenedOatFileFromOatLocation(oat_location);
+ if (oat_file != NULL) {
+ return oat_file;
+ }
+
+ oat_file = OatFile::Open(oat_location, "", NULL);
if (oat_file == NULL) {
if (oat_location.empty() || oat_location[0] != '/') {
LOG(ERROR) << "Failed to open oat file from " << oat_location;
@@ -838,9 +843,30 @@
}
CHECK(oat_file != NULL) << oat_location;
+ RegisterOatFileLocked(*oat_file);
return oat_file;
}
+const DexFile* ClassLinker::FindDexFileFromDexLocation(const std::string& location) {
+ std::string oat_location(OatFile::DexFilenameToOatFilename(location));
+ const OatFile* oat_file = FindOatFileFromOatLocation(oat_location);
+ if (oat_file == NULL) {
+ return NULL;
+ }
+ const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(location);
+ if (oat_dex_file == NULL) {
+ return NULL;
+ }
+ const DexFile* dex_file = oat_dex_file->OpenDexFile();
+ if (dex_file == NULL) {
+ return NULL;
+ }
+ if (oat_dex_file->GetDexFileChecksum() != dex_file->GetHeader().checksum_) {
+ return NULL;
+ }
+ return dex_file;
+}
+
void ClassLinker::InitFromImage() {
VLOG(startup) << "ClassLinker::InitFromImage entering";
CHECK(!init_done_);