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;