Use ashmem to name our various anonymous regions.

Change-Id: If64576b831a2fdcb83ffce40e6ec8ece8d902672
diff --git a/build/Android.libart.mk b/build/Android.libart.mk
index 4f0efe3..6b4377b 100644
--- a/build/Android.libart.mk
+++ b/build/Android.libart.mk
@@ -72,6 +72,7 @@
   ifeq ($$(art_target_or_host),target)
     LOCAL_SHARED_LIBRARIES += libcutils libstlport libz libdl
   else # host
+    LOCAL_STATIC_LIBRARIES += libcutils
     LOCAL_SHARED_LIBRARIES += libz-host
     LOCAL_LDLIBS := -ldl -lpthread -lrt
   endif
diff --git a/src/card_table.cc b/src/card_table.cc
index 4b57aa1..13491d8 100644
--- a/src/card_table.cc
+++ b/src/card_table.cc
@@ -62,7 +62,7 @@
   /* Set up the card table */
   size_t length = heap_max_size / GC_CARD_SIZE;
   /* Allocate an extra 256 bytes to allow fixed low-byte of base */
-  mem_map_.reset(MemMap::Map(length + 256, PROT_READ | PROT_WRITE));
+  mem_map_.reset(MemMap::Map("dalvik-card-table", NULL, length + 256, PROT_READ | PROT_WRITE));
   byte* alloc_base = mem_map_->GetAddress();
   if (alloc_base == NULL) {
     return false;
diff --git a/src/heap.cc b/src/heap.cc
index fe51d48..b2ae47b 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -109,18 +109,18 @@
   size_t limit_bytes = limit - base;
 
   // Allocate the initial live bitmap.
-  UniquePtr<HeapBitmap> live_bitmap(HeapBitmap::Create(base, num_bytes));
+  UniquePtr<HeapBitmap> live_bitmap(HeapBitmap::Create("dalvik-bitmap-1", base, num_bytes));
   if (live_bitmap.get() == NULL) {
     LOG(FATAL) << "Failed to create live bitmap";
   }
 
   // Allocate the initial mark bitmap.
-  UniquePtr<HeapBitmap> mark_bitmap(HeapBitmap::Create(base, num_bytes));
+  UniquePtr<HeapBitmap> mark_bitmap(HeapBitmap::Create("dalvik-bitmap-2", base, num_bytes));
   if (mark_bitmap.get() == NULL) {
     LOG(FATAL) << "Failed to create mark bitmap";
   }
 
-  // Allocate the card table
+  // Allocate the card table.
   UniquePtr<CardTable> card_table(CardTable::Create(base, num_bytes, limit_bytes));
   if (card_table.get() == NULL) {
     LOG(FATAL) << "Failed to create card table";
@@ -136,8 +136,6 @@
   num_bytes_allocated_ = 0;
   num_objects_allocated_ = 0;
 
-  // TODO: allocate the card table
-
   // Make image objects live (after live_bitmap_ is set)
   for (size_t i = 0; i < image_spaces.size(); i++) {
     RecordImageAllocations(image_spaces[i]);
diff --git a/src/heap_bitmap.cc b/src/heap_bitmap.cc
index ebe4e0b..4bd191a 100644
--- a/src/heap_bitmap.cc
+++ b/src/heap_bitmap.cc
@@ -22,9 +22,9 @@
 
 namespace art {
 
-HeapBitmap* HeapBitmap::Create(byte* base, size_t length) {
+HeapBitmap* HeapBitmap::Create(const char* name, byte* base, size_t length) {
   UniquePtr<HeapBitmap> bitmap(new HeapBitmap(base, length));
-  if (!bitmap->Init(base, length)) {
+  if (!bitmap->Init(name, base, length)) {
     return NULL;
   } else {
     return bitmap.release();
@@ -34,10 +34,10 @@
 // Initialize a HeapBitmap so that it points to a bitmap large enough
 // to cover a heap at <base> of <max_size> bytes, where objects are
 // guaranteed to be kAlignment-aligned.
-bool HeapBitmap::Init(const byte* base, size_t max_size) {
+bool HeapBitmap::Init(const char* name, const byte* base, size_t max_size) {
   CHECK(base != NULL);
   size_t length = HB_OFFSET_TO_INDEX(max_size) * kWordSize;
-  mem_map_.reset(MemMap::Map(length, PROT_READ | PROT_WRITE));
+  mem_map_.reset(MemMap::Map(name, NULL, length, PROT_READ | PROT_WRITE));
   if (mem_map_.get() == NULL) {
     return false;
   }
diff --git a/src/heap_bitmap.h b/src/heap_bitmap.h
index f1db795..31adebc 100644
--- a/src/heap_bitmap.h
+++ b/src/heap_bitmap.h
@@ -53,7 +53,7 @@
 
   typedef void SweepCallback(size_t numPtrs, void** ptrs, void* arg);
 
-  static HeapBitmap* Create(byte* base, size_t length);
+  static HeapBitmap* Create(const char* name, byte* base, size_t length);
 
   ~HeapBitmap();
 
@@ -117,7 +117,7 @@
     }
   }
 
-  bool Init(const byte* base, size_t length);
+  bool Init(const char* name, const byte* base, size_t length);
 
   UniquePtr<MemMap> mem_map_;
 
diff --git a/src/image_writer.cc b/src/image_writer.cc
index 6e3e03a..6e4f6ae 100644
--- a/src/image_writer.cc
+++ b/src/image_writer.cc
@@ -67,7 +67,7 @@
   size_t size = source_space_->Size();
   int prot = PROT_READ | PROT_WRITE;
   size_t length = RoundUp(size, kPageSize);
-  image_.reset(MemMap::Map(length, prot));
+  image_.reset(MemMap::Map("image-writer-image", NULL, length, prot));
   if (image_.get() == NULL) {
     LOG(ERROR) << "Failed to allocate memory for image file generation";
     return false;
diff --git a/src/mark_stack.cc b/src/mark_stack.cc
index 4a9502b..34bad7d 100644
--- a/src/mark_stack.cc
+++ b/src/mark_stack.cc
@@ -22,7 +22,7 @@
 
 bool MarkStack::Init() {
   size_t length = 64 * MB;
-  mem_map_.reset(MemMap::Map(length, PROT_READ | PROT_WRITE));
+  mem_map_.reset(MemMap::Map("dalvik-mark-stack", NULL, length, PROT_READ | PROT_WRITE));
   if (mem_map_.get() == NULL) {
     return false;
   }
diff --git a/src/mem_map.cc b/src/mem_map.cc
index f1c85da..0d014c2 100644
--- a/src/mem_map.cc
+++ b/src/mem_map.cc
@@ -1,9 +1,3 @@
-#include "mem_map.h"
-
-#include <sys/mman.h>
-
-#include "utils.h"
-
 /*
  * Copyright (C) 2008 The Android Open Source Project
  *
@@ -24,6 +18,15 @@
 
 #include <sys/mman.h>
 
+#include "ScopedFd.h"
+#include "utils.h"
+
+#define USE_ASHMEM 1
+
+#ifdef USE_ASHMEM
+#include <cutils/ashmem.h>
+#endif
+
 namespace art {
 
 size_t ParseHex(const std::string& string) {
@@ -100,19 +103,27 @@
 #endif
 }
 
-MemMap* MemMap::Map(byte* addr, size_t length, int prot) {
+MemMap* MemMap::Map(const char* name, byte* addr, size_t length, int prot) {
   CHECK_NE(0U, length);
   CHECK_NE(0, prot);
   size_t page_aligned_size = RoundUp(length, kPageSize);
   CheckMapRequest(addr, page_aligned_size);
-  byte* actual = reinterpret_cast<byte*>(mmap(addr,
-                                              page_aligned_size,
-                                              prot,
-                                              MAP_PRIVATE | MAP_ANONYMOUS,
-                                              -1,
-                                              0));
+
+#ifdef USE_ASHMEM
+  ScopedFd fd(ashmem_create_region(name, page_aligned_size));
+  int flags = MAP_PRIVATE;
+  if (fd.get() == -1) {
+    PLOG(ERROR) << "ashmem_create_region failed (" << name << ")";
+    return NULL;
+  }
+#else
+  ScopedFd fd(-1);
+  int flags = MAP_PRIVATE | MAP_ANONYMOUS;
+#endif
+
+  byte* actual = reinterpret_cast<byte*>(mmap(addr, page_aligned_size, prot, flags, fd.get(), 0));
   if (actual == MAP_FAILED) {
-    PLOG(ERROR) << "mmap failed";
+    PLOG(ERROR) << "mmap failed (" << name << ")";
     return NULL;
   }
   return new MemMap(actual, length, actual, page_aligned_size);
diff --git a/src/mem_map.h b/src/mem_map.h
index 3c73613..fa3904d 100644
--- a/src/mem_map.h
+++ b/src/mem_map.h
@@ -28,17 +28,15 @@
 class MemMap {
  public:
 
-  // Request an anonymous region of a specified length.
-  //
-  // On success, returns returns a MemMap instance.  On failure, returns a NULL;
-  static MemMap* Map(size_t length, int prot) {
-    return Map(NULL, length, prot);
-  }
-
   // Request an anonymous region of a specified length and a requested base address.
+  // Use NULL as the requested base address if you don't care.
+  //
+  // The word "anonymous" in this context means "not backed by a file". The supplied
+  // 'ashmem_name' will be used -- on systems that support it -- to give the mapping
+  // a name.
   //
   // On success, returns returns a MemMap instance.  On failure, returns a NULL;
-  static MemMap* Map(byte* addr, size_t length, int prot);
+  static MemMap* Map(const char* ashmem_name, byte* addr, size_t length, int prot);
 
   // Map part of a file, taking care of non-page aligned offsets.  The
   // "start" offset is absolute, not relative.
diff --git a/src/space.cc b/src/space.cc
index d10d14d..4822ceb 100644
--- a/src/space.cc
+++ b/src/space.cc
@@ -59,7 +59,7 @@
 bool Space::Init(size_t initial_size, size_t maximum_size, size_t growth_size, byte* requested_base) {
   const Runtime* runtime = Runtime::Current();
   if (runtime->IsVerboseStartup()) {
-    LOG(INFO) << "Space::Init entering"
+    LOG(INFO) << "Space::Init entering " << name_
               << " initial_size=" << initial_size
               << " maximum_size=" << maximum_size
               << " growth_size=" << growth_size
@@ -67,29 +67,29 @@
   }
   if (initial_size > growth_size) {
     LOG(ERROR) << "Failed to create space with initial size > growth size ("
-               << initial_size << ">" << growth_size << ")";
+               << initial_size << ">" << growth_size << "): " << name_;
     return false;
   }
   if (growth_size > maximum_size) {
     LOG(ERROR) << "Failed to create space with growth size > maximum size ("
-               << growth_size << ">" << maximum_size << ")";
+               << growth_size << ">" << maximum_size << "): " << name_;
     return false;
   }
   size_t length = RoundUp(maximum_size, kPageSize);
   int prot = PROT_READ | PROT_WRITE;
-  UniquePtr<MemMap> mem_map(MemMap::Map(requested_base, length, prot));
+  UniquePtr<MemMap> mem_map(MemMap::Map(name_.c_str(), requested_base, length, prot));
   if (mem_map.get() == NULL) {
-    LOG(WARNING) << "Failed to allocate " << length << " bytes for space";
+    LOG(WARNING) << "Failed to allocate " << length << " bytes for space: " << name_;
     return false;
   }
-  Init(mem_map.release());
+  InitFromMemMap(mem_map.release());
   maximum_size_ = maximum_size;
   size_t growth_length = RoundUp(growth_size, kPageSize);
   growth_size_ = growth_size;
   growth_limit_ = base_ + growth_length;
   mspace_ = CreateMallocSpace(base_, initial_size, maximum_size);
   if (mspace_ == NULL) {
-    LOG(WARNING) << "Failed to create mspace for space";
+    LOG(WARNING) << "Failed to create mspace for space: " << name_;
     return false;
   }
   if (runtime->IsVerboseStartup()) {
@@ -98,13 +98,12 @@
   return true;
 }
 
-void Space::Init(MemMap* mem_map) {
+void Space::InitFromMemMap(MemMap* mem_map) {
   mem_map_.reset(mem_map);
   base_ = mem_map_->GetAddress();
   limit_ = base_ + mem_map->GetLength();
 }
 
-
 bool Space::InitFromImage(const std::string& image_file_name) {
   Runtime* runtime = Runtime::Current();
   if (runtime->IsVerboseStartup()) {
@@ -160,7 +159,7 @@
   callee_save_method = image_header.GetImageRoot(ImageHeader::kRefsAndArgsSaveMethod);
   runtime->SetCalleeSaveMethod(down_cast<Method*>(callee_save_method), Runtime::kRefsAndArgs);
 
-  Init(map.release());
+  InitFromMemMap(map.release());
   growth_limit_ = limit_;
   if (runtime->IsVerboseStartup()) {
     LOG(INFO) << "Space::InitFromImage exiting";
diff --git a/src/space.h b/src/space.h
index 9300be3..be7dfdc 100644
--- a/src/space.h
+++ b/src/space.h
@@ -126,7 +126,7 @@
   bool Init(size_t initial_size, size_t maximum_size, size_t growth_size, byte* requested_base);
 
   // Initializes the space from existing storage, taking ownership of the storage.
-  void Init(MemMap* map);
+  void InitFromMemMap(MemMap* map);
 
   // Initializes the space from an image file
   bool InitFromImage(const std::string& image_file_name);