• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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_IMPORTERS_COMMON_ARGS_TRACKER_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_ARGS_TRACKER_H_
19 
20 #include <cstdint>
21 #include "perfetto/ext/base/small_vector.h"
22 #include "src/trace_processor/importers/common/global_args_tracker.h"
23 #include "src/trace_processor/storage/trace_storage.h"
24 #include "src/trace_processor/tables/metadata_tables_py.h"
25 #include "src/trace_processor/types/trace_processor_context.h"
26 #include "src/trace_processor/types/variadic.h"
27 
28 namespace perfetto {
29 namespace trace_processor {
30 
31 // Tracks and stores args for rows until the end of the packet. This allows
32 // allows args to pushed as a group into storage.
33 class ArgsTracker {
34  public:
35   using UpdatePolicy = GlobalArgsTracker::UpdatePolicy;
36   using CompactArg = GlobalArgsTracker::CompactArg;
37   using CompactArgSet = base::SmallVector<CompactArg, 16>;
38 
39   // Stores the table and row at creation time which args are associated with.
40   // This allows callers to directly add args without repeating the row the
41   // args should be associated with.
42   class BoundInserter {
43    public:
44     virtual ~BoundInserter();
45 
46     BoundInserter(BoundInserter&&) noexcept = default;
47     BoundInserter& operator=(BoundInserter&&) noexcept = default;
48 
49     BoundInserter(const BoundInserter&) = delete;
50     BoundInserter& operator=(const BoundInserter&) = delete;
51 
52     // Adds an arg with the same key and flat_key.
53     BoundInserter& AddArg(
54         StringId key,
55         Variadic v,
56         UpdatePolicy update_policy = UpdatePolicy::kAddOrUpdate) {
57       return AddArg(key, key, v, update_policy);
58     }
59 
60     virtual BoundInserter& AddArg(
61         StringId flat_key,
62         StringId key,
63         Variadic v,
64         UpdatePolicy update_policy = UpdatePolicy::kAddOrUpdate) {
65       args_tracker_->AddArg(arg_set_id_column_, row_, flat_key, key, v,
66                             update_policy);
67       return *this;
68     }
69 
70     // IncrementArrayEntryIndex() and GetNextArrayEntryIndex() provide a way to
71     // track the next array index for an array under a specific key.
GetNextArrayEntryIndex(StringId key)72     size_t GetNextArrayEntryIndex(StringId key) {
73       // Zero-initializes |key| in the map if it doesn't exist yet.
74       return args_tracker_
75           ->array_indexes_[std::make_tuple(arg_set_id_column_, row_, key)];
76     }
77 
78     // Returns the next available array index after increment.
IncrementArrayEntryIndex(StringId key)79     size_t IncrementArrayEntryIndex(StringId key) {
80       // Zero-initializes |key| in the map if it doesn't exist yet.
81       return ++args_tracker_->array_indexes_[std::make_tuple(arg_set_id_column_,
82                                                              row_, key)];
83     }
84 
85    protected:
86     BoundInserter(ArgsTracker* args_tracker,
87                   ColumnLegacy* arg_set_id_column,
88                   uint32_t row);
89 
90    private:
91     friend class ArgsTracker;
92 
93     ArgsTracker* args_tracker_ = nullptr;
94     ColumnLegacy* arg_set_id_column_ = nullptr;
95     uint32_t row_ = 0;
96   };
97 
98   explicit ArgsTracker(TraceProcessorContext*);
99 
100   ArgsTracker(const ArgsTracker&) = delete;
101   ArgsTracker& operator=(const ArgsTracker&) = delete;
102 
103   ArgsTracker(ArgsTracker&&) = default;
104   ArgsTracker& operator=(ArgsTracker&&) = default;
105 
106   virtual ~ArgsTracker();
107 
AddArgsTo(tables::ChromeRawTable::Id id)108   BoundInserter AddArgsTo(tables::ChromeRawTable::Id id) {
109     return AddArgsTo(context_->storage->mutable_chrome_raw_table(), id);
110   }
111 
AddArgsTo(tables::FtraceEventTable::Id id)112   BoundInserter AddArgsTo(tables::FtraceEventTable::Id id) {
113     return AddArgsTo(context_->storage->mutable_ftrace_event_table(), id);
114   }
115 
AddArgsTo(CounterId id)116   BoundInserter AddArgsTo(CounterId id) {
117     return AddArgsTo(context_->storage->mutable_counter_table(), id);
118   }
119 
AddArgsTo(SliceId id)120   BoundInserter AddArgsTo(SliceId id) {
121     return AddArgsTo(context_->storage->mutable_slice_table(), id);
122   }
123 
AddArgsTo(tables::FlowTable::Id id)124   BoundInserter AddArgsTo(tables::FlowTable::Id id) {
125     return AddArgsTo(context_->storage->mutable_flow_table(), id);
126   }
127 
AddArgsTo(tables::InputMethodClientsTable::Id id)128   BoundInserter AddArgsTo(tables::InputMethodClientsTable::Id id) {
129     return AddArgsTo(context_->storage->mutable_inputmethod_clients_table(),
130                      id);
131   }
132 
AddArgsTo(tables::InputMethodServiceTable::Id id)133   BoundInserter AddArgsTo(tables::InputMethodServiceTable::Id id) {
134     return AddArgsTo(context_->storage->mutable_inputmethod_service_table(),
135                      id);
136   }
137 
AddArgsTo(tables::InputMethodManagerServiceTable::Id id)138   BoundInserter AddArgsTo(tables::InputMethodManagerServiceTable::Id id) {
139     return AddArgsTo(
140         context_->storage->mutable_inputmethod_manager_service_table(), id);
141   }
142 
AddArgsTo(tables::MemorySnapshotNodeTable::Id id)143   BoundInserter AddArgsTo(tables::MemorySnapshotNodeTable::Id id) {
144     return AddArgsTo(context_->storage->mutable_memory_snapshot_node_table(),
145                      id);
146   }
147 
AddArgsTo(tables::SurfaceFlingerLayersSnapshotTable::Id id)148   BoundInserter AddArgsTo(tables::SurfaceFlingerLayersSnapshotTable::Id id) {
149     return AddArgsTo(
150         context_->storage->mutable_surfaceflinger_layers_snapshot_table(), id);
151   }
152 
AddArgsTo(tables::SurfaceFlingerLayerTable::Id id)153   BoundInserter AddArgsTo(tables::SurfaceFlingerLayerTable::Id id) {
154     return AddArgsTo(context_->storage->mutable_surfaceflinger_layer_table(),
155                      id);
156   }
157 
AddArgsTo(tables::SurfaceFlingerTransactionsTable::Id id)158   BoundInserter AddArgsTo(tables::SurfaceFlingerTransactionsTable::Id id) {
159     return AddArgsTo(
160         context_->storage->mutable_surfaceflinger_transactions_table(), id);
161   }
162 
AddArgsTo(tables::ViewCaptureTable::Id id)163   BoundInserter AddArgsTo(tables::ViewCaptureTable::Id id) {
164     return AddArgsTo(context_->storage->mutable_viewcapture_table(), id);
165   }
166 
AddArgsTo(tables::ViewCaptureViewTable::Id id)167   BoundInserter AddArgsTo(tables::ViewCaptureViewTable::Id id) {
168     return AddArgsTo(context_->storage->mutable_viewcapture_view_table(), id);
169   }
170 
AddArgsTo(tables::WindowManagerTable::Id id)171   BoundInserter AddArgsTo(tables::WindowManagerTable::Id id) {
172     return AddArgsTo(context_->storage->mutable_windowmanager_table(), id);
173   }
174 
AddArgsTo(tables::WindowManagerShellTransitionsTable::Id id)175   BoundInserter AddArgsTo(tables::WindowManagerShellTransitionsTable::Id id) {
176     return AddArgsTo(
177         context_->storage->mutable_window_manager_shell_transitions_table(),
178         id);
179   }
180 
AddArgsTo(tables::AndroidKeyEventsTable::Id id)181   BoundInserter AddArgsTo(tables::AndroidKeyEventsTable::Id id) {
182     return AddArgsTo(context_->storage->mutable_android_key_events_table(), id);
183   }
184 
AddArgsTo(tables::AndroidMotionEventsTable::Id id)185   BoundInserter AddArgsTo(tables::AndroidMotionEventsTable::Id id) {
186     return AddArgsTo(context_->storage->mutable_android_motion_events_table(),
187                      id);
188   }
189 
AddArgsTo(tables::AndroidInputEventDispatchTable::Id id)190   BoundInserter AddArgsTo(tables::AndroidInputEventDispatchTable::Id id) {
191     return AddArgsTo(
192         context_->storage->mutable_android_input_event_dispatch_table(), id);
193   }
194 
AddArgsTo(MetadataId id)195   BoundInserter AddArgsTo(MetadataId id) {
196     auto* table = context_->storage->mutable_metadata_table();
197     uint32_t row = table->FindById(id)->ToRowNumber().row_number();
198     return BoundInserter(this, table->mutable_int_value(), row);
199   }
200 
AddArgsTo(TrackId id)201   BoundInserter AddArgsTo(TrackId id) {
202     auto* table = context_->storage->mutable_track_table();
203     uint32_t row = table->FindById(id)->ToRowNumber().row_number();
204     return BoundInserter(this, table->mutable_source_arg_set_id(), row);
205   }
206 
AddArgsTo(VulkanAllocId id)207   BoundInserter AddArgsTo(VulkanAllocId id) {
208     return AddArgsTo(
209         context_->storage->mutable_vulkan_memory_allocations_table(), id);
210   }
211 
AddArgsTo(UniquePid id)212   BoundInserter AddArgsTo(UniquePid id) {
213     return BoundInserter(
214         this, context_->storage->mutable_process_table()->mutable_arg_set_id(),
215         id);
216   }
217 
AddArgsTo(tables::ExperimentalProtoPathTable::Id id)218   BoundInserter AddArgsTo(tables::ExperimentalProtoPathTable::Id id) {
219     return AddArgsTo(context_->storage->mutable_experimental_proto_path_table(),
220                      id);
221   }
222 
AddArgsTo(tables::CpuTable::Id id)223   BoundInserter AddArgsTo(tables::CpuTable::Id id) {
224     return AddArgsTo(context_->storage->mutable_cpu_table(), id);
225   }
226 
227   // Returns a CompactArgSet which contains the args inserted into this
228   // ArgsTracker. Requires that every arg in this tracker was inserted for the
229   // "arg_set_id" column given by |column| at the given |row_number|.
230   //
231   // Note that this means the args stored in this tracker will *not* be flushed
232   // into the tables: it is the callers responsibility to ensure this happens if
233   // necessary.
234   CompactArgSet ToCompactArgSet(const ColumnLegacy& column,
235                                 uint32_t row_number) &&;
236 
237   // Returns whether this ArgsTracker contains any arg which require translation
238   // according to the provided |table|.
239   bool NeedsTranslation(const ArgsTranslationTable& table) const;
240 
241   // Commits the added args to storage.
242   // Virtual for testing.
243   virtual void Flush();
244 
245  private:
246   template <typename Table>
AddArgsTo(Table * table,typename Table::Id id)247   BoundInserter AddArgsTo(Table* table, typename Table::Id id) {
248     uint32_t row = table->FindById(id)->ToRowNumber().row_number();
249     return BoundInserter(this, table->mutable_arg_set_id(), row);
250   }
251 
252   void AddArg(ColumnLegacy* arg_set_id,
253               uint32_t row,
254               StringId flat_key,
255               StringId key,
256               Variadic,
257               UpdatePolicy);
258 
259   base::SmallVector<GlobalArgsTracker::Arg, 16> args_;
260   TraceProcessorContext* context_ = nullptr;
261 
262   using ArrayKeyTuple = std::
263       tuple<ColumnLegacy* /*arg_set_id*/, uint32_t /*row*/, StringId /*key*/>;
264   std::map<ArrayKeyTuple, size_t /*next_index*/> array_indexes_;
265 };
266 
267 }  // namespace trace_processor
268 }  // namespace perfetto
269 
270 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_ARGS_TRACKER_H_
271