Add allocation stack traces for HPROF dump.

This feature is currently only enabled when DDMS's allocation tracking
is enabled. In the future there should be a way to enable this feature
before an application starts.

Also updates DDMS's recent allocation tracking to use a new backend
data structure that is shared with this feature.

The following system properties controls customizable parameters:
dalvik.vm.allocTrackerMax: max number of objects that have allocation
                           records, default 512K;

dalvik.vm.recentAllocMax:  max number of records that are sent to DDMS
                           when clicking "Get allocation" button,
                           default 64K-1 (limit of the protocol);

dalvik.vm.allocStackDepth: max number of stack frames in an allocation
                           record, default 4.

Bug: 20037135
Change-Id: I26ed378a5613678bd3c43e846025f90470a8e059
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index aeab7d8..14fa740 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -209,7 +209,8 @@
       blocking_gc_count_last_window_(0U),
       gc_count_rate_histogram_("gc count rate histogram", 1U, kGcCountRateMaxBucketCount),
       blocking_gc_count_rate_histogram_("blocking gc count rate histogram", 1U,
-                                        kGcCountRateMaxBucketCount) {
+                                        kGcCountRateMaxBucketCount),
+      alloc_tracking_enabled_(false) {
   if (VLOG_IS_ON(heap) || VLOG_IS_ON(startup)) {
     LOG(INFO) << "Heap() entering";
   }
@@ -1043,6 +1044,7 @@
   STLDeleteElements(&garbage_collectors_);
   // If we don't reset then the mark stack complains in its destructor.
   allocation_stack_->Reset();
+  allocation_records_.reset();
   live_stack_->Reset();
   STLDeleteValues(&mod_union_tables_);
   STLDeleteValues(&remembered_sets_);
@@ -3653,5 +3655,18 @@
   }
 }
 
+void Heap::SetAllocationRecords(AllocRecordObjectMap* records) {
+  allocation_records_.reset(records);
+}
+
+void Heap::SweepAllocationRecords(IsMarkedCallback* visitor, void* arg) const {
+  if (IsAllocTrackingEnabled()) {
+    MutexLock mu(Thread::Current(), *Locks::alloc_tracker_lock_);
+    if (IsAllocTrackingEnabled()) {
+      GetAllocationRecords()->SweepAllocationRecords(visitor, arg);
+    }
+  }
+}
+
 }  // namespace gc
 }  // namespace art