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