Manually manage thread pool stacks.

We now allocate the thread pool worker stack using a MemMap. This
enables us to name the maps so that we get more descriptive output
for debugging leaks.

Appears to fix the mips build 5/5 successful clean-oat and builds.
This is probably since glibc caches up to 40 MB of thread stacks
before releasing them.

Change-Id: I1df2de50cb95838aa0d272a09807021404ba410c
diff --git a/runtime/thread_pool.h b/runtime/thread_pool.h
index b9a97a1..e8f9afe 100644
--- a/runtime/thread_pool.h
+++ b/runtime/thread_pool.h
@@ -24,6 +24,7 @@
 #include "base/mutex.h"
 #include "closure.h"
 #include "locks.h"
+#include "mem_map.h"
 
 namespace art {
 
@@ -40,7 +41,8 @@
   static const size_t kDefaultStackSize = 1 * MB;
 
   size_t GetStackSize() const {
-    return stack_size_;
+    DCHECK(stack_.get() != nullptr);
+    return stack_->Size();
   }
 
   virtual ~ThreadPoolWorker();
@@ -52,7 +54,7 @@
 
   ThreadPool* const thread_pool_;
   const std::string name_;
-  const size_t stack_size_;
+  UniquePtr<MemMap> stack_;
   pthread_t pthread_;
 
  private:
@@ -77,7 +79,7 @@
   // after running it, it is the caller's responsibility.
   void AddTask(Thread* self, Task* task);
 
-  explicit ThreadPool(size_t num_threads);
+  explicit ThreadPool(const char* name, size_t num_threads);
   virtual ~ThreadPool();
 
   // Wait for all tasks currently on queue to get completed.
@@ -107,6 +109,7 @@
     return shutting_down_;
   }
 
+  const std::string name_;
   Mutex task_queue_lock_;
   ConditionVariable task_queue_condition_ GUARDED_BY(task_queue_lock_);
   ConditionVariable completion_condition_ GUARDED_BY(task_queue_lock_);
@@ -167,7 +170,7 @@
 
 class WorkStealingThreadPool : public ThreadPool {
  public:
-  explicit WorkStealingThreadPool(size_t num_threads);
+  explicit WorkStealingThreadPool(const char* name, size_t num_threads);
   virtual ~WorkStealingThreadPool();
 
  private: