GC data structures allocation tracking

Adds a new stl compatible allocator that is used in most GC data
structures. When the data structures allocate and free memory, it
lets the heap know of how much memory was allocated or freed. Using
this info, we dump the approximated stl data structures memory usage
when a sigquit occurs.

The allocation tracking can be disabled with a compile time boolean
flag to remove performance impact.

Change-Id: Idddb6713169e07be913bceeb50f305c8573e4392
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index b6cef58..edc5529 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -90,6 +90,7 @@
       num_bytes_allocated_(0),
       native_bytes_allocated_(0),
       process_state_(PROCESS_STATE_TOP),
+      gc_memory_overhead_(0),
       verify_missing_card_marks_(false),
       verify_system_weaks_(false),
       verify_pre_gc_heap_(false),
@@ -177,7 +178,7 @@
   card_table_.reset(accounting::CardTable::Create(heap_begin, heap_capacity));
   CHECK(card_table_.get() != NULL) << "Failed to create card table";
 
-  image_mod_union_table_.reset(new accounting::ModUnionTableToZygoteAllocspace(this));
+  image_mod_union_table_.reset(new accounting::ModUnionTableCardCache(this));
   CHECK(image_mod_union_table_.get() != NULL) << "Failed to create image mod-union table";
 
   zygote_mod_union_table_.reset(new accounting::ModUnionTableCardCache(this));
@@ -273,6 +274,18 @@
   }
 }
 
+void Heap::RegisterGCAllocation(size_t bytes) {
+  if (this != NULL) {
+    gc_memory_overhead_.fetch_add(bytes);
+  }
+}
+
+void Heap::RegisterGCDeAllocation(size_t bytes) {
+  if (this != NULL) {
+    gc_memory_overhead_.fetch_sub(bytes);
+  }
+}
+
 void Heap::AddDiscontinuousSpace(space::DiscontinuousSpace* space) {
   WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
   DCHECK(space != NULL);
@@ -333,6 +346,7 @@
   }
   os << "Total mutator paused time: " << PrettyDuration(total_paused_time) << "\n";
   os << "Total time waiting for GC to complete: " << PrettyDuration(total_wait_time_) << "\n";
+  os << "Approximate GC data structures memory overhead: " << gc_memory_overhead_;
 }
 
 Heap::~Heap() {
@@ -1128,6 +1142,7 @@
     // Wake anyone who may have been waiting for the GC to complete.
     gc_complete_cond_->Broadcast(self);
   }
+
   // Inform DDMS that a GC completed.
   ATRACE_END();
   Dbg::GcDidFinish();