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/heap.cc b/src/heap.cc
index d7c9584..73b6640 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -585,9 +585,15 @@
 }
 
 void Heap::Lock() {
-  // TODO: grab the lock, but put ourselves into Thread::kVmWait if it looks like
-  // we're going to have to wait on the mutex.
-  lock_->Lock();
+  // Grab the lock, but put ourselves into Thread::kVmWait if it looks
+  // like we're going to have to wait on the mutex. This prevents
+  // deadlock if another thread is calling CollectGarbageInternal,
+  // since they will have the heap lock and be waiting for mutators to
+  // suspend.
+  if (!lock_->TryLock()) {
+    ScopedThreadStateChange tsc(Thread::Current(), Thread::kVmWait);
+    lock_->Lock();
+  }
 }
 
 void Heap::Unlock() {