Assorted fixes

- Match ClassLinker::oat_files_ against cached oat file locations
- Have DexFile_isDexOptNeeded do checksum comparsion of oat to dex
- Complete TODO in Heap::Lock to use TryLock before switching to kVmWait
- Fix ThrowNew to use Throwable constructor without String when no msg is available

Change-Id: Ie9d7bfef9e80b77e5f7625a4d7c9c4a23c7b30b5
diff --git a/src/class_linker.cc b/src/class_linker.cc
index eda60ca..6dc44d1 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -585,7 +585,7 @@
   return FindOatFile(OatFile::DexFileToOatFilename(dex_file));
 }
 
-const OatFile* ClassLinker::FindOatFile(const std::string& location) {
+const OatFile* ClassLinker::FindOpenedOatFile(const std::string& location) {
   for (size_t i = 0; i < oat_files_.size(); i++) {
     const OatFile* oat_file = oat_files_[i];
     DCHECK(oat_file != NULL);
@@ -593,23 +593,37 @@
       return oat_file;
     }
   }
+  return NULL;
+}
 
-  const OatFile* oat_file = OatFile::Open(location, "", NULL);
+const OatFile* ClassLinker::FindOatFile(const std::string& location) {
+  const OatFile* oat_file = FindOpenedOatFile(location);
+  if (oat_file != NULL) {
+    return oat_file;
+  }
+
+  oat_file = OatFile::Open(location, "", NULL);
   if (oat_file == NULL) {
     if (location.empty() || location[0] != '/') {
       LOG(ERROR) << "Failed to open oat file from " << location;
       return NULL;
     }
+
     // not found in /foo/bar/baz.oat? try /data/art-cache/foo@bar@baz.oat
     std::string cache_location = GetArtCacheOatFilenameOrDie(location);
+    oat_file = FindOpenedOatFile(cache_location);
+    if (oat_file != NULL) {
+      return oat_file;
+    }
     oat_file = OatFile::Open(cache_location, "", NULL);
     if (oat_file  == NULL) {
       LOG(ERROR) << "Failed to open oat file from " << location << " or " << cache_location << ".";
       return NULL;
     }
-
-
   }
+
+  CHECK(oat_file != NULL) << location;
+  oat_files_.push_back(oat_file);
   return oat_file;
 }