trace_processor: add memory events

This CL adds the parsing and storing of the following events into
the counters table:
rss_stat
ion_heap_grow
ion_heap_shrink

It also
- fixes the inconsistent naming in the refType enum
- renames sched tracker to better reflect it's purpose
- remove pre-computed deltas because they can be ambiguous

Bug:117642698
Change-Id: Ie843298b2b54bc8f3997e1afe297e12e1e98215d
diff --git a/src/trace_processor/proto_trace_parser.cc b/src/trace_processor/proto_trace_parser.cc
index 1cb2086..3ce91f1 100644
--- a/src/trace_processor/proto_trace_parser.cc
+++ b/src/trace_processor/proto_trace_parser.cc
@@ -25,8 +25,8 @@
 #include "perfetto/base/utils.h"
 #include "perfetto/protozero/proto_decoder.h"
 #include "perfetto/traced/sys_stats_counters.h"
+#include "src/trace_processor/event_tracker.h"
 #include "src/trace_processor/process_tracker.h"
-#include "src/trace_processor/sched_tracker.h"
 #include "src/trace_processor/slice_tracker.h"
 #include "src/trace_processor/trace_processor_context.h"
 
@@ -122,13 +122,23 @@
           context->storage->InternString("cpu.times.io_wait_ns")),
       cpu_times_irq_ns_id_(context->storage->InternString("cpu.times.irq_ns")),
       cpu_times_softirq_ns_id_(
-          context->storage->InternString("cpu.times.softirq_ns")) {
+          context->storage->InternString("cpu.times.softirq_ns")),
+      ion_heap_grow_id_(context->storage->InternString("ion_heap_grow")),
+      ion_heap_shrink_id_(context->storage->InternString("ion_heap_shrink")) {
   for (const auto& name : BuildMeminfoCounterNames()) {
     meminfo_strs_id_.emplace_back(context->storage->InternString(name));
   }
   for (const auto& name : BuildVmstatCounterNames()) {
     vmstat_strs_id_.emplace_back(context->storage->InternString(name));
   }
+  rss_members_.emplace_back(
+      context->storage->InternString("rss_stat.mm_filepages"));
+  rss_members_.emplace_back(
+      context->storage->InternString("rss_stat.mm_anonpages"));
+  rss_members_.emplace_back(
+      context->storage->InternString("rss_stat.mm_swapents"));
+  rss_members_.emplace_back(
+      context->storage->InternString("rss_stat.nr_mm_counters"));
 }
 
 ProtoTraceParser::~ProtoTraceParser() = default;
