xref: /aosp_15_r20/external/perfetto/src/trace_processor/tables/macros_internal.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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_TABLES_MACROS_INTERNAL_H_
18 #define SRC_TRACE_PROCESSOR_TABLES_MACROS_INTERNAL_H_
19 
20 #include <cstddef>
21 #include <cstdint>
22 #include <initializer_list>
23 #include <type_traits>
24 #include <utility>
25 #include <vector>
26 
27 #include "perfetto/base/logging.h"
28 #include "perfetto/public/compiler.h"
29 #include "perfetto/trace_processor/ref_counted.h"
30 #include "src/trace_processor/containers/row_map.h"
31 #include "src/trace_processor/containers/string_pool.h"
32 #include "src/trace_processor/db/column.h"
33 #include "src/trace_processor/db/column/overlay_layer.h"
34 #include "src/trace_processor/db/column/storage_layer.h"
35 #include "src/trace_processor/db/column_storage.h"
36 #include "src/trace_processor/db/column_storage_overlay.h"
37 #include "src/trace_processor/db/table.h"
38 
39 namespace perfetto::trace_processor::macros_internal {
40 
41 // We define this class to allow the table macro below to compile without
42 // needing templates; in reality none of the methods will be called because the
43 // pointer to this class will always be null.
44 class RootParentTable : public Table {
45  public:
46   struct Row {
47    public:
48     explicit Row(std::nullptr_t = nullptr) {}
49 
typeRow50     const char* type() const { return type_; }
51 
52    protected:
53     const char* type_ = nullptr;
54   };
55   // This class only exists to allow typechecking to work correctly in Insert
56   // below. If we had C++17 and if constexpr, we could statically verify that
57   // this was never created but for now, we still need to define it to satisfy
58   // the typechecker.
59   struct IdAndRow {
60     uint32_t id;
61   };
62   struct RowNumber {
row_numberRowNumber63     static uint32_t row_number() { PERFETTO_FATAL("Should not be called"); }
64   };
Insert(const Row &)65   static IdAndRow Insert(const Row&) { PERFETTO_FATAL("Should not be called"); }
66 
67  private:
68   explicit RootParentTable(std::nullptr_t);
69 };
70 
71 // The parent class for all macro generated tables.
72 // This class is used to extract common code from the macro tables to reduce
73 // code size.
74 class MacroTable : public Table {
75  public:
76   // We don't want a move or copy constructor because we store pointers to
77   // fields of macro tables which will be invalidated if we move/copy them.
78   MacroTable(const MacroTable&) = delete;
79   MacroTable& operator=(const MacroTable&) = delete;
80 
81   MacroTable(MacroTable&&) = delete;
82   MacroTable& operator=(MacroTable&&) noexcept = delete;
83 
84  protected:
85   // Constructors for tables created by the regular constructor.
86   PERFETTO_NO_INLINE explicit MacroTable(StringPool* pool,
87                                          std::vector<ColumnLegacy> columns,
88                                          const MacroTable* parent);
89 
90   // Constructor for tables created by SelectAndExtendParent.
91   MacroTable(StringPool* pool,
92              std::vector<ColumnLegacy> columns,
93              const MacroTable& parent,
94              const RowMap& parent_overlay);
95 
96   ~MacroTable() override;
97 
98   PERFETTO_NO_INLINE void UpdateOverlaysAfterParentInsert();
99 
100   PERFETTO_NO_INLINE void UpdateSelfOverlayAfterInsert();
101 
102   PERFETTO_NO_INLINE static std::vector<ColumnLegacy>
103   CopyColumnsFromParentOrAddRootColumns(MacroTable* self,
104                                         const MacroTable* parent);
105 
106   PERFETTO_NO_INLINE void OnConstructionCompletedRegularConstructor(
107       std::initializer_list<RefPtr<column::StorageLayer>> storage_layers,
108       std::initializer_list<RefPtr<column::OverlayLayer>> null_layers);
109 
110   template <typename T>
AddColumnToVector(std::vector<ColumnLegacy> & columns,const char * name,ColumnStorage<T> * storage,uint32_t flags,uint32_t column_index,uint32_t overlay_index)111   PERFETTO_NO_INLINE static void AddColumnToVector(
112       std::vector<ColumnLegacy>& columns,
113       const char* name,
114       ColumnStorage<T>* storage,
115       uint32_t flags,
116       uint32_t column_index,
117       uint32_t overlay_index) {
118     columns.emplace_back(name, storage, flags, column_index, overlay_index);
119   }
120 
OverlayCount(const MacroTable * parent)121   static uint32_t OverlayCount(const MacroTable* parent) {
122     return parent ? static_cast<uint32_t>(parent->overlays().size()) : 0;
123   }
124 
125   // Stores whether inserts are allowed into this macro table; by default
126   // inserts are allowed but they are disallowed when a parent table is extended
127   // with |ExtendParent|; the rationale for this is that extensions usually
128   // happen in dynamic tables and they should not be allowed to insert rows into
129   // the real (static) tables.
130   bool allow_inserts_ = true;
131 
132   // Stores the most specific "derived" type of this row in the table.
133   //
134   // For example, suppose a row is inserted into the gpu_slice table. This will
135   // also cause a row to be inserted into the slice table. For users querying
136   // the slice table, they will want to know the "real" type of this slice (i.e.
137   // they will want to see that the type is gpu_slice). This sparse vector
138   // stores precisely the real type.
139   //
140   // Only relevant for parentless tables. Will be empty and unreferenced by
141   // tables with parents.
142   ColumnStorage<StringPool::Id> type_;
143 
144  private:
145   PERFETTO_NO_INLINE static std::vector<ColumnStorageOverlay>
146   EmptyOverlaysFromParent(const MacroTable* parent);
147   PERFETTO_NO_INLINE static std::vector<ColumnStorageOverlay>
148   SelectedOverlaysFromParent(const macros_internal::MacroTable& parent,
149                              const RowMap& rm);
150 
151   const MacroTable* parent_ = nullptr;
152 };
153 
154 class BaseConstIterator {
155  public:
156   explicit operator bool() const;
157   BaseConstIterator& operator++();
158 
159  protected:
160   explicit BaseConstIterator(const MacroTable* table, Table::Iterator iterator);
161 
162   Table::Iterator iterator_;
163   const MacroTable* table_;
164 };
165 
166 // Abstract iterator class for macro tables.
167 // Extracted to allow sharing with view code.
168 template <typename Iterator,
169           typename MacroTable,
170           typename RowNumber,
171           typename ConstRowReference>
172 class AbstractConstIterator : public BaseConstIterator {
173  public:
174   Iterator& operator++() {
175     return static_cast<Iterator&>(BaseConstIterator::operator++());
176   }
177 
178   // Returns a RowNumber for the current row.
row_number()179   RowNumber row_number() const {
180     return RowNumber(this_it()->CurrentRowNumber());
181   }
182 
183   // Returns a ConstRowReference to the current row.
row_reference()184   ConstRowReference row_reference() const {
185     return ConstRowReference(table(), this_it()->CurrentRowNumber());
186   }
187 
188  protected:
AbstractConstIterator(const MacroTable * table,Table::Iterator iterator)189   explicit AbstractConstIterator(const MacroTable* table,
190                                  Table::Iterator iterator)
191       : BaseConstIterator(table, std::move(iterator)) {}
192 
table()193   const MacroTable* table() const {
194     return static_cast<const MacroTable*>(table_);
195   }
196 
197  private:
this_it()198   Iterator* this_it() { return static_cast<Iterator*>(this); }
this_it()199   const Iterator* this_it() const { return static_cast<const Iterator*>(this); }
200 };
201 
202 class BaseRowNumber {
203  public:
204   // Converts this object to the underlying int value.
row_number()205   uint32_t row_number() const { return row_number_; }
206 
207   // Allows sorting + storage in a map/set.
208   bool operator<(const BaseRowNumber& other) const {
209     return row_number_ < other.row_number_;
210   }
211 
212  protected:
BaseRowNumber(uint32_t row_number)213   explicit BaseRowNumber(uint32_t row_number) : row_number_(row_number) {}
214 
215   uint32_t row_number_ = 0;
216 };
217 
218 // Abstract RowNumber class for macro tables.
219 // Extracted to allow sharing with view code.
220 template <typename MacroTable,
221           typename ConstRowReference,
222           typename RowReference = void>
223 class AbstractRowNumber : public BaseRowNumber {
224  public:
225   // Converts this RowNumber to a RowReference for the given |table|.
226   template <typename RR = RowReference>
ToRowReference(MacroTable * table)227   RR ToRowReference(MacroTable* table) const {
228     static_assert(!std::is_same_v<RR, void>);
229     return RR(table, row_number_);
230   }
231 
232   // Converts this RowNumber to a ConstRowReference for the given |table|.
ToRowReference(const MacroTable & table)233   ConstRowReference ToRowReference(const MacroTable& table) const {
234     return ConstRowReference(&table, row_number_);
235   }
236 
237  protected:
AbstractRowNumber(uint32_t row_number)238   explicit AbstractRowNumber(uint32_t row_number) : BaseRowNumber(row_number) {}
239 };
240 
241 class BaseRowReference {
242  protected:
243   BaseRowReference(const MacroTable* table, uint32_t row_number);
244 
245   const MacroTable* table_ = nullptr;
246   uint32_t row_number_ = 0;
247 };
248 
249 // Abstract ConstRowReference class for macro tables.
250 // Extracted to allow sharing with view code.
251 template <typename MacroTable, typename RowNumber>
252 class AbstractConstRowReference : public BaseRowReference {
253  public:
254   // Converts this RowReference to a RowNumber object which is more memory
255   // efficient to store.
ToRowNumber()256   RowNumber ToRowNumber() { return RowNumber(row_number_); }
257 
258  protected:
table()259   const MacroTable* table() const {
260     return static_cast<const MacroTable*>(table_);
261   }
262 
AbstractConstRowReference(const MacroTable * table,uint32_t row_number)263   AbstractConstRowReference(const MacroTable* table, uint32_t row_number)
264       : BaseRowReference(table, row_number) {}
265 };
266 
267 }  // namespace perfetto::trace_processor::macros_internal
268 
269 #endif  // SRC_TRACE_PROCESSOR_TABLES_MACROS_INTERNAL_H_
270