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_);