Find OatDexFile by DexFile name and checksum, not just checksum

Bug: 10614658
Change-Id: Ie0b5a34fd396b6299000c37909108c5e7e6ab80f
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();