• 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_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   };
50   // This class only exists to allow typechecking to work correctly in Insert
51   // below. If we had C++17 and if constexpr, we could statically verify that
52   // this was never created but for now, we still need to define it to satisfy
53   // the typechecker.
54   struct IdAndRow {
55     uint32_t id;
56   };
57   struct RowNumber {
row_numberRowNumber58     static uint32_t row_number() { PERFETTO_FATAL("Should not be called"); }
59   };
Insert(const Row &)60   static IdAndRow Insert(const Row&) { PERFETTO_FATAL("Should not be called"); }
61 
62  private:
63   explicit RootParentTable(std::nullptr_t);
64 };
65 
66 // The parent class for all macro generated tables.
67 // This class is used to extract common code from the macro tables to reduce
68 // code size.
69 class MacroTable : public Table {
70  public:
71   // We don't want a move or copy constructor because we store pointers to
72   // fields of macro tables which will be invalidated if we move/copy them.
73   MacroTable(const MacroTable&) = delete;
74   MacroTable& operator=(const MacroTable&) = delete;
75 
76   MacroTable(MacroTable&&) = delete;
77   MacroTable& operator=(MacroTable&&) noexcept = delete;
78 
79  protected:
80   // Constructors for tables created by the regular constructor.
81   PERFETTO_NO_INLINE explicit MacroTable(StringPool* pool,
82                                          std::vector<ColumnLegacy> columns,
83                                          const MacroTable* parent);
84 
85   // Constructor for tables created by SelectAndExtendParent.
86   MacroTable(StringPool* pool,
87              std::vector<ColumnLegacy> columns,
88              const MacroTable& parent,
89              const RowMap& parent_overlay);
90 
91   ~MacroTable() override;
92 
93   PERFETTO_NO_INLINE void UpdateOverlaysAfterParentInsert();
94 
95   PERFETTO_NO_INLINE void UpdateSelfOverlayAfterInsert();
96 
97   PERFETTO_NO_INLINE static std::vector<ColumnLegacy>
98   CopyColumnsFromParentOrAddRootColumns(const MacroTable* parent);
99 
100   PERFETTO_NO_INLINE void OnConstructionCompletedRegularConstructor(
101       std::initializer_list<RefPtr<column::StorageLayer>> storage_layers,
102       std::initializer_list<RefPtr<column::OverlayLayer>> null_layers);
103 
104   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)105   PERFETTO_NO_INLINE static void AddColumnToVector(
106       std::vector<ColumnLegacy>& columns,
107       const char* name,
108       ColumnStorage<T>* storage,
109       uint32_t flags,
110       uint32_t column_index,
111       uint32_t overlay_index) {
112     columns.emplace_back(name, storage, flags, column_index, overlay_index);
113   }
114 
OverlayCount(const MacroTable * parent)115   static uint32_t OverlayCount(const MacroTable* parent) {
116     return parent ? static_cast<uint32_t>(parent->overlays().size()) : 0;
117   }
118 
119   // Stores whether inserts are allowed into this macro table; by default
120   // inserts are allowed but they are disallowed when a parent table is extended
121   // with |ExtendParent|; the rationale for this is that extensions usually
122   // happen in dynamic tables and they should not be allowed to insert rows into
123   // the real (static) tables.
124   bool allow_inserts_ = true;
125 
126  private:
127   PERFETTO_NO_INLINE static std::vector<ColumnStorageOverlay>
128   EmptyOverlaysFromParent(const MacroTable* parent);
129   PERFETTO_NO_INLINE static std::vector<ColumnStorageOverlay>
130   SelectedOverlaysFromParent(const macros_internal::MacroTable& parent,
131                              const RowMap& rm);
132 
133   const MacroTable* parent_ = nullptr;
134 };
135 
136 class BaseConstIterator {
137  public:
138   explicit operator bool() const;
139   BaseConstIterator& operator++();
140 
141  protected:
142   explicit BaseConstIterator(const MacroTable* table, Table::Iterator iterator);
143 
144   Table::Iterator iterator_;
145   const MacroTable* table_;
146 };
147 
148 // Abstract iterator class for macro tables.
149 // Extracted to allow sharing with view code.
150 template <typename Iterator,
151           typename MacroTable,
152           typename RowNumber,
153           typename ConstRowReference>
154 class AbstractConstIterator : public BaseConstIterator {
155  public:
156   Iterator& operator++() {
157     return static_cast<Iterator&>(BaseConstIterator::operator++());
158   }
159 
160   // Returns a RowNumber for the current row.
row_number()161   RowNumber row_number() const {
162     return RowNumber(this_it()->CurrentRowNumber());
163   }
164 
165   // Returns a ConstRowReference to the current row.
row_reference()166   ConstRowReference row_reference() const {
167     return ConstRowReference(table(), this_it()->CurrentRowNumber());
168   }
169 
170  protected:
AbstractConstIterator(const MacroTable * table,Table::Iterator iterator)171   explicit AbstractConstIterator(const MacroTable* table,
172                                  Table::Iterator iterator)
173       : BaseConstIterator(table, std::move(iterator)) {}
174 
table()175   const MacroTable* table() const {
176     return static_cast<const MacroTable*>(table_);
177   }
178 
179  private:
this_it()180   Iterator* this_it() { return static_cast<Iterator*>(this); }
this_it()181   const Iterator* this_it() const { return static_cast<const Iterator*>(this); }
182 };
183 
184 class BaseRowNumber {
185  public:
186   // Converts this object to the underlying int value.
row_number()187   uint32_t row_number() const { return row_number_; }
188 
189   // Allows sorting + storage in a map/set.
190   bool operator<(const BaseRowNumber& other) const {
191     return row_number_ < other.row_number_;
192   }
193 
194  protected:
BaseRowNumber(uint32_t row_number)195   explicit BaseRowNumber(uint32_t row_number) : row_number_(row_number) {}
196 
197   uint32_t row_number_ = 0;
198 };
199 
200 // Abstract RowNumber class for macro tables.
201 // Extracted to allow sharing with view code.
202 template <typename MacroTable,
203           typename ConstRowReference,
204           typename RowReference = void>
205 class AbstractRowNumber : public BaseRowNumber {
206  public:
207   // Converts this RowNumber to a RowReference for the given |table|.
208   template <typename RR = RowReference>
ToRowReference(MacroTable * table)209   RR ToRowReference(MacroTable* table) const {
210     static_assert(!std::is_same_v<RR, void>);
211     return RR(table, row_number_);
212   }
213 
214   // Converts this RowNumber to a ConstRowReference for the given |table|.
ToRowReference(const MacroTable & table)215   ConstRowReference ToRowReference(const MacroTable& table) const {
216     return ConstRowReference(&table, row_number_);
217   }
218 
219  protected:
AbstractRowNumber(uint32_t row_number)220   explicit AbstractRowNumber(uint32_t row_number) : BaseRowNumber(row_number) {}
221 };
222 
223 class BaseRowReference {
224  protected:
225   BaseRowReference(const MacroTable* table, uint32_t row_number);
226 
227   const MacroTable* table_ = nullptr;
228   uint32_t row_number_ = 0;
229 };
230 
231 // Abstract ConstRowReference class for macro tables.
232 // Extracted to allow sharing with view code.
233 template <typename MacroTable, typename RowNumber>
234 class AbstractConstRowReference : public BaseRowReference {
235  public:
236   // Converts this RowReference to a RowNumber object which is more memory
237   // efficient to store.
ToRowNumber()238   RowNumber ToRowNumber() { return RowNumber(row_number_); }
239 
240  protected:
table()241   const MacroTable* table() const {
242     return static_cast<const MacroTable*>(table_);
243   }
244 
AbstractConstRowReference(const MacroTable * table,uint32_t row_number)245   AbstractConstRowReference(const MacroTable* table, uint32_t row_number)
246       : BaseRowReference(table, row_number) {}
247 };
248 
249 }  // namespace perfetto::trace_processor::macros_internal
250 
251 #endif  // SRC_TRACE_PROCESSOR_TABLES_MACROS_INTERNAL_H_
252