Print memory usage in dex2oat shutdown

Example on mako:
I/dex2oat (31071): dex2oat took 31.195s (threads: 2) arena alloc=1013KB java alloc=13MB native alloc=32MB free=1490KB

Bug: 18069309

Change-Id: I08eac00842be35d4e659bddc8513f2062be725c9
diff --git a/build/Android.common_build.mk b/build/Android.common_build.mk
index 8f3e1ef..6ce3877 100644
--- a/build/Android.common_build.mk
+++ b/build/Android.common_build.mk
@@ -200,7 +200,7 @@
 
 ifeq ($(HOST_OS),linux)
   # Larger frame-size for host clang builds today
-  art_host_non_debug_cflags += -Wframe-larger-than=2700
+  art_host_non_debug_cflags += -Wframe-larger-than=3000
   art_target_non_debug_cflags += -Wframe-larger-than=1728
 endif
 
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index ba98bb5..4060d5b 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -378,6 +378,9 @@
   ArenaPool* GetArenaPool() {
     return &arena_pool_;
   }
+  const ArenaPool* GetArenaPool() const {
+    return &arena_pool_;
+  }
 
   bool WriteElf(const std::string& android_root,
                 bool is_host,
diff --git a/compiler/utils/arena_allocator.cc b/compiler/utils/arena_allocator.cc
index da49524..df3434e 100644
--- a/compiler/utils/arena_allocator.cc
+++ b/compiler/utils/arena_allocator.cc
@@ -177,6 +177,15 @@
   return ret;
 }
 
+size_t ArenaPool::GetBytesAllocated() const {
+  size_t total = 0;
+  MutexLock lock(Thread::Current(), lock_);
+  for (Arena* arena = free_arenas_; arena != nullptr; arena = arena->next_) {
+    total += arena->GetBytesAllocated();
+  }
+  return total;
+}
+
 void ArenaPool::FreeArenaChain(Arena* first) {
   if (UNLIKELY(RUNNING_ON_VALGRIND > 0)) {
     for (Arena* arena = first; arena != nullptr; arena = arena->next_) {
diff --git a/compiler/utils/arena_allocator.h b/compiler/utils/arena_allocator.h
index 7bfbb6f..d211eb3 100644
--- a/compiler/utils/arena_allocator.h
+++ b/compiler/utils/arena_allocator.h
@@ -124,6 +124,10 @@
     return Size() - bytes_allocated_;
   }
 
+  size_t GetBytesAllocated() const {
+    return bytes_allocated_;
+  }
+
  private:
   size_t bytes_allocated_;
   uint8_t* memory_;
@@ -142,11 +146,12 @@
  public:
   ArenaPool();
   ~ArenaPool();
-  Arena* AllocArena(size_t size);
-  void FreeArenaChain(Arena* first);
+  Arena* AllocArena(size_t size) LOCKS_EXCLUDED(lock_);
+  void FreeArenaChain(Arena* first) LOCKS_EXCLUDED(lock_);
+  size_t GetBytesAllocated() const LOCKS_EXCLUDED(lock_);
 
  private:
-  Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
+  mutable Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
   Arena* free_arenas_ GUARDED_BY(lock_);
   DISALLOW_COPY_AND_ASSIGN(ArenaPool);
 };
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index b0079a2..8803d8f 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -21,6 +21,7 @@
 
 #include <fstream>
 #include <iostream>
+#include <malloc.h>  // For mallinfo
 #include <sstream>
 #include <string>
 #include <vector>
@@ -264,12 +265,23 @@
 
   ~Dex2Oat() {
     delete runtime_;
-    LogCompletionTime();
   }
 
-  void LogCompletionTime() {
+  void LogCompletionTime(const CompilerDriver* compiler) {
+    std::ostringstream mallinfostr;
+#ifdef HAVE_MALLOC_H
+    struct mallinfo info = mallinfo();
+    const size_t allocated_space = static_cast<size_t>(info.uordblks);
+    const size_t free_space = static_cast<size_t>(info.fordblks);
+    mallinfostr << " native alloc=" << PrettySize(allocated_space) << " free="
+        << PrettySize(free_space);
+#endif
+    const ArenaPool* arena_pool = compiler->GetArenaPool();
+    gc::Heap* heap = Runtime::Current()->GetHeap();
     LOG(INFO) << "dex2oat took " << PrettyDuration(NanoTime() - start_ns_)
-              << " (threads: " << thread_count_ << ")";
+              << " (threads: " << thread_count_ << ")"
+              << " arena alloc=" << PrettySize(arena_pool->GetBytesAllocated())
+              << " java alloc=" << PrettySize(heap->GetBytesAllocated()) << mallinfostr.str();
   }
 
 
@@ -1648,10 +1660,10 @@
     LOG(INFO) << Dumpable<CumulativeLogger>(compiler_phases_timings);
   }
 
+  dex2oat->LogCompletionTime(compiler.get());
   // Everything was successfully written, do an explicit exit here to avoid running Runtime
   // destructors that take time (bug 10645725) unless we're a debug build or running on valgrind.
   if (!kIsDebugBuild && (RUNNING_ON_VALGRIND == 0)) {
-    dex2oat->LogCompletionTime();
     exit(EXIT_SUCCESS);
   }