@@ -187,17 +197,17 @@
         break;
       }
       case protos::SysStats::kNumForksFieldNumber: {
-        context_->sched_tracker->PushCounter(
+        context_->event_tracker->PushCounter(
             ts, fld.as_uint32(), num_forks_name_id_, 0, RefType::kNoRef);
         break;
       }
       case protos::SysStats::kNumIrqTotalFieldNumber: {
-        context_->sched_tracker->PushCounter(
+        context_->event_tracker->PushCounter(
             ts, fld.as_uint32(), num_irq_total_name_id_, 0, RefType::kNoRef);
         break;
       }
       case protos::SysStats::kNumSoftirqTotalFieldNumber: {
-        context_->sched_tracker->PushCounter(ts, fld.as_uint32(),
+        context_->event_tracker->PushCounter(ts, fld.as_uint32(),
                                              num_softirq_total_name_id_, 0,
                                              RefType::kNoRef);
         break;
@@ -225,7 +235,7 @@
   }
   RefType ref_type = is_soft ? RefType::kIrq : RefType::kSoftIrq;
   StringId name_id = is_soft ? num_irq_name_id_ : num_softirq_name_id_;
-  context_->sched_tracker->PushCounter(ts, value, name_id, key, ref_type);
+  context_->event_tracker->PushCounter(ts, value, name_id, key, ref_type);
 }
 
 void ProtoTraceParser::ParseMemInfo(uint64_t ts, TraceBlobView mem) {
@@ -246,7 +256,7 @@
     PERFETTO_ELOG("MemInfo key %d is not recognized.", key);
     return;
   }
-  context_->sched_tracker->PushCounter(ts, value, meminfo_strs_id_[key], 0,
+  context_->event_tracker->PushCounter(ts, value, meminfo_strs_id_[key], 0,
                                        RefType::kNoRef);
 }
 
@@ -268,7 +278,7 @@
     PERFETTO_ELOG("VmStat key %d is not recognized.", key);
     return;
   }
-  context_->sched_tracker->PushCounter(ts, value, vmstat_strs_id_[key], 0,
+  context_->event_tracker->PushCounter(ts, value, vmstat_strs_id_[key], 0,
                                        RefType::kNoRef);
 }
 
@@ -295,44 +305,44 @@
     switch (fld.id) {
       case protos::SysStats::CpuTimes::kUserNsFieldNumber: {
         value = fld.as_uint32();
-        context_->sched_tracker->PushCounter(ts, value, cpu_times_user_ns_id_,
-                                             cpu, RefType::kCPU_ID);
+        context_->event_tracker->PushCounter(ts, value, cpu_times_user_ns_id_,
+                                             cpu, RefType::kCpuId);
         break;
       }
       case protos::SysStats::CpuTimes::kUserIceNsFieldNumber: {
         value = fld.as_uint32();
-        context_->sched_tracker->PushCounter(
-            ts, value, cpu_times_user_ice_ns_id_, cpu, RefType::kCPU_ID);
+        context_->event_tracker->PushCounter(
+            ts, value, cpu_times_user_ice_ns_id_, cpu, RefType::kCpuId);
         break;
       }
       case protos::SysStats::CpuTimes::kSystemModeNsFieldNumber: {
         value = fld.as_uint32();
-        context_->sched_tracker->PushCounter(
-            ts, value, cpu_times_system_mode_ns_id_, cpu, RefType::kCPU_ID);
+        context_->event_tracker->PushCounter(
+            ts, value, cpu_times_system_mode_ns_id_, cpu, RefType::kCpuId);
         break;
       }
       case protos::SysStats::CpuTimes::kIdleNsFieldNumber: {
         value = fld.as_uint32();
-        context_->sched_tracker->PushCounter(ts, value, cpu_times_idle_ns_id_,
-                                             cpu, RefType::kCPU_ID);
+        context_->event_tracker->PushCounter(ts, value, cpu_times_idle_ns_id_,
+                                             cpu, RefType::kCpuId);
         break;
       }
       case protos::SysStats::CpuTimes::kIoWaitNsFieldNumber: {
         value = fld.as_uint32();
-        context_->sched_tracker->PushCounter(
-            ts, value, cpu_times_io_wait_ns_id_, cpu, RefType::kCPU_ID);
+        context_->event_tracker->PushCounter(
+            ts, value, cpu_times_io_wait_ns_id_, cpu, RefType::kCpuId);
         break;
       }
       case protos::SysStats::CpuTimes::kIrqNsFieldNumber: {
         value = fld.as_uint32();
-        context_->sched_tracker->PushCounter(ts, value, cpu_times_irq_ns_id_,
-                                             cpu, RefType::kCPU_ID);
+        context_->event_tracker->PushCounter(ts, value, cpu_times_irq_ns_id_,
+                                             cpu, RefType::kCpuId);
         break;
       }
       case protos::SysStats::CpuTimes::kSoftirqNsFieldNumber: {
         value = fld.as_uint32();
-        context_->sched_tracker->PushCounter(
-            ts, value, cpu_times_softirq_ns_id_, cpu, RefType::kCPU_ID);
+        context_->event_tracker->PushCounter(
+            ts, value, cpu_times_softirq_ns_id_, cpu, RefType::kCpuId);
         break;
       }
       default:
@@ -410,8 +420,13 @@
                                          uint64_t timestamp,
                                          TraceBlobView ftrace) {
   ProtoDecoder decoder(ftrace.data(), ftrace.length());
+  uint32_t pid = 0;
   for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
     switch (fld.id) {
+      case protos::FtraceEvent::kPidFieldNumber: {
+        pid = fld.as_uint32();
+        break;
+      }
       case protos::FtraceEvent::kSchedSwitchFieldNumber: {
         PERFETTO_DCHECK(timestamp > 0);
         const size_t fld_off = ftrace.offset_of(fld.data());
@@ -430,6 +445,25 @@
         ParsePrint(cpu, timestamp, ftrace.slice(fld_off, fld.size()));
         break;
       }
+      case protos::FtraceEvent::kRssStatFieldNumber: {
+        PERFETTO_DCHECK(timestamp > 0);
+        const size_t fld_off = ftrace.offset_of(fld.data());
+        ParseRssStat(timestamp, pid, ftrace.slice(fld_off, fld.size()));
+        break;
+      }
+      case protos::FtraceEvent::kIonHeapGrow: {
+        PERFETTO_DCHECK(timestamp > 0);
+        const size_t fld_off = ftrace.offset_of(fld.data());
+        ParseIonHeapGrow(timestamp, pid, ftrace.slice(fld_off, fld.size()));
+        break;
+      }
+      case protos::FtraceEvent::kIonHeapShrink: {
+        PERFETTO_DCHECK(timestamp > 0);
+        const size_t fld_off = ftrace.offset_of(fld.data());
+        ParseIonHeapShrink(timestamp, pid, ftrace.slice(fld_off, fld.size()));
+        break;
+      }
+
       default:
         break;
     }
@@ -437,6 +471,68 @@
   PERFETTO_DCHECK(decoder.IsEndOfBuffer());
 }
 
+void ProtoTraceParser::ParseRssStat(uint64_t timestamp,
+                                    uint32_t pid,
+                                    TraceBlobView view) {
+  ProtoDecoder decoder(view.data(), view.length());
+  uint32_t member = 0;
+  uint32_t size = 0;
+  for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
+    switch (fld.id) {
+      case protos::RssStatFtraceEvent::kMemberFieldNumber:
+        member = fld.as_uint32();
+        break;
+      case protos::RssStatFtraceEvent::kSizeFieldNumber:
+        size = fld.as_uint32();
+        break;
+    }
+  }
+  UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
+  context_->event_tracker->PushCounter(timestamp, size, rss_members_[member],
+                                       utid, RefType::kUtid);
+  PERFETTO_DCHECK(decoder.IsEndOfBuffer());
+}
+
+void ProtoTraceParser::ParseIonHeapGrow(uint64_t timestamp,
+                                        uint32_t pid,
+                                        TraceBlobView view) {
+  ProtoDecoder decoder(view.data(), view.length());
+  uint32_t value = 0;
+  // TODO(b/118300811): The heap name pointer cannot be read. Read once it
+  // has been fixed.
+  for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
+    switch (fld.id) {
+      case protos::IonHeapGrowFtraceEvent::kTotalAllocatedFieldNumber:
+        value = fld.as_uint32();
+        break;
+    }
+  }
+  UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
+  context_->event_tracker->PushCounter(timestamp, value, ion_heap_grow_id_,
+                                       utid, RefType::kUtid);
+  PERFETTO_DCHECK(decoder.IsEndOfBuffer());
+}
+
+void ProtoTraceParser::ParseIonHeapShrink(uint64_t timestamp,
+                                          uint32_t pid,
+                                          TraceBlobView view) {
+  ProtoDecoder decoder(view.data(), view.length());
+  uint32_t value = 0;
+  // TODO(b/118300811): The heap name pointer cannot be read. Read once it
+  // has been fixed.
+  for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
+    switch (fld.id) {
+      case protos::IonHeapShrinkFtraceEvent::kTotalAllocatedFieldNumber:
+        value = fld.as_uint32();
+        break;
+    }
+  }
+  UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
+  context_->event_tracker->PushCounter(timestamp, value, ion_heap_shrink_id_,
+                                       utid, RefType::kUtid);
+  PERFETTO_DCHECK(decoder.IsEndOfBuffer());
+}
+
 void ProtoTraceParser::ParseCpuFreq(uint64_t timestamp, TraceBlobView view) {
   ProtoDecoder decoder(view.data(), view.length());
 
@@ -452,9 +548,8 @@
         break;
     }
   }
-  context_->sched_tracker->PushCounter(timestamp, new_freq, cpu_freq_name_id_,
-                                       cpu_affected, RefType::kCPU_ID);
-
+  context_->event_tracker->PushCounter(timestamp, new_freq, cpu_freq_name_id_,
+                                       cpu_affected, RefType::kCpuId);
   PERFETTO_DCHECK(decoder.IsEndOfBuffer());
 }
 
@@ -485,7 +580,7 @@
         break;
     }
   }
-  context_->sched_tracker->PushSchedSwitch(cpu, timestamp, prev_pid, prev_state,
+  context_->event_tracker->PushSchedSwitch(cpu, timestamp, prev_pid, prev_state,
                                            next_pid, next_comm);
   PERFETTO_DCHECK(decoder.IsEndOfBuffer());
 }
@@ -524,8 +619,8 @@
 
     case 'C': {
       StringId name_id = context_->storage->InternString(point.name);
-      context_->sched_tracker->PushCounter(timestamp, point.value, name_id,
-                                           utid, RefType::kUTID);
+      context_->event_tracker->PushCounter(timestamp, point.value, name_id,
+                                           utid, RefType::kUtid);
     }
   }
   PERFETTO_DCHECK(decoder.IsEndOfBuffer());