Free Arenas from the ArenaStack before running codegen.

Since the ArenaStack is used only by the MIRGraph and not by
the memory hungry codegen, freeing the ArenaStack's Arenas
just before running the codegen should reduce the compiler's
peak memory usage.

Bug: 13564922
Change-Id: I1cb49d367e4e81d71a03cac89b3739ed61e4f966
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc
index 7890d81..64fa685 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -251,6 +251,15 @@
   /* Reassociate sreg names with original Dalvik vreg names. */
   cu.mir_graph->RemapRegLocations();
 
+  /* Free Arenas from the cu.arena_stack for reuse by the cu.arena in the codegen. */
+  if (cu.enable_debug & (1 << kDebugShowMemoryUsage)) {
+    if (cu.arena_stack.PeakBytesAllocated() > 256 * 1024) {
+      MemStats stack_stats(cu.arena_stack.GetPeakStats());
+      LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(stack_stats);
+    }
+  }
+  cu.arena_stack.Reset();
+
   CompiledMethod* result = NULL;
 
   cu.cg->Materialize();
@@ -266,12 +275,9 @@
   }
 
   if (cu.enable_debug & (1 << kDebugShowMemoryUsage)) {
-    if (cu.arena.BytesAllocated() > (1 * 1024 *1024) ||
-        cu.arena_stack.PeakBytesAllocated() > 256 * 1024) {
+    if (cu.arena.BytesAllocated() > (1 * 1024 *1024)) {
       MemStats mem_stats(cu.arena.GetMemStats());
-      MemStats peak_stats(cu.arena_stack.GetPeakStats());
-      LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(mem_stats)
-          << Dumpable<MemStats>(peak_stats);
+      LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(mem_stats);
     }
   }
 
diff --git a/compiler/utils/scoped_arena_allocator.cc b/compiler/utils/scoped_arena_allocator.cc
index ee3b07e..a78d287 100644
--- a/compiler/utils/scoped_arena_allocator.cc
+++ b/compiler/utils/scoped_arena_allocator.cc
@@ -34,9 +34,19 @@
 }
 
 ArenaStack::~ArenaStack() {
+  DebugStackRefCounter::CheckNoRefs();
   stats_and_pool_.pool->FreeArenaChain(bottom_arena_);
 }
 
+void ArenaStack::Reset() {
+  DebugStackRefCounter::CheckNoRefs();
+  stats_and_pool_.pool->FreeArenaChain(bottom_arena_);
+  bottom_arena_ = nullptr;
+  top_arena_  = nullptr;
+  top_ptr_ = nullptr;
+  top_end_ = nullptr;
+}
+
 MemStats ArenaStack::GetPeakStats() const {
   DebugStackRefCounter::CheckNoRefs();
   return MemStats("ArenaStack peak", static_cast<const TaggedStats<Peak>*>(&stats_and_pool_),
diff --git a/compiler/utils/scoped_arena_allocator.h b/compiler/utils/scoped_arena_allocator.h
index 24a8afe..28e86ec 100644
--- a/compiler/utils/scoped_arena_allocator.h
+++ b/compiler/utils/scoped_arena_allocator.h
@@ -37,6 +37,8 @@
   explicit ArenaStack(ArenaPool* arena_pool);
   ~ArenaStack();
 
+  void Reset();
+
   size_t PeakBytesAllocated() {
     return PeakStats()->BytesAllocated();
   }