ART: Fix DDM client hang transmitting native heap dump with MALLOC_IMPL=dlmalloc

VM acting as a DDM client hangs transmitting native heap segment data when dlmalloc
is used instead of default jemalloc. dlmalloc_inspect_all disallow any memory allocation
inside heap callback. So cannot send any data walking the heap, the same for logging.
Callback function also needs to acquire the heap bitmap lock. Finally, need to indicate
end of a space to flush data.

Change-Id: I9541962268dd58c2a4237fe1550c9e153252ab4a
Signed-off-by: Pavel Vyssotski <pavel.n.vyssotski@intel.com>
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index a9b70cb..c726c82 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -4316,6 +4316,12 @@
     size_t needed = (((length/ALLOCATION_UNIT_SIZE + 255) / 256) * 2) + 17;
     size_t bytesLeft = buf_.size() - (size_t)(p_ - &buf_[0]);
     if (bytesLeft < needed) {
+#if defined(HAVE_ANDROID_OS) && defined(USE_DLMALLOC)
+      // Cannot trigger memory allocation while walking native heap.
+      if (type_ == CHUNK_TYPE("NHSG")) {
+        return;
+      }
+#endif
       Flush();
     }
 
@@ -4435,7 +4441,9 @@
   HeapChunkContext context((what == HPSG_WHAT_MERGED_OBJECTS), native);
   if (native) {
 #if defined(HAVE_ANDROID_OS) && defined(USE_DLMALLOC)
+    ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_);
     dlmalloc_inspect_all(HeapChunkContext::HeapChunkCallback, &context);
+    HeapChunkContext::HeapChunkCallback(NULL, NULL, 0, &context);  // Indicate end of a space.
 #else
     UNIMPLEMENTED(WARNING) << "Native heap inspection is only supported with dlmalloc";
 #endif