am 7ba7936d: am 756ee4e0: Find OatDexFile by DexFile name and checksum, not just checksum
* commit '7ba7936d212634eef17120d190dcfdfdf09f365e':
Find OatDexFile by DexFile name and checksum, not just checksum
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index 74b5da9..bfba9c0 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -110,7 +110,9 @@
ASSERT_EQ("lue.art", oat_header.GetImageFileLocation());
const DexFile* dex_file = java_lang_dex_file_;
- const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file->GetLocation());
+ uint32_t dex_file_checksum = dex_file->GetLocationChecksum();
+ const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file->GetLocation(),
+ &dex_file_checksum);
CHECK_EQ(dex_file->GetLocationChecksum(), oat_dex_file->GetDexFileLocationChecksum());
for (size_t i = 0; i < dex_file->NumClassDefs(); i++) {
const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 5728bf6..e23f1b1 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -671,14 +671,17 @@
const OatFile* ClassLinker::FindOpenedOatFileForDexFile(const DexFile& dex_file) {
ReaderMutexLock mu(Thread::Current(), dex_lock_);
- return FindOpenedOatFileFromDexLocation(dex_file.GetLocation());
+ return FindOpenedOatFileFromDexLocation(dex_file.GetLocation(), dex_file.GetLocationChecksum());
}
-const OatFile* ClassLinker::FindOpenedOatFileFromDexLocation(const std::string& dex_location) {
+const OatFile* ClassLinker::FindOpenedOatFileFromDexLocation(const std::string& dex_location,
+ uint32_t dex_location_checksum) {
for (size_t i = 0; i < oat_files_.size(); i++) {
const OatFile* oat_file = oat_files_[i];
DCHECK(oat_file != NULL);
- const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location, false);
+ const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location,
+ &dex_location_checksum,
+ false);
if (oat_dex_file != NULL) {
return oat_file;
}
@@ -714,7 +717,7 @@
<< ", found " << actual_image_oat_offset;
return NULL;
}
- const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location);
+ const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location, &dex_location_checksum);
if (oat_dex_file == NULL) {
VLOG(class_linker) << "Failed to find oat file at " << oat_location << " containing " << dex_location;
return NULL;
@@ -732,9 +735,10 @@
}
const DexFile* ClassLinker::FindOrCreateOatFileForDexLocation(const std::string& dex_location,
+ uint32_t dex_location_checksum,
const std::string& oat_location) {
WriterMutexLock mu(Thread::Current(), dex_lock_);
- return FindOrCreateOatFileForDexLocationLocked(dex_location, oat_location);
+ return FindOrCreateOatFileForDexLocationLocked(dex_location, dex_location_checksum, oat_location);
}
class ScopedFlock {
@@ -792,13 +796,8 @@
};
const DexFile* ClassLinker::FindOrCreateOatFileForDexLocationLocked(const std::string& dex_location,
+ uint32_t dex_location_checksum,
const std::string& oat_location) {
- uint32_t dex_location_checksum;
- if (!DexFile::GetChecksum(dex_location, &dex_location_checksum)) {
- LOG(ERROR) << "Failed to compute checksum '" << dex_location << "'";
- return NULL;
- }
-
// We play a locking game here so that if two different processes
// race to generate (or worse, one tries to open a partial generated
// file) we will be okay. This is actually common with apps that use
@@ -831,14 +830,17 @@
return NULL;
}
RegisterOatFileLocked(*oat_file);
- const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location);
+ const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location, &dex_location_checksum);
if (oat_dex_file == NULL) {
- LOG(ERROR) << "Failed to find dex file " << dex_location << " in generated oat file: " << oat_location;
+ LOG(ERROR) << "Failed to find dex file " << dex_location
+ << " (checksum " << dex_location_checksum
+ << ") in generated oat file: " << oat_location;
return NULL;
}
const DexFile* result = oat_dex_file->OpenDexFile();
- CHECK_EQ(dex_location_checksum, result->GetLocationChecksum()) << std::hex
- << "dex_location_checksum=" << dex_location_checksum
+ CHECK_EQ(dex_location_checksum, result->GetLocationChecksum())
+ << "dex_location=" << dex_location << " oat_location=" << oat_location << std::hex
+ << " dex_location_checksum=" << dex_location_checksum
<< " DexFile::GetLocationChecksum()=" << result->GetLocationChecksum();
return result;
}
@@ -853,10 +855,11 @@
bool image_check = ((oat_file->GetOatHeader().GetImageFileLocationOatChecksum() == image_oat_checksum)
&& (oat_file->GetOatHeader().GetImageFileLocationOatDataBegin() == image_oat_data_begin));
- const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location);
+ const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location, &dex_location_checksum);
if (oat_dex_file == NULL) {
LOG(ERROR) << "oat file " << oat_file->GetLocation()
- << " does not contain contents for " << dex_location;
+ << " does not contain contents for " << dex_location
+ << " with checksum " << dex_location_checksum;
std::vector<const OatFile::OatDexFile*> oat_dex_files = oat_file->GetOatDexFiles();
for (size_t i = 0; i < oat_dex_files.size(); i++) {
const OatFile::OatDexFile* oat_dex_file = oat_dex_files[i];
@@ -898,15 +901,17 @@
return NULL;
}
RegisterOatFileLocked(*oat_file);
- return oat_file->GetOatDexFile(dex_location)->OpenDexFile();
+ return oat_file->GetOatDexFile(dex_location, &dex_location_checksum)->OpenDexFile();
}
-const DexFile* ClassLinker::FindDexFileInOatFileFromDexLocation(const std::string& dex_location) {
+const DexFile* ClassLinker::FindDexFileInOatFileFromDexLocation(const std::string& dex_location,
+ uint32_t dex_location_checksum) {
WriterMutexLock mu(Thread::Current(), dex_lock_);
- const OatFile* open_oat_file = FindOpenedOatFileFromDexLocation(dex_location);
+ const OatFile* open_oat_file = FindOpenedOatFileFromDexLocation(dex_location,
+ dex_location_checksum);
if (open_oat_file != NULL) {
- return open_oat_file->GetOatDexFile(dex_location)->OpenDexFile();
+ return open_oat_file->GetOatDexFile(dex_location, &dex_location_checksum)->OpenDexFile();
}
// Look for an existing file next to dex. for example, for
@@ -918,7 +923,7 @@
if (!DexFile::GetChecksum(dex_location, &dex_location_checksum)) {
// If no classes.dex found in dex_location, it has been stripped, assume oat is up-to-date.
// This is the common case in user builds for jar's and apk's in the /system directory.
- const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location);
+ const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location, NULL);
CHECK(oat_dex_file != NULL) << odex_filename << " " << dex_location;
RegisterOatFileLocked(*oat_file);
return oat_dex_file->OpenDexFile();
@@ -954,7 +959,7 @@
// Try to generate oat file if it wasn't found or was obsolete.
std::string oat_cache_filename(GetDalvikCacheFilenameOrDie(dex_location));
- return FindOrCreateOatFileForDexLocationLocked(dex_location, oat_cache_filename);
+ return FindOrCreateOatFileForDexLocationLocked(dex_location, dex_location_checksum, oat_cache_filename);
}
const OatFile* ClassLinker::FindOpenedOatFileFromOatLocation(const std::string& oat_location) {
@@ -1036,7 +1041,7 @@
for (int32_t i = 0; i < dex_caches->GetLength(); i++) {
SirtRef<mirror::DexCache> dex_cache(self, dex_caches->Get(i));
const std::string& dex_file_location(dex_cache->GetLocation()->ToModifiedUtf8());
- const OatFile::OatDexFile* oat_dex_file = oat_file.GetOatDexFile(dex_file_location);
+ const OatFile::OatDexFile* oat_dex_file = oat_file.GetOatDexFile(dex_file_location, NULL);
CHECK(oat_dex_file != NULL) << oat_file.GetLocation() << " " << dex_file_location;
const DexFile* dex_file = oat_dex_file->OpenDexFile();
if (dex_file == NULL) {
@@ -1501,7 +1506,9 @@
DCHECK_NE(class_def_idx, DexFile::kDexNoIndex16);
const OatFile* oat_file = FindOpenedOatFileForDexFile(dex_file);
CHECK(oat_file != NULL) << dex_file.GetLocation();
- const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation());
+ uint dex_location_checksum = dex_file.GetLocationChecksum();
+ const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation(),
+ &dex_location_checksum);
CHECK(oat_dex_file != NULL) << dex_file.GetLocation();
const OatFile::OatClass* oat_class = oat_dex_file->GetOatClass(class_def_idx);
CHECK(oat_class != NULL) << dex_file.GetLocation() << " " << class_def_idx;
@@ -2540,7 +2547,9 @@
}
CHECK(oat_file != NULL) << dex_file.GetLocation() << " " << PrettyClass(klass);
- const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation());
+ uint dex_location_checksum = dex_file.GetLocationChecksum();
+ const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation(),
+ &dex_location_checksum);
CHECK(oat_dex_file != NULL) << dex_file.GetLocation() << " " << PrettyClass(klass);
const char* descriptor = ClassHelper(klass).GetDescriptor();
uint16_t class_def_index = klass->GetDexClassDefIndex();
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 3ffcf14..baeec66 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -258,17 +258,20 @@
// it is missing or out of date. Returns the DexFile from within the
// created oat file.
const DexFile* FindOrCreateOatFileForDexLocation(const std::string& dex_location,
+ uint32_t dex_location_checksum,
const std::string& oat_location)
LOCKS_EXCLUDED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
const DexFile* FindOrCreateOatFileForDexLocationLocked(const std::string& dex_location,
+ uint32_t dex_location_checksum,
const std::string& oat_location)
EXCLUSIVE_LOCKS_REQUIRED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Find a DexFile within an OatFile given a DexFile location. Note
// that this returns null if the location checksum of the DexFile
// does not match the OatFile.
- const DexFile* FindDexFileInOatFileFromDexLocation(const std::string& location)
+ const DexFile* FindDexFileInOatFileFromDexLocation(const std::string& location,
+ uint32_t location_checksum)
LOCKS_EXCLUDED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -494,7 +497,8 @@
const OatFile* FindOpenedOatFileForDexFile(const DexFile& dex_file)
LOCKS_EXCLUDED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- const OatFile* FindOpenedOatFileFromDexLocation(const std::string& dex_location)
+ const OatFile* FindOpenedOatFileFromDexLocation(const std::string& dex_location,
+ uint32_t dex_location_checksum)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_, dex_lock_);
const OatFile* FindOpenedOatFileFromOatLocation(const std::string& oat_location)
SHARED_LOCKS_REQUIRED(dex_lock_);
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 4c60b8f..823013a 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -89,25 +89,35 @@
if (sourceName.c_str() == NULL) {
return 0;
}
- std::string source(sourceName.c_str());
+ std::string dex_location(sourceName.c_str());
NullableScopedUtfChars outputName(env, javaOutputName);
if (env->ExceptionCheck()) {
return 0;
}
ScopedObjectAccess soa(env);
- const DexFile* dex_file;
- if (outputName.c_str() == NULL) {
- dex_file = Runtime::Current()->GetClassLinker()->FindDexFileInOatFileFromDexLocation(source);
- } else {
- std::string output(outputName.c_str());
- dex_file =
- Runtime::Current()->GetClassLinker()->FindOrCreateOatFileForDexLocation(source, output);
- }
- if (dex_file == NULL) {
- LOG(WARNING) << "Failed to open dex file: " << source;
+
+ uint32_t dex_location_checksum;
+ if (!DexFile::GetChecksum(dex_location, &dex_location_checksum)) {
+ LOG(WARNING) << "Failed to compute checksum: " << dex_location;
ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/io/IOException;",
- "Unable to open dex file: %s", source.c_str());
+ "Unable to get checksum of dex file: %s", dex_location.c_str());
+ return 0;
+ }
+
+ ClassLinker* linker = Runtime::Current()->GetClassLinker();
+ const DexFile* dex_file;
+ if (outputName.c_str() == NULL) {
+ dex_file = linker->FindDexFileInOatFileFromDexLocation(dex_location, dex_location_checksum);
+ } else {
+ std::string oat_location(outputName.c_str());
+ dex_file = linker->FindOrCreateOatFileForDexLocation(dex_location, dex_location_checksum, oat_location);
+ }
+ if (dex_file == NULL) {
+ LOG(WARNING) << "Failed to open dex file: " << dex_location;
+ ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
+ soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/io/IOException;",
+ "Unable to open dex file: %s", dex_location.c_str());
return 0;
}
return static_cast<jint>(reinterpret_cast<uintptr_t>(dex_file));
@@ -220,7 +230,7 @@
UniquePtr<const OatFile> oat_file(OatFile::Open(odex_filename, odex_filename, NULL, false));
if (oat_file.get() != NULL) {
ScopedObjectAccess soa(env);
- const art::OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(filename.c_str());
+ const art::OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(filename.c_str(), NULL);
if (oat_dex_file == NULL) {
if (debug_logging) {
LOG(INFO) << "DexFile_isDexOptNeeded GetOatDexFile failed";
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 418af0f..7ecaf01 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -323,23 +323,29 @@
return end_;
}
-const OatFile::OatDexFile* OatFile::GetOatDexFile(const std::string& dex_file_location,
+const OatFile::OatDexFile* OatFile::GetOatDexFile(const std::string& dex_location,
+ const uint32_t* const dex_location_checksum,
bool warn_if_not_found) const {
- Table::const_iterator it = oat_dex_files_.find(dex_file_location);
- if (it == oat_dex_files_.end()) {
- if (warn_if_not_found) {
- LOG(WARNING) << "Failed to find OatDexFile for DexFile " << dex_file_location
- << " in OatFile " << GetLocation();
- if (kIsDebugBuild) {
- for (Table::const_iterator it = oat_dex_files_.begin(); it != oat_dex_files_.end(); ++it) {
- LOG(WARNING) << "OatFile " << GetLocation()
- << " contains OatDexFile " << it->second->GetDexFileLocation();
- }
+ Table::const_iterator it = oat_dex_files_.find(dex_location);
+ if (it != oat_dex_files_.end()) {
+ const OatFile::OatDexFile* oat_dex_file = it->second;
+ if (dex_location_checksum == NULL ||
+ oat_dex_file->GetDexFileLocationChecksum() == *dex_location_checksum) {
+ return oat_dex_file;
+ }
+ }
+
+ if (warn_if_not_found) {
+ LOG(WARNING) << "Failed to find OatDexFile for DexFile " << dex_location
+ << " in OatFile " << GetLocation();
+ if (kIsDebugBuild) {
+ for (Table::const_iterator it = oat_dex_files_.begin(); it != oat_dex_files_.end(); ++it) {
+ LOG(WARNING) << "OatFile " << GetLocation()
+ << " contains OatDexFile " << it->second->GetDexFileLocation();
}
}
- return NULL;
}
- return it->second;
+ return NULL;
}
std::vector<const OatFile::OatDexFile*> OatFile::GetOatDexFiles() const {
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index bbd2615..270976f 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -204,7 +204,8 @@
DISALLOW_COPY_AND_ASSIGN(OatDexFile);
};
- const OatDexFile* GetOatDexFile(const std::string& dex_file_location,
+ const OatDexFile* GetOatDexFile(const std::string& dex_location,
+ const uint32_t* const dex_location_checksum,
bool exception_if_not_found = true) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
std::vector<const OatDexFile*> GetOatDexFiles() const;