1 #ifndef SRC_TRACE_PROCESSOR_TABLES_JIT_TABLES_PY_H_ 2 #define SRC_TRACE_PROCESSOR_TABLES_JIT_TABLES_PY_H_ 3 4 #include <array> 5 #include <cstddef> 6 #include <cstdint> 7 #include <memory> 8 #include <optional> 9 #include <type_traits> 10 #include <utility> 11 #include <vector> 12 13 #include "perfetto/base/logging.h" 14 #include "perfetto/trace_processor/basic_types.h" 15 #include "perfetto/trace_processor/ref_counted.h" 16 #include "src/trace_processor/containers/bit_vector.h" 17 #include "src/trace_processor/containers/row_map.h" 18 #include "src/trace_processor/containers/string_pool.h" 19 #include "src/trace_processor/db/column/arrangement_overlay.h" 20 #include "src/trace_processor/db/column/data_layer.h" 21 #include "src/trace_processor/db/column/dense_null_overlay.h" 22 #include "src/trace_processor/db/column/numeric_storage.h" 23 #include "src/trace_processor/db/column/id_storage.h" 24 #include "src/trace_processor/db/column/null_overlay.h" 25 #include "src/trace_processor/db/column/range_overlay.h" 26 #include "src/trace_processor/db/column/selector_overlay.h" 27 #include "src/trace_processor/db/column/set_id_storage.h" 28 #include "src/trace_processor/db/column/string_storage.h" 29 #include "src/trace_processor/db/column/types.h" 30 #include "src/trace_processor/db/column_storage.h" 31 #include "src/trace_processor/db/column.h" 32 #include "src/trace_processor/db/table.h" 33 #include "src/trace_processor/db/typed_column.h" 34 #include "src/trace_processor/db/typed_column_internal.h" 35 #include "src/trace_processor/tables/macros_internal.h" 36 37 #include "src/trace_processor/tables/profiler_tables_py.h" 38 39 namespace perfetto::trace_processor::tables { 40 41 class JitCodeTable : public macros_internal::MacroTable { 42 public: 43 static constexpr uint32_t kColumnCount = 9; 44 45 struct Id : public BaseId { 46 Id() = default; IdId47 explicit constexpr Id(uint32_t v) : BaseId(v) {} 48 }; 49 static_assert(std::is_trivially_destructible_v<Id>, 50 "Inheritance used without trivial destruction"); 51 52 struct ColumnIndex { 53 static constexpr uint32_t id = 0; 54 static constexpr uint32_t type = 1; 55 static constexpr uint32_t create_ts = 2; 56 static constexpr uint32_t estimated_delete_ts = 3; 57 static constexpr uint32_t utid = 4; 58 static constexpr uint32_t start_address = 5; 59 static constexpr uint32_t size = 6; 60 static constexpr uint32_t function_name = 7; 61 static constexpr uint32_t native_code_base64 = 8; 62 }; 63 struct ColumnType { 64 using id = IdColumn<JitCodeTable::Id>; 65 using type = TypedColumn<StringPool::Id>; 66 using create_ts = TypedColumn<int64_t>; 67 using estimated_delete_ts = TypedColumn<std::optional<int64_t>>; 68 using utid = TypedColumn<uint32_t>; 69 using start_address = TypedColumn<int64_t>; 70 using size = TypedColumn<int64_t>; 71 using function_name = TypedColumn<StringPool::Id>; 72 using native_code_base64 = TypedColumn<std::optional<StringPool::Id>>; 73 }; 74 struct Row : public macros_internal::RootParentTable::Row { 75 Row(int64_t in_create_ts = {}, 76 std::optional<int64_t> in_estimated_delete_ts = {}, 77 uint32_t in_utid = {}, 78 int64_t in_start_address = {}, 79 int64_t in_size = {}, 80 StringPool::Id in_function_name = {}, 81 std::optional<StringPool::Id> in_native_code_base64 = {}, 82 std::nullptr_t = nullptr) RowRow83 : macros_internal::RootParentTable::Row(), 84 create_ts(in_create_ts), 85 estimated_delete_ts(in_estimated_delete_ts), 86 utid(in_utid), 87 start_address(in_start_address), 88 size(in_size), 89 function_name(in_function_name), 90 native_code_base64(in_native_code_base64) { 91 type_ = "__intrinsic_jit_code"; 92 } 93 int64_t create_ts; 94 std::optional<int64_t> estimated_delete_ts; 95 uint32_t utid; 96 int64_t start_address; 97 int64_t size; 98 StringPool::Id function_name; 99 std::optional<StringPool::Id> native_code_base64; 100 101 bool operator==(const JitCodeTable::Row& other) const { 102 return type() == other.type() && ColumnType::create_ts::Equals(create_ts, other.create_ts) && 103 ColumnType::estimated_delete_ts::Equals(estimated_delete_ts, other.estimated_delete_ts) && 104 ColumnType::utid::Equals(utid, other.utid) && 105 ColumnType::start_address::Equals(start_address, other.start_address) && 106 ColumnType::size::Equals(size, other.size) && 107 ColumnType::function_name::Equals(function_name, other.function_name) && 108 ColumnType::native_code_base64::Equals(native_code_base64, other.native_code_base64); 109 } 110 }; 111 struct ColumnFlag { 112 static constexpr uint32_t create_ts = static_cast<uint32_t>(ColumnLegacy::Flag::kSorted) | ColumnType::create_ts::default_flags(); 113 static constexpr uint32_t estimated_delete_ts = ColumnType::estimated_delete_ts::default_flags(); 114 static constexpr uint32_t utid = ColumnType::utid::default_flags(); 115 static constexpr uint32_t start_address = ColumnType::start_address::default_flags(); 116 static constexpr uint32_t size = ColumnType::size::default_flags(); 117 static constexpr uint32_t function_name = ColumnType::function_name::default_flags(); 118 static constexpr uint32_t native_code_base64 = ColumnType::native_code_base64::default_flags(); 119 }; 120 121 class RowNumber; 122 class ConstRowReference; 123 class RowReference; 124 125 class RowNumber : public macros_internal::AbstractRowNumber< 126 JitCodeTable, ConstRowReference, RowReference> { 127 public: RowNumber(uint32_t row_number)128 explicit RowNumber(uint32_t row_number) 129 : AbstractRowNumber(row_number) {} 130 }; 131 static_assert(std::is_trivially_destructible_v<RowNumber>, 132 "Inheritance used without trivial destruction"); 133 134 class ConstRowReference : public macros_internal::AbstractConstRowReference< 135 JitCodeTable, RowNumber> { 136 public: ConstRowReference(const JitCodeTable * table,uint32_t row_number)137 ConstRowReference(const JitCodeTable* table, uint32_t row_number) 138 : AbstractConstRowReference(table, row_number) {} 139 id()140 ColumnType::id::type id() const { 141 return table()->id()[row_number_]; 142 } type()143 ColumnType::type::type type() const { 144 return table()->type()[row_number_]; 145 } create_ts()146 ColumnType::create_ts::type create_ts() const { 147 return table()->create_ts()[row_number_]; 148 } estimated_delete_ts()149 ColumnType::estimated_delete_ts::type estimated_delete_ts() const { 150 return table()->estimated_delete_ts()[row_number_]; 151 } utid()152 ColumnType::utid::type utid() const { 153 return table()->utid()[row_number_]; 154 } start_address()155 ColumnType::start_address::type start_address() const { 156 return table()->start_address()[row_number_]; 157 } size()158 ColumnType::size::type size() const { 159 return table()->size()[row_number_]; 160 } function_name()161 ColumnType::function_name::type function_name() const { 162 return table()->function_name()[row_number_]; 163 } native_code_base64()164 ColumnType::native_code_base64::type native_code_base64() const { 165 return table()->native_code_base64()[row_number_]; 166 } 167 }; 168 static_assert(std::is_trivially_destructible_v<ConstRowReference>, 169 "Inheritance used without trivial destruction"); 170 class RowReference : public ConstRowReference { 171 public: RowReference(const JitCodeTable * table,uint32_t row_number)172 RowReference(const JitCodeTable* table, uint32_t row_number) 173 : ConstRowReference(table, row_number) {} 174 set_create_ts(ColumnType::create_ts::non_optional_type v)175 void set_create_ts( 176 ColumnType::create_ts::non_optional_type v) { 177 return mutable_table()->mutable_create_ts()->Set(row_number_, v); 178 } set_estimated_delete_ts(ColumnType::estimated_delete_ts::non_optional_type v)179 void set_estimated_delete_ts( 180 ColumnType::estimated_delete_ts::non_optional_type v) { 181 return mutable_table()->mutable_estimated_delete_ts()->Set(row_number_, v); 182 } set_utid(ColumnType::utid::non_optional_type v)183 void set_utid( 184 ColumnType::utid::non_optional_type v) { 185 return mutable_table()->mutable_utid()->Set(row_number_, v); 186 } set_start_address(ColumnType::start_address::non_optional_type v)187 void set_start_address( 188 ColumnType::start_address::non_optional_type v) { 189 return mutable_table()->mutable_start_address()->Set(row_number_, v); 190 } set_size(ColumnType::size::non_optional_type v)191 void set_size( 192 ColumnType::size::non_optional_type v) { 193 return mutable_table()->mutable_size()->Set(row_number_, v); 194 } set_function_name(ColumnType::function_name::non_optional_type v)195 void set_function_name( 196 ColumnType::function_name::non_optional_type v) { 197 return mutable_table()->mutable_function_name()->Set(row_number_, v); 198 } set_native_code_base64(ColumnType::native_code_base64::non_optional_type v)199 void set_native_code_base64( 200 ColumnType::native_code_base64::non_optional_type v) { 201 return mutable_table()->mutable_native_code_base64()->Set(row_number_, v); 202 } 203 204 private: mutable_table()205 JitCodeTable* mutable_table() const { 206 return const_cast<JitCodeTable*>(table()); 207 } 208 }; 209 static_assert(std::is_trivially_destructible_v<RowReference>, 210 "Inheritance used without trivial destruction"); 211 212 class ConstIterator; 213 class ConstIterator : public macros_internal::AbstractConstIterator< 214 ConstIterator, JitCodeTable, RowNumber, ConstRowReference> { 215 public: id()216 ColumnType::id::type id() const { 217 const auto& col = table()->id(); 218 return col.GetAtIdx( 219 iterator_.StorageIndexForColumn(col.index_in_table())); 220 } type()221 ColumnType::type::type type() const { 222 const auto& col = table()->type(); 223 return col.GetAtIdx( 224 iterator_.StorageIndexForColumn(col.index_in_table())); 225 } create_ts()226 ColumnType::create_ts::type create_ts() const { 227 const auto& col = table()->create_ts(); 228 return col.GetAtIdx( 229 iterator_.StorageIndexForColumn(col.index_in_table())); 230 } estimated_delete_ts()231 ColumnType::estimated_delete_ts::type estimated_delete_ts() const { 232 const auto& col = table()->estimated_delete_ts(); 233 return col.GetAtIdx( 234 iterator_.StorageIndexForColumn(col.index_in_table())); 235 } utid()236 ColumnType::utid::type utid() const { 237 const auto& col = table()->utid(); 238 return col.GetAtIdx( 239 iterator_.StorageIndexForColumn(col.index_in_table())); 240 } start_address()241 ColumnType::start_address::type start_address() const { 242 const auto& col = table()->start_address(); 243 return col.GetAtIdx( 244 iterator_.StorageIndexForColumn(col.index_in_table())); 245 } size()246 ColumnType::size::type size() const { 247 const auto& col = table()->size(); 248 return col.GetAtIdx( 249 iterator_.StorageIndexForColumn(col.index_in_table())); 250 } function_name()251 ColumnType::function_name::type function_name() const { 252 const auto& col = table()->function_name(); 253 return col.GetAtIdx( 254 iterator_.StorageIndexForColumn(col.index_in_table())); 255 } native_code_base64()256 ColumnType::native_code_base64::type native_code_base64() const { 257 const auto& col = table()->native_code_base64(); 258 return col.GetAtIdx( 259 iterator_.StorageIndexForColumn(col.index_in_table())); 260 } 261 262 protected: ConstIterator(const JitCodeTable * table,Table::Iterator iterator)263 explicit ConstIterator(const JitCodeTable* table, 264 Table::Iterator iterator) 265 : AbstractConstIterator(table, std::move(iterator)) {} 266 CurrentRowNumber()267 uint32_t CurrentRowNumber() const { 268 return iterator_.StorageIndexForLastOverlay(); 269 } 270 271 private: 272 friend class JitCodeTable; 273 friend class macros_internal::AbstractConstIterator< 274 ConstIterator, JitCodeTable, RowNumber, ConstRowReference>; 275 }; 276 class Iterator : public ConstIterator { 277 public: row_reference()278 RowReference row_reference() const { 279 return {const_cast<JitCodeTable*>(table()), CurrentRowNumber()}; 280 } 281 282 private: 283 friend class JitCodeTable; 284 Iterator(JitCodeTable * table,Table::Iterator iterator)285 explicit Iterator(JitCodeTable* table, Table::Iterator iterator) 286 : ConstIterator(table, std::move(iterator)) {} 287 }; 288 289 struct IdAndRow { 290 Id id; 291 uint32_t row; 292 RowReference row_reference; 293 RowNumber row_number; 294 }; 295 GetColumns(JitCodeTable * self,const macros_internal::MacroTable * parent)296 static std::vector<ColumnLegacy> GetColumns( 297 JitCodeTable* self, 298 const macros_internal::MacroTable* parent) { 299 std::vector<ColumnLegacy> columns = 300 CopyColumnsFromParentOrAddRootColumns(self, parent); 301 uint32_t olay_idx = OverlayCount(parent); 302 AddColumnToVector(columns, "create_ts", &self->create_ts_, ColumnFlag::create_ts, 303 static_cast<uint32_t>(columns.size()), olay_idx); 304 AddColumnToVector(columns, "estimated_delete_ts", &self->estimated_delete_ts_, ColumnFlag::estimated_delete_ts, 305 static_cast<uint32_t>(columns.size()), olay_idx); 306 AddColumnToVector(columns, "utid", &self->utid_, ColumnFlag::utid, 307 static_cast<uint32_t>(columns.size()), olay_idx); 308 AddColumnToVector(columns, "start_address", &self->start_address_, ColumnFlag::start_address, 309 static_cast<uint32_t>(columns.size()), olay_idx); 310 AddColumnToVector(columns, "size", &self->size_, ColumnFlag::size, 311 static_cast<uint32_t>(columns.size()), olay_idx); 312 AddColumnToVector(columns, "function_name", &self->function_name_, ColumnFlag::function_name, 313 static_cast<uint32_t>(columns.size()), olay_idx); 314 AddColumnToVector(columns, "native_code_base64", &self->native_code_base64_, ColumnFlag::native_code_base64, 315 static_cast<uint32_t>(columns.size()), olay_idx); 316 return columns; 317 } 318 JitCodeTable(StringPool * pool)319 PERFETTO_NO_INLINE explicit JitCodeTable(StringPool* pool) 320 : macros_internal::MacroTable( 321 pool, 322 GetColumns(this, nullptr), 323 nullptr), 324 create_ts_(ColumnStorage<ColumnType::create_ts::stored_type>::Create<false>()), 325 estimated_delete_ts_(ColumnStorage<ColumnType::estimated_delete_ts::stored_type>::Create<false>()), 326 utid_(ColumnStorage<ColumnType::utid::stored_type>::Create<false>()), 327 start_address_(ColumnStorage<ColumnType::start_address::stored_type>::Create<false>()), 328 size_(ColumnStorage<ColumnType::size::stored_type>::Create<false>()), 329 function_name_(ColumnStorage<ColumnType::function_name::stored_type>::Create<false>()), 330 native_code_base64_(ColumnStorage<ColumnType::native_code_base64::stored_type>::Create<false>()) 331 , 332 id_storage_layer_(new column::IdStorage()), 333 type_storage_layer_( 334 new column::StringStorage(string_pool(), &type_.vector())), 335 create_ts_storage_layer_( 336 new column::NumericStorage<ColumnType::create_ts::non_optional_stored_type>( 337 &create_ts_.vector(), 338 ColumnTypeHelper<ColumnType::create_ts::stored_type>::ToColumnType(), 339 true)), 340 estimated_delete_ts_storage_layer_( 341 new column::NumericStorage<ColumnType::estimated_delete_ts::non_optional_stored_type>( 342 &estimated_delete_ts_.non_null_vector(), 343 ColumnTypeHelper<ColumnType::estimated_delete_ts::stored_type>::ToColumnType(), 344 false)), 345 utid_storage_layer_( 346 new column::NumericStorage<ColumnType::utid::non_optional_stored_type>( 347 &utid_.vector(), 348 ColumnTypeHelper<ColumnType::utid::stored_type>::ToColumnType(), 349 false)), 350 start_address_storage_layer_( 351 new column::NumericStorage<ColumnType::start_address::non_optional_stored_type>( 352 &start_address_.vector(), 353 ColumnTypeHelper<ColumnType::start_address::stored_type>::ToColumnType(), 354 false)), 355 size_storage_layer_( 356 new column::NumericStorage<ColumnType::size::non_optional_stored_type>( 357 &size_.vector(), 358 ColumnTypeHelper<ColumnType::size::stored_type>::ToColumnType(), 359 false)), 360 function_name_storage_layer_( 361 new column::StringStorage(string_pool(), &function_name_.vector())), 362 native_code_base64_storage_layer_( 363 new column::StringStorage(string_pool(), &native_code_base64_.vector())) 364 , 365 estimated_delete_ts_null_layer_(new column::NullOverlay(estimated_delete_ts_.bv())) { 366 static_assert( 367 ColumnLegacy::IsFlagsAndTypeValid<ColumnType::create_ts::stored_type>( 368 ColumnFlag::create_ts), 369 "Column type and flag combination is not valid"); 370 static_assert( 371 ColumnLegacy::IsFlagsAndTypeValid<ColumnType::estimated_delete_ts::stored_type>( 372 ColumnFlag::estimated_delete_ts), 373 "Column type and flag combination is not valid"); 374 static_assert( 375 ColumnLegacy::IsFlagsAndTypeValid<ColumnType::utid::stored_type>( 376 ColumnFlag::utid), 377 "Column type and flag combination is not valid"); 378 static_assert( 379 ColumnLegacy::IsFlagsAndTypeValid<ColumnType::start_address::stored_type>( 380 ColumnFlag::start_address), 381 "Column type and flag combination is not valid"); 382 static_assert( 383 ColumnLegacy::IsFlagsAndTypeValid<ColumnType::size::stored_type>( 384 ColumnFlag::size), 385 "Column type and flag combination is not valid"); 386 static_assert( 387 ColumnLegacy::IsFlagsAndTypeValid<ColumnType::function_name::stored_type>( 388 ColumnFlag::function_name), 389 "Column type and flag combination is not valid"); 390 static_assert( 391 ColumnLegacy::IsFlagsAndTypeValid<ColumnType::native_code_base64::stored_type>( 392 ColumnFlag::native_code_base64), 393 "Column type and flag combination is not valid"); 394 OnConstructionCompletedRegularConstructor( 395 {id_storage_layer_,type_storage_layer_,create_ts_storage_layer_,estimated_delete_ts_storage_layer_,utid_storage_layer_,start_address_storage_layer_,size_storage_layer_,function_name_storage_layer_,native_code_base64_storage_layer_}, 396 {{},{},{},estimated_delete_ts_null_layer_,{},{},{},{},{}}); 397 } 398 ~JitCodeTable() override; 399 Name()400 static const char* Name() { return "__intrinsic_jit_code"; } 401 ComputeStaticSchema()402 static Table::Schema ComputeStaticSchema() { 403 Table::Schema schema; 404 schema.columns.emplace_back(Table::Schema::Column{ 405 "id", SqlValue::Type::kLong, true, true, false, false}); 406 schema.columns.emplace_back(Table::Schema::Column{ 407 "type", SqlValue::Type::kString, false, false, false, false}); 408 schema.columns.emplace_back(Table::Schema::Column{ 409 "create_ts", ColumnType::create_ts::SqlValueType(), false, 410 true, 411 false, 412 false}); 413 schema.columns.emplace_back(Table::Schema::Column{ 414 "estimated_delete_ts", ColumnType::estimated_delete_ts::SqlValueType(), false, 415 false, 416 false, 417 false}); 418 schema.columns.emplace_back(Table::Schema::Column{ 419 "utid", ColumnType::utid::SqlValueType(), false, 420 false, 421 false, 422 false}); 423 schema.columns.emplace_back(Table::Schema::Column{ 424 "start_address", ColumnType::start_address::SqlValueType(), false, 425 false, 426 false, 427 false}); 428 schema.columns.emplace_back(Table::Schema::Column{ 429 "size", ColumnType::size::SqlValueType(), false, 430 false, 431 false, 432 false}); 433 schema.columns.emplace_back(Table::Schema::Column{ 434 "function_name", ColumnType::function_name::SqlValueType(), false, 435 false, 436 false, 437 false}); 438 schema.columns.emplace_back(Table::Schema::Column{ 439 "native_code_base64", ColumnType::native_code_base64::SqlValueType(), false, 440 false, 441 false, 442 false}); 443 return schema; 444 } 445 IterateRows()446 ConstIterator IterateRows() const { 447 return ConstIterator(this, Table::IterateRows()); 448 } 449 IterateRows()450 Iterator IterateRows() { return Iterator(this, Table::IterateRows()); } 451 FilterToIterator(const Query & q)452 ConstIterator FilterToIterator(const Query& q) const { 453 return ConstIterator(this, QueryToIterator(q)); 454 } 455 FilterToIterator(const Query & q)456 Iterator FilterToIterator(const Query& q) { 457 return Iterator(this, QueryToIterator(q)); 458 } 459 ShrinkToFit()460 void ShrinkToFit() { 461 type_.ShrinkToFit(); 462 create_ts_.ShrinkToFit(); 463 estimated_delete_ts_.ShrinkToFit(); 464 utid_.ShrinkToFit(); 465 start_address_.ShrinkToFit(); 466 size_.ShrinkToFit(); 467 function_name_.ShrinkToFit(); 468 native_code_base64_.ShrinkToFit(); 469 } 470 471 ConstRowReference operator[](uint32_t r) const { 472 return ConstRowReference(this, r); 473 } 474 RowReference operator[](uint32_t r) { return RowReference(this, r); } 475 ConstRowReference operator[](RowNumber r) const { 476 return ConstRowReference(this, r.row_number()); 477 } 478 RowReference operator[](RowNumber r) { 479 return RowReference(this, r.row_number()); 480 } 481 FindById(Id find_id)482 std::optional<ConstRowReference> FindById(Id find_id) const { 483 std::optional<uint32_t> row = id().IndexOf(find_id); 484 return row ? std::make_optional(ConstRowReference(this, *row)) 485 : std::nullopt; 486 } 487 FindById(Id find_id)488 std::optional<RowReference> FindById(Id find_id) { 489 std::optional<uint32_t> row = id().IndexOf(find_id); 490 return row ? std::make_optional(RowReference(this, *row)) : std::nullopt; 491 } 492 Insert(const Row & row)493 IdAndRow Insert(const Row& row) { 494 uint32_t row_number = row_count(); 495 Id id = Id{row_number}; 496 type_.Append(string_pool()->InternString(row.type())); 497 mutable_create_ts()->Append(row.create_ts); 498 mutable_estimated_delete_ts()->Append(row.estimated_delete_ts); 499 mutable_utid()->Append(row.utid); 500 mutable_start_address()->Append(row.start_address); 501 mutable_size()->Append(row.size); 502 mutable_function_name()->Append(row.function_name); 503 mutable_native_code_base64()->Append(row.native_code_base64); 504 UpdateSelfOverlayAfterInsert(); 505 return IdAndRow{id, row_number, RowReference(this, row_number), 506 RowNumber(row_number)}; 507 } 508 509 510 id()511 const IdColumn<JitCodeTable::Id>& id() const { 512 return static_cast<const ColumnType::id&>(columns()[ColumnIndex::id]); 513 } type()514 const TypedColumn<StringPool::Id>& type() const { 515 return static_cast<const ColumnType::type&>(columns()[ColumnIndex::type]); 516 } create_ts()517 const TypedColumn<int64_t>& create_ts() const { 518 return static_cast<const ColumnType::create_ts&>(columns()[ColumnIndex::create_ts]); 519 } estimated_delete_ts()520 const TypedColumn<std::optional<int64_t>>& estimated_delete_ts() const { 521 return static_cast<const ColumnType::estimated_delete_ts&>(columns()[ColumnIndex::estimated_delete_ts]); 522 } utid()523 const TypedColumn<uint32_t>& utid() const { 524 return static_cast<const ColumnType::utid&>(columns()[ColumnIndex::utid]); 525 } start_address()526 const TypedColumn<int64_t>& start_address() const { 527 return static_cast<const ColumnType::start_address&>(columns()[ColumnIndex::start_address]); 528 } size()529 const TypedColumn<int64_t>& size() const { 530 return static_cast<const ColumnType::size&>(columns()[ColumnIndex::size]); 531 } function_name()532 const TypedColumn<StringPool::Id>& function_name() const { 533 return static_cast<const ColumnType::function_name&>(columns()[ColumnIndex::function_name]); 534 } native_code_base64()535 const TypedColumn<std::optional<StringPool::Id>>& native_code_base64() const { 536 return static_cast<const ColumnType::native_code_base64&>(columns()[ColumnIndex::native_code_base64]); 537 } 538 mutable_create_ts()539 TypedColumn<int64_t>* mutable_create_ts() { 540 return static_cast<ColumnType::create_ts*>( 541 GetColumn(ColumnIndex::create_ts)); 542 } mutable_estimated_delete_ts()543 TypedColumn<std::optional<int64_t>>* mutable_estimated_delete_ts() { 544 return static_cast<ColumnType::estimated_delete_ts*>( 545 GetColumn(ColumnIndex::estimated_delete_ts)); 546 } mutable_utid()547 TypedColumn<uint32_t>* mutable_utid() { 548 return static_cast<ColumnType::utid*>( 549 GetColumn(ColumnIndex::utid)); 550 } mutable_start_address()551 TypedColumn<int64_t>* mutable_start_address() { 552 return static_cast<ColumnType::start_address*>( 553 GetColumn(ColumnIndex::start_address)); 554 } mutable_size()555 TypedColumn<int64_t>* mutable_size() { 556 return static_cast<ColumnType::size*>( 557 GetColumn(ColumnIndex::size)); 558 } mutable_function_name()559 TypedColumn<StringPool::Id>* mutable_function_name() { 560 return static_cast<ColumnType::function_name*>( 561 GetColumn(ColumnIndex::function_name)); 562 } mutable_native_code_base64()563 TypedColumn<std::optional<StringPool::Id>>* mutable_native_code_base64() { 564 return static_cast<ColumnType::native_code_base64*>( 565 GetColumn(ColumnIndex::native_code_base64)); 566 } 567 568 private: 569 570 571 ColumnStorage<ColumnType::create_ts::stored_type> create_ts_; 572 ColumnStorage<ColumnType::estimated_delete_ts::stored_type> estimated_delete_ts_; 573 ColumnStorage<ColumnType::utid::stored_type> utid_; 574 ColumnStorage<ColumnType::start_address::stored_type> start_address_; 575 ColumnStorage<ColumnType::size::stored_type> size_; 576 ColumnStorage<ColumnType::function_name::stored_type> function_name_; 577 ColumnStorage<ColumnType::native_code_base64::stored_type> native_code_base64_; 578 579 RefPtr<column::StorageLayer> id_storage_layer_; 580 RefPtr<column::StorageLayer> type_storage_layer_; 581 RefPtr<column::StorageLayer> create_ts_storage_layer_; 582 RefPtr<column::StorageLayer> estimated_delete_ts_storage_layer_; 583 RefPtr<column::StorageLayer> utid_storage_layer_; 584 RefPtr<column::StorageLayer> start_address_storage_layer_; 585 RefPtr<column::StorageLayer> size_storage_layer_; 586 RefPtr<column::StorageLayer> function_name_storage_layer_; 587 RefPtr<column::StorageLayer> native_code_base64_storage_layer_; 588 589 RefPtr<column::OverlayLayer> estimated_delete_ts_null_layer_; 590 }; 591 592 593 class JitFrameTable : public macros_internal::MacroTable { 594 public: 595 static constexpr uint32_t kColumnCount = 4; 596 597 struct Id : public BaseId { 598 Id() = default; IdId599 explicit constexpr Id(uint32_t v) : BaseId(v) {} 600 }; 601 static_assert(std::is_trivially_destructible_v<Id>, 602 "Inheritance used without trivial destruction"); 603 604 struct ColumnIndex { 605 static constexpr uint32_t id = 0; 606 static constexpr uint32_t type = 1; 607 static constexpr uint32_t jit_code_id = 2; 608 static constexpr uint32_t frame_id = 3; 609 }; 610 struct ColumnType { 611 using id = IdColumn<JitFrameTable::Id>; 612 using type = TypedColumn<StringPool::Id>; 613 using jit_code_id = TypedColumn<JitCodeTable::Id>; 614 using frame_id = TypedColumn<StackProfileFrameTable::Id>; 615 }; 616 struct Row : public macros_internal::RootParentTable::Row { 617 Row(JitCodeTable::Id in_jit_code_id = {}, 618 StackProfileFrameTable::Id in_frame_id = {}, 619 std::nullptr_t = nullptr) RowRow620 : macros_internal::RootParentTable::Row(), 621 jit_code_id(in_jit_code_id), 622 frame_id(in_frame_id) { 623 type_ = "__intrinsic_jit_frame"; 624 } 625 JitCodeTable::Id jit_code_id; 626 StackProfileFrameTable::Id frame_id; 627 628 bool operator==(const JitFrameTable::Row& other) const { 629 return type() == other.type() && ColumnType::jit_code_id::Equals(jit_code_id, other.jit_code_id) && 630 ColumnType::frame_id::Equals(frame_id, other.frame_id); 631 } 632 }; 633 struct ColumnFlag { 634 static constexpr uint32_t jit_code_id = ColumnType::jit_code_id::default_flags(); 635 static constexpr uint32_t frame_id = ColumnType::frame_id::default_flags(); 636 }; 637 638 class RowNumber; 639 class ConstRowReference; 640 class RowReference; 641 642 class RowNumber : public macros_internal::AbstractRowNumber< 643 JitFrameTable, ConstRowReference, RowReference> { 644 public: RowNumber(uint32_t row_number)645 explicit RowNumber(uint32_t row_number) 646 : AbstractRowNumber(row_number) {} 647 }; 648 static_assert(std::is_trivially_destructible_v<RowNumber>, 649 "Inheritance used without trivial destruction"); 650 651 class ConstRowReference : public macros_internal::AbstractConstRowReference< 652 JitFrameTable, RowNumber> { 653 public: ConstRowReference(const JitFrameTable * table,uint32_t row_number)654 ConstRowReference(const JitFrameTable* table, uint32_t row_number) 655 : AbstractConstRowReference(table, row_number) {} 656 id()657 ColumnType::id::type id() const { 658 return table()->id()[row_number_]; 659 } type()660 ColumnType::type::type type() const { 661 return table()->type()[row_number_]; 662 } jit_code_id()663 ColumnType::jit_code_id::type jit_code_id() const { 664 return table()->jit_code_id()[row_number_]; 665 } frame_id()666 ColumnType::frame_id::type frame_id() const { 667 return table()->frame_id()[row_number_]; 668 } 669 }; 670 static_assert(std::is_trivially_destructible_v<ConstRowReference>, 671 "Inheritance used without trivial destruction"); 672 class RowReference : public ConstRowReference { 673 public: RowReference(const JitFrameTable * table,uint32_t row_number)674 RowReference(const JitFrameTable* table, uint32_t row_number) 675 : ConstRowReference(table, row_number) {} 676 set_jit_code_id(ColumnType::jit_code_id::non_optional_type v)677 void set_jit_code_id( 678 ColumnType::jit_code_id::non_optional_type v) { 679 return mutable_table()->mutable_jit_code_id()->Set(row_number_, v); 680 } set_frame_id(ColumnType::frame_id::non_optional_type v)681 void set_frame_id( 682 ColumnType::frame_id::non_optional_type v) { 683 return mutable_table()->mutable_frame_id()->Set(row_number_, v); 684 } 685 686 private: mutable_table()687 JitFrameTable* mutable_table() const { 688 return const_cast<JitFrameTable*>(table()); 689 } 690 }; 691 static_assert(std::is_trivially_destructible_v<RowReference>, 692 "Inheritance used without trivial destruction"); 693 694 class ConstIterator; 695 class ConstIterator : public macros_internal::AbstractConstIterator< 696 ConstIterator, JitFrameTable, RowNumber, ConstRowReference> { 697 public: id()698 ColumnType::id::type id() const { 699 const auto& col = table()->id(); 700 return col.GetAtIdx( 701 iterator_.StorageIndexForColumn(col.index_in_table())); 702 } type()703 ColumnType::type::type type() const { 704 const auto& col = table()->type(); 705 return col.GetAtIdx( 706 iterator_.StorageIndexForColumn(col.index_in_table())); 707 } jit_code_id()708 ColumnType::jit_code_id::type jit_code_id() const { 709 const auto& col = table()->jit_code_id(); 710 return col.GetAtIdx( 711 iterator_.StorageIndexForColumn(col.index_in_table())); 712 } frame_id()713 ColumnType::frame_id::type frame_id() const { 714 const auto& col = table()->frame_id(); 715 return col.GetAtIdx( 716 iterator_.StorageIndexForColumn(col.index_in_table())); 717 } 718 719 protected: ConstIterator(const JitFrameTable * table,Table::Iterator iterator)720 explicit ConstIterator(const JitFrameTable* table, 721 Table::Iterator iterator) 722 : AbstractConstIterator(table, std::move(iterator)) {} 723 CurrentRowNumber()724 uint32_t CurrentRowNumber() const { 725 return iterator_.StorageIndexForLastOverlay(); 726 } 727 728 private: 729 friend class JitFrameTable; 730 friend class macros_internal::AbstractConstIterator< 731 ConstIterator, JitFrameTable, RowNumber, ConstRowReference>; 732 }; 733 class Iterator : public ConstIterator { 734 public: row_reference()735 RowReference row_reference() const { 736 return {const_cast<JitFrameTable*>(table()), CurrentRowNumber()}; 737 } 738 739 private: 740 friend class JitFrameTable; 741 Iterator(JitFrameTable * table,Table::Iterator iterator)742 explicit Iterator(JitFrameTable* table, Table::Iterator iterator) 743 : ConstIterator(table, std::move(iterator)) {} 744 }; 745 746 struct IdAndRow { 747 Id id; 748 uint32_t row; 749 RowReference row_reference; 750 RowNumber row_number; 751 }; 752 GetColumns(JitFrameTable * self,const macros_internal::MacroTable * parent)753 static std::vector<ColumnLegacy> GetColumns( 754 JitFrameTable* self, 755 const macros_internal::MacroTable* parent) { 756 std::vector<ColumnLegacy> columns = 757 CopyColumnsFromParentOrAddRootColumns(self, parent); 758 uint32_t olay_idx = OverlayCount(parent); 759 AddColumnToVector(columns, "jit_code_id", &self->jit_code_id_, ColumnFlag::jit_code_id, 760 static_cast<uint32_t>(columns.size()), olay_idx); 761 AddColumnToVector(columns, "frame_id", &self->frame_id_, ColumnFlag::frame_id, 762 static_cast<uint32_t>(columns.size()), olay_idx); 763 return columns; 764 } 765 JitFrameTable(StringPool * pool)766 PERFETTO_NO_INLINE explicit JitFrameTable(StringPool* pool) 767 : macros_internal::MacroTable( 768 pool, 769 GetColumns(this, nullptr), 770 nullptr), 771 jit_code_id_(ColumnStorage<ColumnType::jit_code_id::stored_type>::Create<false>()), 772 frame_id_(ColumnStorage<ColumnType::frame_id::stored_type>::Create<false>()) 773 , 774 id_storage_layer_(new column::IdStorage()), 775 type_storage_layer_( 776 new column::StringStorage(string_pool(), &type_.vector())), 777 jit_code_id_storage_layer_( 778 new column::NumericStorage<ColumnType::jit_code_id::non_optional_stored_type>( 779 &jit_code_id_.vector(), 780 ColumnTypeHelper<ColumnType::jit_code_id::stored_type>::ToColumnType(), 781 false)), 782 frame_id_storage_layer_( 783 new column::NumericStorage<ColumnType::frame_id::non_optional_stored_type>( 784 &frame_id_.vector(), 785 ColumnTypeHelper<ColumnType::frame_id::stored_type>::ToColumnType(), 786 false)) 787 { 788 static_assert( 789 ColumnLegacy::IsFlagsAndTypeValid<ColumnType::jit_code_id::stored_type>( 790 ColumnFlag::jit_code_id), 791 "Column type and flag combination is not valid"); 792 static_assert( 793 ColumnLegacy::IsFlagsAndTypeValid<ColumnType::frame_id::stored_type>( 794 ColumnFlag::frame_id), 795 "Column type and flag combination is not valid"); 796 OnConstructionCompletedRegularConstructor( 797 {id_storage_layer_,type_storage_layer_,jit_code_id_storage_layer_,frame_id_storage_layer_}, 798 {{},{},{},{}}); 799 } 800 ~JitFrameTable() override; 801 Name()802 static const char* Name() { return "__intrinsic_jit_frame"; } 803 ComputeStaticSchema()804 static Table::Schema ComputeStaticSchema() { 805 Table::Schema schema; 806 schema.columns.emplace_back(Table::Schema::Column{ 807 "id", SqlValue::Type::kLong, true, true, false, false}); 808 schema.columns.emplace_back(Table::Schema::Column{ 809 "type", SqlValue::Type::kString, false, false, false, false}); 810 schema.columns.emplace_back(Table::Schema::Column{ 811 "jit_code_id", ColumnType::jit_code_id::SqlValueType(), false, 812 false, 813 false, 814 false}); 815 schema.columns.emplace_back(Table::Schema::Column{ 816 "frame_id", ColumnType::frame_id::SqlValueType(), false, 817 false, 818 false, 819 false}); 820 return schema; 821 } 822 IterateRows()823 ConstIterator IterateRows() const { 824 return ConstIterator(this, Table::IterateRows()); 825 } 826 IterateRows()827 Iterator IterateRows() { return Iterator(this, Table::IterateRows()); } 828 FilterToIterator(const Query & q)829 ConstIterator FilterToIterator(const Query& q) const { 830 return ConstIterator(this, QueryToIterator(q)); 831 } 832 FilterToIterator(const Query & q)833 Iterator FilterToIterator(const Query& q) { 834 return Iterator(this, QueryToIterator(q)); 835 } 836 ShrinkToFit()837 void ShrinkToFit() { 838 type_.ShrinkToFit(); 839 jit_code_id_.ShrinkToFit(); 840 frame_id_.ShrinkToFit(); 841 } 842 843 ConstRowReference operator[](uint32_t r) const { 844 return ConstRowReference(this, r); 845 } 846 RowReference operator[](uint32_t r) { return RowReference(this, r); } 847 ConstRowReference operator[](RowNumber r) const { 848 return ConstRowReference(this, r.row_number()); 849 } 850 RowReference operator[](RowNumber r) { 851 return RowReference(this, r.row_number()); 852 } 853 FindById(Id find_id)854 std::optional<ConstRowReference> FindById(Id find_id) const { 855 std::optional<uint32_t> row = id().IndexOf(find_id); 856 return row ? std::make_optional(ConstRowReference(this, *row)) 857 : std::nullopt; 858 } 859 FindById(Id find_id)860 std::optional<RowReference> FindById(Id find_id) { 861 std::optional<uint32_t> row = id().IndexOf(find_id); 862 return row ? std::make_optional(RowReference(this, *row)) : std::nullopt; 863 } 864 Insert(const Row & row)865 IdAndRow Insert(const Row& row) { 866 uint32_t row_number = row_count(); 867 Id id = Id{row_number}; 868 type_.Append(string_pool()->InternString(row.type())); 869 mutable_jit_code_id()->Append(row.jit_code_id); 870 mutable_frame_id()->Append(row.frame_id); 871 UpdateSelfOverlayAfterInsert(); 872 return IdAndRow{id, row_number, RowReference(this, row_number), 873 RowNumber(row_number)}; 874 } 875 876 877 id()878 const IdColumn<JitFrameTable::Id>& id() const { 879 return static_cast<const ColumnType::id&>(columns()[ColumnIndex::id]); 880 } type()881 const TypedColumn<StringPool::Id>& type() const { 882 return static_cast<const ColumnType::type&>(columns()[ColumnIndex::type]); 883 } jit_code_id()884 const TypedColumn<JitCodeTable::Id>& jit_code_id() const { 885 return static_cast<const ColumnType::jit_code_id&>(columns()[ColumnIndex::jit_code_id]); 886 } frame_id()887 const TypedColumn<StackProfileFrameTable::Id>& frame_id() const { 888 return static_cast<const ColumnType::frame_id&>(columns()[ColumnIndex::frame_id]); 889 } 890 mutable_jit_code_id()891 TypedColumn<JitCodeTable::Id>* mutable_jit_code_id() { 892 return static_cast<ColumnType::jit_code_id*>( 893 GetColumn(ColumnIndex::jit_code_id)); 894 } mutable_frame_id()895 TypedColumn<StackProfileFrameTable::Id>* mutable_frame_id() { 896 return static_cast<ColumnType::frame_id*>( 897 GetColumn(ColumnIndex::frame_id)); 898 } 899 900 private: 901 902 903 ColumnStorage<ColumnType::jit_code_id::stored_type> jit_code_id_; 904 ColumnStorage<ColumnType::frame_id::stored_type> frame_id_; 905 906 RefPtr<column::StorageLayer> id_storage_layer_; 907 RefPtr<column::StorageLayer> type_storage_layer_; 908 RefPtr<column::StorageLayer> jit_code_id_storage_layer_; 909 RefPtr<column::StorageLayer> frame_id_storage_layer_; 910 911 912 }; 913 914 } // namespace perfetto 915 916 #endif // SRC_TRACE_PROCESSOR_TABLES_JIT_TABLES_PY_H_ 917