processor: Add storage for virtual tracks

Adds an indirection for virtual tracks (incl. async event tracks),
so that we can also store a upid with process-scope async tracks.

The new virtual tracks storage is designed for compatibility with a
more generic "tracks" table (track_id column), but for now, we'll use
track_id == index into vtracks.

Also updates proto & fuchsia parsers to store async events with track
references.

The vtracks table is not yet exposed via SQL.

Change-Id: I3d8fbe0e2575b40c5e652a79a70c9a5999334179
diff --git a/src/trace_processor/trace_storage.h b/src/trace_processor/trace_storage.h
index 79d3fb5..77be056 100644
--- a/src/trace_processor/trace_storage.h
+++ b/src/trace_processor/trace_storage.h
@@ -72,6 +72,15 @@
 using ArgSetId = uint32_t;
 static const ArgSetId kInvalidArgSetId = 0;
 
+using TrackId = uint32_t;
+
+enum class VirtualTrackScope : uint8_t {
+  // VirtualTrack with global scope, will not have a |upid| set.
+  kGlobal = 0,
+  // VirtualTrack associated with a specific process via |upid|.
+  kProcess = 1
+};
+
 enum RefType {
   kRefNoRef = 0,
   kRefUtid = 1,
@@ -80,8 +89,7 @@
   kRefSoftIrq = 4,
   kRefUpid = 5,
   kRefGpuId = 6,
-  kRefGlobalAsyncTrack = 7,
-  kRefProcessAsyncTrack = 8,
+  kRefTrack = 7,
   kRefMax
 };
 
@@ -206,6 +214,35 @@
     std::unordered_map<ArgSetHash, uint32_t> arg_row_for_hash_;
   };
 
+  class VirtualTracks {
+   public:
+    inline uint32_t AddVirtualTrack(TrackId track_id,
+                                    StringId name,
+                                    VirtualTrackScope scope,
+                                    UniquePid upid = 0u) {
+      track_ids_.emplace_back(track_id);
+      names_.emplace_back(name);
+      scopes_.emplace_back(scope);
+      upids_.emplace_back(upid);
+      return virtual_track_count() - 1;
+    }
+
+    uint32_t virtual_track_count() const {
+      return static_cast<uint32_t>(track_ids_.size());
+    }
+
+    const std::deque<uint32_t>& track_ids() const { return track_ids_; }
+    const std::deque<StringId>& names() const { return names_; }
+    const std::deque<VirtualTrackScope>& scopes() const { return scopes_; }
+    const std::deque<UniquePid>& upids() const { return upids_; }
+
+   private:
+    std::deque<uint32_t> track_ids_;
+    std::deque<StringId> names_;
+    std::deque<VirtualTrackScope> scopes_;
+    std::deque<UniquePid> upids_;
+  };
+
   class Slices {
    public:
     inline size_t AddSlice(uint32_t cpu,
@@ -928,6 +965,9 @@
     return std::make_pair(table_id, row);
   }
 
+  const VirtualTracks& virtual_tracks() const { return virtual_tracks_; }
+  VirtualTracks* mutable_virtual_tracks() { return &virtual_tracks_; }
+
   const Slices& slices() const { return slices_; }
   Slices* mutable_slices() { return &slices_; }
 
@@ -1028,6 +1068,9 @@
   // * descriptions of android packages
   Metadata metadata_{};
 
+  // Metadata for virtual slice tracks.
+  VirtualTracks virtual_tracks_;
+
   // One entry for each CPU in the trace.
   Slices slices_;