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