Merge "tp: migrate all table functions to use Python based tables"
diff --git a/Android.bp b/Android.bp
index 9734c15..2077923 100644
--- a/Android.bp
+++ b/Android.bp
@@ -2246,6 +2246,7 @@
"perfetto_src_trace_processor_metrics_gen_cc_all_webview_metrics_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
"perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ "perfetto_src_trace_processor_prelude_table_functions_tables",
"perfetto_src_trace_processor_prelude_tables_views_tables_views",
"perfetto_src_trace_processor_stdlib_gen_amalgamated_stdlib",
"perfetto_src_trace_processor_tables_tables_python",
@@ -10069,6 +10070,43 @@
],
}
+// GN: //src/trace_processor/prelude/table_functions:tables
+genrule {
+ name: "perfetto_src_trace_processor_prelude_table_functions_tables",
+ srcs: [
+ "src/trace_processor/prelude/table_functions/tables.py",
+ ],
+ tools: [
+ "perfetto_src_trace_processor_prelude_table_functions_tables_binary",
+ ],
+ cmd: "$(location perfetto_src_trace_processor_prelude_table_functions_tables_binary) --gen-dir=$(genDir) --relative-input-dir=external/perfetto --inputs $(in)",
+ out: [
+ "src/trace_processor/prelude/table_functions/tables_py.h",
+ ],
+}
+
+// GN: //src/trace_processor/prelude/table_functions:tables
+python_binary_host {
+ name: "perfetto_src_trace_processor_prelude_table_functions_tables_binary",
+ srcs: [
+ "python/generators/trace_processor_table/public.py",
+ "python/generators/trace_processor_table/serialize.py",
+ "python/generators/trace_processor_table/util.py",
+ "src/trace_processor/prelude/table_functions/tables.py",
+ "src/trace_processor/tables/android_tables.py",
+ "src/trace_processor/tables/counter_tables.py",
+ "src/trace_processor/tables/flow_tables.py",
+ "src/trace_processor/tables/memory_tables.py",
+ "src/trace_processor/tables/metadata_tables.py",
+ "src/trace_processor/tables/profiler_tables.py",
+ "src/trace_processor/tables/slice_tables.py",
+ "src/trace_processor/tables/trace_proto_tables.py",
+ "src/trace_processor/tables/track_tables.py",
+ "tools/gen_tp_table_headers.py",
+ ],
+ main: "tools/gen_tp_table_headers.py",
+}
+
// GN: //src/trace_processor/prelude/table_functions:unittests
filegroup {
name: "perfetto_src_trace_processor_prelude_table_functions_unittests",
@@ -10234,7 +10272,7 @@
tools: [
"perfetto_src_trace_processor_tables_py_tables_unittest_binary",
],
- cmd: "$(location perfetto_src_trace_processor_tables_py_tables_unittest_binary) --gen-dir=$(genDir) --inputs $(in) --outputs $(out)",
+ cmd: "$(location perfetto_src_trace_processor_tables_py_tables_unittest_binary) --gen-dir=$(genDir) --relative-input-dir=external/perfetto --inputs $(in)",
out: [
"src/trace_processor/tables/py_tables_unittest_py.h",
],
@@ -10278,7 +10316,7 @@
tools: [
"perfetto_src_trace_processor_tables_tables_python_binary",
],
- cmd: "$(location perfetto_src_trace_processor_tables_tables_python_binary) --gen-dir=$(genDir) --inputs $(in) --outputs $(out)",
+ cmd: "$(location perfetto_src_trace_processor_tables_tables_python_binary) --gen-dir=$(genDir) --relative-input-dir=external/perfetto --inputs $(in)",
out: [
"src/trace_processor/tables/android_tables_py.h",
"src/trace_processor/tables/counter_tables_py.h",
@@ -12048,6 +12086,7 @@
"perfetto_src_trace_processor_metrics_gen_cc_all_webview_metrics_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
"perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ "perfetto_src_trace_processor_prelude_table_functions_tables",
"perfetto_src_trace_processor_prelude_tables_views_tables_views",
"perfetto_src_trace_processor_stdlib_gen_amalgamated_stdlib",
"perfetto_src_trace_processor_tables_py_tables_unittest",
@@ -12565,6 +12604,7 @@
"perfetto_src_trace_processor_metrics_gen_cc_all_webview_metrics_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
"perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ "perfetto_src_trace_processor_prelude_table_functions_tables",
"perfetto_src_trace_processor_prelude_tables_views_tables_views",
"perfetto_src_trace_processor_stdlib_gen_amalgamated_stdlib",
"perfetto_src_trace_processor_tables_tables_python",
@@ -12789,6 +12829,7 @@
"perfetto_src_trace_processor_metrics_gen_cc_all_webview_metrics_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
"perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ "perfetto_src_trace_processor_prelude_table_functions_tables",
"perfetto_src_trace_processor_prelude_tables_views_tables_views",
"perfetto_src_trace_processor_stdlib_gen_amalgamated_stdlib",
"perfetto_src_trace_processor_tables_tables_python",
diff --git a/BUILD b/BUILD
index c30c684..6481aa5 100644
--- a/BUILD
+++ b/BUILD
@@ -1849,6 +1849,20 @@
],
)
+# GN target: //src/trace_processor/prelude/table_functions:tables
+perfetto_cc_tp_tables(
+ name = "src_trace_processor_prelude_table_functions_tables",
+ srcs = [
+ "src/trace_processor/prelude/table_functions/tables.py",
+ ],
+ deps = [
+ ":src_trace_processor_tables_tables_python",
+ ],
+ outs = [
+ "src/trace_processor/prelude/table_functions/tables_py.h",
+ ],
+)
+
# GN target: //src/trace_processor/prelude/tables_views:sources
perfetto_filegroup(
name = "src_trace_processor_prelude_tables_views_sources",
@@ -2023,11 +2037,8 @@
perfetto_filegroup(
name = "src_trace_processor_tables_tables",
srcs = [
- "src/trace_processor/tables/counter_tables.h",
- "src/trace_processor/tables/flow_tables.h",
"src/trace_processor/tables/macros.h",
"src/trace_processor/tables/macros_internal.h",
- "src/trace_processor/tables/profiler_tables.h",
"src/trace_processor/tables/slice_tables.h",
"src/trace_processor/tables/table_destructors.cc",
],
@@ -4736,6 +4747,7 @@
":src_trace_processor_prelude_functions_functions",
":src_trace_processor_prelude_operators_operators",
":src_trace_processor_prelude_table_functions_table_functions",
+ ":src_trace_processor_prelude_table_functions_tables",
":src_trace_processor_sorter_sorter",
":src_trace_processor_sqlite_sqlite",
":src_trace_processor_sqlite_sqlite_minimal",
@@ -4889,6 +4901,7 @@
":src_trace_processor_prelude_functions_functions",
":src_trace_processor_prelude_operators_operators",
":src_trace_processor_prelude_table_functions_table_functions",
+ ":src_trace_processor_prelude_table_functions_tables",
":src_trace_processor_rpc_httpd",
":src_trace_processor_rpc_rpc",
":src_trace_processor_sorter_sorter",
@@ -5101,6 +5114,7 @@
":src_trace_processor_prelude_functions_functions",
":src_trace_processor_prelude_operators_operators",
":src_trace_processor_prelude_table_functions_table_functions",
+ ":src_trace_processor_prelude_table_functions_tables",
":src_trace_processor_sorter_sorter",
":src_trace_processor_sqlite_sqlite",
":src_trace_processor_sqlite_sqlite_minimal",
diff --git a/bazel/rules.bzl b/bazel/rules.bzl
index 4021c58..7a626c1 100644
--- a/bazel/rules.bzl
+++ b/bazel/rules.bzl
@@ -308,7 +308,7 @@
**kwargs,
)
-def perfetto_cc_tp_tables(name, srcs, outs, **kwargs):
+def perfetto_cc_tp_tables(name, srcs, outs, deps = [], **kwargs):
if PERFETTO_CONFIG.root[:2] != "//":
fail("Expected PERFETTO_CONFIG.root to start with //")
@@ -317,12 +317,21 @@
else:
python_path = PERFETTO_CONFIG.root + "/python"
- perfetto_py_binary(
- name = name + "_tool",
+ perfetto_py_library(
+ name = name + "_lib",
deps = [
python_path + ":trace_processor_table_generator",
],
- srcs = srcs + [
+ srcs = srcs,
+ )
+
+ perfetto_py_binary(
+ name = name + "_tool",
+ deps = [
+ ":" + name + "_lib",
+ python_path + ":trace_processor_table_generator",
+ ] + [d + "_lib" for d in deps],
+ srcs = [
"tools/gen_tp_table_headers.py",
],
main = "tools/gen_tp_table_headers.py",
@@ -332,7 +341,6 @@
cmd = ["$(location " + name + "_tool)"]
cmd += ["--gen-dir", "$(RULEDIR)"]
cmd += ["--inputs", "$(SRCS)"]
- cmd += ["--outputs", "$(OUTS)"]
if PERFETTO_CONFIG.root != "//":
cmd += ["--header-prefix", PERFETTO_CONFIG.root[2:]]
diff --git a/gn/perfetto_tp_tables.gni b/gn/perfetto_tp_tables.gni
index da8cfae..0a9d902 100644
--- a/gn/perfetto_tp_tables.gni
+++ b/gn/perfetto_tp_tables.gni
@@ -17,6 +17,10 @@
template("perfetto_tp_tables") {
config_name = target_name + "_config"
action_name = target_name
+ relative_args = [
+ "--relative-input-dir",
+ rebase_path(perfetto_root_path, root_build_dir),
+ ]
config(config_name) {
include_dirs = [ root_gen_dir ]
@@ -32,6 +36,9 @@
}
deps = [ "$perfetto_root_path/python:trace_processor_table_generator" ]
+ if (defined(invoker.deps)) {
+ deps += invoker.deps
+ }
public_configs = [ ":$config_name" ]
gen_args = [
@@ -39,8 +46,7 @@
rebase_path("$root_gen_dir", root_build_dir),
]
input_args = [ "--inputs" ] + rebase_path(invoker.sources, root_build_dir)
- output_args = [ "--outputs" ] + rebase_path(outputs, root_build_dir)
- args = gen_args + input_args + output_args
+ args = gen_args + input_args + relative_args
metadata = {
perfetto_action_type_for_generator = [ "tp_tables" ]
@@ -56,7 +62,7 @@
deps = [ "$perfetto_root_path/python:trace_processor_table_generator" ]
outputs = [ "$target_gen_dir/$docs_name.json" ]
args = [ "--out" ] + rebase_path(outputs, root_build_dir) +
- rebase_path(invoker.sources, root_build_dir)
+ rebase_path(invoker.sources, root_build_dir) + relative_args
}
}
}
diff --git a/python/generators/trace_processor_table/public.py b/python/generators/trace_processor_table/public.py
index abd0aec..c8bdb0b 100644
--- a/python/generators/trace_processor_table/public.py
+++ b/python/generators/trace_processor_table/public.py
@@ -119,6 +119,8 @@
Representation of of a C++ table.
Attributes:
+ python_module: Path to the Python module this table is defined in. Always
+ pass __file__.
class_name: Name of the C++ table class.
sql_name: Name of the table in SQL.
columns: The columns in this table.
@@ -129,6 +131,7 @@
specified table.
wrapping_sql_view: See |WrappingSqlView|.
"""
+ python_module: str
class_name: str
sql_name: str
columns: List[Column]
diff --git a/python/generators/trace_processor_table/serialize.py b/python/generators/trace_processor_table/serialize.py
index 2636733..875b3de 100644
--- a/python/generators/trace_processor_table/serialize.py
+++ b/python/generators/trace_processor_table/serialize.py
@@ -19,6 +19,8 @@
from python.generators.trace_processor_table.public import ColumnFlag
from python.generators.trace_processor_table.util import ParsedTable
from python.generators.trace_processor_table.util import ParsedColumn
+from python.generators.trace_processor_table.util import parse_type
+from python.generators.trace_processor_table.util import typed_column_type
class ColumnSerializer:
@@ -30,8 +32,9 @@
self.col = self.parsed_col.column
self.name = self.col.name
self.flags = self.col.flags
- self.typed_column_type = table.typed_column_type(self.parsed_col)
- self.cpp_type = table.parse_type(self.col.type).cpp_type_with_optionality()
+ self.typed_column_type = typed_column_type(table.table, self.parsed_col)
+ self.cpp_type = parse_type(table.table,
+ self.col.type).cpp_type_with_optionality()
self.is_implicit_id = self.parsed_col.is_implicit_id
self.is_implicit_type = self.parsed_col.is_implicit_type
@@ -180,11 +183,11 @@
if self.is_implicit_id or self.is_implicit_type:
return None
return f'''
- schema.columns.emplace_back(Table::Schema::Column{{
- "{self.name}", ColumnType::{self.name}::SqlValueType(), false,
- {str(ColumnFlag.SORTED in self.flags).lower()},
- {str(ColumnFlag.HIDDEN in self.flags).lower()},
- {str(ColumnFlag.SET_ID in self.flags).lower()}}});
+ schema.columns.emplace_back(Table::Schema::Column{{
+ "{self.name}", ColumnType::{self.name}::SqlValueType(), false,
+ {str(ColumnFlag.SORTED in self.flags).lower()},
+ {str(ColumnFlag.HIDDEN in self.flags).lower()},
+ {str(ColumnFlag.SET_ID in self.flags).lower()}}});
'''
def row_eq(self) -> Optional[str]:
@@ -192,6 +195,42 @@
return None
return f'ColumnType::{self.name}::Equals({self.name}, other.{self.name})'
+ def extend_parent_param(self) -> Optional[str]:
+ if self.is_implicit_id or self.is_implicit_type:
+ return None
+ if self.is_ancestor:
+ return None
+ return f'ColumnStorage<ColumnType::{self.name}::stored_type> {self.name}'
+
+ def extend_parent_param_arg(self) -> Optional[str]:
+ if self.is_implicit_id or self.is_implicit_type:
+ return None
+ if self.is_ancestor:
+ return None
+ return f'std::move({self.name})'
+
+ def static_assert_flags(self) -> Optional[str]:
+ if self.is_implicit_id or self.is_implicit_type:
+ return None
+ if self.is_ancestor:
+ return None
+ return f'''
+ static_assert(
+ Column::IsFlagsAndTypeValid<ColumnType::{self.name}::stored_type>(
+ ColumnFlag::{self.name}),
+ "Column type and flag combination is not valid");
+ '''
+
+ def extend_nullable_vector(self) -> Optional[str]:
+ if self.is_implicit_id or self.is_implicit_type:
+ return None
+ if self.is_ancestor:
+ return None
+ return f'''
+ PERFETTO_DCHECK({self.name}.size() == parent_overlay.size());
+ {self.name}_ = std::move({self.name});
+ '''
+
class TableSerializer(object):
"""Functions for seralizing a single Table into C++."""
@@ -317,6 +356,7 @@
explicit {self.table_name}(StringPool* pool{parent_param})
: macros_internal::MacroTable(pool, {parent_arg}),
{parent_init}{storage_init} {{
+ {self.foreach_col(ColumnSerializer.static_assert_flags)}
{olay}
{col_init}
}}
@@ -389,6 +429,60 @@
}};
'''
+ def extend(self) -> str:
+ if not self.table.parent:
+ return ''
+ params = self.foreach_col(
+ ColumnSerializer.extend_parent_param, delimiter='\n, ')
+ args = self.foreach_col(
+ ColumnSerializer.extend_parent_param_arg, delimiter=', ')
+ delim = ',' if params else ''
+ return f'''
+ static std::unique_ptr<Table> ExtendParent(
+ const {self.parent_class_name}& parent{delim}
+ {params}) {{
+ return std::unique_ptr<Table>(new {self.table_name}(
+ parent.string_pool(), parent, RowMap(0, parent.row_count()){delim}
+ {args}));
+ }}
+
+ static std::unique_ptr<Table> SelectAndExtendParent(
+ const {self.parent_class_name}& parent,
+ std::vector<{self.parent_class_name}::RowNumber> parent_overlay{delim}
+ {params}) {{
+ std::vector<uint32_t> prs_untyped(parent_overlay.size());
+ for (uint32_t i = 0; i < parent_overlay.size(); ++i) {{
+ prs_untyped[i] = parent_overlay[i].row_number();
+ }}
+ return std::unique_ptr<Table>(new {self.table_name}(
+ parent.string_pool(), parent, RowMap(std::move(prs_untyped)){delim}
+ {args}));
+ }}
+ '''
+
+ def extend_constructor(self) -> str:
+ if not self.table.parent:
+ return ''
+ params = self.foreach_col(
+ ColumnSerializer.extend_parent_param, delimiter='\n, ')
+ if params:
+ olay = 'uint32_t olay_idx = static_cast<uint32_t>(overlays_.size()) - 1;'
+ else:
+ olay = ''
+ return f'''
+ {self.table_name}(StringPool* pool,
+ const {self.parent_class_name}& parent,
+ const RowMap& parent_overlay{',' if params else ''}
+ {params})
+ : macros_internal::MacroTable(pool, parent, parent_overlay) {{
+ {self.foreach_col(ColumnSerializer.static_assert_flags)}
+ {self.foreach_col(ColumnSerializer.extend_nullable_vector)}
+
+ {olay}
+ {self.foreach_col(ColumnSerializer.column_init)}
+ }}
+ '''
+
def serialize(self) -> str:
return f'''
class {self.table_name} : public macros_internal::MacroTable {{
@@ -488,11 +582,14 @@
RowNumber(row_number)}};
}}
+ {self.extend().strip()}
+
{self.foreach_col(ColumnSerializer.accessor)}
{self.foreach_col(ColumnSerializer.mutable_accessor)}
private:
+ {self.extend_constructor().strip()}
{self.parent_field().strip()}
{self.foreach_col(ColumnSerializer.storage)}
}};
diff --git a/python/generators/trace_processor_table/util.py b/python/generators/trace_processor_table/util.py
index 015f02c..1f0dc0c 100644
--- a/python/generators/trace_processor_table/util.py
+++ b/python/generators/trace_processor_table/util.py
@@ -14,7 +14,8 @@
import dataclasses
from dataclasses import dataclass
-import runpy
+import importlib
+import sys
from typing import Dict
from typing import List
from typing import Set
@@ -92,71 +93,78 @@
table: Table
columns: List[ParsedColumn]
- input_path: str
- def parse_type(self, col_type: CppColumnType) -> ParsedType:
- """Parses a CppColumnType into its constiuent parts."""
- if isinstance(col_type, CppInt64):
- return ParsedType('int64_t')
- if isinstance(col_type, CppInt32):
- return ParsedType('int32_t')
- if isinstance(col_type, CppUint32):
- return ParsedType('uint32_t')
- if isinstance(col_type, CppDouble):
- return ParsedType('double')
- if isinstance(col_type, CppString):
- return ParsedType('StringPool::Id')
+def parse_type_with_cols(table: Table, cols: List[Column],
+ col_type: CppColumnType) -> ParsedType:
+ """Parses a CppColumnType into its constiuent parts."""
- if isinstance(col_type, Alias):
- col = next(c for c in self.columns
- if c.column.name == col_type.underlying_column)
- return ParsedType(
- self.parse_type(col.column.type).cpp_type,
- is_alias=True,
- alias_underlying_name=col.column.name)
+ if isinstance(col_type, CppInt64):
+ return ParsedType('int64_t')
+ if isinstance(col_type, CppInt32):
+ return ParsedType('int32_t')
+ if isinstance(col_type, CppUint32):
+ return ParsedType('uint32_t')
+ if isinstance(col_type, CppDouble):
+ return ParsedType('double')
+ if isinstance(col_type, CppString):
+ return ParsedType('StringPool::Id')
- if isinstance(col_type, CppTableId):
- return ParsedType(
- f'{col_type.table.class_name}::Id', id_table=col_type.table)
+ if isinstance(col_type, Alias):
+ col = next(c for c in cols if c.name == col_type.underlying_column)
+ return ParsedType(
+ parse_type(table, col.type).cpp_type,
+ is_alias=True,
+ alias_underlying_name=col.name)
- if isinstance(col_type, CppSelfTableId):
- return ParsedType(
- f'{self.table.class_name}::Id', is_self_id=True, id_table=self.table)
+ if isinstance(col_type, CppTableId):
+ return ParsedType(
+ f'{col_type.table.class_name}::Id', id_table=col_type.table)
- if isinstance(col_type, CppOptional):
- inner = self.parse_type(col_type.inner)
- assert not inner.is_optional, 'Nested optional not allowed'
- return dataclasses.replace(inner, is_optional=True)
+ if isinstance(col_type, CppSelfTableId):
+ return ParsedType(
+ f'{table.class_name}::Id', is_self_id=True, id_table=table)
- raise Exception(f'Unknown type {col_type}')
+ if isinstance(col_type, CppOptional):
+ inner = parse_type(table, col_type.inner)
+ assert not inner.is_optional, 'Nested optional not allowed'
+ return dataclasses.replace(inner, is_optional=True)
- def typed_column_type(self, col: ParsedColumn) -> str:
- """Returns the TypedColumn/IdColumn C++ type for a given column."""
+ raise Exception(f'Unknown type {col_type}')
- parsed = self.parse_type(col.column.type)
- if col.is_implicit_id:
- return f'IdColumn<{parsed.cpp_type}>'
- return f'TypedColumn<{parsed.cpp_type_with_optionality()}>'
- def find_table_deps(self) -> Set[str]:
- """Finds all the other table class names this table depends on.
+def parse_type(table: Table, col_type: CppColumnType) -> ParsedType:
+ """Parses a CppColumnType into its constiuent parts."""
+ return parse_type_with_cols(table, table.columns, col_type)
- By "depends", we mean this table in C++ would need the dependency to be
- defined (or included) before this table is defined."""
- deps: Set[str] = set()
- if self.table.parent:
- deps.add(self.table.parent.class_name)
- for c in self.table.columns:
- # Aliases cannot have dependencies so simply ignore them: trying to parse
- # them before adding implicit columns can cause issues.
- if isinstance(c.type, Alias):
- continue
- id_table = self.parse_type(c.type).id_table
- if id_table:
- deps.add(id_table.class_name)
- return deps
+def typed_column_type(table: Table, col: ParsedColumn) -> str:
+ """Returns the TypedColumn/IdColumn C++ type for a given column."""
+
+ parsed = parse_type(table, col.column.type)
+ if col.is_implicit_id:
+ return f'IdColumn<{parsed.cpp_type}>'
+ return f'TypedColumn<{parsed.cpp_type_with_optionality()}>'
+
+
+def find_table_deps(table: Table) -> List[Table]:
+ """Finds all the other table class names this table depends on.
+
+ By "depends", we mean this table in C++ would need the dependency to be
+ defined (or included) before this table is defined."""
+
+ deps: Dict[str, Table] = {}
+ if table.parent:
+ deps[table.parent.class_name] = table.parent
+ for c in table.columns:
+ # Aliases cannot have dependencies so simply ignore them: trying to parse
+ # them before adding implicit columns can cause issues.
+ if isinstance(c.type, Alias):
+ continue
+ id_table = parse_type(table, c.type).id_table
+ if id_table:
+ deps[id_table.class_name] = id_table
+ return list(deps.values())
def public_sql_name(table: Table) -> str:
@@ -165,10 +173,9 @@
wrapping_view = table.wrapping_sql_view
return wrapping_view.view_name if wrapping_view else table.sql_name
-def _create_implicit_columns_for_root(parsed: ParsedTable
- ) -> List[ParsedColumn]:
+
+def _create_implicit_columns_for_root(table: Table) -> List[ParsedColumn]:
"""Given a root table, returns the implicit id and type columns."""
- table = parsed.table
assert table.parent is None
sql_name = public_sql_name(table)
@@ -191,26 +198,25 @@
]
-def _topological_sort_tables(parsed: List[ParsedTable]) -> List[ParsedTable]:
+def _topological_sort_table_and_deps(parsed: List[Table]) -> List[Table]:
"""Topologically sorts a list of tables (i.e. dependenices appear earlier).
See [1] for information on a topological sort. We do this to allow
dependencies to be processed and appear ealier than their dependents.
[1] https://en.wikipedia.org/wiki/Topological_sorting"""
- table_to_parsed_table = {p.table.class_name: p for p in parsed}
visited: Set[str] = set()
- result: List[ParsedTable] = []
+ result: List[Table] = []
# Topological sorting is really just a DFS where we put the nodes in the list
# after any dependencies.
- def dfs(t: ParsedTable):
- if t.table.class_name in visited:
+ def dfs(t: Table):
+ if t.class_name in visited:
return
- visited.add(t.table.class_name)
+ visited.add(t.class_name)
- for dep in t.find_table_deps():
- dfs(table_to_parsed_table[dep])
+ for dep in find_table_deps(t):
+ dfs(dep)
result.append(t)
for p in parsed:
@@ -226,26 +232,27 @@
return ColumnDoc(doc=doc)
-def parse_tables_from_files(input_paths: List[str]) -> List[ParsedTable]:
+def parse_tables_from_modules(modules: List[str]) -> List[ParsedTable]:
"""Creates a list of tables with the associated paths."""
# Create a mapping from the table to a "parsed" version of the table.
+ tables: Dict[str, Table] = {}
+ for module in modules:
+ imported = importlib.import_module(module)
+ run_tables: List[Table] = imported.__dict__['ALL_TABLES']
+ for table in run_tables:
+ existing_table = tables.get(table.class_name)
+ assert not existing_table or existing_table == table
+ tables[table.class_name] = table
+
+ # Sort all the tables: note that this list may include tables which are not
+ # in |tables| dictionary due to dependencies on tables which live in a file
+ # not covered by |input_paths|.
+ sorted_tables = _topological_sort_table_and_deps(list(tables.values()))
+
parsed_tables: Dict[str, ParsedTable] = {}
- for in_path in input_paths:
- tables: List[Table] = runpy.run_path(in_path)['ALL_TABLES']
- for table in tables:
- existing_table = parsed_tables.get(table.class_name)
- assert not existing_table or existing_table.table == table
- parsed_tables[table.class_name] = ParsedTable(table, [], in_path)
-
- # Sort all the tables to be in order.
- sorted_tables = _topological_sort_tables(list(parsed_tables.values()))
-
- # Create the list of parsed columns
- for i, parsed in enumerate(sorted_tables):
+ for table in sorted_tables:
parsed_columns: List[ParsedColumn]
- table = parsed.table
-
if table.parent:
parsed_parent = parsed_tables[table.parent.class_name]
parsed_columns = [
@@ -253,13 +260,17 @@
for c in parsed_parent.columns
]
else:
- parsed_columns = _create_implicit_columns_for_root(parsed)
+ parsed_columns = _create_implicit_columns_for_root(table)
for c in table.columns:
doc = table.tabledoc.columns.get(c.name) if table.tabledoc else None
parsed_columns.append(ParsedColumn(c, _to_column_doc(doc)))
+ parsed_tables[table.class_name] = ParsedTable(table, parsed_columns)
- sorted_tables[i] = dataclasses.replace(parsed, columns=parsed_columns)
- parsed_tables[parsed.table.class_name] = sorted_tables[i]
-
- return sorted_tables
+ # Only return tables which come directly from |input_paths|. This stops us
+ # generating tables which were not requested.
+ return [
+ parsed_tables[p.class_name]
+ for p in sorted_tables
+ if p.class_name in tables
+ ]
diff --git a/src/trace_processor/prelude/table_functions/BUILD.gn b/src/trace_processor/prelude/table_functions/BUILD.gn
index 4f5ced3..1125c22 100644
--- a/src/trace_processor/prelude/table_functions/BUILD.gn
+++ b/src/trace_processor/prelude/table_functions/BUILD.gn
@@ -13,6 +13,7 @@
# limitations under the License.
import("../../../../gn/perfetto.gni")
+import("../../../../gn/perfetto_tp_tables.gni")
assert(enable_perfetto_trace_processor_sqlite)
@@ -44,6 +45,7 @@
"view.h",
]
deps = [
+ ":tables",
"../../../../gn:default_deps",
"../../../../gn:sqlite",
"../../../base",
@@ -59,6 +61,11 @@
]
}
+perfetto_tp_tables("tables") {
+ sources = [ "tables.py" ]
+ deps = [ "../../tables:tables_python" ]
+}
+
source_set("unittests") {
testonly = true
sources = [
@@ -71,6 +78,7 @@
]
deps = [
":table_functions",
+ ":tables",
"../../../../gn:default_deps",
"../../../../gn:gtest_and_gmock",
"../../containers",
diff --git a/src/trace_processor/prelude/table_functions/ancestor.cc b/src/trace_processor/prelude/table_functions/ancestor.cc
index c1656d9..9089b82 100644
--- a/src/trace_processor/prelude/table_functions/ancestor.cc
+++ b/src/trace_processor/prelude/table_functions/ancestor.cc
@@ -19,6 +19,7 @@
#include <memory>
#include <set>
+#include "src/trace_processor/prelude/table_functions/tables_py.h"
#include "src/trace_processor/sqlite/sqlite_utils.h"
#include "src/trace_processor/types/trace_processor_context.h"
#include "src/trace_processor/util/status_macros.h"
diff --git a/src/trace_processor/prelude/table_functions/ancestor.h b/src/trace_processor/prelude/table_functions/ancestor.h
index c625f16..755a482 100644
--- a/src/trace_processor/prelude/table_functions/ancestor.h
+++ b/src/trace_processor/prelude/table_functions/ancestor.h
@@ -16,40 +16,14 @@
#ifndef SRC_TRACE_PROCESSOR_PRELUDE_TABLE_FUNCTIONS_ANCESTOR_H_
#define SRC_TRACE_PROCESSOR_PRELUDE_TABLE_FUNCTIONS_ANCESTOR_H_
+
#include <optional>
#include "src/trace_processor/prelude/table_functions/table_function.h"
#include "src/trace_processor/storage/trace_storage.h"
-#include "src/trace_processor/tables/profiler_tables.h"
-#include "src/trace_processor/tables/slice_tables.h"
namespace perfetto {
namespace trace_processor {
-namespace tables {
-
-#define PERFETTO_TP_ANCESTOR_SLICE_TABLE_DEF(NAME, PARENT, C) \
- NAME(AncestorSliceTable, "ancestor_slice") \
- PARENT(PERFETTO_TP_SLICE_TABLE_DEF, C) \
- C(tables::SliceTable::Id, start_id, Column::Flag::kHidden)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_ANCESTOR_SLICE_TABLE_DEF);
-
-#define PERFETTO_TP_ANCESTOR_STACK_PROFILE_CALLSITE_TABLE_DEF(NAME, PARENT, C) \
- NAME(AncestorStackProfileCallsiteTable, \
- "experimental_ancestor_stack_profile_callsite") \
- PARENT(PERFETTO_TP_STACK_PROFILE_CALLSITE_DEF, C) \
- C(tables::StackProfileCallsiteTable::Id, start_id, Column::Flag::kHidden)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_ANCESTOR_STACK_PROFILE_CALLSITE_TABLE_DEF);
-
-#define PERFETTO_TP_ANCESTOR_SLICE_BY_STACK_TABLE_DEF(NAME, PARENT, C) \
- NAME(AncestorSliceByStackTable, "ancestor_slice_by_stack") \
- PARENT(PERFETTO_TP_SLICE_TABLE_DEF, C) \
- C(int64_t, start_stack_id, Column::Flag::kHidden)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_ANCESTOR_SLICE_BY_STACK_TABLE_DEF);
-
-} // namespace tables
class TraceProcessorContext;
diff --git a/src/trace_processor/prelude/table_functions/ancestor_unittest.cc b/src/trace_processor/prelude/table_functions/ancestor_unittest.cc
index 08fdad4..afc2d33 100644
--- a/src/trace_processor/prelude/table_functions/ancestor_unittest.cc
+++ b/src/trace_processor/prelude/table_functions/ancestor_unittest.cc
@@ -16,6 +16,7 @@
#include "src/trace_processor/prelude/table_functions/ancestor.h"
+#include "src/trace_processor/prelude/table_functions/tables_py.h"
#include "test/gtest_and_gmock.h"
namespace perfetto {
diff --git a/src/trace_processor/prelude/table_functions/connected_flow.h b/src/trace_processor/prelude/table_functions/connected_flow.h
index c05e25e..3ef3fc3 100644
--- a/src/trace_processor/prelude/table_functions/connected_flow.h
+++ b/src/trace_processor/prelude/table_functions/connected_flow.h
@@ -18,24 +18,14 @@
#define SRC_TRACE_PROCESSOR_PRELUDE_TABLE_FUNCTIONS_CONNECTED_FLOW_H_
#include "src/trace_processor/prelude/table_functions/table_function.h"
+#include "src/trace_processor/prelude/table_functions/tables_py.h"
#include "src/trace_processor/storage/trace_storage.h"
-#include "src/trace_processor/tables/flow_tables.h"
#include <queue>
#include <set>
namespace perfetto {
namespace trace_processor {
-namespace tables {
-
-#define PERFETTO_TP_CONNECTED_FLOW_TABLE_DEF(NAME, PARENT, C) \
- NAME(ConnectedFlowTable, "not_exposed_to_sql") \
- PARENT(PERFETTO_TP_FLOW_TABLE_DEF, C) \
- C(uint32_t, start_id, Column::Flag::kHidden)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_CONNECTED_FLOW_TABLE_DEF);
-
-} // namespace tables
class TraceProcessorContext;
diff --git a/src/trace_processor/prelude/table_functions/descendant.cc b/src/trace_processor/prelude/table_functions/descendant.cc
index 75cb8c9..382edf2 100644
--- a/src/trace_processor/prelude/table_functions/descendant.cc
+++ b/src/trace_processor/prelude/table_functions/descendant.cc
@@ -19,6 +19,7 @@
#include <memory>
#include <set>
+#include "src/trace_processor/prelude/table_functions/tables_py.h"
#include "src/trace_processor/sqlite/sqlite_utils.h"
#include "src/trace_processor/types/trace_processor_context.h"
#include "src/trace_processor/util/status_macros.h"
diff --git a/src/trace_processor/prelude/table_functions/descendant.h b/src/trace_processor/prelude/table_functions/descendant.h
index 8e93811..bffd9b5 100644
--- a/src/trace_processor/prelude/table_functions/descendant.h
+++ b/src/trace_processor/prelude/table_functions/descendant.h
@@ -24,23 +24,6 @@
namespace perfetto {
namespace trace_processor {
-namespace tables {
-
-#define PERFETTO_TP_DESCENDANT_SLICE_TABLE_DEF(NAME, PARENT, C) \
- NAME(DescendantSliceTable, "descendant_slice") \
- PARENT(PERFETTO_TP_SLICE_TABLE_DEF, C) \
- C(uint32_t, start_id, Column::Flag::kHidden)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_DESCENDANT_SLICE_TABLE_DEF);
-
-#define PERFETTO_TP_DESCENDANT_SLICE_BY_STACK_TABLE_DEF(NAME, PARENT, C) \
- NAME(DescendantSliceByStackTable, "descendant_slice_by_stack") \
- PARENT(PERFETTO_TP_SLICE_TABLE_DEF, C) \
- C(int64_t, start_stack_id, Column::Flag::kHidden)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_DESCENDANT_SLICE_BY_STACK_TABLE_DEF);
-
-} // namespace tables
class TraceProcessorContext;
diff --git a/src/trace_processor/prelude/table_functions/descendant_unittest.cc b/src/trace_processor/prelude/table_functions/descendant_unittest.cc
index f1ef1ca..67399d1 100644
--- a/src/trace_processor/prelude/table_functions/descendant_unittest.cc
+++ b/src/trace_processor/prelude/table_functions/descendant_unittest.cc
@@ -16,6 +16,7 @@
#include "src/trace_processor/prelude/table_functions/descendant.h"
+#include "src/trace_processor/prelude/table_functions/tables_py.h"
#include "test/gtest_and_gmock.h"
namespace perfetto {
diff --git a/src/trace_processor/prelude/table_functions/experimental_annotated_stack.cc b/src/trace_processor/prelude/table_functions/experimental_annotated_stack.cc
index 8198376..09363f2 100644
--- a/src/trace_processor/prelude/table_functions/experimental_annotated_stack.cc
+++ b/src/trace_processor/prelude/table_functions/experimental_annotated_stack.cc
@@ -19,24 +19,15 @@
#include <optional>
#include "perfetto/ext/base/string_utils.h"
+#include "src/trace_processor/prelude/table_functions/tables_py.h"
#include "src/trace_processor/sqlite/sqlite_utils.h"
#include "src/trace_processor/storage/trace_storage.h"
-#include "src/trace_processor/tables/profiler_tables.h"
#include "src/trace_processor/types/trace_processor_context.h"
namespace perfetto {
namespace trace_processor {
namespace tables {
-#define PERFETTO_TP_ANNOTATED_CALLSTACK_TABLE_DEF(NAME, PARENT, C) \
- NAME(ExperimentalAnnotatedCallstackTable, \
- "experimental_annotated_callstack") \
- PARENT(PERFETTO_TP_STACK_PROFILE_CALLSITE_DEF, C) \
- C(StringId, annotation) \
- C(tables::StackProfileCallsiteTable::Id, start_id, Column::Flag::kHidden)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_ANNOTATED_CALLSTACK_TABLE_DEF);
-
ExperimentalAnnotatedCallstackTable::~ExperimentalAnnotatedCallstackTable() =
default;
diff --git a/src/trace_processor/prelude/table_functions/experimental_counter_dur.cc b/src/trace_processor/prelude/table_functions/experimental_counter_dur.cc
index 3513c89..a7d9814 100644
--- a/src/trace_processor/prelude/table_functions/experimental_counter_dur.cc
+++ b/src/trace_processor/prelude/table_functions/experimental_counter_dur.cc
@@ -16,20 +16,12 @@
#include "src/trace_processor/prelude/table_functions/experimental_counter_dur.h"
-#include "src/trace_processor/tables/counter_tables.h"
+#include "src/trace_processor/prelude/table_functions/tables_py.h"
namespace perfetto {
namespace trace_processor {
namespace tables {
-#define PERFETTO_TP_COUNTER_DUR_TABLE_DEF(NAME, PARENT, C) \
- NAME(ExperimentalCounterDurTable, "experimental_counter_dur") \
- PARENT(PERFETTO_TP_COUNTER_TABLE_DEF, C) \
- C(int64_t, dur) \
- C(double, delta)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_COUNTER_DUR_TABLE_DEF);
-
ExperimentalCounterDurTable::~ExperimentalCounterDurTable() = default;
} // namespace tables
diff --git a/src/trace_processor/prelude/table_functions/experimental_sched_upid.cc b/src/trace_processor/prelude/table_functions/experimental_sched_upid.cc
index 45a76ea..ba3a0c6 100644
--- a/src/trace_processor/prelude/table_functions/experimental_sched_upid.cc
+++ b/src/trace_processor/prelude/table_functions/experimental_sched_upid.cc
@@ -16,17 +16,14 @@
#include "src/trace_processor/prelude/table_functions/experimental_sched_upid.h"
+#include "src/trace_processor/prelude/table_functions/tables_py.h"
+
namespace perfetto {
namespace trace_processor {
namespace tables {
-#define PERFETTO_TP_SCHED_UPID_TABLE_DEF(NAME, PARENT, C) \
- NAME(ExperimentalSchedUpidTable, "experimental_sched_upid") \
- PARENT(PERFETTO_TP_SCHED_SLICE_TABLE_DEF, C) \
- C(std::optional<UniquePid>, upid)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_SCHED_UPID_TABLE_DEF);
ExperimentalSchedUpidTable::~ExperimentalSchedUpidTable() = default;
+
} // namespace tables
ExperimentalSchedUpid::ExperimentalSchedUpid(
diff --git a/src/trace_processor/prelude/table_functions/experimental_slice_layout.cc b/src/trace_processor/prelude/table_functions/experimental_slice_layout.cc
index e544dbb..d6276dc 100644
--- a/src/trace_processor/prelude/table_functions/experimental_slice_layout.cc
+++ b/src/trace_processor/prelude/table_functions/experimental_slice_layout.cc
@@ -20,11 +20,13 @@
#include "perfetto/ext/base/string_splitter.h"
#include "perfetto/ext/base/string_utils.h"
+#include "src/trace_processor/prelude/table_functions/tables_py.h"
#include "src/trace_processor/sqlite/sqlite_utils.h"
namespace perfetto {
namespace trace_processor {
namespace tables {
+
ExperimentalSliceLayoutTable::~ExperimentalSliceLayoutTable() = default;
}
diff --git a/src/trace_processor/prelude/table_functions/experimental_slice_layout.h b/src/trace_processor/prelude/table_functions/experimental_slice_layout.h
index 19af803..3aa61bb 100644
--- a/src/trace_processor/prelude/table_functions/experimental_slice_layout.h
+++ b/src/trace_processor/prelude/table_functions/experimental_slice_layout.h
@@ -25,18 +25,6 @@
namespace perfetto {
namespace trace_processor {
-namespace tables {
-
-#define PERFETTO_TP_SLICE_LAYOUT_TABLE_DEF(NAME, PARENT, C) \
- NAME(ExperimentalSliceLayoutTable, "experimental_slice_layout") \
- PARENT(PERFETTO_TP_SLICE_TABLE_DEF, C) \
- C(uint32_t, layout_depth) \
- C(StringPool::Id, filter_track_ids, Column::kHidden)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_SLICE_LAYOUT_TABLE_DEF);
-
-} // namespace tables
-
class ExperimentalSliceLayout : public TableFunction {
public:
ExperimentalSliceLayout(StringPool* string_pool,
diff --git a/src/trace_processor/prelude/table_functions/experimental_slice_layout_unittest.cc b/src/trace_processor/prelude/table_functions/experimental_slice_layout_unittest.cc
index 43c986d..164dfbb 100644
--- a/src/trace_processor/prelude/table_functions/experimental_slice_layout_unittest.cc
+++ b/src/trace_processor/prelude/table_functions/experimental_slice_layout_unittest.cc
@@ -19,6 +19,7 @@
#include <algorithm>
#include "src/trace_processor/containers/bit_vector.h"
+#include "src/trace_processor/prelude/table_functions/tables_py.h"
#include "test/gtest_and_gmock.h"
namespace perfetto {
diff --git a/src/trace_processor/prelude/table_functions/tables.py b/src/trace_processor/prelude/table_functions/tables.py
new file mode 100644
index 0000000..4ffc526
--- /dev/null
+++ b/src/trace_processor/prelude/table_functions/tables.py
@@ -0,0 +1,166 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Contains tables for finding ancestor events."""
+
+from python.generators.trace_processor_table.public import Column as C
+from python.generators.trace_processor_table.public import ColumnFlag
+from python.generators.trace_processor_table.public import CppDouble
+from python.generators.trace_processor_table.public import CppInt64
+from python.generators.trace_processor_table.public import CppOptional
+from python.generators.trace_processor_table.public import CppString
+from python.generators.trace_processor_table.public import CppTableId
+from python.generators.trace_processor_table.public import CppUint32
+from python.generators.trace_processor_table.public import Table
+
+from src.trace_processor.tables.counter_tables import COUNTER_TABLE
+from src.trace_processor.tables.flow_tables import FLOW_TABLE
+from src.trace_processor.tables.metadata_tables import PROCESS_TABLE
+from src.trace_processor.tables.profiler_tables import STACK_PROFILE_CALLSITE_TABLE
+from src.trace_processor.tables.slice_tables import SLICE_TABLE
+from src.trace_processor.tables.slice_tables import SCHED_SLICE_TABLE
+
+ANCESTOR_SLICE_TABLE = Table(
+ python_module=__file__,
+ class_name="AncestorSliceTable",
+ sql_name="ancestor_slice",
+ columns=[
+ C("start_id", CppTableId(SLICE_TABLE), flags=ColumnFlag.HIDDEN),
+ ],
+ parent=SLICE_TABLE)
+
+ANCESTOR_SLICE_BY_STACK_TABLE = Table(
+ python_module=__file__,
+ class_name="AncestorSliceByStackTable",
+ sql_name="ancestor_slice_by_stack",
+ columns=[
+ C("start_stack_id", CppInt64(), flags=ColumnFlag.HIDDEN),
+ ],
+ parent=SLICE_TABLE)
+
+ANCESTOR_STACK_PROFILE_CALLSITE_TABLE = Table(
+ python_module=__file__,
+ class_name="AncestorStackProfileCallsiteTable",
+ sql_name="experimental_ancestor_stack_profile_callsite",
+ columns=[
+ C("start_id",
+ CppTableId(STACK_PROFILE_CALLSITE_TABLE),
+ flags=ColumnFlag.HIDDEN),
+ ],
+ parent=STACK_PROFILE_CALLSITE_TABLE)
+
+CONNECTED_FLOW_TABLE = Table(
+ python_module=__file__,
+ class_name="ConnectedFlowTable",
+ sql_name="not_exposed_to_sql",
+ columns=[
+ C("start_id", CppTableId(SLICE_TABLE), flags=ColumnFlag.HIDDEN),
+ ],
+ parent=FLOW_TABLE)
+
+DESCENDANT_SLICE_TABLE = Table(
+ python_module=__file__,
+ class_name="DescendantSliceTable",
+ sql_name="descendant_slice",
+ columns=[
+ C("start_id", CppTableId(SLICE_TABLE), flags=ColumnFlag.HIDDEN),
+ ],
+ parent=SLICE_TABLE)
+
+DESCENDANT_SLICE_BY_STACK_TABLE = Table(
+ python_module=__file__,
+ class_name="DescendantSliceByStackTable",
+ sql_name="descendant_slice_by_stack",
+ columns=[
+ C("start_stack_id", CppInt64(), flags=ColumnFlag.HIDDEN),
+ ],
+ parent=SLICE_TABLE)
+
+EXPERIMENTAL_ANNOTATED_CALLSTACK_TABLE = Table(
+ python_module=__file__,
+ class_name="ExperimentalAnnotatedCallstackTable",
+ sql_name="experimental_annotated_callstack",
+ columns=[
+ C("annotation", CppString()),
+ C("start_id",
+ CppTableId(STACK_PROFILE_CALLSITE_TABLE),
+ flags=ColumnFlag.HIDDEN),
+ ],
+ parent=STACK_PROFILE_CALLSITE_TABLE)
+
+EXPERIMENTAL_ANNOTATED_CALLSTACK_TABLE = Table(
+ python_module=__file__,
+ class_name="ExperimentalAnnotatedCallstackTable",
+ sql_name="experimental_annotated_callstack",
+ columns=[
+ C("annotation", CppString()),
+ C("start_id",
+ CppTableId(STACK_PROFILE_CALLSITE_TABLE),
+ flags=ColumnFlag.HIDDEN),
+ ],
+ parent=STACK_PROFILE_CALLSITE_TABLE)
+
+EXPERIMENTAL_ANNOTATED_CALLSTACK_TABLE = Table(
+ python_module=__file__,
+ class_name="ExperimentalAnnotatedCallstackTable",
+ sql_name="experimental_annotated_callstack",
+ columns=[
+ C("annotation", CppString()),
+ C("start_id",
+ CppTableId(STACK_PROFILE_CALLSITE_TABLE),
+ flags=ColumnFlag.HIDDEN),
+ ],
+ parent=STACK_PROFILE_CALLSITE_TABLE)
+
+EXPERIMENTAL_COUNTER_DUR_TABLE = Table(
+ python_module=__file__,
+ class_name="ExperimentalCounterDurTable",
+ sql_name="experimental_counter_dur",
+ columns=[
+ C("dur", CppInt64()),
+ C("delta", CppDouble()),
+ ],
+ parent=COUNTER_TABLE)
+
+EXPERIMENTAL_SCHED_UPID_TABLE = Table(
+ python_module=__file__,
+ class_name="ExperimentalSchedUpidTable",
+ sql_name="experimental_sched_upid",
+ columns=[
+ C("upid", CppOptional(CppTableId(PROCESS_TABLE))),
+ ],
+ parent=SCHED_SLICE_TABLE)
+
+EXPERIMENTAL_SLICE_LAYOUT_TABLE = Table(
+ python_module=__file__,
+ class_name="ExperimentalSliceLayoutTable",
+ sql_name="experimental_slice_layout",
+ columns=[
+ C("layout_depth", CppUint32()),
+ C("filter_track_ids", CppString(), flags=ColumnFlag.HIDDEN),
+ ],
+ parent=SLICE_TABLE)
+
+# Keep this list sorted.
+ALL_TABLES = [
+ ANCESTOR_SLICE_BY_STACK_TABLE,
+ ANCESTOR_SLICE_TABLE,
+ ANCESTOR_STACK_PROFILE_CALLSITE_TABLE,
+ CONNECTED_FLOW_TABLE,
+ DESCENDANT_SLICE_BY_STACK_TABLE,
+ DESCENDANT_SLICE_TABLE,
+ EXPERIMENTAL_ANNOTATED_CALLSTACK_TABLE,
+ EXPERIMENTAL_COUNTER_DUR_TABLE,
+ EXPERIMENTAL_SCHED_UPID_TABLE,
+ EXPERIMENTAL_SLICE_LAYOUT_TABLE,
+]
diff --git a/src/trace_processor/tables/BUILD.gn b/src/trace_processor/tables/BUILD.gn
index 83145a4..ef39e08 100644
--- a/src/trace_processor/tables/BUILD.gn
+++ b/src/trace_processor/tables/BUILD.gn
@@ -32,11 +32,8 @@
source_set("tables") {
sources = [
- "counter_tables.h",
- "flow_tables.h",
"macros.h",
"macros_internal.h",
- "profiler_tables.h",
"slice_tables.h",
"table_destructors.cc",
]
diff --git a/src/trace_processor/tables/android_tables.py b/src/trace_processor/tables/android_tables.py
index b77afcb..03dff07 100644
--- a/src/trace_processor/tables/android_tables.py
+++ b/src/trace_processor/tables/android_tables.py
@@ -28,6 +28,7 @@
from src.trace_processor.tables.metadata_tables import THREAD_TABLE
ANDROID_LOG_TABLE = Table(
+ python_module=__file__,
class_name="AndroidLogTable",
sql_name="android_logs",
columns=[
@@ -54,6 +55,7 @@
}))
ANDROID_GAME_INTERVENTION_LIST_TABLE = Table(
+ python_module=__file__,
class_name='AndroidGameInterventionListTable',
sql_name='android_game_intervention_list',
columns=[
@@ -126,6 +128,7 @@
}))
ANDROID_DUMPSTATE_TABLE = Table(
+ python_module=__file__,
class_name='AndroidDumpstateTable',
sql_name='android_dumpstate',
columns=[
diff --git a/src/trace_processor/tables/counter_tables.h b/src/trace_processor/tables/counter_tables.h
deleted file mode 100644
index 69668b2..0000000
--- a/src/trace_processor/tables/counter_tables.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_TABLES_COUNTER_TABLES_H_
-#define SRC_TRACE_PROCESSOR_TABLES_COUNTER_TABLES_H_
-
-#include "src/trace_processor/tables/macros.h"
-#include "src/trace_processor/tables/track_tables_py.h"
-
-namespace perfetto {
-namespace trace_processor {
-namespace tables {
-
-// @tablegroup Events
-// @param arg_set_id {@joinable args.arg_set_id}
-#define PERFETTO_TP_COUNTER_TABLE_DEF(NAME, PARENT, C) \
- NAME(CounterTable, "counter") \
- PERFETTO_TP_ROOT_TABLE(PARENT, C) \
- C(int64_t, ts, Column::Flag::kSorted) \
- C(CounterTrackTable::Id, track_id) \
- C(double, value) \
- C(std::optional<uint32_t>, arg_set_id)
-
-} // namespace tables
-} // namespace trace_processor
-} // namespace perfetto
-
-#endif // SRC_TRACE_PROCESSOR_TABLES_COUNTER_TABLES_H_
diff --git a/src/trace_processor/tables/counter_tables.py b/src/trace_processor/tables/counter_tables.py
index 1dd6495..e882452 100644
--- a/src/trace_processor/tables/counter_tables.py
+++ b/src/trace_processor/tables/counter_tables.py
@@ -26,6 +26,7 @@
from src.trace_processor.tables.track_tables import COUNTER_TRACK_TABLE
COUNTER_TABLE = Table(
+ python_module=__file__,
class_name='CounterTable',
sql_name='counter',
columns=[
diff --git a/src/trace_processor/tables/flow_tables.h b/src/trace_processor/tables/flow_tables.h
deleted file mode 100644
index a00ee89..0000000
--- a/src/trace_processor/tables/flow_tables.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_TABLES_FLOW_TABLES_H_
-#define SRC_TRACE_PROCESSOR_TABLES_FLOW_TABLES_H_
-
-#include "src/trace_processor/tables/macros.h"
-#include "src/trace_processor/tables/slice_tables.h"
-
-namespace perfetto {
-namespace trace_processor {
-namespace tables {
-
-// @param arg_set_id {@joinable args.arg_set_id}
-#define PERFETTO_TP_FLOW_TABLE_DEF(NAME, PARENT, C) \
- NAME(FlowTable, "flow") \
- PERFETTO_TP_ROOT_TABLE(PARENT, C) \
- C(SliceTable::Id, slice_out) \
- C(SliceTable::Id, slice_in) \
- C(uint32_t, arg_set_id)
-
-} // namespace tables
-} // namespace trace_processor
-} // namespace perfetto
-
-#endif // SRC_TRACE_PROCESSOR_TABLES_FLOW_TABLES_H_
diff --git a/src/trace_processor/tables/flow_tables.py b/src/trace_processor/tables/flow_tables.py
index 0491a31..df0ae4c 100644
--- a/src/trace_processor/tables/flow_tables.py
+++ b/src/trace_processor/tables/flow_tables.py
@@ -22,6 +22,7 @@
from src.trace_processor.tables.slice_tables import SLICE_TABLE
FLOW_TABLE = Table(
+ python_module=__file__,
class_name='FlowTable',
sql_name='flow',
columns=[
diff --git a/src/trace_processor/tables/memory_tables.py b/src/trace_processor/tables/memory_tables.py
index 65263f8..f270aa7 100644
--- a/src/trace_processor/tables/memory_tables.py
+++ b/src/trace_processor/tables/memory_tables.py
@@ -26,6 +26,7 @@
from src.trace_processor.tables.track_tables import TRACK_TABLE
MEMORY_SNAPSHOT_TABLE = Table(
+ python_module=__file__,
class_name='MemorySnapshotTable',
sql_name='memory_snapshot',
columns=[
@@ -43,6 +44,7 @@
}))
PROCESS_MEMORY_SNAPSHOT_TABLE = Table(
+ python_module=__file__,
class_name='ProcessMemorySnapshotTable',
sql_name='process_memory_snapshot',
columns=[
@@ -58,6 +60,7 @@
}))
MEMORY_SNAPSHOT_NODE_TABLE = Table(
+ python_module=__file__,
class_name='MemorySnapshotNodeTable',
sql_name='memory_snapshot_node',
columns=[
@@ -81,6 +84,7 @@
}))
MEMORY_SNAPSHOT_EDGE_TABLE = Table(
+ python_module=__file__,
class_name='MemorySnapshotEdgeTable',
sql_name='memory_snapshot_edge',
columns=[
diff --git a/src/trace_processor/tables/metadata_tables.py b/src/trace_processor/tables/metadata_tables.py
index ee9acca..0219aa9 100644
--- a/src/trace_processor/tables/metadata_tables.py
+++ b/src/trace_processor/tables/metadata_tables.py
@@ -29,6 +29,7 @@
from python.generators.trace_processor_table.public import WrappingSqlView
PROCESS_TABLE = Table(
+ python_module=__file__,
class_name='ProcessTable',
sql_name='internal_process',
columns=[
@@ -100,6 +101,7 @@
}))
THREAD_TABLE = Table(
+ python_module=__file__,
class_name='ThreadTable',
sql_name='internal_thread',
columns=[
@@ -159,6 +161,7 @@
}))
RAW_TABLE = Table(
+ python_module=__file__,
class_name='RawTable',
sql_name='raw',
columns=[
@@ -194,6 +197,7 @@
}))
FTRACE_EVENT_TABLE = Table(
+ python_module=__file__,
class_name='FtraceEventTable',
sql_name='ftrace_event',
parent=RAW_TABLE,
@@ -209,6 +213,7 @@
columns={}))
ARG_TABLE = Table(
+ python_module=__file__,
class_name='ArgTable',
sql_name='internal_args',
columns=[
@@ -235,6 +240,7 @@
}))
METADATA_TABLE = Table(
+ python_module=__file__,
class_name='MetadataTable',
sql_name='metadata',
columns=[
@@ -254,6 +260,7 @@
}))
FILEDESCRIPTOR_TABLE = Table(
+ python_module=__file__,
class_name='FiledescriptorTable',
sql_name='filedescriptor',
columns=[
@@ -290,6 +297,7 @@
}))
EXP_MISSING_CHROME_PROC_TABLE = Table(
+ python_module=__file__,
class_name='ExpMissingChromeProcTable',
sql_name='experimental_missing_chrome_processes',
columns=[
@@ -307,6 +315,7 @@
}))
CPU_TABLE = Table(
+ python_module=__file__,
class_name='CpuTable',
sql_name='cpu',
columns=[
@@ -327,6 +336,7 @@
}))
CPU_FREQ_TABLE = Table(
+ python_module=__file__,
class_name='CpuFreqTable',
sql_name='cpu_freq',
columns=[
@@ -340,6 +350,7 @@
}))
CLOCK_SNAPSHOT_TABLE = Table(
+ python_module=__file__,
class_name='ClockSnapshotTable',
sql_name='clock_snapshot',
columns=[
diff --git a/src/trace_processor/tables/profiler_tables.h b/src/trace_processor/tables/profiler_tables.h
deleted file mode 100644
index f0e84b2..0000000
--- a/src/trace_processor/tables/profiler_tables.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_TABLES_PROFILER_TABLES_H_
-#define SRC_TRACE_PROCESSOR_TABLES_PROFILER_TABLES_H_
-
-#include "src/trace_processor/tables/macros.h"
-#include "src/trace_processor/tables/track_tables_py.h"
-
-namespace perfetto {
-namespace trace_processor {
-namespace tables {
-
-// A callsite. This is a list of frames that were on the stack.
-// This is generated by the stack profilers: heapprofd and traced_perf.
-// @param depth distance from the bottom-most frame of the callstack.
-// @param parent_id parent frame on the callstack. NULL for the bottom-most.
-// @param frame_id frame at this position in the callstack.
-// @tablegroup Callstack profilers
-#define PERFETTO_TP_STACK_PROFILE_CALLSITE_DEF(NAME, PARENT, C) \
- NAME(StackProfileCallsiteTable, "stack_profile_callsite") \
- PERFETTO_TP_ROOT_TABLE(PARENT, C) \
- C(uint32_t, depth) \
- C(std::optional<StackProfileCallsiteTable::Id>, parent_id) \
- C(StackProfileFrameTable::Id, frame_id)
-
-} // namespace tables
-} // namespace trace_processor
-} // namespace perfetto
-
-#endif // SRC_TRACE_PROCESSOR_TABLES_PROFILER_TABLES_H_
diff --git a/src/trace_processor/tables/profiler_tables.py b/src/trace_processor/tables/profiler_tables.py
index d428009..c712adf 100644
--- a/src/trace_processor/tables/profiler_tables.py
+++ b/src/trace_processor/tables/profiler_tables.py
@@ -28,6 +28,7 @@
from src.trace_processor.tables.track_tables import TRACK_TABLE
PROFILER_SMAPS_TABLE = Table(
+ python_module=__file__,
class_name='ProfilerSmapsTable',
sql_name='profiler_smaps',
columns=[
@@ -94,6 +95,7 @@
}))
PACKAGE_LIST_TABLE = Table(
+ python_module=__file__,
class_name='PackageListTable',
sql_name='package_list',
columns=[
@@ -123,6 +125,7 @@
}))
STACK_PROFILE_MAPPING_TABLE = Table(
+ python_module=__file__,
class_name='StackProfileMappingTable',
sql_name='stack_profile_mapping',
columns=[
@@ -151,6 +154,7 @@
}))
STACK_PROFILE_FRAME_TABLE = Table(
+ python_module=__file__,
class_name='StackProfileFrameTable',
sql_name='stack_profile_frame',
columns=[
@@ -181,6 +185,7 @@
}))
STACK_PROFILE_CALLSITE_TABLE = Table(
+ python_module=__file__,
class_name='StackProfileCallsiteTable',
sql_name='stack_profile_callsite',
columns=[
@@ -204,6 +209,7 @@
}))
STACK_SAMPLE_TABLE = Table(
+ python_module=__file__,
class_name='StackSampleTable',
sql_name='stack_sample',
columns=[
@@ -221,6 +227,7 @@
}))
CPU_PROFILE_STACK_SAMPLE_TABLE = Table(
+ python_module=__file__,
class_name='CpuProfileStackSampleTable',
sql_name='cpu_profile_stack_sample',
columns=[
@@ -239,6 +246,7 @@
}))
PERF_SAMPLE_TABLE = Table(
+ python_module=__file__,
class_name='PerfSampleTable',
sql_name='perf_sample',
columns=[
@@ -278,6 +286,7 @@
}))
SYMBOL_TABLE = Table(
+ python_module=__file__,
class_name='SymbolTable',
sql_name='stack_profile_symbol',
columns=[
@@ -323,6 +332,7 @@
}))
HEAP_PROFILE_ALLOCATION_TABLE = Table(
+ python_module=__file__,
class_name='HeapProfileAllocationTable',
sql_name='heap_profile_allocation',
columns=[
@@ -367,6 +377,7 @@
}))
EXPERIMENTAL_FLAMEGRAPH_NODES_TABLE = Table(
+ python_module=__file__,
class_name='ExperimentalFlamegraphNodesTable',
sql_name='experimental_flamegraph_nodes',
columns=[
@@ -421,6 +432,7 @@
}))
HEAP_GRAPH_CLASS_TABLE = Table(
+ python_module=__file__,
class_name='HeapGraphClassTable',
sql_name='heap_graph_class',
columns=[
@@ -455,6 +467,7 @@
}))
HEAP_GRAPH_OBJECT_TABLE = Table(
+ python_module=__file__,
class_name='HeapGraphObjectTable',
sql_name='heap_graph_object',
columns=[
@@ -500,6 +513,7 @@
}))
HEAP_GRAPH_REFERENCE_TABLE = Table(
+ python_module=__file__,
class_name='HeapGraphReferenceTable',
sql_name='heap_graph_reference',
columns=[
@@ -537,6 +551,7 @@
}))
VULKAN_MEMORY_ALLOCATIONS_TABLE = Table(
+ python_module=__file__,
class_name='VulkanMemoryAllocationsTable',
sql_name='vulkan_memory_allocations',
columns=[
@@ -576,6 +591,7 @@
}))
GPU_COUNTER_GROUP_TABLE = Table(
+ python_module=__file__,
class_name='GpuCounterGroupTable',
sql_name='gpu_counter_group',
columns=[
diff --git a/src/trace_processor/tables/py_tables_unittest.cc b/src/trace_processor/tables/py_tables_unittest.cc
index 9c0b72b..c563a40 100644
--- a/src/trace_processor/tables/py_tables_unittest.cc
+++ b/src/trace_processor/tables/py_tables_unittest.cc
@@ -15,6 +15,7 @@
*/
#include "src/trace_processor/db/column.h"
+#include "src/trace_processor/db/column_storage.h"
#include "src/trace_processor/tables/py_tables_unittest_py.h"
#include "test/gtest_and_gmock.h"
@@ -165,6 +166,59 @@
ASSERT_EQ(slice_.dur()[1], 20);
}
+TEST_F(PyTablesUnittest, Extend) {
+ event_.Insert(TestEventTable::Row(50, 0));
+ event_.Insert(TestEventTable::Row(100, 1));
+ event_.Insert(TestEventTable::Row(150, 2));
+
+ ColumnStorage<int64_t> dur;
+ dur.Append(512);
+ dur.Append(1024);
+ dur.Append(2048);
+
+ auto slice_ext = TestSliceTable::ExtendParent(event_, std::move(dur));
+ ASSERT_EQ(slice_ext->row_count(), 3u);
+ ASSERT_EQ(
+ slice_ext->columns()[TestSliceTable::ColumnIndex::ts].Get(0).AsLong(),
+ 50);
+ ASSERT_EQ(
+ slice_ext->columns()[TestSliceTable::ColumnIndex::dur].Get(0).AsLong(),
+ 512);
+ ASSERT_EQ(
+ slice_ext->columns()[TestSliceTable::ColumnIndex::ts].Get(1).AsLong(),
+ 100);
+ ASSERT_EQ(
+ slice_ext->columns()[TestSliceTable::ColumnIndex::dur].Get(1).AsLong(),
+ 1024);
+ ASSERT_EQ(
+ slice_ext->columns()[TestSliceTable::ColumnIndex::ts].Get(2).AsLong(),
+ 150);
+ ASSERT_EQ(
+ slice_ext->columns()[TestSliceTable::ColumnIndex::dur].Get(2).AsLong(),
+ 2048);
+}
+
+TEST_F(PyTablesUnittest, SelectAndExtend) {
+ event_.Insert(TestEventTable::Row(50, 0));
+ event_.Insert(TestEventTable::Row(100, 1));
+ event_.Insert(TestEventTable::Row(150, 2));
+
+ std::vector<TestEventTable::RowNumber> rows;
+ rows.emplace_back(TestEventTable::RowNumber(1));
+ ColumnStorage<int64_t> dur;
+ dur.Append(1024);
+
+ auto slice_ext = TestSliceTable::SelectAndExtendParent(
+ event_, std::move(rows), std::move(dur));
+ ASSERT_EQ(slice_ext->row_count(), 1u);
+ ASSERT_EQ(
+ slice_ext->columns()[TestSliceTable::ColumnIndex::ts].Get(0).AsLong(),
+ 100);
+ ASSERT_EQ(
+ slice_ext->columns()[TestSliceTable::ColumnIndex::dur].Get(0).AsLong(),
+ 1024);
+}
+
} // namespace
} // namespace tables
} // namespace trace_processor
diff --git a/src/trace_processor/tables/py_tables_unittest.py b/src/trace_processor/tables/py_tables_unittest.py
index ba7b824..99f69dd 100644
--- a/src/trace_processor/tables/py_tables_unittest.py
+++ b/src/trace_processor/tables/py_tables_unittest.py
@@ -21,6 +21,7 @@
from python.generators.trace_processor_table.public import CppUint32
EVENT_TABLE = Table(
+ python_module=__file__,
class_name="TestEventTable",
sql_name="event",
columns=[
@@ -29,12 +30,14 @@
])
EVENT_CHILD_TABLE = Table(
+ python_module=__file__,
class_name="TestEventChildTable",
sql_name="event",
parent=EVENT_TABLE,
columns=[])
SLICE_TABLE = Table(
+ python_module=__file__,
class_name="TestSliceTable",
sql_name="slice",
parent=EVENT_TABLE,
@@ -43,6 +46,7 @@
])
ARGS_TABLE = Table(
+ python_module=__file__,
class_name="TestArgsTable",
sql_name="args",
columns=[
diff --git a/src/trace_processor/tables/slice_tables.h b/src/trace_processor/tables/slice_tables.h
index e33ae19..44f5ba9 100644
--- a/src/trace_processor/tables/slice_tables.h
+++ b/src/trace_processor/tables/slice_tables.h
@@ -42,16 +42,6 @@
C(std::optional<int64_t>, thread_instruction_count) \
C(std::optional<int64_t>, thread_instruction_delta)
-#define PERFETTO_TP_SCHED_SLICE_TABLE_DEF(NAME, PARENT, C) \
- NAME(SchedSliceTable, "sched_slice") \
- PERFETTO_TP_ROOT_TABLE(PARENT, C) \
- C(int64_t, ts, Column::Flag::kSorted) \
- C(int64_t, dur) \
- C(uint32_t, cpu) \
- C(uint32_t, utid) \
- C(StringPool::Id, end_state) \
- C(int32_t, priority)
-
} // namespace tables
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/tables/slice_tables.py b/src/trace_processor/tables/slice_tables.py
index 50b8c3e..22bd9b3 100644
--- a/src/trace_processor/tables/slice_tables.py
+++ b/src/trace_processor/tables/slice_tables.py
@@ -29,6 +29,7 @@
from src.trace_processor.tables.track_tables import TRACK_TABLE
SLICE_TABLE = Table(
+ python_module=__file__,
class_name='SliceTable',
sql_name='internal_slice',
columns=[
@@ -69,6 +70,7 @@
}))
SCHED_SLICE_TABLE = Table(
+ python_module=__file__,
class_name='SchedSliceTable',
sql_name='sched_slice',
columns=[
@@ -108,6 +110,7 @@
}))
THREAD_STATE_TABLE = Table(
+ python_module=__file__,
class_name='ThreadStateTable',
sql_name='thread_state',
columns=[
@@ -135,6 +138,7 @@
}))
GPU_SLICE_TABLE = Table(
+ python_module=__file__,
class_name='GpuSliceTable',
sql_name='gpu_slice',
columns=[
@@ -169,6 +173,7 @@
}))
GRAPHICS_FRAME_SLICE_TABLE = Table(
+ python_module=__file__,
class_name='GraphicsFrameSliceTable',
sql_name='frame_slice',
columns=[
@@ -191,6 +196,7 @@
}))
EXPECTED_FRAME_TIMELINE_SLICE_TABLE = Table(
+ python_module=__file__,
class_name='ExpectedFrameTimelineSliceTable',
sql_name='expected_frame_timeline_slice',
columns=[
@@ -211,6 +217,7 @@
}))
ACTUAL_FRAME_TIMELINE_SLICE_TABLE = Table(
+ python_module=__file__,
class_name='ActualFrameTimelineSliceTable',
sql_name='actual_frame_timeline_slice',
columns=[
@@ -243,6 +250,7 @@
}))
EXPERIMENTAL_FLAT_SLICE_TABLE = Table(
+ python_module=__file__,
class_name='ExperimentalFlatSliceTable',
sql_name='experimental_flat_slice',
columns=[
diff --git a/src/trace_processor/tables/trace_proto_tables.h b/src/trace_processor/tables/trace_proto_tables.h
deleted file mode 100644
index aa57b59..0000000
--- a/src/trace_processor/tables/trace_proto_tables.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_TABLES_TRACE_PROTO_TABLES_H_
-#define SRC_TRACE_PROCESSOR_TABLES_TRACE_PROTO_TABLES_H_
-
-#include "src/trace_processor/tables/macros.h"
-
-namespace perfetto {
-namespace trace_processor {
-namespace tables {
-
-// Experimental table, subject to arbitrary breaking changes.
-#define PERFETTO_TP_EXPERIMENTAL_PROTO_PATH_TABLE_DEF(NAME, PARENT, C) \
- NAME(ExperimentalProtoPathTable, "experimental_proto_path") \
- PERFETTO_TP_ROOT_TABLE(PARENT, C) \
- C(std::optional<ExperimentalProtoPathTable::Id>, parent_id) \
- C(StringPool::Id, field_type) \
- C(std::optional<StringPool::Id>, field_name) \
- C(std::optional<uint32_t>, arg_set_id)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_EXPERIMENTAL_PROTO_PATH_TABLE_DEF);
-
-#define PERFETTO_TP_EXPERIMENTAL_PROTO_CONTENT_TABLE_DEF(NAME, PARENT, C) \
- NAME(ExperimentalProtoContentTable, "experimental_proto_content") \
- PERFETTO_TP_ROOT_TABLE(PARENT, C) \
- C(StringPool::Id, path) \
- C(ExperimentalProtoPathTable::Id, path_id) \
- C(int64_t, total_size) \
- C(int64_t, size) \
- C(int64_t, count)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_EXPERIMENTAL_PROTO_CONTENT_TABLE_DEF);
-
-} // namespace tables
-} // namespace trace_processor
-} // namespace perfetto
-
-#endif // SRC_TRACE_PROCESSOR_TABLES_TRACE_PROTO_TABLES_H_
diff --git a/src/trace_processor/tables/trace_proto_tables.py b/src/trace_processor/tables/trace_proto_tables.py
index f6f5f9d..e9c9754 100644
--- a/src/trace_processor/tables/trace_proto_tables.py
+++ b/src/trace_processor/tables/trace_proto_tables.py
@@ -24,6 +24,7 @@
from python.generators.trace_processor_table.public import CppUint32
EXPERIMENTAL_PROTO_PATH_TABLE = Table(
+ python_module=__file__,
class_name='ExperimentalProtoPathTable',
sql_name='experimental_proto_path',
columns=[
@@ -45,6 +46,7 @@
}))
EXPERIMENTAL_PROTO_CONTENT_TABLE = Table(
+ python_module=__file__,
class_name='ExperimentalProtoContentTable',
sql_name='experimental_proto_content',
columns=[
diff --git a/src/trace_processor/tables/track_tables.py b/src/trace_processor/tables/track_tables.py
index bb5a0df..3cbce76 100644
--- a/src/trace_processor/tables/track_tables.py
+++ b/src/trace_processor/tables/track_tables.py
@@ -25,6 +25,7 @@
from python.generators.trace_processor_table.public import CppUint32
TRACK_TABLE = Table(
+ python_module=__file__,
class_name="TrackTable",
sql_name="track",
columns=[
@@ -62,6 +63,7 @@
}))
PROCESS_TRACK_TABLE = Table(
+ python_module=__file__,
class_name="ProcessTrackTable",
sql_name="process_track",
columns=[
@@ -81,6 +83,7 @@
}))
THREAD_TRACK_TABLE = Table(
+ python_module=__file__,
class_name='ThreadTrackTable',
sql_name='thread_track',
columns=[
@@ -101,6 +104,7 @@
}))
CPU_TRACK_TABLE = Table(
+ python_module=__file__,
class_name='CpuTrackTable',
sql_name='cpu_track',
columns=[
@@ -113,6 +117,7 @@
columns={'cpu': 'The CPU associated with this track'}))
GPU_TRACK_TABLE = Table(
+ python_module=__file__,
class_name='GpuTrackTable',
sql_name='gpu_track',
columns=[
@@ -134,6 +139,7 @@
}))
COUNTER_TRACK_TABLE = Table(
+ python_module=__file__,
class_name='CounterTrackTable',
sql_name='counter_track',
columns=[
@@ -156,6 +162,7 @@
}))
THREAD_COUNTER_TRACK_TABLE = Table(
+ python_module=__file__,
class_name='ThreadCounterTrackTable',
sql_name='thread_counter_track',
columns=[
@@ -174,6 +181,7 @@
}))
PROCESS_COUNTER_TRACK_TABLE = Table(
+ python_module=__file__,
class_name='ProcessCounterTrackTable',
sql_name='process_counter_track',
columns=[
@@ -193,6 +201,7 @@
}))
CPU_COUNTER_TRACK_TABLE = Table(
+ python_module=__file__,
class_name='CpuCounterTrackTable',
sql_name='cpu_counter_track',
columns=[
@@ -205,6 +214,7 @@
columns={'cpu': 'The CPU this track is associated with'}))
IRQ_COUNTER_TRACK_TABLE = Table(
+ python_module=__file__,
class_name='IrqCounterTrackTable',
sql_name='irq_counter_track',
columns=[
@@ -217,6 +227,7 @@
columns={'irq': 'The identifier for the hardirq.'}))
SOFTIRQ_COUNTER_TRACK_TABLE = Table(
+ python_module=__file__,
class_name='SoftirqCounterTrackTable',
sql_name='softirq_counter_track',
columns=[
@@ -229,6 +240,7 @@
columns={'softirq': 'The identifier for the softirq.'}))
GPU_COUNTER_TRACK_TABLE = Table(
+ python_module=__file__,
class_name='GpuCounterTrackTable',
sql_name='gpu_counter_track',
columns=[
@@ -241,6 +253,7 @@
columns={'gpu_id': 'The identifier for the GPU.'}))
PERF_COUNTER_TRACK_TABLE = Table(
+ python_module=__file__,
class_name='PerfCounterTrackTable',
sql_name='perf_counter_track',
columns=[
@@ -265,6 +278,7 @@
}))
ENERGY_COUNTER_TRACK_TABLE = Table(
+ python_module=__file__,
class_name='EnergyCounterTrackTable',
sql_name='energy_counter_track',
columns=[
@@ -286,6 +300,7 @@
}))
UID_COUNTER_TRACK_TABLE = Table(
+ python_module=__file__,
class_name='UidCounterTrackTable',
sql_name='uid_counter_track',
columns=[
@@ -298,6 +313,7 @@
columns={'uid': 'uid of process for which breakdowns are emitted'}))
ENERGY_PER_UID_COUNTER_TRACK_TABLE = Table(
+ python_module=__file__,
class_name='EnergyPerUidCounterTrackTable',
sql_name='energy_per_uid_counter_track',
columns=[
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index d0eb99f..5317914 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -819,10 +819,9 @@
module.cmd = ' '.join([
f'$(location {bp_binary_module_name})',
'--gen-dir=$(genDir)',
+ '--relative-input-dir=external/perfetto',
'--inputs',
'$(in)',
- '--outputs',
- '$(out)',
])
module.out.update(target.outputs)
module.genrule_headers.add(module.name)
diff --git a/tools/gen_bazel b/tools/gen_bazel
index a514fe3..3121aa8 100755
--- a/tools/gen_bazel
+++ b/tools/gen_bazel
@@ -582,6 +582,9 @@
label = BazelLabel(get_bazel_label_name(target.name), 'perfetto_cc_tp_tables')
label.comment = target.name
label.srcs += (gn_utils.label_to_path(x) for x in target.sources)
+ label.deps += sorted(':' + get_bazel_label_name(x.name)
+ for x in target.transitive_deps
+ if x.name not in default_python_targets)
label.outs += target.outputs
return [label]
diff --git a/tools/gen_tp_table_docs.py b/tools/gen_tp_table_docs.py
index 8b8565a..97e183e 100755
--- a/tools/gen_tp_table_docs.py
+++ b/tools/gen_tp_table_docs.py
@@ -59,7 +59,9 @@
raise Exception('Unknown column documentation type '
f'{table.table.class_name}::{col.column.name}')
- parsed_type = table.parse_type(col.column.type)
+ parsed_type = util.parse_type_with_cols(table.table,
+ [c.column for c in table.columns],
+ col.column.type)
docs_type = parsed_type.cpp_type
if docs_type == 'StringPool::Id':
docs_type = 'string'
@@ -88,11 +90,20 @@
parser = argparse.ArgumentParser()
parser.add_argument('--out', required=True)
parser.add_argument('inputs', nargs='*')
+ parser.add_argument('--relative-input-dir')
args = parser.parse_args()
- tables = util.parse_tables_from_files(args.inputs)
+ def get_relin_path(in_path: str):
+ if not args.relative_input_dir:
+ return in_path
+ return os.path.relpath(in_path, args.relative_input_dir)
+
+ modules = [
+ os.path.splitext(get_relin_path(i).replace('/', '.'))[0]
+ for i in args.inputs
+ ]
table_docs = []
- for parsed in tables:
+ for parsed in util.parse_tables_from_modules(modules):
table = parsed.table
doc = table.tabledoc
assert doc
diff --git a/tools/gen_tp_table_headers.py b/tools/gen_tp_table_headers.py
index 1ce0963..d06c637 100755
--- a/tools/gen_tp_table_headers.py
+++ b/tools/gen_tp_table_headers.py
@@ -28,63 +28,71 @@
#pylint: disable=wrong-import-position
from python.generators.trace_processor_table.serialize import serialize_header
+from python.generators.trace_processor_table.util import find_table_deps
from python.generators.trace_processor_table.util import ParsedTable
-from python.generators.trace_processor_table.util import parse_tables_from_files
+from python.generators.trace_processor_table.util import parse_tables_from_modules
#pylint: enable=wrong-import-position
+# Suffix which replaces the .py extension for all input modules.
+OUT_HEADER_SUFFIX = '_py.h'
+
@dataclass
class Header:
"""Represents a Python module which will be converted to a header."""
- out_path: str
- relout_path: str
tables: List[ParsedTable]
def main():
"""Main function."""
parser = argparse.ArgumentParser()
- parser.add_argument('--gen-dir', required=True)
parser.add_argument('--inputs', required=True, nargs='*')
- parser.add_argument('--outputs', required=True, nargs='*')
+ parser.add_argument('--gen-dir', required=True)
parser.add_argument('--header-prefix')
+ parser.add_argument('--relative-input-dir')
args = parser.parse_args()
- if len(args.inputs) != len(args.outputs):
- raise Exception('Number of inputs must match number of outputs')
-
header_prefix = args.header_prefix if args.header_prefix else ''
- in_to_out = dict(zip(args.inputs, args.outputs))
+
+ def get_relin_path(in_path: str):
+ if not args.relative_input_dir:
+ return in_path
+ return os.path.relpath(in_path, args.relative_input_dir)
+
+ def get_relout_path(in_path: str):
+ path = os.path.splitext(in_path)[0]
+ return os.path.join(header_prefix, path + OUT_HEADER_SUFFIX)
+
+ def get_out_path(in_path: str):
+ return os.path.join(args.gen_dir, get_relout_path(in_path))
+
+ modules = [
+ os.path.splitext(get_relin_path(i).replace('/', '.'))[0]
+ for i in args.inputs
+ ]
headers: Dict[str, Header] = {}
- for table in parse_tables_from_files(args.inputs):
- out_path = in_to_out[table.input_path]
- relout_path = os.path.join(header_prefix,
- os.path.relpath(out_path, args.gen_dir))
-
- header = headers.get(table.input_path, Header(out_path, relout_path, []))
+ for table in parse_tables_from_modules(modules):
+ input_path = os.path.relpath(table.table.python_module, ROOT_DIR)
+ header = headers.get(input_path, Header([]))
header.tables.append(table)
- headers[table.input_path] = header
+ headers[input_path] = header
- # Build a mapping from table class name to the output path of the header
- # which will be generated for it. This is used to include one header into
- # another for Id dependencies.
- table_class_name_to_relout: Dict[str, str] = {}
- for header in headers.values():
- for table in header.tables:
- table_class_name_to_relout[table.table.class_name] = header.relout_path
+ for in_path, header in headers.items():
+ out_path = get_out_path(in_path)
+ relout_path = get_relout_path(in_path)
- for header in headers.values():
# Find all headers depended on by this table. These will be #include-ed when
# generating the header file below so ensure we remove ourself.
header_relout_deps: Set[str] = set()
for table in header.tables:
- header_relout_deps = header_relout_deps.union(
- [table_class_name_to_relout[c] for c in table.find_table_deps()])
- header_relout_deps.discard(header.relout_path)
+ header_relout_deps = header_relout_deps.union([
+ get_relout_path(os.path.relpath(c.python_module, ROOT_DIR))
+ for c in find_table_deps(table.table)
+ ])
+ header_relout_deps.discard(relout_path)
- with open(header.out_path, 'w', encoding='utf8') as out:
- ifdef_guard = re.sub(r'[^a-zA-Z0-9_-]', '_',
- header.relout_path).upper() + '_'
+ with open(out_path, 'w', encoding='utf8') as out:
+ ifdef_guard = re.sub(r'[^a-zA-Z0-9_-]', '_', relout_path).upper() + '_'
out.write(
serialize_header(ifdef_guard, header.tables,
sorted(header_relout_deps)))