Improve the OOME fragmentation message.

Change-Id: I390d3622f8d572ec7e34ea6dff9e1e0936e81ac1
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index e9adca0..19715e9 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -805,37 +805,23 @@
   return NULL;
 }
 
-static void MSpaceChunkCallback(void* start, void* end, size_t used_bytes, void* arg) {
-  size_t chunk_size = reinterpret_cast<uint8_t*>(end) - reinterpret_cast<uint8_t*>(start);
-  if (used_bytes < chunk_size) {
-    size_t chunk_free_bytes = chunk_size - used_bytes;
-    size_t& max_contiguous_allocation = *reinterpret_cast<size_t*>(arg);
-    max_contiguous_allocation = std::max(max_contiguous_allocation, chunk_free_bytes);
-  }
-}
-
-void Heap::ThrowOutOfMemoryError(Thread* self, size_t byte_count, bool large_object_allocation) {
+void Heap::ThrowOutOfMemoryError(Thread* self, size_t byte_count, AllocatorType allocator_type) {
   std::ostringstream oss;
   size_t total_bytes_free = GetFreeMemory();
   oss << "Failed to allocate a " << byte_count << " byte allocation with " << total_bytes_free
       << " free bytes";
   // If the allocation failed due to fragmentation, print out the largest continuous allocation.
-  if (!large_object_allocation && total_bytes_free >= byte_count) {
-    size_t max_contiguous_allocation = 0;
-    for (const auto& space : continuous_spaces_) {
-      if (space->IsMallocSpace()) {
-        // To allow the Walk/InspectAll() to exclusively-lock the mutator
-        // lock, temporarily release the shared access to the mutator
-        // lock here by transitioning to the suspended state.
-        Locks::mutator_lock_->AssertSharedHeld(self);
-        self->TransitionFromRunnableToSuspended(kSuspended);
-        space->AsMallocSpace()->Walk(MSpaceChunkCallback, &max_contiguous_allocation);
-        self->TransitionFromSuspendedToRunnable();
-        Locks::mutator_lock_->AssertSharedHeld(self);
-      }
+  if (allocator_type != kAllocatorTypeLOS && total_bytes_free >= byte_count) {
+    space::MallocSpace* space = nullptr;
+    if (allocator_type == kAllocatorTypeNonMoving) {
+      space = non_moving_space_;
+    } else if (allocator_type == kAllocatorTypeRosAlloc ||
+               allocator_type == kAllocatorTypeDlMalloc) {
+      space = main_space_;
     }
-    oss << "; failed due to fragmentation (largest possible contiguous allocation "
-        <<  max_contiguous_allocation << " bytes)";
+    if (space != nullptr) {
+      space->LogFragmentationAllocFailure(oss, byte_count);
+    }
   }
   self->ThrowOutOfMemoryError(oss.str().c_str());
 }
@@ -1188,7 +1174,7 @@
   }
   ptr = TryToAllocate<true, true>(self, allocator, alloc_size, bytes_allocated, usable_size);
   if (ptr == nullptr) {
-    ThrowOutOfMemoryError(self, alloc_size, allocator == kAllocatorTypeLOS);
+    ThrowOutOfMemoryError(self, alloc_size, allocator);
   }
   return ptr;
 }