Fix DDMS large heap memory profiling.

Change-Id: Iad91482aaf6fdff2ef1ba2e5ff9ef11cd7ec4a1b
diff --git a/src/gc/large_object_space.cc b/src/gc/large_object_space.cc
index 81f048c..df7e68d 100644
--- a/src/gc/large_object_space.cc
+++ b/src/gc/large_object_space.cc
@@ -118,8 +118,14 @@
 }
 
 bool LargeObjectMapSpace::Contains(const mirror::Object* obj) const {
-  MutexLock mu(Thread::Current(), lock_);
-  return mem_maps_.find(const_cast<mirror::Object*>(obj)) != mem_maps_.end();
+  Thread* self = Thread::Current();
+  if (lock_.IsExclusiveHeld(self)) {
+    // We hold lock_ so do the check.
+    return mem_maps_.find(const_cast<mirror::Object*>(obj)) != mem_maps_.end();
+  } else {
+    MutexLock mu(self, lock_);
+    return mem_maps_.find(const_cast<mirror::Object*>(obj)) != mem_maps_.end();
+  }
 }
 
 FreeListSpace* FreeListSpace::Create(const std::string& name, byte* requested_begin, size_t size) {
diff --git a/src/gc/large_object_space.h b/src/gc/large_object_space.h
index 1654f9c..8a2f970 100644
--- a/src/gc/large_object_space.h
+++ b/src/gc/large_object_space.h
@@ -100,7 +100,8 @@
   virtual mirror::Object* Alloc(Thread* self, size_t num_bytes);
   size_t Free(Thread* self, mirror::Object* ptr);
   virtual void Walk(DlMallocSpace::WalkCallback, void* arg);
-  virtual bool Contains(const mirror::Object* obj) const;
+  // TODO: disabling thread safety analysis as this may be called when we already hold lock_.
+  virtual bool Contains(const mirror::Object* obj) const NO_THREAD_SAFETY_ANALYSIS;
 private:
   LargeObjectMapSpace(const std::string& name);
   virtual ~LargeObjectMapSpace() {}
diff --git a/src/heap.cc b/src/heap.cc
index 7ec6085..718226d 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -579,8 +579,6 @@
       return true;
     }
   }
-  // Note: Doing this only works for the free list version of the large object space since the
-  // multiple memory map version uses a lock to do the contains check.
   return large_object_space_->Contains(obj);
 }