blob: 1b7570be575f2ecb1ff781e1a945ca1cc06931e1 [file] [log] [blame]
Lalit Maganticaed37e2018-06-01 03:03:08 +01001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SRC_TRACE_PROCESSOR_TRACE_STORAGE_H_
18#define SRC_TRACE_PROCESSOR_TRACE_STORAGE_H_
19
Lalit Maganti35622b72018-06-06 12:03:11 +010020#include <array>
Lalit Maganticaed37e2018-06-01 03:03:08 +010021#include <deque>
Isabelle Taylor47328cf2018-06-12 14:33:59 +010022#include <map>
Lalit Maganticaed37e2018-06-01 03:03:08 +010023#include <string>
24#include <unordered_map>
Ioannis Ilkosb8b11102019-01-29 17:56:55 +000025#include <utility>
Lalit Maganticaed37e2018-06-01 03:03:08 +010026#include <vector>
27
Lalit Maganti35622b72018-06-06 12:03:11 +010028#include "perfetto/base/logging.h"
Eric Seckler83dcc8c2019-08-21 12:18:43 +010029#include "perfetto/base/time.h"
Primiano Tucci2c5488f2019-06-01 03:27:28 +010030#include "perfetto/ext/base/hash.h"
31#include "perfetto/ext/base/optional.h"
32#include "perfetto/ext/base/string_view.h"
Primiano Tucci2c5488f2019-06-01 03:27:28 +010033#include "perfetto/ext/base/utils.h"
Lalit Magantib0b53ee2019-01-24 17:53:39 +000034#include "src/trace_processor/ftrace_utils.h"
Mikhail Khokhlove466c002019-05-23 13:33:33 +010035#include "src/trace_processor/metadata.h"
Primiano Tucci0e38a142019-01-07 20:51:09 +000036#include "src/trace_processor/stats.h"
Lalit Maganti5c454312019-04-08 12:11:17 +010037#include "src/trace_processor/string_pool.h"
Mikhail Khokhlov85a0dd02019-05-17 14:22:28 +010038#include "src/trace_processor/variadic.h"
Lalit Maganti35622b72018-06-06 12:03:11 +010039
Lalit Maganticaed37e2018-06-01 03:03:08 +010040namespace perfetto {
41namespace trace_processor {
42
Isabelle Taylora0a22972018-08-03 12:06:12 +010043// UniquePid is an offset into |unique_processes_|. This is necessary because
44// Unix pids are reused and thus not guaranteed to be unique over a long
45// period of time.
46using UniquePid = uint32_t;
Primiano Tucci0d72a312018-08-07 14:42:45 +010047
Isabelle Taylora0a22972018-08-03 12:06:12 +010048// UniqueTid is an offset into |unique_threads_|. Necessary because tids can
49// be reused.
50using UniqueTid = uint32_t;
51
Primiano Tucci0d72a312018-08-07 14:42:45 +010052// StringId is an offset into |string_pool_|.
Lalit Maganti5c454312019-04-08 12:11:17 +010053using StringId = StringPool::Id;
Lalit Maganti1a2936f2019-08-29 17:42:33 +010054static const StringId kNullStringId = StringId(0);
Primiano Tucci0d72a312018-08-07 14:42:45 +010055
Lalit Maganti5ea9e932018-11-30 14:19:39 +000056// Identifiers for all the tables in the database.
57enum TableId : uint8_t {
58 // Intentionally don't have TableId == 0 so that RowId == 0 can refer to an
59 // invalid row id.
Lalit Maganti8320e6d2019-03-14 18:49:33 +000060 kCounterValues = 1,
Lalit Maganti1d915a62019-01-07 12:10:42 +000061 kRawEvents = 2,
Lalit Maganti66ed7ad2019-01-11 16:47:26 +000062 kInstants = 3,
Isabelle Taylorb9222c32019-01-31 10:58:37 +000063 kSched = 4,
Eric Seckler70cc4422019-05-28 16:00:23 +010064 kNestableSlices = 5,
Ryan Savitski51413ad2019-07-09 14:25:21 +010065 kMetadataTable = 6,
Lalit Maganti5ea9e932018-11-30 14:19:39 +000066};
67
68// The top 8 bits are set to the TableId and the bottom 32 to the row of the
69// table.
Lalit Maganti85ca4a82018-12-07 17:28:02 +000070using RowId = int64_t;
Lalit Maganti5ea9e932018-11-30 14:19:39 +000071static const RowId kInvalidRowId = 0;
72
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +000073using ArgSetId = uint32_t;
74static const ArgSetId kInvalidArgSetId = 0;
75
Eric Seckler5703ede2019-07-10 10:13:02 +010076using TrackId = uint32_t;
77
78enum class VirtualTrackScope : uint8_t {
79 // VirtualTrack with global scope, will not have a |upid| set.
80 kGlobal = 0,
81 // VirtualTrack associated with a specific process via |upid|.
82 kProcess = 1
83};
84
Isabelle Taylora97c5f52018-10-23 17:36:12 +010085enum RefType {
Primiano Tucci5403e4f2018-11-27 10:07:03 +000086 kRefNoRef = 0,
87 kRefUtid = 1,
88 kRefCpuId = 2,
89 kRefIrq = 3,
90 kRefSoftIrq = 4,
91 kRefUpid = 5,
Sidath Senanayake1f5f93a2019-06-06 22:24:15 +010092 kRefGpuId = 6,
Eric Seckler5703ede2019-07-10 10:13:02 +010093 kRefTrack = 7,
Primiano Tucci5403e4f2018-11-27 10:07:03 +000094 kRefMax
Isabelle Taylora97c5f52018-10-23 17:36:12 +010095};
Isabelle Taylor14674d42018-09-07 11:33:11 +010096
Eric Seckler972225e2019-04-18 11:07:12 +010097const std::vector<const char*>& GetRefTypeStringMap();
98
Lalit Maganticaed37e2018-06-01 03:03:08 +010099// Stores a data inside a trace file in a columnar form. This makes it efficient
100// to read or search across a single field of the trace (e.g. all the thread
101// names for a given CPU).
102class TraceStorage {
103 public:
Isabelle Taylor47328cf2018-06-12 14:33:59 +0100104 TraceStorage();
Isabelle Taylora0a22972018-08-03 12:06:12 +0100105
106 virtual ~TraceStorage();
Isabelle Taylor47328cf2018-06-12 14:33:59 +0100107
Isabelle Taylora0a22972018-08-03 12:06:12 +0100108 // Information about a unique process seen in a trace.
109 struct Process {
Primiano Tuccib75dcee2018-08-08 12:21:36 +0100110 explicit Process(uint32_t p) : pid(p) {}
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000111 int64_t start_ns = 0;
Lalit Maganti637589a2019-07-04 17:25:29 +0100112 int64_t end_ns = 0;
Isabelle Taylora0a22972018-08-03 12:06:12 +0100113 StringId name_id = 0;
Primiano Tuccib75dcee2018-08-08 12:21:36 +0100114 uint32_t pid = 0;
Lalit Maganti369b0572019-07-11 15:35:09 +0100115 base::Optional<UniquePid> parent_upid;
Isabelle Taylora0a22972018-08-03 12:06:12 +0100116 };
117
118 // Information about a unique thread seen in a trace.
119 struct Thread {
Primiano Tuccib75dcee2018-08-08 12:21:36 +0100120 explicit Thread(uint32_t t) : tid(t) {}
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000121 int64_t start_ns = 0;
Lalit Magantib5bd2332019-06-06 14:20:47 +0100122 int64_t end_ns = 0;
Isabelle Taylora0a22972018-08-03 12:06:12 +0100123 StringId name_id = 0;
Lalit Maganti770886a2018-11-16 17:40:21 +0000124 base::Optional<UniquePid> upid;
Primiano Tuccib75dcee2018-08-08 12:21:36 +0100125 uint32_t tid = 0;
Isabelle Taylora0a22972018-08-03 12:06:12 +0100126 };
Isabelle Taylor3dd366c2018-06-22 16:21:41 +0100127
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000128 // Generic key value storage which can be referenced by other tables.
129 class Args {
130 public:
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000131 struct Arg {
132 StringId flat_key = 0;
133 StringId key = 0;
134 Variadic value = Variadic::Integer(0);
135
136 // This is only used by the arg tracker and so is not part of the hash.
137 RowId row_id = 0;
138 };
139
140 struct ArgHasher {
141 uint64_t operator()(const Arg& arg) const noexcept {
Lalit Maganti1f464742019-02-28 13:49:31 +0000142 base::Hash hash;
143 hash.Update(arg.key);
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000144 // We don't hash arg.flat_key because it's a subsequence of arg.key.
145 switch (arg.value.type) {
146 case Variadic::Type::kInt:
Lalit Maganti1f464742019-02-28 13:49:31 +0000147 hash.Update(arg.value.int_value);
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000148 break;
Eric Secklerc93823e2019-06-03 16:49:19 +0100149 case Variadic::Type::kUint:
150 hash.Update(arg.value.uint_value);
151 break;
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000152 case Variadic::Type::kString:
Lalit Maganti1f464742019-02-28 13:49:31 +0000153 hash.Update(arg.value.string_value);
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000154 break;
155 case Variadic::Type::kReal:
Lalit Maganti1f464742019-02-28 13:49:31 +0000156 hash.Update(arg.value.real_value);
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000157 break;
Eric Secklerc93823e2019-06-03 16:49:19 +0100158 case Variadic::Type::kPointer:
159 hash.Update(arg.value.pointer_value);
160 break;
161 case Variadic::Type::kBool:
162 hash.Update(arg.value.bool_value);
163 break;
164 case Variadic::Type::kJson:
165 hash.Update(arg.value.json_value);
166 break;
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000167 }
Lalit Maganti1f464742019-02-28 13:49:31 +0000168 return hash.digest();
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000169 }
170 };
171
172 const std::deque<ArgSetId>& set_ids() const { return set_ids_; }
Lalit Maganti5ea9e932018-11-30 14:19:39 +0000173 const std::deque<StringId>& flat_keys() const { return flat_keys_; }
174 const std::deque<StringId>& keys() const { return keys_; }
Lalit Maganti1d915a62019-01-07 12:10:42 +0000175 const std::deque<Variadic>& arg_values() const { return arg_values_; }
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000176 uint32_t args_count() const {
177 return static_cast<uint32_t>(set_ids_.size());
Lalit Maganti79472be2018-12-04 13:41:27 +0000178 }
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000179
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000180 ArgSetId AddArgSet(const std::vector<Arg>& args,
181 uint32_t begin,
182 uint32_t end) {
Lalit Maganti1f464742019-02-28 13:49:31 +0000183 base::Hash hash;
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000184 for (uint32_t i = begin; i < end; i++) {
Lalit Maganti1f464742019-02-28 13:49:31 +0000185 hash.Update(ArgHasher()(args[i]));
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000186 }
Lalit Maganti5ea9e932018-11-30 14:19:39 +0000187
Lalit Maganti1f464742019-02-28 13:49:31 +0000188 ArgSetHash digest = hash.digest();
189 auto it = arg_row_for_hash_.find(digest);
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000190 if (it != arg_row_for_hash_.end()) {
191 return set_ids_[it->second];
192 }
193
194 // The +1 ensures that nothing has an id == kInvalidArgSetId == 0.
195 ArgSetId id = static_cast<uint32_t>(arg_row_for_hash_.size()) + 1;
Lalit Maganti1f464742019-02-28 13:49:31 +0000196 arg_row_for_hash_.emplace(digest, args_count());
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000197 for (uint32_t i = begin; i < end; i++) {
198 const auto& arg = args[i];
199 set_ids_.emplace_back(id);
200 flat_keys_.emplace_back(arg.flat_key);
201 keys_.emplace_back(arg.key);
202 arg_values_.emplace_back(arg.value);
203 }
204 return id;
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000205 }
206
Lalit Maganti5ea9e932018-11-30 14:19:39 +0000207 private:
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000208 using ArgSetHash = uint64_t;
209
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000210 std::deque<ArgSetId> set_ids_;
Lalit Maganti5ea9e932018-11-30 14:19:39 +0000211 std::deque<StringId> flat_keys_;
212 std::deque<StringId> keys_;
Lalit Maganti1d915a62019-01-07 12:10:42 +0000213 std::deque<Variadic> arg_values_;
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000214
215 std::unordered_map<ArgSetHash, uint32_t> arg_row_for_hash_;
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000216 };
217
Lalit Magantid11d3e02019-07-26 12:32:09 +0530218 class Tracks {
219 public:
220 inline uint32_t AddTrack(StringId name) {
221 names_.emplace_back(name);
222 return track_count() - 1;
223 }
224
225 uint32_t track_count() const {
226 return static_cast<uint32_t>(names_.size());
227 }
228
229 const std::deque<StringId>& names() const { return names_; }
230
231 private:
232 std::deque<StringId> names_;
233 };
234
Eric Seckler5703ede2019-07-10 10:13:02 +0100235 class VirtualTracks {
236 public:
Lalit Magantid11d3e02019-07-26 12:32:09 +0530237 inline void AddVirtualTrack(TrackId track_id,
238 VirtualTrackScope scope,
239 UniquePid upid = 0u) {
Eric Seckler5703ede2019-07-10 10:13:02 +0100240 track_ids_.emplace_back(track_id);
Eric Seckler5703ede2019-07-10 10:13:02 +0100241 scopes_.emplace_back(scope);
242 upids_.emplace_back(upid);
Eric Seckler5703ede2019-07-10 10:13:02 +0100243 }
244
245 uint32_t virtual_track_count() const {
246 return static_cast<uint32_t>(track_ids_.size());
247 }
248
Lalit Magantid11d3e02019-07-26 12:32:09 +0530249 base::Optional<uint32_t> FindRowForTrackId(uint32_t track_id) const {
250 auto it =
251 std::lower_bound(track_ids().begin(), track_ids().end(), track_id);
252 if (it != track_ids().end() && *it == track_id) {
253 return static_cast<uint32_t>(std::distance(track_ids().begin(), it));
254 }
255 return base::nullopt;
256 }
257
Eric Seckler5703ede2019-07-10 10:13:02 +0100258 const std::deque<uint32_t>& track_ids() const { return track_ids_; }
Eric Seckler5703ede2019-07-10 10:13:02 +0100259 const std::deque<VirtualTrackScope>& scopes() const { return scopes_; }
260 const std::deque<UniquePid>& upids() const { return upids_; }
261
262 private:
263 std::deque<uint32_t> track_ids_;
Eric Seckler5703ede2019-07-10 10:13:02 +0100264 std::deque<VirtualTrackScope> scopes_;
265 std::deque<UniquePid> upids_;
266 };
267
Mikael Pessa803090c2019-08-23 16:03:34 -0700268 class GpuTracks {
269 public:
270 inline void AddGpuTrack(TrackId track_id,
271 StringId scope,
272 // For all below: null == numeric_limits<int_type>::max()
273 uint64_t context_id) {
274 track_ids_.emplace_back(track_id);
275 scopes_.emplace_back(scope);
276 context_ids_.emplace_back(context_id);
277 }
278
279 uint32_t gpu_track_count() const {
280 return static_cast<uint32_t>(track_ids_.size());
281 }
282
283 base::Optional<uint32_t> FindRowForTrackId(uint32_t track_id) const {
284 auto it =
285 std::lower_bound(track_ids().begin(), track_ids().end(), track_id);
286 if (it != track_ids().end() && *it == track_id) {
287 return static_cast<uint32_t>(std::distance(track_ids().begin(), it));
288 }
289 return base::nullopt;
290 }
291
292 const std::deque<TrackId>& track_ids() const { return track_ids_; }
293 const std::deque<StringId>& scopes() const { return scopes_; }
294 const std::deque<uint64_t>& context_ids() const {
295 return context_ids_;
296 }
297
298 private:
299 std::deque<TrackId> track_ids_;
300 std::deque<StringId> scopes_;
301
302 // For all below: null == numeric_limits<int_type>::max()
303 std::deque<uint64_t> context_ids_;
304 };
305
306 class GpuContexts {
307 public:
308 inline void AddGpuContext(uint64_t context_id,
309 UniquePid upid,
310 uint32_t priority) {
311 context_ids_.emplace_back(context_id);
312 upids_.emplace_back(upid);
313 priorities_.emplace_back(priority);
314 }
315
316 uint32_t gpu_context_count() const {
317 return static_cast<uint32_t>(context_ids_.size());
318 }
319
320 const std::deque<uint64_t>& context_ids() const { return context_ids_; }
321 const std::deque<UniquePid>& upids() const { return upids_; }
322 const std::deque<uint32_t>& priorities() const { return priorities_; }
323
324 private:
325 std::deque<uint64_t> context_ids_;
326 std::deque<UniquePid> upids_;
327 std::deque<uint32_t> priorities_;
328 };
329
Lalit Magantiff69c112018-09-24 12:07:47 +0100330 class Slices {
Lalit Maganti35622b72018-06-06 12:03:11 +0100331 public:
Lalit Magantifde29042018-10-04 13:28:52 +0100332 inline size_t AddSlice(uint32_t cpu,
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000333 int64_t start_ns,
334 int64_t duration_ns,
Lalit Magantib0b53ee2019-01-24 17:53:39 +0000335 UniqueTid utid,
336 ftrace_utils::TaskState end_state,
337 int32_t priority) {
Lalit Magantiff69c112018-09-24 12:07:47 +0100338 cpus_.emplace_back(cpu);
Lalit Maganti35622b72018-06-06 12:03:11 +0100339 start_ns_.emplace_back(start_ns);
340 durations_.emplace_back(duration_ns);
Isabelle Taylora0a22972018-08-03 12:06:12 +0100341 utids_.emplace_back(utid);
Lalit Magantib0b53ee2019-01-24 17:53:39 +0000342 end_states_.emplace_back(end_state);
343 priorities_.emplace_back(priority);
Lalit Maganti58638932019-01-31 10:48:26 +0000344
345 if (utid >= rows_for_utids_.size())
346 rows_for_utids_.resize(utid + 1);
347 rows_for_utids_[utid].emplace_back(slice_count() - 1);
Lalit Magantifde29042018-10-04 13:28:52 +0100348 return slice_count() - 1;
349 }
350
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000351 void set_duration(size_t index, int64_t duration_ns) {
Lalit Magantifde29042018-10-04 13:28:52 +0100352 durations_[index] = duration_ns;
Lalit Maganti35622b72018-06-06 12:03:11 +0100353 }
354
Lalit Magantib0b53ee2019-01-24 17:53:39 +0000355 void set_end_state(size_t index, ftrace_utils::TaskState end_state) {
356 end_states_[index] = end_state;
357 }
358
Isabelle Taylor47328cf2018-06-12 14:33:59 +0100359 size_t slice_count() const { return start_ns_.size(); }
Lalit Maganti35622b72018-06-06 12:03:11 +0100360
Lalit Magantiff69c112018-09-24 12:07:47 +0100361 const std::deque<uint32_t>& cpus() const { return cpus_; }
362
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000363 const std::deque<int64_t>& start_ns() const { return start_ns_; }
Lalit Maganti35622b72018-06-06 12:03:11 +0100364
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000365 const std::deque<int64_t>& durations() const { return durations_; }
Lalit Maganti35622b72018-06-06 12:03:11 +0100366
Isabelle Taylor68e42192018-06-19 16:19:31 +0100367 const std::deque<UniqueTid>& utids() const { return utids_; }
368
Lalit Magantib0b53ee2019-01-24 17:53:39 +0000369 const std::deque<ftrace_utils::TaskState>& end_state() const {
370 return end_states_;
371 }
372
373 const std::deque<int32_t>& priorities() const { return priorities_; }
374
Lalit Maganti58638932019-01-31 10:48:26 +0000375 const std::deque<std::vector<uint32_t>>& rows_for_utids() const {
Lalit Magantif0f09c32019-01-18 17:29:31 +0000376 return rows_for_utids_;
377 }
378
Lalit Maganti35622b72018-06-06 12:03:11 +0100379 private:
Hector Dearman947f12a2018-09-11 16:50:36 +0100380 // Each deque below has the same number of entries (the number of slices
Lalit Maganti35622b72018-06-06 12:03:11 +0100381 // in the trace for the CPU).
Lalit Magantiff69c112018-09-24 12:07:47 +0100382 std::deque<uint32_t> cpus_;
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000383 std::deque<int64_t> start_ns_;
384 std::deque<int64_t> durations_;
Isabelle Taylor68e42192018-06-19 16:19:31 +0100385 std::deque<UniqueTid> utids_;
Lalit Magantib0b53ee2019-01-24 17:53:39 +0000386 std::deque<ftrace_utils::TaskState> end_states_;
387 std::deque<int32_t> priorities_;
Lalit Maganti58638932019-01-31 10:48:26 +0000388
389 // One row per utid.
390 std::deque<std::vector<uint32_t>> rows_for_utids_;
Primiano Tucci0d72a312018-08-07 14:42:45 +0100391 };
Isabelle Taylor68e42192018-06-19 16:19:31 +0100392
Primiano Tucci0d72a312018-08-07 14:42:45 +0100393 class NestableSlices {
394 public:
Eric Seckler70cc4422019-05-28 16:00:23 +0100395 inline uint32_t AddSlice(int64_t start_ns,
396 int64_t duration_ns,
397 int64_t ref,
398 RefType type,
Lalit Maganti81a02cd2019-07-12 17:05:11 +0100399 StringId category,
Eric Seckler70cc4422019-05-28 16:00:23 +0100400 StringId name,
401 uint8_t depth,
402 int64_t stack_id,
403 int64_t parent_stack_id) {
Primiano Tucci0d72a312018-08-07 14:42:45 +0100404 start_ns_.emplace_back(start_ns);
405 durations_.emplace_back(duration_ns);
Eric Seckler972225e2019-04-18 11:07:12 +0100406 refs_.emplace_back(ref);
407 types_.emplace_back(type);
Lalit Maganti81a02cd2019-07-12 17:05:11 +0100408 categories_.emplace_back(category);
Primiano Tucci0d72a312018-08-07 14:42:45 +0100409 names_.emplace_back(name);
410 depths_.emplace_back(depth);
Primiano Tuccib75dcee2018-08-08 12:21:36 +0100411 stack_ids_.emplace_back(stack_id);
412 parent_stack_ids_.emplace_back(parent_stack_id);
Eric Seckler70cc4422019-05-28 16:00:23 +0100413 arg_set_ids_.emplace_back(kInvalidArgSetId);
Lalit Maganti7b37bbf2018-11-09 15:58:54 +0000414 return slice_count() - 1;
415 }
416
Eric Seckler70cc4422019-05-28 16:00:23 +0100417 void set_duration(uint32_t index, int64_t duration_ns) {
Lalit Maganti7b37bbf2018-11-09 15:58:54 +0000418 durations_[index] = duration_ns;
419 }
420
Eric Seckler70cc4422019-05-28 16:00:23 +0100421 void set_stack_id(uint32_t index, int64_t stack_id) {
Lalit Maganti7b37bbf2018-11-09 15:58:54 +0000422 stack_ids_[index] = stack_id;
Primiano Tucci0d72a312018-08-07 14:42:45 +0100423 }
424
Eric Seckler70cc4422019-05-28 16:00:23 +0100425 void set_arg_set_id(uint32_t index, ArgSetId id) {
426 arg_set_ids_[index] = id;
427 }
428
429 uint32_t slice_count() const {
430 return static_cast<uint32_t>(start_ns_.size());
431 }
432
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000433 const std::deque<int64_t>& start_ns() const { return start_ns_; }
434 const std::deque<int64_t>& durations() const { return durations_; }
Eric Seckler972225e2019-04-18 11:07:12 +0100435 const std::deque<int64_t>& refs() const { return refs_; }
436 const std::deque<RefType>& types() const { return types_; }
Lalit Maganti81a02cd2019-07-12 17:05:11 +0100437 const std::deque<StringId>& categories() const { return categories_; }
Primiano Tucci0d72a312018-08-07 14:42:45 +0100438 const std::deque<StringId>& names() const { return names_; }
439 const std::deque<uint8_t>& depths() const { return depths_; }
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000440 const std::deque<int64_t>& stack_ids() const { return stack_ids_; }
441 const std::deque<int64_t>& parent_stack_ids() const {
Primiano Tuccib75dcee2018-08-08 12:21:36 +0100442 return parent_stack_ids_;
443 }
Eric Seckler70cc4422019-05-28 16:00:23 +0100444 const std::deque<ArgSetId>& arg_set_ids() const { return arg_set_ids_; }
Primiano Tucci0d72a312018-08-07 14:42:45 +0100445
446 private:
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000447 std::deque<int64_t> start_ns_;
448 std::deque<int64_t> durations_;
Eric Seckler972225e2019-04-18 11:07:12 +0100449 std::deque<int64_t> refs_;
450 std::deque<RefType> types_;
Lalit Maganti81a02cd2019-07-12 17:05:11 +0100451 std::deque<StringId> categories_;
Primiano Tucci0d72a312018-08-07 14:42:45 +0100452 std::deque<StringId> names_;
453 std::deque<uint8_t> depths_;
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000454 std::deque<int64_t> stack_ids_;
455 std::deque<int64_t> parent_stack_ids_;
Eric Seckler70cc4422019-05-28 16:00:23 +0100456 std::deque<ArgSetId> arg_set_ids_;
Lalit Maganti35622b72018-06-06 12:03:11 +0100457 };
458
Eric Secklerd3b89d52019-07-10 15:36:29 +0100459 class ThreadSlices {
460 public:
461 inline uint32_t AddThreadSlice(uint32_t slice_id,
462 int64_t thread_timestamp_ns,
463 int64_t thread_duration_ns,
464 int64_t thread_instruction_count,
465 int64_t thread_instruction_delta) {
466 slice_ids_.emplace_back(slice_id);
467 thread_timestamp_ns_.emplace_back(thread_timestamp_ns);
468 thread_duration_ns_.emplace_back(thread_duration_ns);
469 thread_instruction_counts_.emplace_back(thread_instruction_count);
470 thread_instruction_deltas_.emplace_back(thread_instruction_delta);
471 return slice_count() - 1;
472 }
473
Eric Secklerc3430c62019-07-22 10:49:58 +0100474 uint32_t slice_count() const {
475 return static_cast<uint32_t>(slice_ids_.size());
Eric Secklerd3b89d52019-07-10 15:36:29 +0100476 }
477
Eric Secklerc3430c62019-07-22 10:49:58 +0100478 const std::deque<uint32_t>& slice_ids() const { return slice_ids_; }
479 const std::deque<int64_t>& thread_timestamp_ns() const {
480 return thread_timestamp_ns_;
481 }
482 const std::deque<int64_t>& thread_duration_ns() const {
483 return thread_duration_ns_;
484 }
485 const std::deque<int64_t>& thread_instruction_counts() const {
486 return thread_instruction_counts_;
487 }
488 const std::deque<int64_t>& thread_instruction_deltas() const {
489 return thread_instruction_deltas_;
490 }
491
492 base::Optional<uint32_t> FindRowForSliceId(uint32_t slice_id) const {
493 auto it =
494 std::lower_bound(slice_ids().begin(), slice_ids().end(), slice_id);
495 if (it != slice_ids().end() && *it == slice_id) {
496 return static_cast<uint32_t>(std::distance(slice_ids().begin(), it));
497 }
498 return base::nullopt;
499 }
500
Eric Seckler54f30a32019-07-19 15:10:29 +0100501 void UpdateThreadDeltasForSliceId(uint32_t slice_id,
502 int64_t end_thread_timestamp_ns,
503 int64_t end_thread_instruction_count) {
Eric Secklerc3430c62019-07-22 10:49:58 +0100504 uint32_t row = *FindRowForSliceId(slice_id);
505 int64_t begin_ns = thread_timestamp_ns_[row];
506 thread_duration_ns_[row] = end_thread_timestamp_ns - begin_ns;
Eric Seckler54f30a32019-07-19 15:10:29 +0100507 int64_t begin_ticount = thread_instruction_counts_[row];
508 thread_instruction_deltas_[row] =
509 end_thread_instruction_count - begin_ticount;
Eric Secklerc3430c62019-07-22 10:49:58 +0100510 }
511
512 private:
513 std::deque<uint32_t> slice_ids_;
514 std::deque<int64_t> thread_timestamp_ns_;
515 std::deque<int64_t> thread_duration_ns_;
516 std::deque<int64_t> thread_instruction_counts_;
517 std::deque<int64_t> thread_instruction_deltas_;
518 };
519
520 class VirtualTrackSlices {
521 public:
522 inline uint32_t AddVirtualTrackSlice(uint32_t slice_id,
523 int64_t thread_timestamp_ns,
524 int64_t thread_duration_ns,
525 int64_t thread_instruction_count,
526 int64_t thread_instruction_delta) {
527 slice_ids_.emplace_back(slice_id);
528 thread_timestamp_ns_.emplace_back(thread_timestamp_ns);
529 thread_duration_ns_.emplace_back(thread_duration_ns);
530 thread_instruction_counts_.emplace_back(thread_instruction_count);
531 thread_instruction_deltas_.emplace_back(thread_instruction_delta);
532 return slice_count() - 1;
Eric Secklerd3b89d52019-07-10 15:36:29 +0100533 }
534
535 uint32_t slice_count() const {
536 return static_cast<uint32_t>(slice_ids_.size());
537 }
538
539 const std::deque<uint32_t>& slice_ids() const { return slice_ids_; }
540 const std::deque<int64_t>& thread_timestamp_ns() const {
541 return thread_timestamp_ns_;
542 }
543 const std::deque<int64_t>& thread_duration_ns() const {
544 return thread_duration_ns_;
545 }
546 const std::deque<int64_t>& thread_instruction_counts() const {
547 return thread_instruction_counts_;
548 }
549 const std::deque<int64_t>& thread_instruction_deltas() const {
550 return thread_instruction_deltas_;
551 }
552
Mikhail Khokhlov7db04912019-07-18 16:11:11 +0100553 base::Optional<uint32_t> FindRowForSliceId(uint32_t slice_id) const {
Eric Secklerd3b89d52019-07-10 15:36:29 +0100554 auto it =
555 std::lower_bound(slice_ids().begin(), slice_ids().end(), slice_id);
Mikhail Khokhlov7db04912019-07-18 16:11:11 +0100556 if (it != slice_ids().end() && *it == slice_id) {
557 return static_cast<uint32_t>(std::distance(slice_ids().begin(), it));
558 }
559 return base::nullopt;
Eric Secklerd3b89d52019-07-10 15:36:29 +0100560 }
561
Eric Seckler54f30a32019-07-19 15:10:29 +0100562 void UpdateThreadDeltasForSliceId(uint32_t slice_id,
563 int64_t end_thread_timestamp_ns,
564 int64_t end_thread_instruction_count) {
Mikhail Khokhlov7db04912019-07-18 16:11:11 +0100565 uint32_t row = *FindRowForSliceId(slice_id);
Eric Secklerd3b89d52019-07-10 15:36:29 +0100566 int64_t begin_ns = thread_timestamp_ns_[row];
567 thread_duration_ns_[row] = end_thread_timestamp_ns - begin_ns;
Eric Seckler54f30a32019-07-19 15:10:29 +0100568 int64_t begin_ticount = thread_instruction_counts_[row];
569 thread_instruction_deltas_[row] =
570 end_thread_instruction_count - begin_ticount;
Eric Secklerd3b89d52019-07-10 15:36:29 +0100571 }
572
573 private:
574 std::deque<uint32_t> slice_ids_;
575 std::deque<int64_t> thread_timestamp_ns_;
576 std::deque<int64_t> thread_duration_ns_;
577 std::deque<int64_t> thread_instruction_counts_;
578 std::deque<int64_t> thread_instruction_deltas_;
579 };
580
Mikael Pessa803090c2019-08-23 16:03:34 -0700581 class GpuSlices {
582 public:
583 inline uint32_t AddGpuSlice(uint32_t slice_id,
584 // For all below: null == numeric_limits<int_type>::max()
585 uint64_t context_id,
586 uint64_t render_target,
587 uint32_t frame_id,
588 uint32_t job_id,
589 uint32_t hw_queue_id) {
590 slice_ids_.emplace_back(slice_id);
591 context_ids_.emplace_back(context_id);
592 render_targets_.emplace_back(render_target);
593 frame_ids_.emplace_back(frame_id);
594 job_ids_.emplace_back(job_id);
595 hw_queue_ids_.emplace_back(hw_queue_id);
596 return slice_count() - 1;
597 }
598
599 uint32_t slice_count() const {
600 return static_cast<uint32_t>(slice_ids_.size());
601 }
602
603 const std::deque<uint32_t>& slice_ids() const { return slice_ids_; }
604 const std::deque<uint64_t>& context_ids() const {
605 return context_ids_;
606 }
607 const std::deque<uint64_t>& render_targets() const {
608 return render_targets_;
609 }
610 const std::deque<uint32_t>& frame_ids() const {
611 return frame_ids_;
612 }
613 const std::deque<uint32_t>& job_ids() const {
614 return job_ids_;
615 }
616 const std::deque<uint32_t>& hw_queue_ids() const {
617 return hw_queue_ids_;
618 }
619
620 base::Optional<uint32_t> FindRowForSliceId(uint32_t slice_id) const {
621 auto it =
622 std::lower_bound(slice_ids().begin(), slice_ids().end(), slice_id);
623 if (it != slice_ids().end() && *it == slice_id) {
624 return static_cast<uint32_t>(std::distance(slice_ids().begin(), it));
625 }
626 return base::nullopt;
627 }
628
629 private:
630 std::deque<uint32_t> slice_ids_;
631
632 // For all below: null == numeric_limits<int_type>::max()
633 std::deque<uint64_t> context_ids_;
634 std::deque<uint64_t> render_targets_;
635 std::deque<uint32_t> frame_ids_;
636 std::deque<uint32_t> job_ids_;
637 std::deque<uint32_t> hw_queue_ids_;
638 };
639
Lalit Maganti8320e6d2019-03-14 18:49:33 +0000640 class CounterDefinitions {
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100641 public:
Lalit Maganti8320e6d2019-03-14 18:49:33 +0000642 using Id = uint32_t;
Lalit Maganti521d97b2019-04-29 13:47:03 +0100643 static constexpr Id kInvalidId = std::numeric_limits<Id>::max();
Lalit Maganti8320e6d2019-03-14 18:49:33 +0000644
645 inline Id AddCounterDefinition(StringId name_id,
646 int64_t ref,
Pascal Muetschard91d07892019-08-26 13:55:06 -0700647 RefType type,
Pascal Muetschardceb5c822019-08-26 14:39:15 -0700648 StringId desc_id = 0,
649 StringId unit_id = 0) {
Lalit Maganti8320e6d2019-03-14 18:49:33 +0000650 base::Hash hash;
651 hash.Update(name_id);
652 hash.Update(ref);
653 hash.Update(type);
654
655 // TODO(lalitm): this is a perf bottleneck and likely we can do something
656 // quite a bit better here.
657 uint64_t digest = hash.digest();
658 auto it = hash_to_row_idx_.find(digest);
659 if (it != hash_to_row_idx_.end())
660 return it->second;
661
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100662 name_ids_.emplace_back(name_id);
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100663 refs_.emplace_back(ref);
664 types_.emplace_back(type);
Pascal Muetschard91d07892019-08-26 13:55:06 -0700665 desc_ids_.emplace_back(desc_id);
Pascal Muetschardceb5c822019-08-26 14:39:15 -0700666 unit_ids_.emplace_back(unit_id);
Lalit Maganti8320e6d2019-03-14 18:49:33 +0000667 hash_to_row_idx_.emplace(digest, size() - 1);
668 return size() - 1;
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100669 }
Lalit Magantifde29042018-10-04 13:28:52 +0100670
Lalit Maganti8320e6d2019-03-14 18:49:33 +0000671 uint32_t size() const { return static_cast<uint32_t>(name_ids_.size()); }
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100672
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100673 const std::deque<StringId>& name_ids() const { return name_ids_; }
674
Pascal Muetschard91d07892019-08-26 13:55:06 -0700675 const std::deque<StringId>& desc_ids() const { return desc_ids_; }
676
Pascal Muetschardceb5c822019-08-26 14:39:15 -0700677 const std::deque<StringId>& unit_ids() const { return unit_ids_; }
678
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100679 const std::deque<int64_t>& refs() const { return refs_; }
680
681 const std::deque<RefType>& types() const { return types_; }
682
Lalit Maganti8320e6d2019-03-14 18:49:33 +0000683 private:
684 std::deque<StringId> name_ids_;
685 std::deque<int64_t> refs_;
686 std::deque<RefType> types_;
Pascal Muetschard91d07892019-08-26 13:55:06 -0700687 std::deque<StringId> desc_ids_;
Pascal Muetschardceb5c822019-08-26 14:39:15 -0700688 std::deque<StringId> unit_ids_;
Lalit Maganti8320e6d2019-03-14 18:49:33 +0000689
690 std::unordered_map<uint64_t, uint32_t> hash_to_row_idx_;
691 };
692
693 class CounterValues {
694 public:
695 inline uint32_t AddCounterValue(CounterDefinitions::Id counter_id,
696 int64_t timestamp,
697 double value) {
698 counter_ids_.emplace_back(counter_id);
699 timestamps_.emplace_back(timestamp);
700 values_.emplace_back(value);
701 arg_set_ids_.emplace_back(kInvalidArgSetId);
Ioannis Ilkosf129c262019-04-25 14:53:51 +0100702
Lalit Maganti521d97b2019-04-29 13:47:03 +0100703 if (counter_id != CounterDefinitions::kInvalidId) {
704 if (counter_id >= rows_for_counter_id_.size()) {
705 rows_for_counter_id_.resize(counter_id + 1);
706 }
707 rows_for_counter_id_[counter_id].emplace_back(size() - 1);
708 }
709 return size() - 1;
710 }
711
712 void set_counter_id(uint32_t index, CounterDefinitions::Id counter_id) {
713 PERFETTO_DCHECK(counter_ids_[index] == CounterDefinitions::kInvalidId);
714
715 counter_ids_[index] = counter_id;
Ioannis Ilkosf129c262019-04-25 14:53:51 +0100716 if (counter_id >= rows_for_counter_id_.size()) {
717 rows_for_counter_id_.resize(counter_id + 1);
718 }
Lalit Maganti521d97b2019-04-29 13:47:03 +0100719
720 auto* new_rows = &rows_for_counter_id_[counter_id];
721 new_rows->insert(
722 std::upper_bound(new_rows->begin(), new_rows->end(), index), index);
Lalit Maganti8320e6d2019-03-14 18:49:33 +0000723 }
724
725 void set_arg_set_id(uint32_t row, ArgSetId id) { arg_set_ids_[row] = id; }
726
727 uint32_t size() const { return static_cast<uint32_t>(counter_ids_.size()); }
728
729 const std::deque<CounterDefinitions::Id>& counter_ids() const {
730 return counter_ids_;
731 }
732
733 const std::deque<int64_t>& timestamps() const { return timestamps_; }
734
735 const std::deque<double>& values() const { return values_; }
736
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000737 const std::deque<ArgSetId>& arg_set_ids() const { return arg_set_ids_; }
738
Ioannis Ilkosf129c262019-04-25 14:53:51 +0100739 const std::deque<std::vector<uint32_t>>& rows_for_counter_id() const {
740 return rows_for_counter_id_;
741 }
742
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100743 private:
Lalit Maganti8320e6d2019-03-14 18:49:33 +0000744 std::deque<CounterDefinitions::Id> counter_ids_;
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000745 std::deque<int64_t> timestamps_;
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100746 std::deque<double> values_;
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000747 std::deque<ArgSetId> arg_set_ids_;
Ioannis Ilkosf129c262019-04-25 14:53:51 +0100748
749 // Indexed by counter_id value and contains the row numbers corresponding to
750 // it.
751 std::deque<std::vector<uint32_t>> rows_for_counter_id_;
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100752 };
753
Primiano Tucci5cb84f82018-10-31 21:46:36 -0700754 class SqlStats {
755 public:
756 static constexpr size_t kMaxLogEntries = 100;
Lalit Magantiaac2f652019-04-30 12:16:21 +0100757 uint32_t RecordQueryBegin(const std::string& query,
758 int64_t time_queued,
759 int64_t time_started);
760 void RecordQueryFirstNext(uint32_t row, int64_t time_first_next);
761 void RecordQueryEnd(uint32_t row, int64_t time_end);
Primiano Tucci5cb84f82018-10-31 21:46:36 -0700762 size_t size() const { return queries_.size(); }
763 const std::deque<std::string>& queries() const { return queries_; }
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000764 const std::deque<int64_t>& times_queued() const { return times_queued_; }
765 const std::deque<int64_t>& times_started() const { return times_started_; }
Lalit Magantiaac2f652019-04-30 12:16:21 +0100766 const std::deque<int64_t>& times_first_next() const {
767 return times_first_next_;
768 }
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000769 const std::deque<int64_t>& times_ended() const { return times_ended_; }
Primiano Tucci5cb84f82018-10-31 21:46:36 -0700770
771 private:
Lalit Magantiaac2f652019-04-30 12:16:21 +0100772 uint32_t popped_queries_ = 0;
773
Primiano Tucci5cb84f82018-10-31 21:46:36 -0700774 std::deque<std::string> queries_;
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000775 std::deque<int64_t> times_queued_;
776 std::deque<int64_t> times_started_;
Lalit Magantiaac2f652019-04-30 12:16:21 +0100777 std::deque<int64_t> times_first_next_;
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000778 std::deque<int64_t> times_ended_;
Primiano Tucci5cb84f82018-10-31 21:46:36 -0700779 };
780
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000781 class Instants {
782 public:
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000783 inline uint32_t AddInstantEvent(int64_t timestamp,
784 StringId name_id,
785 double value,
786 int64_t ref,
787 RefType type) {
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000788 timestamps_.emplace_back(timestamp);
789 name_ids_.emplace_back(name_id);
790 values_.emplace_back(value);
791 refs_.emplace_back(ref);
792 types_.emplace_back(type);
Lalit Maganti1c21d172019-02-07 10:48:24 +0000793 arg_set_ids_.emplace_back(kInvalidArgSetId);
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000794 return static_cast<uint32_t>(instant_count() - 1);
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000795 }
796
Lalit Maganti521d97b2019-04-29 13:47:03 +0100797 void set_ref(uint32_t row, int64_t ref) { refs_[row] = ref; }
798
Lalit Maganti1c21d172019-02-07 10:48:24 +0000799 void set_arg_set_id(uint32_t row, ArgSetId id) { arg_set_ids_[row] = id; }
800
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000801 size_t instant_count() const { return timestamps_.size(); }
802
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000803 const std::deque<int64_t>& timestamps() const { return timestamps_; }
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000804
805 const std::deque<StringId>& name_ids() const { return name_ids_; }
806
807 const std::deque<double>& values() const { return values_; }
808
809 const std::deque<int64_t>& refs() const { return refs_; }
810
811 const std::deque<RefType>& types() const { return types_; }
812
Lalit Maganti1c21d172019-02-07 10:48:24 +0000813 const std::deque<ArgSetId>& arg_set_ids() const { return arg_set_ids_; }
814
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000815 private:
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000816 std::deque<int64_t> timestamps_;
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000817 std::deque<StringId> name_ids_;
818 std::deque<double> values_;
819 std::deque<int64_t> refs_;
820 std::deque<RefType> types_;
Lalit Maganti1c21d172019-02-07 10:48:24 +0000821 std::deque<ArgSetId> arg_set_ids_;
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000822 };
823
Lalit Maganti1d915a62019-01-07 12:10:42 +0000824 class RawEvents {
825 public:
826 inline RowId AddRawEvent(int64_t timestamp,
827 StringId name_id,
Lalit Magantie87cc812019-01-10 15:20:06 +0000828 uint32_t cpu,
Lalit Maganti1d915a62019-01-07 12:10:42 +0000829 UniqueTid utid) {
830 timestamps_.emplace_back(timestamp);
831 name_ids_.emplace_back(name_id);
Lalit Magantie87cc812019-01-10 15:20:06 +0000832 cpus_.emplace_back(cpu);
Lalit Maganti1d915a62019-01-07 12:10:42 +0000833 utids_.emplace_back(utid);
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000834 arg_set_ids_.emplace_back(kInvalidArgSetId);
Lalit Maganti1d915a62019-01-07 12:10:42 +0000835 return CreateRowId(TableId::kRawEvents,
836 static_cast<uint32_t>(raw_event_count() - 1));
837 }
838
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000839 void set_arg_set_id(uint32_t row, ArgSetId id) { arg_set_ids_[row] = id; }
840
Lalit Maganti1d915a62019-01-07 12:10:42 +0000841 size_t raw_event_count() const { return timestamps_.size(); }
842
843 const std::deque<int64_t>& timestamps() const { return timestamps_; }
844
845 const std::deque<StringId>& name_ids() const { return name_ids_; }
846
Lalit Magantie87cc812019-01-10 15:20:06 +0000847 const std::deque<uint32_t>& cpus() const { return cpus_; }
848
Lalit Maganti1d915a62019-01-07 12:10:42 +0000849 const std::deque<UniqueTid>& utids() const { return utids_; }
850
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000851 const std::deque<ArgSetId>& arg_set_ids() const { return arg_set_ids_; }
852
Lalit Maganti1d915a62019-01-07 12:10:42 +0000853 private:
854 std::deque<int64_t> timestamps_;
855 std::deque<StringId> name_ids_;
Lalit Magantie87cc812019-01-10 15:20:06 +0000856 std::deque<uint32_t> cpus_;
Lalit Maganti1d915a62019-01-07 12:10:42 +0000857 std::deque<UniqueTid> utids_;
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000858 std::deque<ArgSetId> arg_set_ids_;
Lalit Maganti1d915a62019-01-07 12:10:42 +0000859 };
860
Primiano Tucci2c761ef2019-01-07 20:20:46 +0000861 class AndroidLogs {
862 public:
863 inline size_t AddLogEvent(int64_t timestamp,
864 UniqueTid utid,
865 uint8_t prio,
866 StringId tag_id,
867 StringId msg_id) {
868 timestamps_.emplace_back(timestamp);
869 utids_.emplace_back(utid);
870 prios_.emplace_back(prio);
871 tag_ids_.emplace_back(tag_id);
872 msg_ids_.emplace_back(msg_id);
873 return size() - 1;
874 }
875
876 size_t size() const { return timestamps_.size(); }
877
878 const std::deque<int64_t>& timestamps() const { return timestamps_; }
879 const std::deque<UniqueTid>& utids() const { return utids_; }
880 const std::deque<uint8_t>& prios() const { return prios_; }
881 const std::deque<StringId>& tag_ids() const { return tag_ids_; }
882 const std::deque<StringId>& msg_ids() const { return msg_ids_; }
883
884 private:
885 std::deque<int64_t> timestamps_;
886 std::deque<UniqueTid> utids_;
887 std::deque<uint8_t> prios_;
888 std::deque<StringId> tag_ids_;
889 std::deque<StringId> msg_ids_;
890 };
891
Primiano Tucci0e38a142019-01-07 20:51:09 +0000892 struct Stats {
893 using IndexMap = std::map<int, int64_t>;
894 int64_t value = 0;
895 IndexMap indexed_values;
896 };
897 using StatsMap = std::array<Stats, stats::kNumKeys>;
898
Ryan Savitski51413ad2019-07-09 14:25:21 +0100899 class Metadata {
900 public:
901 const std::deque<metadata::KeyIDs>& keys() const { return keys_; }
902 const std::deque<Variadic>& values() const { return values_; }
903
904 RowId SetScalarMetadata(metadata::KeyIDs key, Variadic value) {
905 PERFETTO_DCHECK(key < metadata::kNumKeys);
906 PERFETTO_DCHECK(metadata::kKeyTypes[key] == metadata::kSingle);
907 PERFETTO_DCHECK(value.type == metadata::kValueTypes[key]);
908
909 // Already set - on release builds, overwrite the previous value.
910 auto it = scalar_indices.find(key);
911 if (it != scalar_indices.end()) {
912 PERFETTO_DFATAL("Setting a scalar metadata entry more than once.");
913 uint32_t index = static_cast<uint32_t>(it->second);
914 values_[index] = value;
915 return TraceStorage::CreateRowId(kMetadataTable, index);
916 }
917 // First time setting this key.
918 keys_.push_back(key);
919 values_.push_back(value);
920 uint32_t index = static_cast<uint32_t>(keys_.size() - 1);
921 scalar_indices[key] = index;
922 return TraceStorage::CreateRowId(kMetadataTable, index);
923 }
924
925 RowId AppendMetadata(metadata::KeyIDs key, Variadic value) {
926 PERFETTO_DCHECK(key < metadata::kNumKeys);
927 PERFETTO_DCHECK(metadata::kKeyTypes[key] == metadata::kMulti);
928 PERFETTO_DCHECK(value.type == metadata::kValueTypes[key]);
929
930 keys_.push_back(key);
931 values_.push_back(value);
932 uint32_t index = static_cast<uint32_t>(keys_.size() - 1);
933 return TraceStorage::CreateRowId(kMetadataTable, index);
934 }
935
Ryan Savitski0476ee92019-07-09 14:29:33 +0100936 void OverwriteMetadata(uint32_t index, Variadic value) {
937 PERFETTO_DCHECK(index < values_.size());
938 values_[index] = value;
939 }
940
Ryan Savitski51413ad2019-07-09 14:25:21 +0100941 private:
942 std::deque<metadata::KeyIDs> keys_;
943 std::deque<Variadic> values_;
944 // Extraneous state to track locations of entries that should have at most
945 // one row. Used only to maintain uniqueness during insertions.
946 std::map<metadata::KeyIDs, uint32_t> scalar_indices;
947 };
Mikhail Khokhlove466c002019-05-23 13:33:33 +0100948
Oystein Eftevaag5419c582019-08-21 13:58:49 -0700949 class StackProfileFrames {
Florian Mayer438b5ab2019-05-02 11:18:06 +0100950 public:
Florian Mayerbee52132019-05-02 13:59:56 +0100951 struct Row {
952 StringId name_id;
953 int64_t mapping_row;
954 int64_t rel_pc;
Florian Mayer438b5ab2019-05-02 11:18:06 +0100955
Florian Mayerbee52132019-05-02 13:59:56 +0100956 bool operator==(const Row& other) const {
957 return std::tie(name_id, mapping_row, rel_pc) ==
958 std::tie(other.name_id, other.mapping_row, other.rel_pc);
959 }
960 };
961
Lalit Maganti9b2d52b2019-05-07 14:32:15 +0100962 uint32_t size() const { return static_cast<uint32_t>(names_.size()); }
963
Florian Mayerbee52132019-05-02 13:59:56 +0100964 int64_t Insert(const Row& row) {
965 names_.emplace_back(row.name_id);
966 mappings_.emplace_back(row.mapping_row);
967 rel_pcs_.emplace_back(row.rel_pc);
Florian Mayer438b5ab2019-05-02 11:18:06 +0100968 return static_cast<int64_t>(names_.size()) - 1;
969 }
970
Ioannis Ilkose6727552019-08-14 15:10:59 +0100971 void SetFrameName(size_t row_idx, StringId name_id) {
972 PERFETTO_CHECK(row_idx < names_.size());
973 names_[row_idx] = name_id;
974 }
975
Florian Mayer438b5ab2019-05-02 11:18:06 +0100976 const std::deque<StringId>& names() const { return names_; }
977 const std::deque<int64_t>& mappings() const { return mappings_; }
978 const std::deque<int64_t>& rel_pcs() const { return rel_pcs_; }
979
980 private:
981 std::deque<StringId> names_;
982 std::deque<int64_t> mappings_;
983 std::deque<int64_t> rel_pcs_;
984 };
985
Oystein Eftevaag5419c582019-08-21 13:58:49 -0700986 class StackProfileCallsites {
Florian Mayer438b5ab2019-05-02 11:18:06 +0100987 public:
Florian Mayerbee52132019-05-02 13:59:56 +0100988 struct Row {
989 int64_t depth;
990 int64_t parent_id;
991 int64_t frame_row;
992
993 bool operator==(const Row& other) const {
994 return std::tie(depth, parent_id, frame_row) ==
995 std::tie(other.depth, other.parent_id, other.frame_row);
Florian Mayer438b5ab2019-05-02 11:18:06 +0100996 }
Florian Mayerbee52132019-05-02 13:59:56 +0100997 };
998
Lalit Maganti9b2d52b2019-05-07 14:32:15 +0100999 uint32_t size() const { return static_cast<uint32_t>(frame_ids_.size()); }
1000
Florian Mayerbee52132019-05-02 13:59:56 +01001001 int64_t Insert(const Row& row) {
1002 frame_depths_.emplace_back(row.depth);
1003 parent_callsite_ids_.emplace_back(row.parent_id);
1004 frame_ids_.emplace_back(row.frame_row);
Florian Mayer438b5ab2019-05-02 11:18:06 +01001005 return static_cast<int64_t>(frame_depths_.size()) - 1;
1006 }
1007
1008 const std::deque<int64_t>& frame_depths() const { return frame_depths_; }
1009 const std::deque<int64_t>& parent_callsite_ids() const {
1010 return parent_callsite_ids_;
1011 }
1012 const std::deque<int64_t>& frame_ids() const { return frame_ids_; }
1013
1014 private:
1015 std::deque<int64_t> frame_depths_;
1016 std::deque<int64_t> parent_callsite_ids_;
1017 std::deque<int64_t> frame_ids_;
1018 };
1019
Oystein Eftevaag5419c582019-08-21 13:58:49 -07001020 class StackProfileMappings {
Florian Mayer438b5ab2019-05-02 11:18:06 +01001021 public:
Florian Mayerbee52132019-05-02 13:59:56 +01001022 struct Row {
1023 StringId build_id;
Florian Mayer12655732019-07-02 15:08:26 +01001024 int64_t exact_offset;
1025 int64_t start_offset;
Florian Mayerbee52132019-05-02 13:59:56 +01001026 int64_t start;
1027 int64_t end;
1028 int64_t load_bias;
1029 StringId name_id;
Florian Mayer438b5ab2019-05-02 11:18:06 +01001030
Florian Mayerbee52132019-05-02 13:59:56 +01001031 bool operator==(const Row& other) const {
Florian Mayer12655732019-07-02 15:08:26 +01001032 return std::tie(build_id, exact_offset, start_offset, start, end,
1033 load_bias, name_id) ==
1034 std::tie(other.build_id, other.exact_offset, other.start_offset,
1035 other.start, other.end, other.load_bias, other.name_id);
Florian Mayerbee52132019-05-02 13:59:56 +01001036 }
1037 };
1038
Lalit Maganti9b2d52b2019-05-07 14:32:15 +01001039 uint32_t size() const { return static_cast<uint32_t>(names_.size()); }
1040
Florian Mayerbee52132019-05-02 13:59:56 +01001041 int64_t Insert(const Row& row) {
1042 build_ids_.emplace_back(row.build_id);
Florian Mayer12655732019-07-02 15:08:26 +01001043 exact_offsets_.emplace_back(row.exact_offset);
1044 start_offsets_.emplace_back(row.start_offset);
Florian Mayerbee52132019-05-02 13:59:56 +01001045 starts_.emplace_back(row.start);
1046 ends_.emplace_back(row.end);
1047 load_biases_.emplace_back(row.load_bias);
1048 names_.emplace_back(row.name_id);
Florian Mayer438b5ab2019-05-02 11:18:06 +01001049 return static_cast<int64_t>(build_ids_.size()) - 1;
1050 }
1051
1052 const std::deque<StringId>& build_ids() const { return build_ids_; }
Florian Mayer12655732019-07-02 15:08:26 +01001053 const std::deque<int64_t>& exact_offsets() const { return exact_offsets_; }
1054 const std::deque<int64_t>& start_offsets() const { return start_offsets_; }
Florian Mayer438b5ab2019-05-02 11:18:06 +01001055 const std::deque<int64_t>& starts() const { return starts_; }
1056 const std::deque<int64_t>& ends() const { return ends_; }
1057 const std::deque<int64_t>& load_biases() const { return load_biases_; }
1058 const std::deque<StringId>& names() const { return names_; }
1059
1060 private:
1061 std::deque<StringId> build_ids_;
Florian Mayer12655732019-07-02 15:08:26 +01001062 std::deque<int64_t> exact_offsets_;
1063 std::deque<int64_t> start_offsets_;
Florian Mayer438b5ab2019-05-02 11:18:06 +01001064 std::deque<int64_t> starts_;
1065 std::deque<int64_t> ends_;
1066 std::deque<int64_t> load_biases_;
1067 std::deque<StringId> names_;
1068 };
1069
1070 class HeapProfileAllocations {
1071 public:
Florian Mayerbee52132019-05-02 13:59:56 +01001072 struct Row {
1073 int64_t timestamp;
Florian Mayerdf1968c2019-05-13 16:39:35 +01001074 UniquePid upid;
Florian Mayerbee52132019-05-02 13:59:56 +01001075 int64_t callsite_id;
1076 int64_t count;
1077 int64_t size;
1078 };
1079
Lalit Maganti9b2d52b2019-05-07 14:32:15 +01001080 uint32_t size() const { return static_cast<uint32_t>(timestamps_.size()); }
1081
Florian Mayerbee52132019-05-02 13:59:56 +01001082 void Insert(const Row& row) {
1083 timestamps_.emplace_back(row.timestamp);
Florian Mayerdf1968c2019-05-13 16:39:35 +01001084 upids_.emplace_back(row.upid);
Florian Mayerbee52132019-05-02 13:59:56 +01001085 callsite_ids_.emplace_back(row.callsite_id);
1086 counts_.emplace_back(row.count);
1087 sizes_.emplace_back(row.size);
Florian Mayer438b5ab2019-05-02 11:18:06 +01001088 }
1089
1090 const std::deque<int64_t>& timestamps() const { return timestamps_; }
Florian Mayerdf1968c2019-05-13 16:39:35 +01001091 const std::deque<UniquePid>& upids() const { return upids_; }
Florian Mayer438b5ab2019-05-02 11:18:06 +01001092 const std::deque<int64_t>& callsite_ids() const { return callsite_ids_; }
1093 const std::deque<int64_t>& counts() const { return counts_; }
1094 const std::deque<int64_t>& sizes() const { return sizes_; }
1095
1096 private:
1097 std::deque<int64_t> timestamps_;
Florian Mayerdf1968c2019-05-13 16:39:35 +01001098 std::deque<UniquePid> upids_;
Florian Mayer438b5ab2019-05-02 11:18:06 +01001099 std::deque<int64_t> callsite_ids_;
1100 std::deque<int64_t> counts_;
1101 std::deque<int64_t> sizes_;
1102 };
1103
Isabelle Taylora0a22972018-08-03 12:06:12 +01001104 void ResetStorage();
Lalit Maganti35622b72018-06-06 12:03:11 +01001105
Primiano Tuccib75dcee2018-08-08 12:21:36 +01001106 UniqueTid AddEmptyThread(uint32_t tid) {
1107 unique_threads_.emplace_back(tid);
Isabelle Taylora0a22972018-08-03 12:06:12 +01001108 return static_cast<UniqueTid>(unique_threads_.size() - 1);
1109 }
Isabelle Taylor47328cf2018-06-12 14:33:59 +01001110
Primiano Tuccib75dcee2018-08-08 12:21:36 +01001111 UniquePid AddEmptyProcess(uint32_t pid) {
1112 unique_processes_.emplace_back(pid);
Isabelle Taylora0a22972018-08-03 12:06:12 +01001113 return static_cast<UniquePid>(unique_processes_.size() - 1);
1114 }
Isabelle Taylor3dd366c2018-06-22 16:21:41 +01001115
Isabelle Taylora0a22972018-08-03 12:06:12 +01001116 // Return an unqiue identifier for the contents of each string.
1117 // The string is copied internally and can be destroyed after this called.
Isabelle Taylor15314ea2018-09-19 11:35:19 +01001118 // Virtual for testing.
Lalit Maganti5c454312019-04-08 12:11:17 +01001119 virtual StringId InternString(base::StringView str) {
1120 return string_pool_.InternString(str);
1121 }
Isabelle Taylor47328cf2018-06-12 14:33:59 +01001122
Isabelle Taylora0a22972018-08-03 12:06:12 +01001123 Process* GetMutableProcess(UniquePid upid) {
Lalit Maganti676658b2018-11-20 18:24:31 +00001124 PERFETTO_DCHECK(upid < unique_processes_.size());
Isabelle Taylora0a22972018-08-03 12:06:12 +01001125 return &unique_processes_[upid];
1126 }
Isabelle Taylor3dd366c2018-06-22 16:21:41 +01001127
Isabelle Taylora0a22972018-08-03 12:06:12 +01001128 Thread* GetMutableThread(UniqueTid utid) {
Florian Mayera1aaec22018-09-19 17:02:26 +01001129 PERFETTO_DCHECK(utid < unique_threads_.size());
Isabelle Taylora0a22972018-08-03 12:06:12 +01001130 return &unique_threads_[utid];
1131 }
Isabelle Taylor3dd366c2018-06-22 16:21:41 +01001132
Primiano Tucci0e38a142019-01-07 20:51:09 +00001133 // Example usage: SetStats(stats::android_log_num_failed, 42);
1134 void SetStats(size_t key, int64_t value) {
1135 PERFETTO_DCHECK(key < stats::kNumKeys);
1136 PERFETTO_DCHECK(stats::kTypes[key] == stats::kSingle);
1137 stats_[key].value = value;
1138 }
1139
1140 // Example usage: IncrementStats(stats::android_log_num_failed, -1);
1141 void IncrementStats(size_t key, int64_t increment = 1) {
1142 PERFETTO_DCHECK(key < stats::kNumKeys);
1143 PERFETTO_DCHECK(stats::kTypes[key] == stats::kSingle);
1144 stats_[key].value += increment;
1145 }
1146
Florian Mayer438b5ab2019-05-02 11:18:06 +01001147 // Example usage: IncrementIndexedStats(stats::cpu_failure, 1);
1148 void IncrementIndexedStats(size_t key, int index, int64_t increment = 1) {
1149 PERFETTO_DCHECK(key < stats::kNumKeys);
1150 PERFETTO_DCHECK(stats::kTypes[key] == stats::kIndexed);
1151 stats_[key].indexed_values[index] += increment;
1152 }
1153
Primiano Tucci0e38a142019-01-07 20:51:09 +00001154 // Example usage: SetIndexedStats(stats::cpu_failure, 1, 42);
1155 void SetIndexedStats(size_t key, int index, int64_t value) {
1156 PERFETTO_DCHECK(key < stats::kNumKeys);
1157 PERFETTO_DCHECK(stats::kTypes[key] == stats::kIndexed);
1158 stats_[key].indexed_values[index] = value;
1159 }
1160
Mikhail Khokhlove466c002019-05-23 13:33:33 +01001161 // Example usage:
1162 // SetMetadata(metadata::benchmark_name,
1163 // Variadic::String(storage->InternString("foo"));
Ryan Savitski51413ad2019-07-09 14:25:21 +01001164 // Returns the RowId of the new entry.
Mikhail Khokhlovb1fe42a2019-05-23 13:58:05 +01001165 // Virtual for testing.
Ryan Savitski51413ad2019-07-09 14:25:21 +01001166 virtual RowId SetMetadata(metadata::KeyIDs key, Variadic value) {
1167 return metadata_.SetScalarMetadata(key, value);
Mikhail Khokhlove466c002019-05-23 13:33:33 +01001168 }
1169
1170 // Example usage:
1171 // AppendMetadata(metadata::benchmark_story_tags,
1172 // Variadic::String(storage->InternString("bar"));
Ryan Savitski51413ad2019-07-09 14:25:21 +01001173 // Returns the RowId of the new entry.
Mikhail Khokhlovb1fe42a2019-05-23 13:58:05 +01001174 // Virtual for testing.
Ryan Savitski51413ad2019-07-09 14:25:21 +01001175 virtual RowId AppendMetadata(metadata::KeyIDs key, Variadic value) {
1176 return metadata_.AppendMetadata(key, value);
Mikhail Khokhlove466c002019-05-23 13:33:33 +01001177 }
1178
Eric Seckler77b52782019-05-02 15:18:57 +01001179 class ScopedStatsTracer {
1180 public:
1181 ScopedStatsTracer(TraceStorage* storage, size_t key)
1182 : storage_(storage), key_(key), start_ns_(base::GetWallTimeNs()) {}
1183
1184 ~ScopedStatsTracer() {
1185 if (!storage_)
1186 return;
1187 auto delta_ns = base::GetWallTimeNs() - start_ns_;
1188 storage_->IncrementStats(key_, delta_ns.count());
1189 }
1190
1191 ScopedStatsTracer(ScopedStatsTracer&& other) noexcept { MoveImpl(&other); }
1192
1193 ScopedStatsTracer& operator=(ScopedStatsTracer&& other) {
1194 MoveImpl(&other);
1195 return *this;
1196 }
1197
1198 private:
1199 ScopedStatsTracer(const ScopedStatsTracer&) = delete;
1200 ScopedStatsTracer& operator=(const ScopedStatsTracer&) = delete;
1201
1202 void MoveImpl(ScopedStatsTracer* other) {
1203 storage_ = other->storage_;
1204 key_ = other->key_;
1205 start_ns_ = other->start_ns_;
1206 other->storage_ = nullptr;
1207 }
1208
1209 TraceStorage* storage_;
1210 size_t key_;
1211 base::TimeNanos start_ns_;
1212 };
1213
1214 ScopedStatsTracer TraceExecutionTimeIntoStats(size_t key) {
1215 return ScopedStatsTracer(this, key);
1216 }
1217
Lalit Maganticaed37e2018-06-01 03:03:08 +01001218 // Reading methods.
Eric Secklerc93823e2019-06-03 16:49:19 +01001219 // Virtual for testing.
1220 virtual NullTermStringView GetString(StringId id) const {
Lalit Maganti5c454312019-04-08 12:11:17 +01001221 return string_pool_.Get(id);
Isabelle Taylora0a22972018-08-03 12:06:12 +01001222 }
1223
Lalit Magantie9d40532018-06-29 13:15:06 +01001224 const Process& GetProcess(UniquePid upid) const {
Lalit Maganti676658b2018-11-20 18:24:31 +00001225 PERFETTO_DCHECK(upid < unique_processes_.size());
Isabelle Taylor47328cf2018-06-12 14:33:59 +01001226 return unique_processes_[upid];
1227 }
1228
Lalit Magantie9d40532018-06-29 13:15:06 +01001229 const Thread& GetThread(UniqueTid utid) const {
Lalit Maganti1f64cfa2018-09-18 13:20:02 +01001230 // Allow utid == 0 for idle thread retrieval.
Florian Mayera1aaec22018-09-19 17:02:26 +01001231 PERFETTO_DCHECK(utid < unique_threads_.size());
Isabelle Taylor68e42192018-06-19 16:19:31 +01001232 return unique_threads_[utid];
1233 }
1234
Lalit Maganti5ea9e932018-11-30 14:19:39 +00001235 static RowId CreateRowId(TableId table, uint32_t row) {
Lalit Maganti85ca4a82018-12-07 17:28:02 +00001236 return (static_cast<RowId>(table) << kRowIdTableShift) | row;
Lalit Maganti5ea9e932018-11-30 14:19:39 +00001237 }
1238
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +00001239 static std::pair<int8_t /*table*/, uint32_t /*row*/> ParseRowId(RowId rowid) {
1240 auto id = static_cast<uint64_t>(rowid);
1241 auto table_id = static_cast<uint8_t>(id >> kRowIdTableShift);
1242 auto row = static_cast<uint32_t>(id & ((1ull << kRowIdTableShift) - 1));
1243 return std::make_pair(table_id, row);
1244 }
1245
Lalit Magantid11d3e02019-07-26 12:32:09 +05301246 const Tracks& tracks() const { return tracks_; }
1247 Tracks* mutable_tracks() { return &tracks_; }
1248
Eric Seckler5703ede2019-07-10 10:13:02 +01001249 const VirtualTracks& virtual_tracks() const { return virtual_tracks_; }
1250 VirtualTracks* mutable_virtual_tracks() { return &virtual_tracks_; }
1251
Lalit Magantiff69c112018-09-24 12:07:47 +01001252 const Slices& slices() const { return slices_; }
Lalit Magantifde29042018-10-04 13:28:52 +01001253 Slices* mutable_slices() { return &slices_; }
1254
Primiano Tucci0d72a312018-08-07 14:42:45 +01001255 const NestableSlices& nestable_slices() const { return nestable_slices_; }
1256 NestableSlices* mutable_nestable_slices() { return &nestable_slices_; }
1257
Eric Secklerd3b89d52019-07-10 15:36:29 +01001258 const ThreadSlices& thread_slices() const { return thread_slices_; }
1259 ThreadSlices* mutable_thread_slices() { return &thread_slices_; }
1260
Eric Secklerc3430c62019-07-22 10:49:58 +01001261 const VirtualTrackSlices& virtual_track_slices() const {
1262 return virtual_track_slices_;
1263 }
1264 VirtualTrackSlices* mutable_virtual_track_slices() {
1265 return &virtual_track_slices_;
1266 }
1267
Mikael Pessa7160ccc2019-07-25 11:19:26 -07001268 const GpuSlices& gpu_track_slices() const { return gpu_track_slices_; }
1269 GpuSlices* mutable_gpu_track_slices() { return &gpu_track_slices_; }
1270
Lalit Maganti8320e6d2019-03-14 18:49:33 +00001271 const CounterDefinitions& counter_definitions() const {
1272 return counter_definitions_;
1273 }
1274 CounterDefinitions* mutable_counter_definitions() {
1275 return &counter_definitions_;
1276 }
1277
1278 const CounterValues& counter_values() const { return counter_values_; }
1279 CounterValues* mutable_counter_values() { return &counter_values_; }
Isabelle Taylor14674d42018-09-07 11:33:11 +01001280
Primiano Tucci5cb84f82018-10-31 21:46:36 -07001281 const SqlStats& sql_stats() const { return sql_stats_; }
1282 SqlStats* mutable_sql_stats() { return &sql_stats_; }
1283
Isabelle Taylorc8c11202018-11-05 11:36:22 +00001284 const Instants& instants() const { return instants_; }
1285 Instants* mutable_instants() { return &instants_; }
1286
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001287 const AndroidLogs& android_logs() const { return android_log_; }
1288 AndroidLogs* mutable_android_log() { return &android_log_; }
1289
Primiano Tucci0e38a142019-01-07 20:51:09 +00001290 const StatsMap& stats() const { return stats_; }
Lalit Maganti05e8c132018-11-09 18:16:12 +00001291
Ryan Savitski51413ad2019-07-09 14:25:21 +01001292 const Metadata& metadata() const { return metadata_; }
Ryan Savitski0476ee92019-07-09 14:29:33 +01001293 Metadata* mutable_metadata() { return &metadata_; }
Mikhail Khokhlove466c002019-05-23 13:33:33 +01001294
Lalit Maganti6e9c55e2018-11-29 12:00:39 +00001295 const Args& args() const { return args_; }
1296 Args* mutable_args() { return &args_; }
1297
Lalit Maganti1d915a62019-01-07 12:10:42 +00001298 const RawEvents& raw_events() const { return raw_events_; }
1299 RawEvents* mutable_raw_events() { return &raw_events_; }
1300
Oystein Eftevaag5419c582019-08-21 13:58:49 -07001301 const StackProfileMappings& stack_profile_mappings() const {
1302 return stack_profile_mappings_;
Florian Mayer438b5ab2019-05-02 11:18:06 +01001303 }
Oystein Eftevaag5419c582019-08-21 13:58:49 -07001304 StackProfileMappings* mutable_stack_profile_mappings() {
1305 return &stack_profile_mappings_;
Florian Mayer438b5ab2019-05-02 11:18:06 +01001306 }
1307
Oystein Eftevaag5419c582019-08-21 13:58:49 -07001308 const StackProfileFrames& stack_profile_frames() const {
1309 return stack_profile_frames_;
Florian Mayer438b5ab2019-05-02 11:18:06 +01001310 }
Oystein Eftevaag5419c582019-08-21 13:58:49 -07001311 StackProfileFrames* mutable_stack_profile_frames() {
1312 return &stack_profile_frames_;
Florian Mayer438b5ab2019-05-02 11:18:06 +01001313 }
1314
Oystein Eftevaag5419c582019-08-21 13:58:49 -07001315 const StackProfileCallsites& stack_profile_callsites() const {
1316 return stack_profile_callsites_;
Florian Mayer438b5ab2019-05-02 11:18:06 +01001317 }
Oystein Eftevaag5419c582019-08-21 13:58:49 -07001318 StackProfileCallsites* mutable_stack_profile_callsites() {
1319 return &stack_profile_callsites_;
Florian Mayer438b5ab2019-05-02 11:18:06 +01001320 }
1321
1322 const HeapProfileAllocations& heap_profile_allocations() const {
1323 return heap_profile_allocations_;
1324 }
1325 HeapProfileAllocations* mutable_heap_profile_allocations() {
1326 return &heap_profile_allocations_;
1327 }
1328
Mikael Pessa7160ccc2019-07-25 11:19:26 -07001329 const GpuTracks& gpu_tracks() const { return gpu_tracks_; }
1330 GpuTracks* mutable_gpu_tracks() { return &gpu_tracks_; }
1331
Lalit Maganti5c454312019-04-08 12:11:17 +01001332 const StringPool& string_pool() const { return string_pool_; }
Lalit Magantiacda68b2018-10-29 15:23:25 +00001333
Isabelle Taylore7003fb2018-07-17 11:39:01 +01001334 // |unique_processes_| always contains at least 1 element becuase the 0th ID
1335 // is reserved to indicate an invalid process.
Lalit Maganti9c6395b2019-01-17 00:25:09 +00001336 size_t process_count() const { return unique_processes_.size(); }
Primiano Tucci0d72a312018-08-07 14:42:45 +01001337
Isabelle Taylore7003fb2018-07-17 11:39:01 +01001338 // |unique_threads_| always contains at least 1 element becuase the 0th ID
1339 // is reserved to indicate an invalid thread.
Lalit Maganti9c6395b2019-01-17 00:25:09 +00001340 size_t thread_count() const { return unique_threads_.size(); }
Isabelle Taylore7003fb2018-07-17 11:39:01 +01001341
Hector Dearman12323362018-08-09 16:09:28 +01001342 // Number of interned strings in the pool. Includes the empty string w/ ID=0.
1343 size_t string_count() const { return string_pool_.size(); }
1344
Ioannis Ilkosb8b11102019-01-29 17:56:55 +00001345 // Start / end ts (in nanoseconds) across the parsed trace events.
1346 // Returns (0, 0) if the trace is empty.
1347 std::pair<int64_t, int64_t> GetTraceTimestampBoundsNs() const;
1348
Lalit Maganticaed37e2018-06-01 03:03:08 +01001349 private:
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +00001350 static constexpr uint8_t kRowIdTableShift = 32;
Isabelle Taylora0a22972018-08-03 12:06:12 +01001351
Primiano Tucci2da5d2e2018-08-10 14:23:31 +01001352 using StringHash = uint64_t;
Lalit Maganticaed37e2018-06-01 03:03:08 +01001353
Lalit Maganti5c454312019-04-08 12:11:17 +01001354 TraceStorage(const TraceStorage&) = delete;
1355 TraceStorage& operator=(const TraceStorage&) = delete;
1356
1357 TraceStorage(TraceStorage&&) = default;
1358 TraceStorage& operator=(TraceStorage&&) = default;
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +00001359
Lalit Maganti05e8c132018-11-09 18:16:12 +00001360 // Stats about parsing the trace.
Primiano Tucci0e38a142019-01-07 20:51:09 +00001361 StatsMap stats_{};
Lalit Maganti35622b72018-06-06 12:03:11 +01001362
Ryan Savitski51413ad2019-07-09 14:25:21 +01001363 // Extra data extracted from the trace. Includes:
1364 // * metadata from chrome and benchmarking infrastructure
1365 // * descriptions of android packages
1366 Metadata metadata_{};
Mikhail Khokhlove466c002019-05-23 13:33:33 +01001367
Lalit Magantid11d3e02019-07-26 12:32:09 +05301368 // Metadata for tracks.
1369 Tracks tracks_;
1370
Eric Seckler5703ede2019-07-10 10:13:02 +01001371 // Metadata for virtual slice tracks.
1372 VirtualTracks virtual_tracks_;
1373
Mikael Pessa803090c2019-08-23 16:03:34 -07001374 // Metadata for gpu tracks.
1375 GpuTracks gpu_tracks_;
1376 GpuContexts gpu_contexts_;
1377
Lalit Maganticaed37e2018-06-01 03:03:08 +01001378 // One entry for each CPU in the trace.
Lalit Magantiff69c112018-09-24 12:07:47 +01001379 Slices slices_;
Lalit Maganticaed37e2018-06-01 03:03:08 +01001380
Lalit Maganti6e9c55e2018-11-29 12:00:39 +00001381 // Args for all other tables.
1382 Args args_;
1383
Lalit Maganticaed37e2018-06-01 03:03:08 +01001384 // One entry for each unique string in the trace.
Lalit Maganti5c454312019-04-08 12:11:17 +01001385 StringPool string_pool_;
Isabelle Taylor47328cf2018-06-12 14:33:59 +01001386
Isabelle Taylor47328cf2018-06-12 14:33:59 +01001387 // One entry for each UniquePid, with UniquePid as the index.
Ioannis Ilkos9c03cbd2019-03-12 18:30:43 +00001388 // Never hold on to pointers to Process, as vector resize will
1389 // invalidate them.
1390 std::vector<Process> unique_processes_;
Isabelle Taylor68e42192018-06-19 16:19:31 +01001391
Isabelle Taylor68e42192018-06-19 16:19:31 +01001392 // One entry for each UniqueTid, with UniqueTid as the index.
Isabelle Taylor3dd366c2018-06-22 16:21:41 +01001393 std::deque<Thread> unique_threads_;
Primiano Tucci0d72a312018-08-07 14:42:45 +01001394
1395 // Slices coming from userspace events (e.g. Chromium TRACE_EVENT macros).
1396 NestableSlices nestable_slices_;
Isabelle Taylor15314ea2018-09-19 11:35:19 +01001397
Eric Secklerd3b89d52019-07-10 15:36:29 +01001398 // Additional attributes for threads slices (sub-type of NestableSlices).
1399 ThreadSlices thread_slices_;
1400
Eric Secklerc3430c62019-07-22 10:49:58 +01001401 // Additional attributes for virtual track slices (sub-type of
1402 // NestableSlices).
1403 VirtualTrackSlices virtual_track_slices_;
1404
Mikael Pessa803090c2019-08-23 16:03:34 -07001405 // Additional attributes for gpu track slices (sub-type of
1406 // NestableSlices).
1407 GpuSlices gpu_track_slices_;
1408
Hector Dearman2442d612019-06-04 18:05:23 +01001409 // The type of counters in the trace. Can be thought of as the "metadata".
Lalit Maganti8320e6d2019-03-14 18:49:33 +00001410 CounterDefinitions counter_definitions_;
1411
1412 // The values from the Counter events from the trace. This includes CPU
1413 // frequency events as well systrace trace_marker counter events.
1414 CounterValues counter_values_;
Primiano Tucci5cb84f82018-10-31 21:46:36 -07001415
1416 SqlStats sql_stats_;
Lalit Maganti6e9c55e2018-11-29 12:00:39 +00001417
Isabelle Taylorc8c11202018-11-05 11:36:22 +00001418 // These are instantaneous events in the trace. They have no duration
1419 // and do not have a value that make sense to track over time.
1420 // e.g. signal events
1421 Instants instants_;
Lalit Maganti1d915a62019-01-07 12:10:42 +00001422
1423 // Raw events are every ftrace event in the trace. The raw event includes
1424 // the timestamp and the pid. The args for the raw event will be in the
1425 // args table. This table can be used to generate a text version of the
1426 // trace.
1427 RawEvents raw_events_;
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001428 AndroidLogs android_log_;
Florian Mayer438b5ab2019-05-02 11:18:06 +01001429
Oystein Eftevaag5419c582019-08-21 13:58:49 -07001430 StackProfileMappings stack_profile_mappings_;
1431 StackProfileFrames stack_profile_frames_;
1432 StackProfileCallsites stack_profile_callsites_;
Florian Mayer438b5ab2019-05-02 11:18:06 +01001433 HeapProfileAllocations heap_profile_allocations_;
Lalit Maganticaed37e2018-06-01 03:03:08 +01001434};
1435
1436} // namespace trace_processor
1437} // namespace perfetto
1438
Florian Mayerbee52132019-05-02 13:59:56 +01001439namespace std {
1440
1441template <>
Oystein Eftevaag5419c582019-08-21 13:58:49 -07001442struct hash<
1443 ::perfetto::trace_processor::TraceStorage::StackProfileFrames::Row> {
Florian Mayerbee52132019-05-02 13:59:56 +01001444 using argument_type =
Oystein Eftevaag5419c582019-08-21 13:58:49 -07001445 ::perfetto::trace_processor::TraceStorage::StackProfileFrames::Row;
Florian Mayerbee52132019-05-02 13:59:56 +01001446 using result_type = size_t;
1447
1448 result_type operator()(const argument_type& r) const {
1449 return std::hash<::perfetto::trace_processor::StringId>{}(r.name_id) ^
1450 std::hash<int64_t>{}(r.mapping_row) ^ std::hash<int64_t>{}(r.rel_pc);
1451 }
1452};
1453
1454template <>
1455struct hash<
Oystein Eftevaag5419c582019-08-21 13:58:49 -07001456 ::perfetto::trace_processor::TraceStorage::StackProfileCallsites::Row> {
Florian Mayerbee52132019-05-02 13:59:56 +01001457 using argument_type =
Oystein Eftevaag5419c582019-08-21 13:58:49 -07001458 ::perfetto::trace_processor::TraceStorage::StackProfileCallsites::Row;
Florian Mayerbee52132019-05-02 13:59:56 +01001459 using result_type = size_t;
1460
1461 result_type operator()(const argument_type& r) const {
1462 return std::hash<int64_t>{}(r.depth) ^ std::hash<int64_t>{}(r.parent_id) ^
1463 std::hash<int64_t>{}(r.frame_row);
1464 }
1465};
1466
1467template <>
1468struct hash<
Oystein Eftevaag5419c582019-08-21 13:58:49 -07001469 ::perfetto::trace_processor::TraceStorage::StackProfileMappings::Row> {
Florian Mayerbee52132019-05-02 13:59:56 +01001470 using argument_type =
Oystein Eftevaag5419c582019-08-21 13:58:49 -07001471 ::perfetto::trace_processor::TraceStorage::StackProfileMappings::Row;
Florian Mayerbee52132019-05-02 13:59:56 +01001472 using result_type = size_t;
1473
1474 result_type operator()(const argument_type& r) const {
1475 return std::hash<::perfetto::trace_processor::StringId>{}(r.build_id) ^
Florian Mayer12655732019-07-02 15:08:26 +01001476 std::hash<int64_t>{}(r.exact_offset) ^
1477 std::hash<int64_t>{}(r.start_offset) ^
1478 std::hash<int64_t>{}(r.start) ^ std::hash<int64_t>{}(r.end) ^
1479 std::hash<int64_t>{}(r.load_bias) ^
Florian Mayerbee52132019-05-02 13:59:56 +01001480 std::hash<::perfetto::trace_processor::StringId>{}(r.name_id);
1481 }
1482};
1483
1484} // namespace std
1485
Lalit Maganticaed37e2018-06-01 03:03:08 +01001486#endif // SRC_TRACE_PROCESSOR_TRACE_STORAGE_H_