Merge "Dex-wide ArenaPool scoping for AOT compilation"
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index a51dd32..db8c3ab 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -2492,6 +2492,7 @@
                    parallel_thread_pool_.get(),
                    parallel_thread_count_,
                    timings);
+    Runtime::Current()->ReclaimArenaPoolMemory();
   }
   VLOG(compiler) << "Compile: " << GetMemoryUsageString(false);
 }
diff --git a/runtime/base/arena_allocator.cc b/runtime/base/arena_allocator.cc
index 771b2d0..a4b38ea 100644
--- a/runtime/base/arena_allocator.cc
+++ b/runtime/base/arena_allocator.cc
@@ -222,6 +222,10 @@
 }
 
 ArenaPool::~ArenaPool() {
+  ReclaimMemory();
+}
+
+void ArenaPool::ReclaimMemory() {
   while (free_arenas_ != nullptr) {
     auto* arena = free_arenas_;
     free_arenas_ = free_arenas_->next_;
@@ -229,6 +233,11 @@
   }
 }
 
+void ArenaPool::LockReclaimMemory() {
+  MutexLock lock(Thread::Current(), lock_);
+  ReclaimMemory();
+}
+
 Arena* ArenaPool::AllocArena(size_t size) {
   Thread* self = Thread::Current();
   Arena* ret = nullptr;
diff --git a/runtime/base/arena_allocator.h b/runtime/base/arena_allocator.h
index 36334c4..8a96571 100644
--- a/runtime/base/arena_allocator.h
+++ b/runtime/base/arena_allocator.h
@@ -276,6 +276,8 @@
   Arena* AllocArena(size_t size) REQUIRES(!lock_);
   void FreeArenaChain(Arena* first) REQUIRES(!lock_);
   size_t GetBytesAllocated() const REQUIRES(!lock_);
+  void ReclaimMemory() NO_THREAD_SAFETY_ANALYSIS;
+  void LockReclaimMemory() REQUIRES(!lock_);
   // Trim the maps in arenas by madvising, used by JIT to reduce memory usage. This only works
   // use_malloc is false.
   void TrimMaps() REQUIRES(!lock_);
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 861bd85..eb5455a 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1300,6 +1300,10 @@
   VLOG(startup) << "Runtime::InitNativeMethods exiting";
 }
 
+void Runtime::ReclaimArenaPoolMemory() {
+  arena_pool_->LockReclaimMemory();
+}
+
 void Runtime::InitThreadGroups(Thread* self) {
   JNIEnvExt* env = self->GetJniEnv();
   ScopedJniEnvLocalRefState env_state(env);
diff --git a/runtime/runtime.h b/runtime/runtime.h
index cbb3e89..8aac4ce 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -564,6 +564,9 @@
   const ArenaPool* GetArenaPool() const {
     return arena_pool_.get();
   }
+
+  void ReclaimArenaPoolMemory();
+
   LinearAlloc* GetLinearAlloc() {
     return linear_alloc_.get();
   }