Fix method tracing and allow alloc counting during tracing.

Forcing alignment on art_trace_exit_from_code was preventing the LR of
profiled frames from matching. Also, the merge of the different types of
stalk walks introduced a small bug.

The metrod tracer now also supports the TRACE_COUNT_ALLOCS flag to count
allocations during method tracing.

Change-Id: Ief9e4612471a134a90eabf15432135162b633b92
diff --git a/src/trace.cc b/src/trace.cc
index c38f017..3b4c3e5 100644
--- a/src/trace.cc
+++ b/src/trace.cc
@@ -200,11 +200,6 @@
     return;
   }
 
-  // TODO: implement alloc counting.
-  if (flags != 0) {
-    UNIMPLEMENTED(FATAL) << "trace flags";
-  }
-
   ScopedThreadStateChange tsc(Thread::Current(), Thread::kRunnable);
   Runtime::Current()->GetThreadList()->SuspendAll(false);
 
@@ -226,7 +221,13 @@
   }
 
   // Create Trace object.
-  Trace* tracer(new Trace(trace_file, buffer_size));
+  Trace* tracer(new Trace(trace_file, buffer_size, flags));
+
+  // Enable count of allocs if specified in the flags.
+  if ((flags && kTraceCountAllocs) != 0) {
+    Runtime::Current()->SetStatsEnabled(true);
+  }
+
   Runtime::Current()->EnableMethodTracing(tracer);
   tracer->BeginTracing();
 
@@ -297,6 +298,10 @@
   size_t final_offset = cur_offset_;
   uint32_t clock_overhead = GetClockOverhead();
 
+  if ((flags_ & kTraceCountAllocs) != 0) {
+    Runtime::Current()->SetStatsEnabled(false);
+  }
+
   GetVisitedMethods(final_offset);
 
   std::ostringstream os;
@@ -317,6 +322,11 @@
   os << StringPrintf("num-method-calls=%zd\n", (final_offset - kTraceHeaderLength) / record_size_);
   os << StringPrintf("clock-call-overhead-nsec=%d\n", clock_overhead);
   os << StringPrintf("vm=art\n");
+  if ((flags_ & kTraceCountAllocs) != 0) {
+    os << StringPrintf("alloc-count=%d\n", Runtime::Current()->GetStat(KIND_ALLOCATED_OBJECTS));
+    os << StringPrintf("alloc-size=%d\n", Runtime::Current()->GetStat(KIND_ALLOCATED_BYTES));
+    os << StringPrintf("gc-count=%d\n", Runtime::Current()->GetStat(KIND_GC_INVOCATIONS));
+  }
   os << StringPrintf("%cthreads\n", kTraceTokenChar);
   DumpThreadList(os);
   os << StringPrintf("%cmethods\n", kTraceTokenChar);